update
This commit is contained in:
87
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Controller.php
vendored
Normal file
87
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Controller.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG\Vendor;
|
||||
|
||||
use GRIM_SG\Settings;
|
||||
|
||||
class Controller {
|
||||
public static $slug = 'xml-sitemap-generator-for-google';
|
||||
|
||||
public function get_settings() {
|
||||
$settings = new Settings();
|
||||
$saved_options = get_option( self::$slug );
|
||||
|
||||
// TODO Remove this after Refactoring
|
||||
if ( is_array( $saved_options ) ) {
|
||||
$saved_options = (object) $saved_options;
|
||||
}
|
||||
|
||||
if ( ! empty( $saved_options ) ) {
|
||||
foreach ( $settings as $key => &$option ) {
|
||||
if ( isset( $saved_options->{$key} ) ) {
|
||||
if ( in_array( $key, array( 'cpt', 'taxonomies' ), true ) ) {
|
||||
if ( is_array( $saved_options->{$key} ) ) {
|
||||
foreach ( $saved_options->{$key} as $inner_key => $value ) {
|
||||
$option[ $inner_key ] = is_array( $value )
|
||||
? (object) $value // TODO Remove this after Refactoring
|
||||
: $value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$option = ( is_object( $option ) && is_array( $saved_options->{$key} ) )
|
||||
? (object) $saved_options->{$key} // TODO Remove this after Refactoring
|
||||
: $saved_options->{$key};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Custom Post Types
|
||||
* @return string[]|\WP_Post_Type[]
|
||||
*/
|
||||
public function get_cpt( $output = 'names' ) {
|
||||
$args = array(
|
||||
'public' => true,
|
||||
'_builtin' => false,
|
||||
);
|
||||
|
||||
return get_post_types( $args, $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Taxonomy Types
|
||||
* @return string[]|\WP_Taxonomy[]
|
||||
*/
|
||||
public function get_taxonomy_types( $output = 'names' ) {
|
||||
$args = array(
|
||||
'public' => true,
|
||||
'show_ui' => true,
|
||||
);
|
||||
|
||||
return get_taxonomies( $args, $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Allowed Post Types List
|
||||
* @return array
|
||||
*/
|
||||
public function get_post_types_list( $post_types, $settings ) {
|
||||
foreach ( $post_types as $key => $post_type ) {
|
||||
if ( isset( $settings->{$post_type}->include ) && ! $settings->{$post_type}->include ) {
|
||||
unset( $post_types[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->get_cpt() as $cpt ) {
|
||||
if ( ! empty( $settings->cpt[ $cpt ] ) && ! empty( $settings->cpt[ $cpt ]->include ) ) {
|
||||
$post_types[] = $cpt;
|
||||
}
|
||||
}
|
||||
|
||||
return $post_types;
|
||||
}
|
||||
}
|
||||
97
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Migration.php
vendored
Normal file
97
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Migration.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG\vendor;
|
||||
|
||||
class Migration extends Controller {
|
||||
const DB_VERSION_KEY = 'sgg_version';
|
||||
|
||||
/**
|
||||
* Database updates and callbacks that need to be run per Migration version.
|
||||
*/
|
||||
private $migrations = array(
|
||||
'1.8.4' => array(
|
||||
'migrate_settings_dynamic_created_objects',
|
||||
),
|
||||
'1.9.9' => array(
|
||||
'migrate_video_settings',
|
||||
),
|
||||
);
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'admin_init', array( $this, 'run_migrations' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all the necessary migrations.
|
||||
*/
|
||||
public function run_migrations() {
|
||||
$current_db_version = get_option( self::DB_VERSION_KEY, '' );
|
||||
|
||||
if ( version_compare( $current_db_version, GRIM_SG_VERSION, '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->migrations as $version => $update_callbacks ) {
|
||||
if ( version_compare( $current_db_version, $version, '<' ) ) {
|
||||
foreach ( $update_callbacks as $update_callback ) {
|
||||
$this->{$update_callback}();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self::update_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Version in Database
|
||||
*/
|
||||
public static function update_version() {
|
||||
update_option( self::DB_VERSION_KEY, GRIM_SG_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Dynamic created CPT and Taxonomies to array
|
||||
*/
|
||||
public function migrate_settings_dynamic_created_objects() {
|
||||
$settings = get_option( self::$slug, array() );
|
||||
|
||||
if ( ! empty( $settings ) ) {
|
||||
$settings->cpt = array();
|
||||
$settings->taxonomies = array();
|
||||
|
||||
foreach ( $this->get_cpt() as $cpt ) {
|
||||
if ( ! empty( $settings->{$cpt} ) ) {
|
||||
$settings->cpt[ $cpt ] = $settings->{$cpt};
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $this->get_taxonomy_types() as $taxonomy ) {
|
||||
if ( ! empty( $settings->{$taxonomy} ) ) {
|
||||
$settings->taxonomies[ $taxonomy ] = $settings->{$taxonomy};
|
||||
}
|
||||
}
|
||||
|
||||
update_option( Controller::$slug, $settings );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Video Sitemap Settings
|
||||
*/
|
||||
public function migrate_video_settings() {
|
||||
$settings = get_option( self::$slug, array() );
|
||||
|
||||
if ( ! empty( $settings ) ) {
|
||||
$settings->enable_video_api_cache = $settings->enable_youtube_cache ?? true;
|
||||
|
||||
update_option( Controller::$slug, $settings );
|
||||
}
|
||||
|
||||
// Migrate YouTube Data to Video API Data
|
||||
$youtube_data = get_option( 'sgg_youtube_data', array() );
|
||||
|
||||
if ( ! empty( $youtube_data ) ) {
|
||||
update_option( 'sgg_video_api_data', $youtube_data );
|
||||
}
|
||||
}
|
||||
}
|
||||
35
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/PTSettings.php
vendored
Normal file
35
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/PTSettings.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG;
|
||||
|
||||
class PTSettings {
|
||||
public $include = true;
|
||||
public $priority = 3;
|
||||
public $frequency = 'weekly';
|
||||
public $google_news = false;
|
||||
public $image_sitemap = true;
|
||||
public $video_sitemap = true;
|
||||
|
||||
// Frequencies
|
||||
public static $ALWAYS = 'always';
|
||||
public static $HOURLY = 'hourly';
|
||||
public static $DAILY = 'daily';
|
||||
public static $WEEKLY = 'weekly';
|
||||
public static $MONTHLY = 'monthly';
|
||||
public static $YEARLY = 'yearly';
|
||||
public static $NEVER = 'never';
|
||||
|
||||
/**
|
||||
* DefaultSettings constructor.
|
||||
*
|
||||
* @param int $priority
|
||||
* @param int $frequency
|
||||
*/
|
||||
public function __construct( $priority = 3, $frequency = 1, $google_news = false, $image_sitemap = false, $video_sitemap = false ) {
|
||||
$this->priority = $priority;
|
||||
$this->frequency = $frequency;
|
||||
$this->google_news = $google_news;
|
||||
$this->image_sitemap = $image_sitemap;
|
||||
$this->video_sitemap = $video_sitemap;
|
||||
}
|
||||
}
|
||||
17
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/QueryBuilder.php
vendored
Normal file
17
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/QueryBuilder.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG\Vendor;
|
||||
|
||||
class QueryBuilder {
|
||||
/**
|
||||
* Run SQL Query
|
||||
*
|
||||
* @param $sql
|
||||
* @return array|null|object
|
||||
*/
|
||||
public static function run_query( $sql ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_results( $sql );
|
||||
}
|
||||
}
|
||||
130
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Settings.php
vendored
Normal file
130
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/Settings.php
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG;
|
||||
|
||||
use GRIM_SG\Vendor\Controller;
|
||||
|
||||
class Settings extends Controller {
|
||||
// Global Settings
|
||||
public $sitemap_url = 'sitemap.xml';
|
||||
public $html_sitemap_url = 'sitemap.html';
|
||||
public $enable_sitemap = true;
|
||||
public $links_per_page = 1000;
|
||||
public $enable_html_sitemap = false;
|
||||
public $sitemap_to_robots = true;
|
||||
public $enable_indexnow = true;
|
||||
public $sitemap_view = 'sitemap-index';
|
||||
|
||||
// Sitemap Data Settings
|
||||
public $home;
|
||||
public $page;
|
||||
public $post;
|
||||
public $archive;
|
||||
public $archive_older;
|
||||
public $authors;
|
||||
public $media;
|
||||
public $exclude_posts;
|
||||
public $exclude_terms;
|
||||
public $include_only_terms;
|
||||
public $posts_priority;
|
||||
public $custom_sitemaps = array();
|
||||
public $additional_pages = array();
|
||||
public $cpt = array();
|
||||
public $taxonomies = array();
|
||||
|
||||
// Google News Data Settings
|
||||
public $enable_google_news = false;
|
||||
public $google_news_old_posts = false;
|
||||
public $google_news_name = '';
|
||||
public $google_news_url = 'google-news.xml';
|
||||
public $google_news_keywords = '';
|
||||
public $google_news_stocks = false;
|
||||
public $google_news_exclude;
|
||||
public $google_news_exclude_terms;
|
||||
public $google_news_include_only_terms;
|
||||
|
||||
// Media Sitemap Data Settings
|
||||
public $enable_image_sitemap = false;
|
||||
public $enable_video_sitemap = false;
|
||||
public $image_sitemap_url = 'image-sitemap.xml';
|
||||
public $video_sitemap_url = 'video-sitemap.xml';
|
||||
public $hide_image_previews = false;
|
||||
public $hide_image_sitemap_xsl = false;
|
||||
public $hide_video_sitemap_xsl = false;
|
||||
public $image_mime_types = array(
|
||||
'image/jpeg' => true,
|
||||
'image/png' => true,
|
||||
'image/gif' => true,
|
||||
'image/bmp' => true,
|
||||
'image/webp' => true,
|
||||
'image/avif' => true,
|
||||
);
|
||||
public $youtube_api_key = '';
|
||||
public $vimeo_api_key = '';
|
||||
public $exclude_broken_images = false;
|
||||
public $include_featured_images = false;
|
||||
public $include_woo_gallery = false;
|
||||
|
||||
// Cache Settings
|
||||
public $enable_cache = false;
|
||||
public $cache_timeout = 24;
|
||||
public $cache_timeout_period = 3600;
|
||||
public $clear_cache_on_save_post = false;
|
||||
public $enable_video_api_cache = true;
|
||||
public $disable_media_sitemap_cache = false;
|
||||
|
||||
public $minimize_sitemap = false;
|
||||
public $hide_branding = true;
|
||||
public $enable_cronjob = false;
|
||||
public $cronjob_runtime = 'daily';
|
||||
public $colors = array(
|
||||
'header_background_color' => '#82a745',
|
||||
'header_text_color' => '#ffffff',
|
||||
'sitemap_background_color' => '#ecf4db',
|
||||
'sitemap_text_color' => '#444444',
|
||||
'sitemap_link_color' => '#2d89c7',
|
||||
'footer_text_color' => '#666666',
|
||||
);
|
||||
|
||||
/**
|
||||
* Settings constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->home = new PTSettings( 10, PTSettings::$DAILY );
|
||||
$this->page = new PTSettings( 6, PTSettings::$WEEKLY, false, true, true );
|
||||
$this->post = new PTSettings( 6, PTSettings::$MONTHLY, true, true, true );
|
||||
$this->archive = new PTSettings( 6, PTSettings::$DAILY );
|
||||
$this->archive_older = new PTSettings( 3, PTSettings::$YEARLY );
|
||||
$this->authors = new PTSettings( 3, PTSettings::$WEEKLY );
|
||||
$this->media = new PTSettings( 3, PTSettings::$WEEKLY );
|
||||
|
||||
// Media Pages are disabled by default
|
||||
$this->media->include = false;
|
||||
|
||||
foreach ( $this->get_cpt() as $cpt ) {
|
||||
$this->cpt[ $cpt ] = new PTSettings( 6, PTSettings::$MONTHLY );
|
||||
}
|
||||
|
||||
foreach ( $this->get_taxonomy_types() as $taxonomy ) {
|
||||
$this->taxonomies[ $taxonomy ] = new PTSettings( 3, PTSettings::$WEEKLY );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Default Settings
|
||||
* @param $option
|
||||
* @return PTSettings
|
||||
*/
|
||||
public function get_row_value( $option ) {
|
||||
$settings = new PTSettings();
|
||||
|
||||
$settings->include = isset( $_POST[ $option . '_include' ] ) ? sanitize_text_field( $_POST[ $option . '_include' ] ) : false;
|
||||
$settings->priority = isset( $_POST[ $option . '_priority' ] ) ? sanitize_text_field( $_POST[ $option . '_priority' ] ) : 0;
|
||||
$settings->frequency = isset( $_POST[ $option . '_frequency' ] ) ? sanitize_text_field( $_POST[ $option . '_frequency' ] ) : $settings->frequency;
|
||||
$settings->google_news = isset( $_POST[ $option . '_google_news' ] ) ? sanitize_text_field( $_POST[ $option . '_google_news' ] ) : 0;
|
||||
$settings->image_sitemap = isset( $_POST[ $option . '_image_sitemap' ] ) ? sanitize_text_field( $_POST[ $option . '_image_sitemap' ] ) : 0;
|
||||
$settings->video_sitemap = isset( $_POST[ $option . '_video_sitemap' ] ) ? sanitize_text_field( $_POST[ $option . '_video_sitemap' ] ) : 0;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
636
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/SitemapGenerator.php
vendored
Normal file
636
wp-content/plugins/xml-sitemap-generator-for-google/includes/vendor/SitemapGenerator.php
vendored
Normal file
@@ -0,0 +1,636 @@
|
||||
<?php
|
||||
|
||||
namespace GRIM_SG\Vendor;
|
||||
|
||||
use GRIM_SG\GoogleNews;
|
||||
use GRIM_SG\ImageSitemap;
|
||||
use GRIM_SG\MultilingualSitemap;
|
||||
use GRIM_SG\VideoSitemap;
|
||||
|
||||
class SitemapGenerator {
|
||||
public $sitemapFileName = 'sitemap.xml';
|
||||
|
||||
public $sitemapIndexFileName = 'sitemap-index.xml';
|
||||
|
||||
public $robotsFileName = 'robots.txt';
|
||||
|
||||
public $maxURLsPerSitemap = 50000;
|
||||
|
||||
public $createGZipFile = false;
|
||||
|
||||
private $baseURL;
|
||||
|
||||
private $searchEngines = array(
|
||||
array(
|
||||
'https://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=USERID&url=',
|
||||
'https://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap=',
|
||||
),
|
||||
'https://www.google.com/webmasters/tools/ping?sitemap=',
|
||||
'https://submissions.ask.com/ping?sitemap=',
|
||||
'https://www.bing.com/webmaster/ping.aspx?siteMap=',
|
||||
);
|
||||
|
||||
private $urls = array();
|
||||
|
||||
private $sitemaps;
|
||||
|
||||
private $sitemapIndex;
|
||||
|
||||
private $sitemapFullURL;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $baseURL You site URL, with / at the end.
|
||||
*/
|
||||
public function __construct( $baseURL ) {
|
||||
$this->baseURL = $baseURL;
|
||||
}
|
||||
|
||||
public function addUrls( $urls_array, $callback = 'addUrl', $template = 'sitemap' ) {
|
||||
if ( ! is_array( $urls_array ) ) {
|
||||
throw new \InvalidArgumentException( 'Array as argument should be given.' );
|
||||
}
|
||||
|
||||
if ( sgg_is_sitemap_index( $template ) ) {
|
||||
foreach ( $urls_array as $sitemap => $inner_urls ) {
|
||||
foreach ( $inner_urls as $url ) {
|
||||
$this->{$callback}( $url, $sitemap );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ( $urls_array as $url ) {
|
||||
$this->{$callback}( $url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to add single URL to Google News Sitemap.
|
||||
*/
|
||||
public function addNewsUrl( $item ) {
|
||||
$url = $item[0] ?? null;
|
||||
|
||||
$this->validateUrl( $url );
|
||||
|
||||
$tmp = array();
|
||||
$tmp['loc'] = $url;
|
||||
$tmp['publication_name'] = $item[1] ?? null;
|
||||
$tmp['language'] = $item[2] ?? null;
|
||||
$tmp['title'] = $item[3] ?? null;
|
||||
|
||||
if ( isset( $item[4] ) ) {
|
||||
$tmp['lastmod'] = $item[4];
|
||||
}
|
||||
|
||||
if ( sgg_pro_enabled() ) {
|
||||
$tmp['keywords'] = implode( ', ', apply_filters( 'sgg_news_keywords', array(), $item[5] ?? null ) );
|
||||
$tmp['stock_tickers'] = implode( ', ', apply_filters( 'sgg_news_stock_tickers', array(), $item[5] ?? null ) );
|
||||
}
|
||||
|
||||
$this->urls[] = $tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to add single URL to Sitemap.
|
||||
*/
|
||||
public function addMediaUrl( $item, $sitemap = null ) {
|
||||
$url = $item[0] ?? null;
|
||||
|
||||
$this->validateUrl( $url );
|
||||
|
||||
$tmp = array();
|
||||
$tmp['loc'] = $url;
|
||||
|
||||
if ( isset( $item[1] ) ) {
|
||||
$tmp['media'] = $item[1];
|
||||
}
|
||||
|
||||
if ( ! empty( $sitemap ) ) {
|
||||
$tmp['lastmod'] = gmdate( 'c' );
|
||||
$this->urls[ $sitemap ][] = $tmp;
|
||||
} else {
|
||||
$this->urls[] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to add single URL to Sitemap.
|
||||
*/
|
||||
public function addUrl( $item, $sitemap = null ) {
|
||||
$url = $item[0] ?? null;
|
||||
|
||||
$this->validateUrl( $url );
|
||||
|
||||
$tmp = array();
|
||||
$tmp['loc'] = $url;
|
||||
|
||||
if ( isset( $item[1] ) ) {
|
||||
$tmp['lastmod'] = $item[1];
|
||||
}
|
||||
if ( isset( $item[2] ) ) {
|
||||
$tmp['changefreq'] = $item[2];
|
||||
}
|
||||
if ( isset( $item[3] ) ) {
|
||||
$tmp['priority'] = $item[3];
|
||||
}
|
||||
|
||||
if ( ! empty( $sitemap ) ) {
|
||||
$this->urls[ $sitemap ][] = $tmp;
|
||||
} else {
|
||||
$this->urls[] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Sitemap Item URL
|
||||
*/
|
||||
public function validateUrl( $url ) {
|
||||
if ( null === $url ) {
|
||||
throw new \InvalidArgumentException( 'URL is mandatory. At least one argument should be given.' );
|
||||
}
|
||||
|
||||
$urlLenght = extension_loaded( 'mbstring' ) ? mb_strlen( $url ) : strlen( $url );
|
||||
if ( $urlLenght > 2048 ) {
|
||||
throw new \InvalidArgumentException(
|
||||
"URL lenght can't be bigger than 2048 characters.
|
||||
Note, that precise url length check is guaranteed only using mb_string extension.
|
||||
Make sure Your server allow to use mbstring extension."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sitemap in memory.
|
||||
*/
|
||||
public function createSitemap( $template = 'sitemap', $headers = array(), $is_xml = true ) {
|
||||
if ( ! isset( $this->urls ) ) {
|
||||
throw new \BadMethodCallException( 'To create sitemap, call addUrl or addUrls function first.' );
|
||||
}
|
||||
|
||||
if ( $this->maxURLsPerSitemap > 50000 ) {
|
||||
throw new \InvalidArgumentException( 'More than 50,000 URLs per single sitemap is not allowed.' );
|
||||
}
|
||||
|
||||
$settings = ( new Controller() )->get_settings();
|
||||
$stylesheet_template = sgg_maybe_remove_inner_suffix( $template );
|
||||
|
||||
$stylesheet_path = apply_filters( 'sitemap_xsl_template_path', 'sitemap-stylesheet.xsl' );
|
||||
$stylesheet_url = sgg_get_sitemap_url( "{$stylesheet_path}?template={$stylesheet_template}", "sitemap_xsl={$stylesheet_template}", false );
|
||||
$stylesheet_url = strtok( $stylesheet_url, '&' ); // remove & query string
|
||||
$is_sitemap_index = sgg_is_sitemap_index( $template, $settings );
|
||||
$is_media_template = in_array( $template, array( 'image-sitemap', 'video-sitemap' ), true );
|
||||
$is_index_template = $is_media_template || 'sitemap' === $template;
|
||||
|
||||
$sitemap_urls = $is_sitemap_index
|
||||
? $this->urls
|
||||
: array_chunk( $this->urls, $this->maxURLsPerSitemap );
|
||||
|
||||
foreach ( $sitemap_urls as $sitemap_key => $sitemap ) {
|
||||
$dom = $this->create_sitemap_dom( $stylesheet_url, $template, $settings );
|
||||
$urlset = $this->create_sitemap_urlset( $dom, $headers );
|
||||
|
||||
$dom->appendChild( $urlset );
|
||||
|
||||
foreach ( $sitemap as $url ) {
|
||||
$url_element = $dom->createElement( 'url' );
|
||||
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'loc', htmlspecialchars( $url['loc'], ENT_QUOTES, 'UTF-8' ) )
|
||||
);
|
||||
|
||||
if ( GoogleNews::$template === $template ) {
|
||||
if ( $settings->google_news_old_posts && GoogleNews::is_older_than_48h( $url['lastmod'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'lastmod', $url['lastmod'] )
|
||||
);
|
||||
} else {
|
||||
$news = $url_element->appendChild( $dom->createElement( 'news:news' ) );
|
||||
|
||||
if ( isset( $url['publication_name'] ) ) {
|
||||
$publication = $dom->createElement( 'news:publication' );
|
||||
$news->appendChild( $publication );
|
||||
|
||||
$publication->appendChild(
|
||||
$dom->createElement( 'news:name', esc_html( $url['publication_name'] ) )
|
||||
);
|
||||
$publication->appendChild(
|
||||
$dom->createElement( 'news:language', $url['language'] )
|
||||
);
|
||||
}
|
||||
if ( isset( $url['lastmod'] ) ) {
|
||||
$news->appendChild(
|
||||
$dom->createElement( 'news:publication_date', $url['lastmod'] )
|
||||
);
|
||||
}
|
||||
if ( isset( $url['title'] ) ) {
|
||||
$news->appendChild(
|
||||
$dom->createElement( 'news:title', esc_html( $url['title'] ) )
|
||||
);
|
||||
}
|
||||
if ( sgg_pro_enabled() ) {
|
||||
$news->appendChild(
|
||||
$dom->createElement( 'news:keywords', $url['keywords'] )
|
||||
);
|
||||
$news->appendChild(
|
||||
$dom->createElement( 'news:stock_tickers', $url['stock_tickers'] )
|
||||
);
|
||||
}
|
||||
}
|
||||
} elseif ( strpos( $template, ImageSitemap::$template ) !== false ) {
|
||||
if ( isset( $url['lastmod'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'lastmod', $url['lastmod'] )
|
||||
);
|
||||
} else {
|
||||
if ( ! empty( $url['media'] ) ) {
|
||||
foreach ( $url['media'] as $image ) {
|
||||
$image_element = $url_element->appendChild( $dom->createElement( 'image:image' ) );
|
||||
$image_element->appendChild(
|
||||
$dom->createElement( 'image:loc', $image )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ( strpos( $template, VideoSitemap::$template ) !== false ) {
|
||||
if ( isset( $url['lastmod'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'lastmod', $url['lastmod'] )
|
||||
);
|
||||
} else {
|
||||
if ( ! empty( $url['media'] ) ) {
|
||||
foreach ( $url['media'] as $video ) {
|
||||
$video_element = $url_element->appendChild( $dom->createElement( 'video:video' ) );
|
||||
$video_element->appendChild(
|
||||
$dom->createElement( 'video:thumbnail_loc', esc_url( $video['thumbnail'] ?? '' ) )
|
||||
);
|
||||
// Decode HTML entities first, then DOMDocument will handle XML escaping properly
|
||||
$video_title = html_entity_decode( $video['title'] ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8' );
|
||||
$video_element->appendChild(
|
||||
$dom->createElement( 'video:title', $video_title )
|
||||
);
|
||||
// Decode HTML entities first, then DOMDocument will handle XML escaping properly
|
||||
$video_description = html_entity_decode( $video['description'] ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8' );
|
||||
$video_element->appendChild(
|
||||
$dom->createElement( 'video:description', $video_description )
|
||||
);
|
||||
$video_element->appendChild(
|
||||
$dom->createElement( 'video:player_loc', esc_url( $video['player_loc'] ?? '' ) )
|
||||
);
|
||||
// Decode HTML entities first, then DOMDocument will handle XML escaping properly
|
||||
$video_duration = html_entity_decode( $video['duration'] ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8' );
|
||||
$video_element->appendChild(
|
||||
$dom->createElement( 'video:duration', $video_duration )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( isset( $url['lastmod'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'lastmod', $url['lastmod'] )
|
||||
);
|
||||
}
|
||||
if ( isset( $url['changefreq'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'changefreq', $url['changefreq'] )
|
||||
);
|
||||
}
|
||||
if ( isset( $url['priority'] ) ) {
|
||||
$url_element->appendChild(
|
||||
$dom->createElement( 'priority', $url['priority'] )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$urlset->appendChild( $url_element );
|
||||
|
||||
if ( $is_sitemap_index && $is_index_template ) {
|
||||
$this->sitemaps[ $sitemap_key ][] = array(
|
||||
'loc' => $url['loc'],
|
||||
'lastmod' => $url['lastmod'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! sgg_pro_enabled() || ! $settings->minimize_sitemap ) {
|
||||
$dom->formatOutput = true;
|
||||
}
|
||||
|
||||
if ( ! $is_index_template || ! $is_sitemap_index ) {
|
||||
$ready_sitemap = $dom->saveXML();
|
||||
|
||||
if ( $is_sitemap_index ) {
|
||||
$this->sitemaps[ $sitemap_key ][] = $ready_sitemap;
|
||||
$this->sitemaps[ $sitemap_key ]['lastmod'] = $url['lastmod'] ?? gmdate( 'c' );
|
||||
} else {
|
||||
$this->sitemaps[] = $ready_sitemap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( null === $this->sitemaps ) {
|
||||
$dom = $this->create_sitemap_dom( $stylesheet_url, $template, $settings );
|
||||
$urlset = $this->create_sitemap_urlset( $dom, $headers );
|
||||
|
||||
$dom->appendChild( $urlset );
|
||||
|
||||
$this->sitemaps[] = $dom->saveXML();
|
||||
}
|
||||
|
||||
if ( count( $this->sitemaps ) > 1000 ) {
|
||||
throw new \LengthException( 'Sitemap index can contains 1000 single sitemaps. Perhaps You trying to submit too many URLs.' );
|
||||
}
|
||||
|
||||
$is_media_index = $is_media_template && $is_sitemap_index;
|
||||
if ( ! empty( $settings->sitemap_view ) && ( ( 'sitemap' === $template && count( $this->sitemaps ) > 0 ) || $is_media_index ) ) {
|
||||
$stylesheet_url = sgg_get_sitemap_url( "{$stylesheet_path}?template=sitemap-index", 'sitemap_xsl=sitemap-index', false );
|
||||
$stylesheet_url = strtok( $stylesheet_url, '&' ); // remove & query string
|
||||
|
||||
$dom = $this->create_sitemap_dom( $stylesheet_url, $template, $settings );
|
||||
|
||||
$sitemapindex = $dom->createElement( 'sitemapindex' );
|
||||
$sitemapindex->setAttribute( 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance' );
|
||||
$sitemapindex->setAttribute( 'xsi:schemaLocation', 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd' );
|
||||
$sitemapindex->setAttribute( 'xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
|
||||
$dom->appendChild( $sitemapindex );
|
||||
|
||||
foreach ( $this->sitemaps as $sitemap_key => $sitemap ) {
|
||||
if ( ! empty( $sitemap ) && is_array( $sitemap ) ) {
|
||||
if ( 'page' === $sitemap_key && sgg_get_home_url_with_trailing_slash() === ( $sitemap[0]['loc'] ?? '' ) && 1 < count( $sitemap ) ) {
|
||||
$sitemap[0] = array(
|
||||
'loc' => $sitemap[0]['loc'],
|
||||
'lastmod' => max( $sitemap[0]['lastmod'] ?? '', $sitemap[1]['lastmod'] ?? '' ),
|
||||
);
|
||||
|
||||
if ( ! empty( $sitemap[1] ) ) {
|
||||
unset( $sitemap[1] );
|
||||
}
|
||||
|
||||
$sitemap = array_values( $sitemap );
|
||||
}
|
||||
|
||||
foreach ( $sitemap as $index => $url ) {
|
||||
$sitemap_element = $dom->createElement( 'sitemap' );
|
||||
$sitemap_type = $is_xml ? 'xml' : 'html';
|
||||
$default_number = $is_media_template ? 1 : '';
|
||||
$sitemap_number = 0 < $index ? intval( $index ) + 1 : $default_number;
|
||||
$page_param = 0 < $sitemap_number ? "&page={$sitemap_number}" : '';
|
||||
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement(
|
||||
'loc',
|
||||
esc_url( sgg_get_sitemap_url( "{$sitemap_key}-sitemap{$sitemap_number}.{$sitemap_type}", "sitemap_{$sitemap_type}=true&inner_sitemap={$sitemap_key}{$page_param}", false ) )
|
||||
)
|
||||
);
|
||||
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement( 'lastmod', $url['lastmod'] ?? gmdate( 'c' ) )
|
||||
);
|
||||
|
||||
$sitemapindex->appendChild( $sitemap_element );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $is_xml && 'sitemap' === $template ) {
|
||||
$additional_sitemaps = apply_filters( 'sgg_additional_index_sitemaps', $settings->custom_sitemaps ?? array() );
|
||||
|
||||
if ( $settings->enable_image_sitemap ) {
|
||||
$additional_sitemaps[] = array(
|
||||
'url' => sgg_get_sitemap_url( $settings->image_sitemap_url, 'image_sitemap' ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( $settings->enable_video_sitemap ) {
|
||||
$additional_sitemaps[] = array(
|
||||
'url' => sgg_get_sitemap_url( $settings->video_sitemap_url, 'video_sitemap' ),
|
||||
);
|
||||
}
|
||||
|
||||
foreach ( $additional_sitemaps as $additional_sitemap ) {
|
||||
$sitemap_element = $dom->createElement( 'sitemap' );
|
||||
$sitemap_url = ! empty( $additional_sitemap['url'] ) ? esc_url( $additional_sitemap['url'] ) : $additional_sitemap;
|
||||
|
||||
if ( ! is_string( $sitemap_url ) ) {
|
||||
continue;
|
||||
}
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement( 'loc', $sitemap_url )
|
||||
);
|
||||
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement(
|
||||
'lastmod',
|
||||
! empty( $additional_sitemap['lastmod'] ) ? $additional_sitemap['lastmod'] : gmdate( 'c' )
|
||||
)
|
||||
);
|
||||
|
||||
$sitemapindex->appendChild( $sitemap_element );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! sgg_pro_enabled() || ! $settings->minimize_sitemap ) {
|
||||
$dom->formatOutput = true;
|
||||
}
|
||||
|
||||
$this->sitemapFullURL = $this->baseURL . $this->sitemapIndexFileName;
|
||||
$this->sitemapIndex = array(
|
||||
$this->sitemapIndexFileName,
|
||||
$dom->saveXML(),
|
||||
);
|
||||
} else {
|
||||
if ( $this->createGZipFile ) {
|
||||
$this->sitemapFullURL = $this->baseURL . $this->sitemapFileName . '.gz';
|
||||
} else {
|
||||
$this->sitemapFullURL = $this->baseURL . $this->sitemapFileName;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->sitemaps[0] ) ) {
|
||||
$this->sitemaps[0] = array(
|
||||
$this->sitemapFileName,
|
||||
$this->sitemaps[0],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create Multilingual Sitemap in memory.
|
||||
*/
|
||||
public function createMultilingualSitemap( $urls = array(), $is_xml = true ) {
|
||||
if ( ! isset( $this->urls ) ) {
|
||||
throw new \BadMethodCallException( 'To create sitemap, call addUrl or addUrls function first.' );
|
||||
}
|
||||
|
||||
if ( $this->maxURLsPerSitemap > 50000 ) {
|
||||
throw new \InvalidArgumentException( 'More than 50,000 URLs per single sitemap is not allowed.' );
|
||||
}
|
||||
|
||||
$stylesheet_path = apply_filters( 'sitemap_xsl_template_path', 'sitemap-stylesheet.xsl' );
|
||||
$settings = ( new Controller() )->get_settings();
|
||||
|
||||
$dom = $this->create_sitemap_dom(
|
||||
sgg_get_sitemap_url( "{$stylesheet_path}?template=multilingual-sitemap", 'sitemap_xsl=sitemap-index', false ),
|
||||
'',
|
||||
$settings
|
||||
);
|
||||
|
||||
$sitemapindex = $dom->createElement( 'sitemapindex' );
|
||||
$sitemapindex->setAttribute( 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance' );
|
||||
$sitemapindex->setAttribute( 'xsi:schemaLocation', 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd' );
|
||||
$sitemapindex->setAttribute( 'xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
|
||||
$dom->appendChild( $sitemapindex );
|
||||
|
||||
foreach ( $urls as $url ) {
|
||||
$sitemap_element = $dom->createElement( 'sitemap' );
|
||||
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement(
|
||||
'loc',
|
||||
esc_url( $url )
|
||||
)
|
||||
);
|
||||
|
||||
$sitemap_element->appendChild(
|
||||
$dom->createElement( 'lastmod', gmdate( DATE_W3C ) )
|
||||
);
|
||||
|
||||
$sitemapindex->appendChild( $sitemap_element );
|
||||
}
|
||||
|
||||
if ( ! sgg_pro_enabled() || ! $settings->minimize_sitemap ) {
|
||||
$dom->formatOutput = true;
|
||||
}
|
||||
|
||||
$this->sitemapFullURL = $this->baseURL . $this->sitemapIndexFileName;
|
||||
$this->sitemapIndex = array(
|
||||
$this->sitemapIndexFileName,
|
||||
$dom->saveXML(),
|
||||
);
|
||||
}
|
||||
|
||||
public function create_sitemap_dom( $stylesheet_url, $template = '', $settings = null ) {
|
||||
$generator_info = 'sitemap-generator-url="https://wpgrim.com" sitemap-generator-version="' . GRIM_SG_VERSION . '"';
|
||||
|
||||
$dom = new \DOMDocument( '1.0', 'UTF-8' );
|
||||
|
||||
// Get settings if not provided
|
||||
if ( null === $settings ) {
|
||||
$settings = ( new Controller() )->get_settings();
|
||||
}
|
||||
|
||||
// Skip XSL stylesheet reference based on settings
|
||||
$is_index_sitemap = strpos( $stylesheet_url, 'sitemap-index' ) !== false;
|
||||
$skip_xsl = false;
|
||||
|
||||
if ( ! $is_index_sitemap ) {
|
||||
if ( strpos( $template, VideoSitemap::$template ) !== false ) {
|
||||
$skip_xsl = ! empty( $settings->hide_video_sitemap_xsl );
|
||||
} elseif ( strpos( $template, ImageSitemap::$template ) !== false ) {
|
||||
$skip_xsl = ! empty( $settings->hide_image_sitemap_xsl );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $skip_xsl ) {
|
||||
$dom->appendChild(
|
||||
$dom->createProcessingInstruction(
|
||||
'xml-stylesheet',
|
||||
'type="text/xsl" href="' . $stylesheet_url . '"'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$dom->appendChild( $dom->createComment( $generator_info ) );
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
public function create_sitemap_urlset( $dom, $headers = array() ) {
|
||||
$urlset = $dom->createElement( 'urlset' );
|
||||
|
||||
$urlset->setAttribute( 'xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
|
||||
if ( ! empty( $headers ) ) {
|
||||
foreach ( $headers as $key => $header ) {
|
||||
$urlset->setAttribute( $key, $header );
|
||||
}
|
||||
}
|
||||
|
||||
return $urlset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns created sitemaps as array of strings.
|
||||
* Use it You want to work with sitemap without saving it as files.
|
||||
* @return array of strings
|
||||
* @access public
|
||||
*/
|
||||
public function toArray() {
|
||||
if ( isset( $this->sitemapIndex ) ) {
|
||||
return array_merge( array( $this->sitemapIndex ), $this->sitemaps );
|
||||
} else {
|
||||
return $this->sitemaps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will print sitemaps.
|
||||
* @access public
|
||||
*/
|
||||
public function outputSitemap( $template, $is_xml, $inner_sitemap = null ) {
|
||||
add_filter( 'trp_stop_translating_page', '__return_true' );
|
||||
|
||||
ob_get_clean();
|
||||
|
||||
if ( $is_xml ) {
|
||||
header( 'Content-Type: text/xml; charset=utf-8' );
|
||||
} else {
|
||||
ob_start();
|
||||
}
|
||||
|
||||
if ( ! empty( $inner_sitemap ) && sgg_is_sitemap_index( $template ) && ! empty( $this->sitemaps[ $inner_sitemap ][0] ) ) {
|
||||
echo $this->sitemaps[ $inner_sitemap ][0];
|
||||
} else {
|
||||
if ( ! empty( $this->sitemapIndex[1] ) ) {
|
||||
$template = 'sitemap-index';
|
||||
echo $this->sitemapIndex[1];
|
||||
} else {
|
||||
echo $this->sitemaps[0][1] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $is_xml ) {
|
||||
$xml_source = ob_get_clean();
|
||||
|
||||
$xml = new \DOMDocument();
|
||||
$xml->loadXML( $xml_source );
|
||||
|
||||
ob_start();
|
||||
|
||||
load_template(
|
||||
GRIM_SG_PATH . '/templates/xsl/sitemap.php',
|
||||
false,
|
||||
compact( 'template', 'is_xml' )
|
||||
);
|
||||
|
||||
$xsl_content = ob_get_clean();
|
||||
|
||||
$xsl = new \DOMDocument();
|
||||
$xsl->loadXML( $xsl_content );
|
||||
|
||||
$proc = new \XSLTProcessor();
|
||||
$proc->importStyleSheet( $xsl );
|
||||
|
||||
$dom_tran_obj = $proc->transformToDoc( $xml );
|
||||
|
||||
foreach ( $dom_tran_obj->childNodes as $node ) {
|
||||
echo $dom_tran_obj->saveXML( $node ) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ( ob_get_contents() ) {
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user