ID ) ) { return true; } // Get current user roles. $user_roles = (array) $current_user->roles; // Merge fixed always-allowed and configurable allowed roles. $allowed_roles = array_merge( array( 'administrator', 'shop_manager' ), self::$settings['article']['allowed_roles'] ); // Check if any of user's roles are in the allowed list. return (bool) array_intersect( $user_roles, $allowed_roles ); } /** * Check if homepage uses Blog mode * * @return bool */ public static function is_homepage_blog_posts() { return is_home() && 'posts' === get_option( 'show_on_front', false ); } /** * Check if the current singular post type is enabled in plugin settings. * * @return bool */ public static function is_supported_singular_post_type() { self::init_settings(); $singular_post_type = self::get_singular_post_type(); return $singular_post_type && in_array( $singular_post_type, self::$settings['article']['post_types'], true ); } /** * Check if current queried request is on supported taxonomy page * * @return bool */ public static function is_supported_taxonomy() { self::init_settings(); $queried_object = get_queried_object(); return ( is_category() || is_tag() || is_tax() ) && isset( $queried_object->taxonomy ) && in_array( $queried_object->taxonomy, self::$settings['article']['taxonomies'], true ); } /** * Determine should we print site-wide code * or it should be replaced with homepage/article/taxonomy code. * * @param string $behavior Behavior for article specific code (replace/append). * @param string $code Article specific custom code. * @param string $post_type Post type of current article. * @param array $post_types Array of post types where article specific code is enabled. * @param boolean $is_taxonomy Indicate if current displayed page is taxonomy or not. * @return boolean Boolean that determine should site-wide code be printed (true) or not (false). */ public static function is_printable_sitewide_v1( $behavior = 'append', $code = '', $post_type = null, $post_types = array(), $is_taxonomy = false ) { // Always print if not replacing. if ( 'replace' !== $behavior ) { return true; } // If replacing but code is empty, still print sitewide. if ( empty( $code ) ) { return true; } // If replacing on non-supported post type, print sitewide. if ( ! $is_taxonomy && ! in_array( $post_type, $post_types, true ) ) { return true; } // Otherwise, don't print sitewide (it's being replaced). return false; } /** * Determine should we print site-wide code * or it should be replaced with homepage/article/taxonomy code. * * @param string $behavior Behavior for article specific code (replace/append). * @param string $code Article specific custom code. * @param string $post_type Post type of current article. * @param array $post_types Array of post types where article specific code is enabled. * @param boolean $is_taxonomy Indicate if current displayed page is taxonomy or not. * @return boolean Boolean that determine should site-wide code be printed (true) or not (false). */ public static function is_printable_sitewide( $behavior = 'append', $code = '', $post_type = null, $post_types = array(), $is_taxonomy = false ) { // Always print if not replacing. if ( 'replace' !== $behavior ) { return true; } // If replacing but code is empty, still print sitewide. if ( empty( $code ) ) { return true; } // Check if we're on homepage in blog mode. $is_homepage_blog_posts = self::is_homepage_blog_posts(); // On homepage with replace behavior and non-empty code, don't print sitewide. if ( $is_homepage_blog_posts ) { return false; } // On taxonomy with replace behavior and non-empty code, don't print sitewide. if ( $is_taxonomy ) { return false; } // If replacing on non-supported post type, print sitewide. if ( ! in_array( $post_type, $post_types, true ) ) { return true; } // We're on a supported post type with replace behavior and non-empty code. // Don't print sitewide (it's being replaced). return false; } /** * Function to check if code should be added on paged homepage in Blog mode * * @param bool $is_homepage_blog_posts If current page is blog homepage. * @param array $settings Plugin settings (optional, uses static if not provided). * * @return bool */ public static function is_addable_to_paged_homepage( $is_homepage_blog_posts, $settings = null ) { // Use provided settings or fall back to static settings. if ( null === $settings ) { self::init_settings(); $settings = self::$settings; } if ( true === $is_homepage_blog_posts && is_paged() && ! empty( $settings['homepage']['paged'] ) && 'no' === $settings['homepage']['paged'] ) { return false; } return true; } /** * Sanitizes an HTML classnames to ensure it only contains valid characters. * * Strips the string down to A-Z,a-z,0-9,_,-, . If this results in an empty * string then it will return the alternative value supplied. * * @param string $classes The classnames to be sanitized (multiple classnames separated by space). * @param string $fallback Optional. The value to return if the sanitization ends up as an empty string. * Defaults to an empty string. * * @return string The sanitized value. */ public static function sanitize_html_classes( $classes, $fallback = '' ) { // Strip out any %-encoded octets. $sanitized = preg_replace( '|%[a-fA-F0-9][a-fA-F0-9]|', '', $classes ); // Limit to A-Z, a-z, 0-9, '_', '-' and ' ' (for multiple classes). $sanitized = trim( preg_replace( '/[^A-Za-z0-9\_\ \-]/', '', $sanitized ) ); if ( '' === $sanitized && $fallback ) { return self::sanitize_html_classes( $fallback ); } return $sanitized; } /** * Defines the expanded schema of allowed HTML tags and attributes for KSES. * * Extends the default `post` global with specific attributes required for * modern tracking scripts, preloading (fetchpriority, imagesrcset), * and security (nonce, integrity). * * @return array Map of allowed tags and their permitted attributes. */ public static function allowed_html() { // Return cached value if already initialized. if ( null !== self::$allowed_html ) { return self::$allowed_html; } // Allow safe HTML, JS, and CSS. self::$allowed_html = array_replace_recursive( wp_kses_allowed_html( 'post' ), // Allow safe HTML for posts. array( 'noscript' => true, // Allow