Skip to content

Instantly share code, notes, and snippets.

@noogen
Last active June 9, 2021 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noogen/8cede8b5cb190dcf0d2bca844f8e96ec to your computer and use it in GitHub Desktop.
Save noogen/8cede8b5cb190dcf0d2bca844f8e96ec to your computer and use it in GitHub Desktop.
Example elasticsearch importer for WP Recipe Maker
<?php
/**
* Responsible for importing recipes.
*
* @since 5.8.0
*
* @package Import Example
*/
/**
* Responsible for importing recipes.
*
*/
class WPRM_Import_Example extends WPRM_Import {
/**
* Get the API arguments.
*
* @since 5.8.0
*/
private function get_api_args() {
$args = [
'method' => 'GET',
'headers' => [
'Content-Type' => 'application/json; charset=utf-8',
'Authorization' => 'Basic ' . base64_encode('user:passwerd')
],
'sslverify' => false
];
return $args;
}
/**
* Search recipe helper
*
* @param integer $page the page number
*/
private function search_recipe_helper( $page = 0 ) {
$found_recipes = array();
$limit = 100;
$offset = $limit * $page;
$api_args = $this->get_api_args();
$api_url = 'https://elasticsearch.server.com/recipe/_search?q=*:*&_source=false&sort=_id&size='.$limit;
$response = wp_remote_get($api_url . '&from=' . $offset, $api_args);
$recipe_rsp = wp_remote_retrieve_body($response);
if (empty($recipe_rsp)) {
return false;
}
$recipe_data = json_decode($recipe_rsp, true);
$recipes = $recipe_data['hits']['hits'];
$i = 0;
foreach($recipes as $hit) {
$i = $i + 1;
$found_recipes[$hit['_id']] = array(
'name' => ($offset + $i) . ': ' . $hit['_id'],
'url' => '#' . $hit['_id']
);
}
return $found_recipes;
}
/**
* Get post by name
* @param String $name recipe name/slug
* @return Object post
*/
public function get_post_by_name($name)
{
$query = new \WP_Query(['name' => $name, 'post_type' => 'wprm_recipe']);
$posts = $query->get_posts();
return $posts[0] ?? null;
}
/**
* Get the UID of this import source.
*
* @since 5.8.0
*/
public function get_uid() {
return 'example-recipe-importer';
}
/**
* Wether or not this importer requires a manual search for recipes.
*
* @since 5.8.0
*/
public function requires_search() {
return false;
}
/**
* Get the name of this import source.
*
* @since 5.8.0
*/
public function get_name() {
return 'Example Recipe Importer';
}
/**
* Get HTML for the import settings.
*
* @since 5.8.0
*/
public function get_settings_html() {
$html = '<h4>General</h4>';
$html .= '<input type="checkbox" name="import-as-checked" id="import-as-checked" value="true" checked> <label for="import-as-checked"> Import as checked</label>';
return $html;
}
/**
* Get the total number of recipes to import.
*
* @since 5.8.0
*/
public function get_recipe_count() {
$api_args = $this->get_api_args();
$response = wp_remote_get('https://elasticsearch.server.com/recipe/_count?q=*:*', $api_args);
$recipe_rsp = wp_remote_retrieve_body($response);
if (empty($recipe_rsp)) {
return 0;
}
return json_decode($recipe_rsp, true)['count'];
}
/**
* Search for recipes to import.
*
* @since 5.8.0
* @param int $page Page of recipes to import.
*/
public function search_recipes( $page = 0 ) {
$count = $this->get_recipe_count();
$search_result = array(
'finished' => true,
'recipes' => $count
);
return $search_result;
}
/**
* Get a list of recipes that are available to import.
*
* @since 5.8.0
* @param int $page Page of recipes to get.
*/
public function get_recipes( $page = 0 ) {
$found_recipes = $this->search_recipe_helper($page);
return $found_recipes;
}
/**
* Get recipe with the specified ID in the import format.
*
* @since 5.8.0
* @param mixed $id ID of the recipe we want to import.
* @param array $post_data POST data passed along when submitting the form.
*/
public function get_recipe( $id, $post_data ) {
$post = $this->get_post_by_name($id);
if ($post) {
return false;
}
$api_args = $this->get_api_args();
$api_url = 'https://elasticsearch.server.com/recipe/_source/'.$id;
$response = wp_remote_get($api_url, $api_args);
$recipe_rsp = wp_remote_retrieve_body($response);
$recipe = false;
if (empty($recipe_rsp)) {
return $recipe;
}
$json_recipe = json_decode($recipe_rsp, true);
if ( $json_recipe ) {
$recipe = array(
'import_id' => 0, // Set to 0 because we need to create a new recipe post.
'import_backup' => array(
'image_url' => $json_recipe['image_url'],
'rating_value' => isset( $json_recipe['rating_value'] ) ? $json_recipe['rating_value'] : '',
'servings' => $servings,
'json' => $recipe_rsp,
),
);
// Simple matching.
$recipe['name'] = isset( $json_recipe['name'] ) ? $json_recipe['name'] : '';
$recipe['summary'] = isset( $json_recipe['description'] ) ? $json_recipe['description'] : '';
// Servings.
$servings = isset( $json_recipe['recipe_yield'] ) ? trim( $json_recipe['recipe_yield'] ) : '';
preg_match_all('/([\d]+)/', $servings, $match);
if (count($match) > 0) {
$recipe['servings'] = $match[0][0] ?? 1;
$recipe['servings_unit'] = '';
}
// Cook times.
$recipe['prep_time'] = isset( $json_recipe['prep_time'] ) ? $json_recipe['prep_time'] : 0;
$recipe['cook_time'] = isset( $json_recipe['cook_time'] ) ? $json_recipe['cook_time'] : 0;
$recipe['custom_time'] = isset( $json_recipe['rest_time'] ) ? $json_recipe['rest_time'] : 0;
$recipe['custom_time_label'] = 'Resting Time';
$recipe['total_time'] = isset( $json_recipe['total_time'] ) ? $json_recipe['total_time'] : 0;
// Recipe Tags.
$recipe['tags'] = array(
'course' => array(),
'cuisine' => array(),
'keyword' => array(),
);
if (!empty($json_recipe['recipe_category'])) {
$recipe['tags']['course'] = explode('|', $json_recipe['recipe_category']);
}
if (!empty($json_recipe['recipe_cuisine'])) {
$recipe['tags']['cuisine'] = explode('|', $json_recipe['recipe_cuisine']);
}
if (!empty($json_recipe['keywords'])) {
$recipe['tags']['keyword'] = explode('|', $json_recipe['keywords']);
}
// Ingredients.
$json_ingredients = isset( $json_recipe['recipe_ingredient'] ) ? $json_recipe['recipe_ingredient'] : array();
$ingredients = array();
$group = array(
'ingredients' => array(),
'name' => '',
);
foreach ( $json_ingredients as $json_ingredient ) {
$group['ingredients'][] = array(
'raw' => $json_ingredient,
);
}
$recipe['ingredients'] = array( $group );
// Instructions.
$json_instructions = isset( $json_recipe['recipe_instructions'] ) ? $json_recipe['recipe_instructions'] : array();
$instructions = array();
$group = array(
'instructions' => array(),
'name' => '',
);
foreach ( $json_instructions as $json_instruction ) {
$group['instructions'][] = array(
'text' => $json_instruction,
'image' => '',
);
}
$instructions[] = $group;
$recipe['instructions'] = $instructions;
// Recipe Nutrition.
$nutrition_mapping = array(
'serving_size' => 'serving_size',
'calories' => 'calories',
'carbohydrates' => 'carbohydrate',
'protein' => 'protein',
'fat' => 'fat',
'saturated_fat' => 'saturated_fat',
'polyunsaturated_fat' => 'polyunsaturated_fat',
'monounsaturated_fat' => 'monounsaturated_fat',
'trans_fat' => 'trans_fat',
'cholesterol' => 'cholesterol',
'sodium' => 'sodium',
'potassium' => 'potassium',
'fiber' => 'dietary_fiber',
'sugar' => 'sugar',
'added_sugar' => 'added_sugar',
'vitamin_a' => 'vitamin_a',
'vitamin_c' => 'vitamin_c',
'calcium' => 'calcium',
'iron' => 'iron',
);
$nutrition = isset( $json_recipe['nutrition'] ) ? $json_recipe['nutrition'] : array();
foreach ( $nutrition_mapping as $wprm_field => $json_field ) {
$recipe['nutrition'][ $wprm_field ] = isset( $nutrition[ $json_field ] ) ? $nutrition[ $json_field ] : '';
}
} else {
$recipe = false;
}
return $recipe;
}
/**
* Replace the original recipe with the newly imported WPRM one.
*
* @since 5.8.0
* @param mixed $id ID of the recipe we want replace.
* @param mixed $wprm_id ID of the WPRM recipe to replace with.
* @param array $post_data POST data passed along when submitting the form.
*/
public function replace_recipe( $id, $wprm_id, $post_data ) {
// The recipe with ID $id has been imported and we now have a WPRM recipe with ID $wprm_id (can be the same ID).
// $post_data will contain any input fields set in the "get_settings_html" function.
// Use this function to do anything after the import, like replacing shortcodes.
// Update Featured Image
$import_backup = get_post_meta( $wprm_id, 'wprm_import_backup', true );
if (!empty($import_backup['image_url'])) {
$image_id = WPRM_Import_Helper::get_or_upload_attachment( $wprm_id, $import_backup['image_url'] );
set_post_thumbnail( $wprm_id, $image_id );
}
// Update rating
if (!empty($import_backup['rating_value'])) {
$rating = array(
'recipe_id' => $wprm_id,
'user_id' => get_current_user_id(),
'ip' => 'importer',
'rating' => ceil(floatval($import_backup['rating_value']))
);
WPRM_Rating_Database::add_or_update_rating( $rating );
$recipe_rating = array(
'count' => 1,
'total' => $rating['rating'],
'average' => $rating['rating'],
);
update_post_meta( $wprm_id, 'wprm_rating', $recipe_rating );
update_post_meta( $wprm_id, 'wprm_rating_average', $recipe_rating['average'] );
}
// Update status to make sure it's published
$post = array(
'ID' => $wprm_id,
'post_status' => 'publish'
);
wp_update_post( $post );
$import_as_checked = isset( $post_data['import-as-checked'] ) ? $post_data['import-as-checked'] : '';
if ('checked' === $import_as_checked) {
// default to checked
update_post_meta( $wprm_id, 'wprm_import_source', $this->get_uid() . '-checked' );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment