JezK
Edit File: loader.php
<?php /** * Loader. * * @package surerank * @since 0.0.1 */ namespace SureRank; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } use SureRank\Inc\Abilities\Abilities_Registrar; use SureRank\Inc\Admin\Admin_Notice; use SureRank\Inc\Admin\Attachment; use SureRank\Inc\Admin\BulkActions; use SureRank\Inc\Admin\BulkEdit; use SureRank\Inc\Admin\Dashboard; use SureRank\Inc\Admin\Delete_Data_Checkbox; use SureRank\Inc\Admin\Onboarding; use SureRank\Inc\Admin\Rest_Site_Health; use SureRank\Inc\Admin\Review_Notice; use SureRank\Inc\Admin\Search_Console_Widget; use SureRank\Inc\Admin\Seo_Bar; use SureRank\Inc\Admin\Seo_Popup; use SureRank\Inc\Admin\Site_Health; use SureRank\Inc\Admin\Sync; use SureRank\Inc\Admin\Update_Timestamp; use SureRank\Inc\Ajax\Ajax; use SureRank\Inc\Ajax\Save_Endpoints; use SureRank\Inc\Analytics\Analytics; use SureRank\Inc\Analyzer\PostAnalyzer; use SureRank\Inc\Analyzer\TermAnalyzer; use SureRank\Inc\Analyzer\UserAnalyzer; use SureRank\Inc\API\Analyzer; use SureRank\Inc\API\Api_Init; use SureRank\Inc\API\Headless; use SureRank\Inc\API\Headless_Sitemap; use SureRank\Inc\API\Rest_Fields; use SureRank\Inc\BatchProcess\Process; use SureRank\Inc\Cli\Cli; use SureRank\Inc\Frontend\Archives; use SureRank\Inc\Frontend\Archives_Meta; use SureRank\Inc\Frontend\Author; use SureRank\Inc\Frontend\Canonical; use SureRank\Inc\Frontend\Common; use SureRank\Inc\Frontend\Content_Seo; use SureRank\Inc\Frontend\Crawl_Optimization; use SureRank\Inc\Frontend\Facebook; use SureRank\Inc\Frontend\Feed; use SureRank\Inc\Frontend\Hentry; use SureRank\Inc\Frontend\Meta_Data; use SureRank\Inc\Frontend\Meta_Tag_Injection; use SureRank\Inc\Frontend\Product; use SureRank\Inc\Frontend\Robots; use SureRank\Inc\Frontend\Seo_Popup as Seo_Popup_Frontend; use SureRank\Inc\Frontend\Single; use SureRank\Inc\Frontend\Special_Page; use SureRank\Inc\Frontend\Taxonomy; use SureRank\Inc\Frontend\Title; use SureRank\Inc\Frontend\Twitter; use SureRank\Inc\Functions\Compat; use SureRank\Inc\Functions\Cron; use SureRank\Inc\Functions\Defaults; use SureRank\Inc\Functions\Get; use SureRank\Inc\Functions\Helper; use SureRank\Inc\Functions\Modified_Date_Lock; use SureRank\Inc\Functions\Update; use SureRank\Inc\GoogleSearchConsole\Auth; use SureRank\Inc\GoogleSearchConsole\Url_Inspection; use SureRank\Inc\Lib\Surerank_Nps_Survey; use SureRank\Inc\Modules\Ai_Auth\Init as Ai_Auth_Init; use SureRank\Inc\Modules\Content_Generation\Init as Content_Generation_Init; use SureRank\Inc\Modules\EmailReports\Init as EmailReports_Init; use SureRank\Inc\Modules\Fix_Seo_Checks\Init as Fix_Seo_Checks_Init; use SureRank\Inc\Modules\Knowledge_Graph\Init as Knowledge_Graph_Init; use SureRank\Inc\Modules\Nudges\Init as Nudges_Init; use SureRank\Inc\Nps_Notice; use SureRank\Inc\Routes; use SureRank\Inc\Schema\Schemas; use SureRank\Inc\Sitemap\Checksum; use SureRank\Inc\Sitemap\Invalidator; use SureRank\Inc\Sitemap\Xml_Sitemap; use SureRank\Inc\ThirdPartyIntegrations\Init as Integrations_Init; /** * Plugin_Loader * * @since 1.0.0 */ class Loader { /** * Instance * * @access private * @var object Class Instance. * @since 1.0.0 */ private static $instance; /** * Constructor * * @since 1.0.0 */ public function __construct() { spl_autoload_register( [ $this, 'autoload' ] ); add_action( 'plugins_loaded', [ $this, 'load_routes' ], 10 ); add_action( 'init', [ $this, 'load_textdomain' ], 10 ); add_action( 'init', [ Url_Inspection::class, 'register_meta_keys' ], 11 ); add_action( 'init', [ $this, 'load_nps' ], 99 ); // Disable the NPS survey entirely (code is kept, just never shown). add_filter( 'surerank_disable_nps_survey', '__return_true' ); add_action( 'init', [ $this, 'setup' ], 999 ); add_action( 'init', [ $this, 'flush_rules' ], 999 ); add_action( 'wp_loaded', [ $this, 'track_cron_run' ], 0 ); add_action( 'wp_loaded', [ \SureRank\Inc\Functions\Cache::class, 'maybe_upgrade' ], 0 ); add_action( 'wp_loaded', [ \SureRank\Inc\Upgrades\Author_Email_Cleanup::class, 'maybe_run' ], 0 ); register_activation_hook( SURERANK_FILE, [ $this, 'activation' ] ); register_deactivation_hook( SURERANK_FILE, [ $this, 'deactivation' ] ); add_filter( 'plugin_row_meta', [ $this, 'add_meta_links' ], 10, 2 ); add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 ); add_filter( 'plugin_action_links_' . SURERANK_BASE, [ $this, 'add_pro_nudge_link' ] ); add_filter( 'body_class', [ $this, 'add_body_class' ] ); // Map custom SureRank capabilities to primitive WordPress capabilities. add_filter( 'map_meta_cap', [ $this, 'map_meta_cap' ], 10, 4 ); // Remove this after the translation error is fixed. add_filter( 'doing_it_wrong_trigger_error', [ $this, 'suppress_translation_error' ], 10, 4 ); // Prevent Query Monitor from collecting the error. add_action( 'doing_it_wrong_run', [ $this, 'prevent_qm_collection' ], 5, 3 ); } /** * Enqueue required classes after plugins loaded. * * @since 0.0.1 * @return void */ public function setup(): void { do_action( 'surerank_before_load_components' ); $this->load_core_components(); $this->load_environment_components(); do_action( 'surerank_after_load_components' ); } /** * Prevent Query Monitor from collecting textdomain errors. * * @param string $function_name The function that was called. * @param string $message The error message. * @param string $version The version. * @return void * @since 1.7.3 */ public function prevent_qm_collection( $function_name, $message, $version ): void { if ( $function_name === '_load_textdomain_just_in_time' && strpos( $message, 'surerank' ) !== false ) { // Remove Query Monitor's action temporarily. if ( class_exists( '\QM_Collectors' ) ) { $collector = \QM_Collectors::get( 'doing_it_wrong' ); $callback = is_object( $collector ) ? [ $collector, 'action_doing_it_wrong_run' ] : null; if ( is_callable( $callback ) ) { remove_action( 'doing_it_wrong_run', $callback, 10 ); // Re-add it after this specific error. add_action( 'shutdown', static function() use ( $callback ): void { if ( ! has_action( 'doing_it_wrong_run', $callback ) ) { add_action( 'doing_it_wrong_run', $callback, 10, 3 ); } }, -1 ); } } } } /** * Suppress translation error. * * @param bool $status Status. * @param string $function_name Function name. * @param string $message Message. * @param string $version Version. * * @return bool * @since 1.7.3 */ public function suppress_translation_error( $status, $function_name, $message, $version ) { if ( $function_name === '_load_textdomain_just_in_time' && strpos( $message, 'surerank' ) !== false ) { return false; } return $status; } /** * Load routes. * * @since 0.0.1 * @return void */ public function load_routes() { do_action( 'surerank_before_load_routes' ); Abilities_Registrar::get_instance(); Routes::get_instance(); Invalidator::get_instance(); Analytics::get_instance(); Admin_Notice::get_instance(); Review_Notice::get_instance(); Delete_Data_Checkbox::get_instance(); do_action( 'surerank_after_load_routes' ); } /** * Initiator * * @since 1.0.0 * @return object initialized object of class. */ public static function get_instance() { if ( null === self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Autoload classes. * * @param string $class class name. * @since 1.0.0 * @return void */ public function autoload( $class ) { if ( 0 !== strpos( $class, __NAMESPACE__ ) ) { return; } $class_to_load = $class; $filename = preg_replace( [ '/^' . __NAMESPACE__ . '\\\/', '/([a-z])([A-Z])/', '/_/', '/\\\/' ], [ '', '$1-$2', '-', DIRECTORY_SEPARATOR ], $class_to_load ); if ( is_string( $filename ) ) { $filename = strtolower( $filename ); $file = SURERANK_DIR . $filename . '.php'; // if the file readable, include it. if ( is_readable( $file ) ) { require_once $file; } } } /** * Load Plugin Text Domain. * This will load the translation textdomain depending on the file priorities. * 1. Global Languages /wp-content/languages/surerank/ folder * 2. Local directory /wp-content/plugins/surerank/languages/ folder * * @since 1.0.0 * @return void */ public function load_textdomain() { // Default languages directory. $lang_dir = SURERANK_DIR . 'languages/'; /** * Filters the languages directory path to use for plugin. * * @param string $lang_dir The languages directory path. */ $lang_dir = apply_filters( 'surerank_languages_directory', $lang_dir ); $get_locale = get_user_locale(); $locale = apply_filters( 'plugin_locale', $get_locale, 'surerank' ); //phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- wordpress hook $mofile = sprintf( '%1$s-%2$s.mo', 'surerank', $locale ); // Setup paths to current locale file. $mofile_global = WP_LANG_DIR . '/plugins/' . $mofile; $mofile_local = $lang_dir . $mofile; if ( file_exists( $mofile_global ) ) { // Look in global /wp-content/languages/surerank/ folder. load_textdomain( 'surerank', $mofile_global ); } elseif ( file_exists( $mofile_local ) ) { // Look in local /wp-content/plugins/surerank/languages/ folder. load_textdomain( 'surerank', $mofile_local ); } } /** * Activation Hook * * @since 1.0.0 * @return void */ public function activation() { Update::option( 'surerank_flush_required', 1 ); Update::option( 'surerank_redirect_on_activation', 'yes' ); // Only schedule the sitemap cron in cron mode; auto mode (default) // builds on the fly. ensure_cron_scheduled() also self-corrects per // request if the mode changes later. if ( \SureRank\Inc\Sitemap\Generation_Mode::cron_prebuild_enabled() ) { Cron::get_instance()->schedule_sitemap_generation(); } } /** * Deactivation Hook * * @since 1.0.0 * @return void */ public function deactivation() { Update::option( 'surerank_flush_required', 1 ); Cron::get_instance()->unschedule_sitemap_generation(); Checksum::get_instance()->clear_checksum(); Compat::teardown(); delete_option( 'surerank_cron_test_ok' ); delete_option( 'surerank_last_cron_run' ); } /** * Record a timestamp on every cron request so Helper::are_crons_available() * can detect server-side cron when DISABLE_WP_CRON or ALTERNATE_WP_CRON is set. * * @since 1.7.5 * @return void */ public function track_cron_run(): void { if ( ! defined( 'DOING_CRON' ) || ! DOING_CRON ) { return; } $now = time(); $last_run = (int) get_option( 'surerank_last_cron_run', 0 ); // Throttle writes to once per minute. if ( $last_run > 0 && ( $now - $last_run ) < MINUTE_IN_SECONDS ) { return; } update_option( 'surerank_last_cron_run', $now, false ); } /** * Flush if settings is updated * * @since 1.0.0 * @return void */ public function flush_rules() { if ( Get::option( 'surerank_flush_required' ) ) { Helper::flush(); delete_option( 'surerank_flush_required' ); } } /** * Add meta links to the plugin row (under description). * * @param array<int,string> $links Array of plugin meta links. * @param string $file Plugin file path. * @return array<int,string> Modified plugin meta links. */ public function add_meta_links( array $links, string $file ): array { if ( SURERANK_BASE === $file ) { $stars = ''; for ( $indx = 0; $indx < 5; $indx++ ) { $stars .= '<span class="dashicons dashicons-star-filled" style="color: #ffb900; font-size: 16px; width: 16px; height: 16px; line-height: 1.2;" aria-hidden="true"></span>'; } $links[] = sprintf( '<a href="%s" target="_blank" rel="noopener noreferrer" aria-label="%s" role="button">%s</a>', esc_url( 'https://wordpress.org/support/plugin/surerank/reviews/#new-post' ), esc_attr__( 'Rate our plugin', 'surerank' ), $stars ); } return $links; } /** * Add Settings link to plugin action links. * * @param array<string,string> $links Array of plugin action links. * @param string $file Plugin file path. * @return array<string,string> Modified plugin action links. * @since 1.6.3 */ public function add_settings_link( array $links, string $file ): array { if ( SURERANK_BASE === $file ) { ob_start(); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=surerank' ) ); ?>"> <?php echo esc_html__( 'Settings', 'surerank' ); ?> </a> <?php $settings_link_html = ob_get_clean(); $plugin_links = apply_filters( 'surerank_plugin_action_links', [ 'surerank_settings' => $settings_link_html, ] ); $links = array_merge( $plugin_links, $links ); } return $links; } /** * Add Pro nudge link to plugin action links. * * @param array<string,string> $links Array of plugin action links. * @return array<string,string> Modified plugin action links. * @since 1.6.3 */ public function add_pro_nudge_link( array $links ): array { // Check if Pro plugin is installed using WordPress function. if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $all_plugins = get_plugins(); $pro_installed = false; foreach ( $all_plugins as $plugin_path => $plugin_data ) { if ( strpos( $plugin_path, '/surerank-pro.php' ) !== false ) { $pro_installed = true; break; } } if ( ! $pro_installed ) { $pricing_url = add_query_arg( [ 'utm_source' => 'surerank-free', 'utm_medium' => 'plugin-list', 'utm_campaign' => 'plugin-screen', ], 'https://surerank.com/pricing/' ); ob_start(); ?> <a href="<?php echo esc_url( $pricing_url ); ?>" target="_blank" rel="noreferrer" style="color: #4330D2; font-weight: 700;"> <?php echo esc_html__( 'Get SureRank Pro', 'surerank' ); ?> </a> <?php $link_html = ob_get_clean(); if ( false !== $link_html ) { $links['surerank_pro'] = trim( $link_html ); } } return $links; } /** * Load NPS Survey if conditions are met. */ public function load_nps(): void { if ( $this->should_load_nps_survey() ) { Surerank_Nps_Survey::get_instance(); Nps_Notice::get_instance(); } } /** * Add body class - Assign version class for reference. * * @param array<int, string> $classes body classes. * @since 1.6.2 * @return array<int, string> */ public function add_body_class( $classes ) { $classes[] = 'surerank-' . SURERANK_VERSION; return $classes; } /** * Map custom SureRank capabilities to primitive WordPress capabilities. * * This maps the custom capabilities used in SureRank to standard WordPress * capabilities so that role management works correctly. The Pro plugin can * override this to provide more granular control. * * @since 1.7.2 * @param array<string> $caps Primitive capabilities required by the user. * @param string $cap Capability being checked. * @param int $user_id User ID. * @param array<int> $args Additional arguments. * @return array<string> Mapped capabilities. */ public function map_meta_cap( $caps, $cap, $user_id, $args ) { // Map custom SureRank capabilities to manage_options for free version. // Pro plugin can override this filter for proper role management. $surerank_caps = [ 'surerank_content_setting', 'surerank_global_setting', ]; if ( in_array( $cap, $surerank_caps, true ) ) { // Map to manage_options for the free version. return [ 'manage_options' ]; } return $caps; } /** * Load core components that are always needed. * * @return void */ private function load_core_components(): void { $core_components = [ Defaults::class, Schemas::class, Crawl_Optimization::class, Hentry::class, Api_Init::class, Headless::class, Headless_Sitemap::class, Rest_Fields::class, Compat::class, Modified_Date_Lock::class, Cron::class, Checksum::class, Integrations_Init::class, Knowledge_Graph_Init::class, Attachment::class, Analyzer::class, PostAnalyzer::class, TermAnalyzer::class, UserAnalyzer::class, Auth::class, Sync::class, Ai_Auth_Init::class, Content_Generation_Init::class, EmailReports_Init::class, Fix_Seo_Checks_Init::class, Knowledge_Graph_Init::class, Nudges_Init::class, Process::class, Cli::class, ]; $this->load_components( $core_components ); // Seo_Bar needed in admin page views and AJAX (for inline-save column rendering). if ( is_admin() ) { $this->load_components( [ Seo_Bar::class ] ); } } /** * Load environment-specific components. * * @return void */ private function load_environment_components(): void { if ( is_admin() ) { $this->load_admin_components(); } else { $this->load_frontend_components(); } } /** * Load admin-specific components. * * @return void */ private function load_admin_components(): void { /** * Filter the required capability to load SureRank admin components. * Allows Pro plugin to grant access based on role capabilities. * * @since 1.6.4 * @param string $capability Required capability. Default: 'manage_options'. */ $required_capability = apply_filters( 'surerank_admin_components_capability', 'manage_options' ); if ( ! current_user_can( $required_capability ) ) { return; } $admin_components = [ Seo_Popup::class, Update_Timestamp::class, Dashboard::class, Onboarding::class, BulkActions::class, BulkEdit::class, Ajax::class, Save_Endpoints::class, Rest_Site_Health::class, Search_Console_Widget::class, Site_Health::class, ]; $this->load_components( $admin_components ); } /** * Load frontend-specific components. * * @return void */ private function load_frontend_components(): void { $frontend_components = [ Single::class, Product::class, Taxonomy::class, Archives_Meta::class, Author::class, Title::class, Canonical::class, Common::class, Robots::class, Facebook::class, Twitter::class, Special_Page::class, Feed::class, Seo_Popup_Frontend::class, Meta_Data::class, Content_Seo::class, Meta_Tag_Injection::class, Xml_Sitemap::class, Archives::class, ]; // Add SEO metabox on the frontend for logged in users. if ( is_user_logged_in() ) { $frontend_components[] = Seo_Popup::class; } $this->load_components( $frontend_components ); } /** * Check if NPS Survey should be loaded. * * @return bool True if should load. */ private function should_load_nps_survey(): bool { return class_exists( 'SureRank\Inc\Lib\Surerank_Nps_Survey' ) && ! apply_filters( 'surerank_disable_nps_survey', false ); } /** * Load an array of components. * * @param array<string> $components Component class names. * @return void */ private function load_components( array $components ): void { foreach ( $components as $component ) { $component::get_instance(); } } } /** * Kicking this off by calling 'get_instance()' method */ Loader::get_instance();
https://personalfinance365.com/post-type-page-sitemap-1.xml
2026-09-27T18:16:25+05:30
https://personalfinance365.com/post-type-post-sitemap-1.xml
2026-09-27T18:16:25+05:30
https://personalfinance365.com/post-type-post-sitemap-2.xml
2026-09-27T18:16:25+05:30
https://personalfinance365.com/taxonomy-type-category-sitemap-1.xml
2026-09-27T18:16:25+05:30
https://personalfinance365.com/taxonomy-type-post_tag-sitemap-1.xml
2026-09-27T18:16:25+05:30
https://personalfinance365.com/taxonomy-type-post_tag-sitemap-2.xml
2026-09-27T18:16:25+05:30