plugin_name = $plugin_name;
$this->version = $version;
$this->load_dependencies();
}
/**
* Load the required dependencies for this plugin.
*
* Include the following files that make up the plugin:
*
* - Siteimprove_Loader. Orchestrates the hooks of the plugin.
* - Siteimprove_I18n. Defines internationalization functionality.
* - Siteimprove_Admin. Defines all hooks for the admin area.
* - Siteimprove_Public. Defines all hooks for the public side of the site.
*
* Create an instance of the loader which will be used to register the hooks
* with WordPress.
*
* @access private
*/
private function load_dependencies() {
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/class-siteimprove-admin-settings.php';
$this->settings = new Siteimprove_Admin_Settings();
}
/**
* Register the stylesheets for the admin area.
*/
public function enqueue_styles() {
wp_enqueue_style( 'siteimprove_admin_css', plugin_dir_url( __FILE__ ) . 'css/siteimprove-admin.css', array(), $this->version, 'all' );
}
/**
* Register the stylesheets for the preview area.
*/
public function enqueue_preview_styles() {
global $wp_query;
$prepublish_allowed = intval( get_option( 'siteimprove_prepublish_allowed', 0 ) );
$prepublish_enabled = intval( get_option( 'siteimprove_prepublish_enabled', 0 ) );
if ( ( $wp_query->is_preview() || $wp_query->is_singular() || is_front_page() ) && 1 === $prepublish_allowed && 1 === $prepublish_enabled ) {
wp_enqueue_style( 'siteimprove_preview_css', plugin_dir_url( __FILE__ ) . 'css/siteimprove-preview.css', array(), $this->version, 'all' );
}
}
/**
* Register the JavaScript for the admin area.
*/
public function enqueue_scripts() {
wp_enqueue_script( 'siteimprove_admin_js', plugin_dir_url( __FILE__ ) . 'js/siteimprove-admin.js', array( 'jquery' ), $this->version, false );
}
/**
* Gutenberg script for adding buttons to its editor such as Recheck
*/
public function gutenberg_siteimprove_plugin() {
global $post;
if ( $post && $post->ID ) {
$permalink = get_permalink( $post->ID );
if ( $permalink ) {
$this->siteimprove_add_js( $permalink, 'siteimprove_input' );
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( 'Siteimprove Debug: Gutenberg - Post ID: ' . $post->ID );
error_log( 'Siteimprove Debug: Gutenberg - Permalink: ' . $permalink );
}
}
}
wp_enqueue_script(
'gutenberg-siteimprove-plugin',
plugin_dir_url( __FILE__ ) . 'js/siteimprove-gutenberg.js',
array( 'wp-plugins', 'wp-edit-post', 'wp-element', 'siteimprove' ),
$this->version,
false
);
$post_id = $post ? $post->ID : 0;
$url = $post_id ? get_permalink( $post_id ) : '';
$si_js_args = array(
'token' => get_option( 'siteimprove_token' ),
'text' => __( 'Siteimprove Recheck', 'siteimprove' ),
'url' => $url,
);
wp_localize_script(
'gutenberg-siteimprove-plugin',
'siteimprove_gutenberg_recheck',
$si_js_args
);
}
/**
* Initial actions.
*/
public function siteimprove_init() {
global $pagenow;
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( 'Siteimprove Debug: Current page: ' . $pagenow );
error_log( 'Siteimprove Debug: GET params: ' . print_r( $_GET, true ) );
}
$urls = get_transient( 'siteimprove_url_' . get_current_user_id() );
if ( ! wp_doing_ajax() && ! empty( $urls ) ) {
if ( is_array( $urls ) && count( $urls ) > 1 ) {
$url = esc_url( home_url() );
$method = 'siteimprove_recrawl';
} else {
$url = array_pop( $urls );
$method = 'siteimprove_recheck';
}
delete_transient( 'siteimprove_url_' . get_current_user_id() );
$this->siteimprove_add_js( $url, $method );
}
switch ( $pagenow ) {
case 'post.php':
$post_id = ! empty( $_GET['post'] ) ? (int) $_GET['post'] : 0;
$permalink = $post_id ? get_permalink( $post_id ) : false;
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( 'Siteimprove Debug: Post ID: ' . $post_id );
error_log( 'Siteimprove Debug: Permalink: ' . $permalink );
error_log( 'Siteimprove Debug: Token: ' . get_option( 'siteimprove_token', 'NOT_SET' ) );
error_log( 'Siteimprove Debug: User can edit posts: ' . ( current_user_can( 'edit_posts' ) ? 'yes' : 'no' ) );
}
if ( $permalink && current_user_can( 'edit_posts' ) ) {
$this->siteimprove_add_js( get_permalink( $post_id ), 'siteimprove_input' );
// Only display recheck button in published posts.
if ( get_post_status( $post_id ) === 'publish' ) {
$this->siteimprove_add_js( get_permalink( $post_id ), 'siteimprove_recheck_button' );
}
}
break;
case 'term.php':
case 'edit-tags.php':
$tag_id = ! empty( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0;
$taxonomy = ! empty( $_GET['taxonomy'] ) ? sanitize_key( $_GET['taxonomy'] ) : '';
if ( ( 'term.php' === $pagenow || ( 'edit-tags.php' === $pagenow && ! empty( $_GET['action'] ) && 'edit' === $_GET['action'] ) ) && current_user_can( 'manage_categories' ) ) {
$term_link = get_term_link( (int) $tag_id, $taxonomy );
if ( ! is_wp_error( $term_link ) ) {
$this->siteimprove_add_js( $term_link, 'siteimprove_input' );
$this->siteimprove_add_js( $term_link, 'siteimprove_recheck_button' );
}
}
break;
default:
$host = isset( $_SERVER['HTTP_HOST'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
$request = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
$this->siteimprove_add_js( $host . $request, 'siteimprove_domain' );
}
}
/**
* Include siteimprove js.
*
* @param string $url Url of the included js file.
* @param string $type Type/Handle of resource being included to localize the script correctly.
* @return void
*/
private function siteimprove_add_js( $url, $type ) {
$file_name = get_option( 'siteimprove_overlayjs_file', 'overlay-v2-dev.js' );
$disabled_new_version = get_option( 'siteimprove_disable_new_version' );
$pattern = '/^[a-zA-Z_\d-]+.js/';
$nonce = wp_create_nonce( 'siteimprove_nonce' );
if ( ! empty( $file_name ) ) {
if ( preg_match( $pattern, $file_name ) ) {
$overlay_path = Siteimprove::JS_LIBRARY_URL . $file_name;
} else {
$overlay_path = $file_name;
}
} else {
if ( $disabled_new_version ) {
$overlay_path = Siteimprove::JS_LIBRARY_URL . 'overlay-latest.js';
} else {
$overlay_path = Siteimprove::JS_LIBRARY_URL . 'overlay-v1.js';
}
}
if ( isset( $_GET['si_preview_nonce'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['si_preview_nonce'] ) ), 'siteimprove_nonce' ) ) {
return;
} else {
wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/siteimprove.js', array( 'jquery' ), $this->version, false );
/*
Pass any server-side vars down to JS. These will be exposed as
php_vars.variablename for example
*/
$jsarray = array(
'prepublish_allowed' => intval( get_option( 'siteimprove_prepublish_allowed', 0 ) ),
'prepublish_enabled' => intval( get_option( 'siteimprove_prepublish_enabled', 0 ) ),
'has_api_key' => intval( strlen( get_option( 'siteimprove_api_key', 0 ) ) > 0 ),
);
wp_localize_script( $this->plugin_name, 'php_vars', $jsarray );
wp_enqueue_script( 'siteimprove_overlay', $overlay_path, array(), $this->version, true );
}
$public_url = get_option( 'siteimprove_public_url' );
$ignore_segments = get_option( 'siteimprove_ignore_path_segments' );
// Parse the URL to get its components.
$parsed_url = wp_parse_url( $url );
$path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
// Apply path segment filtering if configured.
if ( ! empty( $ignore_segments ) && ! empty( $path ) ) {
// Split the ignore segments by comma and trim whitespace.
$segments_to_ignore = array_map( 'trim', explode( ',', $ignore_segments ) );
// Split the path into segments.
$path_segments = array_filter( explode( '/', $path ) );
// Remove segments that should be ignored.
$filtered_segments = array();
foreach ( $path_segments as $segment ) {
if ( ! in_array( $segment, $segments_to_ignore, true ) ) {
$filtered_segments[] = $segment;
}
}
// Reconstruct the path.
$path = '/' . implode( '/', $filtered_segments );
}
// Apply public URL transformation if configured.
if ( ! empty( $public_url ) ) {
$public_url = rtrim( $public_url, '/' );
$normalized_path = '/' . ltrim( $path, '/' );
$query_string = isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '';
$url = $public_url . $normalized_path . $query_string;
} else {
// If no public URL is set, reconstruct the URL with the filtered path.
$scheme = isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '';
$host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : '';
$port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : '';
$query = isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '';
$fragment = isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '';
$url = $scheme . $host . $port . $path . $query . $fragment;
}
$is_content_page = is_preview() || is_singular() || is_front_page();
$si_js_args = array(
'token' => get_option( 'siteimprove_token' ),
'txt' => __( 'Siteimprove Recheck', 'siteimprove' ),
'url' => $url,
'version' => $disabled_new_version,
'is_content_page' => $is_content_page,
'nonce' => $nonce,
);
wp_localize_script(
$this->plugin_name,
esc_js( $type ),
$si_js_args
);
// Adding translation strings.
wp_localize_script(
$this->plugin_name,
'siteimprove_plugin_text',
array(
'loading' => __( 'Loading... Please wait.', 'siteimprove' ),
'prepublish_activate_running' => __( 'We are now activating prepublish for your website... Please keep the current page open while the process is running.', 'siteimprove' ),
'prepublish_feature_ready' => __( 'Prepublish feature is already enabled for the current website. To use it please go to the preview of any page/post or content that you want to check and click the button Siteimprove Prepublish Check located on the top bar of the admin panel.', 'siteimprove' ),
'prepublish_activation_error' => __( 'Error activating prepublish. Please contact support team.', 'siteimprove' ),
)
);
}
/**
* Register settings form section.
*/
public function siteimprove_settings() {
$this->settings->register_section();
}
/**
* Register menu page.
*/
public function siteimprove_settings_page() {
$this->settings->register_menu();
}
/**
* Register action for token requests.
*/
public function siteimprove_request_token() {
$this->settings->request_token();
}
/**
* Register action for prepublish feature check after manual activation on the admin panel side
*
* @return void
*/
public function siteimprove_check_prepublish_activation() {
$this->settings->check_prepublish_activation();
}
/**
* Register action for prepublish feature manual activation made on the admin panel side
*
* @return void
*/
public function siteimprove_prepublish_manual_activation() {
$this->settings->prepublish_manual_activation();
}
/**
* Save in session post url.
*
* @param integer $post_ID WordPress Post ID.
* @return void
*/
public function siteimprove_save_session_url_post( $post_ID ) {
if ( ! wp_is_post_revision( $post_ID ) && ! wp_is_post_autosave( $post_ID ) ) {
$urls = get_transient( 'siteimprove_url_' . get_current_user_id() );
$urls[] = get_permalink( $post_ID );
set_transient( 'siteimprove_url_' . get_current_user_id(), $urls, 900 );
}
}
/**
* Save in session term url.
*
* @param integer $term_id WordPress Term ID.
* @param mixed $tt_id WordPress parameter added for hook compatibility.
* @param mixed $taxonomy WordPress taxonomy.
* @return void
*/
public function siteimprove_save_session_url_term( $term_id, $tt_id, $taxonomy ) {
$urls = get_transient( 'siteimprove_url_' . get_current_user_id() );
$urls[] = get_term_link( (int) $term_id, $taxonomy );
set_transient( 'siteimprove_url_' . get_current_user_id(), $urls, 900 );
}
/**
* Save in session product url.
*
* @param string $new_status WordPress post status.
* @param string $old_status WordPress post status.
* @param object $post WordPress Post Object.
* @return void
*/
public function siteimprove_save_session_url_product( $new_status, $old_status, $post ) {
if (
'publish' === $new_status
&& ! empty( $post->ID )
&& in_array(
$post->post_type,
array( 'product' ),
true
)
) {
$urls = get_transient( 'siteimprove_url_' . get_current_user_id() );
$urls[] = get_permalink( $post->ID );
set_transient( 'siteimprove_url_' . get_current_user_id(), $urls, 900 );
}
}
/**
* Include js in frontend pages.
*/
public function siteimprove_wp_head() {
$user = wp_get_current_user();
$allowed_roles = array(
'shop_manager',
'contributor',
'author',
'editor',
'administrator',
);
if ( array_intersect( $allowed_roles, $user->roles ) ) {
$type = $this->get_current_page_type();
switch ( $type ) {
case 'front':
case 'home':
case 'page':
case 'single':
case 'category':
case 'tag':
case 'tax':
$this->siteimprove_add_js( get_permalink(), 'siteimprove_input' );
break;
default:
$host = isset( $_SERVER['HTTP_HOST'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '';
$request = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
$this->siteimprove_add_js( $host . $request, 'siteimprove_domain' );
}
}
}
/**
* Return current page type.
*/
protected function get_current_page_type() {
global $wp_query;
$loop = 'notfound';
if ( $wp_query->is_page ) {
$loop = is_front_page() ? 'front' : 'page';
} elseif ( $wp_query->is_home ) {
$loop = 'home';
} elseif ( $wp_query->is_single ) {
$loop = ( $wp_query->is_attachment ) ? 'attachment' : 'single';
} elseif ( $wp_query->is_category ) {
$loop = 'category';
} elseif ( $wp_query->is_tag ) {
$loop = 'tag';
} elseif ( $wp_query->is_tax ) {
$loop = 'tax';
} elseif ( $wp_query->is_archive ) {
if ( $wp_query->is_day ) {
$loop = 'day';
} elseif ( $wp_query->is_month ) {
$loop = 'month';
} elseif ( $wp_query->is_year ) {
$loop = 'year';
} elseif ( $wp_query->is_author ) {
$loop = 'author';
} else {
$loop = 'archive';
}
} elseif ( $wp_query->is_search ) {
$loop = 'search';
} elseif ( $wp_query->is_404 ) {
$loop = 'notfound';
}
return $loop;
}
/**
* Adds the prepublish menu item on the top bar when user is
* in preview mode so he can send the content to prepublish.
*
* @param WP_Admin_Bar $admin_bar WordPress Admin Bar Object.
* @return void
*/
public function add_prepublish_toolbar_item( WP_Admin_Bar $admin_bar ) {
global $pagenow;
$prepublish_allowed = intval( get_option( 'siteimprove_prepublish_allowed', 0 ) );
$prepublish_enabled = intval( get_option( 'siteimprove_prepublish_enabled', 0 ) );
$has_api_key = intval( strlen( get_option( 'siteimprove_api_key', 0 ) ) > 0 );
if ( ( is_preview() || is_singular() || is_front_page() ) && 1 === $prepublish_allowed && 1 === $prepublish_enabled && 1 === $has_api_key ) {
$prepublish_button =
'';
$admin_bar->add_menu(
array(
'id' => 'siteimprove-trigger-contentcheck',
'title' => $prepublish_button . __( 'Prepublish', 'siteimprove' ),
'group' => null,
'href' => '#',
'meta' => array(
'title' => __( 'Siteimprove Prepublish', 'siteimprove' ),
'class' => 'siteimprove-trigger-contentcheck',
),
)
);
}
}
}