/** * Get a sitemap's last modified date using either the log or filesystem * * @since 1.3.0 */ private function _get_sitemap_lastmod($sitemap_name) { if (!empty($this->sitemap_logs[$sitemap_name])) { // there's a log entry in db, take last modified date from it in // Unix timestamp format return $this->sitemap_logs[$sitemap_name]; } $sitemap_file = bwp_gxs_get_filename($sitemap_name); if ($filemtime = @filemtime($sitemap_file)) { // if we can get a last modified Unix timestamp from the // filesystem, use that one as a last resort return $filemtime; } // all fail, no lastmod should be display return false; }
/** * Get a sitemap's last modified date using either the log or filesystem * * @since 1.3.0 */ private function _get_sitemap_lastmod($sitemap_name) { global $bwp_gxs; // try to find last modified timestamp from a log entry in db if ($sitemap_log = $bwp_gxs->get_sitemap_logger()->get_sitemap_log_item($sitemap_name)) { return $sitemap_log->get_local_timestamp(); } // if we can get a last modified Unix timestamp from the filesystem, // use that one as a last resort $sitemap_file = bwp_gxs_get_filename($sitemap_name); if ($filemtime = @filemtime($sitemap_file)) { return $filemtime; } // all fail, no lastmod should be display return false; }
/** * Locates correct sitemap module to serve requested sitemap * * @access private */ private function _load_sitemap_module($module, $sub_module = '') { $success = false; // can we successfully serve the sitemap? $module_found = false; // do we have a sitemap module as requested $module_loaded = false; $module = stripslashes($module); $sub_module = stripslashes($sub_module); $part = 0; $module_name = ''; // the final module name used to generate requested sitemap // a full sitemap name consists of a module and a sub-module including // any split part (`_part1`, `_part2`, etc.) if any $sitemap_name = !empty($sub_module) ? $module . '_' . $sub_module : $module; if (!self::_is_bwp_sitemap($sitemap_name)) { // not a BWP sitemap, return this handle to WordPress return false; } // make sure we're on the canonical domain to avoid styling issue $this->_canonical_redirect($sitemap_name); if ('yes' == $this->options['enable_sitemap_split_post'] && (preg_match('/_part([0-9]+)$/i', $sub_module, $matches) || preg_match('/part([0-9]+)$/i', $sub_module, $matches))) { // Check whether or not splitting is enabled and the sub_module has a // 'part' part, if so we strip the part from sub-module name $sub_module = str_replace($matches[0], '', $sub_module); // save the requested part for later use $part = (int) $matches[1]; } $modules = $this->_build_sitemap_modules(); if ('sitemapindex' != $sitemap_name && isset($modules[$module])) { // the currently requested sitemap is not the sitemapindex, and a // sitemap module is available $module_found = true; if (!empty($sub_module)) { // a sub-module is being requested, and found if (in_array($sub_module, $modules[$module])) { $module_name = $module . '_' . $sub_module; } else { $module_found = false; } } else { $module_name = $module; } } else { if ('sitemapindex' == $sitemap_name) { // this is the sitemapindex, use sitemapindex sitemap module $module_found = true; $module_name = 'sitemapindex'; } } if (!$module_found) { // no module is available to handle requested sitemap $message = sprintf(__('Requested sitemap (<em>%s.xml</em>) ' . 'was not found or not enabled.', $this->domain), $sitemap_name); // @since 1.3.0 log a notice instead of an error $this->log_notice($message); $this->commit_logs(); // @since 1.3.0 return this handle to WordPress return false; } $this->_init_sitemap_generation(); if ($this->_load_sitemap_from_cache($module_name, $sitemap_name)) { // if sitemap can be loaded from cache, no need to do anything else exit; } // load the base module so other modules can extend it require_once dirname(__FILE__) . '/class-bwp-gxs-module.php'; // global module data for later use $this->module_data = array('module' => $module, 'sub_module' => $sub_module, 'module_key' => $module_name, 'module_name' => $module_name, 'module_part' => $part, 'part' => $part, 'sitemap_name' => $sitemap_name); if ('sitemapindex' != $sitemap_name) { // generating a regular sitemap $module_file = ''; // path to module file if (!empty($sub_module)) { // try generating the sitemap using a sub-module if (!empty($this->module_map[$sub_module])) { // this module is mapped to use another module, no need to // update global module data $module_name = $module . '_' . $this->module_map[$sub_module]; } $module_file = $this->_get_module_file($module_name, $sitemap_name, true); } if (empty($module_file)) { // try again with parent module, no need to update global module data $module_name = $module; $module_file = $this->_get_module_file($module_name, $sitemap_name); } if (empty($module_file)) { // no luck, let WordPress handles this page // reach here if gxs debug is off return false; } include_once $module_file; $class_name = 'BWP_GXS_MODULE_' . str_replace('-', '_', $module_name); if (class_exists($class_name)) { $module_object = new $class_name(); $module_object->set_module_data($this->module_data); $module_object->set_current_time(); $module_object->build_sitemap_data(); $module_data = $module_object->get_data(); switch ($module_object->get_type()) { case 'url': $success = $this->_generate_sitemap($module_data); break; case 'news': $success = $this->_generate_news_sitemap($module_data); break; case 'index': $success = $this->_generate_sitemap_index($module_data); break; } $module_loaded = true; } } else { if ('sitemapindex' == $sitemap_name) { $module_file = $this->_get_module_file($module_name, $sitemap_name); include_once $module_file; $class_name = 'BWP_GXS_MODULE_INDEX'; if (class_exists($class_name)) { $this->_prepare_sitemap_modules(); // this should fill $this->requested_modules $module_object = new $class_name($this->requested_modules); $module_object->set_module_data($this->module_data); $module_object->set_current_time(); $module_object->build_sitemap_data(); $success = $this->_generate_sitemap_index($module_object->get_data()); $module_loaded = true; } } } $module_filename = $module_name . '.php'; if (!$module_loaded) { // required module class can not be found so not loaded, this // should issue a WP die with 500 internal server error response code $this->log_error(sprintf(__('There is no class named <strong>%s</strong> ' . 'in the module file <strong>%s</strong>.', $this->domain), $class_name, $module_filename), true, 500); } if ($success == true) { // sitemap has been generated and is valid $this->_append_sitemap_stats(); $lastmod = $this->_cache_sitemap(); $lastmod = $lastmod ? $lastmod : time(); $expires = self::_format_header_time($lastmod + $this->cache_time); // send proper headers $this->_send_headers(array('lastmod' => self::_format_header_time($lastmod), 'expires' => $expires, 'etag' => md5($expires . bwp_gxs_get_filename($sitemap_name)))); // display the requested sitemap $this->_display_sitemap(); $success_message = $this->_is_using_custom_module ? __('Successfully generated <em>%s.xml</em> using custom module file <em>%s</em>.', $this->domain) : __('Successfully generated <em>%s.xml</em> using module file <em>%s</em>.', $this->domain); $this->log_success(sprintf($success_message, $sitemap_name, $module_filename)); $this->log_sitemap($sitemap_name); $this->commit_logs(); exit; } else { // @since 1.3.0 commit logs and issue a WP die with 500 internal // server response code $this->commit_logs(); $this->log_error(sprintf(__('An unknown error occurred when generating <em>%s</em> ' . 'using module file <em>%s</em>. Try again later.', $this->domain), $sitemap_name, $module_filename), true, 500); exit; } }
/** * Gets current cache status for the requested sitemap * * @since BWP GXS 1.3.0 * @access public * @return bool|string false if cache is invalid * '304' if http cache can be used * '200' if file cache must be used */ public function get_cache_status($module_name, $sitemap_name) { global $bwp_gxs; $this->module_name = $module_name; $this->sitemap_name = $sitemap_name; $this->cache_file = bwp_gxs_get_filename($sitemap_name); if (!@is_readable($this->cache_file)) { return false; } return $this->_check_cache(); }
/** * Locates correct sitemap module to serve requested sitemap * * @access private */ private function _load_sitemap_module($module, $sub_module = '') { $success = false; // can we successfully serve the sitemap? $module_found = false; // do we have a sitemap module as requested $module = stripslashes($module); $sub_module = stripslashes($sub_module); $part = 0; $module_name = ''; // the final module name used to generate requested sitemap // a full sitemap name consists of a module and a sub-module including // any split part (`_part1`, `_part2`, etc.) if any $sitemap_name = !empty($sub_module) ? $module . '_' . $sub_module : $module; if (!self::_is_bwp_sitemap($sitemap_name)) { // not a BWP sitemap, return this handle to WordPress return false; } // make sure we're on the canonical domain to avoid styling issue $this->_canonical_redirect($sitemap_name); if ('yes' == $this->options['enable_sitemap_split_post'] && (preg_match('/_part([0-9]+)$/i', $sub_module, $matches) || preg_match('/part([0-9]+)$/i', $sub_module, $matches))) { // Check whether or not splitting is enabled and the sub_module has a // 'part' part, if so we strip the part from sub-module name $sub_module = str_replace($matches[0], '', $sub_module); // save the requested part for later use $part = (int) $matches[1]; } $modules = $this->_build_sitemap_modules(); if ('sitemapindex' != $sitemap_name && isset($modules[$module])) { // the currently requested sitemap is not the sitemapindex, and a // sitemap module is available $module_found = true; if (!empty($sub_module)) { // a sub-module is being requested, and found if (in_array($sub_module, $modules[$module])) { $module_name = $module . '_' . $sub_module; } else { $module_found = false; } } else { $module_name = $module; } } else { if ('sitemapindex' == $sitemap_name) { // this is the sitemapindex, use sitemapindex sitemap module $module_found = true; $module_name = 'sitemapindex'; } } if (!$module_found) { // no module is available to handle requested sitemap $message = sprintf(__('Requested sitemap (<em>%s.xml</em>) ' . 'was not found or not enabled.', $this->domain), $sitemap_name); // @since 1.3.0 log a notice instead of an error $this->log_notice($message); $this->commit_logs(); // @since 1.3.0 return this handle to WordPress return false; } $this->_init_sitemap_generation(); if ($this->_load_sitemap_from_cache($module_name, $sitemap_name)) { // if sitemap can be loaded from cache, no need to do anything else exit; } // global module data for later use $this->module_data = array('module' => $module, 'sub_module' => $sub_module, 'module_key' => $module_name, 'module_name' => $module_name, 'module_part' => $part, 'part' => $part, 'sitemap_name' => $sitemap_name); if ('sitemapindex' != $sitemap_name) { // generating a regular sitemap $module_file = ''; // path to module file if (!empty($sub_module)) { // try generating the sitemap using a sub-module if (!empty($this->module_map[$sub_module])) { // this module is mapped to use another module, no need to // update global module data $module_name = $module . '_' . $this->module_map[$sub_module]; } $module_file = $this->_get_module_file($module_name, $sitemap_name, true); } if (empty($module_file)) { // try again with parent module, no need to update global module data $module_name = $module; $module_file = $this->_get_module_file($module_name, $sitemap_name); } if (empty($module_file)) { // no luck, let WordPress handles this page // reach here if gxs debug is off return false; } include_once $module_file; $class_name = 'BWP_GXS_MODULE_' . str_replace('-', '_', $module_name); if (class_exists($class_name)) { $module_object = new $class_name(); $module_object->set_module_data($this->module_data); $module_object->set_current_time(); $module_object->build_sitemap_data(); $this->sitemap = $this->create_sitemap_from_module($module_object); } } else { if ('sitemapindex' == $sitemap_name) { $module_file = $this->_get_module_file($module_name, $sitemap_name); include_once $module_file; $class_name = 'BWP_GXS_MODULE_INDEX'; if (class_exists($class_name)) { $this->_prepare_sitemap_modules(); // this should fill $this->requested_modules $module_object = new $class_name($this->requested_modules); $module_object->set_module_data($this->module_data); $module_object->set_current_time(); $module_object->build_sitemap_data(); $this->sitemap = $this->create_sitemap_from_module($module_object); } } } $module_filename = $module_name . '.php'; // no sitemap was created, this is due to a missing module // should issue a WP DIE with 500 internal server error response code if (!$this->sitemap) { $this->log_error(sprintf(__('There is no class named <strong>%s</strong> ' . 'in the module file <strong>%s</strong>.', $this->domain), $class_name, $module_filename), true, 500); } if ($this->sitemap->has_items()) { // append sitemap stats $this->sitemap->append("\n\n" . $this->_get_credit())->append("\n\n" . $this->_get_sitemap_stats()); $lastmod = $this->_cache_sitemap(); $lastmod = $lastmod ? $lastmod : time(); $expires = self::_format_header_time($lastmod + $this->cache_time); // send proper headers $this->_send_headers(array('lastmod' => self::_format_header_time($lastmod), 'expires' => $expires, 'etag' => md5($expires . bwp_gxs_get_filename($sitemap_name)))); // display the requested sitemap $this->_display_sitemap(); $success_message = $this->_is_using_custom_module ? __('Successfully generated <em>%s.xml</em> using custom module file <em>%s</em>.', $this->domain) : __('Successfully generated <em>%s.xml</em> using module file <em>%s</em>.', $this->domain); $this->log_success(sprintf($success_message, $sitemap_name, $module_filename)); $this->log_sitemap($sitemap_name); $this->commit_logs(); exit; } else { // if output is empty we log it so the user knows what's going on, // and should die accordingly $error_message = sprintf(__('<em>%s.xml</em> does not have any item.', $this->domain), $this->module_data['sitemap_name']); $module_label = $this->_get_module_label($this->module_data['module'], $this->module_data['sub_module']); $module_guide = 'google_news' != $this->module_data['sub_module'] ? __('Enable/disable sitemaps via <em>BWP Sitemaps >> XML Sitemaps</em>.', $this->domain) : ''; $error_message_module = $module_label ? ' ' . sprintf(__('There are no public <em>%s</em>.', $this->domain) . " {$module_guide}", $module_label) : ' ' . $module_guide; $error_message_admin = $this->module_data['sitemap_name'] == 'sitemapindex' ? ' ' . __('Please make sure that you have at least one sitemap enabled ' . 'in <em>BWP Sitemaps >> XML Sitemaps >> Sitemaps to generate</em>.', $this->domain) : $error_message_module; // issue a WP DIE with 404 not found response code // this is equivalent to calling "exit" $this->log_error($error_message . $error_message_admin, true, 404); } }