コード例 #1
0
 /**
  * Process the template text
  *
  * @param null $data
  * @param int $options
  * @return mixed|string
  */
 function replace($data = null, $options = 0)
 {
     /**
      * If we have replacements, pre-process the template and remove conditionally INCLUDEd stuff
      */
     if ($data === null) {
         $data = new stdClass();
     }
     $currentPosition = 0;
     $this->opText = '';
     $inText = $this->inText;
     $firstType = null;
     /**
      * We return from within this loop when we have nothing left to process
      */
     while (true) {
         /**
          * Look for stuff to replace and find the first of them
          */
         $firstPosition = strlen($inText);
         $varPosition = strpos($inText, $this->delimiter, $currentPosition);
         if ($varPosition !== false) {
             $firstPosition = $varPosition;
             $firstType = self::VARIABLEREPLACE;
         }
         $repeatPosition = strpos($inText, '<!-- START REPEAT ', $currentPosition);
         if ($repeatPosition !== false && $repeatPosition < $firstPosition) {
             $firstPosition = $repeatPosition;
             $firstType = self::REPEATREPLACE;
         }
         $includeifPosition = strpos($inText, '<!-- START INCLUDEIF ', $currentPosition);
         if ($includeifPosition !== false && $includeifPosition < $firstPosition) {
             $firstPosition = $includeifPosition;
             $firstType = self::INCLUDEIF;
         }
         $startStripPosition = strpos($inText, '<!-- START STRIP WHITESPACE ', $currentPosition);
         if ($startStripPosition !== false && $startStripPosition < $firstPosition) {
             $firstPosition = $startStripPosition;
             $firstType = self::STARTSTRIP;
         }
         $endStripPosition = strpos($inText, '<!-- END STRIP WHITESPACE ', $currentPosition);
         if ($endStripPosition !== false && $endStripPosition < $firstPosition) {
             $firstPosition = $endStripPosition;
             $firstType = self::ENDSTRIP;
         }
         /**
          * If there's nothing to do, just return what we've got
          */
         if ($firstPosition == strlen($inText)) {
             /**
              * Copy any remaining input over to the output
              */
             $this->opText .= substr($inText, $currentPosition);
             /*
              * If there's any block to whitespace strip, do it
              * Tidy up the start/stop positions first to make it easy to process
              * This allows overlapping and unterminated stip blocks
              */
             if (count($this->stripWhitespace) > 0) {
                 $stripBlocks = array();
                 $startPosition = -1;
                 foreach ($this->stripWhitespace as $position) {
                     /**
                      * End strip?
                      */
                     if ($position < 0) {
                         /**
                          * If there's no previous unterminated START STRIP, ignore this END
                          */
                         if ($startPosition == -1) {
                             continue;
                         }
                         $stripBlocks[] = array($startPosition, abs($position));
                         $startPosition = -1;
                     } else {
                         /**
                          * If there's a previous unterminated START STRIP, ignore this one
                          */
                         if ($startPosition != -1) {
                             continue;
                         }
                         $startPosition = $position;
                     }
                 }
                 /**
                  * Allow for a missing END STRIP
                  */
                 if ($startPosition != -1) {
                     $stripBlocks[] = array($startPosition, strlen($this->opText));
                 }
                 /**
                  * Actually strip out whitespace in the strip blocks
                  */
                 $currentPosition = 0;
                 $strippedText = '';
                 foreach ($stripBlocks as $stripBlock) {
                     $strippedText .= substr($this->opText, $currentPosition, $stripBlock[0] - $currentPosition);
                     $text = substr($this->opText, $stripBlock[0], $stripBlock[1] - $stripBlock[0]);
                     $text = preg_replace('/>\\s+</', '><', $text);
                     $strippedText .= trim($text);
                     $currentPosition = $stripBlock[1];
                 }
                 $strippedText .= substr($this->opText, $currentPosition, strlen($this->opText) - $currentPosition);
                 $this->opText = $strippedText;
             }
             /**
              * If we aren't translating, then just (optionally) clean up whitespace and return
              */
             if (!self::$translate || !class_exists('EasyRecipePlusDOMDocument')) {
                 return $this->cleanWhitespace($this->opText, $options);
             }
             $doc = new EasyRecipePlusDOMDocument($this->opText, true);
             if (!$doc) {
                 return $this->opText;
             }
             $xlates = $doc->getElementsByClassName('xlate');
             if (count($xlates) == 0) {
                 return $this->cleanWhitespace($this->opText, $options);
             }
             // FIXME - use gettext if no __
             foreach ($xlates as $xlate) {
                 $original = $doc->innerHTML($xlate);
                 $translation = __($original, self::$textDomain);
                 if ($translation != $original) {
                     $xlate->nodeValue = $translation;
                 }
             }
             $html = $doc->getHTML(true);
             return $this->cleanWhitespace($html, $options);
         }
         /**
          * Copy over everything up to the first thing we need to process
          */
         $length = $firstPosition - $currentPosition;
         $this->opText .= substr($inText, $currentPosition, $length);
         $currentPosition = $firstPosition;
         /**
          * Get the thing to be replaced
          */
         switch ($firstType) {
             /**
              * INCLUDEIF includes the code up to the matching END INCLUDEIF:
              *  IF the condition variable exists and it's not false or null
              */
             case self::INCLUDEIF:
                 /**
                  * Get the conditional.
                  * Only check a smallish substring for efficiency
                  * This limits include condition names to 20 characters
                  */
                 $subString = substr($inText, $currentPosition, 60);
                 if (preg_match('/<!-- START INCLUDEIF (!?)([_a-z][_0-9a-z]{0,31}) -->/i', $subString, $regs)) {
                     $negate = $regs[1];
                     $trueFalse = $negate != '!';
                     $includeCondition = $regs[2];
                 } else {
                     trigger_error("Malformed START INCLUDEIF at {$currentPosition} ({$subString})", E_USER_NOTICE);
                     $this->opText .= "<";
                     $currentPosition++;
                     continue;
                 }
                 $endInclude = "<!-- END INCLUDEIF {$negate}{$includeCondition} -->";
                 $endIncludeLength = strlen($endInclude);
                 $endPosition = strpos($inText, $endInclude);
                 if ($endPosition == false) {
                     trigger_error(htmlspecialchars("'{$endInclude}'") . " not found", E_USER_NOTICE);
                     $this->opText .= "<";
                     $currentPosition++;
                     break;
                 }
                 /**
                  * If the condition is met, just remove the INCLUDEIF comments
                  * If the condition isn't met, remove everything up to the END INCLUDEIF
                  * The condition must be present, and NOT false or NULL
                  */
                 $condition = isset($data->{$includeCondition}) && $data->{$includeCondition} !== false && $data->{$includeCondition} !== null;
                 if ($condition === $trueFalse) {
                     $startInclude = "<!-- START INCLUDEIF {$negate}{$includeCondition} -->";
                     $startIncludeLength = strlen($startInclude);
                     $inText = substr($inText, 0, $currentPosition) . substr($inText, $currentPosition + $startIncludeLength, $endPosition - $currentPosition - $startIncludeLength) . substr($inText, $endPosition + $endIncludeLength);
                 } else {
                     $inText = substr($inText, 0, $currentPosition) . substr($inText, $endPosition + $endIncludeLength);
                 }
                 break;
                 /**
                  * Remove whitespace between tags.
                  * Useful to remove unwanted significant HTML whitespace that may have been introduced by auto formatting the source template
                  */
             /**
              * Remove whitespace between tags.
              * Useful to remove unwanted significant HTML whitespace that may have been introduced by auto formatting the source template
              */
             case self::STARTSTRIP:
                 $currentPosition += 31;
                 $this->stripWhitespace[] = strlen($this->opText);
                 break;
                 /**
                  * Save the output position at which to stop stripping. -ve indicates that it's an end position
                  */
             /**
              * Save the output position at which to stop stripping. -ve indicates that it's an end position
              */
             case self::ENDSTRIP:
                 $currentPosition += 29;
                 $this->stripWhitespace[] = -strlen($this->opText);
                 break;
                 /**
                  * A variable is a valid PHP variable name (limited to 20 chars) between delimiters
                  * If we don't find a valid name, copy over the delimiter and continue
                  * FIXME - fall back to caller's vars if it doesn't exist
                  */
             /**
              * A variable is a valid PHP variable name (limited to 20 chars) between delimiters
              * If we don't find a valid name, copy over the delimiter and continue
              * FIXME - fall back to caller's vars if it doesn't exist
              */
             case self::VARIABLEREPLACE:
                 $s = substr($inText, $currentPosition, 34);
                 if (!preg_match("/^{$this->delimiter}([_a-z][_0-9a-z]{0,31}){$this->delimiter}/si", $s, $regs)) {
                     $this->opText .= $this->delimiter;
                     $currentPosition++;
                     continue;
                 }
                 /**
                  * If we don't have a match for the variable, just assume it's not what we wanted to do
                  * so put the string we matched back into the output and continue from the trailing delimiter
                  */
                 $varName = $regs[1];
                 if (!isset($data->{$varName})) {
                     $this->opText .= $this->delimiter . $varName;
                     $currentPosition += strlen($varName) + 1;
                     continue;
                 }
                 /**
                  * Got a match - replace the <delimiter>...<delimiter> with the vars stuff
                  * We *could* pass this on for recursive processing, but it's not something we would normally want to do
                  * Maybe have a special naming convention for vars we want to do recursively?
                  */
                 $this->opText .= $data->{$varName};
                 $currentPosition += strlen($varName) + 2;
                 break;
                 /**
                  * We've seen a start repeat.
                  * Find the name of the repeat (limited to 20 chars)
                  * If we can't find the name, assume it's not what we want and continue
                  *
                  * Look for a valid START REPEAT in the next 45 characters
                  */
             /**
              * We've seen a start repeat.
              * Find the name of the repeat (limited to 20 chars)
              * If we can't find the name, assume it's not what we want and continue
              *
              * Look for a valid START REPEAT in the next 45 characters
              */
             case self::REPEATREPLACE:
                 $s = substr($inText, $currentPosition, 45);
                 if (!preg_match('/<!-- START REPEAT ([_a-zA-Z][_0-9a-zA-Z]{0,19}) -->/m', $s, $regs)) {
                     $this->opText .= '<';
                     $currentPosition++;
                     continue;
                 }
                 $rptName = $regs[1];
                 /**
                  * Make sure we have a matching key and it's an array
                  */
                 if (!isset($data->{$rptName}) || !is_array($data->{$rptName})) {
                     $this->opText .= '<';
                     $currentPosition++;
                     continue;
                 }
                 /**
                  * Now try to find the end of this repeat
                  */
                 $currentPosition += strlen($rptName) + 22;
                 $rptEnd = strpos($inText, "<!-- END REPEAT {$rptName} -->", $currentPosition);
                 if ($rptEnd === false) {
                     $this->opText .= '<!-- START REPEAT $rptName -->';
                     trigger_error("END REPEAT not found for {$rptName}", E_USER_NOTICE);
                     continue;
                 }
                 /**
                  * Do the repeat processing.
                  * For each item in the repeated array, process as a new template
                  */
                 $rptLength = $rptEnd - $currentPosition;
                 $rptString = substr($inText, $currentPosition, $rptLength);
                 $rptVars = $data->{$rptName};
                 for ($i = 0; $i < count($rptVars); $i++) {
                     $saveTranslate = self::$translate;
                     self::$translate = false;
                     $rpt = new EasyRecipePlusTemplate($rptString, self::TEXT, $this->delimiter);
                     $this->opText .= $rpt->replace($rptVars[$i], $options);
                     self::$translate = $saveTranslate;
                 }
                 /**
                  * Step over the end repeat
                  */
                 $currentPosition += strlen($rptName) + $rptLength + 20;
                 break;
         }
     }
     return '';
 }
