/** * Get the post, extract the recipe and combine with the current style and output it * * @param integer $postID The post ID to print * @param integer $recipeIX The zero based index of the recipe in the post */ public function printRecipe($postID, $recipeIX) { /** @var $wpdb wpdb */ global $wpdb; $settings = EasyRecipePlusSettings::getInstance(); /** * Be paranoid and force the ID to an integer */ $postID = (int) $postID; $q = "SELECT * FROM {$wpdb->posts} WHERE ID = {$postID}"; $post = $wpdb->get_row($q); if (!$post) { return; } /** * Process the [br] shortcodes and remove the spurious <br>'s that wp_auto() inserts */ $content = str_replace("[br]", "<br>", $post->post_content); $content = preg_replace('%</div>\\s*</p></div>%im', '</div></div>', $content); $content = $this->plugin->possiblyConvert($postID, $post->post_type, $content); $postDOM = new EasyRecipePlusDocument($content); if (!$postDOM->isEasyRecipe) { return; } /** * If the post is formatted already then it came from the Object cache (?) * If that's the case we need to re-read the original */ if ($postDOM->isFormatted) { $post = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "posts WHERE ID = {$postID}"); $content = str_replace("[br]", "<br>", $post->post_content); $content = preg_replace('%</div>\\s*</p></div>%im', '</div></div>', $content); $content = $this->plugin->possiblyConvert($postID, '', $content); $postDOM = new EasyRecipePlusDocument($content); if (!$postDOM->isEasyRecipe) { return; } } if (isset($_GET['style'])) { $styleName = $_GET['style']; } else { $styleName = $settings->printStyle; } // $printStyleData = call_user_func(array($this->stylesClass, 'getStyleData'), $styleName, $settings->get('customTemplates'), true); $printStyleData = EasyRecipePlusStyles::getStyleData($styleName, $settings->customTemplates, true); if (get_locale() != 'en_US') { EasyRecipePlusTemplate::setTranslate('easyrecipe'); } /** * Fix possibly broken times in older posts * Fix the Cholesterol oops in early versions */ if ($postDOM->recipeVersion < '3') { $postDOM->fixTimes("preptime"); $postDOM->fixTimes("cooktime"); $postDOM->fixTimes("duration"); $postDOM->setParentValueByClassName("cholestrol", $settings->lblCholesterol, "Cholestrol"); } $postDOM->setSettings($settings); $data = new stdClass(); $data->hasRating = false; $data->convertFractions = $settings->convertFractions; $settings->getLabels($data); $data->hasLinkback = $settings->allowLink; $data->title = $post->post_title; $data->blogname = get_option("blogname"); $data->recipeurl = get_permalink($post->ID); $data->customCSS = $this->plugin->getCSS('Print'); $data->extraPrintHeader = $settings->extraPrintHeader; $data->easyrecipeURL = EasyRecipePlus::$EasyRecipePlusUrl; $recipe = $postDOM->getRecipe($recipeIX); $photoURL = $postDOM->findPhotoURL($recipe); $data->hasPhoto = !empty($photoURL); $data->jqueryjs = self::JQUERYJS; $data->jqueryuijs = self::JQUERYUIJS; $data->jqueryuicss = self::JQUERYUICSS; if (current_user_can('edit_posts')) { $data->isAdmin = true; $data->formatDialog = $this->plugin->getFormatDialog($printStyleData, true); $cssLink = '<link href="' . EasyRecipePlus::$EasyRecipePlusUrl . '/css/%s?version=' . EasyRecipePlus::$pluginVersion . '" rel="stylesheet" type="text/css"/>'; $jsLink = '<script type="text/javascript" src="' . EasyRecipePlus::$EasyRecipePlusUrl . '/js/%s?version=' . EasyRecipePlus::$pluginVersion . '"></script>'; $data->formatCSS = sprintf($cssLink, 'easyrecipe-format-min.css'); $data->formatJS = sprintf($jsLink, 'easyrecipe-format-min.js'); } else { $data->formatDialog = ''; $data->printJS = '<script type="text/javascript" src="' . EasyRecipePlus::$EasyRecipePlusUrl . '/js/easyrecipe-print-min.js?version=' . EasyRecipePlus::$pluginVersion . '"></script>'; } $data->style = $styleName; if ($data->style[0] == '_') { $style = substr($data->style, 1); $data->css = "/easyrecipe-printstyle"; $templateFile = $settings->customTemplates . "/printstyles/{$style}/style.html"; } else { $data->css = EasyRecipePlus::$EasyRecipePlusUrl . "/printstyles/{$data->style}"; $templateFile = EasyRecipePlus::$EasyRecipePlusDir . "/printstyles/{$data->style}/style.html"; } $data->css .= "/style.css?version=" . EasyRecipePlus::$pluginVersion . ".{$printStyleData->version}"; $template = new EasyRecipePlusTemplate($templateFile); /** * Brain dead IE shows "friendly" error pages (i.e. it's non-compliant) so we need to force a 200 */ header("HTTP/1.1 200 OK"); /** * Set the character encoding explicitly */ $charset = get_bloginfo('charset'); header("Content-Type:text/html; charset={$charset}"); echo $postDOM->formatRecipe($recipe, $template, $data); flush(); exit; }
/** * Explicitly allow the itemprop, datetime and link attributes otherwise WP will strip them * * @param $postID */ function publishFuturePost($postID) { global $allowedposttags; $post = get_post($postID); if (strpos($post->post_content, 'easyrecipe') !== false) { $allowedposttags['time'] = array('itemprop' => true, 'datetime' => true); $allowedposttags['link'] = array('itemprop' => true, 'href' => true); $this->settings = EasyRecipePlusSettings::getInstance(); if ($this->settings->enableFooderific) { $this->fdPostStatusChanged('publish', 'future', $post); } } }
/** * Scan all posts for recipes if $postID == 0, or a single post if $postID <> 0 and send basic details to fooderific * If it's a sitewide scan, data is batched up to minimize network traffic * * @param int $postID Scan all posts if this is zero, else a single post if not */ function scanRun($postID = 0) { /* @var $wpdb wpdb */ global $wpdb; $settings = EasyRecipePlusSettings::getInstance(); $this->delay = $settings->scanDelay; $this->getRecipePlugins(); /** * Read each published post (or the specific post if we're processing a specific post's update) and if it contains a recipe, then shoot the details off to fooderific.com * We're not interested in attachments or revisions. Also probably not interested in other types, but we don't know about custom post types so process anything else */ if ($postID != 0) { $q = "SELECT * FROM {$wpdb->prefix}posts WHERE ID = '{$postID}' AND post_type <> 'attachment' AND post_type <> 'revision'"; $this->batchSize = 1; } else { $q = "SELECT * FROM {$wpdb->prefix}posts WHERE post_status = 'publish' AND post_type <> 'attachment' AND post_type <> 'revision' ORDER BY ID DESC"; $this->batchSize = self::BATCHSIZE; $settings->lastScanStarted = time(); $settings->update(); } $posts = $wpdb->get_results($q); /** * If this is a scan, notify fooderific that we're starting */ if ($postID == 0) { $data = new stdClass(); $data->action = 'start'; $data->wpurl = get_bloginfo("wpurl"); $data->count = count($posts); $args = array('body' => array('data' => serialize($data))); wp_remote_post(self::FOODERIFIC_URL, $args); } $this->nPostsSent = 0; $this->results = array(); /** * Flag that we're running in scan so we don't schedule another scan on top of this one * Don't hold for longer than SCAN_TIMEOUT seconds so if the process crashes or has some kind of problem, it's not going to stop another scan later */ set_transient(self::FOODERIFIC_SCAN, 'run', self::SCAN_TIMEOUT); /** * Also reset the run time limit to SCAN_TIMEOUT seconds so unintended loops or horribly slow processing doesn't tie this up forever */ @set_time_limit(self::SCAN_TIMEOUT); foreach ($posts as $post) { $this->processPost($post); } if (count($this->results) > 0) { $this->nPostsSent += count($this->results); $args = array('body' => array('data' => serialize($this->results))); wp_remote_post(self::FOODERIFIC_URL, $args); $this->results = array(); } /** * If this was a scan, notify fooderific that we're done */ if ($postID == 0) { $data = new stdClass(); $data->action = 'stop'; $data->wpurl = get_bloginfo("wpurl"); $data->count = $this->nPostsSent; $args = array('body' => array('data' => serialize($data))); wp_remote_post(self::FOODERIFIC_URL, $args); } delete_transient(self::FOODERIFIC_SCAN); }
/** * Save a reference to the global settings * Add a reference to this instance in an array indexed by postID so that, given a postID, we can figure out which instance to use * * @param EasyRecipePlus $plugin */ function __construct(EasyRecipePlus $plugin) { $this->plugin = $plugin; $this->settings = EasyRecipePlusSettings::getInstance(); }
/** * Gets details about the site and installed plugins etc * * @return stdClass Object containing diagnostics data */ function get() { global $wp_version; /** @var wpdb $wpdb */ global $wpdb; /** * Get the php info. Save anything already in the output buffer, just in case it's relevant for the site's output in show() */ $this->existingOP = ob_get_clean(); ob_start(); phpinfo(); $phpinfo = ob_get_contents(); ob_end_clean(); preg_match('%<body>(.*)</body>%si', $phpinfo, $regs); $this->phpinfo = $regs[1]; /** @noinspection PhpUndefinedClassInspection */ $this->pluginURL = EasyRecipePlus::$EasyRecipePlusUrl; /** @noinspection PhpUndefinedClassInspection */ $this->pluginDir = EasyRecipePlus::$EasyRecipePlusDir; /** * Get our own settings. This is the same for all Easy Plugins and individualised by the build processs */ /** @noinspection PhpUndefinedClassInspection */ $settings = EasyRecipePlusSettings::getInstance(); /** * Don't send any settings (passwords etc) that we really have no business knowing */ if (isset($settings->privateSettings)) { foreach ($settings->privateSettings as $privateSetting) { if (isset($settings->{$privateSetting})) { unset($settings->{$privateSetting}); } } unset($settings->privateSettings); } $this->settings = $settings; $capabilities = ""; get_currentuserinfo(); $user = $GLOBALS['current_user']; if (isset($user->caps)) { foreach ($user->caps as $cap => $allowed) { if ($allowed) { $capabilities .= "{$cap},"; } } } $this->wpCapabilities = rtrim($capabilities, ","); $this->wpVersion = $wp_version; $this->wpSiteURL = site_url(); $this->wpHomeURL = home_url(); $this->wpMultiSite = is_multisite() ? 'Yes' : 'No'; $this->mysqlVersion = $wpdb->db_version(); $this->gmtOffset = get_option('gmt_offset'); $this->timezone = get_option('timezone_string'); if ($wp_version < '3.4') { /** @noinspection PhpDeprecationInspection */ $themeData = get_theme_data(get_stylesheet_directory() . "/style.css"); $this->wpTheme = $themeData["Name"]; $this->wpThemeVersion = $themeData["Version"]; $this->wpThemeURL = $themeData["URI"]; } else { $themeData = wp_get_theme(); $this->wpTheme = $themeData->get("Name"); $this->wpThemeVersion = $themeData->get("Version"); $this->wpThemeURL = $themeData->get("ThemeURI"); } if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $plugins = get_plugins(); foreach ($plugins as $pluginFile => $null) { $plugins[$pluginFile]["active"] = is_plugin_active($pluginFile) ? "Active" : "Inactive"; } usort($plugins, array($this, "sortPlugins")); $this->PLUGINS = array(); foreach ($plugins as $plugin) { $item = new stdClass(); $item->name = $plugin["Title"]; $item->active = $plugin["active"]; $item->version = $plugin["Version"]; $item->url = $plugin["PluginURI"]; $this->PLUGINS[] = $item; } }
/** * Update all taxonomies. * This should only ever be called from a cron job scheduled by EasyRecipePlusScheduler because it can potentially take quite a while */ function updateAll() { /** @var wpdb $wpdb */ global $wpdb; /** * If we are already running, don't do it again */ if ($this->scheduler->isRunning()) { return; } /** * Set as running * Set a "timeout" of 10 minutes. This will prevent it being re-run for 10 minutes if the current run terminates abnormally for any reason */ $this->scheduler->setRunning(10 * 60); $q = "SELECT ID FROM {$wpdb->posts} WHERE post_type NOT IN ('attachment','index','nav_menu_item')"; $postIDs = $wpdb->get_col($q); $this->countTerms['cuisine'] = array(); $this->countTerms['course'] = array(); foreach ($postIDs as $postID) { $post = WP_Post::get_instance($postID); $this->update($post, false); } /** * Update any term counts that we may have adjusted */ if (count($this->countTerms['cuisine']) > 0) { wp_update_term_count_now(array_unique(array_keys($this->countTerms['cuisine'])), 'cuisine'); } if (count($this->countTerms['course']) > 0) { wp_update_term_count_now(array_unique(array_keys($this->countTerms['course'])), 'course'); } /** * Mark the taxonomies as having been created */ $settings = EasyRecipePlusSettings::getInstance(); $settings->taxonomiesCreated = true; $settings->update(); /** * Mark this job as complete */ $this->scheduler->terminate(); }