コード例 #2
0
 private function doConvert($postID, $postType)
 {
     /** @global $wpdb wpdb */
     global $wpdb;
     $result = new stdClass();
     switch ($postType) {
         case 'ultimate-recipe':
             $result->recipe = new stdClass();
             if ($postID == 'random') {
                 $posts = get_posts(array('post_type' => 'recipe', 'nopaging' => true));
                 $post = $posts[array_rand($posts)];
             } else {
                 $post = get_post($postID);
             }
             $recipe = get_post_custom($post->ID);
             $user = get_userdata($post->post_author);
             $image = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
             $cuisine = wp_get_object_terms($post->ID, 'cuisine');
             if ($cuisine instanceof WP_Error) {
                 register_taxonomy('cuisine', 'recipe');
                 $cuisine = wp_get_object_terms($post->ID, 'cuisine');
             }
             $course = wp_get_object_terms($post->ID, 'course');
             if ($course instanceof WP_Error) {
                 register_taxonomy('course', 'recipe');
                 $course = wp_get_object_terms($post->ID, 'course');
             }
             /**
              * Very dodgy way of processing times - not sure what else we can do!
              * Times other than "x minutes" are going to be unparsable reliably
              * Will have to adjust this based on real user values as we come across them
              *
              * Try for xlated "minutes" first
              * If that doesn't work, at least try some likely English duration specifiers
              */
             $xMinutes = __('minutes', 'wp-ultimate-recipe');
             $timeText = !empty($recipe['recipe_prep_time_text']) ? $recipe['recipe_prep_time_text'][0] : '';
             if ($timeText == $xMinutes || $timeText == 'minute') {
                 $result->recipe->prep_time = 'PT' . $recipe['recipe_prep_time'][0] . 'M';
             } elseif ($timeText == 'hours' || $timeText == 'hour') {
                 $result->recipe->prep_time = 'PT' . $recipe['recipe_prep_time'][0] . 'H0M';
             } else {
                 $result->recipe->prep_time = '';
             }
             $timeText = !empty($recipe['recipe_cook_time_text']) ? $recipe['recipe_cook_time_text'][0] : '';
             if ($timeText == $xMinutes || $timeText == 'minute') {
                 $result->recipe->cook_time = 'PT' . $recipe['recipe_cook_time'][0] . 'M';
             } elseif ($timeText == 'hours' || $timeText == 'hour') {
                 $result->recipe->cook_time = 'PT' . $recipe['recipe_cook_time'][0] . 'H0M';
             } else {
                 $result->recipe->cook_time = '';
             }
             $result->recipe->recipe_image = !empty($image) ? $image[0] : '';
             if (is_array($cuisine) && !empty($cuisine[0])) {
                 $result->recipe->cuisine = htmlspecialchars($cuisine[0]->name);
             }
             if (is_array($course) && !empty($course[0])) {
                 $result->recipe->mealType = htmlspecialchars($course[0]->name);
             }
             $result->recipe->recipe_title = !empty($recipe['recipe_title']) ? htmlspecialchars($recipe['recipe_title'][0]) : '';
             /** @noinspection PhpUndefinedFieldInspection */
             $result->recipe->author = htmlspecialchars($user->data->display_name);
             $result->recipe->summary = !empty($recipe['recipe_description']) ? htmlspecialchars($recipe['recipe_description'][0]) : '';
             $notes = !empty($recipe['recipe_notes'][0]) ? preg_replace_callback('%<(strong|em)>(.*?)</\\1>%', array($this, 'notesConversion'), $recipe['recipe_notes'][0]) : '';
             $result->recipe->notes = preg_replace('%<a ([^>]+)>(.*?)</a>%i', '[url $1]$2[/url]', $notes);
             $section = '';
             $ingredients = array();
             $urIngredients = @unserialize($recipe['recipe_ingredients'][0]);
             if (!$urIngredients) {
                 $urIngredients = array();
             }
             foreach ($urIngredients as $urIngredient) {
                 if ($urIngredient['group'] != $section) {
                     $section = $urIngredient['group'];
                     $ingredients[] = '!' . htmlspecialchars($urIngredient['group']);
                 }
                 $ingredient = htmlspecialchars($urIngredient['amount']) . ' ' . htmlspecialchars($urIngredient['unit']) . ' ' . htmlspecialchars($urIngredient['ingredient']);
                 if (!empty($urIngredient['notes'])) {
                     $ingredient .= ' ' . htmlspecialchars($urIngredient['notes']);
                 }
                 $ingredients[] = $ingredient;
             }
             $result->ingredients = $ingredients;
             $section = '';
             $instructions = array();
             $urInstructions = @unserialize($recipe['recipe_instructions'][0]);
             if (!$urInstructions) {
                 $urInstructions = array();
             }
             foreach ($urInstructions as $urInstruction) {
                 if ($urInstruction['group'] != $section) {
                     $section = $urInstruction['group'];
                     $instructions[] = '!' . htmlspecialchars($urInstruction['group']);
                 }
                 $instruction = htmlspecialchars($urInstruction['description']);
                 if (!empty($urInstruction['image'])) {
                     $instructionImage = wp_get_attachment_image_src($urInstruction['image'], 'large');
                     if (!empty($instructionImage)) {
                         $instruction .= '[br][img src="' . $instructionImage[0] . '" width="' . $instructionImage[1] . '" height="' . $instructionImage[2] . '" /]';
                     }
                 }
                 $instructions[] = $instruction;
             }
             $result->recipe->instructions = implode("\n", $instructions);
             break;
         case 'recipage':
             /** @var WP_Post $post */
             $post = $wpdb->get_row("SELECT * FROM " . $wpdb->posts . " WHERE ID=" . $postID);
             $content = $post->post_content;
             $document = new EasyRecipePlusDOMDocument($content);
             if (!$document->isValid()) {
                 return null;
             }
             $hrecipe = $document->getElementByClassName('hrecipe');
             if (!$hrecipe) {
                 return null;
             }
             $result->recipe = new stdClass();
             $result->recipe->total_time = '';
             $result->recipe->serving_size = '';
             $result->recipe->notes = '';
             $result->recipe->calories = '';
             $result->recipe->fat = '';
             $result->recipe->rating = '';
             /** @var DOMElement $element */
             $element = $document->getElementByClassName('photo', 'img', $hrecipe);
             $result->recipe->recipe_image = $element != null ? $element->getAttribute('src') : '';
             $element = $document->getElementByClassName('fn', '*', $hrecipe);
             $result->recipe->recipe_title = $element != null ? htmlspecialchars($element->textContent) : '';
             $element = $document->getElementByClassName('author', '*', $hrecipe);
             $result->recipe->author = $element != null ? htmlspecialchars($element->textContent) : '';
             $element = $document->getElementByClassName('summary', '*', $hrecipe);
             $result->recipe->summary = $element != null ? htmlspecialchars($element->textContent) : '';
             $element = $document->getElementByClassName('yield', '*', $hrecipe);
             $result->recipe->yield = $element != null ? htmlspecialchars($element->textContent) : '';
             $element = $document->getElementByClassName('preptime', '*', $hrecipe);
             $prepTime = $element != null ? $element->textContent : '';
             $result->recipe->prep_time = $this->convertTimeString($prepTime);
             $element = $document->getElementByClassName('cooktime', '*', $hrecipe);
             $cookTime = $element != null ? $element->textContent : '';
             $result->recipe->cook_time = $this->convertTimeString($cookTime);
             $result->ingredients = array();
             $ingredients = $document->getElementsByClassName('ingredient', '*', $hrecipe);
             /** @var DOMElement $ingredient */
             foreach ($ingredients as $ingredient) {
                 $result->ingredients[] = trim($ingredient->textContent);
             }
             $instructions = array();
             $elements = $document->getElementsByClassName('instruction', '*', $hrecipe);
             /** @var DOMElement $instruction */
             foreach ($elements as $instruction) {
                 $instructions[] = trim($instruction->textContent);
             }
             $result->recipe->instructions = implode("\n", $instructions);
             break;
         case 'recipeseo':
             $result->recipe = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "amd_recipeseo_recipes WHERE recipe_id=" . $postID);
             $ingredients = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "amd_recipeseo_ingredients WHERE recipe_id=" . $postID . " ORDER BY ingredient_id");
             $result->ingredients = array();
             foreach ($ingredients as $ingredient) {
                 $result->ingredients[] = $ingredient->amount . " " . $ingredient->name;
             }
             break;
         case 'zlrecipe':
             $result->recipe = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "amd_zlrecipe_recipes WHERE recipe_id=" . $postID);
             $result->recipe->nReviews = 1;
             $result->recipe->summary = $this->decodeMarkdown($result->recipe->summary);
             $result->recipe->notes = $this->decodeMarkdown($result->recipe->notes);
             /**
              * If only total time is specified, use it as the cook time
              * TODO - Do this for all plugins?
              */
             if ($result->recipe->cook_time == '' && $result->recipe->prep_time == '') {
                 $result->recipe->cook_time = $result->recipe->total_time;
             }
             $ingredients = explode("\n", str_replace("\r", "", $result->recipe->ingredients));
             $result->ingredients = array();
             foreach ($ingredients as $ingredient) {
                 $ingredient = trim($ingredient);
                 if ($ingredient != '') {
                     if (preg_match('/^%([^\\s]+)/', $ingredient, $regs)) {
                         if (($n = count($result->ingredients)) > 0 && $result->ingredients[$n - 1][0] != '!') {
                             $result->ingredients[$n - 1] .= '[br][img src="' . $regs[1] . '"]';
                             continue;
                         } else {
                             $ingredient = '[img src="' . $regs[1] . '"]';
                         }
                     } else {
                         $ingredient = $this->decodeMarkdown($ingredient);
                     }
                     $result->ingredients[] = $ingredient;
                 }
             }
             unset($result->recipe->ingredients);
             $instructions = explode("\n", str_replace("\r", "", $result->recipe->instructions));
             $convertedInstructions = array();
             foreach ($instructions as $instruction) {
                 $instruction = trim($instruction);
                 if ($instruction != '') {
                     if (preg_match('/^%([^\\s]+)/', $instruction, $regs)) {
                         if (($n = count($convertedInstructions)) > 0 && $convertedInstructions[$n - 1][0] != '!') {
                             $convertedInstructions[$n - 1] .= '[br][img src="' . $regs[1] . '"]';
                             continue;
                         } else {
                             $instruction = '[img src="' . $regs[1] . '"]';
                         }
                     } else {
                         $instruction = $this->decodeMarkdown($instruction);
                     }
                     $convertedInstructions[] = $instruction;
                 }
             }
             /**
              * For silly historical reasons, instructions are returned as a string
              */
             $result->recipe->instructions = implode("\n", $convertedInstructions);
             break;
         case 'recipress':
             $meta = get_post_custom($postID);
             $result->recipe = new stdClass();
             $result->ingredients = array();
             $result->recipe->instructions = '';
             /** @noinspection PhpUndefinedFunctionInspection */
             $size = recipress_options('instruction_image_size');
             $result->recipe->recipe_title = $meta['title'][0] ? $meta['title'][0] : '';
             $photo = wp_get_attachment_image_src($meta['photo'][0], 'thumbnail', false);
             $result->recipe->recipe_image = $photo ? $photo[0] : '';
             $result->recipe->summary = $meta['summary'][0] ? $meta['summary'][0] : '';
             $terms = get_the_terms($postID, 'cuisine');
             $result->recipe->cuisine = $terms[0]->name;
             $terms = get_the_terms($postID, 'course');
             $result->recipe->mealType = $terms[0]->name;
             /** @noinspection PhpUndefinedFunctionInspection */
             $result->recipe->cook_time = $meta['cook_time'][0] ? recipress_time($meta['cook_time'][0], 'iso') : '';
             /** @noinspection PhpUndefinedFunctionInspection */
             $result->recipe->prep_time = $meta['prep_time'][0] ? recipress_time($meta['prep_time'][0], 'iso') : '';
             $result->recipe->yield = $meta['yield'][0] ? $meta['yield'][0] : '';
             $result->recipe->serves = $meta['servings'][0] ? $meta['servings'][0] : '';
             $ingredients = $meta['ingredient'];
             $ingredients = unserialize($ingredients[0]);
             foreach ($ingredients as $ingredient) {
                 $newIngredient = $ingredient['amount'] . ' ' . $ingredient['measurement'] . ' ' . $ingredient['ingredient'];
                 if (!empty($ingredient['notes'])) {
                     $newIngredient .= ', ' . $ingredient['notes'];
                 }
                 $result->ingredients[] = trim(str_replace('  ', ' ', $newIngredient));
             }
             $instructions = $meta['instruction'];
             $instructions = unserialize($instructions[0]);
             foreach ($instructions as $instruction) {
                 $result->recipe->instructions .= $instruction['description'];
                 if (!empty($instruction['image'])) {
                     $result->recipe->instructions .= "[br]" . wp_get_attachment_image($instruction['image'], $size, false);
                     $result->recipe->instructions = str_replace('<', '[', $result->recipe->instructions);
                     $result->recipe->instructions = str_replace('>', ']', $result->recipe->instructions);
                 }
                 $result->recipe->instructions .= "\n";
             }
             break;
             /**
              * Make the Recipe Card data look like RecipeSEO/Ziplist - only because we already have the JS for those
              */
         /**
          * Make the Recipe Card data look like RecipeSEO/Ziplist - only because we already have the JS for those
          */
         case 'yumprint':
             $post = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "yumprint_recipe_recipe WHERE id=" . $postID);
             $nutrition = @json_decode($post->nutrition);
             $recipe = @json_decode($post->recipe);
             if (empty($recipe)) {
                 $recipe = new stdClass();
             }
             $recipe->recipe_title = !empty($recipe->title) ? $recipe->title : '';
             $recipe->recipe_image = !empty($recipe->image) ? $recipe->image : '';
             $ingredients = !empty($recipe->ingredients) && is_array($recipe->ingredients) ? $recipe->ingredients : array();
             $result->ingredients = array();
             foreach ($ingredients as $value) {
                 if ($value->title != '') {
                     $result->ingredients[] = '!' . $value->title;
                 }
                 foreach ($value->lines as $line) {
                     $result->ingredients[] = $line;
                 }
             }
             $instructions = !empty($recipe->directions) && is_array($recipe->directions) ? $recipe->directions : array();
             $recipe->instructions = array();
             foreach ($instructions as $value) {
                 if ($value->title != '') {
                     $recipe->instructions[] = '!' . $value->title;
                 }
                 foreach ($value->lines as $line) {
                     $recipe->instructions[] = $line;
                 }
             }
             $recipe->instructions = implode("\n", $recipe->instructions);
             $recipe->notes = !empty($recipe->notes) && is_array($recipe->notes) ? implode("\n", $recipe->notes[0]->lines) : '';
             $recipe->prep_time = !empty($recipe->prepTime) ? $this->yumprintTime($recipe->prepTime) : '';
             $recipe->cook_time = !empty($recipe->cookTime) ? $this->yumprintTime($recipe->cookTime) : '';
             $recipe->yield = !empty($recipe->yields) ? $recipe->yields : '';
             $recipe->serving_size = !empty($recipe->servings) ? $recipe->servings : '';
             $serves = !empty($recipe->servings) ? (int) $recipe->servings : '';
             $div = !empty($serves) ? $serves : 1;
             if (!empty($nutrition)) {
                 /** @noinspection PhpUnusedLocalVariableInspection */
                 foreach ($nutrition as $key => &$value) {
                     $value /= $div;
                 }
                 $nutrition->calories = round($nutrition->calories);
                 $nutrition->totalFat = round($nutrition->totalFat) . 'g';
                 $nutrition->saturatedFat = round($nutrition->saturatedFat) . 'g';
                 $nutrition->transFat = round($nutrition->transFat) . 'g';
                 $nutrition->polyunsaturatedFat = round($nutrition->polyunsaturatedFat);
                 $nutrition->monounsaturatedFat = round($nutrition->monounsaturatedFat);
                 $nutrition->unsaturatedFat = $nutrition->polyunsaturatedFat + $nutrition->monounsaturatedFat . 'g';
                 $nutrition->cholesterol = round($nutrition->cholesterol) . 'mg';
                 $nutrition->sodium = round($nutrition->sodium) . 'mg';
                 $nutrition->totalCarbohydrates = round($nutrition->totalCarbohydrates) . 'g';
                 $nutrition->dietaryFiber = round($nutrition->dietaryFiber) . 'g';
                 $nutrition->sugars = round($nutrition->sugars) . 'g';
                 $nutrition->protein = round($nutrition->protein) . 'g';
                 foreach ($nutrition as $key => &$value) {
                     if ($value == '0g' || $value == '0mg') {
                         $value = '';
                     }
                 }
             } else {
                 $nutrition = new stdClass();
                 $nutrition->calories = '';
                 $nutrition->totalFat = '';
                 $nutrition->saturatedFat = '';
                 $nutrition->transFat = '';
                 $nutrition->polyunsaturatedFat = '';
                 $nutrition->monounsaturatedFat = '';
                 $nutrition->unsaturatedFat = '';
                 $nutrition->cholesterol = '';
                 $nutrition->sodium = '';
                 $nutrition->totalCarbohydrates = '';
                 $nutrition->dietaryFiber = '';
                 $nutrition->sugars = '';
                 $nutrition->protein = '';
             }
             $result->recipe = $recipe;
             $result->recipe->nutrition = $nutrition;
             unset($result->recipe->prepTime);
             unset($result->recipe->cookTime);
             unset($result->recipe->totalTime);
             unset($result->recipe->yields);
             unset($result->recipe->servings);
             unset($result->recipe->title);
             unset($result->recipe->image);
             unset($result->recipe->ingredients);
             unset($result->recipe->directions);
             break;
             /**
              * Get me cooking
              */
         /**
          * Get me cooking
          */
         case 'gmc':
         case 'gmc_recipe':
             /**
              * If GMC is installed, use it to get ingredients, but turn off error reporting to stop it crashing
              */
             if (function_exists('print_ingredient_description')) {
                 error_reporting(0);
                 $gmcInstalled = true;
             } else {
                 $gmcInstalled = false;
             }
             $result->recipe = new stdClass();
             $post = get_post($postID);
             $result->recipe->recipe_title = html_entity_decode(get_the_title($postID), ENT_COMPAT, 'UTF-8');
             $result->recipe->author = get_post_meta($postID, 'gmc-source-name', true);
             $result->recipe->summary = get_post_meta($post->ID, "gmc-description", true);
             $thumbID = get_post_thumbnail_id($postID);
             $postThumb = $thumbID != 0 ? wp_get_attachment_image_src($thumbID, 'medium') : '';
             if (!empty($postThumb)) {
                 $result->recipe->recipe_image = $postThumb[0];
             }
             $prepHour = (int) get_post_meta($postID, "gmc-prep-time-hours", true);
             $prepMinute = (int) get_post_meta($postID, "gmc-prep-time-mins", true);
             $cookHour = (int) get_post_meta($postID, "gmc-cooking-time-hours", true);
             $cookMinute = (int) get_post_meta($postID, "gmc-cooking-time-mins", true);
             $result->recipe->prep_time = "PT{$prepHour}H{$prepMinute}M";
             $result->recipe->cook_time = "PT{$cookHour}H{$cookMinute}M";
             $mealTypes = wp_get_object_terms($postID, 'gmc_course');
             if ($mealTypes instanceof WP_Error) {
                 register_taxonomy('gmc_course', 'gmc_recipe');
                 $mealTypes = wp_get_object_terms($postID, 'gmc_course');
             }
             if (is_array($mealTypes) && count($mealTypes) > 0) {
                 $result->recipe->mealType = $mealTypes[0]->name;
             }
             $regions = wp_get_object_terms($postID, 'gmc_region');
             if ($regions instanceof WP_Error) {
                 register_taxonomy('gmc_region', 'gmc_recipe');
                 $regions = wp_get_object_terms($postID, 'gmc_region');
             }
             if (is_array($regions) && count($regions) > 0) {
                 $result->recipe->cuisine = $regions[0]->name;
             }
             $result->ingredients = array();
             $result->recipe->instructions = '';
             $currentSection = '';
             $steps = get_posts('post_status=publish&post_type=gmc_recipestep&nopaging=1&orderby=menu_order&order=ASC&post_parent=' . $postID);
             /** @var $step WP_Post */
             foreach ($steps as $step) {
                 if (!empty($step->post_content)) {
                     $section = get_post_meta($step->ID, 'gmc_stepgroup', true);
                     if (!empty($section) && $section != $currentSection) {
                         $result->recipe->instructions .= "!{$section}\n";
                         $currentSection = $section;
                     }
                     $content = preg_replace('/\\r?\\n/i', '[br]', $step->post_content);
                     $thumbID = get_post_thumbnail_id($step->ID);
                     if ($thumbID) {
                         $postThumb = wp_get_attachment_image_src($thumbID, 'medium');
                         if ($postThumb) {
                             $content .= '[br][img src="' . $postThumb[0] . '" width="' . $postThumb[1] . '" height="' . $postThumb[2] . '"]';
                         }
                     }
                     $result->recipe->instructions .= $content . "\n";
                 }
             }
             $result->recipe->instructions = rtrim($result->recipe->instructions, "\n");
             $ingredients = get_posts('post_status=publish&post_type=gmc_recipeingredient&nopaging=1&orderby=menu_order&order=ASC&post_parent=' . $postID);
             $currentSection = '';
             /** @var $ingredient WP_Post */
             foreach ($ingredients as $ingredient) {
                 $section = get_post_meta($ingredient->ID, "gmc-ingredientgroup", true);
                 if (!empty($section) && $section != $currentSection) {
                     $result->ingredients[] = "!{$section}";
                     $currentSection = $section;
                 }
                 if ($gmcInstalled) {
                     /** @noinspection PhpUndefinedFunctionInspection */
                     $iLine = trim(print_ingredient_description($ingredient));
                 } else {
                     $quantity = get_post_meta($ingredient->ID, "gmc-ingredientquantity", true);
                     $measurement = get_post_meta($ingredient->ID, 'gmc-ingredientmeasurement', true);
                     $title = $ingredient->post_title;
                     $iLine = trim("{$quantity} {$measurement} {$title}");
                 }
                 if (!empty($iLine)) {
                     $result->ingredients[] = $iLine;
                 }
             }
             /**
              * Try to convert HTML in notes into something EasyRecipe will understand
              */
             $notes = preg_replace_callback('%<(strong|em)>(.*?)</\\1>%', array($this, 'notesConversion'), $post->post_content);
             $notes = preg_replace('%<a ([^>]+)>(.*?)</a>%i', '[url $1]$2[/url]', $notes);
             $result->recipe->notes = strip_tags($notes);
             $result->recipe->yield = $servings = get_post_meta($post->ID, "gmc-nr-servings", true);
             $nutrition = new stdClass();
             if (get_post_meta($postID, "gmc_has_nutrition", true)) {
                 $result->recipe->serving_size = get_post_meta($post->ID, "gmc_gda_servings", true);
                 $nutrition->calories = get_post_meta($post->ID, "gmc_nutrition_kcal_serving", true);
                 if ($nutrition->calories != '') {
                     $nutrition->calories *= 1000;
                 }
                 $nutrition->totalFat = round(get_post_meta($post->ID, "gmc_nutrition_fat_total_serving", true)) . 'g';
                 $nutrition->saturatedFat = round(get_post_meta($post->ID, "gmc_nutrition_fat_sat_serving", true)) . 'g';
                 $nutrition->sodium = round(get_post_meta($post->ID, "gmc_nutrition_salt_sod_serving", true)) . 'mg';
                 $nutrition->totalCarbohydrates = round(get_post_meta($post->ID, "gmc_nutrition_carb_total_serving", true)) . 'g';
                 $nutrition->dietaryFiber = round(get_post_meta($post->ID, "gmc_nutrition_fibre_serving", true)) . 'g';
                 $nutrition->sugars = round(get_post_meta($post->ID, "gmc_nutrition_carb_sugar_serving", true)) . 'g';
                 $nutrition->protein = round(get_post_meta($post->ID, "gmc_nutrition_protein_serving", true)) . 'g';
             }
             $result->recipe->nutrition = $nutrition;
             break;
         case 'kitchebug':
             break;
     }
     return $result;
 }