File: /home/coopserp/public_html/main.tar
promo.php 0000644 00000003456 15152641416 0006426 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Promo{
static function update_notice(){
if(defined('SOFTACULOUS_PLUGIN_UPDATE_NOTICE')){
return;
}
$to_update_plugins = apply_filters('softaculous_plugin_update_notice', []);
if(empty($to_update_plugins)){
return;
}
/* translators: %1$s is replaced with a "string" of name of plugins, and %2$s is replaced with "string" which can be "is" or "are" based on the count of the plugin */
$msg = sprintf(__('New versions of %1$s %2$s available. Updating ensures better performance, security, and access to the latest features.', 'speedycache'), '<b>'.esc_html(implode(', ', $to_update_plugins)).'</b>', (count($to_update_plugins) > 1 ? 'are' : 'is')) . ' <a class="button button-primary" href='.esc_url(admin_url('plugins.php?plugin_status=upgrade')).'>Update Now</a>';
define('SOFTACULOUS_PLUGIN_UPDATE_NOTICE', true); // To make sure other plugins don't return a Notice
echo '<div class="notice notice-info is-dismissible" id="speedycache-plugin-update-notice">
<p>'.$msg. '</p>
</div>';
wp_register_script('speedycache-update-notice', '', ['jquery'], '', true);
wp_enqueue_script('speedycache-update-notice');
wp_add_inline_script('speedycache-update-notice', 'jQuery("#speedycache-plugin-update-notice").on("click", function(e){
let target = jQuery(e.target);
if(!target.hasClass("notice-dismiss")){
return;
}
var data;
// Hide it
jQuery("#speedycache-plugin-update-notice").hide();
// Save this preference
jQuery.post("'.admin_url('admin-ajax.php?action=speedycache_close_update_notice').'&security='.wp_create_nonce('speedycache_promo_nonce').'", data, function(response) {
//alert(response);
});
});');
}
} admin.php 0000644 00000045724 15152641416 0006366 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
// Show menu with error if speedy cache is installed but is older than 1.1.0
// as after that we dont short circuit the free version
if(!defined('SPEEDYCACHE_VERSION') || version_compare(SPEEDYCACHE_VERSION, '1.1.1') < 0){
add_action('admin_menu', 'speedycachepro_add_menu');
return; // Return else going forward will break things.
}
add_action('speedycache_license_tmpl', '\SpeedyCache\SettingsPage::license_tab');
add_action('speedycache_db_tmpl', '\SpeedyCache\SettingsPage::db_tab');
add_action('speedycache_pro_logs_tmpl', '\SpeedyCache\SettingsPage::logs');
add_action('speedycache_pro_stats_tmpl', '\SpeedyCache\SettingsPage::stats');
add_action('speedycache_image_optm_tmpl', '\SpeedyCache\SettingsPage::image_optm');
add_action('speedycache_bloat_tmpl', '\SpeedyCache\SettingsPage::bloat_tab');
add_action('speedycache_object_cache_tmpl', '\SpeedyCache\SettingsPage::object_tab');
include_once SPEEDYCACHE_PRO_DIR . '/main/premium.php';
if(defined('SPEEDYCACHE_PRO') && file_exists(SPEEDYCACHE_PRO_DIR . '/main/image.php')){
\SpeedyCache\Image::init();
add_action('wp_ajax_speedycache_download_cwebp', '\SpeedyCache\Image::download_cwebp');
add_action('add_meta_boxes_attachment', 'speedycache_pro_media_metabox');
}
add_action('admin_init', 'speedycache_pro_schedule_test_event');
add_action('admin_notices', 'speedycache_pro_notices');
add_filter('softaculous_expired_licenses', 'speedycache_pro_plugins_expired');
add_action('admin_enqueue_scripts', 'speedycache_pro_enqueue_admin_scripts');
// ----- AJAX ACTIONS ----- //
add_action('wp_ajax_speedycache_statics_ajax_request', 'speedycache_pro_img_stats');
add_action('wp_ajax_speedycache_optimize_image_ajax_request', 'speedycache_pro_optimize_image');
add_action('wp_ajax_speedycache_update_image_settings', 'speedycache_pro_save_img_settings');
add_action('wp_ajax_speedycache_update_image_list_ajax_request', 'speedycache_pro_list_imgs');
add_action('wp_ajax_speedycache_revert_image_ajax_request', 'speedycache_pro_revert_img');
add_action('wp_ajax_speedycache_img_revert_all', 'speedycache_pro_revert_all_imgs');
add_action('wp_ajax_speedycache_verify_license', 'speedycache_pro_verify_license');
add_action('wp_ajax_speedycache_copy_test_settings', 'speedycache_pro_copy_test_settings');
add_action('wp_ajax_speedycache_dismiss_test_notice','speedycache_pro_dismiss_test_notice');
add_action('wp_ajax_speedycache_pro_dismiss_expired_licenses', 'speedycache_pro_dismiss_expired_licenses');
function speedycachepro_add_menu(){
add_menu_page('SpeedyCache Settings', 'SpeedyCache', 'activate_plugins', 'speedycache', 'speedycachepro_menu_page');
}
function speedycachepro_menu_page(){
echo '<div style="color: #333;padding: 50px;text-align: center;">
<h1 style="font-size: 2em;margin-bottom: 10px;">Update Speedycache to Latest Version!</h>
<p style=" font-size: 16px;margin-bottom: 20px; font-weight:400;">SpeedyCache Pro depends on the free version of SpeedyCache, so you need to update the free version to use SpeedyCache without any issue.</p>
<a href="'.admin_url('plugin-install.php?s=speedycache&tab=search').'" style="text-decoration: none;font-size:16px;">Install Now</a>
</div>';
}
function speedycache_pro_img_stats(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
if(!class_exists('\SpeedyCache\Image')){
wp_send_json_error(__('The file required to Process Image optimization is not present', 'speedycache'));
}
$res = \SpeedyCache\Image::statics_data();
wp_send_json($res);
}
function speedycache_pro_optimize_image(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
if(!class_exists('\SpeedyCache\Image')){
wp_send_json_error(__('The file required to Process Image optimization is not present', 'speedycache'));
}
$id = null;
if(!empty($_POST['img_id'])){
$id = (int) sanitize_text_field(wp_unslash($_POST['img_id']));
if(empty($id)){
wp_send_json_error('Empty Image ID');
}
}
$res = \SpeedyCache\Image::optimize_single($id);
$res[1] = isset($res[1]) ? $res[1] : '';
$res[2] = isset($res[2]) ? $res[2] : '';
$res[3] = isset($res[3]) ? $res[3] : '';
$response = array(
'message' => $res[0],
'success' => $res[1],
'id' => $res[2],
'percentage' => $res[3],
);
wp_send_json($response);
}
function speedycache_pro_save_img_settings(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
global $speedycache;
$settings = speedycache_optpost('settings');
foreach($settings as $key => $setting){
$new_key = str_replace('img_', '', $key);
$settings[$new_key] = $setting;
unset($settings[$key]);
}
$speedycache->image['settings'] = $settings;
if(update_option('speedycache_img', $speedycache->image['settings'])){
wp_send_json_success();
}
wp_send_json_error();
}
function speedycache_pro_list_imgs(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
$query_images_args = array();
$query_images_args['offset'] = intval(speedycache_optget('page')) * intval(speedycache_optget('per_page'));
$query_images_args['order'] = 'DESC';
$query_images_args['orderby'] = 'ID';
$query_images_args['post_type'] = 'attachment';
$query_images_args['post_mime_type'] = array('image/jpeg', 'image/png', 'image/gif');
$query_images_args['post_status'] = 'inherit';
$query_images_args['posts_per_page'] = speedycache_optget('per_page');
$query_images_args['meta_query'] = array(
array(
'key' => 'speedycache_optimisation',
'compare' => 'EXISTS'
)
);
$query_images_args['s'] = speedycache_optget('search');
if(!empty($_GET['filter'])){
if(speedycache_optget('filter') == 'error_code'){
$filter = array(
'key' => 'speedycache_optimisation',
'value' => base64_encode('"error_code"'),
'compare' => 'LIKE'
);
$filter_second = array(
'key' => 'speedycache_optimisation',
'compare' => 'NOT LIKE'
);
array_push($query_images_args['meta_query'], $filter);
array_push($query_images_args['meta_query'], $filter_second);
}
}
$result = array(
'content' => \SpeedyCache\Image::list_content($query_images_args),
'result_count' => \SpeedyCache\Image::count_query($query_images_args)
);
wp_send_json($result);
}
function speedycache_pro_revert_img(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must Be admin');
}
global $speedycache;
if(!empty($_GET['id'])){
$speedycache->image['id'] = (int) speedycache_optget('id');
}
wp_send_json(\SpeedyCache\Image::revert());
}
function speedycache_pro_revert_all_imgs(){
check_ajax_referer('speedycache_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
\SpeedyCache\Image::revert_all();
}
function speedycache_pro_verify_license(){
if(!wp_verify_nonce($_GET['security'], 'speedycache_license')){
wp_send_json_error(__('Security Check Failed', 'speedycache'));
}
if(!current_user_can('manage_options')){
wp_send_json_error(__('You do not have required permission.', 'speedycache'));
}
global $speedycache;
$license = sanitize_key($_GET['license']);
if(empty($license)){
wp_send_json_error(__('The license key was not submitted', 'speedycache'));
}
$resp = wp_remote_get(SPEEDYCACHE_API.'license.php?license='.$license.'&url='.rawurlencode(site_url()), array('timeout' => 30));
if(!is_array($resp)){
wp_send_json_error(__('The response was malformed<br>'.var_export($resp, true), 'speedycache'));
}
$json = json_decode($resp['body'], true);
// Save the License
if(empty($json['license'])){
wp_send_json_error(__('The license key is invalid', 'speedycache'));
}
$speedycache->license = $json;
update_option('speedycache_license', $json, false);
wp_send_json_success();
}
function speedycache_pro_enqueue_admin_scripts(){
wp_enqueue_style('speedycache-admin-pro', SPEEDYCACHE_PRO_URL . '/assets/css/admin.css', [], SPEEDYCACHE_PRO_VERSION);
wp_enqueue_script('speedycache-admin-pro', SPEEDYCACHE_PRO_URL . '/assets/js/admin.js', [], SPEEDYCACHE_PRO_VERSION);
wp_localize_script('speedycache-admin-pro', 'speedycache_pro_ajax', [
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('speedycache_pro_ajax_nonce'),
'premium' => defined('SPEEDYCACHE_PRO'),
]);
}
// Sets speedycache settings to our predefined defaults.
function speedycache_pro_copy_test_settings(){
check_ajax_referer('speedycache_pro_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
global $speedycache;
$test_settings = ['minify_html' => true, 'delay_js' => true, 'render_blocking' => true, 'minify_js' => true, 'critical_images' => true, 'lazy_load' => true, 'delay_js_mode' => 'selected', 'delay_js_scripts' => ['fbevents.js', 'google-analytics.com', 'adsbygoogle.js', 'googletagmanager.com', 'fbq(', "ga( '", "ga('", '/gtm.js', '/gtag/js', 'gtag(', '/gtm-', '/gtm.']];
$speedycache->options = array_merge($speedycache->options, $test_settings);
update_option('speedycache_options', $speedycache->options);
delete_option('speedycache_test_results');
wp_send_json_success(__('Settings applied successfully.', 'speedycache-pro'));
}
function speedycache_pro_dismiss_test_notice(){
check_ajax_referer('speedycache_pro_ajax_nonce', 'security');
if(!current_user_can('manage_options')){
wp_die('Must be admin');
}
delete_option('speedycache_test_results');
}
function speedycache_pro_schedule_test_event() {
$install_time = get_option('speedycache_free_installed', 0);
$event_executed = get_option('speedycache_test_executed', 0);
if($install_time && !$event_executed){
if(($install_time + WEEK_IN_SECONDS) < time()){
$event_time = time() + DAY_IN_SECONDS;
} else {
$event_time = $install_time + WEEK_IN_SECONDS;
}
if(!wp_next_scheduled('speedycache_test_event')){
wp_schedule_single_event($event_time, 'speedycache_test_event');
}
}
}
function speedycache_pro_test_results_notice() {
if(!current_user_can('manage_options')){
return;
}
$current_screen = get_current_screen();
if(!isset($current_screen->id) || strpos($current_screen->id, 'speedycache') === false){
return;
}
$test_results = get_option('speedycache_test_results');
if(empty($test_results)){
return;
}
$old_score = $test_results['old_score'];
$new_score = $test_results['new_score'];
$stroke_old = !empty($old_score) ? 100 - $old_score : 0;
$stroke_new = !empty($new_score) ? 100 - $new_score : 0;
$old_color = speedycache_pro_get_score_color($old_score);
$new_color = speedycache_pro_get_score_color($new_score);
echo '<div class="notice notice-success is-dismissible speedycache-test-notice">
<p class="speedycache-notice-title"><strong>'.esc_html__('Speed Test Results:', 'speedycache-pro').'</strong></p>
<div class="speedycache-test-chart-wrap">
<!-- Before Optimization -->
<div class="speedycache-donut-wrap speedycache-before-optimization">
<svg width="150" height="150" viewBox="0 0 40 40" class="speedycache-donut">
<circle class="donut-hole" cx="20" cy="20" r="15.91549430918954" fill="'.esc_attr($old_color[1]).'"></circle>
<circle class="speedycache-donut-segment" cx="20" cy="20" r="15.91549430918954" fill="transparent" stroke-width="3" stroke-linecap="round" stroke-dasharray="'.esc_attr($old_score).' '.esc_attr($stroke_old).'" stroke-dashoffset="25" style="stroke:'.esc_attr($old_color[0]).';"></circle>
<g class="speedycache-test-donut-text">
<text y="55%" transform="translate(0, 2)">
<tspan x="50%" text-anchor="middle" class="speedycache-donut-percent" style="fill:'.esc_attr($old_color[2]).';">'.esc_attr($old_score).'</tspan>
</text>
</g>
</svg>
<p class="speedycache-donut-label">'.esc_html__('Before Optimization', 'speedycache-pro').'</p>
</div>
<!-- After Optimization -->
<div class="speedycache-donut-wrap speedycache-after-optimization">
<svg width="150" height="150" viewBox="0 0 40 40" class="speedycache-donut">
<circle class="donut-hole" cx="20" cy="20" r="15.91549430918954" fill="'.esc_attr($new_color[1]).'"></circle>
<circle class="speedycache-donut-segment" cx="20" cy="20" r="15.91549430918954" fill="transparent" stroke-width="3" stroke-linecap="round" stroke-dasharray="'.esc_attr($new_score).' '.esc_attr($stroke_new).'" stroke-dashoffset="25" style="stroke:'.esc_attr($new_color[0]).';"></circle>
<g class="speedycache-test-donut-text">
<text y="55%" transform="translate(0, 2)">
<tspan x="50%" text-anchor="middle" class="speedycache-donut-percent" style="fill:'.esc_attr($new_color[2]).';">'.esc_attr($new_score).'</tspan>
</text>
</g>
</svg>
<p class="speedycache-donut-label">'.esc_html__('After Optimization', 'speedycache-pro').'</p>
</div>
</div>
<div class="speedycache-test-action">
'.esc_html__('Want to enable the SpeedyCache settings used for this test?', 'speedycache-pro').'
<button class="speedycache-enable-btn speedycache-copy-test-settings">'.esc_html__('Enable Now', 'speedycache-pro').'</button>
</div>
<button type="button" class="notice-dismiss speedycache-custom-dismiss">
<span class="screen-reader-text">'.esc_html__('Dismiss this notice.', 'speedycache-pro').'</span>
</button>
</div>';
}
function speedycache_pro_plugins_expired($plugins){
global $speedycache;
if(!empty($speedycache->license) && empty($speedycache->license['active'])){
$plugins[] = 'SpeedyCache';
}
return $plugins;
}
function speedycache_pro_notices(){
global $speedycache;
if(!current_user_can('activate_plugins')){
return;
}
$current_screen = get_current_screen();
// Test result notice
if(isset($current_screen->id) && strpos($current_screen->id, 'speedycache') !== false){
speedycache_pro_test_results_notice();
}
// If the license is active then we do not need to show any notice.
if(!empty($speedycache->license) && empty($speedycache->license['active'])){
speedycache_pro_expiry_notice();
}
}
function speedycache_pro_expiry_notice(){
global $speedycache;
// The combined notice for all Softaculous plugin to show that the license has expired
$dismissed_at = get_option('softaculous_expired_licenses', 0);
$expired_plugins = apply_filters('softaculous_expired_licenses', []);
if(
!empty($expired_plugins) &&
is_array($expired_plugins) &&
!defined('SOFTACULOUS_EXPIRY_LICENSES') &&
(empty($dismissed_at) || ($dismissed_at + WEEK_IN_SECONDS) < time())
){
define('SOFTACULOUS_EXPIRY_LICENSES', true); // To make sure other plugins don't return a Notice
echo '<div class="notice notice-error is-dismissible" id="speedycache-pro-expiry-notice">
<p>'.sprintf(__('Your %1$s plugin license has %2$sExpired%3$s. Please renew your license for uninterrupted updates and support.', 'speedycache-pro'),
esc_html(implode(', ', $expired_plugins)),
'<font style="color:red;"><b>',
'</b></font>'
). '</p>
</div>';
wp_register_script('speedycache-pro-expiry-notice', '', array('jquery'), SPEEDYCACHE_PRO_VERSION, true );
wp_enqueue_script('speedycache-pro-expiry-notice');
wp_add_inline_script('speedycache-pro-expiry-notice', '
jQuery(document).ready(function(){
jQuery("#speedycache-pro-expiry-notice").on("click", ".notice-dismiss", function(e){
e.preventDefault();
let target = jQuery(e.target);
let jEle = target.closest("#speedycache-pro-expiry-notice");
jEle.slideUp();
jQuery.post("'.admin_url('admin-ajax.php').'", {
security : "'.wp_create_nonce('speedycache_expiry_notice').'",
action: "speedycache_pro_dismiss_expired_licenses",
}, function(res){
if(!res["success"]){
alert(res["data"]);
}
}).fail(function(data){
alert("There seems to be some issue dismissing this alert");
});
});
})');
}
}
function speedycache_pro_get_score_color($score) {
$score_color_map = [
0 => ['#c00', '#c003', '#c00'], // Red
50 => ['#fa3', '#ffa50036', '#fa3'], // Orange
90 => ['#0c6', '#00cc663b', '#080'], // Green
];
if ($score >= 0 && $score < 50) {
return $score_color_map[0];
} elseif ($score >= 50 && $score < 90) {
return $score_color_map[50];
} else {
return $score_color_map[90];
}
}
function speedycache_pro_media_metabox($post){
if(empty($post)){
return;
}
$allowed_img_types = [
'image/png',
'image/jpg',
'image/jpeg',
];
if(!in_array($post->post_mime_type, $allowed_img_types)){
return;
}
add_meta_box(
'speedycache-optm-img',
__('SpeedyCache Image Optimization', 'speedycache-pro'),
'speedycache_pro_img_optm_metabox',
'attachment',
'side',
'default'
);
}
function speedycache_pro_img_optm_metabox($post){
if(empty($post)){
echo 'No Post data';
return;
}
$optimized_data = get_post_meta($post->ID, 'speedycache_optimisation', true);
if(!empty($optimized_data)){
$optimized_data = base64_decode($optimized_data);
$optimized_data = json_decode($optimized_data, true);
if(!empty($optimized_data) && !empty($optimized_data[0]) && !empty($optimized_data[0]['file']) && file_exists($optimized_data[0]['file'])){
esc_html_e('Image has already been optimized', 'speedycache-pro');
return;
}
}
echo '<button class="button" id="speedycache-optm-attachment" data-id="'.esc_attr($post->ID).'">'.esc_html__('Optimize this Image', 'speedycache-pro').'</button>';
wp_register_script('speedycache-img-optm-meta-box', '', array('jquery'), '', true);
wp_enqueue_script('speedycache-img-optm-meta-box');
wp_add_inline_script('speedycache-img-optm-meta-box', 'jQuery(document).ready(function(){
jQuery("#speedycache-optm-attachment").on("click", function(e){
e.preventDefault();
let attachment_id = jQuery(e.target).data("id"),
nonce = "'.wp_create_nonce('speedycache_ajax_nonce').'";
jQuery.ajax({
url : "'.esc_url(admin_url('admin-ajax.php')).'",
method : "POST",
data : {
"action":"speedycache_optimize_image_ajax_request",
"security": nonce,
"img_id": attachment_id,
},
success: function(res){
if(res.success){
window.location.reload();
}
}
});
})
})');
}
function speedycache_pro_dismiss_expired_licenses(){
check_admin_referer('speedycache_expiry_notice', 'security');
if(!current_user_can('activate_plugins')){
wp_send_json_error(__('You do not have required access to do this action', 'speedycache-pro'));
}
update_option('softaculous_expired_licenses', time());
wp_send_json_success();
} cdn.php 0000644 00000021241 15152641416 0006026 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class CDN{
static $allowed_types = [];
static $cdn_url = '';
static $specific = [];
static $excludes = [];
static function rewrite(&$content){
global $speedycache;
self::$cdn_url = $speedycache->cdn['cdn_url'];
self::$allowed_types = $speedycache->cdn['file_types'];
self::$excludes = $speedycache->cdn['excludekeywords'];
self::$specific = $speedycache->cdn['keywords'];
if(empty(self::$cdn_url) || empty(self::$allowed_types)){
return;
}
// Define the patterns to match specific URLs (e.g., images, CSS, JS)
$base_dir = defined('SITEPAD') ? 'sitepad-data' : 'wp-content';
if (defined('SITEPAD')){
global $sitepad;
$site_inc_url = $sitepad['url'] . '/site-inc';
} else {
$site_inc_url = home_url('/wp-includes/');
}
$patterns = [
'/' . preg_quote(home_url("/{$base_dir}/uploads/"), '/') . '([^"\']+)/i',
'/'. preg_quote($site_inc_url, '/') . '([^"\']+)/i',
'/' . preg_quote(home_url("/{$base_dir}/themes/"), '/') . '([^"\']+)/i',
'/' . preg_quote(defined('SP_PLUGIN_URL') ? SP_PLUGIN_URL : home_url('/wp-content/plugins/'), '/') . '([^"\']+)/i',
'/' . preg_quote(home_url("/{$base_dir}/cache/"), '/') . '([^"\']+)/i',
];
// Loop through each pattern and replace only URLs with the specified file types
foreach($patterns as $pattern){
$content = preg_replace_callback($pattern, '\SpeedyCache\CDN::replace_urls', $content);
}
}
static function replace_urls($matches) {
global $speedycache;
// Get the file extension
$file_url = preg_replace('/\?.*$/', '', $matches[0]);
if(empty($file_url)){
$file_url = $matches[0];
}
$file_url = trim($file_url, '/');
if(self::is_excluded($file_url)){
return $matches[0];
}
// To rewrite just some specific files only
if(!empty(self::$specific) && is_array(self::$specific)){
$is_specific = false;
foreach(self::$specific as $required_source){
if(preg_match('/'.preg_quote($required_source).'/i', $file_url)){
$is_specific = true;
break;
}
}
if(empty($is_specific)){
return $matches[0];
}
}
$file_extension = self::get_file_extension($file_url);
// Check if the file extension is in the allowed list
if(in_array(strtolower($file_extension), self::$allowed_types)){
$home_url = home_url();
// Rewrite the URL to use the CDN
return str_replace($home_url, self::$cdn_url, $matches[0]);
}
// If not in the allowed list, return the original URL
return $matches[0];
}
static function get_file_extension($url) {
$url = strtok($url, ' ');
$url = strtok($url, '?');
return strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
}
static function is_excluded($url){
if(empty($url)){
return false;
}
// array check if just to make sure things dont break for 1.2.0 in which we rewrote the plugin
if(empty(self::$excludes) || !is_array(self::$excludes)){
return false;
}
foreach(self::$excludes as $exclude){
if(preg_match('/'.preg_quote($exclude).'/i', $url)){
return true;
}
}
return false;
}
static function purge(){
global $speedycache;
// Only cloudflare and Bunny can be purged, that too we only want that to happen if CDN is enabled.
if(
empty($speedycache->cdn['enabled']) ||
empty($speedycache->cdn['cdn_key']) ||
empty($speedycache->cdn['cdn_type']) ||
$speedycache->cdn['cdn_type'] == 'other'
){
return;
}
if($speedycache->cdn['cdn_type'] == 'bunny'){
self::purge_bunny($speedycache->cdn);
}elseif($speedycache->cdn['cdn_type'] == 'cloudflare'){
self::purge_cloudflare($speedycache->cdn);
}
}
// Get unique pull ID to purge cache on CDN
static function bunny_get_pull_id(&$cdn){
global $speedycache;
$pull_zone = $cdn['cdn_url']; // bunny cdn calls it cdn url as pull zone
$access_key = $cdn['cdn_key'];
if(empty($access_key)){
return array('success' => false, 'message' => __('Bunny CDN Access Key not found', 'speedycache'));
}
$options = array(
'headers' => array(
'AccessKey' => $access_key,
'accept' => 'application/json'
)
);
$res = wp_remote_get('https://api.bunny.net/pullzone', $options);
if(is_wp_error($res) || empty($res)){
if(empty($res)){
return array('success' => false, 'message' => __('Bunny CDN retuned an empty response', 'speedycache'));
}
return array('success' => false, 'message' => 'Something Went Wrong: ' . $res->get_error_message());
}
$res_code = wp_remote_retrieve_response_code($res);
if(substr($res_code, 0, 1) != 2){
return array('success' => false, 'message' => __('Something Went Wrong: Getting Pull ID was unsuccessful ', 'speedycache') . $res_code);
}
$res_body = wp_remote_retrieve_body($res);
if(empty($res_body)){
return array('success' => false, 'message' => __('Bunny CDN pull ID response body is empty', 'speedycache'));
}
$res_body = json_decode($res_body, true);
foreach($res_body as $pull_zones){
if($pull_zones['OriginUrl'] == $cdn['origin_url']){
return $pull_zones['Id'];
}
}
return array('success' => false, 'message' => __('Bunny Pull Zone not found', 'speedycache'));
}
static function purge_bunny($cdn){
if(empty($cdn['cdn_key']) || empty($cdn['cdn_url'])){
return false;
}
$pull_zone = $cdn['cdn_url']; // bunny cdn calls it cdn url as pull zone
$access_key = $cdn['cdn_key'];
$pull_id = !empty($cdn['bunny_pull_id']) ? $cdn['bunny_pull_id'] : '';
if(empty($access_key) || empty($pull_id)){
return false;
}
$options = array(
'headers' => array(
'AccessKey' => $access_key,
'content-type' => 'application/json'
)
);
$res = wp_remote_post('https://api.bunny.net/pullzone/'.$pull_id.'/purgeCache', $options);
if(is_wp_error($res) || empty($res)){
if(empty($res)){
return __('Bunny CDN retuned an empty response', 'speedycache');
}
return 'Something Went Wrong: ' . $res->get_error_message();
}
$res_code = wp_remote_retrieve_response_code($res);
if($res_code != 204){
return esc_html__('Something Went Wrong: Purge was unsuccessful with response code of ', 'speedycache') . $res_code;
}
return esc_html__('Success: Bunny CDN purged successfully', 'speedycache');
}
static function cloudflare_zone_id(&$cdn){
if(empty($cdn['cdn_key'])){
return false;
}
$api_token = $cdn['cdn_key'];
$domain = parse_url(home_url(), PHP_URL_HOST);
$url = 'https://api.cloudflare.com/client/v4/zones?name='.$domain;
$args = [
'headers' => [
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json',
],
];
$response = wp_remote_get($url, $args);
if (is_wp_error($response)) {
return 'Error: ' . $response->get_error_message();
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if($body && isset($body['result'][0]['id'])){
return $body['result'][0]['id']; // This is the Zone ID
}
return false;
}
static function purge_cloudflare($cdn){
if(empty($cdn['cloudflare_zone_id']) || empty($cdn['cdn_key'])){
return;
}
$zone_id = $cdn['cloudflare_zone_id'];
$api_token = $cdn['cdn_key'];
$url = 'https://api.cloudflare.com/client/v4/zones/'.$zone_id.'/purge_cache';
$args = [
'headers' => [
'Authorization' => 'Bearer ' . $api_token,
'Content-Type' => 'application/json',
],
'body' => json_encode([
'purge_everything' => true, // Set to true to purge all cache
]),
];
$response = wp_remote_post($url, $args);
if (is_wp_error($response)) {
return 'Error: ' . $response->get_error_message();
}
$body = json_decode(wp_remote_retrieve_body($response), true);
if ($body && isset($body['success']) && $body['success'] === true) {
return esc_html__('Cloudflare cache purged successfully.', 'speedycache');
}
return 'Failed to purge Cloudflare cache. ' . (isset($body['errors'][0]['message']) ? $body['errors'][0]['message'] : '');
}
// Users can add a custom CDN URL in Head Tag
static function cdn_preconnect(){
global $speedycache;
if(empty($speedycache->options['status']) || empty($speedycache->cdn['enabled']) || empty($speedycache->cdn['cdn_url'])){
return;
}
if($speedycache->cdn['cdn_type'] == 'other' || $speedycache->cdn['cdn_type'] == 'bunny'){
echo '<link rel="preconnect" href="'. esc_url($speedycache->cdn['cdn_url']) .'" crossorigin="anonymous">';
}
}
}
js.php 0000644 00000013574 15152641416 0005710 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT');
}
use \SpeedyCache\Util;
class JS{
// Depericated since 1.2.0
// do not use it just to prevent site from breaking.
static function init(){
}
static function minify(&$content){
global $speedycache;
if(!class_exists('\SpeedyCache\Enhanced')){
return;
}
preg_match_all('/<script\s+([^>]+[\s"\'])?src\s*=\s*[\'"]\s*?(?<url>[^\'"]+\.js(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?><\/script>/is', $content, $tags, PREG_SET_ORDER);
if(empty($tags)){
return;
}
if(empty($_SERVER['HTTP_HOST'])){
return;
}
$site_host = str_replace('www.', '', sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])));
$site_url = site_url();
foreach($tags as $tag){
if(empty($tag['url'])){
continue;
}
$url = $tag['url'];
if(self::is_excluded($url)) continue;
// We don't want to minify already minified js
if(strpos($url, '.min.js') !== FALSE){
continue;
}
// We wont process any css that is not present on this WordPress install
if(strpos($url, $site_host) === FALSE){
continue;
}
$file_path = Util::url_to_path($url);
if(!file_exists($file_path)){
continue;
}
$file_name = self::file_name($file_path);
if(empty($speedycache->enhanced)){
\SpeedyCache\Enhanced::init();
}
$js = file_get_contents($file_path);
$js = \SpeedyCache\Enhanced::minify_js($js);
$asset_path = Util::cache_path('assets');
if(!is_dir($asset_path)){
mkdir($asset_path, 0755, true);
touch($asset_path . 'index.html');
}
$minified_path = $asset_path.$file_name;
file_put_contents($minified_path, $js);
$minified_url = Util::path_to_url($minified_path);
$content = str_replace($tag['url'], $minified_url, $content);
// TODO: check if there is a preload.
}
}
static function combine_head(&$content){
global $speedycache;
if (preg_match('/<head.*?>(.*?)<\/head>/is', $content, $head_section)) {
$head = preg_replace( '/<!--(.*)-->/Uis', '', $head_section[1]);
// Regex pattern to match script tags with src attribute in the head section
preg_match_all('/<script\s+([^>]+[\s"\'])?src\s*=\s*[\'"]\s*?(?<url>[^\'"]+\.js(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?><\/script>/is', $head, $tags, PREG_SET_ORDER);
if(empty($tags)){
return;
}
if(empty($_SERVER['HTTP_HOST'])){
return;
}
$site_host = str_replace('www.', '', sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])));
$site_url = site_url();
$tags = array_reverse($tags);
// There is no sense in combinining just 2 files.
if(count($tags) < 2){
return;
}
$combined_js = '';
$prev_tag = '';
foreach($tags as $tag){
if(empty($tag['url'])){
continue;
}
// We wont combine modules.
if(!empty($tag[1]) && strpos($tag[1], 'module')){
continue;
}
$url = $tag['url'];
if(self::is_excluded($url)) continue;
// We wont process any js that is not present on this WordPress install
if(strpos($url, $site_host) === FALSE){
continue;
}
$file_path = Util::url_to_path($url);
if(!file_exists($file_path) || !is_readable($file_path)){
continue;
}
$combined_js = file_get_contents($file_path) . "\n" . $combined_js;
// Removing the JS which has already been combined, as we will add the combined file at the top after title.
if(!empty($prev_tag)){
$content = str_replace($prev_tag, '', $content);
}
// We remove the previous tag, in current iteration, so at last we have a tag to replace wirh the combined script.
$prev_tag = $tag[0];
}
if(empty($combined_js)){
return;
}
if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['minify_js'])){
if(empty($speedycache->enhanced)){
\SpeedyCache\Enhanced::init();
}
$combined_js = \SpeedyCache\Enhanced::minify_js($combined_js);
}
// Creating Combined file name
$file_name = md5($combined_js);
$file_name = substr($file_name, 0, 16) . '-combined.js';
$asset_path = Util::cache_path('assets');
if(!is_dir($asset_path)){
mkdir($asset_path, 0755, true);
touch($asset_path . 'index.html');
}
$combined_path = $asset_path.$file_name;
file_put_contents($combined_path, $combined_js);
$final_url = Util::path_to_url($combined_path);
// Injecting the Combined JS
if(!empty($prev_tag)){
$content = str_replace($prev_tag, '<script src="'.esc_url($final_url).'" />', $content);
return;
}
$content = str_replace('</title>', "</title>\n".'<script src="'.esc_url($final_url).'"/>', $content);
}
}
static function file_name($path){
$file_hash = md5_file($path);
$file_name = substr($file_hash, 0, 16) . '-' . basename($path);
return $file_name;
}
static function combine_body(&$content){
global $speedycache;
\SpeedyCache\Enhanced::init();
\SpeedyCache\Enhanced::set_html($content);
if(!empty($speedycache->options['minify_js'])){
$content = \SpeedyCache\Enhanced::combine_js_in_footer(true);
}else{
$content = \SpeedyCache\Enhanced::combine_js_in_footer();
}
}
static function is_excluded($url){
$excludes = get_option('speedycache_exclude', []);
// Combining JQUERY will mess up the site.
if(strpos($url, 'jquery')){
return true;
}
if(empty($excludes)){
return false;
}
foreach($excludes as $exclude){
if(empty($exclude['type'])){
continue;
}
if($exclude['type'] !== 'js'){
continue;
}
if(empty($exclude['content'])){
continue;
}
if(preg_match('/'.preg_quote($exclude['content'], '/').'/', $url)){
return true;
}
}
return false;
}
}
gravatar.php 0000644 00000006172 15152641416 0007077 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('Hacking Attempt');
}
class Gravatar{
// Gets gravatar data
static function get_avatar_data($args, $id_or_email){
if(empty($args) || empty($args['found_avatar'])){
return $args;
}
if(empty($args['url'])){
return $args;
}
// Path to Gravatars
$path = \SpeedyCache\Util::cache_path('gravatars');
if(!is_dir($path)){
mkdir($path, 0755, true);
touch($path . 'index.html');
}
$email_hash = self::get_email_hash($id_or_email);
if(empty($email_hash)){
$email_hash = 'default';
}
$file_name = $email_hash . 'x' . $args['size'] . '.jpg';
$file = $path . $file_name;
if(file_exists($file)){
$url = self::convert_path_to_link($path) . $file_name;
$args['url'] = esc_url($url);
return $args;
}
$res = wp_remote_get($args['url']);
if(empty($res) || is_wp_error($res)){
return $args;
}
if(empty($res['body'])){
return $args;
}
// If we fail to write return the same URL;
if(!file_put_contents($file, $res['body'])){
return $args;
}
$url = self::convert_path_to_link($path) . $file_name;
$args['url'] = esc_url($url);
return $args;
}
// Gets the Email hash which is used in the URL.
static function get_email_hash($id_or_email){
if(is_numeric($id_or_email)){
$user = get_user_by('id', $id_or_email);
if(empty($user) || !is_a($user, 'WP_User')){
return false;
}
} elseif(is_a($id_or_email, 'WP_User')){
$user = $id_or_email;
} elseif(is_a($id_or_email, 'WP_Post')){
$user = get_user_by('id', (int) $id_or_email->post_author);
} elseif(is_a($id_or_email, 'WP_Comment')){
if(!empty($id_or_email->user_id)){
$user = get_user_by('id', (int) $id_or_email->user_id);
}
if(empty($user) && !empty($id_or_email->comment_author_email)){
$id_or_email = $id_or_email->comment_author_email;
}
if(is_a($id_or_email, 'WP_Comment')){
return false;
}
}
if(!empty($user) && is_a($user, 'WP_User')){
$id_or_email = $user->user_email;
}
// We need an email which should be a string if something else is being passed then just return
if(!is_string($id_or_email)){
return false;
}
$email_hash = md5(strtolower(trim($id_or_email)));
return $email_hash;
}
// Deletes all the gravatar stored
static function delete(){
$path = \SpeedyCache\Util::cache_path('gravatars');
if(!file_exists($path)){
return;
}
$files = scandir($path);
if(empty($files)){
return __('No file present to delete', 'speedycache');
}
foreach($files as $file){
// We dont want to delete index.html or any directory.
if(file_exists($path . $file) && !is_dir($path . $file) && $file != 'index.html'){
@unlink($path . $file);
}
}
return __('Gravatar files deleted', 'speedycache');
}
static function convert_path_to_link($path){
preg_match('/\/cache\/speedycache\/.+/', $path, $out);
$prefix_link = str_replace(array('http:', 'https:'), '', content_url());
return $prefix_link . $out[0];
}
}
install.php 0000644 00000013277 15152641416 0006742 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Install{
static function activate(){
self::default_settings();
update_option('siteseo_version', SITESEO_VERSION);
}
static function deactivate(){
flush_rewrite_rules();
}
static function uninstall(){
flush_rewrite_rules();
delete_option('siteseo_version');
delete_option('siteseo_toggle');
delete_option('siteseo_titles_option_name');
delete_option('siteseo_social_option_name');
delete_option('siteseo_advanced_option_name');
delete_option('siteseo_instant_indexing_option_name');
delete_option('siteseo_xml_sitemap_option_name');
delete_option('siteseo_google_analytics_option_name');
delete_option('siteseo_dismiss_intro');
}
static function action_links($links, $file){
if($file === plugin_basename(SITESEO_FILE)){
$links['siteseo-settings'] = '<a href="'.admin_url('admin.php?page=siteseo').'">'. __('Settings', 'siteseo').'</a>';
$links['siteseo-wizard'] = '<a href="'.admin_url('?page=siteseo-onboarding').'">'. __('Configuration Wizard', 'siteseo').'</a>';
$links['siteseo-docs-link'] = '<a href="https://siteseo.io/docs/" target="_blank"">'. __('Docs', 'siteseo').'</a>';
}
return $links;
}
static function default_settings(){
// We do not need to set defaults if we just upgrading the plugin
$current_version = get_option('siteseo_version');
if(!empty($current_version)){
return;
}
$titles_metas = get_option('siteseo_titles_option_name', []);
$social_settings = get_option('siteseo_social_option_name', []);
$advanced_settings = get_option('siteseo_advanced_option_name', []);
$sitemap_settings = get_option('siteseo_xml_sitemap_option_name', []);
$toggle_settings = [
'toggle-titles' => true,
'toggle-xml-sitemap' => true,
'toggle-instant-indexing' => true,
'toggle-advanced' => true,
'toggle-social' => true,
'toggle-google-analytics' => true
];
// Titles and Metas
$titles_metas['titles_sep'] = '-';
$titles_metas['titles_home_site_title'] = !isset($titles_metas['titles_home_site_title']) ? '%%sitetitle%%' : $titles_metas['titles_home_site_title'];
$titles_metas['titles_home_site_desc'] = !isset($titles_metas['titles_home_site_desc']) ? '%%tagline%%' : $titles_metas['titles_home_site_desc'];
$post_types = siteseo_post_types();
if(!empty($post_types) && is_array($post_types)){
$post_types = array_keys($post_types);
foreach($post_types as $post_type){
$titles_metas['titles_single_titles'][$post_type]['title'] = !isset($titles_metas['titles_single_titles'][$post_type]['title']) ? '%%post_title%% %%sep%% %%sitetitle%%' : $titles_metas['titles_single_titles'][$post_type]['title'];
$titles_metas['titles_single_titles'][$post_type]['description'] = !isset($titles_metas['titles_single_titles'][$post_type]['description']) ? '%%post_excerpt%% ' : $titles_metas['titles_single_titles'][$post_type]['description'];
}
}
$taxonomies = get_taxonomies(array('public' => true), 'objects');
if(!empty($taxonomies) && is_array($taxonomies)){
$taxonomies = array_keys($taxonomies);
foreach($taxonomies as $taxonomy){
$titles_metas['titles_tax_titles'][$taxonomy]['title'] = !isset($titles_metas['titles_tax_titles'][$taxonomy]['title']) ? '%%_category_title%% %%sep%% %%sitetitle%%' : $titles_metas['titles_tax_titles'][$taxonomy]['title'];
$titles_metas['titles_tax_titles'][$taxonomy]['description'] = !isset($titles_metas['titles_tax_titles'][$taxonomy]['description']) ? '%%_category_description%%' : $titles_metas['titles_tax_titles'][$taxonomy]['description'];
}
}
$titles_metas['titles_archives_author_title'] = !isset($titles_metas['titles_archives_author_title']) ? '%%post_author%% %%sep%% %%sitetitle%%' : $titles_metas['titles_archives_author_title'];
$titles_metas['titles_archives_author_noindex'] = !isset($titles_metas['titles_archives_author_noindex']) ? true : '';
$titles_metas['titles_archives_date_title'] = !isset($titles_metas['titles_archives_date_title']) ? '%%archive_date%% %%sep%% %%sitetitle%%' : '';
$titles_metas['titles_archives_date_noindex'] = !isset($titles_metas['titles_archives_date_noindex']) ? true : '';
$titles_metas['titles_archives_search_title_noindex'] = !isset($titles_metas['titles_archives_search_title_noindex']) ? true : '';
$titles_metas['titles_nositelinkssearchbox'] = !isset($titles_metas['titles_nositelinkssearchbox']) ? true : '';
$titles_metas['titles_archives_search_title'] = !isset($titles_metas['titles_archives_search_title']) ? '%%search_keywords%% %%sep%% %%sitetitle%%' : '';
$titles_metas['titles_archives_404_title'] = !isset($titles_metas['titles_archives_404_title']) ? '404 - Page not found %%sep%% %%sitetitle%%' : $titles_metas['titles_archives_404_title'];
// Social
$social_settings['social_twitter_card'] = true;
$social_settings['social_facebook_og'] = true;
// Sitemap
$sitemap_settings['xml_sitemap_general_enable'] = true;
$sitemap_settings['xml_sitemap_post_types_list']['post']['include'] = true;
$sitemap_settings['xml_sitemap_post_types_list']['page']['include'] = true;
$sitemap_settings['xml_sitemap_taxonomies_list']['category']['include'] = true;
$sitemap_settings['xml_sitemap_img_enable'] = true;
// Advanced
$advanced_settings['advanced_attachments'] = true;
$advanced_settings['appearance_universal_metabox'] = true;
update_option('siteseo_toggle', $toggle_settings);
update_option('siteseo_titles_option_name', $titles_metas);
update_option('siteseo_social_option_name', $social_settings);
update_option('siteseo_xml_sitemap_option_name', $sitemap_settings);
update_option('siteseo_advanced_option_name', $advanced_settings);
}
}
settings.php 0000644 00000313541 15152641416 0007131 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Settings{
static function base(){
global $speedycache;
if(!file_exists(SPEEDYCACHE_CACHE_DIR) || !is_writable(WP_CONTENT_DIR)){
echo '<div class="notice notice-error">
<p><strong>Error:</strong> '.esc_html__('SpeedyCache was not able to create the cache directory, there might be a permission issue with the '.(defined('SITEPAD') ? 'sitepad-data' : 'wp-content').' directory.', 'speedycache').'</p>
</div>';
}
echo '<div id="speedycache-admin">
<div id="speedycache-navigation">
<div class="speedycache-logo">
<img src="'.esc_url(SPEEDYCACHE_URL . '/assets/images/speedycache.png').'" alt="SpeedyCache Logo" width="200" height="35">
<span>version '.esc_html(SPEEDYCACHE_VERSION).'</span>
</div>
<ul>
<li><a href="#"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/dashboard.svg"/>Dashboard</a></li>
<li><a href="#cache"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/cache.svg"/>Cache</a></li>
<li><a href="#file"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/file.svg"/>File Optimization</a></li>
<li><a href="#excludes"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/excludes.svg"/>Excludes</a></li>
<li><a href="#preload"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/preload.svg"/>Preloading</a></li>
<li><a href="#media"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/media.svg"/>Media</a></li>
<li><a href="#cdn"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/cdn.svg"/>CDN</a></li>';
if(!defined('SITEPAD')){
echo '<li><a href="#object"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/object.svg"/>Object Cache</a></li>';
}
echo' <li><a href="#image"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/image.svg"/>Image Optimization</a></li>';
if(!defined('SITEPAD')){
echo '<li><a href="#bloat"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/broom.svg"/>Bloat</a></li>';
}
echo' <li><a href="#db"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/db.svg"/>Database</a></li>
<li><a href="#settings"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/settings.svg"/>Settings</a></li>';
if(!defined('SITEPAD') && defined('SPEEDYCACHE_PRO')){
echo '<li><a href="#license"><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/license.svg"/> License</a></li>';
}
echo '<ul>
</div>
<div class="speedycache-tabs">
<div class="speedycache-tab" id="speedycache-dashboard">';
self::dashboard_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-cache">';
self::cache_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-file">';
self::file_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-preload">';
self::preload_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-media">';
self::media_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-excludes">';
self::excludes_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-cdn">';
self::cdn_tab();
echo '</div>
<div class="speedycache-tab" id="speedycache-image">';
do_action('speedycache_image_optm_tmpl');
if(!defined('SPEEDYCACHE_PRO') || (defined('SPEEDYCACHE_PRO_VERSION') && version_compare(SPEEDYCACHE_PRO_VERSION, '1.2.0', '<'))){
self::pro_notice('Image Optimization');
}
echo '</div>
<div class="speedycache-tab" id="speedycache-object">';
do_action('speedycache_object_cache_tmpl');
if(!defined('SPEEDYCACHE_PRO') || (defined('SPEEDYCACHE_PRO_VERSION') && version_compare(SPEEDYCACHE_PRO_VERSION, '1.2.0', '<'))){
self::pro_notice('Object Cache');
}
echo '</div>
<div class="speedycache-tab" id="speedycache-bloat">';
do_action('speedycache_bloat_tmpl');
if(!defined('SPEEDYCACHE_PRO') || (defined('SPEEDYCACHE_PRO_VERSION') && version_compare(SPEEDYCACHE_PRO_VERSION, '1.2.0', '<'))){
self::pro_notice('Bloat Settings');
}
echo '</div>
<div class="speedycache-tab" id="speedycache-db">';
do_action('speedycache_db_tmpl');
if(!defined('SPEEDYCACHE_PRO') || (defined('SPEEDYCACHE_PRO_VERSION') && version_compare(SPEEDYCACHE_PRO_VERSION, '1.2.0', '<'))){
self::pro_notice('DB Optimization');
}
echo '</div>
<div class="speedycache-tab" id="speedycache-settings">';
self::settings_tab();
echo '</div>';
if(!defined('SITEPAD')) {
do_action('speedycache_license_tmpl');
}
echo '</div>';
if(!defined('SITEPAD')) {
echo '<div class="speedycache-sidebar">
<div class="speedycache-need-help">
<p>Quick Access</p>
<div class="speedycache-quick-links">
<div class="speedycache-quick-access-item">
<span class="dashicons dashicons-format-status"></span>
<a href="https://softaculous.deskuss.com/open.php?topicId=19" target="_blank">Support</a>
</div>
<div class="speedycache-quick-access-item">
<span class="dashicons dashicons-media-document"></span>
<a href="https://speedycache.com/docs/" target="_blank">Documentation</a>
</div>
<div class="speedycache-quick-access-item">
<span class="dashicons dashicons-feedback"></span>
<a href="https://softaculous.deskuss.com/open.php?topicId=19" target="_blank">Feedback</a>
</div>
<div class="speedycache-quick-access-item">
<span class="dashicons dashicons-star-filled"></span><a href="https://wordpress.org/support/plugin/speedycache/reviews/?rate=5#new-post" target="_blank">Rate Us</a>
</div>
</div>
</div>';
if(!defined('SPEEDYCACHE_PRO')){
self::pro_upsell();
}
echo '</div>';
}
echo '</div>';
}
static function dashboard_tab(){
global $speedycache;
$speed_results = get_option('speedycache_pagespeed_test', []);
$speed_score = 0;
$speed_colors = ['#0c6', '#00cc663b', '#080'];
if(!empty($speed_results)){
$speed_colors = Util::pagespeed_color($speed_results['score']);
$speed_score = $speed_results['score'];
}
$speedycache->object_memory = 'None';
if(!empty($speedycache->object['enable']) && class_exists('Redis') && class_exists('\SpeedyCache\ObjectCache')){
try{
$speedycache->object_memory = \SpeedyCache\ObjectCache::get_memory();
} catch(\Exception $e) {
$memory = 'None';
}
}
$license_expires = '';
if(defined('SPEEDYCACHE_PRO') && !empty($speedycache->license['expires'])){
$license_expires = $speedycache->license['expires'];
$license_expires = substr($license_expires, 0, 4).'/'.substr($license_expires, 4, 2).'/'.substr($license_expires, 6);
}
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/dashboard.svg" height="32" width="32"/> Dashboard</h2>
<div class="speedycache-admin-row">
<div class="speedycache-perf-score speedycache-is-block">
<div class="speedycache-perf-score-meter-heading">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="24" height="24"><path d="M349.4 44.6c5.9-13.7 1.5-29.7-10.6-38.5s-28.6-8-39.9 1.8l-256 224c-10 8.8-13.6 22.9-8.9 35.3S50.7 288 64 288H175.5L98.6 467.4c-5.9 13.7-1.5 29.7 10.6 38.5s28.6 8 39.9-1.8l256-224c10-8.8 13.6-22.9 8.9-35.3s-16.6-20.7-30-20.7H272.5L349.4 44.6z"/></svg>
<h4>Performance Score <span id="speedycache-analyze">[Analyze]<span class="speedycache-spinner"></span></span></h4>
</div>
<div class="speedycache-perf-score-meter">
<div class="speedycache-perf-score-donut">
<svg width="80%" height="80%" viewBox="0 0 40 40">
<circle cx="20" cy="20" r="15.91549430918954" fill="'.esc_attr($speed_colors[1]).'"></circle>
<circle cx="20" cy="20" r="15.91549430918954" fill="transparent" stroke-width="2" stroke-linecap="round" stroke-dasharray="'.esc_html($speed_score).' '.esc_html(100 - $speed_score).'" stroke-dashoffset="25" style="stroke:'.esc_attr($speed_colors[0]).';"></circle>
<g class="speedycache-donut-text speedycache-donut-text-1">
<text y="56%" transform="translate(0, 2)">
<tspan x="50%" text-anchor="middle" style="fill:'.esc_attr($speed_colors[2]).'">'.esc_html($speed_score).'</tspan>
</text>
</g>
</svg>
</div>
<div class="speedycache-perf-score-guide">
<div>
<span style="background-color:#f33;"></span>
0-49
</div>
<div>
<span style="background-color:#fa3;"></span>
50-89
</div>
<div>
<span style="background-color:#0c6;"></span>
90-100
</div>
</div>
</div>
</div>
<div class="speedycache-dashboard-info">';
if(!defined('SITEPAD')){
echo'
<div class="speedycache-licence-brief speedycache-is-block">
<h4>License</h4>
<span>Version: '.esc_html(SPEEDYCACHE_VERSION).'</span>
<span>Status: '.(!defined('SPEEDYCACHE_PRO') ? 'Free' : (!empty($speedycache->license) && defined('SPEEDYCACHE_PRO') ? 'Pro' : 'License not Linked')).'</span>
<span>Expires on: '.(!defined('SPEEDYCACHE_PRO') ? 'Never' : (!empty($speedycache->license) && !empty($license_expires) ? esc_html($license_expires) : '')).'</span>
</div>';
}
echo'
<div class="speedycache-is-block">
<h4>Cache Info</h4>
<span>File Cache: '.(!empty($speedycache->options['status']) ? esc_html__('Enabled', 'speedycache') : esc_html__('Disabled', 'speedycache')).'</span>';
if(!defined('SITEPAD')){
echo'<span>Object Cache: '.(!empty($speedycache->object['enable']) ? esc_html__('Enabled', 'speedycache') : esc_html__('Disabled', 'speedycache')).'</span>';
}
echo'
<span>CDN: '.(!empty($speedycache->cdn) && !empty($speedycache->cdn['cdn_type']) ? esc_html(ucfirst($speedycache->cdn['cdn_type'])) : 'OFF').'</span>
</div>
</div>
</div>';
// TODO: Need to add this stats code in the Pro version.
if(defined('SPEEDYCACHE_PRO')){
do_action('speedycache_pro_stats_tmpl');
}
echo '<h3>Manage Cache</h3>
<form method="POST" action="'.esc_url(admin_url('admin-post.php')).'">';
wp_nonce_field('speedycache_post_nonce');
echo '<input type="hidden" value="speedycache_delete_cache" name="action"/>
<div class="speedycache-option-wrap">
<label for="speedycache_delete_minified" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_delete_minified" name="minified"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Delete Minified', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Deletes Minfied/ Combined CSS/JS files', 'speedycache').'</span>
</div>
</div>';
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_delete_fonts" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_delete_fonts" name="fonts"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Delete Fonts', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Deletes Local Google Fonts', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_delete_gravatars" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_delete_gravatars" name="gravatars"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Delete Gravatars', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Delete locally hosted Gravatars.', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_preload_cache" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_preload_cache" name="preload_cache"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Preload Cache', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('After cache gets deleted, it restarts auto cache generation.', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<div class="submit">
<input type="submit" value="'.esc_html__('Clear all cache and the selections', 'speedycache').'" class="speedycache-button speedycache-btn-black"/>
</div>
</div>
</form>';
if(defined('SPEEDYCACHE_PRO')){
do_action('speedycache_pro_logs_tmpl');
}
}
static function cache_tab(){
global $speedycache;
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/cache.svg" height="32" width="32"/> Cache Settings</h2>
<form method="post">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" value="speedycache_save_cache_settings" name="action"/>
<div class="speedycache-option-wrap">
<label for="speedycache_enable_cache" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['status']) ? ' checked' : '').' id="speedycache_enable_cache" name="status"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Enable Cache', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Enables caching', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_mobile" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['mobile']) ? ' checked' : '').' id="speedycache_mobile" name="mobile"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Mobile Override', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Disable desktop cache display on mobile devices.', 'speedycache').'</span>
</div>
</div>';
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_mobile_theme" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['mobile_theme']) ? ' checked' : '').' id="speedycache_mobile_theme" name="mobile_theme"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Mobile Cache', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Separate cache for Mobile version of your website, modern themes don\'t require this', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label for="speedycache_mobile_theme" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_mobile_theme" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Mobile Cache', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Separate cache for Mobile version of your website, modern themes don\'t require this', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_preload" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['preload']) ? ' checked' : '').' id="speedycache_preload" name="preload"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Preload', 'speedycache').'
<span class="speedycache-modal-settings-link" setting-id="speedycache_preload" style="display:'.(!empty($speedycache->options['preload']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Create the cache of all the site automatically', 'speedycache').'</span>
</div>
</div>
<!--SpeedyCache Update Post Modal Starts Here-->
<div modal-id="speedycache_preload" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Preload Settings', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content">
<p style="color:#666;margin-top:0 !important;">'.esc_html__('Select the interval after which you want the preload to run', 'speedycache').'</p>
<div class="speedycache-form-input">
<label style="width:100%;">
<span style="font-weight:500; margin-bottom:5px">'.esc_html__('Select Preload interval', 'speedycache').'</span>
<select name="preload_interval" value="'.(!empty($speedycache->options['preload_interval']) ? esc_attr($speedycache->options['preload_interval']) : '').'">
<option value="2" '.(isset($speedycache->options['preload_interval']) ? selected($speedycache->options['preload_interval'], '2', false) : '').'>'.esc_html__('Every 2 hours', 'speedycache').'</option>
<option value="6" '.(isset($speedycache->options['preload_interval']) ? selected($speedycache->options['preload_interval'], '6', false) : '').'>'.esc_html__('Every 6 hours', 'speedycache').'</option>
<option value="12" '.(isset($speedycache->options['preload_interval']) ? selected($speedycache->options['preload_interval'], '12', false) : '').'>'.esc_html__('Every 12 hours', 'speedycache').'</option>
<option value="24" '.(isset($speedycache->options['preload_interval']) ? selected($speedycache->options['preload_interval'], '24', false) : '').'>'.esc_html__('Once a day', 'speedycache').'</option>
<option value="168" '.(isset($speedycache->options['preload_interval']) ? selected($speedycache->options['preload_interval'], '168', false) : '').'>'.esc_html__('Once a week', 'speedycache').'</option>
</select>
</label>
</div>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_lbc" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_lbc" name="lbc" '.(!empty($speedycache->options['lbc']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Browser Caching', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Stores web data locally for faster loading.', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_logged_in_user" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['logged_in_user']) ? ' checked' : '').' id="speedycache_logged_in_user" name="logged_in_user"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Logged-in Users', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Serve cached version to logged in user.', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_gzip_compression" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['gzip']) ? ' checked' : '').' id="speedycache_gzip_compression" name="gzip"/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('GZIP Compressions', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Compresses the text files to reduce the size to be sent on the network.', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_purge_varnish" class="speedycache-custom-checkbox">
<input type="checkbox" '.(!empty($speedycache->options['purge_varnish']) ? ' checked' : '').' id="speedycache_purge_varnish" name="purge_varnish" />
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Purge Varnish', 'speedycache').'
<span class="speedycache-modal-settings-link" setting-id="speedycache_purge_varnish" style="display:'.(!empty($speedycache->options['purge_varnish']) ? 'inline-block' : 'none').';">- Settings</span>
</span>
<span class="speedycache-option-desc">'.esc_html__('Deletes cache created by Varnish on Deletion of cache from SpeedyCache', 'speedycache').'</span>
</div>
</div>
<!--SpeedyCache Update Post Modal Starts Here-->
<div modal-id="speedycache_purge_varnish" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Varnish Settings', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content">
<p style="color:#666;margin-top:0 !important;">'.esc_html__('If you use any different IP for Varnish than the default then set it here.', 'speedycache').'</p>
<div class="speedycache-form-input">
<label style="width:100%;">
<span style="font-weight:500; margin-bottom:5px">'.esc_html__('Set your Varnish IP', 'speedycache').'</span>
<input type="text" name="varniship" style="width:100%;" value="'. (!empty($speedycache->options['varniship']) ? esc_attr($speedycache->options['varniship']) : '127.0.0.1').'"/><br/>
</label>
</div>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
<h3>'.esc_html__('Cache Lifespan', 'speedycache').'</h3>
<p>'.esc_html__('This defines the time after which the cache will be automatically deleted. Set to 0 to disable automatic cache deletion.', 'speedycache').'</p>
<input type="number" min="0" name="purge_interval" value="'.(isset($speedycache->options['purge_interval']) ? esc_html($speedycache->options['purge_interval']) : 24).'"/>
<select name="purge_interval_unit">
<option value="hours" '.(!empty($speedycache->options['purge_interval_unit']) ? selected($speedycache->options['purge_interval_unit'], 'hours', false) : ' selected').'>'.esc_html__('Hours', 'speedycache').'</option>
<option value="days" '.(!empty($speedycache->options['purge_interval_unit']) ? selected($speedycache->options['purge_interval_unit'], 'days', false) : '').'>'.esc_html__('Days', 'speedycache').'</option>
</select>
<div>
<input type="checkbox" id="speedycache-run-exact-time" name="purge_enable_exact_time" value="1" '.(!empty($speedycache->options['purge_enable_exact_time']) ? checked($speedycache->options['purge_enable_exact_time'], true, false) : '').'/>'.esc_html__('Run at exact time', 'speedycache').'
<div id="speedycache-exact-time-selector" style="'.(empty($speedycache->options['purge_enable_exact_time']) ? 'display:none;' : '').'">
<label>
<input type="time" name="purge_exact_time" value="'.(!empty($speedycache->options['purge_exact_time']) ? esc_attr($speedycache->options['purge_exact_time']) : '').'"/>'.esc_html__('Select exact time', 'speedycache').'
</label>
<p class="description">'.esc_html__('This is dependent on WP Cron, which does not guarantee execution at an exact time. For more details, ', 'speedycache').'<a href="https://speedycache.com/docs/caching/running-cache-lifespan-at-specific-time/" target="_blank">click here</a>
</div>
<div>
<input type="checkbox" name="auto_purge_fonts" value="1" '.(!empty($speedycache->options['auto_purge_fonts']) ? checked($speedycache->options['auto_purge_fonts'], true, false) : '').'/>'.esc_html__('Delete Fonts', 'speedycache').'
<input type="checkbox" name="auto_purge_gravatar" value="1" '.(!empty($speedycache->options['auto_purge_gravatar']) ? checked($speedycache->options['auto_purge_gravatar'], true, false) : '').'/>'.esc_html__(
'Delete Gravatar', 'speedycache').'
<p class="description">'.esc_html__('Deletion of these options only takes effect if the lifespan is more than 10 hours.', 'speedycache').'</p>
</div>
</div>
';
self::save_btn();
echo '</form>';
}
static function file_tab(){
global $speedycache;
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/file.svg" height="32" width="32"/> File Optimization</h2>
<form method="post">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" name="action" value="speedycache_save_file_settings"/>';
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_minify_html" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_minify_html" name="minify_html" '.(!empty($speedycache->options['minify_html']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Minify HTML', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Removes comments, extra spaces', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Minify HTML', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Removes comments, extra spaces', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_minify_css" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_minify_css" name="minify_css" '.(!empty($speedycache->options['minify_css']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Minify CSS', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('You can decrease the size of CSS files', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-option-wrap">
<label for="speedycache_combine_css" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_combine_css" name="combine_css" '.(!empty($speedycache->options['combine_css']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Combine CSS', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Combines CSS files to reduce HTTP requests', 'speedycache').'</span>
</div>
</div>';
// Critical CSS Option
if(!defined('SITEPAD')){
if(defined('SPEEDYCACHE_PRO') && !empty($speedycache->license) && !empty($speedycache->license['active'])){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_critical_css" class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" id="speedycache_critical_css" name="critical_css" '.(!empty($speedycache->options['critical_css']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Critical CSS', 'speedycache');
if(!empty($speedycache->options['critical_css'])){
echo ' -
<span class="speedycache-action-link" action-name="speedycache_critical_css">'.esc_html__('Create Now', 'speedycache').'</span>
|
<span class="speedycache-modal-settings-link" setting-id="speedycache_critical_css">'.esc_html__('Logs', 'speedycache').'</span>';
}
echo '</span><span class="speedycache-option-desc">'.esc_html__('It extracts the necessary CSS of the viewport on load to improve load speed.', 'speedycache').'</span>
</div>
</div>';
echo wp_kses(\SpeedyCache\CriticalCss::status_modal(), array_merge(wp_kses_allowed_html('post'), [
'div' => [
'modal-id' => true,
'class' => true,
'title' => true,
'style' => true,
]
]));
} else {
if(empty($speedycache->license) || empty($speedycache->license['active'])){
$need_key = true;
}
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Critical CSS', 'speedycache').' <span class="speedycache-premium-tag">'.(!empty($need_key) ? 'Link License Key' : 'Premium').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('It extracts the necessary CSS of the viewport on load to improve load speed.', 'speedycache').'</span>
</div>
</div>';
}
}
// Unused CSS
if(!defined('SITEPAD')){
if(defined('SPEEDYCACHE_PRO') && !empty($speedycache->license) && !empty($speedycache->license['active'])){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_unused_css" class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" id="speedycache_unused_css" name="unused_css" '.(!empty($speedycache->options['unused_css']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name" title="Unused CSS"><span>'.esc_html__('Unused CSS', 'speedycache').'</span><a href="https://speedycache.com/docs/file-optimization/how-to-remove-unused-css/" target="_blank"><span class="dashicons dashicons-info" style="font-size:14px"></span></a>
<span class="speedycache-modal-settings-link" setting-id="speedycache_unused_css" style="display:'.(!empty($speedycache->options['unused_css']) ? 'inline-block' : 'none').';">- Settings</span>
</span><span class="speedycache-option-desc">'.esc_html__('It removes the unused CSS.', 'speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_unused_css" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Unused CSS Settings', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<p>'.esc_html__('Extracts the CSS being used on the page.', 'speedycache').'</p>
<div>
<label>
<span style="font-weight:500; margin:20px 0 3px 0; display:block;">'.esc_html__('Load Unused CSS', 'speedycache').'</span>
<span class="speedycache-model-label-description" style="margin-bottom:5px;">'.esc_html__('Select the way you want the Unused CSS to load.', 'speedycache').'</span>
</label>
<input type="radio" id="speedycache_unusedcss_async" name="unusedcss_load" value="async" '.(empty($speedycache->options['unusedcss_load']) || (!empty($speedycache->options['unusedcss_load']) && $speedycache->options['unusedcss_load'] == 'async') ? 'checked' : '').'/>
<input type="radio" id="speedycache_unusedcss_interaction" name="unusedcss_load" value="interaction" '.(!empty($speedycache->options['unusedcss_load']) && $speedycache->options['unusedcss_load'] == 'interaction' ? 'checked' : '').'/>
<input type="radio" id="speedycache_unusedcss_remove" name="unusedcss_load" value="remove" '.(!empty($speedycache->options['unusedcss_load']) && $speedycache->options['unusedcss_load'] == 'remove' ? 'checked' : '').'/>
<div class="speedycache-radio-input">
<label for="speedycache_unusedcss_async">'.esc_html__('Asynchronously', 'speedycache').'</label>
<label for="speedycache_unusedcss_interaction">'.esc_html__('On User Interaction', 'speedycache').'</label>
<label for="speedycache_unusedcss_remove">'.esc_html__('Remove', 'speedycache').'</label>
</div>
</div>
<div class="speedycache-unusedcss-excludes">
<label for="speedycache_unused_css_exclude_stylesheets" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; display:block;">'.esc_html__('Exclude Stylesheets', 'speedycache').'</span>
<span class="speedycache-model-label-description">'.esc_html__('Enter the URL, name or the stylesheet to be excluded from removing unused CSS.', 'speedycache').'</span>
<textarea name="unused_css_exclude_stylesheets" id="speedycache_unused_css_exclude_stylesheets" rows="4" placeholder="Enter URL, CSS file name one per line">'.(!empty($speedycache->options['unused_css_exclude_stylesheets']) ? esc_html(implode("\n", $speedycache->options['unused_css_exclude_stylesheets'])) : '').'</textarea>
</label>
<br><br>
<label for="speedycache_unusedcss_include_selector" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; dispaly:block;">'.esc_html__('Include Selectors', 'speedycache').'</span>
<span class="speedycache-model-label-description">'.esc_html__('Enter Selectors you want to be included in used CSS', 'speedycache').'</span>
<textarea name="unusedcss_include_selector" id="speedycache_unusedcss_include_selector" rows="4" placeholder="Enter selector one per line">'.(!empty($speedycache->options['unusedcss_include_selector']) ? esc_html(implode("\n", $speedycache->options['unusedcss_include_selector'])) : '').'</textarea>
</label>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Unused CSS', 'speedycache').'<span class="speedycache-premium-tag">'.(!empty($need_key) ? 'Link License Key' : 'Premium').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('It removes the unused CSS from the page.', 'speedycache').'</span>
</div>
</div>';
}
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_minify_js" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_minify_js" name="minify_js" '.(!empty($speedycache->options['minify_js']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Minify JS', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('You can decrease the size of JS files', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<div class="speedycache-form-input">
<label class="speedycache-custom-checkbox">
<input type="checkbox"disabled/>
<div class="speedycache-input-slider"></div>
</label>
</div>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Minify JS', 'speedycache').'<span class="speedycache-premium-tag">Premium</span></span>
<span class="speedycache-option-desc">'.esc_html__('You can decrease the size of JS files', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_combine_js" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_combine_js" name="combine_js" '.(!empty($speedycache->options['combine_js']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Combine JS', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Reduce HTTP requests by Combining JS files', 'speedycache').'</span>
</div>
</div>';
// Delay JS option
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_delay_js" class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" id="speedycache_delay_js" name="delay_js" '.(!empty($speedycache->options['delay_js']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name"><span>'.esc_html__('Delay JS', 'speedycache').'</span><a href="https://speedycache.com/docs/file-optimization/how-to-delay-js-until-user-interaction/" target="_blank"><span class="dashicons dashicons-info" style="font-size:14px"></span></a>
<span class="speedycache-modal-settings-link" setting-id="speedycache_delay_js" style="display:'.(!empty($speedycache->options['delay_js']) ? 'inline-block' : 'none').';">- Settings</span>
</span><span class="speedycache-option-desc">'.esc_html__('Delays JS until user interaction(like scroll, click etc) to improve performance', 'speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_delay_js" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Delay JS', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<p>'.esc_html__('Delay All is a more aggressive option which can increase the chances of breaking the site too.', 'speedycache').'</p>
<input type="radio" id="speedycache_delayjs_selected" name="delay_js_mode" value="selected" '.(empty($speedycache->options['delay_js_mode']) || (!empty($speedycache->options['delay_js_mode']) && $speedycache->options['delay_js_mode'] == 'selected') ? 'checked' : '').'/>
<input type="radio" id="speedycache_delayjs_all" name="delay_js_mode" value="all" '.(!empty($speedycache->options['delay_js_mode']) && $speedycache->options['delay_js_mode'] == 'all' ? 'checked' : '').'/>
<div class="speedycache-radio-input">
<label for="speedycache_delayjs_selected">'.esc_html__('Delay Selected', 'speedycache').'</label>
<label for="speedycache_delayjs_all">'.esc_html__('Delay All', 'speedycache').'</label>
</div>
<div class="speedycache-delay_js_list">
<label for="speedycache_delay_js_excludes" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; display:block;">Scripts to exclude</span>
<span style="display:block; font-weight:400; font-size:12px; color: #2c2a2a;">Enter Below The Scipts that you no not want to be delayed.</span>
<textarea name="delay_js_excludes" id="speedycache_delay_js_excludes" rows="4" placeholder="jquery.min">'.(!empty($speedycache->options['delay_js_excludes']) && is_array($speedycache->options['delay_js_excludes']) ? esc_html(implode("\n", $speedycache->options['delay_js_excludes'])) : '').'</textarea>
</label>
<label for="speedycache_delay_js_scripts" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; dispaly:block;">Scripts to Delay</span>
<span style="display:block; font-weight:400; font-size:12px; color: #2c2a2a;">Enter the scripts that you want to be delayed like googletagmanager.com</span>
<textarea name="delay_js_scripts" id="speedycache_delay_js_scripts" rows="4" placeholder="googletagmanager.com">'.(!empty($speedycache->options['delay_js_scripts']) && is_array($speedycache->options['delay_js_scripts']) ? esc_html(implode("\n", $speedycache->options['delay_js_scripts'])) : '').'</textarea>
<h5>Suggestions</h5>
<p style="position: relative;">
<button class="speedycache-delay-suggestions">
<span>Use These</span>
<svg xmlns="http://www.w3.org/2000/svg" height="18px" viewBox="0 -960 960 960" width="18px" fill="#e3e3e3"><path d="M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z"/></svg>
</button>
<span class="speedycache-modal-scripts">
fbevents.js<br>
google-analytics.com<br>
adsbygoogle.js<br>
googletagmanager.com<br>
fbq(<br>
ga( \' <br>
ga(\'<br>
/gtm.js<br>
/gtag/js<br>
gtag(<br>
/gtm-<br>
/gtm.<br>
</span>
</p>
</label>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
</div>';
}else{
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Delay JS', 'speedycache').'<span class="speedycache-premium-tag">Premium</span></span>
</span><span class="speedycache-option-desc">'.esc_html__('Delays JS until user interaction(like scroll, click etc) to improve performance', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_render_blocking" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_render_blocking" name="render_blocking" '.(!empty($speedycache->options['render_blocking']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name" setting-id="speedycache_render_blocking">'.esc_html__('Defer JS', 'speedycache').'
<span class="speedycache-modal-settings-link" setting-id="speedycache_render_blocking" style="display:'.(!empty($speedycache->options['render_blocking']) ? 'inline-block' : 'none').';">- Settings</span>
</span><span class="speedycache-option-desc">'.esc_html__('Defers render-blocking JavaScript resources', 'speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_render_blocking" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Defer JS', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<div>
<label for="speedycache_render_blocking_excludes" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; display:block;">'.esc_html__('Exclude script from Render Blocking JS', 'speedycache').'</span>
<span style="display:block; font-weight:400; font-size:12px; color: #2c2a2a;">'.esc_html__('Add one script per line ,Enter the script URL or script ID', 'speedycache').'</span>
<textarea name="render_blocking_excludes" id="speedycache_render_blocking_excludes" rows="4" style="width:100%">'.(!empty($speedycache->options['render_blocking_excludes']) && is_array($speedycache->options['render_blocking_excludes']) ? esc_html(implode("\n", $speedycache->options['render_blocking_excludes'])) : '').'</textarea>
</label>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Defer JS', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Defers render-blocking JavaScript resources', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_disable_emojis" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_disable_emojis" name="disable_emojis" '. (!empty($speedycache->options['disable_emojis']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Disable Emojis', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('You can remove the emoji inline css and wp-emoji-release.min.js', 'speedycache').'</span>
</div>
</div>';
// Lazy Render HTML element
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_lazy_load_html" class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" id="speedycache_lazy_load_html" name="lazy_load_html" '.(!empty($speedycache->options['lazy_load_html']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name"><span>'.esc_html__('Lazy Render HTML Element', 'speedycache').'</span><a href="https://speedycache.com/docs/file-optimization/how-to-lazy-render-html-elements/" target="_blank"><span class="dashicons dashicons-info" style="font-size:14px"></span></a>
<span class="speedycache-modal-settings-link" setting-id="speedycache_lazy_load_html" style="display:'.(!empty($speedycache->options['lazy_load_html']) ? 'inline-block' : 'none').';">- Settings</span>
</span><span class="speedycache-option-desc">'.esc_html__('Lazy Render a HTML element(class or id) if not in view-port.', 'speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_lazy_load_html" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Lazy Render HTML Elements', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<p>'.esc_html__('Lazy Rendering HTML is usually good for Comments.', 'speedycache').'</p>
<div>
<label for="speedycache_lazy_load_html_elements" style="width:100%;">
<span style="font-weight:500; margin:20px 0 3px 0; display:block;">'.esc_html__('Elements to Lazy Render', 'speedycache').'</span>
<span style="display:block; font-weight:400; font-size:12px; color: #2c2a2a;">'.esc_html__('Add one element per line, use # as prefix for ID and . as prefix for class.', 'speedycache').'</span>
<textarea name="lazy_load_html_elements"id="lazy_load_html_elements" rows="4" style="width:100%">'.(!empty($speedycache->options['lazy_load_html_elements']) ? esc_html(implode("\n", $speedycache->options['lazy_load_html_elements'])) : '').'</textarea>
</label>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>
</div>';
}else{
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label for="speedycache_lazy_load_html" class="speedycache-custom-checkbox" style="margin-top:0;">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Lazy Render HTML Element', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
</span><span class="speedycache-option-desc">'.esc_html__('Lazy Render a HTML element(class or id) if not in view-port.', 'speedycache').'</span>
</div>
</div>';
}
self::save_btn();
echo '</form>';
}
static function preload_tab(){
global $speedycache;
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/preload.svg" height="32" width="32"/> Preload Settings</h2>
<form method="post">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" value="speedycache_save_preload_settings" name="action"/>';
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_critical_images" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_critical_images" name="critical_images" '.(!empty($speedycache->options['critical_images']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Preload Critical Images', 'speedycache').'
<span class="speedycache-modal-settings-link" setting-id="speedycache_critical_images" style="display:'.(!empty($speedycache->options['critical_images']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Preloads critical Images to improve LCP', 'speedycache').'</span>
</div>
</div>
<!--SpeedyCache Lazy Load Modal Starts here-->
<div modal-id="speedycache_critical_images" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Preload Critical Images', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<div class="speedycache-modal-block">
<p>'.esc_html__('Select the number of images you want to be preloaded.', 'speedycache').'</p>
<table>
<tr>
<th>'.esc_html__('Critical Image Count', 'speedycache').'</th>
<td>
<div class="speedycache-form-input">
<select name="critical_image_count" value="'.(!isset($speedycache->options['critical_image_count']) ? '' : esc_attr($speedycache->options['critical_image_count'])).'">';
$image_count = array('1','2','3','4','5');
foreach($image_count as $count){
echo '<option value="'.esc_attr($count).'" '. ((!empty($speedycache->options['critical_image_count']) && $speedycache->options['critical_image_count'] == $count ) ? ' selected' : '') .'>'.esc_html($count).'</option>';
}
echo '</select>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Preload Critical Images', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Preloads critical Images to improve LCP', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_instant_page" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_instant_page" name="instant_page" '.(!empty($speedycache->options['instant_page']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Instant Page', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Improves page load speed', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Instant Page', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Improves page load speed', 'speedycache').'</span>
</div>
</div>';
}
if ( !defined('SITEPAD') && (version_compare( get_bloginfo( 'version' ), '6.8', '>=' )) ) {
echo '<div class="speedycache-option-wrap">
<label for="speedycache_speculative_loading" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_speculative_loading" name="speculation_loading" '.(!empty($speedycache->options['speculation_loading']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Edit Speculative Loading', 'speedycache').' <span class="speedycache-modal-settings-link" setting-id="speedycache_speculative_loading" style="display:'.(!empty($speedycache->options['speculation_loading']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Change how aggresive you want preloading/prefetching to happen.','speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_speculative_loading" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Speculation Settings', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content">
<p style="color:#666;margin-top:0 !important;"></p>
<div class="speedycache-form-input">
<label style="width:100%;">
<span style="font-weight:500; margin-bottom:5px">'.esc_html__('Select the Speculation Mode', 'speedycache').'</span>
<select name="speculation_mode" value="'.(!empty($speedycache->options['speculation_mode']) ? esc_attr($speedycache->options['speculation_mode']) : '').'">
<option value="auto" '.(isset($speedycache->options['speculation_mode']) ? selected($speedycache->options['speculation_mode'], 'auto', false) : '').'>'.esc_html__('Auto', 'speedycache').'</option>
<option value="prefetch" '.(isset($speedycache->options['speculation_mode']) ? selected($speedycache->options['speculation_mode'], 'prefetch', false) : '').'>'.esc_html__('Prefetch', 'speedycache').'</option>
<option value="prerender" '.(isset($speedycache->options['speculation_mode']) ? selected($speedycache->options['speculation_mode'], 'prerender', false) : '').'>'.esc_html__('Prerender', 'speedycache').'</option>
<option value="disabled" '.(isset($speedycache->options['speculation_mode']) ? selected($speedycache->options['speculation_mode'], 'disabled', false) : '').'>'.esc_html__('Disabled', 'speedycache').'</option>
</select>
</label>
</div>
<div class="speedycache-form-input">
<label style="width:100%;">
<span style="font-weight:500; margin-bottom:5px">'.esc_html__('Select Eagerness', 'speedycache').'</span>
<select name="speculation_eagerness" value="'.(!empty($speedycache->options['speculation_eagerness']) ? esc_attr($speedycache->options['speculation_eagerness']) : '').'">
<option value="auto" '.(isset($speedycache->options['speculation_eagerness']) ? selected($speedycache->options['speculation_eagerness'], 'auto', false) : '').'>'.esc_html__('Auto', 'speedycache').'</option>
<option value="eager" '.(isset($speedycache->options['speculation_eagerness']) ? selected($speedycache->options['speculation_eagerness'], 'eager', false) : '').'>'.esc_html__('Eager', 'speedycache').'</option>
<option value="moderate" '.(isset($speedycache->options['speculation_eagerness']) ? selected($speedycache->options['speculation_eagerness'], 'moderate', false) : '').'>'.esc_html__('Moderate', 'speedycache').'</option>
<option value="conservative" '.(isset($speedycache->options['speculation_eagerness']) ? selected($speedycache->options['speculation_eagerness'], 'conservative', false) : '').'>'.esc_html__('Conservative', 'speedycache').'</option>
</select>
</label>
</div>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>';
}
if(!defined('SITEPAD')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_dns_prefetch" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_dns_prefetch" name="dns_prefetch" '.(!empty($speedycache->options['dns_prefetch']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('DNS Prefetch', 'speedycache').' <span class="speedycache-modal-settings-link" setting-id="speedycache_dns_prefetch" style="display:'.(!empty($speedycache->options['dns_prefetch']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('DNS prefetching can make external files load faster.', 'speedycache').'</span>
</div>
</div>
<div modal-id="speedycache_dns_prefetch" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Prefetch DNS Requests', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<h3>'.esc_html__('How DNS Prefetch can help?', 'speedycache').'</h3>
<p>'.esc_html__('DNS prefetch can improve page load performance by resolving domain names in advance, so that the browser can start loading resources from those domains as soon as possible.', 'speedycache').'</p>
<label><strong>'.esc_html__('URLs to prefetch', 'speedycache').'</strong>
<span style="display:block;">'.esc_html__('Specify external hosts to be prefetched (no http:, one per line)', 'speedycache').'</span>
<textarea name="dns_urls" style="width:100%" rows="4" placeholder="//example.com">'.(!empty($speedycache->options['dns_urls']) ? esc_html(implode("\n", $speedycache->options['dns_urls'])) : '').'</textarea>
</label>
</div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_preload_resources" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_preload_resources" name="preload_resources" '.(!empty($speedycache->options['preload_resources']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Preload Resources', 'speedycache').' <span class="speedycache-modal-settings-link" setting-id="speedycache_preload_resources" style="display:'.(!empty($speedycache->options['preload_resources']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Hints browser to load resources early.', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'. esc_html__('Preload Resources', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'. esc_html__('Hints browser to load resources early.', 'speedycache').'</span>
</div>
</div>';
}
if(!defined('SITEPAD')){
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_pre_connect" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_pre_connect" name="pre_connect" '. (!empty($speedycache->options['pre_connect']) ? 'checked' : '') .'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'. esc_html__('PreConnect', 'speedycache').' <span class="speedycache-modal-settings-link" setting-id="speedycache_pre_connect" style="display:'. (!empty($speedycache->options['pre_connect']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Establish early connections to speed up page load.', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'. esc_html__('Preconnect', 'speedycache') .'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'. esc_html__('Establish early connections to speed up page load.', 'speedycache').'</span>
</div>
</div>';
}
}
self::save_btn();
echo '</form>';
if(defined('SPEEDYCACHE_PRO')){
echo '<div modal-id="speedycache_preload_resources" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Preload Resource', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<form class="speedycache-pseudo-form" data-type="preload_resource_list">'.
wp_kses(self::preload_modal_options('preload_resource', ['type' => true, 'crossorigin' => true, 'priority' => true, 'device' => true]), [
'input' => ['type' => true, 'value' => true, 'style' => true, 'name' => true, 'placeholder' => true],
'option' => ['value' => true],
'select' => ['name' => true, 'required' => true],
'label' => ['for' => true, 'style' => true],
'div' => ['class' => true, 'style' => true],
'span' => ['class' => true, 'title' => true, 'spdf-hover-tooltip' => true, 'spdf-tooltip-position' => true],
]).'
<div style="display:flex; justify-content:center;">
<button type="submit" class="speedycache-button speedycache-btn-black speedycache-preloading-add">Add<span class="speedycache-spinner"></span></button>
</div>
</form>';
echo '<p><strong>Note:</strong> Preloading too many resources can actually slow down your website, so it\'s important to only preload the resources that are absolutely necessary for the initial load. These might include fonts, image, CSS or JS files.</p>';
echo '<div style="width:100%; overflow-x:scroll;"><table class="speedycache-table speedycache-preloading-table" data-type="preload_resource_list">
<thead>
<tr>
<th class="speedycache-table-hitem" scope="col" width="70%">'.esc_html__('Resource', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="15%">'. esc_html__('Type', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="10%"><abbr title="Crossorigin">'. esc_html__('CS', 'speedycache').'</abbr></th>
<th class="speedycache-table-hitem" scope="col" width="10%">'. esc_html__('Device', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="10%">'. esc_html__('Fetch Priority', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="5%"></th>
</tr>
</thead>
<tbody>';
if(empty($speedycache->options['preload_resource_list']) || !is_array($speedycache->options['preload_resource_list'])){
echo '<tr><td colspan="6" align="center" class="speedycache-preloading-empty">No Resource Preload added yet</td></tr>';
} else {
foreach($speedycache->options['preload_resource_list'] as $pkey => $preload_resource){
echo '<tr>
<td>'.esc_url($preload_resource['resource']).'</td>
<td>'.esc_html($preload_resource['type']).'</td>
<td>'.(!empty($preload_resource['crossorigin']) ? 'Yes' : 'No').'</td>
<td>'.(!empty($preload_resource['device']) ? esc_html($preload_resource['device']) : 'All').'</td>
<td>'.(!empty($preload_resource['fetch_priority']) ? esc_html(ucfirst($preload_resource['fetch_priority'])) : 'Auto').'</td>
<td data-key="'.esc_attr($pkey).'"><span class="dashicons dashicons-trash"></span></td>
</tr>';
}
}
echo '</tbody>
</table>
</div>
</div>
</div>
</div>';
if(!defined('SITEPAD')){
echo'
<div modal-id="speedycache_pre_connect" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'. esc_html__('Preconnect', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<form class="speedycache-pseudo-form" data-type="pre_connect_list">
'.wp_kses(self::preload_modal_options('pre_connect', ['crossorigin' => true]), [
'input' => ['type' => true, 'value' => true, 'style' => true, 'name' => true, 'placeholder' => true],
'option' => ['value' => true],
'select' => ['name' => true, 'required' => true],
'label' => ['for' => true, 'style' => true],
'div' => ['class' => true, 'style' => true],
'span' => ['aria-label' => true, 'data-microtip-position' => true, 'role' => true],
]).'
<div style="display:flex; justify-content:center;">
<button tabindex="" type="submit" class="speedycache-button speedycache-btn-black speedycache-preloading-add">Add<span class="speedycache-spinner"></span><span class="dashicons dashicons-yes speedycache-spinner-done"></span></button>
</div>
</form>';
if(!empty($speedycache->options['pre_connect_list']) && count($speedycache->options['pre_connect_list']) > 6){
echo '<p><strong>Note:</strong> A good rule of thumb is to limit the number of preconnects to 6-8. However, the exact number will vary depending on the specific website and the resources that are being loaded.</p>';
}
echo '<table class="speedycache-table speedycache-preloading-table" data-type="pre_connect_list">
<thead>
<tr>
<th class="speedycache-table-hitem" scope="col" width="80%">'.esc_html__('Resource', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="15%">'. esc_html__('Crossorigin', 'speedycache').'</th>
<th class="speedycache-table-hitem" scope="col" width="5%"></th>
</tr>
</thead>
<tbody>';
if(empty($speedycache->options['pre_connect_list']) || !is_array($speedycache->options['pre_connect_list'])){
echo '<tr><td colspan="4" align="center" class="speedycache-preloading-empty">'.esc_html__('No PreConnect added yet', 'speedycache').'</td></tr>';
} else {
foreach($speedycache->options['pre_connect_list'] as $pkey => $pre_connect){
echo '<tr>
<td>'.esc_html($pre_connect['resource']).'</td>
<td>'.(!empty($pre_connect['crossorigin']) ? 'Yes' : 'No').'</td>
<td data-key="'.esc_html($pkey).'"><span class="dashicons dashicons-trash"></span></td>
</tr>';
}
}
echo '</tbody>
</table>
</div>
</div>
</div>';
}
}
}
static function cdn_tab(){
global $speedycache;
$default_file_types = ['aac', 'css', 'eot', 'gif', 'jpeg', 'js', 'jpg', 'less', 'mp3', 'mp4', 'ogg', 'otf', 'pdf', 'png', 'svg', 'swf', 'ttf', 'webm', 'webp', 'woff', 'woff2'];
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/cdn.svg" height="32" width="32"/> CDN Settings</h2>
<form method="POST">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" value="speedycache_save_cdn_settings" name="action"/>
<div class="speedycache-option-wrap">
<label for="speedycache_enable_cdn" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_enable_cdn" name="enable_cdn" '.(!empty($speedycache->cdn['enabled']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Enable CDN', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('This will start rewriting asset URL\'s to the CDN URL', 'speedycache').'</span>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('Select CDN Provider', 'speedycache').'</label>
</div>
<div>
<select id="speedycache-cdn-type" name="cdn_type" value="'.(!empty($speedycache->cdn['cdn_type']) ? esc_attr($speedycache->cdn['cdn_type']) : '').'">
<option value="cloudflare" '. (!empty($speedycache->cdn['cdn_type']) ? selected($speedycache->cdn['cdn_type'], 'cloudflare', false) : '').'>Cloudflare</option>
<option value="bunny" '. (!empty($speedycache->cdn['cdn_type']) ? selected($speedycache->cdn['cdn_type'], 'bunny', false) : '').'>Bunny</option>
<option value="other" '. (!empty($speedycache->cdn['cdn_type']) ? selected($speedycache->cdn['cdn_type'], 'other', false) : '').'>Others</option>
</select>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('CDN URL', 'speedycache').'</label>
<span class="speedycache-option-desc">'.esc_html__('It is the URL that CDN Provider provides you.', 'speedycache').'</span>
</div>
<div>
<input type="url" name="cdn_url" style="width:50%;" value="'.(!empty($speedycache->cdn['cdn_url']) ? esc_url($speedycache->cdn['cdn_url']) : '').'" id="speedycache-cdn-url" placeholder="https://cdn-url.com"/>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('API Key', 'speedycache').'</label>
<span class="speedycache-option-desc">'.esc_html__('API keys/ tokens are not required but used to purge cache on CDN when cache from SpeedyCache gets purged.', 'speedycache').'</span>
</div>
<div>
<input type="text" name="cdn_key" style="width:50%;" id="speedycache-cdn-key" value="'.(!empty($speedycache->cdn['cdn_key']) ? esc_html($speedycache->cdn['cdn_key']) : '').'"/>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('File Types', 'speedycache').'</label>
<span class="speedycache-option-desc">'.esc_html__('Types of files you want to be served through the CDN(one file per line)', 'speedycache').'</span>
</div>
<div>
<textarea name="file_types" style="width:50%;" rows="5">'.(!empty($speedycache->cdn['file_types']) ? esc_html(implode("\n", $speedycache->cdn['file_types'])) : esc_html(implode("\n", $default_file_types))).'</textarea>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('Exclude Sources', 'speedycache').'</label>
<span class="speedycache-option-desc">'.esc_html__('Files you do not want to be rewritten to a CDN url(one file per line).', 'speedycache').'</span>
</div>
<div>
<textarea name="excludekeywords" style="width:50%;" rows="5">'.(!empty($speedycache->cdn['excludekeywords']) ? esc_html(implode("\n", $speedycache->cdn['excludekeywords'])) : '').'</textarea>
</div>
</div>
<div class="speedycache-stacked-option-wrap">
<div class="speedycache-option-info">
<label class="speedycache-option-name">'.esc_html__('Specific Sources', 'speedycache').'</label>
<span class="speedycache-option-desc">'.esc_html__('Specific files which you want to be rewritten using CDN URL(one file per line).', 'speedycache').'</span>
</div>
<div>
<textarea name="keywords" style="width:50%;" rows="5">'.(!empty($speedycache->cdn['keywords']) ? esc_html(implode("\n", $speedycache->cdn['keywords'])) : '').'</textarea>
</div>
</div>';
self::save_btn();
echo '</form>';
}
static function excludes_tab(){
$excludes = get_option('speedycache_exclude', []);
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/excludes.svg" height="32" width="32"/> Exclude Settings</h2>
<div class="speedycache-table-actions">
<div class="speedycache-table-filter">
<select id="speedycache-type-filter">
<option value="">All</option>
<option value="cookie">Cookies</option>
<option value="js">JS</option>
<option value="css">CSS</option>
<option value="useragent">User Agent</option>
<option value="page">Page</option>
</select>
</div>
<div class="speedycach-table-add-new"><button class="speedycache-button speedycache-btn-black" id="speedycache_add_excludes">'.esc_html__('Add New Rule', 'speedycache').'</button></div>
</div>
<div class="speedycache-table speedycache-exclude-list" id="speedycache-exclude-list">
<table>
<thead>
<tr role="row">
<th>Type</th>
<th>Prefix</th>
<th>Content</th>
<th>Actions</th>
</tr>
</thead>
<tbody>';
if(empty($excludes)){
echo '<tr role="row">
<td colspan="4">'.esc_html__('No exclude rule added yet','speedycache').'</td>
</tr>';
} else {
foreach($excludes as $id => $exclude){
echo '<tr role="row" data-id='.esc_attr($id).'>
<td>'.esc_html($exclude['type']).'</td>
<td>'.esc_html($exclude['prefix']).'</td>';
if($exclude['prefix'] == 'post_id'){
if(!is_array($exclude['content'])){
$exclude['content'] = explode(',', $exclude['content']);
}
echo '<td>'.'#ID:';
foreach($exclude['content'] as $exclude){
$post = get_post($exclude);
if(empty($post)){
continue;
}
$post_link = get_permalink($post->ID);
echo '<a href="'.esc_url($post_link).'" class="speedycache-tooltip-link" target="_blank">'.esc_html($exclude);
// We show a tool tip with the excluded page URL and title
echo '<div class="speedycache-link-tooltip">
<h4>'.esc_html($post->post_title).'</h4>
<p>'.esc_url($post_link).'</p>
</div></a>';
}
echo '</td>';
}
else{
echo'<td>'.esc_html($exclude['content']).'</td>';
}
echo'<td><button class="speedycache-button speedycache-delete-rule">Delete<span class="speedycache-spinner"></span></button>
</tr>';
}
}
echo '</tbody>
</table>
</div>
<div modal-id="speedycache_add_excludes" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Add Exclude Rule', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<form method="POST">
<input type="hidden" name="action" value="speedycache_save_excludes"/>';
wp_nonce_field('speedycache_ajax_nonce');
echo '<div class="speedycache-input-wrap">
<label for="speedycache-exclude-type">Exclude Type</label>
<select name="type" id="speedycache-exclude-type" class="speedycache-100" required>
<option value="page"/>Page</option>
<option value="useragent"/>User-Agent</option>
<option value="cookie"/>Cookie</option>
<option value="css"/>CSS</option>
<option value="js"/>JS</option>
</select>
</div>
<div class="speedycache-input-wrap">
<label for="speedycache-exclude-rule-prefix">Exclude</label>
<select name="prefix" id="speedycache-exclude-rule-prefix" class="speedycache-100" required>
<option selected="" value="" selected data-partof="page">Select a Value</option>
<option value="homepage" data-partof="page">Home Page</option>
<option value="category" data-partof="page">Categories</option>
<option value="tag" data-partof="page">Tags</option>
<option value="post" data-partof="page">Posts</option>
<option value="page" data-partof="page">Pages</option>
<option value="post_id" data-partof="page">Post ID</option>
<option value="shortcode" data-partof="page">Shortcode</option>
<option value="archive" data-partof="page">Archives</option>
<option value="attachment" data-partof="page">Attachments</option>
<option value="startwith" data-partof="page">Starts With</option>
<option value="contain" data-partof="page,useragent,cookie,css,js">Contains</option>
<option value="exact" data-partof="page">URI Is Equal To</option>';
if (!defined('SITEPAD')){
echo '<option value="woocommerce_items_in_cart" data-partof="cookie">has Woocommerce Items in Cart</option>';
}
echo'
</select>
</div>
<div class="speedycache-input-wrap" style="display:none;">
<label for="speedycache-exclude-rule-content">Content</label>
</div>
<div class="speedycache-exclude-btn-wrap">
<button class="speedycache-button speedycache-btn-black">'.esc_html__('Save Rule', 'speedycache').'<span class="speedycache-spinner"></button>
</div>
</form>
</div>
</div>
</div>';
}
static function media_tab(){
global $speedycache;
// Backward compatibility
if(!empty($speedycache->options['lazy_load_keywords']) && is_string($speedycache->options['lazy_load_keywords'])){
$speedycache->options['lazy_load_keywords'] = explode(',', $speedycache->options['lazy_load_keywords']);
}
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/media.svg" height="32" width="32"/> Media Settings</h2>
<form method="POST">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" name="action" value="speedycache_save_media_settings"/>';
if(!defined('SITEPAD')){
echo'
<div class="speedycache-option-wrap">
<label for="speedycache_gravatar_cache" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_gravatar_cache" name="gravatar_cache" '.(!empty($speedycache->options['gravatar_cache']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Gravatar Cache', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Locally host Gravatar', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<input type="hidden" value="'.(isset($speedycache->options['lazy_load_placeholder']) ? esc_attr($speedycache->options['lazy_load_placeholder']) : '').'" id="speedycache_lazy_load_placeholder" name="lazy_load_placeholder"/>
<input style="display: none;" type="checkbox" '.(isset($speedycache->options['lazy_load_exclude_full_size_img']) ? esc_attr($speedycache->options['lazy_load_exclude_full_size_img']) : '').' id="speedycache_lazy_load_exclude_full_size_img" name="lazy_load_exclude_full_size_img">
<label for="speedycache_lazy_load" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_lazy_load" name="lazy_load" '.(!empty($speedycache->options['lazy_load']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Lazy Load', 'speedycache').' <span class="speedycache-modal-settings-link" setting-id="speedycache_lazy_load" style="display:'.(!empty($speedycache->options['lazy_load']) ? 'inline-block' : 'none').';">- Settings</span></span>
<span class="speedycache-option-desc">'.esc_html__('Load images and iframes when they enter the browsers viewport', 'speedycache').'</span>
</div>
</div>
<!--SpeedyCache Lazy Load Modal Starts here-->
<div modal-id="speedycache_lazy_load" class="speedycache-modal">
<div class="speedycache-modal-wrap">
<div class="speedycache-modal-header">
<div>'.esc_html__('Lazy Load Settings', 'speedycache').'</div>
<div title="Close Modal" class="speedycache-close-modal">
<span class="dashicons dashicons-no"></span>
</div>
</div>
<div class="speedycache-modal-content speedycache-info-modal">
<div class="speedycache-modal-block">
<h4>'.esc_html__('Image Placeholder', 'speedycache').'</h4>
<p>'.esc_html__('Specify an image to be used as a placeholder while other images finish loading.', 'speedycache').'
<a target="_blank" href="https://speedycache.com/docs/miscellaneous/lazy-load-images-and-iframes/">
<span class="dashicons dashicons-info"></span>
</a>
</p>
<div class="speedycache-form-input">
<select name="lazy_load_placeholder" id="speedycache-ll-type" class="speedycache_lazy_load_placeholder speedycache-100" value="'.(!isset($speedycache->options['lazy_load_placeholder']) ? '' : esc_attr($speedycache->options['lazy_load_placeholder'])).'">
<option value="default" '.((isset($speedycache->options['lazy_load_placeholder']) && $speedycache->options['lazy_load_placeholder'] == 'default') ? 'selected' : '').'>'.esc_html(preg_replace("/https?\:\/\//", '', esc_url(SPEEDYCACHE_URL))).'/assets/images/image-palceholder.png'.'</option>
<option value="custom" '.((isset($speedycache->options['lazy_load_placeholder']) && $speedycache->options['lazy_load_placeholder'] == 'custom') ? 'selected' : '').'>'.esc_html__('Custom Placeholder', 'speedycache').'</option>
</select>
</div>';
$hide_css_class = '';
if(isset($speedycache->options['lazy_load_placeholder']) && $speedycache->options['lazy_load_placeholder'] != 'custom'){
$hide_css_class = 'speedycache-hidden ';
}
echo '<div class="speedycache-form-input">
<input type="text" id="speedycache-custom-ll-url" class="'.esc_attr($hide_css_class).'speedycache-100" placeholder="https://example.com/sample.jpg" name="lazy_load_placeholder_custom_url" value="'.(!isset($speedycache->options['lazy_load_placeholder_custom_url']) ? '' : esc_url($speedycache->options['lazy_load_placeholder_custom_url'])).'"/>
</div>
<div class="speedycache-modal-block">
<h4>'.esc_html__('Exclude above fold images', 'speedycache').'</h4>
<p>'.esc_html__('Number of images you want to exclude from getting lazyloaded from top of the screen', 'speedycache').'</p>
<select name="exclude_above_fold">';
foreach([0,1,2,3,4,5] as $exclude_no){
$selected = '';
if(isset($speedycache->options['exclude_above_fold']) && $exclude_no == $speedycache->options['exclude_above_fold']){
$selected = 'selected';
}elseif(!isset($speedycache->options['exclude_above_fold']) && $exclude_no == 2){
$selected = 'selected';
}
echo '<option value="'.esc_attr($exclude_no).'" '.esc_attr($selected).'>'.esc_html($exclude_no).'</option>';
}
echo '</select>
</div>
<div class="speedycache-modal-block">
<h4>'.esc_html__('Exclude Sources', 'speedycache').'</h4>
<p>'.esc_html__('It is enough to write a keyword such as', 'speedycache').' <strong>home.jpg or iframe or .gif</strong> instead of full url.</p>
<div class="speedycache-form-input">
<label for="speedycache-full-width">
'.esc_html__('Add Keyword', 'speedycache').'
<span class="speedycache-input-desc">('.esc_html__('one keyword per line', 'speedycache').')</span>
<textarea name="lazy_load_keywords" class="speedycache-100" rows="5">'.(empty($speedycache->options['lazy_load_keywords']) ? '' : esc_attr(implode("\n", $speedycache->options['lazy_load_keywords']))).'</textarea>
</label>
</div>';
echo '</div>
</div></div>
<div class="speedycache-modal-footer">
<button type="button" action="close">
<span>'.esc_html__('Submit', 'speedycache').'</span>
</button>
</div>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Lazy Load', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Load images and iframes when they enter the browsers viewport', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_image_dimensions" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_image_dimensions" name="image_dimensions" '.(!empty($speedycache->options['image_dimensions']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Image Dimensions', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Adds dimensions to the image, to reduce CLS', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Image Dimensions', 'speedycache').'<span class="speedycache-premium-tag">'. esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Adds dimensions to the image, to reduce CLS', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_local_gfonts" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_local_gfonts" name="local_gfonts" '. (!empty($speedycache->options['local_gfonts']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Local Google Fonts', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Loads google fonts from your local server', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox"disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Local Google Fonts', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Loads google fonts from your local server', 'speedycache').'</span>
</div>
</div>';
}
if(defined('SPEEDYCACHE_PRO')){
echo '<div class="speedycache-option-wrap">
<label for="speedycache_google_fonts" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_google_fonts" name="google_fonts" '.(!empty($speedycache->options['google_fonts']) ? ' checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Google Fonts', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Load Google Fonts asynchronously', 'speedycache').'</span>
</div>
</div>';
} else {
echo '<div class="speedycache-option-wrap speedycache-disabled">
<label class="speedycache-custom-checkbox">
<input type="checkbox" disabled/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Google Fonts', 'speedycache').'<span class="speedycache-premium-tag">'.esc_html__('Premium', 'speedycache').'</span></span>
<span class="speedycache-option-desc">'.esc_html__('Load Google Fonts asynchronously', 'speedycache').'</span>
</div>
</div>';
}
echo '<div class="speedycache-option-wrap">
<label for="speedycache_font_rendering" class="speedycache-custom-checkbox">
<input type="checkbox" id="speedycache_font_rendering" name="font_rendering" '. (!empty($speedycache->options['font_rendering']) ? 'checked' : '').'/>
<div class="speedycache-input-slider"></div>
</label>
<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Improve Font Rendering', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Improved Font rendeing by adding text-rendring CSS.', 'speedycache').'</span>
</div>
</div>';
self::save_btn();
echo '</form>';
}
static function settings_tab(){
echo '<h2><img src="'.esc_url(SPEEDYCACHE_URL).'/assets/images/icons/settings.svg" height="32" width="32"/> '.esc_html__('General Settings', 'speedycache').'</h2>';
$roles = get_editable_roles();
if(!empty($roles)){
$saved_roles = get_option('speedycache_deletion_roles', []);
echo '<div class="speedycache-option-info">
<span class="speedycache-option-name">'.esc_html__('Can Delete Cache', 'speedycache').'</span>
<span class="speedycache-option-desc">'.esc_html__('Allows roles to delete cache using Admin bar and post links, Admin is included by default', 'speedycache').'</span>
<form method="POST">';
wp_nonce_field('speedycache_ajax_nonce');
echo '<input type="hidden" name="action" value="speedycache_save_deletion_role_settings"/>
<div class="speedycache-deletion-roles">';
foreach($roles as $key => $role){
// Admin will always have access to everything, so no need to give option to be able to enable it.
if($key == 'administrator'){
continue;
}
// We need to make sure the user has capability to publish_posts
// Giving access to anyone other than this capability does not makes sense
// As giving option to enable subscriber could cause issue becuase of human error.
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts', $role['capabilities'])){
continue;
}
$checked = false;
if(in_array($key, $saved_roles)){
$checked = 'checked';
}
echo '<label for="speedycache-admin-bar-cap-'.esc_attr($key).'"><input type="checkbox" id="speedycache-admin-bar-cap-'.esc_attr($key).'"name="cache_deletion_roles[]" value="'.esc_attr($key).'" '.esc_attr($checked).'/>'.esc_html($role['name']).'</label>';
}
echo '</div>
<div class="speedycache-btn-spl-wrapper"><button class="speedycache-button speedycache-btn-black" style="margin-top:10px;">Save<span class="speedycache-spinner"></span></button></div></form></div>';
}
echo '<div class="speedycache-option-info" style="margin-top:20px;">
<label class="speedycache-option-name">'.esc_html__('Import / Export Settings', 'speedycache').'</label>
<span class="speedycache-option-desc" style="margin-bottom:10px;">'.esc_html__('Imports SpeedyCache Settings from another site or Exports your current SpeedyCache Settings as a JSON file', 'speedycache').'</span>
</div>
<div>
<select id="speedycache-import-export" name="img-exp">
<option value="import">Import</option>
<option value="export">Export</option>
</select>
</div>';
echo '<!-- Import Section -->
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="speedycache_import_settings"/>
<div class="speedycache-option-info speedycache-import-block" style="display:block;">
<span class="speedycache-option-desc">'.esc_html__('Select a JSON file containing SpeedyCache Settings. This will overwrite your current SpeedyCache Settings', 'speedycache').'</span>
<input type="file" name="speedycache_import_file" id="speedycache_import_file" accept=".json" required />
<button class="speedycache-button speedycache-btn-black speedycache-import-settings" style="margin-top:10px;">Import Settings<span class="speedycache-spinner"></span></button>
</div>
</form>';
echo '<!-- Export Section -->
<form method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="speedycache_export_settings"/>
<div class="speedycache-option-info speedycache-export-block" style="display:none;">
<span class="speedycache-option-desc">'.esc_html__('Click the button below to download the current SpeedyCache settings as a JSON file', 'speedycache').'</span>
<button class="speedycache-button speedycache-btn-black speedycache-export-settings" style="margin-top:10px;">Download Export File<span class="speedycache-spinner"></span></button>
</div>
</form>';
}
static function preload_modal_options($field_name, $fields){
if(empty($fields)){
return '';
}
switch($field_name){
case 'pre_connect':
$placeholder = 'https://fonts.google.com';
break;
default:
$placeholder = site_url() . '/' . (defined('SITEPAD') ? 'sitepad-data' : 'wp-content') . '/uploads/image.jpg';
}
$html = '<div class="speedycache-preloading-options">
<div class="speedycache-stacked-label" style="width:100%;">
<label style="width:100%;">
<span>Resource URL <span spdf-hover-tooltip="Required field" spdf-tooltip-position="bottom">*</span></span>
<input type="text" name="resource" style="width:100%;" placeholder="'.esc_html($placeholder).'" required/>
</label>
</div>';
$html .= '<div class="speedycache-preload-checkboxes">';
if(isset($fields['parent_selector'])){
$html .= '<label><input type="checkbox" name="parent_selector" value="true"/>Use Parent Selector</label>';
}
if(isset($fields['crossorigin'])){
$html .= '<label><input type="checkbox" name="crossorigin" value="true"/>Crossorigin</label>';
}
$html .= '</div>';
if(isset($fields['type'])){
$html .= '<div class="speedycache-stacked-label"><label><span>Resource Type <span spdf-hover-tooltip="Required field" spdf-tooltip-position="top">*</span></span><select name="type" required>
<option value="">Select Type</option>
<option value="image">Image</option>
<option value="font">Font</option>
<option value="script">Script</option>
<option value="style">Style</option>
<option value="audio">Audio</option>"
<option value="document">Document</option>
<option value="video">Video</option>
</select></label></div>';
}
if(isset($fields['priority'])){
$html .= '<div class="speedycache-stacked-label"><label>
<span>Fetch Priority</span>
<select name="fetch_priority">
<option value="" selected>Auto</option>
<option value="high">High</option>
<option value="low">Low</option>
</select></label>
</div>';
}
if(isset($fields['device'])){
$html .= '<div class="speedycache-stacked-label"><label>
<span>Device <span class="dashicons dashicons-editor-help" spdf-hover-tooltip="For this to work, you will need to enable Mobile Override and Mobile Cache options, this is not a required field" spdf-tooltip-position="top"></span></span>
<select name="device">
<option value="" selected>All</option>
<option value="desktop">Desktop</option>
<option value="mobile">Mobile</option>
</select></label>
</div>';
}
$html .= '</div>';
return $html;
}
static function pro_notice($tab_name){
echo '<h2>'.esc_html($tab_name).'</h2>
<div class="notice notice-warning">
<p>'.esc_html__('This is a part of SpeedyCache Pro, so update/upgrade to pro to utilize this feature', 'speedycache').'</p>
</div>';
}
static function save_btn(){
echo '<div class="speedycache-save-settings-wrapper"><button class="speedycache-button speedycache-btn-black">'.esc_html__('Save Settings', 'speedycache').'<span class="speedycache-spinner"></span><svg class="speedycache-spinner-done" xmlns="http://www.w3.org/2000/svg" height="15px" viewBox="0 -960 960 960" width="15px" fill="#FFF"><path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"/></svg></button></div>';
}
static function pro_upsell(){
$features = [
'Delay JS Execution',
'Defer JS Loading',
'Lazy Load Iframes',
'Database Cleanup',
'Critical CSS',
'and More...',
];
echo '<div class="speedycache-promo-modern-card">
<div class="speedycache-promo-header-group">
<h3 class="speedycache-promo-title">SpeedyCache</h3>
<span class="speedycache-promo-badge-pro">Pro</span>
</div>
<p class="speedycache-promo-desc">'.esc_html__('Unlock advanced performance features.', 'speedycache').'</p>
<ul class="speedycache-promo-feature-list">';
foreach($features as $feature){
echo '<li class="speedycache-promo-feature-item">
<div class="speedycache-promo-check-circle">
<div class="speedycache-promo-check-icon"></div>
</div>
'.esc_html($feature).'
</li>';
}
echo '</ul>
<a href="https://speedycache.com/pricing/?utm_source=plugin_settings" class="speedycache-promo-btn-main" target="_blank">
<span class="speedycache-promo-btn-text">'.esc_html__('Upgrade to Pro', 'speedycache').'</span>
<span class="speedycache-promo-arrow">→</span>
</a>
</div>';
}
}
ajax.php 0000644 00000053201 15152641416 0006206 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Ajax{
static function hooks(){
add_action('wp_ajax_siteseo_save_titles_meta_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_save_sitemap_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_save_indexing_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_save_advanced_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_save_social_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_save_analytics_toggle', '\SiteSEO\Ajax::save_toggle_state');
add_action('wp_ajax_siteseo_generate_bing_api_key', '\SiteSEO\Ajax::generate_bing_api_key');
add_action('wp_ajax_siteseo_url_submitter_submit', '\SiteSEO\Ajax::instant_indexing');
add_action('wp_ajax_siteseo_refresh_analysis', '\SiteSEO\Ajax::refresh_seo_analysis');
add_action('wp_ajax_siteseo_export_settings', '\SiteSEO\Ajax::export_settings');
add_action('wp_ajax_siteseo_import_settings', '\SiteSEO\Ajax::import_settings');
add_action('wp_ajax_siteseo_reset_settings', '\SiteSEO\Ajax::reset_settings');
add_action('wp_ajax_siteseo_migrate_seo', '\SiteSEO\Ajax::handle_import');
add_action('wp_ajax_siteseo_dismiss_intro', '\SiteSEO\Ajax::dismiss_intro');
add_action('wp_ajax_siteseo_save_universal_metabox', '\SiteSEO\Ajax::save_universal_metabox');
add_action('wp_ajax_siteseo_resolve_variables', '\SiteSEO\Ajax::resolve_variables');
add_action('wp_ajax_siteseo_clear_indexing_history', '\SiteSEO\Ajax::clear_indexing_history');
add_action('wp_ajax_siteseo_close_update_notice', '\SiteSEO\Ajax::close_update_notice');
// This is just to make sure, close of update notice works.
if(isset($_GET['action']) && 'siteseo_close_update_notice' === sanitize_text_field(wp_unslash($_GET['action']))){
add_filter('softaculous_plugin_update_notice', 'siteseo_plugin_update_notice_filter');
}
// Onboarding Actions
add_action('wp_ajax_siteseo_save_onboarding_settings', '\SiteSEO\Ajax::save_onboarding_settings');
}
static function handle_import(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!siteseo_user_can('manage_options')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$plugin = !empty($_POST['plugin']) ? sanitize_text_field(wp_unslash($_POST['plugin'])) : '';
switch($plugin){
case 'wordpress-seo':
$result = \SiteSEO\Import::yoast_seo();
break;
case 'all-in-one-seo-pack':
$result = \SiteSEO\Import::aio_seo();
break;
case 'autodescription':
$result = \SiteSEO\Import::seo_framework();
break;
case 'wp-seopress':
$result = \SiteSEO\Import::seo_press();
break;
case 'seo-by-rank-math':
$result = \SiteSEO\Import::rank_math();
break;
case 'slim-seo':
$result = \SiteSEO\Import::slim_seo();
break;
case 'surerank':
$result = \SiteSEO\Import::surerank();
break;
default:
throw new \Exception('Invalid plugin selected');
}
if(empty($result)){
wp_send_json_error(['message' => __('Invalid plugin selected', 'siteseo')]);
}
update_option('siteseo_last_migration_log', $result['log'], false);
wp_send_json_success(['message' => $result['message']]);
}
static function reset_settings(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$options = [
'siteseo_toggle',
'siteseo_titles_option_name',
'siteseo_social_option_name',
'siteseo_advanced_option_name',
'siteseo_instant_indexing_option_name',
'siteseo_xml_sitemap_option_name',
'siteseo_google_analytics_option_name',
'siteseo_dismiss_intro',
'siteseo_pro_options'
];
foreach($options as $option){
delete_option($option);
}
wp_send_json_success(['message' => esc_html__('Settings reset successfully.', 'siteseo')]);
}
static function import_settings(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
if(!isset($_FILES['import_file'])){
wp_send_json_error(array('message' => 'No file was uploaded.'));
}
// If name or tmp path is not available return
if(empty($_FILES['import_file']['name']) || empty($_FILES['import_file']['tmp_name'])){
wp_send_json_error(array('message' => 'No file was uploaded.'));
}
$imported_file = $_FILES['import_file']['tmp_name'];
$filename = sanitize_file_name($_FILES['import_file']['name']);
$file_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// Verify file exists and is readable
if(!file_exists($imported_file) || !is_readable($imported_file) || !is_uploaded_file($imported_file)){
wp_send_json_error(array('message' => __('Uploaded file is not readable.', 'siteseo')));
}
$mime_type = sanitize_text_field(wp_unslash($_FILES['import_file']['type']));
if($mime_type !== 'application/json'){
wp_send_json_error(array('message' => __('Invalid mime type. The uploaded file has invalid mime type', 'siteseo')));
}
// Making sure is the correct file format
if($file_extension !== 'json') {
wp_send_json_error(array('message' => __('Invalid file type. Please upload a JSON file.', 'siteseo')));
}
$file_contents = file_get_contents($imported_file);
$settings = json_decode($file_contents, true);
if(json_last_error() !== JSON_ERROR_NONE){
wp_send_json_error(array('message' => __('Invalid JSON file.', 'siteseo')));
}
if(empty($settings) || !is_array($settings)){
wp_send_json_error(array('message' => __('Invalid settings format.', 'siteseo')));
}
$settings = map_deep(wp_unslash($settings), 'sanitize_textarea_field');
if(isset($settings['siteseo_titles_option_name'])){
update_option('siteseo_titles_option_name', $settings['siteseo_titles_option_name']);
}
if(isset($settings['siteseo_social_option_name'])){
update_option('siteseo_social_option_name', $settings['siteseo_social_option_name']);
}
if(isset($settings['siteseo_xml_sitemap_option_name'])){
update_option('siteseo_xml_sitemap_option_name', $settings['siteseo_xml_sitemap_option_name']);
}
if(isset($settings['siteseo_toggle'])){
update_option('siteseo_toggle', $settings['siteseo_toggle']);
}
if(isset($settings['siteseo_advanced_option_name'])){
update_option('siteseo_advanced_option_name', $settings['siteseo_advanced_option_name']);
}
if(isset($settings['siteseo_instant_indexing_option_name'])){
update_option('siteseo_instant_indexing_option_name', $settings['siteseo_instant_indexing_option_name']);
}
if(isset($settings['siteseo_google_analytics_option_name'])){
update_option('siteseo_google_analytics_option_name', $settings['siteseo_google_analytics_option_name']);
}
// Pro
if(isset($settings['siteseo_pro_options'])){
update_option('siteseo_pro_options', $settings['siteseo_pro_options']);
}
wp_send_json_success(['message' => esc_html__('Settings imported successfully.', 'siteseo')]);
}
static function export_settings(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$export_data = array(
'siteseo_titles_option_name' => get_option('siteseo_titles_option_name'),
'siteseo_social_option_name' => get_option('siteseo_social_option_name'),
'siteseo_xml_sitemap_option_name' => get_option('siteseo_xml_sitemap_option_name'),
'siteseo_toggle' => get_option('siteseo_toggle'),
'siteseo_google_analytics_option_name' => get_option('siteseo_google_analytics_option_name'),
'siteseo_instant_indexing_option_name' => get_option('siteseo_instant_indexing_option_name'),
'siteseo_advanced_option_name' => get_option('siteseo_advanced_option_name'),
'siteseo_pro_options' =>get_option('siteseo_pro_options'),
);
$file_name = 'siteseo-settings-export-' . current_time('m-d-Y') . '.json';
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename="'.$file_name.'"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
echo wp_json_encode($export_data);
exit;
}
static function refresh_seo_analysis(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('siteseo_manage')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
$post_type = isset($_POST['post_type']) ? sanitize_text_field(wp_unslash($_POST['post_type'])) : '';
$target_keywords = isset($_POST['target_keywords']) ? sanitize_text_field(wp_unslash($_POST['target_keywords'])) : '';
$post = get_post($post_id);
if(!$post || !current_user_can('edit_post', $post_id)){
wp_send_json_error(['message' => __('Invalid post or insufficient permissions', 'siteseo')]);
}
update_post_meta($post_id, '_siteseo_analysis_target_kw', $target_keywords);
$analysis_data = \SiteSEO\Metaboxes\Analysis::perform_seo_analysis($post);
update_post_meta($post_id, '_siteseo_analysis_data', $analysis_data);
ob_start();
\SiteSEO\Metaboxes\Analysis::display_seo_analysis($post);
$analysis_html = ob_get_clean();
wp_send_json_success([
'html' => $analysis_html,
'analysis_data' => $analysis_data
]);
}
static function instant_indexing(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!siteseo_user_can('manage_instant_indexing')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
// Validate input
if(!isset($_POST['search_engine'], $_POST['urls'])){
wp_send_json_error(['message' => esc_html__('Missing required parameters', 'siteseo')]);
}
$urls = sanitize_textarea_field(wp_unslash($_POST['urls']));
$options = get_option('siteseo_instant_indexing_option_name');
$google_api_key = isset($options['instant_indexing_google_api_key']) ? $options['instant_indexing_google_api_key'] : '';
$bing_api_key = isset($options['instant_indexing_bing_api_key']) ? $options['instant_indexing_bing_api_key'] : '';
$url_list = array_filter(array_map('trim', explode("\n", $urls)));
if(empty($url_list)){
wp_send_json_error(['message' => 'No valid URLs provided']);
}
$response = [];
try{
if(!empty($options['engines']['google']) && !empty($google_api_key)){
$response['google'] = \SiteSEO\InstantIndexing::submit_urls_to_google($url_list);
}
if(!empty($options['engines']['bing']) && !empty($bing_api_key)){
$response['bing'] = \SiteSEO\InstantIndexing::submit_urls_to_bing($url_list, $bing_api_key);
}
if(empty($response)){
wp_send_json_error(['message' => 'No search engines configured or missing API keys']);
}
$res_google = !empty($response['google']) ? $response['google'] : null;
$res_bing = !empty($response['bing']) ? $response['bing'] : null;
\SiteSEO\InstantIndexing::save_index_history($url_list, $res_google, $res_bing, null);
wp_send_json_success([
'message' => 'URLs submitted successfully',
'details' => $response
]);
} catch(\Exception $e){
wp_send_json_error(['message' => $e->getMessage()]);
}
}
static function generate_bing_api_key(){
if(!check_ajax_referer('siteseo_admin_nonce', 'nonce', false)){
wp_send_json_error('Invalid nonce');
return;
}
if(!siteseo_user_can('manage_instant_indexing')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$lowercase = range('a', 'z');
$uppercase = range('A', 'Z');
$numbers = range('0', '9');
$dash = ['-'];
$characters = array_merge($lowercase, $uppercase, $numbers, $dash);
$characters_length = count($characters);
$length = 32;
$api_key = '';
for($i = 0; $i < $length; $i++){
$api_key .= $characters[random_int(0, $characters_length - 1)];
}
wp_send_json_success(['api_key' => $api_key]);
}
static function save_toggle_state(){
check_ajax_referer('siteseo_toggle_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'siteseo')]);
}
$action = isset($_POST['action']) ? sanitize_text_field(wp_unslash($_POST['action'])) : '';
switch($action){
case 'siteseo_save_titles_meta_toggle':
$toggle_key = 'toggle-titles';
break;
case 'siteseo_save_sitemap_toggle':
$toggle_key = 'toggle-xml-sitemap';
break;
case 'siteseo_save_indexing_toggle':
$toggle_key = 'toggle-instant-indexing';
break;
case 'siteseo_save_advanced_toggle':
$toggle_key = 'toggle-advanced';
break;
case 'siteseo_save_social_toggle':
$toggle_key = 'toggle-social';
break;
case 'siteseo_save_analytics_toggle':
$toggle_key = 'toggle-google-analytics';
break;
default:
wp_send_json_error(['message' => __('Invalid action', 'siteseo')]);
return;
}
$toggle_value = isset($_POST['toggle_value']) ? sanitize_text_field(wp_unslash($_POST['toggle_value'])) : '0';
$options = get_option('siteseo_toggle', []);
$options[$toggle_key] = $toggle_value;
$updated = update_option('siteseo_toggle', $options);
if($updated){
wp_send_json_success([
'message' => ucfirst($toggle_key) . ' toggle state saved successfully',
'value' => $toggle_value
]);
}
wp_send_json_error(['message' => __('Failed to save toggle state', 'siteseo')]);
}
static function save_onboarding_settings(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(__('You do not have required permission to edit this file.', 'siteseo'));
}
if(empty($_POST['step'])){
wp_send_json_error(['message' => __('Could not figure out the current step', 'siteseo')]);
}
$step_name = !empty($_POST['step']) ? sanitize_text_field(wp_unslash($_POST['step'])) : '';
switch($step_name){
case 'your-site':
$title_options = get_option('siteseo_titles_option_name', []);
$social_options = get_option('siteseo_social_option_name', []);
if(!empty($_POST['data']['website_name'])){
$title_options['titles_home_site_title'] = sanitize_text_field(wp_unslash($_POST['data']['website_name']));
}
if(!empty($_POST['data']['alternate_site_name'])){
$title_options['titles_home_site_title_alt'] = sanitize_text_field(wp_unslash($_POST['data']['alternate_site_name']));
}
if(!empty($_POST['data']['site_type'])){
$social_options['social_knowledge_type'] = sanitize_text_field(wp_unslash($_POST['data']['site_type']));
}
if(!empty($_POST['data']['organization_name'])){
$social_options['social_knowledge_name'] = sanitize_text_field(wp_unslash($_POST['data']['organization_name']));
}
if(!empty($_POST['data']['organization_logo'])){
$social_options['social_knowledge_img'] = sanitize_url(wp_unslash($_POST['data']['organization_logo']));
}
if(!empty($_POST['data']['social_fb'])){
$social_options['social_accounts_facebook'] = sanitize_url(wp_unslash($_POST['data']['social_fb']));
}
if(!empty($_POST['data']['social_x'])){
$social_options['social_accounts_twitter'] = sanitize_text_field(wp_unslash($_POST['data']['social_x']));
}
if(!empty($_POST['data']['social_additional'])){
$social_options['social_accounts_additional'] = explode("\n", sanitize_textarea_field(wp_unslash($_POST['data']['social_additional'])));
}
update_option('siteseo_titles_option_name', $title_options);
update_option('siteseo_social_option_name', $social_options);
wp_send_json_success();
break;
case 'indexing':
if(empty($_POST['data'])){
break;
}
$data = map_deep(wp_unslash($_POST['data']), 'sanitize_text_field');
$site_status = !empty($data['site_status']) ? $data['site_status'] : '';
if(empty($site_status)){
wp_send_json_error(['message' => __('Request data did not reach the backend', 'siteseo')]);
}
$title_options = get_option('siteseo_titles_option_name', []);
if($site_status == 'underconstruction'){
$title_options['titles_noindex'] = true;
update_option('siteseo_titles_option_name', $title_options);
wp_send_json_success();
}
// Saving Post type indexing values
if(!empty($data['post_types'])){
if(!is_array($data['post_types'])){
$data['post_types'] = [$data['post_types']];
}
$post_types = get_post_types(['public' => true, 'show_ui' => true], 'objects', 'and');
unset($post_types['attachment']);
foreach($post_types as $post){
if(in_array($post->name, $data['post_types'])){
$title_options['titles_single_titles'][$post->name]['noindex'] = $post->name;
}
}
}
// Saving Taxonomies indexing values
if(!empty($data['taxonomies'])){
if(!is_array($data['taxonomies'])){
$data['taxonomies'] = [$data['taxonomies']];
}
$taxonomies = get_taxonomies(['public' => true, 'show_ui' => true], 'objects', 'and');
foreach($taxonomies as $taxonomy){
if(in_array($taxonomy->name, $data['taxonomies'])){
$title_options['titles_tax_titles'][$taxonomy->name]['noindex'] = $taxonomy->name;
}
}
}
update_option('siteseo_titles_option_name', $title_options);
wp_send_json_success();
break;
case 'advanced':
$data = map_deep(wp_unslash($_POST['data']), 'sanitize_text_field');
$advanced_options = get_option('siteseo_advanced_option_name');
$title_options = get_option('siteseo_titles_option_name', []);
$title_options['titles_archives_author_noindex'] = isset($data['author_noindex']) ? $data['author_noindex'] : '';
$advanced_options['advanced_attachments_file'] = isset($data['redirect_attachment']) ? $data['redirect_attachment'] : '';
$advanced_options['advanced_category_url'] = isset($data['category_url']) ? $data['category_url'] : '';
$advanced_options['appearance_universal_metabox_disable'] = isset($data['universal_seo_metabox']) ? '' : '1';
$advanced_options['appearance_universal_metabox'] = isset($data['universal_seo_metabox']) ? '1' : '';
update_option('siteseo_titles_option_name', $title_options);
update_option('siteseo_advanced_option_name', $advanced_options);
wp_send_json_success();
break;
}
}
static function dismiss_intro(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('siteseo_manage')){
wp_send_json_error(__('You do not have required permission to edit this file.', 'siteseo'));
}
update_option('siteseo_dismiss_intro', time());
}
static function save_universal_metabox(){
check_ajax_referer('siteseo_universal_nonce', 'security');
if(!current_user_can('siteseo_manage') || !siteseo_user_can_metabox()){
wp_send_json_error(__('You do not have required permission to edit this file.', 'siteseo'));
}
if(empty($_POST['post_id'])){
wp_send_json_error(__('Post ID not found', 'siteseo'));
}
$post_id = sanitize_text_field(wp_unslash($_POST['post_id']));
if(!current_user_can('edit_post', $post_id)){
wp_send_json_error(__('You do not have required permission to edit this file.', 'siteseo'));
}
$post = get_post($post_id);
\SiteSEO\Metaboxes\Settings::save_metabox($post_id, $post);
}
static function resolve_variables(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('siteseo_manage')){
wp_send_json_error(__('You do not have required permission to edit this file.', 'siteseo'));
}
if(empty($_POST['content']) || empty($_POST['post_id'])){
wp_send_json_error(__('The required content or ID is empty', 'siteseo'));
}
global $post, $wp_query;
$post_id = (int) sanitize_text_field(wp_unslash($_POST['post_id']));
$content = sanitize_text_field(wp_unslash($_POST['content']));
if(!current_user_can('edit_post', $post_id)){
wp_send_json_error(__('You do not have permission to access this post', 'siteseo'));
}
$tmp_post = $post;
$post = get_post($post_id);
$replaced_content = \SiteSEO\TitlesMetas::replace_variables($content, true);
$post = $tmp_post;
wp_send_json_success($replaced_content);
}
static function clear_indexing_history(){
check_ajax_referer('siteseo_admin_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(__('You do not have required permission to clear indexing history.', 'siteseo'));
}
global $siteseo;
$indexing_history = $siteseo->instant_settings;
if(is_array($indexing_history) && isset($indexing_history['indexing_history'])){
unset($indexing_history['indexing_history']);
update_option('siteseo_instant_indexing_option_name', $indexing_history);
}
wp_send_json_success();
}
static function close_update_notice(){
check_ajax_referer('siteseo_promo_nonce', 'security');
if(!current_user_can('manage_options')){
wp_send_json_error('You don\'t have privilege to close this notice!');
}
$plugin_update_notice = get_option('softaculous_plugin_update_notice', []);
$available_update_list = get_site_transient('update_plugins');
$to_update_plugins = apply_filters('softaculous_plugin_update_notice', []);
if(empty($available_update_list) || empty($available_update_list->response)){
return;
}
foreach($to_update_plugins as $plugin_path => $plugin_name){
if(isset($available_update_list->response[$plugin_path])){
$plugin_update_notice[$plugin_path] = $available_update_list->response[$plugin_path]->new_version;
}
}
update_option('softaculous_plugin_update_notice', $plugin_update_notice);
}
}
util.php 0000644 00000021614 15152641416 0006243 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Util{
static function sanitize_get($name, $default = ''){
if(empty($_GET[$name])){
return $default;
}
if(is_array($_GET[$name]) || is_object($_GET[$name])){
return map_deep(wp_unslash($_GET[$name]), 'sanitize_text_field');
}
return sanitize_text_field(wp_unslash($_GET[$name]));
}
static function sanitize_post($name, $default = ''){
if(empty($_POST[$name])){
return $default;
}
if(is_array($_POST[$name]) || is_object($_POST[$name])){
return map_deep(wp_unslash($_POST[$name]), 'sanitize_text_field');
}
return sanitize_text_field(wp_unslash($_POST[$name]));
}
static function sanitize_request($name, $default = ''){
if(empty($_REQUEST[$name])){
return $default;
}
if(is_array($_REQUEST[$name]) || is_object($_REQUEST[$name])){
return map_deep(wp_unslash($_REQUEST[$name]), 'sanitize_text_field');
}
return sanitize_text_field(wp_unslash($_REQUEST[$name]));
}
static function sanitize_server($name, $default = ''){
if(empty($_SERVER[$name])){
return $default;
}
return sanitize_text_field(wp_unslash($_SERVER[$name]));
}
static function pagespeed_color($score){
// The structure of this array is 0 => [Stroke Color, Background Color, Text Color]
$score_color_map = array(
0 => ['#c00', '#c003', '#c00'], // Red
50 => ['#fa3', '#ffa50036', '#fa3'],// Orange
90 => ['#0c6', '#00cc663b', '#080']// Green
);
if($score >= 0 && $score < 50){
return $score_color_map[0];
}
if($score >= 50 && $score < 90){
return $score_color_map[50];
}
return $score_color_map[90];
}
static function url_to_path($url){
$url = preg_replace('/\?.*/', '', $url); // Removing any query string
$dir_slug = str_replace(site_url(), '', $url);
if(defined('SITEPAD')){
global $sitepad;
$file_path = $sitepad['path'] . '/' .trim($dir_slug, '/');
} else {
$file_path = ABSPATH . trim($dir_slug, '/');
}
return wp_normalize_path($file_path);
}
static function path_to_url($path){
$path = wp_normalize_path($path);
if(defined('SITEPAD')){
global $sitepad;
$abs_path = wp_normalize_path($sitepad['path']);
} else {
$abs_path = wp_normalize_path(ABSPATH);
}
$path = str_replace($abs_path, '', $path);
$url = site_url() . '/' . $path;
return $url;
}
static function cache_path($loc = ''){
if((defined('WP_CLI') && WP_CLI) || empty($_SERVER['HTTP_HOST'])){
global $blog_id;
$url = get_option('home');
if(!empty($blog_id) && is_multisite()){
switch_to_blog($blog_id);
$url = get_option('home');
restore_current_blog();
}
$url = wp_parse_url($url);
$host = $url['host'];
return trailingslashit(SPEEDYCACHE_CACHE_DIR . '/'.$host.'/'.$loc);
}
$host = sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST']));
return trailingslashit(SPEEDYCACHE_CACHE_DIR . '/'.$host.'/'.$loc);
}
// Creates a config file based on the URL of the website
static function set_config_file(){
global $speedycache;
$export_config['settings']['status'] = !empty($speedycache->options['status']);
$export_config['settings']['gzip'] = !empty($speedycache->options['gzip']);
$export_config['settings']['logged_in_user'] = !empty($speedycache->options['logged_in_user']);
$export_config['settings']['mobile_theme'] = !empty($speedycache->options['mobile_theme']);
$export_config['settings']['mobile'] = !empty($speedycache->options['mobile']);
//$export_config['user_agents'] = speedycache_get_excluded_useragent();
$export_config['excludes'] = get_option('speedycache_exclude', []);
$config = var_export($export_config, true);
$url = get_site_url();
$file = parse_url(untrailingslashit($url));
$file['path'] = (!empty($file['path'])) ? str_replace( '/', '.', untrailingslashit($file['path'])) : '';
$config_file_path = WP_CONTENT_DIR .'/speedycache-config/'. strtolower($file['host']) . $file['path'] . '.php';
if(!file_exists(WP_CONTENT_DIR .'/speedycache-config/')){
if(mkdir(WP_CONTENT_DIR .'/speedycache-config/', 0755, true)){
touch(WP_CONTENT_DIR .'/speedycache-config/index.html');
file_put_contents(WP_CONTENT_DIR .'/speedycache-config/.htaccess', 'deny from all');
}
}
$config_temp = file_get_contents(SPEEDYCACHE_DIR . '/assets/config-template.php');
$config_content = str_replace("'REPLACE_CONFIG'", $config, $config_temp);
file_put_contents($config_file_path, $config_content);
}
static function dir_size($dir){
$size = 0;
foreach(glob(rtrim($dir, '/').'/*', GLOB_NOSORT) as $file){
$size += is_file($file) ? filesize($file) : self::dir_size($file);
}
return $size;
}
static function cache_lifespan(){
global $speedycache;
$schedule_time = 0;
if(empty($speedycache->options['purge_interval'])){
return $schedule_time;
}
if(!empty($speedycache->options['purge_enable_exact_time']) && !empty($speedycache->options['purge_exact_time'])){
$schedule_time = DAY_IN_SECONDS;
} elseif($speedycache->options['purge_interval_unit'] == 'hours'){
$schedule_time = HOUR_IN_SECONDS * $speedycache->options['purge_interval'];
} elseif($speedycache->options['purge_interval_unit'] == 'days'){
$schedule_time = DAY_IN_SECONDS * $speedycache->options['purge_interval'];
}
return (int) $schedule_time;
}
static function lifespan_cron(){
global $speedycache;
if(empty($speedycache->options['purge_interval'])){
return;
}
if(!empty(wp_next_scheduled('speedycache_purge_cache'))){
return;
}
if(!empty($speedycache->options['purge_enable_exact_time']) && !empty($speedycache->options['purge_exact_time'])){
// Getting the exact time of the user's timezone by using the offset and strtotime return gtm time.
$future_timestamp = strtotime('today '.$speedycache->options['purge_exact_time']);
$offset = get_option('gmt_offset') * HOUR_IN_SECONDS;
$current_time = time() - $offset;
$future_timestamp -= $offset;
if(time() > $future_timestamp){
$future_timestamp = strtotime('tomorrow '.$speedycache->options['purge_exact_time']);
$future_timestamp -= $offset;
}
$schedule_time = $future_timestamp - time();
} elseif($speedycache->options['purge_interval_unit'] == 'hours'){
$schedule_time = HOUR_IN_SECONDS * $speedycache->options['purge_interval'];
} elseif($speedycache->options['purge_interval_unit'] == 'days'){
$schedule_time = DAY_IN_SECONDS * $speedycache->options['purge_interval'];
}
wp_schedule_event(time() + $schedule_time, 'speedycache_expired_cache_schedule', 'speedycache_purge_cache');
}
static function preload_cron(){
global $speedycache;
if(empty($speedycache->options['preload_interval']) || empty($speedycache->options['preload'])){
return;
}
if(wp_next_scheduled('speedycache_preload')){
return;
}
$schedule_time = HOUR_IN_SECONDS * (int) $speedycache->options['preload_interval'];
wp_schedule_event(time() + $schedule_time, 'speedycache_preload_cache_schedule', 'speedycache_preload');
}
static function custom_expiry_cron($schedules){
$cache_interval = self::cache_lifespan();
if(empty($cache_interval)){
return $schedules;
}
$schedules['speedycache_expired_cache_schedule'] = [
'interval' => $cache_interval,
'display' => __('SpeedyCache Cache Lifespan cron', 'speedycache'),
];
return $schedules;
}
static function custom_preload_cron($schedules){
global $speedycache;
if(empty($speedycache->options['preload_interval'])){
return $schedules;
}
$cache_interval = $speedycache->options['preload_interval'] * HOUR_IN_SECONDS;
if(empty($cache_interval)){
return $schedules;
}
$schedules['speedycache_preload_cache_schedule'] = [
'interval' => $cache_interval,
'display' => __('SpeedyCache Cache Preload cron', 'speedycache'),
];
return $schedules;
}
static function custom_cron($schedules){
// Every 14 days (Fortnight)
$schedules['speedycache_fortnight'] = [
'interval' => 14 * DAY_IN_SECONDS,
'display' => __('Once Every Fortnight', 'speedycache'),
];
// Monthly (approx 30 days)
$schedules['speedycache_monthly'] = [
'interval' => 30 * DAY_IN_SECONDS,
'display' => __('Once Monthly', 'speedycache'),
];
return $schedules;
}
// Deletes binaries
static function delete_cwebp(){
$binary_dir = wp_upload_dir()['basedir'] .'/speedycache-binary';
if(!file_exists($binary_dir)){
return;
}
$binaries = @scandir($binary_dir);
$binaries = array_diff($binaries, ['.', '..']);
if(empty($binaries)){
@rmdir($binary_dir);
return;
}
foreach($binaries as $binary){
if(file_exists($binary_dir.'/'.$binary)){
@unlink($binary_dir.'/'.$binary);
}
}
}
}
cache.php 0000644 00000036235 15152641416 0006336 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
use \SpeedyCache\Util;
class Cache {
static $cache_file_path = '';
static $ignored_parameters = ['fbclid', 'utm_id', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_source_platform', 'gclid', 'dclid', 'msclkid', 'ref', 'fbaction_ids', 'fbc', 'fbp', 'clid', 'mc_cid', 'mc_eid', 'hsCtaTracking', 'hsa_cam', 'hsa_grp', 'hsa_mt', 'hsa_src', 'hsa_ad', 'hsa_acc', 'hsa_net', 'hsa_kw'];
static $content = '';
static function init(){
global $speedycache;
if(!defined('SPEEDYCACHE_SERVER_HOST')){
define('SPEEDYCACHE_SERVER_HOST', Util::sanitize_server('HTTP_HOST'));
}
if(!defined('SITEPAD')){
if(!empty($speedycache->options['dns_prefetch']) && !empty($speedycache->options['dns_urls'])){
add_filter('wp_resource_hints', '\SpeedyCache\Cache::dns_prefetch_hint', 10, 2);
}
}
// Filter for Gravatar cache. We are updating the URL of the gravatar here so the local hosted Gravatar URL will be cached.
if(!empty($speedycache->options['gravatar_cache'])){
add_filter('get_avatar_data', '\SpeedyCache\Gravatar::get_avatar_data', 10, 2);
}
// Loads Instant Page to improve load page speed by 1%
if(defined('SPEEDYCACHE_PRO') && !empty($speedycache->options['instant_page'])){
add_action('wp_enqueue_scripts', '\SpeedyCache\Cache::instant_page');
}
if(!empty($speedycache->options['disable_emojis'])){
add_action('init', '\SpeedyCache\Cache::disable_emojis');
}
// Optimizes images when a page gets loaded and it finds no image optimized
if(class_exists('\SpeedyCache\Image') && !empty($speedycache->image['settings']['automatic_optm'])){
add_filter('the_content', '\SpeedyCache\Image::optimize_on_fly');
}
// Adds preconnect
if(class_exists('\SpeedyCache\Enhanced')){
if(!defined('SITEPAD')){
if(!empty($speedycache->options['pre_connect']) && !empty($speedycache->options['pre_connect_list'])){
add_filter('wp_resource_hints', '\SpeedyCache\Enhanced::pre_connect_hint', 10, 2);
}
}
// Adds Preload link tag to the head
if(!empty($speedycache->options['preload_resources'])){
add_action('wp_head', '\SpeedyCache\Enhanced::preload_resource', 0);
}
}
// Image URL rewrite
if(class_exists('\SpeedyCache\Image') && !empty($speedycache->image['settings']['url_rewrite'])){
add_filter('the_content', 'SpeedyCache\Image::rewrite_url_to_webp', 10);
}
ob_start('\SpeedyCache\Cache::optimize');
}
static function create(){
global $speedycache;
$cache_path = self::cache_path();
if(!file_exists($cache_path)){
mkdir($cache_path, 0755, true);
}
$cache_path .= '/' . self::cache_file_name();
$mobile = '';
if(strpos($cache_path, 'mobile-cache') !== FALSE){
$mobile = 'Mobile: ';
}
$cache_path = wp_normalize_path($cache_path);
file_put_contents($cache_path, self::$content . "\n<!-- ".esc_html($mobile)."Cache by SpeedyCache https://speedycache.com -->");
if(function_exists('gzencode') && !empty($speedycache->options['gzip'])){
$gzidded_content = gzencode(self::$content . "\n<!-- ".esc_html($mobile)."Cache by SpeedyCache https://speedycache.com -->");
file_put_contents($cache_path . '.gz', $gzidded_content);
}
delete_option('speedycache_html_size');
delete_option('speedycache_assets_size');
}
static function cache_file_name(){
$file_name = 'index';
if(isset($_COOKIE['wcu_current_currency'])){
$file_name .= '-'. strtolower(sanitize_file_name($_COOKIE['wcu_current_currency']));
}
return $file_name . '.html';
}
static function cache_path(){
global $speedycache;
if(!file_exists(SPEEDYCACHE_CACHE_DIR)){
if(mkdir(SPEEDYCACHE_CACHE_DIR, 0755, true)){
touch(SPEEDYCACHE_CACHE_DIR . '/index.html');
}
}
$host = $_SERVER['HTTP_HOST'];
$request_uri = urldecode(esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])));
$request_uri = preg_replace('/\.{2,}/', '', $request_uri); // Cleaning the path
$request_uri = remove_query_arg(self::$ignored_parameters, $request_uri); // Cleaning ignored query
$parsed_uri = wp_parse_url($request_uri);
$path = SPEEDYCACHE_CACHE_DIR;
$path .= '/' . $host;
if(wp_is_mobile() && !empty($speedycache->options['mobile_theme'])){
$path .= '/mobile-cache';
} else {
$path .= '/all';
}
// Handling WeGlot
if(function_exists('weglot_get_current_full_url')){
$weglot_url = weglot_get_current_full_url();
$weglot_path = parse_url($weglot_url, PHP_URL_PATH);
$path .= $weglot_path;
} else {
$path .= $parsed_uri['path'];
}
self::$cache_file_path = $path;
return $path;
}
static function can_cache(){
global $speedycache;
if(empty($speedycache->options['status'])) return false;
if(empty($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] != 'GET') return false;
if(defined('WP_CLI') && !empty(WP_CLI)) return false;
if(defined('REST_REQUEST') && !empty(REST_REQUEST)) return false;
if(function_exists('http_response_code') && (http_response_code() > 309)) return false;
if(preg_match('/\./', $_SERVER['REQUEST_URI'])) return false;
if (defined('SITEPAD')) {
if (preg_match('/(site-admin|login|wp-register|wp-comments-post|cron|sp-json)/', $_SERVER['REQUEST_URI'])) {
return false;
}
} else {
if (preg_match('/(wp-(?:admin|login|register|comments-post|cron|json))/', $_SERVER['REQUEST_URI'])) {
return false;
}
}
if(preg_match('/html.*\s(amp|⚡)/', substr(self::$content, 0, 300))) return false;
if(wp_is_mobile() && !empty($speedycache->options['mobile']) && empty($speedycache->options['mobile_theme'])) return false;
if(is_admin()) return false;
// Since: 1.2.8 we will only cache the page if user is not logged-in.
if(is_user_logged_in()) return false;
if(!preg_match( '/<\s*\/\s*html\s*>/i', self::$content)) return false;
if(is_singular() && post_password_required()) return false;
if(function_exists('is_404') && is_404()) return false;
if(self::is_excluded()) return false;
if(function_exists('is_cart') && is_cart()) return false;
if(function_exists('is_checkout') && is_checkout()) return false;
if(function_exists('is_account_page') && is_account_page()) return false;
if(!self::can_handle_query()) return false;
return true;
}
static function optimize($content){
global $speedycache;
self::$content = &$content;
$start_time = microtime(TRUE);
if(!self::can_cache()){
return self::$content;
}
self::clean_html();
// Minify HTML
if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['minify_html']) && (defined('SPEEDYCACHE_PRO_VERSION') && version_compare(SPEEDYCACHE_PRO_VERSION, '1.2.0', '>='))){
\SpeedyCache\Enhanced::init();
\SpeedyCache\Enhanced::minify_html(self::$content);
}
// ADD Font Rendering CSS
if(!empty($speedycache->options['font_rendering'])){
self::$content = str_replace('</head>', '<style>body{text-rendering: optimizeSpeed;}</style></head>', self::$content);
}
// Lazy Load HTML elements
if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['lazy_load_html']) && !empty($speedycache->options['lazy_load_html_elements'])){
self::$content = \SpeedyCache\Enhanced::lazy_load_html(self::$content);
}
if(!empty($speedycache->options['combine_css'])){
\SpeedyCache\CSS::combine(self::$content);
}
if(!empty($speedycache->options['minify_css'])){
\SpeedyCache\CSS::minify(self::$content);
}
if(!empty($speedycache->options['combine_js'])){
\SpeedyCache\JS::combine_head(self::$content);
}
// if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['combine_js'])){
// \SpeedyCache\JS::combine_body($content);
// }
if(!empty($speedycache->options['minify_js'])){
\SpeedyCache\JS::minify(self::$content);
}
// Adds Image dimensions to the Image which does not have height or width
if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['image_dimensions'])){
self::$content = \SpeedyCache\Enhanced::image_dimensions(self::$content);
}
// Google Fonts
if(class_exists('\SpeedyCache\GoogleFonts') && !empty($speedycache->options['local_gfonts'])){
\SpeedyCache\GoogleFonts::get($content);
self::$content = \SpeedyCache\GoogleFonts::replace(self::$content);
self::$content = \SpeedyCache\GoogleFonts::add_swap(self::$content);
}
// Preload Critical Images
if(class_exists('\SpeedyCache\Enhanced') && !empty($speedycache->options['critical_images'])){
self::$content = \SpeedyCache\Enhanced::preload_critical_images(self::$content);
}
// Delay JS
if(!empty($speedycache->options['delay_js']) && class_exists('\SpeedyCache\ProOptimizations')){
\SpeedyCache\ProOptimizations::delay_js(self::$content);
}
// Defer JS
if(!empty($speedycache->options['render_blocking']) && class_exists('\SpeedyCache\ProOptimizations')){
\SpeedyCache\ProOptimizations::defer_js(self::$content);
}
// IMG Lazy Load
if(class_exists('\SpeedyCache\ProOptimizations') && !empty($speedycache->options['lazy_load'])){
\SpeedyCache\ProOptimizations::img_lazy_load(self::$content);
}
// For other plugins to hook into.
self::$content = (string) apply_filters('speedycache_content', self::$content);
// ----- DO NOT DO ANY OPTIMIZATION BELOW THIS ------
// Unused and Critical CSS
if(
!empty($_SERVER['HTTP_HOST']) &&
!empty($_SERVER['REQUEST_URI']) &&
!empty($_SERVER['HTTP_USER_AGENT']) &&
class_exists('\SpeedyCache\ProOptimizations') &&
speedycache_optserver('HTTP_USER_AGENT') !== 'SpeedyCacheCCSS' &&
!(defined('SITEPAD'))
){
$post_meta = get_post_meta(get_the_ID(), 'speedycache_post_meta', true);
if(!empty($speedycache->options['critical_css']) && empty($post_meta['disable_critical_css'])){
\SpeedyCache\ProOptimizations::critical_css();
}
if(empty($post_meta['disable_unused_css']) && !empty($speedycache->options['unused_css'])){
\SpeedyCache\ProOptimizations::unused_css();
}
}
// Rewriting to a CDN
if(
!empty($speedycache->cdn) &&
!empty($speedycache->cdn['enabled']) &&
!empty($speedycache->cdn['cdn_url']) &&
!empty($speedycache->cdn['cdn_type']) &&
$speedycache->cdn['cdn_type'] !== 'cloudflare'
){
\SpeedyCache\CDN::rewrite(self::$content);
}
self::create();
$end_time = microtime(TRUE);
self::$content .= '<!-- Cached by SpeedyCache, it took '.($end_time - $start_time).'s-->';
self::$content .= '<!-- Refresh to see the cached version -->';
if(file_exists(self::$cache_file_path)){
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime(self::$cache_file_path)) . ' GMT');
}
return self::$content;
}
static function clean_html(){
self::$content = str_replace("\r\n", "\n", trim(self::$content));
}
static function is_excluded(){
global $speedycache;
$excludes = get_option('speedycache_exclude', []);
if(empty($excludes)){
return false;
}
$is_excluded = false;
foreach($excludes as $rule){
switch($rule['type']){
case 'page':
$is_excluded = self::is_page_excluded($rule);
break;
case 'useragent':
$is_excluded = self::is_useragent_excluded($rule);
break;
case 'cookie':
$is_excluded = self::is_cookie_excluded($rule);
break;
}
if(!empty($is_excluded)){
return true;
}
}
return false;
}
static function can_handle_query(){
$uri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI']));
$uri = remove_query_arg(self::$ignored_parameters, $uri);
$parsed_uri = wp_parse_url($uri);
if(!empty($parsed_uri['query'])){
return false;
}
return true;
}
static function is_page_excluded($rule){
if(empty($rule['prefix'])){
return false;
}
if($rule['prefix'] === 'homepage'){
return is_front_page();
}
if($rule['prefix'] === 'page'){
return is_page();
}
if($rule['prefix'] === 'post_id' && !empty($rule['content'])){
$excluded_ids = is_array($rule['content']) ? $rule['content'] : explode(',', $rule['content']);
return in_array(get_queried_object_id(), $excluded_ids);
}
// Excludes a page if it has the given shortcode.
if($rule['prefix'] === 'shortcode' && !empty($rule['content'])){
if(self::has_shortcode($rule['content'])){
return true;
}
}
if($rule['prefix'] === 'category'){
return is_category();
}
if($rule['prefix'] === 'archive'){
return is_archive();
}
if($rule['prefix'] === 'tag'){
return is_tag();
}
if($rule['prefix'] === 'attachment'){
return is_attachment();
}
if($rule['prefix'] === 'startwith' && !empty($rule['content'])){
return (bool) preg_match('/^'.preg_quote($rule['content'], '/').'/', trim($_SERVER['REQUEST_URI'], '/'));
}
if($rule['prefix'] === 'contain' && !empty($rule['content'])){
return (bool) preg_match('/'.preg_quote($rule['content'], '/').'/', trim($_SERVER['REQUEST_URI'], '/'));
}
if($rule['prefix'] === 'exact' && !empty($rule['content'])){
return trim($rule['content'], '/') === trim($_SERVER['REQUEST_URI'], '/');
}
return false;
}
static function is_cookie_excluded($rule){
if(!isset($_SERVER['HTTP_COOKIE'])){
return false;
}
$cookie = sanitize_text_field(wp_unslash($_SERVER['HTTP_COOKIE']));
return preg_match('/'.preg_quote($rule['content'], '/').'/i', $cookie);
}
static function is_useragent_excluded($rule){
return preg_match('/'.preg_quote($rule['content'], '/').'/i', $_SERVER['HTTP_USER_AGENT']);
}
// Adds DNS prefetch
static function dns_prefetch_hint($urls, $relation_type){
global $speedycache;
if($relation_type !== 'dns-prefetch'){
return $urls;
}
foreach($speedycache->options['dns_urls'] as $url) {
if(!empty($url)){
$urls[] = $url;
}
}
return $urls;
}
// Depricated since 1.2.0 do not use it
// Just to prevent site from breaking
static function create_dir($path, $content, $type = ''){
}
static function disable_emojis(){
add_filter('emoji_svg_url', '__return_false');
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles');
remove_filter('the_content_feed', 'wp_staticize_emoji');
remove_filter('comment_text_rss', 'wp_staticize_emoji');
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
}
static function instant_page(){
wp_enqueue_script('speedycache_instant_page', SPEEDYCACHE_PRO_URL . '/assets/js/instantpage.js', array(), SPEEDYCACHE_PRO_VERSION, ['strategy' => 'defer', 'in_footer' => true]);
}
/*
* @param string $shortcode shortcode tag name.
* @return bool.
*/
static function has_shortcode($shortcode){
global $post;
return \has_shortcode($post->post_content, $shortcode);
}
}
htaccess.php 0000644 00000020731 15152641416 0007062 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Htaccess {
static function init(){
if(!empty($_SERVER['SERVER_SOFTWARE'])){
$server_name = sanitize_text_field(wp_unslash($_SERVER['SERVER_SOFTWARE']));
if(!empty($server_name) && (preg_match('/nginx/i', $server_name) || preg_match('/iis/i', $server_name))){
return;
}
}
if(defined('SITEPAD')){
global $sitepad;
$htaccess_file = $sitepad['path'] . '/.htaccess';
}else{
$htaccess_file = ABSPATH . '/.htaccess';
}
if(!file_exists($htaccess_file)){
return false;
}
if(!is_writable($htaccess_file)){
return;
}
$htaccess_content = file_get_contents($htaccess_file);
$htaccess_rules = '';
self::headers($htaccess_rules);
self::gzip($htaccess_rules);
self::browser_cache($htaccess_rules);
self::webp($htaccess_rules);
self::serving_rules($htaccess_rules);
// TODO: Need to add modified time here.
// Cleaning stuff
$htaccess_content = preg_replace("/#\s?BEGIN\s?LBCspeedycache.*?#\s?END\s?LBCspeedycache/s", '', $htaccess_content);
$htaccess_content = preg_replace("/#\s?BEGIN\s?WEBPspeedycache.*?#\s?END\s?WEBPspeedycache/s", '', $htaccess_content);
$htaccess_content = preg_replace("/#\s?BEGIN\s?Gzipspeedycache.*?#\s?END\s?Gzipspeedycache/s", '', $htaccess_content);
$htaccess_content = preg_replace("/#\s?BEGIN\s?SpeedyCacheheaders.*?#\s?END\s?SpeedyCacheheaders/s", '', $htaccess_content);
$htaccess_content = preg_replace("/#\s?BEGIN\s?speedycache.*?#\s?END\s?speedycache/s", '', $htaccess_content);
$htaccess_content = $htaccess_rules ."\n" . trim($htaccess_content);
file_put_contents($htaccess_file, $htaccess_content);
}
static function serving_rules(&$htaccess_rules){
global $speedycache;
$base_cache_path = defined('SITEPAD') ? 'sitepad-data' : 'wp-content';
$platform_excludes = defined('SITEPAD') ?
'RewriteCond %{REQUEST_URI} !^/(site-admin|login|wp-register|wp-comments-post|cron|sp-json)/ [NC]' :
'RewriteCond %{REQUEST_URI} !^/(wp-(?:admin|login|register|comments-post|cron|json))/ [NC]';
$htaccess_rules .= '# BEGIN speedycache
<IfModule mod_rewrite.c>
RewriteEngine On';
if(!defined('SITEPAD')){
$htaccess_rules .= "\n".'RewriteBase /';
}
if(!empty($speedycache->options['mobile']) && !empty($speedycache->options['mobile_theme'])){
$htaccess_rules .= '
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{HTTP_USER_AGENT} !(Mediatoolkitbot|facebookexternalhit|SpeedyCacheCCSS)
RewriteCond %{HTTP_USER_AGENT} (Mobile|Android|Silk\/|Kindle|Opera\sMini|BlackBerry|Opera\sMobi) [NC]
RewriteCond %{QUERY_STRING} =""
'.self::cookie_excludes().'
RewriteCond %{REQUEST_URI} !(\/){2}$
'.$platform_excludes.'
RewriteCond %{DOCUMENT_ROOT}/'.$base_cache_path.'/cache/speedycache/%{HTTP_HOST}/mobile-cache%{REQUEST_URI}/index.html -f
RewriteRule ^(.*) /'.$base_cache_path.'/cache/speedycache/%{HTTP_HOST}/mobile-cache%{REQUEST_URI}/index.html [L]'."\n";
}
$htaccess_rules .= '
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{HTTP_USER_AGENT} !(Mediatoolkitbot|facebookexternalhit|SpeedyCacheCCSS)
RewriteCond %{QUERY_STRING} =""
'.self::cookie_excludes()."\n";
if(!empty($speedycache->options['mobile'])){
$htaccess_rules .= '
RewriteCond %{HTTP_USER_AGENT} !(Mobile|Android|Silk\/|Kindle|Opera\sMini|BlackBerry|Opera\sMobi) [NC]' . "\n";
}
$htaccess_rules .= '
RewriteCond %{REQUEST_URI} !(\/){2}$
'.$platform_excludes.'
RewriteCond %{DOCUMENT_ROOT}/'.$base_cache_path.'/cache/speedycache/%{HTTP_HOST}/all%{REQUEST_URI}/index.html -f
RewriteRule ^(.*) /'.$base_cache_path.'/cache/speedycache/%{HTTP_HOST}/all%{REQUEST_URI}/index.html [L]
</IfModule>
# END speedycache' . PHP_EOL;
}
static function browser_cache(&$htaccess_rules){
global $speedycache;
if(empty($speedycache->options['lbc'])){
return;
}
$htaccess_rules .= '# BEGIN LBCspeedycache
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault A0
ExpiresByType text/css A31536000
ExpiresByType text/javascript A31536000
ExpiresByType font/ttf A31536000
ExpiresByType font/otf A31536000
ExpiresByType font/woff A31536000
ExpiresByType font/woff2 A31536000
ExpiresByType image/jpg A31536000
ExpiresByType image/jpeg A31536000
ExpiresByType image/png A31536000
ExpiresByType image/gif A31536000
ExpiresByType image/webp A31536000
ExpiresByType image/x-icon A31536000
ExpiresByType image/svg+xml A31536000
ExpiresByType image/vnd.microsoft.icon A31536000
ExpiresByType video/ogg A31536000
ExpiresByType video/mp4 A31536000
ExpiresByType video/webm A31536000
ExpiresByType audio/ogg A31536000
ExpiresByType application/pdf A31536000
ExpiresByType application/javascript A31536000
ExpiresByType application/x-javascript A31536000
ExpiresByType application/x-font-ttf A31536000
ExpiresByType application/x-font-woff A31536000
ExpiresByType application/font-woff A31536000
ExpiresByType application/font-woff2 A31536000
ExpiresByType application/vnd.ms-fontobject A31536000
</IfModule>
# END LBCspeedycache' . PHP_EOL;
}
static function webp(&$htaccess_rules){
$htaccess_rules .= '# BEGIN WEBPspeedycache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME} \.(jpe?g|png|gif)$
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f
RewriteRule ^(.+)\.(jpe?g|png|gif)$ $1.webp [T=image/webp,L]
</IfModule>
<IfModule mod_headers.c>
Header append Vary Accept env=REDIRECT_accept
</IfModule>
AddType image/webp .webp
# END WEBPspeedycache' . PHP_EOL;
}
static function gzip(&$htaccess_rules){
global $speedycache;
if(empty($speedycache->options['gzip'])){
return;
}
$htaccess_rules .= '# BEGIN Gzipspeedycache
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE font/woff
AddOutputFilterByType DEFLATE font/woff2
AddOutputFilterByType DEFLATE text/js
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/font-woff2
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
</IfModule>
# END Gzipspeedycache'. PHP_EOL;
}
static function headers(&$htaccess_rules){
$url = site_url();
$parsed_url = wp_parse_url($url);
$htaccess_rules .= '# BEGIN SpeedyCacheheaders
FileETag None
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
<FilesMatch "\.(html)$">
<IfModule mod_headers.c>
Header set x-speedycache-source "Server"
Header set Cache-Tag "'.$parsed_url['host'].'"
Header set CDN-Cache-Control "max-age=1296000"
Header set Cache-Control "public"
Header unset Pragma
Header unset Last-Modified
</IfModule>
</FilesMatch>
<FilesMatch "\.(css|htc|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$">
<IfModule mod_headers.c>
Header unset Pragma
Header set Cache-Control "public"
</IfModule>
</FilesMatch>
# END SpeedyCacheheaders'. PHP_EOL;
}
static function cookie_excludes(){
$cookies = [];
$cookies[] = 'comment_author_';
$cookies[] = 'wordpress_logged_in_';
if(!defined('SITEPAD')){
if(is_plugin_active('woo-currency/wcu.php')){
$cookies[] = 'wcu_current_currency';
}
}
$cookies_to_exclude = implode('|', $cookies);
$cookies_to_exclude = preg_replace("/\s/", "\s", $cookies_to_exclude);
return 'RewriteCond %{HTTP:Cookie} !('.$cookies_to_exclude.')';
}
}
advanced-cache.php 0000644 00000014744 15152641416 0010102 0 ustar 00 <?php
/*
* SPEEDYCACHE
* https://speedycache.com/
* (c) SpeedyCache Team
*/
if(!defined('ABSPATH')) exit;
// Check request method is Head or get
if(!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] !== 'GET'){
return;
}
if(defined('WP_INSTALLING') && WP_INSTALLING){
return;
}
if(defined('WP_CLI') && WP_CLI){
return;
}
if(empty($_SERVER['REQUEST_URI']) || empty($_SERVER['HTTP_HOST']) || empty($_SERVER['HTTP_USER_AGENT'])){
return false;
}
if(preg_match('/(\/){2}$/', $_SERVER['REQUEST_URI'])){
return false;
}
function speedycache_ac_serve_cache(){
$ignored_parameters = ['fbclid', 'utm_id', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_source_platform', 'gclid', 'dclid', 'msclkid', 'ref', 'fbaction_ids', 'fbc', 'fbp', 'clid', 'mc_cid', 'mc_eid', 'hsCtaTracking', 'hsa_cam', 'hsa_grp', 'hsa_mt', 'hsa_src', 'hsa_ad', 'hsa_acc', 'hsa_net', 'hsa_kw', 'test_speedycache'];
$uri = '';
$parsed_uri = [];
$uri = $_SERVER['REQUEST_URI'];
$uri = urldecode($uri); // Users use other languages to write as well
$uri = preg_replace('/\.{2,}/', '', $uri); // Cleaning the path
$parsed_uri = parse_url($uri);
if(!empty($parsed_uri) && !empty($parsed_uri['query'])){
parse_str($parsed_uri['query'], $parsed_query);
foreach($parsed_query as $query => $value){
if(in_array($query, $ignored_parameters)){
unset($parsed_query[$query]);
continue;
}
}
$uri = $parsed_uri['path'] . (!empty($parsed_query) ? '?'.http_build_query($parsed_query) : '');
}
// We dont know if the site is a /directory based so we just hit and try
$site_dir = '';
$path = '';
if(!empty($parsed_uri['path'])){
$path = trim($parsed_uri['path'], '/');
}
if(strpos($path, '/') !== FALSE){
$parsed_path = explode('/', $path);
$site_dir = $parsed_path[0];
} elseif(!empty($path)){
$site_dir = $path;
}
$config_file = WP_CONTENT_DIR . '/speedycache-config/' . basename($_SERVER['HTTP_HOST']) . '.php';
if(!file_exists($config_file)){
$config_file = WP_CONTENT_DIR . '/speedycache-config/' . basename($_SERVER['HTTP_HOST']) . '.'. $site_dir . '.php';
if(!file_exists($config_file)){
return;
}
}
if(!file_exists($config_file)){
return;
}
// Accessing the config file
include_once $config_file;
if(empty($speedycache_ac_config) || !is_array($speedycache_ac_config)){
return;
}
if(empty($speedycache_ac_config['settings']['status'])){
return;
}
// Exclude pages|useragent|cookie
if(speedycache_ac_excludes($speedycache_ac_config)){
return;
}
if(!empty($speedycache_ac_config['user_agents']) && preg_match('/'.preg_quote($speedycache_ac_config['user_agents']).'/', $_SERVER['HTTP_USER_AGENT'])){
return;
}
if(empty($speedycache_ac_config['settings']['logged_in_user']) && preg_grep('/^wordpress_logged_in_/i', array_keys($_COOKIE))){
return false;
}
// check comment author
if(preg_grep('/comment_author_/i', array_keys($_COOKIE))){
return false;
}
$cache_path = WP_CONTENT_DIR.'/cache/speedycache/' . basename($_SERVER['HTTP_HOST']);
// For the test cache
if(isset($_GET['test_speedycache'])){
$cache_path = '/test'. $uri;
} else if(!empty($speedycache_ac_config['settings']['mobile']) && preg_match('/Mobile|Android|Silk\/|Kindle|BlackBerry|Opera (Mini|Mobi)/i', $_SERVER['HTTP_USER_AGENT'])) {
// Check for Mobile
if(!empty($speedycache_ac_config['settings']['mobile_theme'])){
$cache_path .= '/mobile-cache' . $uri;
} else {
return; // If just mobile is enabled then we don't want to show desktop verison of cache on mobile.
}
} else {
// get path of file
$cache_path .= '/all'. $uri;
}
$file_name = 'index';
if(isset($_COOKIE['wcu_current_currency'])){
$file_name .= '-' . strtolower($_COOKIE['wcu_current_currency']);
$file_name = preg_replace('/\.{2,}/', '', $file_name); // Cleaning the path
}
$file_name .= '.html';
//check file extension
$serving_gz = '';
if(isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE && !empty($speedycache_ac_config['settings']['gzip']) && @file_exists($cache_path . '/'. $file_name.'.gz')){
$serving_gz = '.gz';
// We do not want output compression to be enabled if we are gzipping the page.
if(function_exists('ini_set')){
ini_set('zlib.output_compression', 0);
}
header('Content-Encoding: gzip');
}
if(!file_exists($cache_path . '/'.$file_name . $serving_gz)){
$serving_gz = '';
}
if(!file_exists($cache_path . '/'.$file_name . $serving_gz)){
return;
}
if(!headers_sent()){
header('x-speedycache-source: PHP');
}
$cache_created_at = filemtime($cache_path. '/'.$file_name . $serving_gz);
header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $cache_created_at) . ' GMT');
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : 0;
if($if_modified_since === $cache_created_at){
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304);
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
exit();
}
readfile($cache_path. '/'.$file_name . $serving_gz);
exit();
}
function speedycache_ac_excludes($excludes){
if(empty($excludes) || !is_array($excludes)){
return false;
}
$preg_match_rule = '';
$request_url = !empty($_SERVER['REQUEST_URI']) ? urldecode(trim($_SERVER['REQUEST_URI'], '/')) : '';
foreach($excludes as $key => $value){
$value['type'] = !empty($value['type']) ? $value['type'] : 'page';
if(!empty($value['prefix']) && $value['type'] == 'page'){
$value['content'] = trim($value['content']);
$value['content'] = trim($value['content'], '/');
if($value['prefix'] == 'exact' && strtolower($value['content']) == strtolower($request_url)){
return true;
}else{
$preg_match_rule = preg_quote($value['content'], '/');
if($preg_match_rule){
if(preg_match('/'.$preg_match_rule.'/i', $request_url)){
return true;
}
}
}
}else if($value['type'] == 'useragent'){
if(preg_match('/'.preg_quote($value['content'], '/').'/i', $_SERVER['HTTP_USER_AGENT'])){
return true;
}
}else if($value['type'] == 'cookie'){
if(isset($_SERVER['HTTP_COOKIE'])){
if(preg_match('/'.preg_quote($value['content'], '/').'/i', $_SERVER['HTTP_COOKIE'])){
return true;
}
}
}
}
}
speedycache_ac_serve_cache(); delete.php 0000644 00000033135 15152641416 0006531 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT');
}
use \SpeedyCache\Util;
class Delete{
static $cache_lifespan = 0;
static function run($actions){
global $speedycache;
// Even if the actions are empty, the cache will be deleted.
self::all_cache();
self::purge_varnish();
\SpeedyCache\CDN::purge();
delete_option('speedycache_html_size');
delete_option('speedycache_assets_size');
if(empty($actions)){
return;
}
if(!empty($actions['minified'])){
self::minified();
}
if(!empty($actions['font'])){
self::local_fonts();
}
if(!empty($actions['gravatars'])){
self::gravatar();
}
if(!empty($actions['domain'])){
self::all_for_domain();
}
if(!empty($actions['preload'])){
if(!empty($speedycache->options['preload'])){
\SpeedyCache\Preload::build_preload_list();
}
}
}
/**
* Deletes cache of a single page
* @param int $post_id
*/
static function cache($post_id = false){
global $speedycache;
if(!isset($post_id) || $post_id === FALSE || !is_numeric($post_id)){
return;
}
$link = get_permalink($post_id);
// If its 0 then it's a homepage
if($post_id == 0){
$link = home_url();
}
if(empty($link)){
return;
}
self::url($link);
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
if(!empty($speedycache->options['preload'])){
\SpeedyCache\Preload::url($link);
}
delete_option('speedycache_html_size');
delete_option('speedycache_assets_size');
}
/**
* Deletes cache of a URL
* Parses and converts a URL to cache path and purges it
* @param array|string $urls
*/
static function url($urls){
global $speedycache;
$urls = (array) $urls;
$cache_paths = [];
foreach($urls as $url){
$parsed_url = wp_parse_url($url);
$path = !empty($parsed_url['path']) ? $parsed_url['path'] : '';
// Path to be used in glob so that we can get all the variations of file created like for language or currency
$file = (empty($path) || $path == '/') ? 'index*html' : trim($path, '/') . '/index*html';
// Cache path for desktop cache
$all_path = glob(Util::cache_path('all') . $file);
$gz_path = glob(Util::cache_path('all') . $file .'.gz');
$all_path = array_merge(
is_array($all_path) ? $all_path : [],
is_array($gz_path) ? $gz_path : []
);
if(!empty($all_path)){
$cache_paths = array_merge($cache_paths, $all_path);
}
// Cache path for Mobile cache
if(!empty($speedycache->options['mobile_theme'])){
$mobile_path = glob(Util::cache_path('mobile-cache') . $file);
if(!empty($mobile_path)){
$cache_paths = array_merge($cache_paths, $mobile_path);
}
}
}
foreach($cache_paths as $cache_path){
if(!file_exists($cache_path)){
continue;
}
if(is_dir($cache_path)){
self::rmdir($cache_path);
continue;
}
unlink($cache_path);
}
}
// Delete cache of whole site
static function all_cache(){
// Our cache is saved in 2 file, /all and /mobile-cache
// We also need to delete Critical CSS too as it gets injected in the HTML
$deletable_dirs = ['all', 'mobile-cache', 'critical-css'];
foreach($deletable_dirs as $dir){
$path = Util::cache_path($dir);
self::rmdir($path);
}
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
}
// Delete minified and Critical css content.
static function minified(){
$assets_cache_path = Util::cache_path('assets');
if(!file_exists($assets_cache_path)){
return;
}
self::rmdir($assets_cache_path);
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
}
// Delete local fonts
static function local_fonts(){
$fonts_path = Util::cache_path('fonts');
if(!file_exists($fonts_path)){
return;
}
self::rmdir($fonts_path);
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
}
static function gravatar(){
$gravatar_path = Util::cache_path('gravatars');
if(!file_exists($gravatar_path)){
return;
}
self::rmdir($gravatar_path);
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
}
// Delete everything of the current domain, like minfied, cache, gravatar and fonts.
static function all_for_domain(){
}
static function rmdir($dir){
if(!file_exists($dir)){
return;
}
$files = array_diff(scandir($dir), ['..', '.']);
foreach($files as $file){
if(is_dir($dir.'/'.$file)){
self::rmdir($dir.'/'.$file);
continue;
}
unlink($dir.'/'.$file);
}
rmdir($dir);
}
static function purge_varnish(){
global $speedycache;
if(empty($speedycache->options['purge_varnish'])){
return;
}
$server = !empty($speedycache->options['varniship']) ? $speedycache->options['varniship'] : '127.0.0.1';
$url = home_url();
$url = parse_url($url);
if($url == FALSE){
return;
}
$sslverify = ($url['scheme'] === 'https') ? true : false;
$request_url = $url['scheme'] .'://'. $server . '/.*';
$request_args = array(
'method' => 'PURGE',
'headers' => array(
'Host' => $url['host'],
),
'sslverify' => $sslverify,
);
$res = wp_remote_request($request_url, $request_args);
if(is_wp_error($res)){
$msg = $res->get_error_message();
return array($msg, 'error');
}
if(is_array($res) && !empty($res['response']['code']) && '200' != $res['response']['code']){
$msg = 'Something Went Wrong Unable to Purge Varnish';
if(empty($res['response']['code']) && '501' == $res['response']['code']){
$msg = 'Your server dosen\'t allows PURGE request';
if(!empty($res['headers']['allow'])){
$msg .= 'The accepted HTTP methods are' . $res['headers']['allow'];
}
$msg = __('Please contact your hosting provider if, Varnish is enabled and still getting this error', 'speedycache');
}
return array($msg, 'error');
}
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
return array(__('Purged Varnish Cache Succesfully', 'speedycache'), 'success');
}
static function expired_cache(){
global $speedycache;
self::$cache_lifespan = Util::cache_lifespan();
// We don't want to clean cache if cache is disabled
if(empty($speedycache->options['status']) || empty(self::$cache_lifespan)){
wp_clear_scheduled_hook('speedycache_purge_cache');
return;
}
$cache_path = [];
$cache_path[] = Util::cache_path('all');
$cache_path[] = Util::cache_path('mobile-cache');
foreach($cache_path as $path){
if(!file_exists($path)){
continue;
}
self::rec_clean_expired($path);
}
// Assets are deleted only if the lifetime is more than 10 hours,
// because only then is the entire cache deleted.
// Cached assets may be used on multiple pages,
// so we must ensure they are not deleted unless all cached pages are removed.
if(self::$cache_lifespan > 10 * HOUR_IN_SECONDS){
self::minified();
if(!empty($speedycache->options['auto_purge_fonts'])){
self::local_fonts();
}
if(!empty($speedycache->options['auto_purge_gravatar'])){
self::gravatar();
}
}
// We will delete it even if the cache does not gets deleted
delete_option('speedycache_html_size');
delete_option('speedycache_assets_size');
if(class_exists('\SpeedyCache\Logs')){
\SpeedyCache\Logs::log('delete');
\SpeedyCache\Logs::action();
}
// Preload the cached
if(self::$cache_lifespan > 10 * HOUR_IN_SECONDS && !empty($speedycache->options['preload'])){
\SpeedyCache\Preload::build_preload_list();
}
}
// Recursively deletes expired cache
static function rec_clean_expired($path){
$files = array_diff(scandir($path), array('..', '.'));
if(empty($files)){
return;
}
foreach($files as $file){
$file_path = $path . '/'. $file;
if(is_dir($file_path)){
self::rec_clean_expired($file_path);
continue;
}
// We will delete all cache if the lifespan is greater than 10 hours to prevent nonce issues,
// We could delete all the cache for lifespan above 10 hrs, but for larger sites deleting
// everything colud be a overhead.
if((self::$cache_lifespan >= 10 * HOUR_IN_SECONDS) || ((filemtime($file_path) + self::$cache_lifespan) < time())){
unlink($file_path);
}
}
}
// Deletes the cache of the post whose status got changed,
// only deletes when the post transitions in our out of published mode
static function on_status_change($new_status, $old_status, $post){
global $speedycache;
if($old_status == $new_status && $old_status !== 'publish') return;
if($old_status !== 'publish' && $new_status !== 'publish'){
return;
}
if(empty($speedycache->options['status'])){
return;
}
if(!empty(wp_is_post_revision($post->ID))){
return;
}
// Current post should not be deleted when its anything other than publish,
// As in some states its URL changes to ?page_id=
if($new_status == 'publish'){
self::cache($post->ID);
}
// Deleting the cache of home page and blog page
$home_page_id = get_option('page_on_front');
self::cache($home_page_id);
// For some sites home page and blog page could be same
$blog_page_id = get_option('page_for_posts');
if($home_page_id !== $blog_page_id){
self::cache($blog_page_id);
}
// Deleting the author page cache
$author_page_url = get_author_posts_url($post->post_author);
self::url($author_page_url);
// Deleting cache of related terms
self::terms($post->ID);
// Delete shop page when product status changes.
if(function_exists('wc_get_page_id')){
$shop_page_id = wc_get_page_id('shop');
if($home_page_id !== $shop_page_id){
self::cache($shop_page_id);
}
}
// This is used to delete post which may have the current post as the related post / product in them
self::adjacent_posts_urls();
}
// Deletes cache of the page where a comments status got change.
static function on_comment_status($new_status, $old_status, $comment){
global $speedycache;
if($old_status == $new_status && $old_status !== 'approved') return;
if($old_status !== 'approved' && $new_status !== 'approved'){
return;
}
if(empty($speedycache->options['status'])){
return;
}
self::cache($comment->comment_parent);
}
static function terms($post_id){
global $speedycache;
if(empty($post_id) || !is_numeric($post_id)){
return;
}
$post_type = get_post_type($post_id);
if(empty($post_type)){
return;
}
// Get all taxonomies for the post type
$taxonomies = get_object_taxonomies($post_type, 'objects');
// Filter to keep only public taxonomies
$public_taxonomies = [];
foreach($taxonomies as $taxonomy){
if($taxonomy->public){
$public_taxonomies[] = $taxonomy->name;
}
}
if(empty($public_taxonomies)){
return;
}
$terms = wp_get_post_terms($post_id, $public_taxonomies);
if(empty($terms) || is_wp_error($terms)){
return;
}
$deletable_links = [];
foreach($terms as $term){
$link = get_term_link($term->term_id);
if(is_wp_error($link) || empty($link)){
continue;
}
$deletable_links[] = $link;
$ancestors = get_ancestors($term->term_id, $term->taxonomy);
if(!empty($ancestors)){
foreach($ancestors as $ancestor){
$ancestor_link = get_term_link($ancestor);
if(is_wp_error($ancestor_link) || empty($ancestor_link)){
continue;
}
$deletable_links[] = $ancestor_link;
}
}
}
if(empty($deletable_links)){
return;
}
$deletable_links = array_unique($deletable_links);
self::url($deletable_links);
if(!empty($speedycache->options['preload'])){
\SpeedyCache\Preload::url($deletable_links);
}
}
static function adjacent_posts_urls(){
$post_urls = [];
$prev_post = get_adjacent_post();
$prev_post_term = get_adjacent_post(true, '');
$next_post = get_adjacent_post(false, '', true);
$next_post_term = get_adjacent_post(true, '', true);
if(!empty($prev_post)){
$post_urls[] = get_permalink($prev_post);
}
if(!empty($prev_post_term)){
$post_urls[] = get_permalink($prev_post_term);
}
if(!empty($next_post)){
$post_urls[] = get_permalink($next_post);
}
if(!empty($next_post_term)){
$post_urls[] = get_permalink($next_post_term);
}
if(!empty($post_urls)){
self::url($post_urls);
}
}
// Deletes cache of product page and its related pages when a order is made
static function order($order_id){
global $speedycache;
if(empty($speedycache->options['status'])){
return;
}
if(!function_exists('wc_get_order')){
return;
}
$order = wc_get_order($order_id);
$items = $order->get_items();
foreach($items as $item){
$product_id = $item->get_product_id();
if(empty($product_id)){
continue;
}
self::cache($product_id);
$categories = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'ids'));
foreach($categories as $category){
self::cache($category);
}
}
$shop_page_id = wc_get_page_id('shop');
self::cache($shop_page_id);
}
}
css.php 0000644 00000014334 15152641416 0006057 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
use \SpeedyCache\lib\Minify;
use \SpeedyCache\Util;
class CSS{
static function minify(&$content){
global $speedycache;
if(empty($content)){
return;
}
preg_match_all('/<link\s+([^>]+[\s"\'])?href\s*=\s*[\'"]\s*?(?<url>[^\'"]+\.css(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?>/Umsi', $content, $tags, PREG_SET_ORDER);
if(empty($tags)){
return;
}
if(empty($_SERVER['HTTP_HOST'])){
return;
}
$site_host = str_replace('www.', '', sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])));
$site_url = site_url();
foreach($tags as $tag){
if(empty($tag['url'])){
continue;
}
$url = $tag['url'];
if(self::is_excluded($url)) continue;
// We don't want to minify already minified css
if(strpos($url, '.min.css') !== FALSE){
continue;
}
// We wont process any css that is not present on this WordPress install
if(strpos($url, $site_host) === FALSE){
continue;
}
$file_path = Util::url_to_path($url);
if(!file_exists($file_path)){
continue;
}
$file_name = self::file_name($file_path);
$asset_path = Util::cache_path('assets');
if(!is_dir($asset_path)){
mkdir($asset_path, 0755, true);
touch($asset_path . 'index.html');
}
$minified_path = $asset_path.$file_name;
// If we already have a minified file then we dont need to process it again.
if(!file_exists($minified_path)){
$minified = new Minify\CSS($file_path);
$minified = $minified->minify();
$minified = self::fix_relative_path($minified, $url);
file_put_contents($minified_path, $minified);
}
$minified_url = Util::path_to_url($minified_path);
$content = str_replace($tag['url'], $minified_url, $content);
// TODO: check if there is a preload.
}
}
static function file_name($path){
$file_hash = md5_file($path);
$file_name = substr($file_hash, 0, 16) . '-' . basename($path);
return $file_name;
}
static function combine(&$content){
if(empty($content)){
return;
}
preg_match_all('/<link\s+([^>]+[\s"\'])?href\s*=\s*[\'"]\s*?(?<url>[^\'"]+\.css(?:\?[^\'"]*)?)\s*?[\'"]([^>]+)?\/?>/Umsi', $content, $tags, PREG_SET_ORDER);
if(empty($tags)){
return;
}
if(empty($_SERVER['HTTP_HOST'])){
return;
}
$site_host = str_replace('www.', '', sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])));
$site_url = site_url();
$combined_css = '';
$prev_tag = '';
$tags = array_reverse($tags);
foreach($tags as $tag){
if(empty($tag['url'])){
continue;
}
$url = $tag['url'];
if(self::is_excluded($url)) continue;
// We wont process any css that is not present on this WordPress install
if(strpos($url, $site_host) === FALSE){
continue;
}
$file_path = Util::url_to_path($url);
if(!file_exists($file_path) || !is_readable($file_path)){
continue;
}
$new_css = file_get_contents($file_path);
$new_css = self::fix_relative_path($new_css, $url);
$combined_css = $new_css . "\n" . $combined_css;
// Removing the CSS which has already been combined, as we will add the combined file at the top after title.
if(!empty($prev_tag)){
$content = str_replace($prev_tag, '', $content);
}
// We remove the previous tag, in current iteration, so at last we have a tag to replace wirh the combined script.
$prev_tag = $tag[0];
//TODO: Need to remove any preload added by any plugin or a theme.
}
if(empty($combined_css)){
return;
}
// Creating Combined file name
$file_name = md5($combined_css);
$file_name = substr($file_name, 0, 16) . '-combined.css';
$asset_path = Util::cache_path('assets');
if(!is_dir($asset_path)){
mkdir($asset_path, 0755, true);
touch($asset_path . 'index.html');
}
$combined_path = $asset_path.$file_name;
file_put_contents($combined_path, $combined_css);
$final_url = Util::path_to_url($combined_path);
// Injecting the Combined CSS
if(!empty($prev_tag)){
$content = str_replace($prev_tag, '<link rel="stylesheet" href="'.esc_url($final_url).'" />', $content);
return;
}
$content = str_replace('</title>', "</title>\n".'<link rel="stylesheet" href="'.esc_url($final_url).'" />', $content);
}
static function is_excluded($url){
$excludes = get_option('speedycache_exclude', []);
if(empty($excludes)){
return false;
}
foreach($excludes as $exclude){
if(empty($exclude['type'])){
continue;
}
if($exclude['type'] !== 'css'){
continue;
}
if(empty($exclude['content'])){
continue;
}
if(preg_match('/'.preg_quote($exclude['content'], '/').'/', $url)){
return true;
}
}
return false;
}
static function fix_relative_path($content, $base_url){
// We need base url as the relative url file will be in the same folder as file at the base url or will be relative to path of the base url
$content = preg_replace_callback('/url\(\s*["\']?(?!http|https|\/\/)([^"\')]+)["\']?\s*\)/i', function($matches) use ($base_url) {
$relative_path = $matches[1];
$relative_path = trim($relative_path, '/');
$base_path = Util::url_to_path($base_url);
if(strpos($relative_path, '..') === 0 || strpos($relative_path, './') === 0){
$parameter = '';
// Some URL's had query parameters, that were breaking when using realpath
if(strpos($relative_path, '?') !== FALSE){
$parsed_path = explode('?', $relative_path);
$parameter = $parsed_path[1];
$relative_path = $parsed_path[0];
$parsed_path = null;
}
$absolute_path = realpath(dirname($base_path) . '/' . $relative_path);
$absolute_url = Util::path_to_url($absolute_path);
// Appending the parameter again
if(!empty($parameter)){
$absolute_url .= '?'. $parameter;
}
} else if(strpos($relative_path, 'wp-content') === 0){
$absolute_url = site_url() . '/'. $relative_path;
}
if(empty($absolute_url)){
$absolute_url = $relative_path;
}
return 'url("' . $absolute_url . '")';
}, $content);
return $content;
}
}
preload.php 0000644 00000006571 15152641416 0006721 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Preload{
static function build_preload_list(){
global $wp_rewrite;
delete_transient('speedycache_preload_transient');
if(!isset($wp_rewrite)){
$wp_rewrite = new \WP_Rewrite();
}
$preload_urls = [];
$preload_urls[] = home_url();
$args = [
'fields' => 'ids',
'post_type' => ['post', 'page', 'product', 'docs'],
'posts_per_page' => 80,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'has_password' => false,
];
$query = new \WP_Query($args);
if($query->have_posts()){
$posts = $query->get_posts();
foreach($posts as $post_id){
$preload_urls[] = get_permalink($post_id);
}
}
$query = null;
$args = [
'fields' => 'ids',
'post_type' => 'page',
'posts_per_page' => 10,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'has_password' => false
];
$query = new \WP_Query($args);
if($query->have_posts()){
$posts = $query->get_posts();
foreach($posts as $post_id){
$preload_urls[] = get_permalink($post_id);
}
}
$preload_urls = array_unique($preload_urls);
set_transient('speedycache_preload_transient', $preload_urls, HOUR_IN_SECONDS);
wp_schedule_single_event(time(), 'speedycache_preload_split');
}
static function cache(){
global $speedycache;
$preload_urls = get_transient('speedycache_preload_transient');
$cache_urls = 0;
if(empty($preload_urls) || !is_array($preload_urls)){
return;
}
foreach($preload_urls as $key => $url){
if($cache_urls >= 10){
break;
}
wp_remote_get($url, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
],
'timeout' => 0.01,
'blocking' => false,
'sslverify' => false,
]);
// Preload mobile version too
if(!empty($speedycache->options['mobile_theme'])){
wp_remote_get($url, [
'headers' => [
'User-Agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/114.0.5735.99 Mobile/15E148 Safari/604.1'
],
'timeout' => 0.01,
'blocking' => false,
'sslverify' => false,
]);
}
unset($preload_urls[$key]); // We remove from the list to be preloaded
$cache_urls++;
}
if(empty($preload_urls)){
set_transient('speedycache_preload_transient', [], HOUR_IN_SECONDS);
return;
}
wp_schedule_single_event(time() + 60, 'speedycache_preload_split');
set_transient('speedycache_preload_transient', $preload_urls, HOUR_IN_SECONDS);
}
// This will push a request to preload URLS
// TODO: need to add a lock here
static function url($urls){
if(!is_array($urls)){
$urls = [$urls];
}
$preload_urls = get_transient('speedycache_preload_transient');
if(empty($preload_urls) || !is_array($preload_urls)){
$preload_urls = [];
}
$preload_urls = array_merge($preload_urls, $urls);
$preload_urls = array_unique($preload_urls);
set_transient('speedycache_preload_transient', $preload_urls, HOUR_IN_SECONDS);
if(!wp_next_scheduled('speedycache_preload_split')){
wp_schedule_single_event(time() + 60, 'speedycache_preload_split');
}
}
}
imageseo.php 0000644 00000006052 15152641524 0007056 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class ImageSeo{
static function init(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return; // toggle disable
}
if(!empty($siteseo->advanced_settings['advanced_attachments'])){
add_action('template_redirect', '\SiteSEO\ImageSeo::redirect_attachment_to_parent');
}
if(!empty($siteseo->advanced_settings['advanced_clean_filename'])){
add_filter('sanitize_file_name', '\SiteSEO\ImageSeo::clean_media_filename', 10, 1);
}
if(!empty($siteseo->advanced_settings['advanced_image_auto_alt_editor']) ||
!empty($siteseo->advanced_settings['advanced_image_auto_caption_editor']) ||
!empty($siteseo->advanced_settings['advanced_image_auto_desc_editor']) ||
!empty($siteseo->advanced_settings['advanced_image_auto_title_editor'])
){
add_action('add_attachment', '\SiteSEO\ImageSeo::set_image_content');
}
}
static function set_image_content($attachment_id){
global $siteseo;
if(!wp_attachment_is_image($attachment_id)){
return;
}
$attachment = get_post($attachment_id);
$file_name = pathinfo($attachment->guid, PATHINFO_FILENAME);
$file_name = sanitize_file_name($file_name);
$file_name = ucwords(str_replace(['-', '_'], ' ', $file_name));
// WooCommerce product img
$is_woocommerce_product_image = false;
$product_title = '';
$parent_id = $attachment->post_parent;
if(!empty($parent_id)){
$parent_post = get_post($parent_id);
if(!empty($parent_post) && $parent_post->post_type === 'product'){
$is_woocommerce_product_image = true;
$product_title = get_the_title($parent_id);
}
}
$file_name = $is_woocommerce_product_image ? $product_title : $file_name;
// Adding alt text to the image
if(!empty($siteseo->advanced_settings['advanced_image_auto_alt_editor'])){
update_post_meta($attachment_id, '_wp_attachment_image_alt', $file_name);
}
$options = [];
$options['ID'] = $attachment_id;
// Adding Title to the image
if(!empty($siteseo->advanced_settings['advanced_image_auto_title_editor'])){
$options['post_title'] = $file_name;
}
// Adding Img Caption
if(!empty($siteseo->advanced_settings['advanced_image_auto_caption_editor'])){
$options['post_content'] = $file_name;
}
// Adding Img Caption
if(!empty($siteseo->advanced_settings['advanced_image_auto_desc_editor'])){
$options['post_excerpt'] = $file_name;
}
if(count($options) > 1){
wp_update_post($options);
}
}
static function clean_media_filename($filename){
$filename = strtolower($filename);
$filename = preg_replace('/[^a-z0-9-._]+/', '-', $filename);
$filename = trim($filename, '-.');
return $filename;
}
static function redirect_attachment_to_parent(){
if(is_attachment()){
$attachment_id = get_queried_object_id();
$parent_id = wp_get_post_parent_id($attachment_id);
if($parent_id){
wp_redirect(get_permalink($parent_id));
}else{
wp_redirect(home_url());
}
exit;
}
}
}
settings/statistics.php 0000644 00000143411 15152641524 0011320 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Statistics{
static function init(){
global $siteseo;
$current_tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'tab_dashbord';
wp_enqueue_script('siteseo-chart-js', SITESEO_ASSETS_URL . '/js/chart.umd.min.js', [], SITESEO_VERSION, ['strategy' => 'defer', 'in_footer' => true]);
wp_enqueue_script('siteseo-gsc-charts', SITESEO_ASSETS_URL . '/js/gsc-charts.js', ['jquery', 'siteseo-chart-js'], SITESEO_VERSION, ['strategy' => 'defer', 'in_footer' => true]);
$saved_data = get_option('siteseo_search_console_data', []);
wp_localize_script('siteseo-gsc-charts', 'siteseo_chart_data', $saved_data);
if(isset($_GET['siteseo_auth_code']) && class_exists('\SiteSEOPro\GoogleConsole') && method_exists('\SiteSEOPro\GoogleConsole', 'generate_tokens')){
\SiteSEOPro\GoogleConsole::generate_tokens();
}
if(isset($_GET['siteseo_auth_code']) && class_exists('\SiteSEOPro\GoogleConsole')){
add_action('admin_footer', '\SiteSEO\Settings\Statistics::connect_site_dialogbox');
}
$site_connected = false;
if(class_exists('\SiteSEOPro\GoogleConsole') && method_exists('\SiteSEOPro\GoogleConsole', 'is_connected')){
$site_connected = \SiteSEOPro\GoogleConsole::is_connected();
}
$statistics_subtabs = [
'tab_dashbord' => esc_html__('Dashboard', 'siteseo'),
'tab_seo_statistics' => esc_html__('Site Search Traffic', 'siteseo'),
'tab_keyword_rank' => esc_html__('Keyword Rank Tracker', 'siteseo'),
'tab_content_ranking' => esc_html__('Content Ranking', 'siteseo'),
'tab_audience' => esc_html__('Audience Overview', 'siteseo'),
];
echo'<div id="siteseo-root" class="siteseo-search-console">';
Util::admin_header();
$show_sample_data = isset($_GET['sample_data']) && $_GET['sample_data'] === '1';
if(!class_exists('\SiteSEOPro\GoogleConsole') && !$show_sample_data){
echo'<div class="siteseo-blur-overlay"></div>
<div class="siteseo-pro-notice-center">
<div class="siteseo-pro-notice-content">
<span class="dashicons dashicons-lock siteseo-lock-icon"></span>
<h2>'.esc_html__('Search Console Pro Feature', 'siteseo').'</h2>
<p>'.esc_html__('Upgrade to PRO to unlock Google Search Console integration and access real-time search analytics data.', 'siteseo').'</p>
<div class="siteseo-option siteseo-pro-notice-buttons">
<a href="https://siteseo.io/pricing" class="siteseo-option btnPrimary" target="_blank">' . esc_html__('Buy Pro', 'siteseo') . '</a>
<a href="'.esc_url(add_query_arg('sample_data', '1')).'" class="siteseo-option btnSecondary">'.esc_html__('Explore Sample Data', 'siteseo').'</a>
</div>
</div>
</div>';
} elseif(class_exists('\SiteSEOPro\GoogleConsole') && !$show_sample_data && empty($site_connected)){
echo'<div class="siteseo-blur-overlay"></div>
<div class="siteseo-pro-notice-center">
<div class="siteseo-pro-notice-content">
<span class="dashicons dashicons-admin-links siteseo-link-icon"></span>
<h2>'.esc_html__('Search Console statistics', 'siteseo').'</h2>
<p>'.esc_html__('Please connect your Google Search Console account to unlock real-time search analytics data.', 'siteseo').'</p>
<div class="siteseo-option siteseo-pro-notice-buttons">
<form method="post">';
wp_nonce_field('siteseo_pro_connect_google');
echo '<input type="hidden" name="redirect_type" value="settings">
<button type="submit" name="siteseo_pro_connect_btn" class="siteseo-option btnPrimary siteseo-connect-btn">'.esc_html__('Connect Search Console', 'siteseo') .'</button>
</form>
<a href="'.esc_url(add_query_arg('sample_data', '1')).'" class="siteseo-option btnSecondary">'.esc_html__('Explore Sample Data', 'siteseo').'</a>
</div>
</div>
</div>';
}
echo'<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">
<div class="siteseo-toggle-cnt"><span id="siteseo-tab-title"><strong>'.esc_html__('Google Search Console Statistics', 'siteseo').'</strong></span></div>';
if(!empty($site_connected)){
if(class_exists('\SiteSEOPro\GoogleConsole') && method_exists('\SiteSEOPro\GoogleConsole', 'get_site_url')){
$site_url = \SiteSEOPro\GoogleConsole::get_site_url();
}
if(!empty($site_url)){
echo'<div class="siteseo-statistics-wrapper">
<span class="siteseo-statistics-sites">Site: '.(strpos($site_url, 'sc-domain:') === 0 ? sanitize_text_field($site_url) : esc_url($site_url)).' <span id="siteseo-refresh-search-stats" class="dashicons dashicons-update" title="'.esc_attr__('Update Stats', 'siteseo').'"></span></span>
<span class="siteseo-statistics-disconnect"><span class="dashicons dashicons-migrate"></span>'.esc_html__('Disconnect', 'siteseo').'</span>
<span class="siteseo-statistics-data-range">'.esc_html__('[Last 90 days data]', 'siteseo').'</span>
</div>';
}
}
echo'<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($statistics_subtabs as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo'<a id="' . esc_attr($tab_key) . '-tab" class="siteseo-nav-tab' . esc_attr($active_class) . '" data-tab="' . esc_attr($tab_key) . '">' . esc_html($tab_caption) . '</a>';
}
echo'</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab' .($current_tab == 'tab_dashbord' ? ' active' : '').'" id="tab_dashbord" style="display: none;">';
self::dashbord_tab();
echo'</div>
<div class="siteseo-tab' .($current_tab == 'tab_seo_statistics' ? ' active' : '').'" id="tab_seo_statistics" style="display: none;">';
self::seo_statistics_tab();
echo'</div>
<div class="siteseo-tab' .($current_tab == 'tab_keyword_rank' ? ' active' : '').'" id="tab_keyword_rank" style="display: none;">';
self::keyword_ranking_tab();
echo'</div>
<div class="siteseo-tab' .($current_tab == 'tab_content_ranking' ? ' active' : '').'" id="tab_content_ranking" style="display: none;">';
self::content_ranking_tab();
echo'</div>
<div class="siteseo-tab '.($current_tab =='tab_audience' ? ' active' : '').'" id="tab_audience" style="display:none;">';
self::audience_tab();
echo'</div>
</div>';
echo'</form></div>';
}
static function fetch_data(){
$is_connected = '';
if(class_exists('\SiteSEOPro\GoogleConsole') && method_exists('\SiteSEOPro\GoogleConsole', 'is_connected')){
$is_connected = \SiteSEOPro\GoogleConsole::is_connected();
}
$analytics_data = get_option('siteseo_search_console_data', []);
if(empty($analytics_data) && empty($is_connected)){
// Show sample data when not connected
return [
'metrics' => self::sample_metrics_data(),
'top_pages' => self::sample_top_pages(),
'top_loss_pages' => array_slice(self::sample_top_pages(), 0, 3), // Sample loss pages
'top_winning_pages' => array_slice(self::sample_top_pages(), 3, 3), // Sample winning pages
'keywords' => self::sample_keywords(),
'top_winning_keywords' => array_slice(self::sample_keywords(), 0, 3), // Sample winning keywords
'top_loss_keywords' => array_slice(self::sample_keywords(), 3, 2), // Sample loss keywords
'content_ranking' => self::sample_content_ranking(),
'country_data' => self::sample_country_data(),
'device_data' => self::sample_device_data(),
'is_sample' => true
];
}
return [
'metrics' => isset($analytics_data['metrics']) ? $analytics_data['metrics'] : [
'impressions' => [
'current' => '0',
'change' => '0',
'trend' => 'neutral',
'chart_data' => []
],
'clicks' => [
'current' => '0',
'change' => '0',
'trend' => 'neutral',
'chart_data' => []
],
'ctr' => [
'current' => '0%',
'change' => '0',
'trend' => 'neutral',
'chart_data' => []
],
'position' => [
'current' => '0',
'change' => '0',
'trend' => 'neutral',
'chart_data' => []
]
],
'top_pages' => isset($analytics_data['top_pages']) ? array_slice($analytics_data['top_pages'], 0, 5) : [],
'top_loss_pages' => isset($analytics_data['top_loss_pages']) ? array_slice($analytics_data['top_loss_pages'], 0, 5) : [],
'top_winning_pages' => isset($analytics_data['top_winning_pages']) ? array_slice($analytics_data['top_winning_pages'], 0, 5) : [],
'keywords' => isset($analytics_data['top_keywords']) ? array_slice($analytics_data['top_keywords'], 0, 5) : [],
'top_winning_keywords' => isset($analytics_data['top_winning_keywords']) ? array_slice($analytics_data['top_winning_keywords'], 0, 5) : [],
'top_loss_keywords' => isset($analytics_data['top_loss_keywords']) ? array_slice($analytics_data['top_loss_keywords'], 0, 5) : [],
'content_ranking' => isset($analytics_data['content_ranking']) ? $analytics_data['content_ranking'] : [],
'country_data' => isset($analytics_data['country_audience']) ? $analytics_data['country_audience'] : [],
'device_data' => isset($analytics_data['device_audience']) ? $analytics_data['device_audience'] : [],
'is_sample' => false
];
}
static function dashbord_tab(){
self::connect_notices();
$data = self::fetch_data();
$metrics = $data['metrics'];
$top_pages = $data['top_pages'];
$top_loss_pages = $data['top_loss_pages'];
$top_winning_pages = $data['top_winning_pages'];
$keywords = $data['keywords'];
$top_winning_keywords = $data['top_winning_keywords'];
$top_loss_keywords = $data['top_loss_keywords'];
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Search Performance', 'siteseo').'</h2>
<hr class="siteseo-stats-separator">
<div class="siteseo-dashboard-grid">
<div class="siteseo-metric-card">
<div class="siteseo-metric-header">
<span class="siteseo-metric-title">'.esc_html__('Search Impressions', 'siteseo').'</span>
</div>
<div class="siteseo-metric-value-row">
<span class="siteseo-metric-value">'.esc_html($metrics['impressions']['current']).'</span>
<span class="siteseo-metric-change '.($metrics['impressions']['trend'] == 'negative' ? 'siteseo-change-negative' : ($metrics['impressions']['trend'] == 'positive' ? 'siteseo-change-positive' : '')).'">
'.($metrics['impressions']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['impressions']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['impressions']['change']).'
</span>
</div>
<div class="siteseo-chart-container">
<canvas id="siteseo_impressions_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
</div>
<div class="siteseo-metric-card">
<div class="siteseo-metric-header">
<span class="siteseo-metric-title">'.esc_html__('Total Clicks', 'siteseo').'</span>
</div>
<div class="siteseo-metric-value-row">
<span class="siteseo-metric-value">'.esc_html($metrics['clicks']['current']).'</span>
<span class="siteseo-metric-change '.($metrics['clicks']['trend'] == 'negative' ? 'siteseo-change-negative' : ($metrics['clicks']['trend'] == 'positive' ? 'siteseo-change-positive' : '')).'">
'.($metrics['clicks']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['clicks']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['clicks']['change']).'
</span>
</div>
<div class="siteseo-chart-container">
<canvas id="siteseo_clicks_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
</div>
<div class="siteseo-metric-card">
<div class="siteseo-metric-header">
<span class="siteseo-metric-title">'.esc_html__('Avg. CTR', 'siteseo').'</span>
</div>
<div class="siteseo-metric-value-row">
<span class="siteseo-metric-value">'.esc_html($metrics['ctr']['current']).'</span>
<span class="siteseo-metric-change '.($metrics['ctr']['trend'] == 'negative' ? 'siteseo-change-negative' : ($metrics['ctr']['trend'] == 'positive' ? 'siteseo-change-positive' : '')).'">
'.($metrics['ctr']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['ctr']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['ctr']['change']).'
</span>
</div>
<div class="siteseo-chart-container">
<canvas id="siteseo_ctr_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
</div>
<div class="siteseo-metric-card">
<div class="siteseo-metric-header">
<span class="siteseo-metric-title">'.esc_html__('Avg. Position', 'siteseo').'</span>
</div>
<div class="siteseo-metric-value-row">
<span class="siteseo-metric-value">'.esc_html($metrics['position']['current']).'</span>
<span class="siteseo-metric-change '.($metrics['position']['trend'] == 'negative' ? 'siteseo-change-negative' : ($metrics['position']['trend'] == 'positive' ? 'siteseo-change-positive' : '')).'">
'.($metrics['position']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['position']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['position']['change']).'
</span>
</div>
<div class="siteseo-chart-container">
<canvas id="siteseo_position_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
</div>
</div>
</div>';
if(!empty($top_pages) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Content Performance ( Top 5 )', 'siteseo').'</h2>
<div class="siteseo-inner-tabs-wrap">
<input type="radio" id="siteseo-statistics-top-page" name="siteseo-inner-tabs-pages" checked>
<input type="radio" id="siteseo-statistics-top-loss" name="siteseo-inner-tabs-pages">
<input type="radio" id="siteseo-statistics-top-winning" name="siteseo-inner-tabs-pages">
<ul class="siteseo-inner-tabs">
<li class="siteseo-inner-tab"><label for="siteseo-statistics-top-page">'.esc_html__('Top Pages', 'siteseo').'</label></li>
<li class="siteseo-inner-tab"><label for="siteseo-statistics-top-loss">'.esc_html__('Top loss', 'siteseo').'</label></li>
<li class="siteseo-inner-tab"><label for="siteseo-statistics-top-winning">'.esc_html__('Top winning', 'siteseo').'</label></li>
</ul>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Title', 'siteseo').'</th>
<th>'.esc_html__('Score', 'siteseo').'</th>
<th>'.esc_html__('Indexed', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
<th>'.esc_html__('Diff', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($top_pages as $page){
$score = $page['truseo_score'];
if($score >= 80){
$badge_class = 'siteseo-gsc-score-good';
} elseif ($score >= 50){
$badge_class = 'siteseo-gsc-score-avg';
} else{
$badge_class = 'siteseo-gsc-score-bad';
}
echo'<tr>
<td>'.esc_html($page['title']).'</td>
<td><span class="'.esc_attr($badge_class).'">'.esc_html($page['truseo_score']).'/100</span></td>
<td><span class="dashicons '.($page['indexed'] ? 'dashicons-yes-alt siteseo-statistics-index-icon' : 'dashicons-dismiss siteseo-statistics-noindex-icon').'"></span></td>
<td>'.esc_html($page['clicks']).'</td>
<td>'.esc_html($page['impressions']).'</td>
<td>'.esc_html($page['position']).'</td>
<td style="color:'.(isset($page['diff']) && strpos($page['diff'], '+') === 0 ? '#28a745' : '#dc3545').';">'.esc_html($page['diff']).'</td>
</tr>';
}
if(empty($top_pages) && !$data['is_sample']){
echo '<tr><td colspan="7" style="text-align:center;">'.esc_html__('No data available yet', 'siteseo').'</td></tr>';
}
echo'</tbody></table>
</div>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Title', 'siteseo').'</th>
<th>'.esc_html__('Score', 'siteseo').'</th>
<th>'.esc_html__('Indexed', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
<th>'.esc_html__('Diff', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
// Use top_loss_pages instead of top_pages
foreach($top_loss_pages as $page){
$score = $page['truseo_score'];
if($score >= 80){
$badge_class = 'siteseo-gsc-score-good';
} elseif($score >= 50){
$badge_class = 'siteseo-gsc-score-avg';
} else{
$badge_class = 'siteseo-gsc-score-bad';
}
echo'<tr>
<td>'.esc_html($page['title']).'</td>
<td><span class="'.esc_attr($badge_class).'">'.esc_html($page['truseo_score']).'/100</span></td>
<td><span class="dashicons '.($page['indexed'] ? 'dashicons-yes-alt siteseo-statistics-index-icon' : 'dashicons-dismiss siteseo-statistics-noindex-icon').'"></span></td>
<td>'.esc_html($page['clicks']).'</td>
<td>'.esc_html($page['impressions']).'</td>
<td>'.esc_html($page['position']).'</td>
<td style="color:#dc3545;">'.esc_html($page['diff']).'</td>
</tr>';
}
if(empty($top_loss_pages) && !$data['is_sample']){
echo '<tr><td colspan="7" style="text-align:center;">'.esc_html__('No loss pages data available', 'siteseo').'</td></tr>';
}
echo'</tbody></table>
</div>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Title', 'siteseo').'</th>
<th>'.esc_html__('Score', 'siteseo').'</th>
<th>'.esc_html__('Indexed', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
<th>'.esc_html__('Diff', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
// Use top_winning_pages instead of top_pages
foreach($top_winning_pages as $page){
$score = $page['truseo_score'];
if($score >= 80){
$badge_class = 'siteseo-gsc-score-good';
} elseif($score >= 50){
$badge_class = 'siteseo-gsc-score-avg';
} else{
$badge_class = 'siteseo-gsc-score-bad';
}
echo'<tr>
<td>'.esc_html($page['title']).'</td>
<td><span class="'.esc_attr($badge_class).'">'.esc_html($page['truseo_score']).'/100</span></td>
<td><span class="dashicons '.($page['indexed'] ? 'dashicons-yes-alt siteseo-statistics-index-icon' : 'dashicons-dismiss siteseo-statistics-noindex-icon').'"></span></td>
<td>'.esc_html($page['clicks']).'</td>
<td>'.esc_html($page['impressions']).'</td>
<td>'.esc_html($page['position']).'</td>
<td style="color:#28a745;">'.esc_html($page['diff']).'</td>
</tr>';
}
if(empty($top_winning_pages) && !$data['is_sample']){
echo '<tr><td colspan="7" style="text-align:center;">'.esc_html__('No winning pages data available', 'siteseo').'</td></tr>';
}
echo'</tbody></table>
</div>
</div>
</div>';
}
if(!empty($keywords) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Keyword Rankings ( Top 5 )', 'siteseo').'</h2>
<div class="siteseo-inner-tabs-wrap">
<input type="radio" id="siteseo-statistics-top-keywords" name="siteseo-inner-tabs-keywords" checked>
<input type="radio" id="siteseo-statistics-winning-keywords" name="siteseo-inner-tabs-keywords">
<input type="radio" id="siteseo-statistics-loss-keywords" name="siteseo-inner-tabs-keywords">
<ul class="siteseo-inner-tabs">
<li class="siteseo-inner-tab"><label for="siteseo-statistics-top-keywords">'.esc_html__('Top Keywords', 'siteseo').'</label></li>
<li class="siteseo-inner-tab"><label for="siteseo-statistics-winning-keywords">'.esc_html__('Top Winning', 'siteseo').'</label></li>
<li class="siteseo-inner-tab"><label for="siteseo-statistics-loss-keywords">'.esc_html__('Top LOSS', 'siteseo').'</label></li>
</ul>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead>
<tr>
<th>'.esc_html__('Keyword', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('CTR', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($keywords as $keyword){
echo'<tr>
<td class="siteseo-table-row">'.esc_html($keyword['keyword']).'</td>
<td style="font-weight:bold;">'.esc_html($keyword['clicks']).'</td>
<td>'.esc_html($keyword['impressions']).'</td>
<td>'.esc_html($keyword['ctr']).'</td>
<td>'.esc_html($keyword['position']).'</td>
</tr>';
}
if(empty($keywords) && !$data['is_sample']){
echo'<tr><td colspan="5" style="text-align:center;">'.esc_html__('No data available yet', 'siteseo').'</td></tr>';
}
echo'</tbody>
</table>
</div>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead>
<tr>
<th>'.esc_html__('Keyword', 'siteseo').'</th>
<th>'.esc_html__('Points', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
// Use top_winning_keywords instead of keywords
foreach($top_winning_keywords as $keyword){
echo'<tr>
<td class="siteseo-table-row">'.esc_html($keyword['keyword']).'</td>
<td style="color:#28a745;font-weight:bold;">'.esc_html($keyword['points']).'</td>
<td>'.esc_html($keyword['clicks']).'</td>
<td>'.esc_html($keyword['position']).'</td>
</tr>';
}
if(empty($top_winning_keywords) && !$data['is_sample']){
echo'<tr><td colspan="4" style="text-align:center;">'.esc_html__('No winning keywords data available', 'siteseo').'</td></tr>';
}
echo'</tbody>
</table>
</div>
<div class="siteseo-inner-tab-content">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead>
<tr>
<th>'.esc_html__('Keyword', 'siteseo').'</th>
<th>'.esc_html__('Points', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
// Use top_loss_keywords instead of keywords
foreach($top_loss_keywords as $keyword){
echo'<tr>
<td class="siteseo-table-row">'.esc_html($keyword['keyword']).'</td>
<td style="color:#dc3545;font-weight:bold;">'.esc_html($keyword['points']).'</td>
<td>'.esc_html($keyword['clicks']).'</td>
<td>'.esc_html($keyword['position']).'</td>
</tr>';
}
if(empty($top_loss_keywords) && !$data['is_sample']){
echo'<tr><td colspan="4" style="text-align:center;">'.esc_html__('No loss keywords data available', 'siteseo').'</td></tr>';
}
echo'</tbody>
</table>
</div>
</div>
</div>';
}
}
static function seo_statistics_tab(){
self::connect_notices();
$data = self::fetch_data();
$metrics = $data['metrics'];
$top_pages = $data['top_pages'];
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Site Search Traffic', 'siteseo').'</h2>
<hr class="siteseo-stats-separator">
<ul class="siteseo-stats-list">
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Search Impressions', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($metrics['impressions']['current']).'</span>
<span class="siteseo-stat-change '.($metrics['impressions']['trend'] == 'negative' ? 'negative' : ($metrics['impressions']['trend'] == 'positive' ? 'positive' : '')).'">
'.($metrics['impressions']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['impressions']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['impressions']['change']).'
</span>
</div>
</li>
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Total Clicks', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($metrics['clicks']['current']).'</span>
<span class="siteseo-stat-change '.($metrics['clicks']['trend'] == 'negative' ? 'negative' : ($metrics['clicks']['trend'] == 'positive' ? 'positive' : '')).'">
'.($metrics['clicks']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['clicks']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['clicks']['change']).'
</span>
</div>
</li>
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Avg. CTR', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($metrics['ctr']['current']).'</span>
<span class="siteseo-stat-change '.($metrics['ctr']['trend'] == 'negative' ? 'negative' : ($metrics['ctr']['trend'] == 'positive' ? 'positive' : '')).'">
'.($metrics['ctr']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-'.($metrics['ctr']['trend'] == 'negative' ? 'down' : 'up').'"></span>' : '').'
'.esc_html($metrics['ctr']['change']).'
</span>
</div>
</li>
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Avg. Position.', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($metrics['position']['current']).'</span>
<span class="siteseo-stat-change '.($metrics['position']['trend'] == 'negative' ? 'negative' : ($metrics['position']['trend'] == 'positive' ? 'positive' : '')) . '">
'.($metrics['position']['trend'] != 'neutral' ? '<span class="dashicons dashicons-arrow-' . ($metrics['position']['trend'] == 'negative' ? 'down' : 'up') . '"></span>' : ''
) . '
'.esc_html($metrics['position']['change']).'
</span>
</div>
</li>
</ul>
<canvas id="seo_statistics" width="950" height="250" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>';
if(!empty($top_pages) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Content Analysis ( Top 5 )', 'siteseo').'</h2>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Page', 'siteseo').'</th>
<th>'.esc_html__('Status', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Avg position', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('Content Score', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($top_pages as $page){
$score = $page['truseo_score'];
if($score >= 80){
$badge_class = 'siteseo-gsc-score-good';
} elseif ($score >= 50){
$badge_class = 'siteseo-gsc-score-avg';
} else{
$badge_class = 'siteseo-gsc-score-bad';
}
echo'<tr>
<td>'.esc_html($page['title']).'</td>
<td>'.(isset($page['indexed']) ? ($page['indexed'] ? '<span class="dashicons dashicons-yes-alt" style="color:#28a745;"></span>' : '<span class="dashicons dashicons-dismiss" style="color:#dc3545;"></span>') : '<span class="dashicons dashicons-editor-help" style="color:#6c757d;"></span>').'</td>
<td>'.esc_html($page['clicks']).'</td>
<td>'.esc_html($page['position']).'</td>
<td>'.esc_html($page['impressions']).'</td>
<td><span class="'.esc_attr($badge_class).'">'.esc_html($page['truseo_score']).'/100</span></td>
</tr>';
}
if(empty($top_pages) && !$data['is_sample']){
echo'<tr><td colspan="6" style="text-align:center;">'.esc_html__('No data available yet', 'siteseo').'</td></tr>';
}
echo'</tbody></table>
</div>';
}
}
static function keyword_ranking_tab(){
self::connect_notices();
$data = self::fetch_data();
$keywords = $data['keywords'];
// Get actual analytics data if available
$analytics_data = get_option('siteseo_search_console_data', []);
$has_actual_data = !empty($analytics_data) && !isset($analytics_data['error']);
// Prepare values based on actual data or sample
if($has_actual_data && !$data['is_sample']){
// Use actual data
$total_keywords = isset($analytics_data['top_keywords']) ? count($analytics_data['top_keywords']) : 0;
$total_impressions = isset($analytics_data['metrics']['impressions']['current']) ? $analytics_data['metrics']['impressions']['current'] : '0';
$avg_ctr = isset($analytics_data['metrics']['ctr']['current']) ? $analytics_data['metrics']['ctr']['current'] : '0%';
$impression_change = isset($analytics_data['metrics']['impressions']['change']) ? $analytics_data['metrics']['impressions']['change'] : '0';
$impression_trend = isset($analytics_data['metrics']['impressions']['trend']) ? $analytics_data['metrics']['impressions']['trend'] : 'neutral';
$ctr_change = '0';
$ctr_trend = 'neutral';
} else{
// Use sample data or zeros
$total_keywords = $data['is_sample'] ? '19K' : '0';
$total_impressions = $data['is_sample'] ? '15M' : '0';
$avg_ctr = $data['is_sample'] ? '48.25%' : '0%';
$impression_change = $data['is_sample'] ? '475.7K' : '0';
$impression_trend = $data['is_sample'] ? 'negative' : 'neutral';
$ctr_change = $data['is_sample'] ? '1' : '0';
$ctr_trend = $data['is_sample'] ? 'negative' : 'neutral';
}
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Keyword Positions', 'siteseo').'</h2>
<hr class="siteseo-stats-separator">
<ul class="siteseo-stats-list">
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Total Keyword', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($total_keywords).'</span>
'.($data['is_sample'] ? '<span class="siteseo-stat-change positive">
<span class="dashicons dashicons-arrow-up"></span>2.9K
</span>' : '').'
</div>
</li>
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Search Impressions', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($total_impressions).'</span>
'.((!$data['is_sample'] && $has_actual_data) ?
'<span class="siteseo-stat-change '.esc_attr($impression_trend).'">
<span class="dashicons dashicons-arrow-'.($impression_trend === 'positive' ? 'up' : 'down').'"></span>'
.esc_html($impression_change).'
</span>' :
($data['is_sample'] ?
'<span class="siteseo-stat-change negative">
<span class="dashicons dashicons-arrow-down"></span>475.7K
</span>' : '')).'
</div>
</li>
<li class="siteseo-stat-item">
<div class="siteseo-stat-header">
<span class="siteseo-stat-label">'.esc_html__('Avg. CTR', 'siteseo').'</span>
</div>
<div class="siteseo-stat-value-group">
<span class="siteseo-stat-value">'.esc_html($avg_ctr).'</span>
'.($data['is_sample'] ?
'<span class="siteseo-stat-change negative">
<span class="dashicons dashicons-arrow-down"></span>1
</span>' : '').'
</div>
</li>
</ul>
<div style="display:flex; gap:20px; flex-wrap:wrap;">
<div style="flex:1; min-width:280px; max-width:50%;">
<canvas id="siteseo_keyword_muti_line_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'" data-actual="'.($has_actual_data ? '1' : '0').'"></canvas>
</div>
<div style="flex:1; min-width:280px; max-width:50%;">
<canvas id="siteseo_keyword_bar_chart" data-sample="'.($data['is_sample'] ? '1' : '0').'" data-actual="'.($has_actual_data ? '1' : '0').'"></canvas>
</div>
</div>
</div>';
if(!empty($keywords) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Content Analysis ( Top 5 )', 'siteseo').'</h2>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Keywords', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Avg. CTR', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
<th>'.esc_html__('Position', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($keywords as $keyword){
echo'<tr>
<td class="siteseo-table-row">'.esc_html($keyword['keyword']).'</td>
<td>'.esc_html($keyword['clicks']).'</td>
<td>'.esc_html($keyword['ctr']).'</td>
<td>'.esc_html($keyword['impressions']).'</td>
<td>'.esc_html($keyword['position']).'</td>
</tr>';
}
if(empty($keywords) && !$data['is_sample']){
echo'<tr><td colspan="6" style="text-align:center;">'.esc_html__('No data available yet', 'siteseo').'</td></tr>';
}
echo'</tbody></table>
</div>';
}
}
static function content_ranking_tab(){
self::connect_notices();
$data = self::fetch_data();
$content_ranking = $data['content_ranking'];
if(!empty($content_ranking) || $data['is_sample']){
// Pagination setup
$items_per_page = 10;
$total_items = count($content_ranking);
$total_pages = ceil($total_items / $items_per_page);
$current_page = isset($_GET['cr_page']) ? max(1, intval($_GET['cr_page'])) : 1;
$offset = ($current_page - 1) * $items_per_page;
$paged_items = array_slice($content_ranking, $offset, $items_per_page);
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Content Analysis (Top 30)', 'siteseo').'</h2>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Title', 'siteseo').'</th>
<th>'.esc_html__('Indexed', 'siteseo').'</th>
<th>'.esc_html__('Last Update on', 'siteseo').'</th>
<th>'.esc_html__('Loss', 'siteseo').'</th>
<th>'.esc_html__('Drop (%)', 'siteseo').'</th>
<th>'.esc_html__('Performance Score', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($paged_items as $content){
$score = (int) explode('/', $content['performance_score'])[0];
if($score >= 80){
$badge_class = 'siteseo-gsc-score-good';
} elseif($score >= 50){
$badge_class = 'siteseo-gsc-score-avg';
} else{
$badge_class = 'siteseo-gsc-score-bad';
}
echo'<tr>
<td>'.esc_html($content['title']).'</td>
<td><span class="dashicons '.($content['indexed'] === 'Yes' ? 'dashicons-yes-alt siteseo-statistics-index-icon' : 'dashicons-dismiss siteseo-statistics-noindex-icon').'"></span></td>
<td>'.esc_html($content['last_update']).'</td>
<td style="color:#dc3545;">'.esc_html($content['loss']).'</td>
<td style="color:#dc3545;">'.esc_html($content['drop_percent']).'</td>
<td><span class="'.esc_attr($badge_class).'">'.esc_html($content['performance_score']).'</span></td>
</tr>';
}
if(empty($content_ranking) && !$data['is_sample']){
echo'<tr><td colspan="6" style="text-align:center;">'.esc_html__('No data available yet', 'siteseo').'</td></tr>';
}
echo'</tbody></table>';
// Pagination controls
if($total_pages > 1){
echo'<div class="siteseo-pagination" style="margin-top: 20px; text-align: center;">';
// Previous btn
if($current_page > 1){
echo'<a href="'.esc_url(add_query_arg('cr_page', $current_page - 1)).'" class="siteseo-option btnSecondary">'.esc_html__('Previous', 'siteseo').'</a> ';
}
// Page numbers
for($i = 1; $i <= $total_pages; $i++){
if($i == $current_page){
echo'<span class="siteseo-option btnSecondary" style="margin: 0 2px;">'.esc_html($i).'</span> ';
} else{
echo'<a href="'.esc_url(add_query_arg('cr_page', $i)).'" class="siteseo-option btnSecondary" style="margin: 0 2px;">'.esc_html($i).'</a> ';
}
}
// Next btn
if($current_page < $total_pages){
echo'<a href="'.esc_url(add_query_arg('cr_page', $current_page + 1)).'" class="siteseo-option btnSecondary">'.esc_html__('Next', 'siteseo').'</a>';
}
echo'</div>';
}
echo'</div>';
}
}
static function audience_tab(){
self::connect_notices();
$data = self::fetch_data();
$country_data = $data['country_data'];
$device_data = $data['device_data'];
echo'<div class="siteseo-audience-statisc">
<div class="siteseo-stats-container">
<h2 class="siteseo-stat-title">'.esc_html__('Device breakdown', 'siteseo').'</h2>
<hr class="siteseo-stats-separator">
<canvas id="siteseo_device_statics" height="250px" width="520px" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Top countries by click ( Top 5 )', 'siteseo').'</h2>
<hr class="siteseo-stats-separator">
<canvas id="siteseo_country_statics" height="300px" width="520px" data-sample="'.($data['is_sample'] ? '1' : '0').'"></canvas>
</div>
</div>';
if(!empty($device_data) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Device Performance', 'siteseo').'</h2>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Device', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($device_data as $data){
echo'<tr>
<td style="font-weight:bold;">'.esc_html( is_array($data['device']) ? implode(', ', $data['device']) : $data['device']).'</td>
<td>'.esc_html($data['clicks']).'</td>
<td>'.esc_html($data['impressions']).'</td>
</tr>';
}
echo'</tbody></table>
</div>';
}
if(!empty($country_data) || $data['is_sample']){
echo'<div class="siteseo-stats-container">
<h2 class="siteseo-stats-title">'.esc_html__('Country Performance ( Top 5 )', 'siteseo').'</h2>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Country', 'siteseo').'</th>
<th>'.esc_html__('Clicks', 'siteseo').'</th>
<th>'.esc_html__('Impressions', 'siteseo').'</th>
</tr>
</thead>
<tbody>';
foreach($country_data as $data){
echo '<tr>
<td style="font-weight:bold;">'.esc_html($data['country']).'</td>
<td>'.esc_html($data['clicks']).'</td>
<td>'.esc_html($data['impressions']).'</td>
</tr>';
}
echo'</tbody></table>
</div>';
}
}
static function connect_notices(){
$analytics_data = '';
$gsc_connected = '';
if(class_exists('\SiteSEOPro\GoogleConsole') && method_exists('\SiteSEOPro\GoogleConsole', 'is_connected')){
$analytics_data = get_option('siteseo_search_console_data', []);
$gsc_connected = \SiteSEOPro\GoogleConsole::is_connected();
}
if(empty($gsc_connected)){
echo'<div class="siteseo-notice is-warning"><p>'.wp_kses_post(__('The data shown here is only a <strong> sample from Google Analytics</strong> how SiteSEO will display your site\'s analytics once connected.', 'siteseo')).'</p>';
if(class_exists('\SiteSEOPro\GoogleConsole')){
echo'<form method="post">';
wp_nonce_field('siteseo_pro_connect_google');
echo '<input type="hidden" name="redirect_type" value="settings">
<button type="submit" name="siteseo_pro_connect_btn" class="siteseo-statistics-connect-btn">'.esc_html__('Connect Search Console', 'siteseo') .'</button>
</form>';
} else{
echo'<a href="https://siteseo.io/pricing" class="siteseo-statistics-connect-btn" target="_blank">'.esc_html__('Buy Pro', 'siteseo').'</a>';
}
echo'</div>';
} elseif(empty($analytics_data['top_pages']) && !empty($gsc_connected)){
echo '<div class="siteseo-notice is-info"><p>'.wp_kses_post(__('Connected to Google Search Console. If this is your first time connecting the site and data doesn’t appear yet, please wait—Google may take a few days to populate the data. You can also try refreshing.', 'siteseo')).'</p></div>';
}
}
static function sample_device_data(){
return [
[
'device' => 'Mobile',
'clicks' => '48k',
'impressions' => '285k',
'ctr' => '5.2%',
],
[
'device' => 'Desktop',
'clicks' => '70k',
'impressions' => '196k',
'ctr' => '3.8%',
],
[
'device' => 'Tablet',
'clicks' => '10k',
'impressions' => '185k',
'ctr' => '8.1%',
],
];
}
static function sample_country_data(){
return [
[
'country' => 'India',
'clicks' => '8K',
'impressions' => '154K',
'ctr' => '5.2%',
],
[
'country' => 'Poland',
'clicks' => '5K',
'impressions' => '132K',
'ctr' => '3.8%',
],
[
'country' => 'South Africa',
'clicks' => '15K',
'impressions' => '185k',
'ctr' => '8.1%',
],
[
'country' => 'Russia',
'clicks' => '19K',
'impressions' => '200k',
'ctr' => '9.5%',
],
[
'country' => 'United kingdom',
'clicks' => '12K',
'impressions' => '150k',
'ctr' => '5.5%',
],
];
}
static function sample_metrics_data(){
return [
'impressions' => [
'current' => '15M',
'change' => '-475.7K',
'trend' => 'negative',
'chart_data' => [12, 19, 3, 5, 2, 3, 10, 8, 12, 14, 13, 15]
],
'clicks' => [
'current' => '111.5K',
'change' => '+1.7K',
'trend' => 'positive',
'chart_data' => [7, 11, 5, 8, 3, 7, 4, 5, 6, 7, 6, 8]
],
'ctr' => [
'current' => '0.74%',
'change' => '+0.03%',
'trend' => 'positive',
'chart_data' => [0.5, 0.6, 0.7, 0.65, 0.75, 0.7, 0.6, 0.7, 0.72, 0.74, 0.73, 0.75]
],
'position' => [
'current' => '49',
'change' => '+1',
'trend' => 'negative',
'chart_data' => [55, 50, 45, 50, 48, 52, 55, 50, 49, 47, 48, 49]
]
];
}
static function sample_top_pages(){
return [
[
'title' => '/blog/',
'truseo_score' => '95',
'indexed' => true,
'clicks' => '4.5K',
'impressions' => '57.2K',
'position' => '23',
'diff' => '+2'
],
[
'title' => '/contact-us/',
'truseo_score' => '88',
'indexed' => false,
'clicks' => '1.2K',
'impressions' => '1.2M',
'position' => '40',
'diff' => '-5'
],
[
'title' => '/support/',
'truseo_score' => '92',
'indexed' => false,
'clicks' => '15K',
'impressions' => '1.9M',
'position' => '16',
'diff' => '+3'
],
[
'title' => '/pricing/',
'truseo_score' => '85',
'indexed' => true,
'clicks' => '8.7K',
'impressions' => '890K',
'position' => '12',
'diff' => '+1'
],
[
'title' => '/features/',
'truseo_score' => '90',
'indexed' => true,
'clicks' => '12.3K',
'impressions' => '1.5M',
'position' => '8',
'diff' => '+4'
]
];
}
static function sample_keywords(){
return [
[
'keyword' => 'One click seo plugin',
'clicks' => '8K',
'ctr' => '5.2%',
'impressions' => '154K',
'position' => '3',
'trend' => 'up',
'points' => '90'
],
[
'keyword' => 'wordpress seo',
'clicks' => '5K',
'ctr' => '3.8%',
'impressions' => '132K',
'position' => '7',
'trend' => 'up',
'points' => '80'
],
[
'keyword' => 'best seo plugin plugin',
'clicks' => '15K',
'ctr' => '8.1%',
'impressions' => '185K',
'position' => '2',
'trend' => 'up',
'points' => '85'
],
[
'keyword' => 'seo optimization',
'clicks' => '3.2K',
'ctr' => '2.1%',
'impressions' => '152K',
'position' => '15',
'trend' => 'down',
'points' => '88'
],
[
'keyword' => 'website ranking',
'clicks' => '6.8K',
'ctr' => '4.5%',
'impressions' => '151K',
'position' => '5',
'trend' => 'up',
'points' => '70'
]
];
}
static function sample_content_ranking(){
return [
[
'title' => 'Ultimate SEO Guide 2024',
'indexed' => 'Yes',
'last_update' => '2024-01-15',
'loss' => '2.1K',
'drop_percent' => '5.2%',
'performance_score' => '88'
],
[
'title' => 'WordPress Optimization Tips',
'indexed' => 'Yes',
'last_update' => '2024-01-10',
'loss' => '1.5K',
'drop_percent' => '3.8%',
'performance_score' => '92'
],
[
'title' => 'Mobile SEO Strategies',
'indexed' => 'No',
'last_update' => '2024-01-08',
'loss' => '3.2K',
'drop_percent' => '8.1%',
'performance_score' => '75'
],
[
'title' => 'Content Marketing Guide',
'indexed' => 'Yes',
'last_update' => '2024-01-12',
'loss' => '0.8K',
'drop_percent' => '2.1%',
'performance_score' => '95'
]
];
}
static function connect_site_dialogbox(){
$gsc_sites = '';
$current_site_url = trailingslashit(get_site_url());
if(class_exists('\SiteSEOPro\GSCSetup') && method_exists('\SiteSEOPro\GSCSetup', 'get_pre_connected_sites')){
$gsc_sites = \SiteSEOPro\GSCSetup::get_pre_connected_sites();
}
$current_site_exists = false;
if(!empty($gsc_sites) && !isset($gsc_sites['error'])){
foreach($gsc_sites as $site){
if($site['siteUrl'] === $current_site_url){
$current_site_exists = true;
break;
}
}
}
echo'<div id="siteseo-site-connection-dialog" title="'.esc_attr__('Connect site search console', 'siteseo').'" style="display:none;">
<div class="siteseo-dialog-content">';
echo'<div id="siteseo-main-section">';
if($current_site_exists){
// Tab: Current Site
echo'<div class="siteseo-option-primary" style="margin-bottom:20px;">
<p style="color:#1d2327;font-weight:400;font-size:14px;">'.esc_html__('This site is already in your Google Search Console account.', 'siteseo').'</p>
<div class="siteseo-form-group">
<input type="text" id="siteseo-site-url" value="' . esc_attr($current_site_url) . '" class="regular-text" readonly
style="width:100%;padding:8px;background:#f6f7f7;border:1px solid #8c8f94;color:#666;cursor:not-allowed;" />
</div>
<div class="siteseo-dialog-actions">
<button type="button" class="button button-primary siteseo-action-btn" id="siteseo-connect-existing">'.esc_html__('Connect', 'siteseo').'</button>
<span class="spinner"></span>
</div>
</div>';
if(!empty($gsc_sites)){
echo '<div class="siteseo-option-secondary">
<button type="button" class="button button-link" id="siteseo-show-existing-properties" style="width:100%;text-decoration:none;">'.esc_html__('Select from existing sites', 'siteseo').'</button>
</div>';
}
} else{
// Not connected yet
echo'<div class="siteseo-option-primary" style="margin-bottom:20px;">
<p style="color:#1d2327;font-weight:400;font-size:14px;">'.esc_html__('This domain isn\'t yet connected to Google Search Console.', 'siteseo').'</p>
<div class="siteseo-form-group">
<input type="text" id="siteseo-new-domain-url" value="' . esc_attr($current_site_url) . '" class="regular-text" readonly
style="width:100%;padding:8px;background:#f6f7f7;border:1px solid #8c8f94;color:#666;cursor:not-allowed;" />
</div>
<button type="button" class="button button-primary siteseo-action-btn siteseo-create-btn" id="siteseo-create-gsc-property" style="margin-bottom:10px;">'.esc_html__('Connect New Domain', 'siteseo').'</button>
<span class="spinner"></span>
</div>';
if(!empty($gsc_sites)){
echo'<div class="siteseo-option-secondary">
<button type="button" class="button button-link" id="siteseo-show-existing-properties" style="width:100%;text-decoration:none;">'.esc_html__('Connect with existing properties', 'siteseo').'</button>
</div>';
}
}
echo'</div>';
if(!empty($gsc_sites) && !isset($gsc_sites['error'])){
echo'<div id="siteseo-existing-properties-section" style="display:none;">
<p style="color:#1d2327;font-weight:400;font-size:14px;">'. esc_html__('Select an existing site from your Google Search Console account.', 'siteseo').'</p>
<div class="siteseo-form-group">
<select id="siteseo-site-url" name="existing_site_url" class="siteseo-select-box">';
foreach($gsc_sites as $site){
echo'<option value="'.esc_attr($site['siteUrl']).'">'.esc_html($site['siteUrl']).'</option>';
}
echo'</select>
</div>
<div class="siteseo-dialog-actions">
<button type="button" class="button button-secondary siteseo-action-btn" id="siteseo-back-to-main">'.esc_html__('Back', 'siteseo').'</button>
<button type="button" class="button button-primary siteseo-action-btn" id="siteseo-connect-existing">'.esc_html__('Connect', 'siteseo').'</button>
<span class="spinner" style="margin-top:7px;"></span>
</div>
</div>';
}
echo'</div></div>'; // End dialog content + wrapper
}
}
settings/titles.php 0000644 00000134211 15152641524 0010430 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Titles{
static function menu(){
global $siteseo;
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_siteseo_home'; // Default tab
$titles_meta_subtabs = [
'tab_siteseo_home' => esc_html__('Home', 'siteseo'),
'tab_siteseo_post_types' => esc_html__('Post types', 'siteseo'),
'tab_siteseo_archives' => esc_html__('Archives', 'siteseo'),
'tab_siteseo_taxonomies' => esc_html__('Taxonomies', 'siteseo'),
'tab_siteseo_advanced' => esc_html__('Advanced','siteseo')
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_title_settings');
$titles_meta_toggle = isset($siteseo->setting_enabled['toggle-titles']) ? $siteseo->setting_enabled['toggle-titles'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
Util::render_toggle('Titles & Metas - SiteSEO', 'titles_meta_toggle', $titles_meta_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($titles_meta_subtabs as $tab_key => $tab_caption) {
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="' . esc_attr($tab_key) . '-tab" class="siteseo-nav-tab' . esc_attr($active_class) . '" data-tab="' . esc_attr($tab_key) . '">' . esc_html($tab_caption) . '</a>';
}
echo '</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab '.($current_tab == 'tab_siteseo_home' ? ' active' : '').'" id="tab_siteseo_home" style="display: none;">';
self::home();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_siteseo_post_types' ? ' active' : '').'" id="tab_siteseo_post_types" style="display: none;">';
self::post_types();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_siteseo_archives' ? ' active' : '').'" id="tab_siteseo_archives" style="display: none;">';
self::archives();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_siteseo_taxonomies' ? ' active' : '').'" id="tab_siteseo_taxonomies" style="display: none;" style="display: none;">';
self::taxonomies();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_siteseo_advanced' ? ' active' : '').'" id="tab_siteseo_advanced">';
self::advanced();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function home(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_titles_option_name');
//$options = $siteseo->titles_settings;
$option_separator = !empty($options['titles_sep']) ? $options['titles_sep'] : '';
$option_site_title = !empty($options['titles_home_site_title']) ? $options['titles_home_site_title'] : '';
$option_site_title_alt = !empty($options['titles_home_site_title_alt']) ? $options['titles_home_site_title_alt'] : '';
$option_site_desc = !empty($options['titles_home_site_desc']) ? $options['titles_home_site_desc'] : '';
if(get_option('show_on_front') === 'page'){
$front_page_id = get_option('page_on_front');
$edit_link = get_edit_post_link($front_page_id, '');
echo'<div class="siteseo_wrap_label">
<div class="siteseo-notice is-warning">
<span id="dashicons-warning" class="dashicons dashicons-info"></span>
<p>'. // translators: %s is the platform name
wp_kses_post(sprintf(__('A static page is set as your site front page <strong>(%s Dashboard > Settings > Reading)</strong>. To add an SEO title, description, and meta tags for the homepage, please click here -', 'siteseo'), !defined('SITEPAD') ? 'WP' : 'Sitepad')) . '</p>
<div>
<a href="'.esc_url($edit_link).'" target="_blank">'.esc_html__('Edit Home Page', 'siteseo').'</a>
</div>
</div>
</div>';
return;
}
echo '<h3 class="siteseo-tabs">'.esc_html__('HOME','siteseo').'</h3>
<div class="siteseo-notice">
<span id="siteseo-dash-icon" class="dashicons dashicons-info"></span>
<p>'.esc_html__('Search engines use the title and meta description to create a snippet of your site for the search results page.', 'siteseo').'</p>
</div>
<p>'.esc_html__('Personalize the title and meta description for your homepage.','siteseo').'</p>
<span class="dashicons dashicons-external"></span>
<a href="'.esc_attr('https://siteseo.io/docs/meta/google-uses-the-wrong-meta-title-meta-description-in-search-results/').'" target="_blank">'.esc_html__('Incorrect meta title or description appearing in search results?', 'siteseo').'</a>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Separator','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[separator]" placeholder="'.esc_attr__('Specify your separator, e.g:-','siteseo').'" value="'.esc_attr($option_separator).'">
<p class="description">'.esc_attr__('Include this separator using %%sep%% in your title and meta description.','siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Site title','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[site_title]" value="'.esc_attr($option_site_title).'" placeholder="'.esc_html__('My fantastic site','siteseo').'">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-site-title" data-tag="%%sitetitle%%"><span id="icon" class="dashicons dashicons-insert"></span>'.
esc_html__('SITE TITLE','siteseo').'</button>
<button class="tag-title-btn" id="btn-separator" data-tag="%%sep%%"><span id="icon" class="dashicons dashicons-insert"></span>'.
esc_html__('SEPARATOR','siteseo').'</button>
<button class="tag-title-btn" id="btn-tagline" data-tag="%%tagline%%"><span id="icon" class="dashicons dashicons-insert"></span>'.
esc_html__('TAGLINE','siteseo').'</button>';
siteseo_suggestion_button();
echo '</div>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Alternative site title','siteseo').'</th>
<td>
<input type="text" value="'.esc_attr($option_site_title_alt).'" name="siteseo_options[alt_site_title]" placeholder="'.esc_html__('Alternative website title','siteseo').'">
<p class="description">'.esc_html__('The alternative name of the website (e.g., a commonly recognized acronym or shorter name, if applicable). Ensure the name meets the criteria.', 'siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Meta description','siteseo').'</th>
<td>
<textarea type="text" name="siteseo_options[media_desc]" placeholder="'.esc_html__('This is an awesome website about galactic creatures.','siteseo').'">'.esc_html($option_site_desc).'</textarea>
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-tagline-meta" data-tag="%%tagline%%"><span id="icon" class="dashicons dashicons-insert"></span>'.
esc_html__('TAGLINE','siteseo').'</button>';
siteseo_suggestion_button();
echo '</div>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[home_tab]" value="1"/>';
}
static function advanced(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->titles_settings;
$options = get_option('siteseo_titles_option_name');
$option_noindex = !empty($options['titles_noindex']) ? $options['titles_noindex'] : '';
$option_nofollow = !empty($options['titles_nofollow']) ? $options['titles_nofollow'] : '';
$option_noimage = !empty($options['titles_noimageindex']) ? $options['titles_noimageindex'] : '';
$option_noarchive = !empty($options['titles_noarchive']) ? $options['titles_noarchive'] : '';
$option_nosnippet = !empty($options['titles_nosnippet']) ? $options['titles_nosnippet'] : '';
$option_nositelinkssearchbox = !empty($options['titles_nositelinkssearchbox']) ? $options['titles_nositelinkssearchbox'] : '';
$option_page_rel = !empty($options['titles_paged_rel']) ? $options['titles_paged_rel'] : '';
$option_paged_noindex = !empty($options['titles_paged_noindex']) ? $options['titles_paged_noindex'] : '';
$option_attachments_noindex = !empty($options['titles_attachments_noindex']) ? $options['titles_attachments_noindex'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Advanced','siteseo').'</h3>
<p>'.esc_html__('Customize your metas for all pages','siteseo').'</p>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('noindex','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[noindex]" type="checkbox" '.(!empty($option_noindex) ? 'checked="yes"' : '') . ' value="1"/>' . esc_html__('noindex', 'siteseo') .
'</label>
<p class="description">'.esc_attr__('Do not show all pages of the site in Google search results and avoid displaying "Cached" links in search results.','siteseo').'</p>
'.wp_kses_post('<p class="description">Check also the<strong>"Search engine visibility"</strong> setting from the <a href="%s">WordPress Reading page</a></p>').'
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('nofollow','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[no_follow]" type="checkbox"'.(!empty($option_nofollow) ? 'checked="yes"' : '') . ' value="1"/>'. esc_html__('nofollow', 'siteseo').
'</label>
<p class="description">'.esc_html__('Do not follow links on all pages.','siteseo').'</p>
</td>
<tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('noimageindex','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[no_image]" type="checkbox"'.(!empty($option_noimage) ? 'checked="yes"' : '').' value="1"/>'. esc_html__('noimageindex', 'siteseo').
'</label>
<p class="description">'.esc_html__('Do not follow links on any pages.','siteseo').'</p>
</td>
<tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('noarchive','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[no_archive]" type="checkbox"'.(!empty($option_noarchive) ? 'checked="yes"' : '').' value="1"/>' . esc_html__('noarchive', 'siteseo').
'</label>
<p class="description">'.esc_html__('Do not show a "Cached" link in Google search results.','siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('nosnippet','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[no_snippet]" type="checkbox"'.(!empty($option_nosnippet) ? 'checked="yes"' : '').' value="1"/>' . esc_html__('nosnippet', 'siteseo').
'</label>
<p class="description">'.esc_html__('Do not show a description in the Google search results for any pages.','siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('nositelinkssearchbox','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[no_site_links_searchbox]" type="checkbox"'.(!empty($option_nositelinkssearchbox) ? 'checked="yes"' : ''). ' value="1"/>' . esc_html__('nositelinkssearchbox', 'siteseo') .
'</label>
<p class="description">'.esc_html__('Prevents Google from displaying a sitelinks search box in search results. Enabling this option will remove the "Website" schema from your source code.','siteseo') .'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Indicate paginated content to Google','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[page_rel]" type="checkbox"' . (!empty($option_page_rel) ? 'checked="yes"' : '') . ' value="1"/>' . esc_html__('Add rel next/prev link in head of paginated archive pages', 'siteseo') .
'</label>
<p class="description">'.esc_html__('eg: https://example.com/category/my-category/page/2/.','siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('noindex on paged archives','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[titles_paged_noindex]" type="checkbox" '. (!empty($option_paged_noindex) ? 'checked="yes"' : '') . ' value="1"/>'.esc_html__('Add a "noindex" meta robots for all paginated archive pages', 'siteseo').
'</label>
<p class="description">'.esc_html__('eg: https://example.com/category/my-category/page/2/.','siteseo').'</p>
</td>
</tr>
<td colspan="2"><span class="dashed-line"></span></td>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('noindex on attachment pages','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[attachments_noindex]" type="checkbox"' . (!empty($option_attachments_noindex) ? 'checked="yes"' : '').' value="1"/>'.esc_html__(' Add a "noindex" meta robots for all attachment pages', 'siteseo') .
'</label>
<p class="description">'.esc_html__('eg: https://example.com/my-media-attachment-page.','siteseo').'</p>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[advanced_tab]" value="1"/>';
}
static function archives(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
// $options = $siteseo->titles_settings;
$options = get_option('siteseo_titles_option_name');
// Load settings
$option_author_title = !empty($options['titles_archives_author_title']) ? $options['titles_archives_author_title'] : '';
$option_author_desc = !empty($options['titles_archives_author_desc']) ? $options['titles_archives_author_desc'] : '';
$option_author_noindex = !empty($options['titles_archives_author_noindex']) ? $options['titles_archives_author_noindex'] : '';
$option_author_disabled = !empty($options['titles_archives_author_disable']) ? $options['titles_archives_author_disable'] : '';
$option_date_title = !empty($options['titles_archives_date_title']) ? $options['titles_archives_date_title'] : '';
$option_date_desc = !empty($options['titles_archives_date_desc']) ? $options['titles_archives_date_desc'] : '';
$option_date_noindex = !empty($options['titles_archives_date_noindex']) ? $options['titles_archives_date_noindex'] : '';
$option_date_disabled = !empty($options['titles_archives_date_disable']) ? $options['titles_archives_date_disable'] : '';
$option_search_title = !empty($options['titles_archives_search_title']) ? $options['titles_archives_search_title'] : '';
$option_search_desc = !empty($options['titles_archives_search_desc']) ? $options['titles_archives_search_desc'] : '';
$option_search_noindex = !empty($options['titles_archives_search_title_noindex']) ? $options['titles_archives_search_title_noindex'] : '';
$option_404_title = !empty($options['titles_archives_404_title']) ? $options['titles_archives_404_title'] : '';
$option_404_desc = !empty($options['titles_archives_404_desc']) ? $options['titles_archives_404_desc'] : '';
$author_base_url = !empty($options['author_base_url']) ? $options['author_base_url'] : 'author';
$archives_fields = [
'author-archives' => 'Author archives',
'date-archives' => 'Date archives',
'search-archives' => 'Search archives',
'404-archives' => '404 archives'
];
$post_types = siteseo_post_types();
echo'<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($archives_fields as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="-' . esc_attr($post_key) . '" class="' . esc_attr($active_class) . '">' . esc_html($post_val) . '</a>';
$is_first = false;
}
foreach($post_types as $post_name => $post_type){
if($post_type->has_archive){
$active_class = $is_first ? 'active' : '';
echo '<a href="-' . esc_attr($post_name) . '" class="' . esc_attr($active_class) . '">' . esc_html($post_type->label) . '</a>';
$is_first = false;
}
}
echo '</div>
</th>
<td>
<div id="author-archives">
<h3>'.esc_html__('Archives', 'siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Personalize your meta descriptions for all archives.','siteseo').'</p>
</div>
<span class="line"></span>
<h3>'.esc_html__('Author archives', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template', 'siteseo').'</p></div>
<input type="text" name="siteseo_options[author_title]" value="'. esc_attr($option_author_title) . '">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-author-acrhive-title" data-tag="%%post_author%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('POST AUTHOR','siteseo').'
</button>
<button class="tag-title-btn" id="btn-author-acrhive-separator" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" id="btn-author-acrhive-sitetitle" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label"><p>Meta description template</p></div>
<textarea name="siteseo_options[author_desc]">'.esc_html($option_author_desc) . '</textarea><br>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options[author_noindex]" type="checkbox" '.(!empty($option_author_noindex) ? 'checked="yes"' : '').' value="1"/>' . wp_kses_post('Do not display author archives in search engine results <strong>(noindex)</strong>') .'
</label>
<label>
<input name="siteseo_options[author_disable]" type="checkbox" '.(!empty($option_author_disabled) ? 'checked="yes"' : '').' value="1"/>
' . esc_html__('Disable author archives', 'siteseo') . '
</label>
</div>
<div class="siteseo_wrap_label"><p style="font-weight: 500;">'.esc_html__('Author base', 'siteseo');
if(!defined('SITESEO_PRO_VERSION')){
echo'<span class="siteseo-pro-tag">Pro</span>';
}
echo'</p></div>
<input type="text" name="siteseo_options[author_base]" value="' . esc_attr($author_base_url) . '" ' .(!defined('SITESEO_PRO_VERSION') ? 'disabled="disabled" style="cursor:not-allowed;"' : '').'>
<div class="siteseo_wrap_label"><p>'.esc_html__('Change the /author/ slug used in author archive URLs.', 'siteseo').'</p>
</div>
<div id="date-archives">
<h3>'.esc_html__('Date archives', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template','siteseo').'</p></div>
<input type="text" name="siteseo_options[date_title]" value="'. esc_attr($option_date_title) .'">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-date-archive" data-tag="%%archive_date%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('DATE ARCHIVES','siteseo').'
</button>
<button class="tag-title-btn" id="btn-date-separator" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" id="btn-date-sitetitle" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label"><p>'.esc_html__('Meta description template','siteseo').'</p></div>
<textarea name="siteseo_options[date_desc]">'.esc_attr($option_date_desc).'</textarea><br>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options[date_noindex]" type="checkbox" '.(!empty($option_date_noindex) ? 'checked="yes"' : '').' value="1"/>' . wp_kses_post('Do not display date archives in search engine results <strong>(noindex)</strong>') . '
</label>
<label>
<input name="siteseo_options[date_disable]" type="checkbox" '.(!empty($option_date_disabled) ? 'checked="yes"' : '').' value="1"/>
' . esc_html__('Disable date archives', 'siteseo') . '
</label>
</div>
<span class="line"><span>
</div>
<div id="search-archives">
<h3>Search archives</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template','siteseo').'</p></div>
<input type="text" name="siteseo_options[search_title]" value="'.esc_attr($option_search_title).'">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-search-keyword" data-tag="%%search_keywords%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEARCH KEYWORDS','siteseo').'
</button>
<button class="tag-title-btn" id="btn-search-separator" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" id="btn-search-sitetitle" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label"><p>'.esc_html__('Meta description template','siteseo').'</p></div>
<textarea name="siteseo_options[search_desc]">'.esc_attr($option_search_desc).'</textarea><br>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options[search_noindex]" type="checkbox" '.(!empty($option_search_noindex) ? 'checked="yes"' : '').' value="1"/>
' . wp_kses_post('Do not display date archives in search engine results <strong>(noindex)</strong>') . '
</label>
</div>
<span class="line"><span>
</div>
<div id="404-archives">
<h3>404 archives</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template','siteseo').'</p></div>
<input type="text" name="siteseo_options[title_404]" value="'.esc_attr($option_404_title).'">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-404-sitetitle" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" id="btn-404-separator" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label"><p>'.esc_html__('Meta description template','siteseo').'</p></div>
<textarea name="siteseo_options[desc_404]">'.esc_attr($option_404_desc).'</textarea><br>
</div>
<br/><br/>
<span class="line"></span>';
foreach($post_types as $post_name => $post_type){
if(empty($post_type->has_archive)){
continue;
}
$post_data = isset($options['titles_archive_titles'][$post_name]) ? $options['titles_archive_titles'][$post_name] : '';
$archive_title = !empty($post_data['archive_title'])? $post_data['archive_title'] : '';
$archive_description = !empty($post_data['archive_desc']) ? $post_data['archive_desc'] : '';
$archive_noindex = !empty($post_data['archive_noindex']) ? $post_data['archive_noindex'] : '';
$archive_nofollow = !empty($post_data['archive_nofollow']) ? $post_data['archive_nofollow'] : '';
$value_check = !empty($options['titles_archive_titles'][$post_name]['archive_title']) ? $options['titles_archive_titles'][$post_name]['archive_title'] : '';
echo'<div id="'.esc_attr($post_name).'">
<h3>'.esc_html($post_type->label).'</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template','siteseo').'</p></div>
<input type="text" name="siteseo_options['.esc_attr($post_name).'][archive_title]" value="'.esc_attr($archive_title).'">
<div class="wrap-tags">
<button class="tag-title-btn" data-tag="%%cpt_plural%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('POST TYPE ARCHIVE NAME','siteseo').'
</button>
<button class="tag-title-btn" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo'</div>
<div class="siteseo_wrap_label"><p>'.esc_html__('Meta description template','siteseo').'</p></div>
<textarea name="siteseo_options['.esc_attr($post_name).'][archive_desc]">'.esc_attr($archive_description).'</textarea><div class="wrap-tags">';
siteseo_suggestion_button();
echo'</div></div><br>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($post_name).'][archive_noindex]" type="checkbox" '.(!empty($archive_noindex) ? 'checked="yes"' : '').' value="1"/>
' . wp_kses_post('Do not display author archives in search engine results <strong>(noindex)</strong>') .'
</label><br/><br/>
<label>
<input name="siteseo_options['.esc_attr($post_name).'][archive_nofollow]" type="checkbox" '.(!empty($archive_nofollow) ? 'checked="yes"' : 'value="1"').' />'.wp_kses_post(__('Do not follow links for this taxonomy archive<strong>(nofollow)</strong>', 'siteseo')).'
</label>
</div><span class="line"><span>';
}
echo'</td>
</tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[archives_tab]" value="1"/>';
}
static function post_types(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_titles_option_name');
$post_types = siteseo_post_types();
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($post_types as $post_type => $post_arr){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($post_type).'-types" class="'.esc_attr($active_class).'">'.esc_html($post_arr->labels->name).'</a>';
$is_first = false;
}
echo '</div>
</th><td>
<div>
<h3>'.esc_html__('Post Types', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><p class="description">'.esc_html__('Personalize your titles and meta descriptions for single custom post types.', 'siteseo').'</p></div>
</div>';
foreach($post_types as $post_type => $post_arr){
// Load array
$post_data = isset($options['titles_single_titles'][$post_type]) ? $options['titles_single_titles'][$post_type] : '';
// Load settings
$option_post_disabled = !empty($post_data['disabled']) ? true : false;
$option_post_title = !empty($post_data['title']) ? $post_data['title'] : '';
$option_post_desc = !empty($post_data['description']) ? $post_data['description'] : '';
$option_noindex = !empty($post_data['noindex']) ? $post_data['noindex'] : '';
$option_nofollow = !empty($post_data['nofollow']) ? $post_data['nofollow'] : '';
$option_date = !empty($post_data['date']) ? $post_data['date'] : '';
$option_thumb_gcs = !empty($post_data['thumb_gcs']) ? $post_data['thumb_gcs'] : '';
echo '<div id="'.esc_attr($post_type).'-types">';
echo '<div class="siteseo-toggle-cnt">
<h3>'.esc_html($post_arr->labels->name.' ['.$post_type.']').'</h3>
<div class="siteseo-toggle-meta '.($option_post_disabled ? '' : 'active').'" id="siteseo-toggle-meta-'.esc_attr($post_type).'"></div>
<span id="siteseo-arrow-icon" class="dashicons dashicons-arrow-left-alt siteseo-arrow-icon"></span>
<p class="toggle_state_posts" id="toggle_state_'.esc_attr($post_type).'">'.(!$option_post_disabled ? ' Click to hide any SEO metaboxes / columns for this post type' : ' Click to show any SEO metaboxes / columns for this post type').'</p>
<input type="hidden" name="siteseo_options['.esc_attr($post_type).'][disabled]" id="enable_'.esc_attr($post_type).'_toggle" value="'.esc_attr($option_post_disabled).'" class="siteseo-suboption-toggle">
</div>
<div class="siteseo_wrap_label"><p>'.esc_html__('Title template', 'siteseo').'</p></div>
<input type="text" name="siteseo_options['.esc_attr($post_type).'][title]" value="'.esc_attr($option_post_title).'">
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-post-title" data-tag="%%post_title%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('POST TITLE', 'siteseo').'
</button>
<button class="tag-title-btn" id="btn-post-separator" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR', 'siteseo').'
</button>
<button class="tag-title-btn" id="btn-post-site-title" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE', 'siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label"><p class="description">'.esc_html__('Meta description template', 'siteseo').'</p></div>
<textarea name="siteseo_options['.esc_attr($post_type).'][desc]">'.esc_attr($option_post_desc).'</textarea>
<div class="wrap-tags">
<button class="tag-title-btn" id="btn-'.esc_attr($post_type).'-meta" data-tag="%%post_excerpt%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('POST EXCERPT', 'siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($post_type).'][noindex]" type="checkbox" '.(!empty($option_noindex) ? 'checked="yes"' : 'value="1"').' />
'.wp_kses_post(__('Do not display this single post type in search engine results <strong>(noindex)</strong>', 'siteseo')).'
</label>
</div>';
if(!empty($option_noindex)){
echo '<div class="siteseo_wrap_label">
<div class="siteseo-notice is-error">
<p>'.wp_kses_post(__('This custom post type is <strong>NOT</strong> excluded from your XML sitemaps despite the fact that it is set to <strong>NOINDEX</strong>.', 'siteseo')).'
</p>
</div>
</div>';
}
echo '<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($post_type).'][nofollow]" type="checkbox" '.(!empty($option_nofollow) ? 'checked="yes"' : 'value="1"').' />
'.wp_kses_post(__('Do not follow links for this single post type <strong>nofollow</strong>', 'siteseo')).'
</label>
</div>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($post_type).'][date]" type="checkbox" '.(!empty($option_date) ? 'checked="yes"' : 'value="1"').' />
'.esc_html__('Display date in Google search results by adding article:published_time and article:modified_time meta?', 'siteseo').'
</label>
<p class="description">'. esc_html__('Unchecking this does not prevent Google from displaying the post date in search results.', 'siteseo').'</p>
</div>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($post_type).'][thumb_gcs]" type="checkbox" '.(!empty($option_thumb_gcs) ? 'checked="yes"' : 'value="1"').' />
'.esc_html__('Display post thumbnail in Google Custom Search results?', 'siteseo').'
</label>
<p class="description">'.esc_html__('This option does not apply to traditional search results.', 'siteseo').'</p>
</div>
</div>';
}
echo '</td></tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[post_types_tab]" value="1"/>';
}
static function taxonomies(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
// $options = $siteseo->titles_setting;
$options = get_option('siteseo_titles_option_name');
$taxonomies = get_taxonomies(['show_ui' => true, 'public' => true], 'objects', 'and');
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($taxonomies as $fields_key => $fields_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($fields_key).'-types" class="'.esc_attr($active_class).'">'.esc_html($fields_val->label).'</a>';
$is_first = false;
}
echo '</th>
<td>
<h3>'.esc_html__('Taxonomies','siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Personalize your meta descriptions for all taxonomy archives.','siteseo').'</p>
</div>';
foreach($taxonomies as $taxonomy => $_tax){
// Load array
$options_tax = isset($options['titles_tax_titles'][$taxonomy]) ? $options['titles_tax_titles'][$taxonomy] : '';
// Load settings
$option_disabled_category = !empty($options_tax['disabled']) ? $options_tax['disabled'] : '';
$option_cat_title = !empty($options_tax['title']) ? $options_tax['title'] : '';
$option_cat_desc = !empty($options_tax['description']) ? $options_tax['description'] : '';
$option_cat_noindex = !empty($options_tax['noindex']) ? $options_tax['noindex'] : '';
$option_cat_nofollow = !empty($options_tax['nofollow']) ? $options_tax['nofollow'] : '';
$taxonomies_fields = [
'categories-types' => 'Categories',
'tags-types' => 'Tags',
];
echo '<div id="'.esc_attr($taxonomy).'-types"><h3>'.esc_html($_tax->label.'['.$taxonomy.']').'</h3>
<div class="siteseo-toggle-cnt">
<div class="siteseo-toggle-meta '.($option_disabled_category ? '' : 'active').'" id="siteseo-toggle-meta-category"></div>
<span id="siteseo-arrow-icon" class="dashicons dashicons-arrow-left-alt siteseo-arrow-icon"></span>
<p class="toggle_state_category" id="toggle_state_category">' .($option_disabled_category ? 'Enable' : 'Disable'). '</p>
<input type="hidden" name="siteseo_options['.esc_attr($taxonomy).'][disabled]" id="enable_'.esc_attr($taxonomy).'" value="'.esc_attr($option_disabled_category).'" class="siteseo-suboption-toggle">
</div>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Title template','siteseo').'</p>
</div>
<input type="text" value="'.esc_attr($option_cat_title).'" name="siteseo_options['.esc_attr($taxonomy).'][title]">
<div class="wrap-tags">
<button class="tag-title-btn" data-tag="%%_category_title%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('CATEGORY TITLE','siteseo').'
</button>
<button class="tag-title-btn" data-tag="%%sep%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SEPARATOR','siteseo').'
</button>
<button class="tag-title-btn" data-tag="%%sitetitle%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('SITE TITLE','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label">
<p class="description">Meta description template</p>
</div>
<textarea name="siteseo_options['.esc_attr($taxonomy).'][desc]">'.esc_attr($option_cat_desc).'</textarea>
<div class="wrap-tags">
<button class="tag-title-btn" data-tag="%%_category_description%%">
<span id="icon" class="dashicons dashicons-insert"></span>'.esc_html__('CATEGORY DESCRIPTION','siteseo').'
</button>';
siteseo_suggestion_button();
echo '</div>
<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($taxonomy).'][noindex]" type="checkbox" '.(!empty($option_cat_noindex) ? 'checked="yes"' : 'value="1"').' />
'.wp_kses_post(__('Do not display this taxonomy archive in search engine results<strong>(noindex)</strong>', 'siteseo')).'
</label>
</div>';
if(!empty($option_cat_noindex)){
echo '<div class="siteseo_wrap_label">
<div class="siteseo-notice is-error">
<p>'.wp_kses_post(__('This custom taxonomy is <strong>NOT</strong> excluded from your XML sitemaps despite the fact that it is set to <strong>NOINDEX</strong>. We recommend that you check this out.', 'siteseo')).'
</p>
</div>
</div>';
}
echo '<div class="siteseo_wrap_label">
<label>
<input name="siteseo_options['.esc_attr($taxonomy).'][nofollow]" type="checkbox" '.(!empty($option_cat_nofollow) ? 'checked="yes"' : 'value="1"').' />
'.wp_kses_post(__('Do not follow links for this taxonomy archive<strong>(nofollow)</strong>', 'siteseo')).'
</label>
</div>
</div>';
}
echo '</td>
</tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[taxonomies_tab]" value="1"/>';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_title_settings');
if(!siteseo_user_can('manage_title') || !is_admin()){
return;
}
$options = [];
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['home_tab'])){
$options['titles_sep'] = isset($_POST['siteseo_options']['separator']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['separator'])) : '';
$options['titles_home_site_title'] = isset($_POST['siteseo_options']['site_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['site_title'])) : '';
$options['titles_home_site_title_alt'] = isset($_POST['siteseo_options']['alt_site_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['alt_site_title'])) : '';
$options['titles_home_site_desc'] = isset($_POST['siteseo_options']['media_desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['media_desc'])) : '';
}
if(isset($_POST['siteseo_options']['advanced_tab'])){
$options['titles_noindex'] = isset($_POST['siteseo_options']['noindex']);
$options['titles_nofollow'] = isset($_POST['siteseo_options']['no_follow']);
$options['titles_noimageindex'] = isset($_POST['siteseo_options']['no_image']);
$options['titles_noarchive'] = isset($_POST['siteseo_options']['no_archive']);
$options['titles_nosnippet'] = isset($_POST['siteseo_options']['no_snippet']);
$options['titles_nositelinkssearchbox'] = isset($_POST['siteseo_options']['no_site_links_searchbox']);
$options['titles_paged_rel'] = isset($_POST['siteseo_options']['page_rel']);
$options['titles_paged_noindex'] = isset($_POST['siteseo_options']['titles_paged_noindex']);
$options['titles_attachments_noindex'] = isset($_POST['siteseo_options']['attachments_noindex']);
}
if(isset($_POST['siteseo_options']['post_types_tab'])){
$post_types = siteseo_post_types();
$post_types = array_keys($post_types);
// Saving Posts
foreach($post_types as $post_type){
$options['titles_single_titles'][$post_type]['disabled'] = !empty($_POST['siteseo_options'][$post_type]['disabled']) ? true : false;
$options['titles_single_titles'][$post_type]['title'] = isset($_POST['siteseo_options'][$post_type]['title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$post_type]['title'])) : '';
$options['titles_single_titles'][$post_type]['description'] = isset($_POST['siteseo_options'][$post_type]['desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$post_type]['desc'])) : '';
$options['titles_single_titles'][$post_type]['noindex'] = isset($_POST['siteseo_options'][$post_type]['noindex']);
$options['titles_single_titles'][$post_type]['nofollow'] = isset($_POST['siteseo_options'][$post_type]['nofollow']);
$options['titles_single_titles'][$post_type]['date'] = isset($_POST['siteseo_options'][$post_type]['date']);
$options['titles_single_titles'][$post_type]['thumb_gcs'] = isset($_POST['siteseo_options'][$post_type]['thumb_gcs']);
}
}
if(isset($_POST['siteseo_options']['archives_tab'])){
$post_types = siteseo_post_types();
$post_types = array_keys($post_types);
$options['titles_archives_author_title'] = isset($_POST['siteseo_options']['author_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['author_title'])) : '';
$options['titles_archives_author_desc'] = isset($_POST['siteseo_options']['author_desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['author_desc'])) : '';
$options['titles_archives_author_noindex'] = isset($_POST['siteseo_options']['author_noindex']);
$options['titles_archives_author_disable'] = isset($_POST['siteseo_options']['author_disable']);
$options['titles_archives_date_title'] = isset($_POST['siteseo_options']['date_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['date_title'])) : '';
$options['titles_archives_date_desc'] = isset($_POST['siteseo_options']['date_desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['date_desc'])) : '';
$options['titles_archives_date_noindex'] = isset($_POST['siteseo_options']['date_noindex']);
$options['titles_archives_date_disable'] = isset($_POST['siteseo_options']['date_disable']);
$options['titles_archives_search_title'] = isset($_POST['siteseo_options']['search_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['search_title'])) : '';
$options['titles_archives_search_desc'] = isset($_POST['siteseo_options']['search_desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['search_desc'])) : '';
$options['titles_archives_search_title_noindex'] = isset($_POST['siteseo_options']['search_noindex']);
$options['titles_archives_404_title'] = isset($_POST['siteseo_options']['title_404']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['title_404'])) : '';
$options['titles_archives_404_desc'] = isset($_POST['siteseo_options']['desc_404']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['desc_404'])) : '';
foreach($post_types as $post_type){
$options['titles_archive_titles'][$post_type]['archive_title'] = isset($_POST['siteseo_options'][$post_type]['archive_title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$post_type]['archive_title'])) : '';
$options['titles_archive_titles'][$post_type]['archive_desc'] = isset($_POST['siteseo_options'][$post_type]['archive_desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$post_type]['archive_desc'])) : '';
$options['titles_archive_titles'][$post_type]['archive_noindex'] = isset($_POST['siteseo_options'][$post_type]['archive_noindex']);
$options['titles_archive_titles'][$post_type]['archive_nofollow'] = isset($_POST['siteseo_options'][$post_type]['archive_nofollow']);
}
}
if(isset($_POST['siteseo_options']['taxonomies_tab'])){
$taxonomies = get_taxonomies(['show_ui' => true, 'public' => true], 'objects', 'and');
$taxonomies = array_keys($taxonomies);
foreach($taxonomies as $taxonomy){
$options['titles_tax_titles'][$taxonomy]['disabled'] = !empty($_POST['siteseo_options'][$taxonomy]['disabled']) ? true : false;
$options['titles_tax_titles'][$taxonomy]['title'] = isset($_POST['siteseo_options'][$taxonomy]['title']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$taxonomy]['title'])) : '';
$options['titles_tax_titles'][$taxonomy]['description'] = isset($_POST['siteseo_options'][$taxonomy]['desc']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options'][$taxonomy]['desc'])) : '';
$options['titles_tax_titles'][$taxonomy]['noindex'] = isset($_POST['siteseo_options'][$taxonomy]['noindex']);
$options['titles_tax_titles'][$taxonomy]['nofollow'] = isset($_POST['siteseo_options'][$taxonomy]['nofollow']);
}
}
$options = apply_filters('siteseo_titles_save_settings', $options);
update_option('siteseo_titles_option_name', $options);
}
}
settings/analytics.php 0000644 00000166213 15152641524 0011122 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Analytics{
static function menu(){
global $siteseo;
$analytics_toggle = isset($siteseo->setting_enabled['toggle-google-analytics']) ? $siteseo->setting_enabled['toggle-google-analytics'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_google_analytics';
$analytics_sub_tags = [
'tab_google_analytics' => esc_html__('Google Analytics', 'siteseo'),
'tab_matomo' => esc_html__('Matomo', 'siteseo'),
'tab_clarity' => esc_html__('Clarity', 'siteseo'),
'tab_advanced' => esc_html__('Advanced', 'siteseo'),
'tab_cookie' => esc_html__('Cookie bar / GDPR', 'siteseo'),
'tab_custom_tracking' => esc_html__('Custom Tracking', 'siteseo'),
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_analytics_settings');
Util::render_toggle('Analytics - SiteSEO', 'analytics_toggle', $analytics_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($analytics_sub_tags as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="'.esc_attr($tab_key).'-tab" class="siteseo-nav-tab'.esc_attr($active_class).'" data-tab="'.esc_attr($tab_key).'">'.esc_html($tab_caption).'</a>';
}
echo '</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab'.($current_tab == 'tab_google_analytics' ? ' active' : '').'" id="tab_google_analytics" style="display: none;">';
self::google_anlytics();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_matomo' ? ' active' : '') . '" id="tab_matomo" style="display: none;">';
self::matomo();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_clarity' ? ' active' : '').'" id="tab_clarity" style="display: none;">';
self::clarity();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_advanced' ? ' active' : '').'" id="tab_advanced" style="display: none;">';
self::advanced();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_cookie' ? ' active' : '').'" id="tab_cookie" style="display: none;">';
self::cookies();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_custom_tracking' ? 'active' : '').'" id="tab_custom_tracking" style="display: none;">';
self::custom_tracking();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function custom_tracking(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->analaytics_settings;
$options = get_option('siteseo_google_analytics_option_name');
$option_head_tracking = !empty($options['google_analytics_other_tracking']) ? $options['google_analytics_other_tracking'] : '';
$option_body_tracking = !empty($options['google_analytics_other_tracking_body']) ? $options['google_analytics_other_tracking_body'] : '';
$option_footer_tracking = !empty($options['google_analytics_other_tracking_footer']) ? $options['google_analytics_other_tracking_footer'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Custom Tracking','siteseo').'</h3>
<P class="description">'.esc_html__('Add custom scripts like GTM or Facebook Pixel by copying and pasting the provided code into the HEAD, BODY, or FOOTER sections.','siteseo').'</p>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('[HEAD] Add an additional tracking code (like Facebook Pixel, Hotjar...)','siteseo').'</th>
<td>
<textarea name="siteseo_options[head_tracking]" rows="16" placeholder="'.esc_html__('Paste your tracking code here, such as Google Tag Manager (head). Do NOT paste GA4 or Universal Analytics codes, as they are automatically included in your source code.','siteseo').'">'.esc_html($option_head_tracking).'</textarea>
<p class="description">'.esc_html__('This code will be added in the head section of your page','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('[BODY] Add an additional tracking code (like Google Tag Manager...)','siteseo').'</th>
<td>
<textarea name="siteseo_options[body_tracking]" rows="16" placeholder="'.esc_html__('This code will be added just after the opening body tag of your page','siteseo').'">'.esc_html($option_body_tracking).'</textarea>
<p>'.esc_html__('This code will be added just after the opening body tag of your page','siteseo').'</p>
<p>'.esc_html__('You don‘t see your code? Make sure to call wp_body_open(); just after the opening body tag in your theme.','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('[BODY (FOOTER)] Add an additional tracking code (like Google Tag Manager...)', 'siteseo').'</th>
<td>
<textarea name="siteseo_options[footer_tracking]" rows="16" placeholder="'.esc_html__('Paste your tracking code here(footer)','siteseo').'">'.esc_html($option_footer_tracking).'</textarea>
<p>'.esc_html__('This code will be added just after the closing body tag of your page','siteseo').'</P>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[custom_tracking_tab]" value="1"/>';
}
static function cookies(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->analaytics_settings;
$options = get_option('siteseo_google_analytics_option_name');
$option_cookies_postion = !empty($options['google_analytics_hook']) ? $options['google_analytics_hook'] : '';
$option_tracking_opt = !empty($options['google_analytics_disable']) ? $options['google_analytics_disable'] : '';
$option_half_disable = !empty($options['google_analytics_half_disable']) ? $options['google_analytics_half_disable'] : '';
$option_opt_choices = !empty($options['google_analytics_opt_out_edit_choice']) ? $options['google_analytics_opt_out_edit_choice'] : '';
$option_opt_msg = !empty($options['google_analytics_opt_out_msg']) ? $options['google_analytics_opt_out_msg'] : '';
$option_opt_msg_ok = !empty($options['google_analytics_opt_out_msg_ok']) ? $options['google_analytics_opt_out_msg_ok'] : '';
$option_opt_msg_close = !empty($options['google_analytics_opt_out_msg_close']) ? $options['google_analytics_opt_out_msg_close'] : '';
$option_opt_msg_edit = !empty($options['google_analytics_opt_out_msg_edit']) ? $options['google_analytics_opt_out_msg_edit'] : '';
$option_cd_exp_date = !empty($options['google_analytics_cb_exp_date']) ? $options['google_analytics_cb_exp_date'] : '30';
$option_cd_pos = !empty($options['google_analytics_cb_pos']) ? $options['google_analytics_cb_pos'] : '';
$option_cd_txt_align = !empty($options['google_analytics_cb_txt_align']) ? $options['google_analytics_cb_txt_align'] : '';
$option_cd_width = !empty($options['google_analytics_cb_width']) ? $options['google_analytics_cb_width'] : '';
$option_cd_backdrop = !empty($options['google_analytics_cb_backdrop']) ? $options['google_analytics_cb_backdrop'] : '';
$option_cd_scheme = !empty($options['google_analytics_cb_scheme']) ? $options['google_analytics_cb_scheme'] : '';
//colors load
$option_backdrop_bg = !empty($options['google_analytics_cb_backdrop_bg']) ? $options['google_analytics_cb_backdrop_bg'] : '';
$option_cookiebar_bg = !empty($options['google_analytics_cb_bg']) ? $options['google_analytics_cb_bg'] : '#ffffff';
$option_cookiebar_txt = !empty($options['google_analytics_cb_txt_col']) ? $options['google_analytics_cb_txt_col'] : '#000000';
$option_cookiebar_lk = !empty($options['google_analytics_cb_lk_col']) ? $options['google_analytics_cb_lk_col'] : '#0000ff';
$option_primarybtn_bg = !empty($options['google_analytics_cb_btn_bg']) ? $options['google_analytics_cb_btn_bg'] : '#0073aa';
$option_primarybtn_bg_hov = !empty($options['google_analytics_cb_btn_bg_hov']) ? $options['google_analytics_cb_btn_bg_hov'] : '#005f8b';
$option_primarybtn_txt = !empty($options['google_analytics_cb_btn_col']) ? $options['google_analytics_cb_btn_col'] : '#ffffff';
$option_primarybtn_txt_hov = !empty($options['google_analytics_cb_btn_col_hov']) ? $options['google_analytics_cb_btn_col_hov'] : '#ffffff';
$option_sec_bg = !empty($options['google_analytics_cb_btn_sec_bg']) ? $options['google_analytics_cb_btn_sec_bg'] : '#cccccc';
$option_sec_bg_hov = !empty($options['google_analytics_cb_btn_sec_bg_hov']) ? $options['google_analytics_cb_btn_sec_bg_hov'] : '#aaaaaa';
$option_sec_bg_txt = !empty($options['google_analytics_cb_btn_sec_col']) ? $options['google_analytics_cb_btn_sec_col'] : '#000000';
$option_sec_bg_txt_hov = !empty($options['google_analytics_cb_btn_sec_col_hov']) ? $options['google_analytics_cb_btn_sec_col_hov'] : '#000000';
echo '<h3 class="siteseo-tabs">'.esc_html__('Cookies','siteseo').'</h3>
<p class="description">'.esc_html__('Easily manage user consent for GDPR and customize your cookie bar.','siteseo').'</p>
<p class="description">'.esc_html__('Compatible with Google Analytics and Matomo.','siteseo').'</p>
<table>
<tbody class="form-table">
<tr>
<div class="siteseo-notice" id="custom-dimensions">
<span class="dashicons dashicons-info"></span>
<p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('%1$s Note : %2$s This feature applies only to cookies added through SiteSEO analytics and tracking.', 'siteseo'), '<strong>', '</strong>')).'</p>
</div>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Where to load the cookie bar?','siteseo').'</th>
<td>
<select name="siteseo_options[cookie_pos]">
<option value="wp_body_open" '.selected($option_cookies_postion, 'wp_body_open', false).'>'.esc_html__('After the opening body tag (recommended)', 'siteseo').'</option>
<option value="wp_footer" '.selected($option_cookies_postion, 'wp_footer', false).'>'.esc_html__('Footer', 'siteseo') .'</option>
<option value="wp_head" '.selected($option_cookies_postion, 'wp_head', false).'>'.esc_html__('Header (not recommended)', 'siteseo').'</option>
</select>
</td>
</tr>
<tr>
<th scope"user-select:auto">'.esc_html__('Analytics tracking opt-in','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[opt_tracking]" type="checkbox" '.(!empty($option_tracking_opt) ? 'checked="yes"' : 'value="1"').' />
'.esc_html__('Obtain user consent for analytics tracking, as required by GDPR.', 'siteseo').'
</label><br/><br/>
<label>
<input type="checkbox" name="siteseo_options[half_disable]" '.(!empty($option_half_disable) ? 'checked="yes"' : 'value="1"').' />
'.esc_html__('Display and automatically accept if user does not accept or reject within 10 seconds.','siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto:">'.esc_html__('Allow user to change its choice','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[opt_edit_choices]" type="checkbox" '.(!empty($option_opt_choices) ? 'checked="yes"' : 'value="1"').' />
Allow user to change its choice about cookies'.esc_html__('Request user consent for analytics tracking (required by GDPR)', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Consent message for user tracking','siteseo').'</th>
<td>
<textarea placeholder="'.esc_html__('Enter your message (HTML allowed)','siteseo').'" name="siteseo_options[opt_msg]" >'.esc_attr($option_opt_msg).'</textarea>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Accept button for user tracking','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[opt_msg_ok]" value="'.esc_attr($option_opt_msg_ok).'" placeholder="'.esc_html__('Accept','siteseo').'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Close button','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[opt_close]" value="'.esc_attr($option_opt_msg_close).'" placeholder="'.esc_attr__('default:X', 'siteseo').'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;" >'.esc_html__('Edit cookies button','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[opt_edit_btn]" value="'.esc_attr($option_opt_msg_edit).'" placeholder="'.esc_attr__('default:Manage cookie', 'siteseo').'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('User consent cookie expiration date','siteseo').'</th>
<td>
<input type="number" name="siteseo_options[cd_exp_date]" value="'.esc_attr($option_cd_exp_date).'" >
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Cookie bar position','siteseo').'</th>
<td>
<select name="siteseo_options[cd_pos]">
<option value="bottom" '.selected($option_cd_pos, 'bottom', false).'>'.esc_html__('Bottom (default)','siteseo').'</option>
<option value="middle" '.selected($option_cd_pos, 'middle', false).'>'.esc_html__('Middle','siteseo').'</option>
<option value="top" '.selected($option_cd_pos, 'top', false).'>'.esc_html__('Top','siteseo').'</option>
</select>
</td>
</tr>
<tr>
<th scope="row" style="use-select:auto;">'.esc_html__('Text alignment','siteseo').'</th>
<td>
<select name="siteseo_options[cd_txt_align]">
<option value="center" '.selected($option_cd_txt_align, 'center', false).'>'.esc_html__('Center (default)', 'siteseo').'</option>
<option value="left" '.selected($option_cd_txt_align, 'left', false).'>'.esc_html__('Left', 'siteseo').'</option>
<option value="right" '.selected($option_cd_txt_align, 'right', false).'>'.esc_html__('Right', 'siteseo').'</option>
</select>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Cookie bar width', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[cd_width]" value="'.esc_attr($option_cd_width).'"/>
<p class="description">'.esc_html__('The default unit is Pixels. To use percentages, simply add % after your custom value (e.g., 80%).', 'siteseo').'</p>
<br/>
<span class="line"></span>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;"></th>
<td>
<h3>'.esc_html__('Backdrop', 'siteseo').'</h3>
<p>'.esc_html__('Customize the backdrop of the cookie bar.', 'siteseo').'</p><br/>
<label>
<input type="checkbox" name="siteseo_options[cd_backdrop]" '.(!empty($option_cd_backdrop) ? 'checked="yes"' : 'value="1"').'>'. esc_html__('Display a backdrop with the cookie bar', 'siteseo') .'
</label>
<br/><br/>
<p>'.esc_html__('Background color:','siteseo').'</p><br/>
<input type="color" placeholder="Select color" name="siteseo_options[backdrop_bg]" value="'.esc_attr($option_backdrop_bg).'"/>
<br/></br/>
<span class="line"></span>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;"></th>
<td>
<h3>'.esc_html__('Main settings', 'siteseo').'</h3>
<p>'.esc_html__('Customize the general settings of the cookie bar', 'siteseo').'</p>
<p>'.esc_html__('Background color:', 'siteseo').'</p><br/>
<input type="color" placeholder="'.esc_html__('Select color', 'siteseo').'" name="siteseo_options[cookiesbar_bg]" value="'.esc_attr($option_cookiebar_bg).'"/>
<p>'.esc_html__('Text color:', 'siteseo').'</p><br/>
<input type="color" placeholder="'.esc_html__('Select color', 'siteseo').'" name="siteseo_options[cookiebar_txt]" value="'.esc_attr($option_cookiebar_txt).'"/>
<p>'.esc_html__('Link color: ','siteseo').'</p></br>
<input type="color" placeholder="'.esc_html__('Select color', 'siteseo').'" name="siteseo_options[line_co]" value="'.esc_attr($option_cookiebar_lk).'"/><br/></br>
<span class="line"></span>
</td>
</tr>
<tr>
<th scope="row" style="use-select:auto"></th>
<td>
<h3>'.esc_html__('Primary button', 'siteseo').'</h3>
<p>'.esc_html__('Customize the Accept button', 'siteseo').'</p><br/>
<p>'.esc_html__('Background color:', 'siteseo').'</p>
<input type="color" placeholder="'.esc_html__('Select color', 'siteseo').'" name="siteseo_options[primary_btn_bg]" value="'.esc_attr($option_primarybtn_bg).'"/><br/><br/>
<p>'.esc_html__('Background color on hover:','siteseo').'</p>
<input type="color" name="siteseo_options[primary_btn_bg_hov]" value="'.esc_attr($option_primarybtn_bg_hov).'" /><br/><br/>
<p>'.esc_html__('Text color:', 'siteseo').'</p>
<input type="color" name="siteseo_options[primary_btn_txt]" value="'.esc_attr($option_primarybtn_txt).'"/>
<p>'. esc_html__('Text color on hover:', 'siteseo') .'</p>
<input type="color" name="siteseo_options[primary_btn_txt_hov]" value="'.esc_attr($option_primarybtn_txt_hov).'"/><br/><br/>
<span class="line"></span>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto"></th>
<td>
<h3>'.esc_html__('Secondary button', 'siteseo').'</h3>
<p>'.esc_html__('Customize the Accept button', 'siteseo').'</p><br/>
<p>'.esc_html__('Background color:', 'siteseo').'</p>
<input type="color" placeholder="'.esc_html__('Select color','siteseo').'" name="siteseo_options[sec_btn_bg]" value="'.esc_attr($option_sec_bg).'"/><br/><br/>
<p>'.esc_html__('Background color on hover:', 'siteseo').'</p>
<input type="color" name="siteseo_options[sec_btn_bg_hov]" value="'.esc_attr($option_sec_bg_hov).'"/><br/><br/>
<p>'.esc_html__('Text color:', 'siteseo').'</p>
<input type="color" name="siteseo_options[sec_btn_txt]" value="'.esc_attr($option_sec_bg_txt).'"/>
<p>'.esc_html__('Text color on hover:', 'siteseo').'</p>
<input type="color" name="siteseo_options[sec_btn_txt_hov]" value="'.esc_attr($option_sec_bg_txt_hov).'"/>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[cookies_tab]" value="1"/>';
}
static function matomo(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->analaytics_settings;
$options = get_option('siteseo_google_analytics_option_name');
$option_enable_matomo = !empty($options['google_analytics_matomo_enable']) ? $options['google_analytics_matomo_enable'] : '';
$option_self_hosted = !empty($options['google_analytics_matomo_self_hosted']) ? $options['google_analytics_matomo_self_hosted'] : '';
$option_matomo_id = !empty($options['google_analytics_matomo_id']) ? $options['google_analytics_matomo_id'] : '';
$option_site_id = !empty($options['google_analytics_matomo_site_id']) ? $options['google_analytics_matomo_site_id'] : '';
$option_sub_domain = !empty($options['google_analytics_matomo_subdomains']) ? $options['google_analytics_matomo_subdomains'] : '';
$option_site_domain = !empty($options['google_analytics_matomo_site_domain']) ? $options['google_analytics_matomo_site_domain'] : '';
$option_enable_corss_domain = !empty($options['google_analytics_matomo_cross_domain']) ? $options['google_analytics_matomo_cross_domain'] : '';
$option_no_js = !empty($options['google_analytics_matomo_no_js']) ? $options['google_analytics_matomo_no_js'] : '';
$option_cross_domain_sites = !empty($options['google_analytics_matomo_cross_domain_sites']) ? $options['google_analytics_matomo_cross_domain_sites'] : '';
$option_no_cookies = !empty($options['google_analytics_matomo_no_cookies']) ? $options['google_analytics_matomo_no_cookies'] : '';
$options_link_tracking = !empty($options['google_analytics_matomo_link_tracking']) ? $options['google_analytics_matomo_link_tracking'] : '';
$options_no_heatmaps = !empty($options['google_analytics_matomo_no_heatmaps']) ? $options['google_analytics_matomo_no_heatmaps'] : '';
$options_matomo_dtn = !empty($options['google_analytics_matomo_dnt']) ? $options['google_analytics_matomo_dnt'] : '';
$matomo_subtabs = [
'tracking' => 'Tracking',
];
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($matomo_subtabs as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($post_key).'" class="'.esc_attr($active_class).'">'.esc_html($post_val).'</a>';
$is_first = false;
}
echo '</div>
</th>
<td>
<h3>'.esc_html__('Matomo', 'siteseo').'</h3>
<div class="siteseo_wrap_label" id="tracking">
<p class="description">'.esc_html__('Track your users with privacy in mind using Matomo. We support both On-Premise and Cloud installations.', 'siteseo').'</p>
</div>
<span class="line"></span>
<h3>'.esc_html__('Tracking', 'siteseo').'</h3>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Enable Matomo tracking.', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[enable_matomo]" '.(!empty($option_enable_matomo) ? 'checked="yes"' : '').' value="1"/>
'.esc_html__('Enable Matomo tracking', 'siteseo') .'
</label>
<p class="description">'.esc_html__('A Matomo Cloud account or a self-hosted Matomo installation is necessary.', 'siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Self hosted Matomo installation.', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[self_hosted]" '.(!empty($option_self_hosted) ? 'checked="yes"' : '').' value="1" "/>
'.esc_html__('Yes, self-hosted installation', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enter your tracking ID', 'siteseo').'</th>
<td>
<input type="text" placeholder="'.esc_html__('Enter "example" if you Matomo account URL is "example.matomo.cloud', 'siteseo').'" name="siteseo_options[tracking_id]" value="'.esc_attr($option_matomo_id).'"/>
'.wp_kses_post('<p class="description">Enter only the host without quotes, such as "example.matomo.cloud" </br> (Cloud) or "matomo.example.com" (self-hosted).</p>').'
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enter your site ID.', 'siteseo').'</th>
<td>
<input type="text" placeholder="'.esc_html__('Enter your site ID', 'siteseo').'" name="siteseo_options[site_id]" value="'.esc_attr($option_site_id).'"/>
<p class="description">'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('To find your site ID, visit your %1$s Matomo Cloud %2$s account, go to Websites, and click Manage. The <br/>"Site ID" will be displayed on the right side.', 'siteseo'), '<strong>', '</strong>')).'</p>
<p class="description">'.
/* translators: placeholder is just <br> tag */
wp_kses_post(sprintf(__('For self-hosted installations, navigate to your Matomo administration, then go to Settings, Websites, %1$s and Manage. From the list of websites, locate the "ID" line.', 'siteseo'), '<br/>')).'<p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track visitors across all subdomains', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[track_visitors]" '.(!empty($option_sub_domain) ? 'checked="yes"' : '').' value="1"/>
'.esc_html__('Monitor one domain along with its subdomains on the same website.','siteseo') .'
<p class=description">'.esc_html__('If a visitor visits x.example.com and y.example.com, they will be counted as a single unique visitor.', 'siteseo').'</p>
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Prepend the site domain.', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[site_domain]" '.(!empty($option_site_domain) ? 'checked="yes"' : '').' value="1" />
'.esc_html__('Add the site domain before the page title when tracking', 'siteseo').'
<p class="description">For example, if someone visits the About page on blog.example.com, it will be recorded as "blog / About".<br/> This provides a simple way to get an overview of your traffic by subdomain.</p>`
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track users with JavaScript disabled.', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[track_users]" '.(!empty($option_no_js) ? 'checked="yes"' : '').' value="1" />
'. esc_html__('Track users with JavaScript disabled', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enables cross domain linking', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[enable_cross_domains]" '.(!empty($option_enable_corss_domain) ? 'checked="yes"' : '').' value="1" />
'.esc_html__('Enables cross domain linking', 'siteseo').'
</label>
<p class="description">'.esc_html__('By default, the visitor ID, which uniquely identifies each visitor, is stored in the browser first-party cookies. These cookies can only be accessed by pages on the same domain.', 'siteseo').'</p>
<p class="description">'.esc_html__('Enabling cross-domain tracking allows you to monitor all actions and pageviews of a specific visitor within the same session, even when they visit pages across different domains.', 'siteseo').'</p>
<p class="description">'.esc_html__('When a user clicks on a link to one of your site alias URLs, a URL parameter, <code>pk_vid</code>, will be appended, forwarding the Visitor ID.', 'siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Cross domain', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[corss_domains]" value="'.esc_attr($option_cross_domain_sites).'" placeholder="'.esc_attr('Enter your domains: siteseo.io,sub.siteseo.io,sub2.siteseo.io').'"/>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable DoNotTrack detection', 'siteseo').'</th>
<td>
<input type="checkbox" name="siteseo_options[enable_donottack]" '.(!empty($options_matomo_dtn) ? 'checked="yes"' : '').' value="1"/>
'.esc_html__('Activate client-side Do Not Track detection.', 'siteseo').'
<p class="description">'.esc_html__('Tracking requests will be blocked if visitors opt out of being tracked.', 'siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Disable all tracking cookies.', 'siteseo').'</th>
<td>
<input type="checkbox" name="siteseo_options[disabled_cookies]" '.(!empty($option_no_cookies) ? 'checked="yes"' : '').' value="1" />
'.esc_html__('Disables all first-party cookies. Any existing Matomo cookies for this site will be deleted on the next page view.', 'siteseo').'
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Download & Outlink tracking.', 'siteseo').'</th>
<td>
<input type="checkbox" name="siteseo_options[outlink_tracking]" '.(!empty($options_link_tracking) ? 'checked="yes"' : '').' value="1" />
'.esc_html__('Enabling Download & Outlink tracking','siteseo').'
<p class="description">By default, files with any of these extensions will be treated as a "download" in the Matomo interface.<p>
<div class="siteseo-styles pre"><pre>7z|aac|arc|arj|apk|asf|asx|avi|bin|bz|bz2|csv|deb|dmg|doc|exe|flv|gif|gz|gzip|hqx|jar|jpg|jpeg|js|mp2|mp3|mp4|mpg|mpeg|mov|movie|msi|msp|odb|odf|odg|odp|ods|odt|ogg|ogv| pdf|phps|png|ppt|qt|qtm|ra|ram|rar|rpm|sea|sit|tar|tbz|tbz2|tgz|torrent|txt|wav|wma|wmv|wpd|xls|xml|z|zip</pre></div>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Disable all heatmaps and session recordings.', 'siteseo').'</th>
<td>
<input type="checkbox" '.(!empty($options_no_heatmaps) ? 'checked="yes"' : '').' value="1" name="siteseo_options[disabled_heatmaps]" />
'.esc_html__('Turns off all heatmaps and session recordings.', 'siteseo').'
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[matomo_tab]" value="1"/>';
}
static function advanced(){
global $siteseo,$wp_roles;
if(!empty($_POST['submit'])){
self::save_settings();
}
if(!isset($wp_roles)){
$wp_roles = new \WP_Roles();
}
//$options = $siteseo->analaytics_settings;
$options = get_option('siteseo_google_analytics_option_name');
$option_track_authors = !empty($options['google_analytics_cd_author']) ? $options['google_analytics_cd_author'] : '';
$option_track_categories = !empty($options['google_analytics_cd_category']) ? $options['google_analytics_cd_category'] : '';
$option_track_tag = !empty($options['google_analytics_cd_tag']) ? $options['google_analytics_cd_tag'] : '';
$option_track_post_types = !empty($options['google_analytics_cd_post_type']) ? $options['google_analytics_cd_post_type'] : '';
$option_logged_user = !empty($options['google_analytics_cd_logged_in_user']) ? $options['google_analytics_cd_logged_in_user'] : '';
$adavnced_subtabs =[
'custom-dimensions' => 'Custom Dimensions',
'Misc' => 'Misc',
];
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($adavnced_subtabs as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($post_key).'" class="'.esc_attr($active_class).'">'.esc_html($post_val).'</a>';
$is_first = false;
}
echo '</div>
</th>
<td>
<h3>'.esc_html__('Advanced settings', 'siteseo').'</h3>
<div class="siteseo-notice" id="custom-dimensions">
<span class="dashicons dashicons-info"></span>
<p>'.esc_html__('All advanced settings are compatible with both Google Analytics and Matomo tracking codes.', 'siteseo').'</p>
</div>
<br/>
<span class="line"></span>
<h3>'.esc_html__('Custom Dimensions', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><p class="description">'.esc_html__('Set up your Google Analytics custom dimensions.', 'siteseo').'</p></div>
<div class="siteseo_wrap_label"><p class="description">'.esc_html__('Custom dimensions and metrics are similar to the default ones in Google Analytics, but you have the flexibility to create your own.', 'siteseo').'</p></div>
<div class="description"><p class="description">'.esc_html__('Utilize custom dimensions to gather and analyze data that Google Analytics does not track automatically.', 'siteseo').'</p></div>
<div class="description"><p class="description">'.esc_html__('Remember, you must also configure your custom dimensions in your Google Analytics account. Click the help icon for more information.', 'siteseo').'</p></div>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Track Authors', 'siteseo').'</th>
<td>
<select name="siteseo_options[track_authors]">
<option value="none" '.selected($option_track_authors, 'none', false).'>'.esc_html__('None','siteseo').'</option>';
for($i = 1; $i <= 20; ++$i){
/* translators: %d represents the custom dimension */
echo '<option '.selected($option_track_authors, 'dimension' . $i, false).' value="dimension'.esc_attr($i).'">'.sprintf(esc_html__('Custom Dimension #%d', 'siteseo'), esc_html($i)).'</option>';
}
echo '</select>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track Categories', 'siteseo').'</th>
<td>
<select name="siteseo_options[track_categories]">
<option value="none" '.selected($option_track_categories, 'none', false).'>'.esc_html__('None','siteseo').'</option>';
for($i = 1; $i <= 20; ++$i){
/* translators: %d represents the custom dimension */
echo '<option '.selected($option_track_categories, 'dimension' . $i, false).' value="dimension'.esc_attr($i).'">'.sprintf(esc_html__('Custom Dimension #%d', 'siteseo'), esc_html($i)).'</option>';
}
echo '</select>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track Tags', 'siteseo').'</th>
<td>
<select name="siteseo_options[track_tags]">
<option value="none" '.selected($option_track_tag, 'none', false).'>'.esc_html__('None','siteseo').'</option>';
for($i = 1; $i <= 20; ++$i){
/* translators: %d represents the custom dimension */
echo '<option '.selected($option_track_tag, 'dimension' . $i, false).' value="dimension'.esc_attr($i).'">'.sprintf(esc_html__('Custom Dimension #%d', 'siteseo'), esc_html($i)).'</option>';
}
echo '</select>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track Post Types','siteseo').'</th>
<td>
<select name="siteseo_options[track_post_types]">
<option value="none" '.selected($option_track_post_types, 'none', false).'>'.esc_html__('None','siteseo').'</option>';
for($i = 1; $i <= 20; ++$i){
/* translators: %d represents the custom dimension */
echo '<option '.selected($option_track_post_types, 'dimension' . $i, false).' value="dimension'.esc_attr($i).'">'.sprintf(esc_html__('Custom Dimension #%d', 'siteseo'), esc_html($i)).'</option>';
}
echo '</select>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track Logged In Users','siteseo').'</th>
<td>
<select name="siteseo_options[track_user]">
<option value="none" '.selected($option_logged_user, 'none', false).'>'.esc_html__('None','siteseo').'</option>';
for($i = 1; $i <= 20; ++$i){
/* translators: %d represents the custom dimension */
echo '<option '.selected($option_logged_user, 'dimension' . $i, false).' value="dimension'.esc_attr($i).'">'. sprintf(esc_html__('Custom Dimension #%d', 'siteseo'), esc_html($i)).'</option>';
}
echo '</select>
</td>
</tr>
</tbody>
</table>
<div class="description" id="Misc"><span class="line"></span>
<h3>'.esc_html__('Misc','siteseo').'</h3>
<table>
<tbody class="form-table">
<tr>
<th scope="row">'.esc_html__('Exclude user roles from tracking (Google Analytics and Matomo)','siteseo').'</th>
<td>';
foreach($wp_roles->get_names() as $key => $value){
$select = isset($options['google_analytics_roles'][$key]);
echo '<p>
<label>
<input name="siteseo_options[misc_roles]['.esc_attr($key).']" type="checkbox" '.(!empty($select) ? 'checked="yes"' : 'value="1"').'/>
<strong>'. esc_html($value) .'</strong> (<em> '. esc_html(translate_user_role($value, 'default')) .'</em>)
</label>
</p>';
}
echo '</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[advanced_tab]" value="1"/>';
}
static function clarity(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->analaytics_settings;
$options = get_option('siteseo_google_analytics_option_name');
$option_enable_clarity = !empty($options['google_analytics_clarity_enable']) ? $options['google_analytics_clarity_enable'] : '';
$option_project_id = !empty($options['google_analytics_clarity_project_id']) ? $options['google_analytics_clarity_project_id'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Microsoft Clarity', 'siteseo').'</h3>
<p class="description">'.esc_html__('Use Microsoft Clarity to capture session recordings, access instant heatmaps, and gain powerful insights for free. Understand how users interact with your site to enhance the user experience and boost conversions.', 'siteseo').'</p>
<div class="siteseo-notice">
<span class="dashicons dashicons-info"></span>
<p>'.
/* translators: %s represents the microsoft clarity api url */
wp_kses_post(sprintf(__('Create your first Microsoft Clarity project %1$shere%2$s.', 'siteseo'), '<a href="https://clarity.microsoft.com/" target="_blank">', '</a>')) .'</p>
</div>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Enable Microsoft Clarity','siteseo').'</th>
<td>
<input type="checkbox" name="siteseo_options[microsoft_clarity]" '.(!empty($option_enable_clarity) ? 'checked="yes"' : ''). ' value="1">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Enter your Clarity project ID', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[project_id]" placeholder="'.esc_attr__('Enter your Project Id', 'siteseo').'" value="'.esc_attr($option_project_id).'" >
<p><span class="dashicons dashicons-external"></span>
<a href="https://siteseo.io/docs/analytics/find-my-microsoft-clarity-project-id/" target="_blank">
'.esc_html__('Find your project ID', 'siteseo').'
</a>
</span>
</p>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[clarity_tab]" value="1" />';
}
static function google_anlytics(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_google_analytics_option_name');
//$options = $siteseo->analaytics_settings;
$option_enable_anaytics = !empty($options['google_analytics_enable']) ? $options['google_analytics_enable'] : '';
$option_anaytics_id = !empty($options['google_analytics_ga4']) ? $options['google_analytics_ga4'] : '';
$option_enable_optimize = !empty($options['google_analytics_link_tracking_enable']) ? $options['google_analytics_link_tracking_enable'] : '';
$option_enable_download_tracking= !empty($options['google_analytics_download_tracking_enable']) ? $options['google_analytics_download_tracking_enable'] : '';
$option_download_tracking = !empty($options['google_analytics_download_tracking']) ? $options['google_analytics_download_tracking'] : '';
$option_affiliate_tracking_enable = !empty($options['google_analytics_affiliate_tracking_enable']) ? $options['google_analytics_affiliate_tracking_enable'] : '';
$option_affiliate_tracking = !empty($options['google_analytics_affiliate_tracking']) ? $options['google_analytics_affiliate_tracking'] : '';
$option_phone_tracking = !empty($options['google_analytics_phone_tracking']) ? $options['google_analytics_phone_tracking'] : '';
$option_container_id = !empty($options['google_analytics_optimize']) ? $options['google_analytics_optimize'] : '';
$option_conversion_id = !empty($options['google_analytics_ads']) ? $options['google_analytics_ads'] : '';
$option_ip_anonymization = !empty($options['google_analytics_ip_anonymization']) ? $options['google_analytics_ip_anonymization'] : '';
$option_links_attribution = !empty($options['google_analytics_link_attribution']) ? $options['google_analytics_link_attribution'] : '';
$option_domain_tracking = !empty($options['google_analytics_cross_enable']) ? $options['google_analytics_cross_enable'] : '';
$option_cross_domain = !empty($options['google_analytics_cross_domain']) ? $options['google_analytics_cross_domain'] : '';
$option_enable_remarketing = !empty($options['google_analytics_remarketing']) ? $options['google_analytics_remarketing'] : '';
$google_analytics_fileds = [
'general-settings' =>'General',
'tracking-settings'=>'Tracking',
'events-settings' => 'Events'
];
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($google_analytics_fileds as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($post_key).'" class="'.esc_attr($active_class).'">'.esc_html($post_val).'</a>';
$is_first = false;
}
echo '</div></th>
<td>
<div id="general-settings">
<h3>'.esc_html__('Google Anlytics', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><p class="description">'.esc_html__('Connect your Google Analytics to your website. The tracking code will be automatically added to your site.', 'siteseo') .'</p></div>
<span class="line"></span>
<div class="siteseo_wrap_label"><p class="'.esc_html__('description">Link your Google Analytics to your website. The tracking code will be automatically added to your site', 'siteseo').'</p></div>
<span class="line"></span>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('General', 'siteseo').'</th>
<td></td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable Google Analytics tracking', 'siteseo').'</th>
<td>
<label><input type="checkbox" name="siteseo_options[google_anlytics_tracking]" '.(!empty($option_enable_anaytics) ? 'checked="yes"' : '') . ' value="1"/> ' . esc_html__('Activate Google Analytics tracking using the Global Site Tag (gtag.js).', 'siteseo') . '</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enter your measurement ID (GA4)', 'siteseo').'</th>
<td>
<input type="text" placeholder="'.esc_attr__('Enter your measurement ID (G-XXXXXXXXXX)','siteseo').'" name="siteseo_options[anlytics_measurement_id]" value="'.esc_attr($option_anaytics_id).'">
<p>
<span class="dashicons dashicons-external"></span>
<a href="https://support.google.com/analytics/answer/9539598?hl=en&ref_topic=9303319" target="_blank">'.esc_html__('Find your measurement ID', 'siteseo').'</a>
</p>
</td>
</tr>
</tbody>
</table>
</div></div>
<div id="tracking-settings">
<span class="line"></span>
<h3>'.esc_html__('Tracking','siteseo').'</h3>
<p class="description">'.esc_html__('Set up your Google Analytics tracking code.', 'siteseo').'</P>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Enable Google Optimize.', 'siteseo').'</th>
<td>
<label>
<input type="text" name="siteseo_options[container_id]" placeholder="'.esc_attr__('Enter your Google Optimize container ID.', 'siteseo').'" value="'.esc_attr($option_container_id).'"/>
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable Google Ads','siteseo').'</th>
<td>
<label>
<input type="text" placeholder="'.esc_attr__('Enter your Google Ads conversion ID (eg: AW-123456789).', 'siteseo').'" name="siteseo_options[conversion_id]" value="'.esc_attr($option_conversion_id).'"/>
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable remarketing, demographics, and interests reporting', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[enable_remarketing]" '.(!empty($option_enable_remarketing) ? 'checked="yes"' : '').' value="1"/>
'. esc_html__('Enable remarketing, demographics, and interests reporting', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable IP Anonymization', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[ip_anonymiza]" '.(!empty($option_ip_anonymization) ? 'checked="yes"' : '').'/>
'. esc_html__('Enable IP Anonymization', 'siteseo') .'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enhanced Link Attribution', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[link_attribution]" '.(!empty($option_links_attribution) ? 'checked="yes"' : '').'/>
'. esc_html__('Enhanced Link Attribution', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable cross-domain tracking', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[domain_tracking]" '.(!empty($option_domain_tracking) ? 'checked="yes"' : '').' />
'. esc_html__('Enable cross-domain tracking', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Cross domains', 'siteseo').'</th>
<td>
<input type="text" placeholder="Enter your domains: siteseo.io,sub.siteseo.io,sub2.siteseo.io" name="siteseo_options[cross_domain]" value="'.esc_attr($option_cross_domain).'" />
</td>
</tr>
</tbody>
<table>
</div>
<div id="events-settings">
<span class="line"></span>
<h3>'.esc_html__('Events', 'siteseo').'</h3>
<P class="description">'.esc_html__('Track events in Google Analytics', 'siteseo').'</p>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Enable Google Optimize', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[google_optimize]" '.(!empty($option_enable_optimize) ? 'checked="yes"' : ''). ' value="1">' . esc_html__(' Enable external links tracking', 'siteseo') . '
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable downloads tracking (eg: PDF, XLSX, DOCX...)', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[enable_download_tracking]" '.(!empty($option_enable_download_tracking) ? 'checked="yes"' : '').' value="1"> '.esc_html__('Enable download tracking', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track downloads clicks', 'siteseo').'</th>
<td>
<input type="text" placeholder="pdf|docs|pptx|zip" name="siteseo_options[track_downlaods]" value="'.esc_attr($option_download_tracking).'"/>
<p class="description">'.esc_html__('Separate each file type extensions with a pipe "|"','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable affiliate/outbound links tracking (eg: aff, go, out, recommends)', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[aff_tracking_enable]" '.(!empty($option_affiliate_tracking_enable ) ? 'checked="yes"' : '').' value="1"/>
'. esc_html__('Enable affiliate/outbound tracking','siteseo') .'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track affiliate/outbound links','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[aff_tracking]" placeholder="aff|go|out" value="'.esc_attr($option_affiliate_tracking).'"/>
<p class="description">'.esc_html__('Separate each keyword with a pipe "|"', 'siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Track phone links','siteseo').'</th>
<td>
<input type="checkbox" name="siteseo_options[track_phones]" '.(!empty($option_phone_tracking ) ? 'checked="yes"' : '') . ' value="1"/>
'.esc_html__(' Enable tracking of "tel:" links' , 'siteseo'). '
<div class="siteseo-styles pre"><pre>'.esc_html('<a href="tel:+33123456789">').'</pre></div>
</td>
</tr>
</tbody>
</table
</div>
</td>
</tbody>
</table>
<input type="hidden" name="siteseo_options[analytics_tab]" value="1"/>';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_analytics_settings');
if(!siteseo_user_can('manage_analytics') || !is_admin()){
return;
}
$options = [];
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['analytics_tab'])){
$options['google_analytics_enable'] = isset($_POST['siteseo_options']['google_anlytics_tracking']);
$options['google_analytics_ga4'] = isset($_POST['siteseo_options']['anlytics_measurement_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['anlytics_measurement_id'])) : '';
$options['google_analytics_link_tracking_enable'] = isset($_POST['siteseo_options']['google_optimize']);
$options['google_analytics_download_tracking_enable'] = isset($_POST['siteseo_options']['enable_download_tracking']);
$options['google_analytics_download_tracking'] = isset($_POST['siteseo_options']['track_downlaods']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_downlaods'])) : '';
$options['google_analytics_affiliate_tracking_enable'] = isset($_POST['siteseo_options']['aff_tracking_enable']);
$options['google_analytics_affiliate_tracking'] = isset($_POST['siteseo_options']['aff_tracking']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['aff_tracking'])) : '';
$options['google_analytics_phone_tracking'] = isset($_POST['siteseo_options']['track_phones']);
$options['google_analytics_optimize'] = isset($_POST['siteseo_options']['container_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['container_id'])) : '';
$options['google_analytics_ads'] = isset($_POST['siteseo_options']['conversion_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['conversion_id'])) : '';
$options['google_analytics_remarketing'] = isset($_POST['siteseo_options']['enable_remarketing']);
$options['google_analytics_ip_anonymization'] = isset($_POST['siteseo_options']['ip_anonymiza']);
$options['google_analytics_link_attribution'] = isset($_POST['siteseo_options']['link_attribution']);
$options['google_analytics_cross_enable'] = isset($_POST['siteseo_options']['domain_tracking']);
$options['google_analytics_cross_domain'] = isset($_POST['siteseo_options']['cross_domain']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cross_domain'])) : '';
}
if(isset($_POST['siteseo_options']['clarity_tab'])){
$options['google_analytics_clarity_enable'] = isset($_POST['siteseo_options']['microsoft_clarity']);
$options['google_analytics_clarity_project_id'] = isset($_POST['siteseo_options']['project_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['project_id'])) : '';
}
if(isset($_POST['siteseo_options']['matomo_tab'])){
$options['google_analytics_matomo_enable'] = isset($_POST['siteseo_options']['enable_matomo']);
$options['google_analytics_matomo_self_hosted'] = isset($_POST['siteseo_options']['self_hosted']);
$options['google_analytics_matomo_id'] = isset($_POST['siteseo_options']['tracking_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['tracking_id'])) : '';
$options['google_analytics_matomo_site_id'] = isset($_POST['siteseo_options']['site_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['site_id'])) : '';
$options['google_analytics_matomo_subdomains'] = isset($_POST['siteseo_options']['track_visitors']);
$options['google_analytics_matomo_site_domain'] = isset($_POST['siteseo_options']['site_domain']);
$options['google_analytics_matomo_cross_domain'] = isset($_POST['siteseo_options']['enable_cross_domains']);
$options['google_analytics_matomo_no_js'] = isset($_POST['siteseo_options']['track_users']);
$options['google_analytics_matomo_cross_domain_sites'] = isset($_POST['siteseo_options']['corss_domains']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['corss_domains'])) : '';
$options['google_analytics_matomo_no_cookies'] = isset($_POST['siteseo_options']['disabled_cookies']);
$options['google_analytics_matomo_link_tracking'] = isset($_POST['siteseo_options']['outlink_tracking']);
$options['google_analytics_matomo_no_heatmaps'] = isset($_POST['siteseo_options']['disabled_heatmaps']);
$options['google_analytics_matomo_dnt'] = isset($_POST['siteseo_options']['enable_donottack']);
}
if(isset($_POST['siteseo_options']['advanced_tab'])){
$options['google_analytics_cd_author'] = isset($_POST['siteseo_options']['track_authors']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_authors'])) : '';
$options['google_analytics_cd_category'] = isset($_POST['siteseo_options']['track_categories']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_categories'])) : '';
$options['google_analytics_cd_tag'] = isset($_POST['siteseo_options']['track_tags']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_tags'])) : '';
$options['google_analytics_cd_post_type'] = isset($_POST['siteseo_options']['track_post_types']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_post_types'])) : '';
$options['google_analytics_cd_logged_in_user'] = isset($_POST['siteseo_options']['track_user']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['track_user'])) : '';
// mics roles
if(isset($_POST['siteseo_options']['misc_roles'])){
$options['google_analytics_roles'] = map_deep(wp_unslash($_POST['siteseo_options']['misc_roles']), 'sanitize_text_field');
}
}
if(isset($_POST['siteseo_options']['custom_tracking_tab']) && current_user_can('unfiltered_html')){
// NOTE: These options can not be sanitized as we need user to be able to add some JS code, so we have added a capability check which only a super admin can have.
$options['google_analytics_other_tracking'] = isset($_POST['siteseo_options']['head_tracking']) ? wp_unslash($_POST['siteseo_options']['head_tracking']) : '';
$options['google_analytics_other_tracking_body'] = isset($_POST['siteseo_options']['body_tracking']) ? wp_unslash($_POST['siteseo_options']['body_tracking']) : '';
$options['google_analytics_other_tracking_footer'] = isset($_POST['siteseo_options']['footer_tracking']) ? wp_unslash($_POST['siteseo_options']['footer_tracking']) : '';
}
if(isset($_POST['siteseo_options']['cookies_tab'])){
$options['google_analytics_hook'] = isset($_POST['siteseo_options']['cookie_pos']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cookie_pos'])) : '';
$options['google_analytics_disable'] = isset($_POST['siteseo_options']['opt_tracking']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['opt_tracking'])) : '';
$options['google_analytics_half_disable'] = isset($_POST['siteseo_options']['half_disable']);
$options['google_analytics_opt_out_edit_choice'] = isset($_POST['siteseo_options']['opt_edit_choices']);
$options['google_analytics_opt_out_msg'] = isset($_POST['siteseo_options']['opt_msg']) ? wp_kses_post(wp_unslash($_POST['siteseo_options']['opt_msg'])) : 'We use cookies to enhance your experience.';
$options['google_analytics_opt_out_msg_ok'] = isset($_POST['siteseo_options']['opt_msg_ok']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['opt_msg_ok'])) : 'Accept';
$options['google_analytics_opt_out_msg_edit'] = isset($_POST['siteseo_options']['opt_edit_btn']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['opt_edit_btn'])) : 'Manage cookies';
$options['google_analytics_opt_out_msg_close'] = isset($_POST['siteseo_options']['opt_close']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['opt_close'])) : 'X';
$options['google_analytics_cb_exp_date'] = isset($_POST['siteseo_options']['cd_exp_date']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cd_exp_date'])) : '30';
$options['google_analytics_cb_pos'] = isset($_POST['siteseo_options']['cd_pos']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cd_pos'])) : 'center';
$options['google_analytics_cb_txt_align'] = isset($_POST['siteseo_options']['cd_txt_align']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cd_txt_align'])) : 'center';
$options['google_analytics_cb_width'] = isset($_POST['siteseo_options']['cd_width']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cd_width'])) : '100%';
$options['google_analytics_cb_scheme'] = isset($_POST['siteseo_options']['google_analytics_cb_scheme']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['google_analytics_cb_scheme'])) : '';
// Colors
$options['google_analytics_cb_backdrop'] = isset($_POST['siteseo_options']['cd_backdrop']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cd_backdrop'])) : '';
$options['google_analytics_cb_backdrop_bg'] = isset($_POST['siteseo_options']['backdrop_bg']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['backdrop_bg'])) : '';
$options['google_analytics_cb_bg'] = isset($_POST['siteseo_options']['cookiesbar_bg']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cookiesbar_bg'])) : '';
$options['google_analytics_cb_txt_col'] = isset($_POST['siteseo_options']['cookiebar_txt']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['cookiebar_txt'])) : '';
$options['google_analytics_cb_lk_col'] = isset($_POST['siteseo_options']['line_co']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['line_co'])) : '';
$options['google_analytics_cb_btn_bg'] = isset($_POST['siteseo_options']['primary_btn_bg']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['primary_btn_bg'])) : '';
$options['google_analytics_cb_btn_bg_hov'] = isset($_POST['siteseo_options']['primary_btn_bg_hov']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['primary_btn_bg_hov'])) : '';
$options['google_analytics_cb_btn_col'] = isset($_POST['siteseo_options']['primary_btn_txt']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['primary_btn_txt'])) : '';
$options['google_analytics_cb_btn_col_hov'] = isset($_POST['siteseo_options']['primary_btn_txt_hov']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['primary_btn_txt_hov'])) : '';
$options['google_analytics_cb_btn_sec_bg'] = isset($_POST['siteseo_options']['sec_btn_bg']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['sec_btn_bg'])) : '';
$options['google_analytics_cb_btn_sec_bg_hov'] = isset($_POST['siteseo_options']['sec_btn_bg_hov']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['sec_btn_bg_hov'])) : '';
$options['google_analytics_cb_btn_sec_col'] = isset($_POST['siteseo_options']['sec_btn_txt']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['sec_btn_txt'])) : '';
$options['google_analytics_cb_btn_sec_col_hov'] = isset($_POST['siteseo_options']['sec_btn_txt_hov']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['sec_btn_txt_hov'])) : '';
}
update_option('siteseo_google_analytics_option_name', $options);
}
}
settings/dashboard.php 0000644 00000042402 15152641524 0011053 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Dashboard{
static function dashboard_tab(){
global $siteseo;
$pro = get_option('siteseo_pro_options');
$options = $siteseo->setting_enabled;
$titles_meta_toggle = isset($options['toggle-titles']) ? $options['toggle-titles'] : '';
$sitemap_toggle = isset($options['toggle-xml-sitemap']) ? $options['toggle-xml-sitemap'] : '';
$social_toggle = isset($options['toggle-social']) ? $options['toggle-social'] : '';
$advanced_toggle = isset($options['toggle-advanced']) ? $options['toggle-advanced'] : '';
$analytics_toggle = isset($options['toggle-google-analytics']) ? $options['toggle-google-analytics'] : '';
$indexing_toggle = isset($options['toggle-instant-indexing']) ? $options['toggle-instant-indexing'] : '';
//pro-features
$toggle_localBusiness = isset($pro['toggle_state_local_buz']) ? $pro['toggle_state_local_buz'] : '';
$toggle_easy_digital = isset($pro['toggle_state_easy_digital']) ? $pro['toggle_state_easy_digital'] : '';
$toggle_woocommerce = isset($pro['toggle_state_woocommerce']) ? $pro['toggle_state_woocommerce'] : '';
$toggle_structured_data = isset($pro['toggle_state_stru_data']) ? $pro['toggle_state_stru_data'] : '';
$toggle_state_redirect = isset($pro['toggle_state_redirect_monitoring']) ? $pro['toggle_state_redirect_monitoring'] : '';
$toggle_state_google_news = isset($pro['toggle_state_google_news']) ? $pro['toggle_state_google_news'] : '';
$toggle_state_video_sitemap = isset($pro['toggle_state_video_sitemap']) ? $pro['toggle_state_video_sitemap'] : '';
$toggle_state_llm_txt = isset($pro['toggle_state_llm_txt']) ? $pro['toggle_state_llm_txt'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
$pro_nonce = wp_create_nonce('siteseo_pro_toggle_nonce');
$siteseo_dashboard_img = SITESEO_ASSETS_URL.'/img/seo-get-started.jpg';
$siteseo_loginizer_product = SITESEO_ASSETS_URL.'/img/loginizer_product.png';
echo'<div id="siteseo-root">';
Util::admin_header();
$dismissed_intro = get_option('siteseo_dismiss_intro', 0);
echo'<div id="siteseo-dashbord">';
if(empty($dismissed_intro) && !defined('SITEPAD')){
echo '<div class="siteseo-dashbord-intro">
<div class="siteseo-text-content">
<h2>'.esc_html__('HOW-TO GET STARTED', 'siteseo').'</h2><h1>'.esc_html__('Welcome to SiteSEO!', 'siteseo').'</h1>
<p>'.esc_html__('Launch our installation wizard to quickly and easily configure the basic SEO settings for your site. Cant find the answers to your questions? Write us at support@siteseo.io. A happiness engineer will be happy to help you.', 'siteseo').'</p>
<div class="siteseo-buttons">
<a class="get-started" href="?page=siteseo-onboarding">'.esc_html__('Get started', 'siteseo').'</a>
<a class="dismiss" id="siteseo-dismiss-get-started" href="#">'.esc_html__('Dismiss', 'siteseo').'</a>
</div>
</div>
<div class="siteseo-image-content"><img alt="'.esc_html__('Illustration of a megaphone with various icons representing SEO and digital marketing', 'siteseo').'" height="470" src="'.esc_url($siteseo_dashboard_img).'" width="470"/>
</div>
</div>';
}
echo '<div class="siteseo-dashbord-content">
<section class="siteseo-dashboard-features">
<h2>'.esc_html__('Manage SiteSEO Features', 'siteseo').'</h2></br/>
<div class="siteseo-dashbord-container">
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-edit-large siteseo-card-icon"></span>
<h3>'.esc_html__('Titles & Metas', 'siteseo').'</h3>
<p>'.esc_html__('Manage all your titles and metas for post types, taxonomies more...', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-titles">'.esc_html__('Settings', 'siteseo').'</a>';
Util::render_toggle('Titles & Metas -SiteSEO', 'titles_meta_toggle', $titles_meta_toggle, $nonce, true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-networking siteseo-card-icon"></span>
<h3>'.esc_html__('XML & HTML Sitemaps', 'siteseo').'</h3>
<p>'.esc_html__('Manage your XML - Image - Video- Taxonomies - HTML Sitemap more...', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-sitemaps">'.esc_html__('Settings', 'siteseo').'</a>';
Util::render_toggle('Sitemaps - SiteSEO', 'sitemap_toggle', $sitemap_toggle, $nonce,true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-share siteseo-card-icon"></span>
<h3>'.esc_html__('Social Networks', 'siteseo').'</h3>
<p>'.esc_html__('Open Graph, X Card, Google Knowledge Graph and more...', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-social">'.esc_html__('Settings','siteseo').'</a>';
Util::render_toggle('Social - SiteSEO', 'social_toggle', $social_toggle, $nonce,true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-performance siteseo-card-icon"></span>
<h3>'.esc_html__('Analytics', 'siteseo').'</h3>
<p>'.esc_html__('Track everything about your visitors with Analytics/Matomo more...', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-analytics">'.esc_html__('Settings','siteseo').'</a>';
Util::render_toggle('Analytics - SiteSEO', 'analytics_toggle', $analytics_toggle, $nonce,true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-superhero siteseo-card-icon"></span>
<h3>'.esc_html__('Instant Indexing','siteseo').'</h3>
<p>'.esc_html__('Ping Google & Bing to quickly index your content. Updated and remove submit URLs','siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-instant-indexing">'.esc_html__('Settings','siteseo').'</a>';
Util::render_toggle('Instant indexing - SiteSEO', 'indexing_toggle', $indexing_toggle, $nonce,true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-format-gallery siteseo-card-icon"></span>
<h3>'.esc_html__('Image SEO','siteseo').'</h3>
<p>'.esc_html__('Optimize your images for SEO. Configure advanced settings more...','siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-advanced">'.esc_html__('Settings','siteseo').'</a>';
Util::render_toggle('Advanced - SiteSEO', 'advanced_toggle', $advanced_toggle, $nonce,true);
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-upload siteseo-card-icon"></span>
<h3>'.esc_html__('Tools', 'siteseo').'</h3>
<p>'.esc_html__('Import/Export plugin settings from site to site. Reset settings more...', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">
<a href="admin.php?page=siteseo-tools">'.esc_html__('Settings', 'siteseo').'</a>
<div class="siteseo-toggle-container">
</div>
</div>
</div>';
if(!defined('SITEPAD')){
echo'<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-cart siteseo-card-icon"></span>
<h3>'.esc_html__('WooCommerces SEO','siteseo'),'</h3>
<p>'.esc_html__('Add meta tags required for WooCommerce SEO','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings','siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('woocommerce', $toggle_woocommerce, $pro_nonce, true);
}
echo'</div></div>';
echo '<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-money-alt siteseo-card-icon"></span>
<h3>'.esc_html__('Easy Digital Downloads', 'siteseo').'</h3>
<p>'.esc_html__('Add meta tags required for Easy Digitial Downloads SEO', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings','siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('edd', $toggle_easy_digital, $pro_nonce,true);
}
echo'</div></div>';
}
echo '<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-code-standards siteseo-card-icon"></span>
<h3>'.esc_html__('Page Speed', 'siteseo').'</h3>
<p>'.esc_html__('Enhance Your Website Performance with PageSpeed Insights','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else {
echo'<div class="siteseo-pro-badge">Pro</div>';
}
echo'</div>
</div>
<div class="siteseo-card">
'.((time() < strtotime('30 November 2025')) ? '<span class="siteseo-feature-update-badge">Updated</span>' : '') .'
<div class="siteseo-card-body">
<span class="dashicons dashicons-list-view siteseo-card-icon"></span>
<h3>'.esc_html__('Structured Data','siteseo').'</h3>
<p>'.esc_html__('Enhance Search Visibility with Structured Data Optimization','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('structured', $toggle_structured_data, $pro_nonce,true);
}
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-location siteseo-card-icon"></span>
<h3>'.esc_html__('Local Business', 'siteseo').'</h3>
<p>'.esc_html__('Optimize Your Online Presence for Local Business Success', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo '<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('local', $toggle_localBusiness, $pro_nonce, true);
}
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-editor-unlink siteseo-card-icon"></span>
<h3>'.esc_html__('Redirections / 404 monitoring','siteseo').'</h3>
<p>'.esc_html__('Track 404 errors and set up redirects to improve user experience and SEO.','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('404_monitoring', $toggle_state_redirect, $pro_nonce, true);
}
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-index-card siteseo-card-icon"></span>
<h3>'.esc_html__('Google News','siteseo').'</h3>
<p>'.esc_html__('Generate and manage a Google News sitemap to ensure your news articles get indexed quickly.','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('google_news', $toggle_state_google_news, $pro_nonce, true);
}
echo'</div>
</div>
<div class="siteseo-card">
<div class="siteseo-card-body">
<span class="dashicons dashicons-format-video siteseo-card-icon"></span>
<h3>'.esc_html__('Video Sitemap','siteseo').'</h3>
<p>'.esc_html__('Create and manage a video sitemap to help search engines index your video content efficiently.','siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('video_sitemap', $toggle_state_video_sitemap, $pro_nonce, true);
}
echo'</div>
</div>
<div class="siteseo-card">
'.((time() < strtotime('30 November 2025')) ? '<span class="siteseo-feature-new-badge">New</span>' : '') .'
<div class="siteseo-card-body">
<span class="dashicons dashicons-media-text siteseo-card-icon"></span>
<h3>'.esc_html__('LLMs txt', 'siteseo').'</h3>
<p>'.esc_html__('Generate an llms.txt file with a single click to help AI crawlers better understand, index, and represent your business accurately.', 'siteseo').'</p>
</div>
<div class="siteseo-card-footer">';
if(defined('SITESEO_PRO_VERSION')){
echo'<a href="admin.php?page=siteseo-pro-page">'.esc_html__('Settings', 'siteseo').'</a>';
} else{
echo'<div class="siteseo-pro-badge">Pro</div>';
}
if(class_exists('\SiteSEOPro\Settings\Util') && method_exists('\SiteSEOPro\Settings\Util', 'render_toggle')){
\SiteSEOPro\Settings\Util::render_toggle('llm_txt', $toggle_state_llm_txt, $pro_nonce, true);
}
echo'</div>
</div>';
echo'</div></section>';
if(!defined('SITEPAD')){
echo'<section class="siteseo-dashboard-extras">';
if(defined('SITESEO_PRO_VERSION') && defined('SITESEO_PRO_AI_BUY')){
do_action('siteseo_pro_show_ai_tokens_sidebar');
}
echo '<div class="siteseo-need-help">
<p>Quick Access</p>
<div class="siteseo-quick-links">
<div class="siteseo-quick-access-item">
<span class="dashicons dashicons-format-status"></span>
<a href="https://softaculous.deskuss.com/open.php?topicId=22" target="_blank">Support</a>
</div>
<div class="siteseo-quick-access-item">
<span class="dashicons dashicons-media-document"></span>
<a href="https://siteseo.io/docs/" target="_blank">Documentation</a>
</div>
<div class="siteseo-quick-access-item">
<span class="dashicons dashicons-feedback"></span>
<a href="https://softaculous.deskuss.com/open.php?topicId=22" target="_blank">Feedback</a>
</div>
<div class="siteseo-quick-access-item">
<span class="dashicons dashicons-star-filled" style="color:#FFD700;"></span><a href="https://wordpress.org/support/plugin/siteseo/reviews/?rate=5#new-post" target="_blank">Rate Us</a>
</div>
</div>
</div>
<div class="siteseo-admin-softaculous-branding">SiteSEO - A Softaculous Product</div>';
if(!defined('SITEPAD') && !defined('SITESEO_PRO_VERSION')){
self::pro_upsell();
}
echo '</section>';
}
echo '</div></div></div>';
}
static function pro_upsell(){
$features = [
'Search Statistics',
'Advanced Sitemaps',
'Redirection Management',
'AI-Generations Titles & Descriptions',
'LLMs.txt Support',
'and More…',
];
echo '<div class="siteseo-promo-modern-card">
<div class="siteseo-promo-header-group">
<h3 class="siteseo-promo-title">SiteSEO</h3>
<span class="siteseo-promo-badge-pro">Pro</span>
</div>
<p class="siteseo-promo-desc">'.esc_html__('Unlock advanced performance features.', 'siteseo').'</p>
<ul class="siteseo-promo-feature-list">';
foreach($features as $feature){
echo '<li class="siteseo-promo-feature-item">
<div class="siteseo-promo-check-circle">
<div class="siteseo-promo-check-icon"></div>
</div>
'.esc_html($feature).'
</li>';
}
echo '</ul>
<a href="https://siteseo.io/pricing/?utm_source=plugin_settings" class="siteseo-promo-btn-main" target="_blank">
<span class="siteseo-promo-btn-text">'.esc_html__('Upgrade to Pro', 'siteseo').'</span>
<span class="siteseo-promo-arrow">→</span>
</a>
</div>';
}
}
settings/tools.php 0000644 00000012776 15152641524 0010277 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Tools{
static function menu(){
echo '<div id="siteseo-root">';
Util::admin_header();
$plugins = Util::importable_plugins();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">
<span id="siteseo-tab-title"><strong>'.esc_html__('Tools - SiteSEO','siteseo').'</strong></span><br/><br/>
<span class="line"></span>
<div style="siteseo-tools-page">';
if(!defined('SITEPAD')){
echo '<h3>'.esc_html__('Import Settings From Other Plugins','siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Import posts and terms metadata from the specified source', 'siteseo').'</p>
</div>
<p><select id="siteseo-plugin-selector">
<option value="none">'.esc_html__('Select an option', 'siteseo').'</option>';
foreach($plugins as $plugin => $name){
$plugin_slug = explode('/', $plugin);
$plugin = $plugin_slug[0];
echo '<option value="'. esc_attr($plugin) . '-migration-tool">'.esc_html($name).'</option>';
}
echo '</select></p>
<p class="description">' . esc_html__('You don\'t need to enable the selected SEO plugin to run the import.', 'siteseo').'</p>';
foreach($plugins as $plugin =>$name){
self::display_plugins($plugin, $name);
}
echo '<span class="line"></span>';
}
echo '<h3>'.esc_html__('Export plugin settings','siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Export the plugin settings for this site as a .json file, making it easy to import the configuration into another site.', 'siteseo').'</p>
</div>
<div class="siteseo_wrap_label">
<button class="btn btnSecondary" id="siteseo-export-btn">'.esc_html__('Export', 'siteseo').'</button>
</div>
<span class="line"></span>
<h3>'.esc_html__('Import plugin settings', 'siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Import the plugin settings from a .json file. You can obtain this file by exporting the settings from another site using the form above.','siteseo').'</p>
</div>
<div class=siteseo_wrap_label>
<input type="file" id="siteseo-import-file" accept=".json" />
</div>
<div class="siteseo_wrap_label">
<button class="brn btnSecondary" id="siteseo-import-btn">'. esc_html__('Import', 'siteseo') .'</button>
</div>
<span class="line"></span>
<h3>'.esc_html__('Reset All Settings', 'siteseo').'</h3>
<div class="siteseo_wrap_label"><div class="siteseo-notice is-warning">
<span id="dashicons-warning" class="dashicons dashicons-info"></span>
<div><p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('%1$s WARNING: %2$s Delete all options related to this plugin in your database.','siteseo'), '<strong>', '</strong>')).'</p></div>
</div></div>
<button class="btn btnSecondary" id="siteseo-reset-settings">'.esc_html__('Reset settings', 'siteseo').'</button>
</div>
</form></div>';
}
static function display_plugins($plugin,$name){
$seo_title = 'SiteSEO';
$plugin_slug = explode('/', $plugin);
$plugin = $plugin_slug[0];
echo '<div id="'.esc_attr($plugin).'-migration-tool" class="postbox siteseo-section-tool">
<div class="inside">
<h3>'. /* translators: %s represents the import posts and terms */
sprintf(esc_html__('Import posts and terms (if available) metadata from %s', 'siteseo'), esc_html($name)).'</h3>
<p>'. esc_html__('By clicking Migrate, we\'ll import:', 'siteseo').'</p>
<ul>
<li>'. esc_html__('Title tags', 'siteseo') .'</li>
<li>'. esc_html__('Meta description', 'siteseo') .'</li>
<li>'. esc_html__('Facebook Open Graph tags (title, description and image thumbnail)', 'siteseo') .'</li>
<li>'. esc_html__('Twitter tags (title, description and image thumbnail)', 'siteseo') .'</li>
<li>'. esc_html__('Meta Robots (noindex, nofollow...)', 'siteseo') .'</li>
<li>'.esc_html__('Canonical URL', 'siteseo').'</li>';
if($plugin !='slim-seo' && $plugin != 'surerank'){
echo '<li>'. esc_html__('Focus / target keywords', 'siteseo') .'<li>';
}
if($plugin != 'all-in-one-seo-pack' && $plugin !='slim-seo' && $plugin != 'surerank'){
echo '<li>'. esc_html__('Primary category', 'siteseo') .'</li>';
}
if('autodescription' == $plugin || 'all-in-one-seo-pack' == $plugin || 'wp-seopress' == $plugin){
echo '<li>'. esc_html__('Redirect URL', 'siteseo') .'</li>';
}
echo '</ul>
<div class="siteseo_wrap_label">
<div class="siteseo-notice is-warning">
<span id="dashicons-warning" class="dashicons dashicons-warning"></span>
<p>'.
/* translators: %s represents the degree of severity */
wp_kses_post(sprintf(__('<strong>WARNING:</strong> Migration will delete / update all <strong>%1$s posts and terms metadata</strong>. Some dynamic variables will not be interpreted. We do <strong>NOT delete any %2$s data</strong>.', 'siteseo'), esc_html($seo_title), esc_html($name))). '
</p>
</div>
</div>
<button id="siteseo-'.esc_attr($plugin).'-migrate" type="button" class="btn btnSecondary">'
. esc_html__('Import now', 'siteseo').'</button><span class="spinner"></span><div class="log"></div>
</div>
</div>';
}
}
settings/util.php 0000644 00000006662 15152641524 0010111 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Util{
static function clean_text($text){
return sanitize_text_field(wp_unslash($text));
}
static function clean_url($url){
if(is_array($url)){
return map_deep(wp_unslash($url), 'sanitize_url');
}
return sanitize_url(wp_unslash($url));
}
static function render_toggle($title, $toggle_key, $toggle_state, $nonce, $label = false){
$is_active = $toggle_state ? 'active' : '';
$state_text = $toggle_state ? 'Disable' : 'Enable';
// for dashbord screen
if(!empty($label)){
echo '<div class="siteseo-toggle-cnt">
<div class="siteseo-toggle-Sw '.esc_attr($is_active).'" id="siteseo-toggleSw-' . esc_attr($toggle_key) . '" data-nonce="'.esc_attr($nonce).'" data-toggle-key="'.esc_attr($toggle_key).'" data-action="siteseo_save_'.esc_attr($toggle_key).'"></div>
<input type="hidden" name="siteseo_options['.esc_attr($toggle_key) . ']" id="'.esc_attr($toggle_key).'" value="'.esc_attr($toggle_state).'">
</div>';
}else{
echo '<div class="siteseo-toggle-cnt">
<span id="siteseo-tab-title"><strong>'.esc_html($title).'</strong></span>
<div class="siteseo-toggle-Sw '.esc_attr($is_active).'" id="siteseo-toggleSw-'.esc_attr($toggle_key).'" data-nonce="' . esc_attr($nonce) . '" data-toggle-key="'.esc_attr($toggle_key).'" data-action="siteseo_save_'.esc_attr($toggle_key).'"></div>
<span id="siteseo-arrow-icon" class="dashicons dashicons-arrow-left-alt siteseo-arrow-icon"></span>
<p class="toggle_state_'.esc_attr($toggle_key).'">'.esc_html($state_text).'</p>
<input type="hidden" name="siteseo_options['.esc_attr($toggle_key).']" id="'.esc_attr($toggle_key).'" value="'.esc_attr($toggle_state).'">
</div>';
}
}
static function admin_header(){
echo '<div class="siteseo-navbar">
<div class="logo">
<img alt="'.esc_html__('siteseo logo', 'siteseo').'" height="30" src="'. esc_url(SITESEO_ASSETS_URL).'/img/logo-24.svg'.'" width="40"/>
<div class="siteseo-breadcrumb">
<a href="#">'.esc_html__('Home', 'siteseo').'</a>
<span>/</span>
<a class="active" href="">'.esc_html(get_admin_page_title()).'</a>
</div>
</div>';
echo'<div class="links">
<span class="siteseo-header-version-badge">v'.esc_html(SITESEO_VERSION).'</span>
<a target="_blank" href="https://siteseo.io/docs/">'.esc_html__('Docs', 'siteseo').'</a>';
if(!defined('SITEPAD')){
echo'<a target="_blank" class="support" href="https://softaculous.deskuss.com/open.php?topicId=22">'.esc_html__('Support', 'siteseo').'</a>';
}
echo'</div>
</div>';
}
static function importable_plugins(){
return [
'wordpress-seo/wp-seo.php' => 'Yoast SEO',
'all-in-one-seo-pack/all_in_one_seo_pack.php' => 'All In One SEO',
'autodescription/autodescription.php' => 'The SEO Framework',
'seo-by-rank-math/rank-math.php' => 'Rank Math',
'wp-seopress/seopress.php' => 'SEOPress',
'slim-seo/slim-seo.php' => 'Slim SEO',
'surerank/surerank.php' => 'Surerank'
];
}
static function submit_btn($value = ''){
echo '<div class="siteseo-submit-button"><input type="submit" id="submit" name="submit" value="'.esc_attr($value ?: 'Save changes') . '" class="submit-button"></div>';
}
static function extract_content($input){
if(preg_match('/content=["\']([^"\']+)["\']/', $input, $matches)){
return $matches[1];
}
return $input;
}
} settings/onboarding.php 0000644 00000047771 15152641524 0011264 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class OnBoarding{
static $current_step = '';
static $import_options = [];
static $steps = [];
static $current_step_no = 1;
static function init(){
if(wp_doing_ajax()){
return;
}
self::$steps = [
'your-site' => [
'title' => 'Your Site',
'desc' => 'Your site and social data',
'fn' => '\SiteSEO\Settings\OnBoarding::site_page',
],
'indexing' => [
'title' => 'Indexing',
'desc' => 'Select post type indexing',
'fn' => '\SiteSEO\Settings\OnBoarding::indexing_page',
],
'advanced' => [
'title' => 'Advanced',
'desc' => 'URL configuration',
'fn' => '\SiteSEO\Settings\OnBoarding::advanced_page',
],
'ready' => [
'title' => 'Ready',
'desc' => 'All set now!',
'fn' => '\SiteSEO\Settings\OnBoarding::ready_page',
],
];
$active_plugins = get_option('active_plugins', []);
$importable_plugins = Util::importable_plugins();
$importable_plugins = array_keys($importable_plugins);
$importable_found = array_intersect($active_plugins, $importable_plugins);
if(!empty($importable_found)){
$import_step = [
'import' => [
'title' => 'Import',
'desc' => 'Importing meta data',
'fn' => '\SiteSEO\Settings\OnBoarding::import_page',
]
];
self::$steps = array_merge($import_step, self::$steps);
self::$import_options = $importable_found;
}
self::$current_step = !empty($_REQUEST['step']) ? sanitize_text_field(wp_unslash($_REQUEST['step'])) : '';
remove_all_actions('admin_notices');
remove_all_actions('all_admin_notices');
remove_all_actions('network_admin_notices');
add_action('admin_menu', '\SiteSEO\Settings\OnBoarding::add_to_menu');
add_action('admin_init', '\SiteSEO\Settings\OnBoarding::page');
}
static function enqueue_assets(){
wp_enqueue_media();
wp_enqueue_script('siteseo-onboarding', SITESEO_ASSETS_URL . '/js/onboarding.js', ['jquery'], SITESEO_VERSION, true);
wp_enqueue_style('siteseo-onboarding' , SITESEO_ASSETS_URL . '/css/onboarding.css', [], SITESEO_VERSION);
wp_add_inline_script('siteseo-onboarding', "let siteseo_onboarding = ".wp_json_encode([
'nonce' => wp_create_nonce('siteseo_admin_nonce'),
'ajax_url' => admin_url('admin-ajax.php'),
]));
}
static function add_to_menu(){
add_submenu_page('', __('SiteSEO Onboarding', 'siteseo'), 'Onboarding', 'manage_options', 'siteseo-onboarding', 'SiteSEO\Settings\Onboarding::wizard');
}
static function page(){
self::enqueue_assets();
ob_start();
?><!DOCTYPE html>
<html <?php language_attributes();?>>
<?php echo'<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>'.esc_html__('SiteSEO OnBoarding', 'siteseo').'</title>';
wp_print_head_scripts();
wp_print_styles('siteseo-onboarding');
echo '</head>
<body>';
self::wizard();
if(function_exists('wp_print_media_templates')){
wp_print_media_templates();
}
wp_print_footer_scripts();
wp_print_scripts('siteseo-onboarding');
echo '</body>
</html>';
die();
}
static function wizard(){
echo '<div id="siteseo-onboarding-root">
<div class="siteseo-onboarding-nav-wrapper">
<nav>
<div class="content">
<div class="header">
<img src="'.esc_url(SITESEO_ASSETS_URL) .'/img/siteseo-white.png" height="40"/>
<a href="'.esc_url(admin_url('?page=siteseo')).'" title="'.esc_attr__('Exit to SiteSEO Dashboard', 'siteseo').'"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#fff"><path d="M200-120q-33 0-56.5-23.5T120-200v-160h80v160h560v-560H200v160h-80v-160q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm220-160-56-58 102-102H120v-80h346L364-622l56-58 200 200-200 200Z"/></svg></a>
</div>';
$step_count = 1;
echo '<div class="steps">';
foreach(self::$steps as $step_slug => $step){
echo '<div class="step">
<div class="step-milestone" data-step="'.esc_attr($step_count).'" data-step-slug="'.esc_attr($step_slug).'"></div>
<div class="step-info"><span>'.esc_html($step['title']).'</span><span class="description">'.esc_html($step['desc']).'</span></div>
</div>';
$step_count++;
}
echo '
</div>
</div>
<div class="footer">A Softaculous Product</div>
</nav>
</div>
<main>
<div class="siteseo-onboarding-content">';
self::welcome_page();
foreach(self::$steps as $step){
call_user_func($step['fn']);
self::$current_step_no++; // increasing the step number after we have rendered the step page.
}
echo '</div>
</main>
</div>';
}
static function welcome_page(){
$is_active = empty(self::$current_step) ? 'siteseo-step-active' : '';
echo '<div class="siteseo-step-page siteseo-step-is-welcome '.esc_attr($is_active).'" data-step="welcome">
<h1>'.esc_html__('Welcome to the SiteSEO Setup Wizard', 'siteseo').'</h1>
<p>'.esc_html__('This wizard will guide you through setting up SiteSEO and help you get started in no time.', 'siteseo').'</p>
<button class="siteseo-btn primary" id="siteseo-onboarding-begin" style="margin-top:20px">'.esc_html__('Let\'s begin!', 'siteseo').'</button>
</div>';
}
static function import_page(){
$is_active = !empty(self::$current_step) && self::$current_step == 'import' ? 'siteseo-step-active' : '';
echo '<div class="siteseo-step-page '.esc_attr($is_active).'" data-step="import">
<span>Step '.esc_html(self::$current_step_no).' of '.count(self::$steps).'</span>
<h1>'.esc_html__('Import data from your current SEO plugin', 'siteseo').'</h1>
<p>'.esc_html__('SiteSEO has detected the presence of other SEO plugins. To ensure a smooth transition, please select the plugins you wish to import SEO data from', 'siteseo').'</p>
<div class="siteseo-onboarding-import-plugins">';
$importable_plugins = Util::importable_plugins();
echo '<form><div class="siteseo-radio-input">';
foreach(self::$import_options as $plugin){
$id = strtolower(str_replace(' ', '-', $plugin));
echo '<input type="radio" name="plugin_name" value="'.esc_attr($id).'" id="'.esc_attr($id).'"/>
<label for="'.esc_attr($id).'">'.esc_html($importable_plugins[$plugin]).'</label>';
}
echo '</div>
<div class="siteseo-onboarding-import-info">
<details>
<summary>'.esc_html__('What will be imported?', 'siteseo').'</summary>
<ul>
<li>'. esc_html__('Title tags', 'siteseo') .'</li>
<li>'. esc_html__('Meta description', 'siteseo') .'</li>
<li>'. esc_html__('Facebook Open Graph tags (title, description and image thumbnail)', 'siteseo') .'</li>
<li>'. esc_html__('Twitter tags (title, description and image thumbnail)', 'siteseo') .'</li>
<li>'. esc_html__('Meta Robots (noindex, nofollow...)', 'siteseo') .'</li>
<li>'. esc_html__('Canonical URL', 'siteseo').'</li>
<li>'. esc_html__('Focus / target keywords', 'siteseo') .'</li>
</ul>
</details>
<button class="siteseo-btn primary" id="siteseo-do-import">Import</button>
<p class="siteseo-onboarding-msg"></p>
</div>
</form>
<div class="siteseo-onboarding-content-footer">
<button class="siteseo-skip-step siteseo-btn secondary">'.esc_html__('Skip Step', 'siteseo').'</button><button class="siteseo-btn primary siteseo-skip-step">'.esc_html__('Next Step', 'siteseo').'</button>
</div>
</div>
</div>';
}
static function site_page(){
$title_options = get_option('siteseo_titles_option_name', []);
$social_options = get_option('siteseo_social_option_name', []);
$site_name = !empty($title_options['titles_home_site_title']) ? $title_options['titles_home_site_title'] : '%%sitetitle%%';
$alt_site_name = !empty($title_options['titles_home_site_title_alt']) ? $title_options['titles_home_site_title_alt'] : '';
$site_type = !empty($social_options['social_knowledge_type']) ? $social_options['social_knowledge_type'] : '';
$org_name = !empty($social_options['social_knowledge_name']) ? $social_options['social_knowledge_name'] : '';
$org_img = !empty($social_options['social_knowledge_img']) ? $social_options['social_knowledge_img'] : '';
$fb_url = !empty($social_options['social_accounts_facebook']) ? $social_options['social_accounts_facebook'] : '';
$x_account = !empty($social_options['social_accounts_twitter']) ? $social_options['social_accounts_twitter'] : '';
$additional_url = !empty($social_options['social_accounts_additional']) ? implode("\n", $social_options['social_accounts_additional']) : '';
$is_active = !empty(self::$current_step) && self::$current_step == 'your-site' ? 'siteseo-step-active' : '';
echo '<div class="siteseo-step-page '.esc_attr($is_active).'" data-step="your-site">
<span>Step '.esc_html(self::$current_step_no).' of '.count(self::$steps).'</span>
<h1>Your Site: '.esc_html(get_bloginfo('name')).'</h1>
<p>'.esc_html__('We need some basic information about your site, so we can built up the knowledge graph', 'siteseo').'</p>
<form>
<div class="siteseo-input-block">
<label>'.esc_html__('Website Name', 'siteseo').'</label>
<input type="text" name="website_name" value="'.esc_attr($site_name).'"/>
<p class="siteseo-input-description">'.esc_html__('Enter the name of your site as it should appear in search results, %%sitetitle%% is a dynamic variable for your site title', 'siteseo').'</p>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Altername sitename', 'siteseo').'</label>
<input type="text" name="alternate_site_name" value="'.esc_attr($alt_site_name).'" placeholder="Alternate site name"/>
<p class="siteseo-input-description">'.esc_html__('The website\'s alternate name, like a common acronym or shorter version, if applicable.', 'siteseo').'</p>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Is your site about an Organization or a Person?', 'siteseo').'</label>
<select type="text" name="site_type">
<option value="Person" '.selected($site_type, 'Person', false).'>Person</option>
<option value="Organization" '.selected($site_type, 'Organization', false).'>Organization</option>
</select>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Your/Organization name', 'siteseo').'</label>
<input type="text" name="organization_name" placeholder="eg:. My Company Name" value="'.esc_attr($org_name).'"/>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Organization Logo', 'siteseo').'</label>
<button id="siteseo-onboarding-img-holder">
<img src="'.esc_url($org_img).'"/>
<svg xmlns="http://www.w3.org/2000/svg" height="50px" viewBox="0 -960 960 960" width="50px" fill="#5f6368" style="'.(!empty($org_img) ? 'display:none;' : '').'"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z"/></svg></button>
<p class="siteseo-input-description">'.esc_html__('A square image is preferred, with a minimum size of 112x112 pixels.', 'siteseo').'</p>
<input type="hidden" name="organization_logo" value="'.esc_url($org_img).'"/>
<button class="siteseo-btn primary" id="siteseo-upload-org-img" style="align-self:flex-start">'.esc_html__('Select Image', 'siteseo').'</button>
</div>
<h4>Social Details</h4>
<div class="siteseo-input-block">
<label>'.esc_html__('Facebook page URL', 'siteseo').'</label>
<input type="text" name="social_fb" value="'.esc_url($fb_url).'" placeholder="eg: https://facebook.com/my-page-url"/>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('X Username', 'siteseo').'</label>
<input type="text" name="social_x" value="'.esc_attr($x_account).'" placeholder="eg: @x_account"/>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Additional Accounts', 'siteseo').'</label>
<textarea rows="3" name="social_additional" placeholder="eg:https://somesocial.com/my-page">'.esc_textarea($additional_url).'</textarea>
<p class="siteseo-input-description">'.esc_html__('Enter 1 URL per line.', 'siteseo').'</p>
</div>
<div class="siteseo-onboarding-content-footer">
<button class="siteseo-skip-step siteseo-btn secondary">'.esc_html__('Skip Step', 'siteseo').'</button><button class="siteseo-btn primary siteseo-save-n-continue">'.esc_html__('Save and Continue', 'siteseo').'<span class="siteseo-spinner"></span></button>
</div>
</form>
</div>';
}
static function indexing_page(){
$is_active = !empty(self::$current_step) && self::$current_step == 'indexing' ? 'siteseo-step-active' : '';
$post_types = get_post_types(['public' => true, 'show_ui' => true], 'objects', 'and');
unset($post_types['attachment']);
$taxonomies = get_taxonomies(['public' => true, 'show_ui' => true], 'objects', 'and');
echo '<div class="siteseo-step-page '.esc_attr($is_active).'" data-step="indexing">
<span>Step '.esc_html(self::$current_step_no).' of '.count(self::$steps).'</span>
<h1>Indexing</h1>
<p>'.esc_html__('Let us know which parts of your website you’d like to be crawled.', 'siteseo').'</p>
<form method="POST">
<div class="siteseo-input-block">
<label>'.esc_html__('Is your site under construction or live?', 'siteseo').'</label>
<div class="siteseo-radiogroup">
<label><input type="radio" name="site_status" value="underconstruction"/>Under Construction</label>
<label><input type="radio" name="site_status" value="live" checked/>Live</label>
</div>
<p class="siteseo-input-description">'.esc_html__('If your site is under construction then Search Engines will be discouraged to crawl your site by adding noindex metatag attribute and sitemap will be disabled.', 'siteseo').'</p>
</div>
<div class="siteseo-live-site-options" style="margin-top:35px;">
<p>'.esc_html__('Choose items to exclude from search results', 'siteseo').'</p>
<div class="siteseo-input-block">
<label>'.esc_html__('Post Types', 'siteseo').'</label>
<div class="siteseo-radiogroup">';
if(!empty($post_types)){
foreach($post_types as $post){
echo '<div><input type="checkbox" name="post_types" value="'.esc_attr($post->name).'" id="post_type_'.esc_attr($post->name).'"/>
<label for="post_type_'.esc_attr($post->name).'">'.esc_html($post->label).'</label>
</div>';
}
echo '<p class="siteseo-input-description">'.esc_html__('Discourage search engines from indexing these post types.', 'siteseo').'</p>';
} else {
echo '<p class="siteseo-input-description">'.esc_html__('No post type found.', 'siteseo').'</p>';
}
//TODO:: Will need to add options for Archive as well
echo '</div>
</div>
<div class="siteseo-input-block">
<label>'.esc_html__('Taxonomies', 'siteseo').'</label>
<div class="siteseo-radiogroup">';
if(!empty($taxonomies)){
foreach($taxonomies as $taxonomy){
echo '<div><input type="checkbox" name="taxonomies" value="'.esc_attr($taxonomy->name).'" id="taxonomy_'.esc_attr($taxonomy->name).'"/>
<label for="taxonomy_'.esc_attr($taxonomy->name).'">'.esc_html($taxonomy->label).'</label>
</div>';
}
echo '<p class="siteseo-input-description">'.esc_html__('Discourage search engines from indexing these taxonomies.', 'siteseo').'</p>
<p class="siteseo-input-description">'.esc_html__('Note: We strongly recommend disabling the indexing of tags to avoid potential duplicate content issues that could negatively impact your site\'s SEO.', 'siteseo').'</p>';
} else {
echo '<p class="siteseo-input-description">'.esc_html__('No taxonomy found.', 'siteseo').'</p>';
}
echo '</div>
</div>
</div>
<div class="siteseo-onboarding-content-footer">
<button class="siteseo-skip-step siteseo-btn secondary">'.esc_html__('Skip Step', 'siteseo').'</button><button class="siteseo-btn primary siteseo-save-n-continue">'.esc_html__('Save and Continue', 'siteseo').'<span class="siteseo-spinner"></span></button>
</div>
</form>
</div>';
}
static function advanced_page(){
$is_active = !empty(self::$current_step) && self::$current_step == 'advanced' ? 'siteseo-step-active' : '';
echo '<div class="siteseo-step-page '.esc_attr($is_active).'" data-step="advanced">
<span>Step '.esc_html(self::$current_step_no).' of '.count(self::$steps).'</span>
<h1>Advanced Options</h1>
<p>'.esc_html__('We\'re nearly there—just a few final optimizations left!', 'siteseo').'</p>
<form method="POST">
<div class="siteseo-input-block">
<div class="siteseo-radiogroup">
<label><input type="checkbox" name="universal_metabox" checked/>Enable Universal Metabox</label>
</div>
<p class="siteseo-input-description">'.esc_html__('Universal metabox makes SiteSEO on page content SEO helper compatible with every Page Builder, so if you are not using Gutenberg then this is a must.', 'siteseo').'</p>
</div>
<div class="siteseo-input-block">
<div class="siteseo-radiogroup">
<label><input type="checkbox" name="author_noindex"/>'.esc_html__('Don\'t let search engines index author archive pages', 'siteseo').'</label>
</div>
<p class="siteseo-input-description">'.esc_html__('Recommended: Enable this option if you are the sole author of the site to prevent duplicate content on author archive pages.', 'siteseo').'</p>
</div>
<div class="siteseo-input-block">
<div class="siteseo-radiogroup">
<label><input type="checkbox" name="redirect_attachment"/>'.esc_html__('Redirect attachment pages to the file itself', 'siteseo').'</label>
</div>
<p class="siteseo-input-description">'.esc_html__('By default SiteSEO redirects to the parent post.', 'siteseo').'</p>
</div>
<div class="siteseo-input-block">
<div class="siteseo-radiogroup">
<label><input type="checkbox" name="category_url"/>'.esc_html__('Remove /category/ in your permalinks', 'siteseo').'</label>
</div>
<p class="siteseo-input-description">'.esc_html__('This reduces the length of the URL.', 'siteseo').'</p>
</div>';
do_action('siteseo_gsc_onboarding');
echo '<div class="siteseo-onboarding-content-footer">
<button class="siteseo-skip-step siteseo-btn secondary">'.esc_html__('Skip Step', 'siteseo').'</button><button class="siteseo-btn primary siteseo-save-n-continue">'.esc_html__('Save and Continue', 'siteseo').'<span class="siteseo-spinner"></span></button>
</div>
</form>
</div>';
}
static function ready_page(){
$is_active = !empty(self::$current_step) && self::$current_step == 'ready' ? 'siteseo-step-active' : '';
echo '<div class="siteseo-step-page '.esc_attr($is_active).'" data-step="ready">
<span>Step '.esc_html(self::$current_step_no).' of '.count(self::$steps).'</span>
<h1>Done! 🎉</h1>
<p>'.esc_html__('We are done with the setup, now you can start making content and submit the Sitemap to the search engines.', 'siteseo').'</p>
<h4>'.esc_html__('What Next?', 'siteseo').'</h4>
<ol style="margin:0">
<li><a href="?page=siteseo-sitemaps" target="_blank">'.esc_html__('Configure your Sitemap', 'siteseo').'</a></li>
<li>'.esc_html__('Submit yours sitemap to search engines', 'siteseo').'</li>
</ol>
<h4>'.esc_html__('You can also, subscribe to our newletter', 'siteseo').'</h4>
'.esc_html__('You will get', 'siteseo').'
<ul style="list-style-type:none">
<li><span class="dashicons dashicons-minus"></span> '.esc_html__('Alerted about Google Algorithm changes.', 'siteseo').'</li>
<li><span class="dashicons dashicons-minus"></span> '.esc_html__('Updates about our products.', 'siteseo').'</li>
<li><span class="dashicons dashicons-minus"></span> '.esc_html__('Improve SEO of your website with our resourceful blogs.', 'siteseo').'</li>
</ul>
<a class="siteseo-btn secondary" href="https://siteseo.io/subscribe/" style="align-self:flex-start;" target="_blank">'.esc_html__('Subscribe', 'siteseo').'</a>
<div class="siteseo-onboarding-content-footer">
<a href="'.esc_url(admin_url()).'"class="siteseo-btn primary">Go to Dashboard</a>
<a href="?page=siteseo"class="siteseo-btn primary">Review Settings</a>
<a href="https://siteseo.io/docs/" class="siteseo-btn primary" target="_blank">Knowledge Base</a>
</div>
</div>';
}
}
settings/instant.php 0000644 00000034275 15152641524 0010615 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Instant{
static function menu(){
global $siteseo;
$indexing_toggle = isset($siteseo->setting_enabled['toggle-instant-indexing']) ? $siteseo->setting_enabled['toggle-instant-indexing'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_siteseo_general';
$instant_subtabs = [
'tab_siteseo_general' => esc_html__('General', 'siteseo'),
'tab_siteseo_settings' => esc_html__('Settings', 'siteseo'),
'tab_siteseo_history' => esc_html__('History', 'siteseo'),
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_instant_indexing');
Util::render_toggle('Instant Indexing - SiteSEO', 'indexing_toggle', $indexing_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($instant_subtabs as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="'.esc_attr($tab_key).'-tab" class="siteseo-nav-tab'.esc_attr($active_class).'" data-tab="'.esc_attr($tab_key).'">'.esc_html($tab_caption).'</a>';
}
echo '</div>
<div class"tab-content-wrapper">
<div class="siteseo-tab'.($current_tab == 'tab_siteseo_general' ? ' active' : '').'" id="tab_siteseo_general" style="display: none;">';
self::general();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_siteseo_settings' ? ' active' : '').'" id="tab_siteseo_settings" style="display: none;">';
self::settings();
echo '</div>
<div class="siteseo-tab'.($current_tab == 'tab_siteseo_history' ? 'active' : '').'" id="tab_siteseo_history" style="display : none;">';
self::history();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function general(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_instant_indexing_option_name');
//$options = $siteseo->instant_settings;
$option_engines = !empty($options['engines']) ? $options['engines'] : '';
$option_search_engine_google = !empty($option_engines['google']) ? $option_engines['google'] : '';
$option_search_engine_bing = !empty($option_engines['bing']) ? $option_engines['bing'] : '';
$option_action = !empty($options['instant_indexing_google_action']) ? $options['instant_indexing_google_action'] : '';
$option_manual_batch = !empty($options['instant_indexing_manual_batch']) ? $options['instant_indexing_manual_batch'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Instant Indexing','siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Utilize the Indexing API to inform Google and Bing about updates or removals of pages from their indexes. The process may take a few minutes. You can submit URLs in batches of up to 100 (maximum 200 requests per day for Google).','siteseo').'</p>
</div>
<div class="siteseo-notice">
<span class="dashicons dashicons-info"></span>
<div><h3>'.esc_html__('How does this work?', 'siteseo').'</h3>
<ol>
<li>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('Setup your Google / Bing API keys from the %1$s Settings %2$s tab', 'siteseo'), '<strong>', '</strong>')).'</li>
<li>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('%1$s Enter the URLs %2$s you want to index in the field below.', 'siteseo'), '<strong>', '</strong>')).'</li>
<li><strong>'.wp_kses_post(__('Save changes', 'siteseo')).'</strong></li>
<li>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('Click %1$s Submit URLs to Google & Bing %2$s', 'siteseo'), '<strong>', '</strong>')).'</li>
</ol>
</div>
</div>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('select search engines','siteseo').'</th>
<td>
<div class="siteseo_wrap_label"><label for="siteseo_search_engines">
<input id="siteseo_search_engines" name="siteseo_options[search_engine_google]" type="checkbox"' . (!empty($option_search_engine_google) ? 'checked="yes"' : '') . ' value="1"/>'.esc_html__('Google', 'siteseo') .
'</label></div>
<label for="siteseo_search_engines">
<input id="siteseo_search_engines" name="siteseo_options[search_engine_bing]" type="checkbox"' . (!empty($option_search_engine_bing) ? 'checked="yes"' : '') . ' value="1"/>'.esc_html__('Bing', 'siteseo') .
'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Which action to run for Google?', 'siteseo') .'</th>
<td>
<div class="siteseo_wrap_label">
<label>
<input id="siteseo_update_urls" name="siteseo_options[instant_indexing_actions]" type="radio" value="update_urls" '.checked($option_action, 'update_urls', false).'/>
'.esc_html__('Update URLs', 'siteseo').'
</label>
</div>
<div class="siteseo_wrap_label">
<label>
<input id="siteseo_remove_urls" name="siteseo_options[instant_indexing_actions]" type="radio" value="remove_urls" '.checked($option_action, 'remove_urls', false).'/>
'.esc_html__('Remove URLs (the URL must return a 404 or 410 status code, or the page must include the <meta name="robots" content="noindex" /> meta tag).', 'siteseo').'
</label>
</div>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Submit URLs for indexing','siteseo').'</th>
<td>
<textarea rows="20" name="siteseo_options[instant_indexing_batch]" placeholder="'.esc_html__('Submit one URL per line for search engine submission (maximum of 100 URLs).','siteseo').'">'.esc_attr($option_manual_batch).'</textarea>
</td>
</tr>
<tr>
<th scope="row"></th>
<td>
<button id="siteseo-submit-urls-button" class="btn btnSecondary">'.esc_html__('Submits URLs to Google & Bing', 'siteseo').'</button>
</td><div style="position:absolute;margin-top:52.5%;margin-left:38%;" class="spinner"></div>
</tr>
<tr>
<th scope="row"></th>
<td>
<div id="url-submitter-response"></div>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[general]" value="1"/>';
}
static function settings(){
global $siteseo,$docs;
if(!empty($_POST['submit'])){
self::save_settings();
}
$docs['instant_indexing']['api'] = 'https://console.cloud.google.com/apis/library/indexing.googleapis.com?hl=en';
$docs['instant_indexing']['google'] = 'https://siteseo.io/docs/api-cli-dev/use-google-instant-indexing-api-with-siteseo-pro/';
//$options = $siteseo->instant_settings;
$options = get_option('siteseo_instant_indexing_option_name');
$option_google_api_key = !empty($options['instant_indexing_google_api_key']) ? $options['instant_indexing_google_api_key'] : '';
$option_bing_api_key = !empty($options['instant_indexing_bing_api_key']) ? $options['instant_indexing_bing_api_key'] : '';
$option_auto_url_submission = !empty($options['instant_indexing_automate_submission']) ? $options['instant_indexing_automate_submission'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Settings','siteseo').'</h3>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Instant Indexing Google API Key','siteseo').'</th>
<td>
<textarea name="siteseo_options[google_api_key]" rows="12" placeholder="'.esc_html__('Paste your Google Json key file here','siteseo').'">'.esc_html($option_google_api_key).'</textarea>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Instant Indexing Bing API Key', 'siteseo').'</th>
<td>
<input type="text" id="bing-api-key" name="siteseo_options[bing_api_key]" placeholder="'.esc_html__('Enter your Bing Instant Indexing API', 'siteseo').'" value="'.esc_attr($option_bing_api_key).'">
<button type="button" id="siteseo-generate-api-key-btn" class="btn btnSecondary">'.esc_html__('Generate key', 'siteseo').'</button>
<p class="description">'.esc_html__('The Bing Indexing API key is generated automatically. Click Generate Key if you need to recreate it or if it missing.', 'siteseo') .'</p>
<p class="description">'.esc_html__('A key should look like this: YjI4MGQxZmU0NWM1NGY2ZGIxMDk5M2VlYTAxMTUyODI=', 'siteseo') .'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Automate URL Submission','siteseo').'</th>
<td>
<label for="siteseo_search_engines">
<input id="siteseo_search_engines" name="siteseo_options[auto_submission]" type="checkbox"'.(!empty($option_auto_url_submission) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Activate automatic URL submission for the IndexNow API.', 'siteseo') .
'</label>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Inform search engines via the IndexNow protocol whenever a post is created, updated, or removed.','siteseo').'</p>
</div>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[setting_tab]" value="1"/>';
}
static function history(){
global $siteseo;
$options = get_option('siteseo_instant_indexing_option_name');
$indexing_history = !empty($options['indexing_history']) ? $options['indexing_history'] : '';
echo'<h3 class="siteseo-tabs">'.esc_html__('History', 'siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Most Recent 10 Indexing API Requests.', 'siteseo').'</p>
</div>
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead><tr>
<th>'.esc_html__('Time & Date', 'siteseo').'</th>
<th>'.esc_html__('URLs', 'siteseo').'</th>
<th>'.esc_html__('Google Response', 'siteseo').'</th>
<th>'.esc_html__('Bing Response', 'siteseo').'</th>
</tr></thead>
<tbody>';
if(empty($indexing_history)){
echo'<tr>
<td>'.esc_html__('No submissions yet.', 'siteseo').'</td>
</tr></tbody></table><br/><br/>';
return;
}
foreach($indexing_history as $history){
echo'<tr>
<td>'.esc_html(date_i18n('Y-m-d H:i:s', $history['time'])).'</td>
<td>'.esc_html(implode(', ', $history['urls'])).'</td>
<td>'.(isset($history['google_status_code']) ? esc_html($history['google_status_code']) : 'N/A') . (isset($history['source']) && $history['source'] === 'auto' ? esc_html(' ( Auto )') : '') .'</td>
<td>'.(isset($history['bing_status_code']) ? esc_html($history['bing_status_code']) : 'N/A') . (isset($history['source']) && $history['source'] === 'auto' ? esc_html(' ( Auto )') : '') .
'</td>
</tr>';
}
echo'</tr>
</tbody></table><br/>
<tr>
<td>
<button id="siteseo-clear-history" class="btn btnSecondary">'.esc_html__('Clean History', 'siteseo').'</button>
</td>
</tr><br/><br/>
<a class="siteseo-show-details">'.esc_html__('Response code guide', 'siteseo').'<span class="dash-icon dashicons dashicons-arrow-down-alt2"></span></a>
<div class="siteseo-response-code-table">
<table class="wp-list-table widefat fixed striped siteseo-history-table">
<thead>
<tr>
<th>'.esc_html__('Response Code', 'siteseo').'</th>
<th>'.esc_html__('Response Message', 'siteseo').'</th>
<th>'.esc_html__('Reason', 'siteseo').'</th>
</tr>
</thead>
<tr>
<td>'.esc_html__('200', 'siteseo').'</td>
<td>'.esc_html__('Ok', 'siteseo').'</td>
<td>'.esc_html__('URLs submitted successfully.', 'siteseo').'</td>
</tr>
<tr>
<td>'.esc_html__('202', 'siteseo').'</td>
<td>'.esc_html__('Accepted', 'siteseo').'</td>
<td>'.esc_html__('URL received. IndexNow key validation pending.', 'siteseo').'</td>
</tr>
<tr>
<td>'.esc_html__('400', 'siteseo').'</td>
<td>'.esc_html__('Bad Request', 'siteseo').'</td>
<td>'.esc_html__('Request Invalid format.', 'siteseo').'</td>
</tr>
<tr>
<td>'.esc_html__('403', 'siteseo').'</td>
<td>'.esc_html__('Forbidden', 'siteseo').'</td>
<td>'.esc_html__('Key not valid.', 'siteseo').'</td>
</tr>
<tr>
<td>'.esc_html__('422', 'siteseo').'</td>
<td>'.esc_html__('Unprocessable Entity', 'siteseo').'</td>
<td>'.esc_html__('URLs don\'t belong to the host.', 'siteseo').'</td>
</tr>
<tr>
<td>'.esc_html__('429', 'siteseo').'</td>
<td>'.esc_html__('Too Many Requests', 'siteseo').'</td>
<td>'.esc_html__('Too Many Requests: Potential Spam.', 'siteseo').'</td>
</tr>
<tbody>
</table></div><br/><br/>';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_instant_indexing');
if(!siteseo_user_can('manage_instant_indexing')|| !is_admin()){
return;
}
$options = $siteseo->instant_settings;
if(!is_array($options)){
$options = [];
}
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['general'])){
// general tab
$options['engines']['bing'] = isset($_POST['siteseo_options']['search_engine_bing']);
$options['engines']['google'] = isset($_POST['siteseo_options']['search_engine_google']);
$options['instant_indexing_google_action'] = isset($_POST['siteseo_options']['instant_indexing_actions']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['instant_indexing_actions'])) : 'URL_UPDATED';
$options['instant_indexing_manual_batch'] = isset($_POST['siteseo_options']['instant_indexing_batch']) ? sanitize_textarea_field(wp_unslash($_POST['siteseo_options']['instant_indexing_batch'])) : '';
}
if(isset($_POST['siteseo_options']['setting_tab'])){
// setting tab
$options['instant_indexing_google_api_key'] = isset($_POST['siteseo_options']['google_api_key']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['google_api_key'])) : '';
$options['instant_indexing_bing_api_key'] = isset($_POST['siteseo_options']['bing_api_key']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['bing_api_key'])) : '';
$options['instant_indexing_automate_submission'] = isset($_POST['siteseo_options']['auto_submission']);
}
update_option('siteseo_instant_indexing_option_name', $options);
}
}
settings/sitemap.php 0000644 00000047232 15152641524 0010574 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Sitemap{
static function menu(){
global $siteseo;
$sitemap_toggle = isset($siteseo->setting_enabled['toggle-xml-sitemap']) ? $siteseo->setting_enabled['toggle-xml-sitemap'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_sitemap_general'; // Default tab
$titles_meta_subtabs = [
'tab_sitemap_general' => esc_html__('Home', 'siteseo'),
'tab_sitemap_post_types' => esc_html__('Post types', 'siteseo'),
'tab_sitemap_taxonomy ' => esc_html__('Taxonomy', 'siteseo'),
'tab_sitmap_html' => esc_html__('HTML Sitemap', 'siteseo')
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_sitemap_settings');
Util::render_toggle('Sitemaps - SiteSEO', 'sitemap_toggle', $sitemap_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($titles_meta_subtabs as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="' . esc_attr($tab_key) . '-tab" class="siteseo-nav-tab' . esc_attr($active_class) . '" data-tab="' . esc_attr($tab_key) . '">' . esc_html($tab_caption) . '</a>';
}
echo '</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab' .($current_tab == 'tab_sitemap_general' ? ' active' : '').'" id="tab_sitemap_general" style="display: none;">';
self::general_sitemaps();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_sitemap_post_types' ? ' active' : '').'" id="tab_sitemap_post_types" style="display: none;">';
self::post_types_sitemaps();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_sitemap_taxonomy' ? ' active' : '').'" id="tab_sitemap_taxonomy" style="display: none;">';
self::taxonomy_sitemap();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_sitmap_html' ? ' active' : '').'" id="tab_sitmap_html" style="display: none;">';
self::html_sitemap();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function general_sitemaps(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->sitemap_settings;
$options = get_option('siteseo_xml_sitemap_option_name', []);
$xml_sitemap = !empty($options['xml_sitemap_general_enable']) ? $options['xml_sitemap_general_enable'] : '';
$img_sitemap = !empty($options['xml_sitemap_img_enable']) ? $options['xml_sitemap_img_enable'] : '';
$author_sitemap = !empty($options['xml_sitemap_author_enable']) ? $options['xml_sitemap_author_enable'] : '';
$html_sitemap = !empty($options['xml_sitemap_html_enable']) ? $options['xml_sitemap_html_enable'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('General','siteseo').'</h3>
<p>'.esc_html__('Sitemaps are pages which help search engine, know your site better and makes it easier for them to index the pages.','siteseo').'</p>
<p>'.esc_html__('Not having a sitemap does not mean search engines won\'t be able to crawl your website, but sitemaps make it easier for them to discover all the URLs which are needed to be indexed.','siteseo').'</p>
<div class="siteseo-styles pre"><pre><span class="dashicons dashicons-external"></span><a href="'.esc_url(get_option('home')).'/sitemaps.xml" target="_blank">' . esc_url(get_option('home')) . '/sitemaps.xml</a></pre></div>
<div class="siteseo-notice">
<span id="siteseo-dash-icon" class="dashicons dashicons-info"></span>
<p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('To view your sitemap, %1$s enable permalinks %2$s (other than the default one) and save the settings to flush them.', 'siteseo'), '<strong>', '</strong>')).'</p>
</div>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Enable XML Sitemap','siteseo').'</th>
<td>
<label><input id="siteseo_enable_sitemap" name="siteseo_options[enable_xml_sitemap]" type="checkbox" '.(!empty($xml_sitemap) ? 'checked' : '').' value="1"/>'. esc_html__('Enable XML Sitemap', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable Image Sitemap','siteseo').'</th>
<td>
<label><input id="siteseo_image_sitemap" name="siteseo_options[enable_img_sitemap]" type="checkbox" '.(!empty($img_sitemap) ? 'checked' : '').' value="1"/>'. esc_html__('Enable Image Sitemap for standard images, image galleries, featured images, and WooCommerce / Kkart product images.)', 'siteseo').'</label>
<p class="description">'.esc_html__('Images in XML sitemaps are only visible from the source code.', 'siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable Author Sitemap','siteseo').'</th>
<td>
<label><input id="siteseo_author_sitemap" name="siteseo_options[enable_author_sitemap]" type="checkbox" '.(!empty($author_sitemap) ? 'checked' : '').' value="1"/>' . esc_html__('Enable Author Sitemap', 'siteseo').'</label>
<p class="description">'.esc_html__('Ensure that you enable the author archive from SEO, under the Titles & Metas section, in the Archives tab.','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Enable HTML Sitemap','siteseo').'</th>
<td>
<label><input id="siteseo_html_sitemap" name="siteseo_options[enable_html_sitemap]" type="checkbox" '.(!empty($html_sitemap) ? 'checked' : ''). ' value="1"/>' . esc_html__('Enable HTML Sitemap', 'siteseo').'</label>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[general_sitemaps] value="1"/>';
}
static function post_types_sitemaps(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->sitemap_settings;
$options = get_option('siteseo_xml_sitemap_option_name', []);
$option_sitemap_posts = !empty($options['xml_sitemap_post_types_list']['post']['include']) ? $options['xml_sitemap_post_types_list']['post']['include'] : '';
$option_sitemap_pages = !empty($options['xml_sitemap_post_types_list']['page']['include']) ? $options['xml_sitemap_post_types_list']['page']['include'] : '';
$option_sitemap_media = !empty($options['xml_sitemap_post_types_list']['media']['include']) ? $options['xml_sitemap_post_types_list']['media']['include'] : '';
$post_types = siteseo_post_types();
echo '<h3 class="siteseo-tabs">'.esc_html__('Post Types', 'siteseo').'</h3>
<p>'.esc_html__('Select Post Types to Include or Exclude', 'siteseo').'</p>
<table class="form-table">
<tbody>';
foreach($post_types as $post_type){
$post_type_name = $post_type->name;
$post_type_label = $post_type->labels->singular_name;
$option_sitemap_custom = !empty($options['xml_sitemap_post_types_list'][$post_type_name]['include']) ? 'checked="yes"' : '';
echo '<tr>
<th></th>
<td>
<label for="sitemap_post_types_'.esc_attr($post_type_name).'">
<h4>'.esc_html($post_type_label).' <em>(['.esc_html($post_type_name).'])</em></h4>
<input id="sitemap_post_types_'.esc_attr($post_type_name).'" name="siteseo_options[xml_sitemap_post_types_list]['.esc_attr($post_type_name).'][include]" type="checkbox" '.esc_attr($option_sitemap_custom).' value="1"/>
'.esc_html__('Include', 'siteseo').'
</label>
</td>
</tr>';
}
echo '</tbody>
</table>
<input type="hidden" name= siteseo_options[post_types_tab] value="1"/>';
}
static function taxonomy_sitemap(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->sitemap_settings;
$get_taxonomies = get_taxonomies(['public' => true, 'show_ui' => true], 'objects');
$check_taxonomies = apply_filters('siteseo_sitemaps_tax', $get_taxonomies);
$options = get_option('siteseo_xml_sitemap_option_name');
$option_category = isset($options['xml_sitemap_taxonomies_list']['category']['include']) ? $options['xml_sitemap_taxonomies_list']['category']['include'] : '';
$option_post_tags = isset($options['xml_sitemap_taxonomies_list']['post_tag']['include']) ? $options['xml_sitemap_taxonomies_list']['post_tag']['include'] : '';
$get_taxonomies = get_taxonomies();
$check_taxomies = apply_filters('siteseo_sitemaps_tax', $get_taxonomies);
$excluded_taxonomies = ['post_format', 'category', 'post_tag'];
echo '<h3 class="siteseo-tabs">'.esc_html__('Taxonomies', 'siteseo').'</h3>
<p>'.esc_html__('Select Taxonomies to Include or Exclude', 'siteseo').'</p>
<table class="form-table">
<tr scope="row">
<th>'.esc_html__('Select to INCLUDE Taxonomies', 'siteseo').'</th>
<td><br/><br/>
<label for="sitemap_post_types_pages">
<h4>'.esc_html__('Categories ', 'siteseo').' <em>[categories]</em></h4>
<input id="sitemap_post_types_pages" name="siteseo_options[xml_sitemap_taxonomies_list][category][include]" type="checkbox" '.(!empty($option_category) ? 'checked' : 'value="1"').'/>
'.esc_html__('Include', 'siteseo').'
</label>
</td>
</tr>
<tr>
<th></th>
<td>
<label for="sitemap_post_types_pages">
<h4>'.esc_html__('Tags', 'siteseo').' <em>[post_tag]</em></h4>
<input id="sitemap_post_types_pages" name="siteseo_options[xml_sitemap_taxonomies_list][post_tag][include]" type="checkbox" '.(!empty($option_post_tags) ? 'checked' : 'value="1"').'/>
'.esc_html__('Include', 'siteseo').'
</label>
</td>
</tr>';
foreach($check_taxonomies as $taxonomy_name => $taxonomy_obj){
if(in_array($taxonomy_name, $excluded_taxonomies)){
continue;
}
//check selected
$is_included = !empty($options['xml_sitemap_taxonomies_list'][$taxonomy_name]['include']);
// Generate a row for the taxonomy
echo '<tr scope="row">
<th></th>
<td>
<label for="sitemap_taxonomy_'.esc_attr($taxonomy_name).'">
<h4>'.esc_html($taxonomy_obj->labels->name).' <em>[' . esc_html($taxonomy_name).']</em></h4>
<input id="sitemap_taxonomy_' . esc_attr($taxonomy_name) . '"
name="siteseo_options[xml_sitemap_taxonomies_list][' . esc_attr($taxonomy_name).'][include]"
type="checkbox" '.($is_included ? 'checked' : '').' value="1" />
' . esc_html__('Include', 'siteseo') . '
</label>
</td>
</tr>';
}
echo '</table><input type="hidden" name="siteseo_options[taxonomy_sitemap_tabs]" value="1">';
}
static function html_sitemap(){
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->$sitemap_settings;
$options = get_option('siteseo_xml_sitemap_option_name', []);
$include_pages = !empty($options['xml_sitemap_html_mapping']) ? $options['xml_sitemap_html_mapping'] : '';
$exclude_page = !empty($options['xml_sitemap_html_exclude']) ? $options['xml_sitemap_html_exclude'] : '';
$order = !empty($options['xml_sitemap_html_order']) ? $options['xml_sitemap_html_order'] : '';
$order_by = !empty($options['xml_sitemap_html_orderby']) ? $options['xml_sitemap_html_orderby'] : '';
$disable_date = !empty($options['xml_sitemap_html_date']) ? $options['xml_sitemap_html_date'] : '';
$remove_archive = !empty($options['xml_sitemap_html_archive_links']) ? $options['xml_sitemap_html_archive_links'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('HTML Sitemap', 'siteseo').'</h3>
<p>'.esc_html__('Generate an HTML sitemap for your visitors to improve your SEO.','siteseo').'</p>
<p>'.esc_html__('Restricted to 1,000 posts per post type. You can change the order and sorting settings below.','siteseo').'</p>
<div class="siteseo-notice"><span class="dashicons dashicons-info"></span>
<div>
<h3>'.esc_html__('How to make use of the HTML Sitemap?', 'siteseo').'</h3>
<h4>'.esc_html__('Block Editor', 'siteseo').'</h4>
<p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('Insert the HTML sitemap block via the %1$s Block Editor %2$s.', 'siteseo'), '<strong>', '</strong>')).'</p>
<h4>'.esc_html__('Shortcode', 'siteseo').'</h4>
<p>'.esc_html__('You can also insert this shortcode into your content (post, page, custom post type, etc.):', 'siteseo').'</p>
<div class="siteseo-styles pre"><pre>'.esc_attr('[siteseo_html_sitemap]').'</div></pre>
<p>'.esc_html__('To include specific custom post types, use the CPT attribute:', 'siteseo') .'</p>
<div class="siteseo-styles pre"><pre>'.esc_attr('[siteseo_html_sitemap cpt="post,product"]').'</div></pre>
<h4>'.esc_html__('Other', 'siteseo').'</h4>
<p>'.esc_html__('Display the sitemap dynamically by entering an ID in the first field below.', 'siteseo').'</p>
</div>
</div>
<table class="form-table">
<tr scope="row">
<th>'.esc_html__('Post, Page, or Custom Post Type IDs to display:','siteseo').'</th>
<td>
<input type="text" value="'.esc_html($include_pages).'" name="siteseo_options[page_numbers]" placeholder="'.esc_html__('eg:2, 28, 68','siteseo').'">
</td>
</tr>
<tr scope="row">
<th>'.esc_html__('Exclude Posts, Pages, Custom Post Types or Terms IDs:','siteseo').'</th>
<td>
<input type="text" value="'.esc_html($exclude_page).'" name="siteseo_options[exclude_page]" placeholder="'.esc_html__('eg: 13 ,8 ,28','siteseo').'">
</td>
</tr>
<tr scope="row">
<th>'.esc_html__('Order:','siteseo').'</th>
<td>
<select name="siteseo_options[order]">
<option value="DESC" '.selected($order, 'DESC', false).'>'.esc_html__('DESC (descending order from highest to lowest values (3, 2, 1; c, b, a))','siteseo').'</option>
<option value="ASC" '.selected($order, 'ASC', false).'>'.esc_html__('ASC (ascending order from lowest to highest values (1, 2, 3; a, b, c))','siteseo').'</option>
</select>
</td>
</tr>
<tr scope="row">
<th>'.esc_html__('Order By:','siteseo').'</th>
<td>
<select name="siteseo_options[order_by]">
<option value="date" '.selected($order_by, 'date', false).'>'.esc_html__('Deafult (date)','siteseo').'</option>
<option value="post_title" '.selected($order_by, 'post_title', false).'>'.esc_html__('Post Title','siteseo').'</option>
<option value="modified_date" '.selected($order_by, 'modified_date', false).'>'.esc_html__('Modified date','siteseo').'</option>
<option value="post_id" '.selected($order_by, 'post_id', false).'>'.esc_html__('POST ID','siteseo').'</option>
<option value="menu_order" '.selected($order_by, 'menu_order', false).'>'.esc_html__('Menu Order','siteseo').'</option>
</select>
</td>
</tr>
<tr scope="row">
<th>'.esc_html__('Disable Date:','siteseo').'</th>
<td>
<label for="sitemap_html_date">
<input id="sitemap_html_date" name="siteseo_options[disable_date]" type="checkbox" '.(!empty($disable_date) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Disable the date display after each post, page, or post type?', 'siteseo').
'</label>
</td>
</tr>
<tr scope="row">
<th>'.esc_html__('Remove Archive Links:','siteseo').'</th>
<td>
<label for="sitemap_remove_link">
<input id="sitemap_remove_link" name="siteseo_options[remove_links]" type="checkbox" '.(!empty($remove_archive) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove links from archive pages (e.g., Products).', 'siteseo').
'</label>
</td>
</tr>
</table><input type="hidden" name="siteseo_options[html_sitemap]" value="1"/>';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_sitemap_settings');
if(!siteseo_user_can('manage_sitemap') || !is_admin()){
return;
}
$options = [];
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['general_sitemaps'])){
$options['xml_sitemap_general_enable'] = isset($_POST['siteseo_options']['enable_xml_sitemap']);
$options['xml_sitemap_img_enable'] = isset($_POST['siteseo_options']['enable_img_sitemap']);
$options['xml_sitemap_author_enable'] = isset($_POST['siteseo_options']['enable_author_sitemap']);
$options['xml_sitemap_html_enable'] = isset($_POST['siteseo_options']['enable_html_sitemap']);
flush_rewrite_rules();
}
if(isset($_POST['siteseo_options']['html_sitemap'])){
$options['xml_sitemap_html_mapping'] = isset($_POST['siteseo_options']['page_numbers']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['page_numbers'])) : '';
$options['xml_sitemap_html_exclude'] = isset($_POST['siteseo_options']['exclude_page']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['exclude_page'])) : '';
$options['xml_sitemap_html_order'] = isset($_POST['siteseo_options']['order'])? sanitize_text_field(wp_unslash($_POST['siteseo_options']['order'])) : '';
$options['xml_sitemap_html_orderby'] = isset($_POST['siteseo_options']['order_by']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['order_by'])) : '';
$options['xml_sitemap_html_date'] = isset($_POST['siteseo_options']['disable_date']);
$options['xml_sitemap_html_archive_links'] = isset($_POST['siteseo_options']['remove_links']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['remove_links'])) : '';
}
// posts
if(isset($_POST['siteseo_options']['post_types_tab'])){
if(isset($_POST['siteseo_options']['xml_sitemap_post_types_list'])){
$xml_post_types = map_deep(wp_unslash($_POST['siteseo_options']['xml_sitemap_post_types_list']), 'sanitize_text_field');
foreach($xml_post_types as $posttypes_key => $posttypes_value) {
if(isset($posttypes_value['include'])) {
$options['xml_sitemap_post_types_list'][$posttypes_key]['include'] = $posttypes_value['include'];
}
}
}
}
// Taxonomies
if(isset($_POST['siteseo_options']['taxonomy_sitemap_tabs'])){
if(isset($_POST['siteseo_options']['xml_sitemap_taxonomies_list'])){
$xml_tax_list = map_deep(wp_unslash($_POST['siteseo_options']['xml_sitemap_taxonomies_list']), 'sanitize_text_field');
foreach($xml_tax_list as $taxonomy_key => $taxonomy_value){
if(isset($taxonomy_value['include'])){
$options['xml_sitemap_taxonomies_list'][$taxonomy_key]['include'] = $taxonomy_value['include'];
}
}
}
}
update_option('siteseo_xml_sitemap_option_name',$options);
}
}
settings/advanced.php 0000644 00000140755 15152641524 0010703 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Advanced{
static function menu(){
global $siteseo;
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_image_seo'; // Default tab
$titles_meta_subtabs = [
'tab_image_seo' => esc_html__('Image SEO', 'siteseo'),
'tab_advanced' => esc_html__('Advanced', 'siteseo'),
'tab_appearance' => esc_html__('Appearance', 'siteseo'),
'tab_security' => esc_html__('Security', 'siteseo'),
'tab_toc' => esc_html__('Table of content', 'siteseo')
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_advance_settings');
$advanced_toggle = isset($siteseo->setting_enabled['toggle-advanced']) ? $siteseo->setting_enabled['toggle-advanced'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
Util::render_toggle('Image SEO & Advanced Settings - SiteSEO', 'advanced_toggle', $advanced_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($titles_meta_subtabs as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="' . esc_attr($tab_key) . '-tab" class="siteseo-nav-tab' . esc_attr($active_class) . '" data-tab="' . esc_attr($tab_key) . '">' . esc_html($tab_caption) . '</a>';
}
echo '</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab '.($current_tab == 'tab_image_seo' ? ' active' : '').'" id="tab_image_seo" style="display: none;">';
self::image_seo();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_advanced' ? ' active' : '').'" id="tab_advanced" style="display: none;">';
self::advanced();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_appearance' ? ' active' : '').'" id="tab_appearance" style="display: none;">';
self::appearance();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_security' ? ' active' : '').'" id="tab_security" style="display: none;">';
self::security();
echo '</div>
<div class="siteseo-tab '.($current_tab == 'tab_toc' ? ' active' : '').'" id="tab_toc" style="display: none;">';
self::toc();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function image_seo(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->$advanced_settings;
$options = get_option('siteseo_advanced_option_name');
$option_attachment = isset($options['advanced_attachments']) ? $options['advanced_attachments'] : '';
$option_attachment_file = isset($options['advanced_attachments_file']) ? $options['advanced_attachments_file'] : '';
$option_clean_filename = isset($options['advanced_clean_filename']) ? $options['advanced_clean_filename'] : '';
$option_img_title = isset($options['advanced_image_auto_title_editor']) ? $options['advanced_image_auto_title_editor'] : '';
$option_img_alt = isset($options['advanced_image_auto_alt_editor']) ? $options['advanced_image_auto_alt_editor'] : '';
$option_target_key = isset($options['advanced_image_auto_alt_target_kw']) ? $options['advanced_image_auto_alt_target_kw'] : '';
$option_cap_img = isset($options['advanced_image_auto_caption_editor']) ? $options['advanced_image_auto_caption_editor'] : '';
$option_desc_img = isset($options['advanced_image_auto_desc_editor']) ? $options['advanced_image_auto_desc_editor'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Image SEO','siteseo').'</h3>
<p>'.esc_html__('Images can drive significant traffic to your site. Be sure to always add alt text, optimize file sizes, and properly name the files, among other best practices.','siteseo').'</p>
<table class="form-table">
<tbody class="siteseo_tbody">
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Redirect attachment pages to the post parent page.','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[attachment]" type="checkbox"'.(!empty($option_attachment) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Redirect attachment pages to the post parent, or to the homepage if no parent exists.', 'siteseo').
'</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Redirect attachment pages to their file URL','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[attachment_file]" type="checkbox"'.(!empty($option_attachment_file) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Redirect attachment pages to their respective file URLs (e.g., https://www.example.com/my-image-file.jpg).', 'siteseo').
'</label>
<p class="description">'.esc_html__('If this option is enabled, it will override the redirection of attachment pages to the post parent.','siteseo').'</p>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Cleaning media filename','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[clean_filename]" type="checkbox"'.(!empty($option_clean_filename) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('When uploading media, remove accents, spaces, and capital letters, and enforce UTF-8 encoding.', 'siteseo').
'</label>
<p class="description">'.esc_html__('e.g. "ExãMple 1 cópy!.jpg" => "example-1-copy.jpg"','siteseo').'</p>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Automatically set the image Title','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[auto_img_title]" type="checkbox"'.(!empty($option_img_title) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('When uploading an image file, automatically set the title to match the filename.', 'siteseo').
'</label>
<p class="description">' . esc_html__('We use the product title for ', 'siteseo') . esc_html(!defined('SITEPAD') ? 'WooCommerce' : 'Kkart') . esc_html__(' items.', 'siteseo') . '</p>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Automatically set the image Alt txt','siteseo').'</th>
<td>
<label><input name="siteseo_options[auto_img_alt]" type="checkbox"'.(!empty($option_img_alt) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('When uploading an image file, automatically set the alt text to match the filename.', 'siteseo').
'</label>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Automatically set the image alt text using target keywords..','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[auto_target_keyword]" type="checkbox"'.(!empty($option_target_key) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Use the target keywords if no alt text is set for the image.', 'siteseo').
'</label>
<p class="description">'.esc_html__('This setting will apply only to images without alt text on the frontend. It is retroactive, meaning if you disable it, images that previously had empty alt text will revert to being empty.','siteseo').'</p>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Automatically set the image Caption','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[caption_image]" type="checkbox"'.(!empty($option_cap_img) ? 'checked="yes"' : '') . ' value="1"/>'.esc_html__('When uploading an image file, automatically set the caption to match the filename.', 'siteseo') .
'</label>
</td>
<tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Automatically set the image Description','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[description_img]" type="checkbox"'.(!empty($option_desc_img) ? 'checked="yes"' : ''). ' value="1"/>'.esc_html__('When uploading an image file, automatically set the description to match the filename.', 'siteseo').
'</label>
</td>
<tr>
</tbody>
</table><input type="hidden" name="siteseo_options[image_seo]" value="1"/>';
}
static function advanced(){
global $siteseo, $wp_version;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->advanced_settings;
$options = get_option('siteseo_advanced_option_name');
$platform_name = defined('SITEPAD') ? 'SitePad' : 'WordPress';
$option_taxonomy_desc = isset($options['advanced_tax_desc_editor']) ? $options['advanced_tax_desc_editor'] : '';
$option_category_url = isset($options['advanced_category_url']) ? $options['advanced_category_url'] : '';
$option_noreferrer_link = isset($options['advanced_noreferrer']) ? $options['advanced_noreferrer'] : '';
$option_wp_generator = isset($options['advanced_wp_generator']) ? $options['advanced_wp_generator'] : '';
$option_hentry_post = isset($options['advanced_hentry']) ? $options['advanced_hentry'] : '';
$option_author_url = isset($options['advanced_comments_author_url']) ? $options['advanced_comments_author_url'] : '';
$option_site_fileds = isset($options['advanced_comments_website']) ? $options['advanced_comments_website'] : '';
$option_rel_attributes = isset($options['advanced_comments_form_link']) ? $options['advanced_comments_form_link'] : '';
$option_shortlink = isset($options['advanced_wp_shortlink']) ? $options['advanced_wp_shortlink'] : '';
$option_wlw_meta_tag = isset($options['advanced_wp_wlw']) ? $options['advanced_wp_wlw'] : '';
$option_rsd_meta_tag = isset($options['advanced_wp_rsd']) ? $options['advanced_wp_rsd'] : '';
$option_google_meta_value = isset($options['advanced_google']) ? $options['advanced_google'] : '';
$option_bing_meta_value = isset($options['advanced_bing']) ? $options['advanced_bing'] : '';
$option_pinterest_meta_value = isset($options['advanced_pinterest']) ? $options['advanced_pinterest'] : '';
$option_yandex_meta_value = isset($options['advanced_yandex']) ? $options['advanced_yandex'] : '';
$option_remove_wocommerce_cat_url = isset($options['advanced_product_cat_url']) ? $options['advanced_product_cat_url'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Advanced','siteseo').'</h3>
<p class="description">'.esc_html__('Advanced SEO options for advanced users.','siteseo').'</p>
<table class="form-table"/>
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Add WP Editor to taxonomy description textarea','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[taxonomy_desc]" type="checkbox"'.(!empty($option_taxonomy_desc) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Add the TINYMCE editor to the term description field to enable rich text formatting.', 'siteseo').
'</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove /category/ in URL','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[category_url]" type="checkbox"'.(!empty($option_category_url) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove /category/ in your permalinks', 'siteseo').
'</label>
<p class="description">'.esc_html('e.g. "https://example.com/category/my-post-category/" => "https://example.com/my-post-category/"').'</p>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Remove category base from product permalinks', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" name="siteseo_options[remove_cate_woocommerce]" '.(!empty($option_remove_wocommerce_cat_url) ? 'checked="yes"' : '').' value="1"/>
'.
/* translators: placeholders are just html tags */
wp_kses_post(sprintf(__('Remove %1$s product-category %2$s in your permalinks', 'siteseo'), '<strong>','</strong>')).'
</label>
</div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove noreferrer link attribute in post content','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[noreferrer_link]" type="checkbox"'.(!empty($option_noreferrer_link) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove the noreferrer link attribute from the source code.', 'siteseo').
'</label>
<p class="description">'.esc_html__('Useful for affiliate links (eg: Amazon)','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.
// translators: %s is the platform name
sprintf(esc_html__('Remove %s meta generator tag', 'siteseo'), esc_html( $platform_name )).'</th>
<td>
<label>
<input name="siteseo_options[wp_generator_meta]" type="checkbox"'.(!empty($option_wp_generator) ? 'checked="yes"' : '').' value="1"/>'. // translators: %s is the platform name
sprintf(esc_html__('Remove %s meta generator in source code', 'siteseo'), esc_html( $platform_name)).
'</label>
<div class="siteseo-styles pre"><pre>'.esc_html('<meta name="generator" content="WordPress '.(!empty($wp_version) ? $wp_version : '6.8.2').'" />').'</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove hentry post class','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[hentry_post]" type="checkbox"' . (!empty($option_hentry_post) ? 'checked="yes"' : '') . ' value="1"/>' . esc_html__('Remove the `hentry` post class to prevent Google from treating it as structured data (schema)', 'siteseo') .
'</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove author URL','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[comments_author_url]" type="checkbox"'.(!empty($option_author_url) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove the comment author URL in comments if the website field is filled in the profile page.', 'siteseo').
'</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove website field from comment form','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[website_filed]" type="checkbox"'.(!empty($option_site_fileds) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove the website field from the comment form to reduce spam.', 'siteseo').
'</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Add the "nofollow", "noopener", and "noreferrer" rel attributes to the links in the comment form.','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[comment_form_link]" type="checkbox"'.(!empty($option_rel_attributes) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Prevent search engines from following or indexing the link to the comment form by adding a "noindex", "nofollow" directive.', 'siteseo').
'</label>
<div class="siteseo-styles pre"><pre>'.esc_url('https://www.example.com/my-blog-post/#respond').'</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.
// translators: %s is the platform name
sprintf(esc_html__('Remove %s shortlink meta tag', 'siteseo'), esc_html( $platform_name)).
'</th>
<td>
<label>
<input name="siteseo_options[shortlink]" type="checkbox"'.(!empty($option_shortlink) ? 'checked="yes"' : '') .' value="1"/>'. // translators: %s is the platform name
sprintf(esc_html__('Remove %s shortlink meta tag in source.', 'siteseo'), esc_html( $platform_name )).
'</label>
<div class="siteseo-styles pre"><pre>'.esc_html('<link rel="shortlink" href="https://www.example.com/"/>').'</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove Windows Live Writer meta tag','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[wlw_meta]" type="checkbox"'.(!empty($option_wlw_meta_tag) ? 'checked="yes"' : '').' value="1"/>'.esc_html__('Remove the Windows Live Writer meta tag from the source code.', 'siteseo') .
'</label>
<div class="siteseo-styles pre"><pre>'.esc_html('<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://www.example.com/wp-includes/wlwmanifest.xml" />').'</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Remove RSD meta tag','siteseo').'</th>
<td>
<label>
<input name="siteseo_options[rsd_meta]" type="checkbox"'.(!empty($option_rsd_meta_tag) ? 'checked="yes"' : ''). ' value="1"/>'. esc_html__('Remove the Really Simple Discovery (RSD) meta tag from the source code.', 'siteseo').
'</label>
<p class="description">'.
// translators: %s is the platform name
sprintf(esc_html__('The %s Site Health feature will display an HTTPS warning if you enable this option. However, this is a false positive.', 'siteseo'), esc_html($platform_name)).'</p>
<div class="siteseo-styles pre"><pre>' . esc_html('<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://www.example.com/wp-includes/wlwmanifest.xml" />') . '</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Google site verification','siteseo').'</th>
<td>
<input name="siteseo_options[google_meta_value]" type="text" placeholder="'.esc_html__('Enter Google meta value site verification','siteseo').'" value="'.esc_attr($option_google_meta_value).'"/>
<p class="description">'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('If your site is already verified in %1$s Google Search Console %2$s, you can leave this field blank.', 'siteseo'), '<strong>', '</strong>')).'
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Bing site verification','siteseo').'</th>
<td>
<input name="siteseo_options[bing_meta_value]" type="text" placeholder="'.esc_html__('Enter Bing meta value site verification','siteseo').'" value="'.esc_attr($option_bing_meta_value).'"/>
<p class="description">'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('If your site is already verified in %1$s Bing Webmaster Tools %2$s, you can leave this field blank.', 'siteseo'), '<strong>', '</strong>')).'</p>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Pinterest site verification','siteseo').'</th>
<td>
<input name="siteseo_options[pinterest_meta_value]" type="text" placeholder="'.esc_html__('Enter the Pinterest meta value for site verification.','siteseo').'" value="'.esc_attr($option_pinterest_meta_value).'"/>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Yandex site verification','siteseo').'</th>
<td>
<input name="siteseo_options[yandex_meta_value]" type="text" placeholder="'.esc_html__('Enter the Yandex meta value for site verification.','siteseo').'" value="'.esc_attr($option_yandex_meta_value).'"/>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[advanced_tab]" value="1"/>';
}
static function appearance(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->advanced_settings;
$options = get_option('siteseo_advanced_option_name');
$option_enable_universal_metabox = isset($options['appearance_universal_metabox']) ? $options['appearance_universal_metabox'] : '';
$option_disable_universal_metabox = isset($options['appearance_universal_metabox_disable']) ? $options['appearance_universal_metabox_disable'] : '';
$option_content_analysis_metabox = isset($options['appearance_ca_metaboxe']) ? $options['appearance_ca_metaboxe'] : '';
$option_hide_genesis_metabox = isset($options['appearance_genesis_seo_metaboxe']) ? $options['appearance_genesis_seo_metaboxe'] : '';
$option_structured_type_metabox = isset($options['appearance_advice_schema']) ? $options['appearance_advice_schema'] : '';
$option_admin_bar = isset($options['appearance_adminbar']) ? $options['appearance_adminbar'] : '';
$option_noindex_admin_bar = isset($options['appearance_adminbar_noindex']) ? $options['appearance_adminbar_noindex'] : '';
$option_column_title = isset($options['appearance_title_col']) ? $options['appearance_title_col'] : '';
$option_column_desc = isset($options['appearance_meta_desc_col']) ? $options['appearance_meta_desc_col'] : '';
$option_column_redirect = isset($options['appearance_redirect_enable_col']) ? $options['appearance_redirect_enable_col'] : '';
$option_column_post_type = isset($options['appearance_redirect_url_col']) ? $options['appearance_redirect_url_col'] : '';
$option_column_canonical_post_ty = isset($options['appearance_canonical']) ? $options['appearance_canonical'] : '';
$option_column_target_key = isset($options['appearance_target_kw_col']) ? $options['appearance_target_kw_col'] : '';
$option_column_noindex = isset($options['appearance_noindex_col']) ? $options['appearance_noindex_col'] : '';
$option_column_nofollow = isset($options['appearance_nofollow_col']) ? $options['appearance_nofollow_col'] : '';
$option_column_words_no = isset($options['appearance_words_col']) ? $options['appearance_words_col'] : '';
$option_column_score = isset($options['appearance_score_col']) ? $options['appearance_score_col'] : '';
$option_misc_genesis_metabox = isset($options['appearance_genesis_seo_menu']) ? $options['appearance_genesis_seo_menu'] : '';
$appearance_fields =[
'metaboxes'=>'Metaboxes',
'Columns' => 'Columns',
'Misc' =>'Misc',
];
if(!defined('SITEPAD')){
$appearance_fields['admin-bar'] = 'Admin bar';
}
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($appearance_fields as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#'.esc_attr($post_key).'" class="'.esc_attr($active_class).'">'.esc_html($post_val).'</a>';
$is_first = false;
}
echo '</div>
</th>
<td>
<div>
<h3>'.esc_html__('Appearance','siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Customize the plugin to fit your needs','siteseo').'</p>
</div>
<span class="line"></span>
<h3>'.esc_html__('Metaboxes','siteseo').'</h3>
<p>'.esc_html__('Edit your SEO metadata directly from your favorite page builder.','siteseo').'</p>
<table class="form-table" id="metaboxes">
<tbody>';
if(!defined('SITEPAD')){
echo '<tr>
<th scope="row">'.esc_html__('Universal Metabox (Gutenberg)','siteseo').'</th>
<td>
<label><input type="checkbox" name="siteseo_options[enable_universal_metabox]" '.(!empty($option_enable_universal_metabox) ? 'checked="yes"' : 'value="1"').' "/> ' . esc_html__('Enable the universal SEO metabox for the Block Editor (Gutenberg)', 'siteseo') . '<label>
</td>
</tr>';
}
echo '<tr>
<th scope="row">'.esc_html__('Disable Universal Metabox','siteseo').'</th>
<td>
</label><input type="checkbox" name="siteseo_options[disable_universal_metabox]" '.(!empty($option_disable_universal_metabox) ? 'checked="yes"' : 'value="1"').' "/>'.esc_html__('Disable the universal SEO metabox','siteseo').'
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Remove Content Analysis Metabox','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_content_analysis_metabox) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[remove_content_analysis]"> '.esc_html__(' Remove Content Analysis Metabox','siteseo').'</label>
<p class="description">'.esc_html__('By checking this option, we will no longer track the significant keywords','siteseo').'</p>
</td>
</tr>
<tr>
<th scope=row">'.esc_html__('Hide Genesis SEO Metabox','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_hide_genesis_metabox) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[genesis_metabox]"> '.esc_html__(' Remove Genesis SEO Metabox', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Hide advice in Structured Data Types metabox','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_structured_type_metabox) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[structured_data_types_metabox]">'.esc_html__(' Remove the advice if None schema selected', 'siteseo').'</label>
</td>
</tr>
</tbody>
</table>';
if(!defined('SITEPAD')){
echo'<div id="Admin-bar">
<span class="line"></span>
<h3>'.esc_html__('Admin bar','siteseo').'</h3>
<p class="description">'.esc_html__('The admin bar appears on the top of your pages when logged in to your WP admin','siteseo').'</p>
<table>
<tbody>
<tr>
<th scope="row">'.esc_html__('SEO in admin bar','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_admin_bar) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[admin_bar]"> '.esc_html__('Remove SEO from Admin Bar in backend and frontend', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Noindex in admin bar','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_noindex_admin_bar) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[noindex_admin_bar]"> '.esc_html__('Remove noindex item from Admin Bar in backend and frontend', 'siteseo').'</label>
</td>
</tr>
</tbody>
</table>
</div>';
}
echo'<div id="Columns">
<span class="line"></span>
<h3>'.esc_html__('Columns','siteseo').'</h3>
<p>'.esc_html__('Customize the SEO columns displayed in the posts/pages list.','siteseo').'</p>
<table>
<tbody>
<tr>
<th scope="row">'.esc_html__('Show Title tag column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_title) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[title_post_types]"> '.esc_html__('Add title column', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show Meta description column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_desc) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[desc_post_types]"> '.esc_html__('Add meta description column','siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show Redirection Enable column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_redirect) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[redirect_post_types]"> '.esc_html__('Add redirection enable column', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show Redirect URL column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_post_type) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[redirect_url_post_types]"> '.esc_html__('Add redirection URL column', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show canonical URL column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_canonical_post_ty) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[url_column_post_types]"> '.esc_html__('Add canonical URL column', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show Target Keyword column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_target_key) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[keyword_column_post_types]"> '.esc_html__('Add target keyword column', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show noindex column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_noindex) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[noindex_column_post_types]"> '.esc_html__('Display noindex status', 'siteseo').'</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Show nofollow column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_nofollow) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[nofollow_column_post_types]"> '.esc_html__('Display nofollow status', 'siteseo').'</label>
</td>
</tr>
<th scope="row">'.esc_html__('Show total number of words column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_words_no) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[words_column_post_types]"> '.esc_html__('Display total number of words in content', 'siteseo').'</label>
</td>
</tr>
<th scope="row">'.esc_html__('Show content analysis score column in post types','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_column_score) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[score_column_post_types]"> '.esc_html__('Display Content Analysis results column ("Good" or "Should be improved")', 'siteseo').'</label>
</td>
</tr>
</tbody>
</table>
</div>
<div id="Misc">
<span class="line"></span>
<h3>'.esc_html__('Misc','siteseo').'</h3>
<div class="siteseo_wrap_label"><p>'.esc_html__('Miscellaneous settings for the SEO plugin.','siteseo').'</p></div>
<table class="form-table">
<tbody>
<tr>
<th scope="row">'.esc_html__('Hide Genesis SEO Settings link','siteseo').'</th>
<td>
<label><input type="checkbox" '.(!empty($option_misc_genesis_metabox) ? 'checked="yes"' : 'value="1"').' name="siteseo_options[genesis_seo_settings]">'.esc_html__('Remove Genesis SEO link in WP Admin Menu', 'siteseo') .'</label>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<input type="hidden" name="siteseo_options[appearance_tab]" value="1"/>';
}
static function security(){
global $siteseo, $wp_roles, $submenu;
if(!current_user_can('administrator')){
echo '<div class="siteseo_wrap_label">
<div class="siteseo-notice is-warning">
<span id="dashicons-warning" class="dashicons dashicons-info"></span>
<p>Only Admin can change security settings</p>
</div>
</div>';
return;
}
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_advanced_option_name');
$menus_check = $submenu['siteseo'];
$security_fields = [
'siteseo-metaboxes' => 'SiteSEO Metaboxes',
'siteseo-settings-pages' => 'SiteSEO setting pages',
];
$roles = get_editable_roles();
if(empty($roles)){
return;
}
wp_nonce_field('siteseo_advance_settings');
echo '<table class="form-table">
<tbody>
<tr>
<th scope="row">
<div class="siteseo-container">';
$is_first = true;
foreach($security_fields as $post_key => $post_val){
$active_class = $is_first ? 'active' : '';
echo '<a href="#' . esc_attr($post_key) . '" class="' . esc_attr($active_class) . '">' . esc_html($post_val) . '</a>';
$is_first = false;
}
echo '</div>
</th>
<td>
<div>
<h3 class="siteseo-tabs">'.esc_html__('Security', 'siteseo').'</h3>
<div class="siteseo_wrap_label">
<p class="description">'.esc_html__('Control access to SEO settings and metaboxes by user roles.', 'siteseo').'</p>
</div>
<h3 class="siteseo-tabs">'.esc_html__('SiteSEO metaboxes', 'siteseo').'</h3>
<div class="siteseo_wrap_label">
<p>'.esc_html__('Check a user role to prevent it from editing a specific metabox.', 'siteseo').'</p>
</div>
<table class="form-table" id="siteseo-metaboxes">
<tbody>
<tr>
<th scope="row">'.esc_html__('Block SEO metabox to user roles', 'siteseo').'</th>
<td>';
foreach($roles as $key => $role){
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts' , $role['capabilities'])){
continue;
}
$checked = isset($options['security_metaboxe_role'][$key]) ? 'checked' : '';
echo '<label>
<input type="checkbox" name="siteseo_options[security_metaboxe_role]['.esc_attr($key).']" value="1" '.esc_attr($checked).'/>
<strong>'.esc_html($role['name']).'</strong>
</label><br/><br/>';
}
echo '</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Block Content analysis metabox to user roles', 'siteseo').'</th>
<td>';
foreach($roles as $key => $role){
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts' , $role['capabilities'])){
continue;
}
$checked = isset($options['security_metaboxe_ca_role'][$key]) ? 'checked' : '';
echo '<label>
<input type="checkbox" name="siteseo_options[security_metaboxe_ca_role]['.esc_attr($key).']" value="1" '.esc_attr($checked).'/><strong>'.esc_html($role['name']).'</strong>
</label><br/><br/>';
}
echo '</td>
</tr>
</tbody>
</table>
<span class="line"></span>
<h3 class="siteseo-tabs">'.esc_html__('SiteSEO settings pages', 'siteseo').'</h3>
<p class="description">'.esc_html__('Check a user role to allow it to edit a specific settings page', 'siteseo').'</p>
<table class="form-table" id="siteseo-settings-pages">
<tbody>';
$settings_pages = [
'titles' => esc_html__('Titles & Metas', 'siteseo'),
'xml-sitemap' => esc_html__('Sitemaps', 'siteseo'),
'social' => esc_html__('Social Networks', 'siteseo'),
'google-analytics' => esc_html__('Analytics', 'siteseo'),
'instant-indexing' => esc_html__('Instant Indexing', 'siteseo'),
'advanced' => esc_html__('Advanced', 'siteseo'),
];
foreach($settings_pages as $page_key => $page_title){
echo '<tr>
<th scope="row">' . esc_html($page_title) . '</th>
<td>';
foreach($roles as $role_key => $role){
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts' , $role['capabilities']) || $role_key == 'administrator'){
continue;
}
$checked = isset($options['siteseo_advanced_security_metaboxe_siteseo-' . $page_key][$role_key]) ? 'checked' : '';
echo '<label>
<input type="checkbox" name="siteseo_options[siteseo_advanced_security_metaboxe_siteseo-' . esc_attr($page_key) . '][' . esc_attr($role_key) . ']" value="1" ' . esc_attr($checked) . '/>
<strong>' . esc_html($role['name']) . '</strong>
</label><br/><br/>';
}
echo '</td>
</tr>';
}
//Pro
if(is_plugin_active('siteseo-pro/siteseo.php') && !defined('SITEPAD')){
echo '<tr>
<th scope="row">' . esc_html__('Pro Features', 'siteseo') . '</th>
<td>';
foreach($roles as $key => $role){
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts' , $role['capabilities']) || $key == 'administrator'){
continue;
}
$checked = isset($options['siteseo_advanced_security_page_pro'][$key]) ? 'checked' : '';
echo '<label>
<input type="checkbox" name="siteseo_options[siteseo_advanced_security_page_pro][' . esc_attr($key) . ']" value="1" ' . esc_attr($checked) . '/>
<strong>'.esc_html($role['name']).'</strong>
</label><br/><br/>';
}
echo '</td>
</tr>';
}
echo '</tbody>
</table>
</div>
</td>
</tr>
</tbody></table><input type="hidden" name="siteseo_options[security_tab]" value="1"/>';
}
static function toc(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_advanced_option_name');
$option_toc_enable = isset($options['toc_enable']) ? $options['toc_enable'] : '';
$option_toc_label = isset($options['toc_label']) ? $options['toc_label'] : '';
$option_headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
$option_list_types = [
'ol' => __('Ordered List', 'siteseo'),
'ul' => __('Unordered List', 'siteseo')
];
echo'<h3 class="siteseo-tabs">'.esc_html__('Table of Contents', 'siteseo').'</h3>
<p>'.esc_html__('A table of content works as an index section for your post or page. It helps search engines understand your page structure and users find specific sections quickly, which might help SEO, as it helps search engines better understand the structure of your content and also improves user experience.', 'siteseo').'</p>
<p>'.esc_html__('To use Table of Content on your pages, you can use this shortcode', 'siteseo').' <code>[siteseo_toc]</code></p>
<table class="form-table">
<tr>
<th scope="row">'.esc_html__('Enable TOC', 'siteseo').'</th>
<td>
<label>
<input type="checkbox" value="1" id="siteseo_toc_enable" name="siteseo_options[toc_enable]" '.checked($option_toc_enable, true, false).'/>
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('TOC Label', 'siteseo').'</th>
<td>
<label>
<input type="text" value="'.esc_attr($option_toc_label).'" name="siteseo_options[toc_label]" placeholder="'.esc_attr__('Table of content', 'siteseo').'"/>
</label>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('Exclude Headings', 'siteseo').'</th>
<td>
<div style="display:flex; gap: 20px;">';
foreach($option_headings as $heading){
$checked = !empty($options) && !empty($options['toc_excluded_headings']) && is_array($options['toc_excluded_headings']) && in_array($heading, $options['toc_excluded_headings']);
echo '<label>
<input type="checkbox" value="'.esc_attr($heading).'" name="siteseo_options[toc_excluded_headings][]" '.checked($checked, true, false).'/>'.esc_html(strtoupper($heading)).'
</label>';
}
echo '</div>
</td>
</tr>
<tr>
<th scope="row">'.esc_html__('List Type', 'siteseo').'</th>
<td>
<div>
<label>
<select name="siteseo_options[toc_heading_type]">';
foreach($option_list_types as $list_type => $list_title){
$selected = !empty($options['toc_heading_type']) && $options['toc_heading_type'] == $list_type ? 'selected' : '';
echo '<option value="'.esc_attr($list_type).'" '.esc_attr($selected).'>'.esc_html($list_title).'</option>';
}
echo '</select>
</label>
</div>
</td>
</tr>
</table><input type="hidden" name="siteseo_options[toc_tab]" value="1" />';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_advance_settings');
if(!siteseo_user_can('manage_advanced') || !is_admin()){
return;
}
$options = [];
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['image_seo'])){
$options['advanced_attachments'] = isset($_POST['siteseo_options']['attachment']);
$options['advanced_attachments_file'] = isset($_POST['siteseo_options']['attachment_file']);
$options['advanced_clean_filename'] = isset($_POST['siteseo_options']['clean_filename']);
$options['advanced_image_auto_title_editor'] = isset($_POST['siteseo_options']['auto_img_title']);
$options['advanced_image_auto_alt_editor'] = isset($_POST['siteseo_options']['auto_img_alt']);
$options['advanced_image_auto_alt_target_kw'] = isset($_POST['siteseo_options']['auto_target_keyword']);
$options['advanced_image_auto_caption_editor'] = isset($_POST['siteseo_options']['caption_image']);
$options['advanced_image_auto_desc_editor'] = isset($_POST['siteseo_options']['description_img']);
}
if(isset($_POST['siteseo_options']['advanced_tab'])){
$options['advanced_product_cat_url'] = isset($_POST['siteseo_options']['remove_cate_woocommerce']);
$options['advanced_tax_desc_editor'] = isset($_POST['siteseo_options']['taxonomy_desc']);
$options['advanced_category_url'] = isset($_POST['siteseo_options']['category_url']);
$options['advanced_noreferrer'] = isset($_POST['siteseo_options']['noreferrer_link']);
$options['advanced_wp_generator'] = isset($_POST['siteseo_options']['wp_generator_meta']);
$options['advanced_hentry'] = isset($_POST['siteseo_options']['hentry_post']);
$options['advanced_comments_author_url'] = isset($_POST['siteseo_options']['comments_author_url']);
$options['advanced_comments_website'] = isset($_POST['siteseo_options']['website_filed']);
$options['advanced_comments_form_link'] = isset($_POST['siteseo_options']['comment_form_link']);
$options['advanced_wp_shortlink'] = isset($_POST['siteseo_options']['shortlink']);
$options['advanced_wp_rsd'] = isset($_POST['siteseo_options']['rsd_meta']);
$options['advanced_wp_wlw'] = isset($_POST['siteseo_options']['wlw_meta']);
$options['advanced_google'] = isset($_POST['siteseo_options']['google_meta_value']) ? sanitize_text_field(Util::extract_content(wp_unslash($_POST['siteseo_options']['google_meta_value']))) : '';
$options['advanced_bing'] = isset($_POST['siteseo_options']['bing_meta_value']) ? sanitize_text_field(Util::extract_content(wp_unslash($_POST['siteseo_options']['bing_meta_value']))) : '';
$options['advanced_pinterest'] = isset($_POST['siteseo_options']['pinterest_meta_value']) ? sanitize_text_field(Util::extract_content(wp_unslash($_POST['siteseo_options']['pinterest_meta_value']))) : '';
$options['advanced_yandex'] = isset($_POST['siteseo_options']['yandex_meta_value']) ? sanitize_text_field(Util::extract_content(wp_unslash($_POST['siteseo_options']['yandex_meta_value']))) : '';
}
if(isset($_POST['siteseo_options']['appearance_tab'])){
$options['appearance_universal_metabox'] = isset($_POST['siteseo_options']['enable_universal_metabox']);
$options['appearance_universal_metabox_disable'] = isset($_POST['siteseo_options']['disable_universal_metabox']);
$options['appearance_ca_metaboxe'] = isset($_POST['siteseo_options']['remove_content_analysis']);
$options['appearance_genesis_seo_metaboxe'] = isset($_POST['siteseo_options']['genesis_metabox']);
$options['appearance_advice_schema'] = isset($_POST['siteseo_options']['structured_data_types_metabox']);
$options['appearance_adminbar'] = isset($_POST['siteseo_options']['admin_bar']);
$options['appearance_adminbar_noindex'] = isset($_POST['siteseo_options']['noindex_admin_bar']);
$options['appearance_title_col'] = isset($_POST['siteseo_options']['title_post_types']);
$options['appearance_meta_desc_col'] = isset($_POST['siteseo_options']['desc_post_types']);
$options['appearance_redirect_enable_col'] = isset($_POST['siteseo_options']['redirect_post_types']);
$options['appearance_redirect_url_col'] = isset($_POST['siteseo_options']['redirect_url_post_types']);
$options['appearance_canonical'] = isset($_POST['siteseo_options']['url_column_post_types']);
$options['appearance_target_kw_col'] = isset($_POST['siteseo_options']['keyword_column_post_types']);
$options['appearance_noindex_col'] = isset($_POST['siteseo_options']['noindex_column_post_types']);
$options['appearance_nofollow_col'] = isset($_POST['siteseo_options']['nofollow_column_post_types']);
$options['appearance_words_col'] = isset($_POST['siteseo_options']['words_column_post_types']);
$options['appearance_score_col'] = isset($_POST['siteseo_options']['score_column_post_types']);
$options['appearance_genesis_seo_menu'] = isset($_POST['siteseo_options']['genesis_seo_settings']);
}
if(isset($_POST['siteseo_options']['toc_tab'])){
$options['toc_enable'] = isset($_POST['siteseo_options']['toc_enable']);
$options['toc_label'] = isset($_POST['siteseo_options']['toc_label']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['toc_label'])) : '';
$options['toc_heading_type'] = isset($_POST['siteseo_options']['toc_heading_type']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['toc_heading_type'])) : '';
//toc_excluded_headings
if(isset($_POST['siteseo_options']['toc_excluded_headings'])){
$options['toc_excluded_headings'] = map_deep(wp_unslash($_POST['siteseo_options']['toc_excluded_headings']), 'sanitize_text_field');
}
}
if(isset($_POST['siteseo_options']['security_tab']) && current_user_can('manage_options')){
$has_admin = ['security_metaboxe_role', 'security_metaboxe_ca_role'];
$settings = [
'security_metaboxe_role',
'security_metaboxe_ca_role',
'siteseo_advanced_security_metaboxe_siteseo-titles',
'siteseo_advanced_security_metaboxe_siteseo-xml-sitemap',
'siteseo_advanced_security_metaboxe_siteseo-social',
'siteseo_advanced_security_metaboxe_siteseo-google-analytics',
'siteseo_advanced_security_metaboxe_siteseo-instant-indexing',
'siteseo_advanced_security_metaboxe_siteseo-advanced',
'siteseo_advanced_security_metaboxe_siteseo-import-export'
];
$advanced_options = map_deep($_POST['siteseo_options'], function($value){
if(!empty($value)){
if(is_string($value)){
return true;
}
return sanitize_text_field(wp_unslash($value));
}
return '';
});
$filtered_options = [];
$roles = get_editable_roles();
foreach($settings as $setting){
$accepted_roles = [];
foreach($roles as $key => $role){
// We will skip, admin if the setting does not require it.
if(!in_array($setting, $has_admin) && $key == 'administrator'){
continue;
}
// We only accept roles which has capability to 'publish_posts', as giving access to anyone less does not makes sense.
if(empty($role['capabilities']) || !is_array($role['capabilities']) || !array_key_exists('publish_posts' , $role['capabilities'])){
continue;
}
array_push($accepted_roles, $key);
}
// Making sure the roles being pushed are the once we want.
if(isset($advanced_options[$setting])){
$filtered_options[$setting] = array_intersect(
$advanced_options[$setting],
array_flip($accepted_roles)
);
}
}
$options = array_merge($options, $filtered_options);
}
update_option('siteseo_advanced_option_name', $options);
}
}
settings/social.php 0000644 00000063224 15152641524 0010403 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Settings;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Social{
static function menu(){
global $siteseo;
$social_toggle = isset($siteseo->setting_enabled['toggle-social']) ? $siteseo->setting_enabled['toggle-social'] : '';
$nonce = wp_create_nonce('siteseo_toggle_nonce');
$current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'tab_knowledge_graph';
$social_subtabs = [
'tab_knowledge_graph' => esc_html__('Knowledge Graph', 'siteseo'),
'tab_social_accounts' => esc_html__('Your social accounts', 'siteseo'),
'tab_facebook' => esc_html__('Facebook (Open Graph) ', 'siteseo'),
'tab_twitter' => esc_html__('X Card', 'siteseo')
];
echo '<div id="siteseo-root">';
Util::admin_header();
echo '<form method="post" id="siteseo-form" class="siteseo-option" name="siteseo-flush">';
wp_nonce_field('siteseo_social_settings');
Util::render_toggle('Social Networks - SiteSEO', 'social_toggle', $social_toggle, $nonce);
echo '<div id="siteseo-tabs" class="wrap">
<div class="siteseo-nav-tab-wrapper">';
foreach($social_subtabs as $tab_key => $tab_caption){
$active_class = ($current_tab === $tab_key) ? ' siteseo-nav-tab-active' : '';
echo '<a id="' . esc_attr($tab_key) . '-tab" class="siteseo-nav-tab' . esc_attr($active_class) . '" data-tab="' . esc_attr($tab_key) . '">' . esc_html($tab_caption) . '</a>';
}
echo '</div>
<div class="tab-content-wrapper">
<div class="siteseo-tab' .($current_tab == 'tab_knowledge_graph' ? ' active' : '').'" id="tab_knowledge_graph" style="display: none;">';
self::knowledge_graph();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_social_accounts' ? ' active' : '').'" id="tab_social_accounts" style="display: none;">';
self::social_accouts();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_twitter' ? ' active' : '').'" id="tab_twitter" style="display: none;">';
self::twitter();
echo '</div>
<div class="siteseo-tab' .($current_tab == 'tab_facebook' ? ' active' : '').'" id="tab_facebook" style="display: none;">';
self::facebook();
echo '</div>
</div>';
Util::submit_btn();
echo '</form></div>';
}
static function knowledge_graph(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
$options = get_option('siteseo_social_option_name');
//load data
$option_org_type = !empty($options['social_knowledge_type']) ? $options['social_knowledge_type'] : '';
$option_org_name = !empty($options['social_knowledge_name']) ? $options['social_knowledge_name'] : '';
$option_org_logo = !empty($options['social_knowledge_img']) ? $options['social_knowledge_img'] : '';
$option_org_number = !empty($options['social_knowledge_phone']) ? $options['social_knowledge_phone'] : '';
$option_org_contact_type = !empty($options['social_knowledge_contact_type']) ? $options['social_knowledge_contact_type'] : '';
$option_org_contact_option = !empty($options['social_knowledge_contact_option']) ? $options['social_knowledge_contact_option'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Knowledge Graph','siteseo').'</h3>
<p class="description">'.esc_html__('Set up Google Knowledge Graph.','siteseo').'</p>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Person or organization','siteseo').'</th>
<td>
<select name="siteseo_options[org_type]">
<option value="none" '.selected($option_org_type, 'none', false).'>'.esc_html__('None','siteseo').'</option>
<option value="Person" '.selected($option_org_type, 'Person', false).'>'.esc_html__('Person','siteseo').'</option>
<option value="Organization" '.selected($option_org_type, 'Organization', false).'>'.esc_html__('Organization','siteseo').'</option>
</select>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Your name/organization','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[org_name]" value="'.esc_attr($option_org_name).'" placeholder="'.esc_html__('eg.Miremont','siteseo').'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Your photo/organization logo','siteseo').'</th>
<td>
<input id="knowledge_org_logo_url" autocomplete="off" type="text" name="siteseo_options[org_logo]" value="'.esc_url($option_org_logo).'" placeholder="'.esc_html__('select your logo','siteseo').'">
<button id="knowledge_org_logo" class="btn btnSecondary">'.esc_html__('Upload an image','siteseo').'</button>
<p class="description">'.esc_html__('JPG, PNG, WebP and GIF allowed.','siteseo').'</p><br />
<img style="width:300px;max-height:400px;" src="'.esc_url($option_org_logo).'" />
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Organizations phone number (only for Organizations)','siteseo').'</th>
<td>
<input type="text" name="siteseo_options[org_contact_number]" value="'.esc_attr($option_org_number).'" placeholder="'.esc_html__('eg: +33123456789 (internationlized version required)','siteseo').'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Contact type (only for Organizations)','siteseo').'</th>
<td>
<select name="siteseo_options[org_contact_type]">
<option value="Customer support" '.selected($option_org_contact_type, 'Customer support', false).'>'.esc_html__('Customer support','siteseo').'</option>
<option value="Technical support" '.selected($option_org_contact_type, 'Technical support', false).'>'.esc_html__('Technical support','siteseo').'</option>
<option value="Billing support" '.selected($option_org_contact_type, 'Billing support', false).'>'.esc_html__('Billing support','siteseo').'</option>
<option value="Bill payment" '.selected($option_org_contact_type, 'Bill payment', false).'>'.esc_html__('Bill payment','siteseo').'</option>
<option value="Sales payment" '.selected($option_org_contact_type, 'Sales payment', false).'>'.esc_html__('Sales payment','siteseo').'</option>
<option value="Credit card support" '.selected($option_org_contact_type, 'Credit card support', false).'>'.esc_html__('Credit card support','siteseo').'</option>
<option value="Emergency support" '.selected($option_org_contact_type, 'Emergency support', false).'>'.esc_html__('Emergency support','siteseo').'</option>
<option value="Baggage tracking" '.selected($option_org_contact_type, 'Baggage tracking', false).'>'.esc_html__('Baggage tracking','siteseo').'</option>
<option value="Roadside assistance" '.selected($option_org_contact_type, 'Roadside assistance', false).'>'.esc_html__('Roadside assistance','siteseo').'</option>
<option value="Package tracking" '.selected($option_org_contact_type, 'Package tracking', false).'>'.esc_html__('Package tracking','siteseo').'</option>
</select>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Contact option (only for Organizations)','siteseo').'</th>
<td>
<select name="siteseo_options[org_contact_option]">
<option value="None" '.selected($option_org_contact_option, 'None', false).'>'.esc_html__('None','siteseo').'</option>
<option value="TollFree" '.selected($option_org_contact_option, 'TollFree', false).'>'.esc_html__('TollFree', 'siteseo').'</option>
<option value="HearingImpairedSupported" '.selected($option_org_contact_option, 'HearingImpairedSupported', false).'>'.esc_html__('Hearing Impaired Supported','siteseo').'</option>
</select>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[knowledge_graph_tab]" value="1" >';
}
static function social_accouts(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->social_settings;
$options = get_option('siteseo_social_option_name');
//load settings
$facebook_acct = !empty($options['social_accounts_facebook']) ? $options['social_accounts_facebook'] : '';
$twitter_acct = !empty($options['social_accounts_twitter']) ? $options['social_accounts_twitter'] : '';
$instagram_acct = !empty($options['social_accounts_instagram']) ? $options['social_accounts_instagram'] : '';
$youtube_acct = !empty($options['social_accounts_youtube']) ? $options['social_accounts_youtube'] : '';
$pinterest_acct = !empty($options['social_accounts_pinterest']) ? $options['social_accounts_pinterest'] : '';
$additional_acct = !empty($options['social_accounts_additional']) ? implode("\n", $options['social_accounts_additional']) : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Your social accouts', 'siteseo').'</h3>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Facebook', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[facebook]" placeholder="'.esc_html__('eg: https://facebook.com/my-page-url','siteseo').'" value="'.esc_url($facebook_acct).'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('X Username', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[twitter]" placeholder="'.esc_html__('eg : x_username','siteseo').'" value="'.esc_attr($twitter_acct).'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Pinterest URL', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[pinterest]" placeholder="'.esc_html__('eg : https://pinterest.com/my-page-url/','siteseo').'" value="'.esc_url($pinterest_acct).'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Instagram URL', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[instagram]" placeholder="'.esc_html__('eg : https://www.instagram.com/my-page-url/','siteseo').'" value="'.esc_url($instagram_acct).'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('YouTube URL', 'siteseo').'</th>
<td>
<input type="text" name="siteseo_options[youtube]" placeholder="'.esc_html__('eg : https://www.youtube.com/my-channel-url/','siteseo').'" value="'.esc_url($youtube_acct).'">
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Additional Accounts', 'siteseo').'</th>
<td>
<textarea name="siteseo_options[additional]" placeholder="'.esc_html__('eg : https://somesite.com/my-channel-url/','siteseo').'">'.esc_textarea($additional_acct).'</textarea>
<p class="description">'.esc_html__('Enter 1 URL per line.', 'siteseo').'</p>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[social_account_tab]" value="1">';
}
static function twitter(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
//$options = $siteseo->social_settings;
$options = get_option('siteseo_social_option_name');
//load data
$option_enable_card = !empty($options['social_twitter_card']) ? $options['social_twitter_card'] : '';
$option_image_size = !empty($options['social_twitter_card_img_size']) ? $options['social_twitter_card_img_size'] : '';
$option_twitter_img = !empty($options['social_twitter_card_img']) ? $options['social_twitter_card_img'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('X Card','siteseo').'</h3>
<p class="description">'.esc_html__('Manage your X card','siteseo').'</p>
<div class="siteseo-notice">
<span class="dashicons dashicons-info"></span>
<div>
<p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('We generate the %1$s og:image %2$s meta in the following order:', 'siteseo'), '<strong>', '</strong>')).'</p>
<ol>
<li>'.esc_html__('Custom OG Image from the SEO metabox', 'siteseo').'</li>
<li>'.esc_html__('Post thumbnail / Product category thumbnail (Featured image)', 'siteseo').'</li>
<li>'.esc_html__('First image of your post content', 'siteseo').'</li>
<li>'.esc_html__('Global OG Image set in SEO > Social > Open Graph', 'siteseo').'</li>
<li>'.esc_html__('Site icon from the Customizer', 'siteseo').'</li>
</ol>
</div>
</div>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user:select-auto;">'.esc_html__('X Card','siteseo').'</th>
<td>'.esc_html__('Manage your X Card','siteseo').'</td>
</tr>
<tr>
<th scope="row" style="user:select-auto;">'.esc_html__('Enable X Card','siteseo').'</th>
<td>
<label for="enable_twitter_card"><input id="enable_twitter_card" type="checkbox" name="siteseo_options[enable_twitter_card]" '.(!empty($option_enable_card) ? 'checked="checked"' : 'value="1"') . '>'.esc_html__('Enable X card', 'siteseo') .'</label>
</td>
</tr>
<tr>
<th scope="row" style="user:select-auto;">'.esc_html__('Default X Image','siteseo').'</th>
<td>
<input type="text" id="twitter_logo_url" autocomplete="off" name="siteseo_options[twitter_img]" value="'.esc_url($option_twitter_img).'" placeholder="'.esc_html__('Choose your default thumbnail.','siteseo').'">
<button id="twitter_logo" class="btn btnSecondary">'.esc_html__('Upload a image','siteseo').'</button>
<p class="description">'.esc_html__('Minimum size: 144x144px (300x157px with large card), recommended aspect ratio 1:1 (2:1 for large card), maximum file size 5MB.','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row" style="user:select-auto;">'.esc_html__('X Card Image Size','siteseo').'</th>
<td>
<select name="siteseo_options[image_size]">
<option value="Default" '.selected($option_image_size, 'Default', false).'>'.esc_html__('Default','siteseo').'</option>
<option value="Large" '.selected($option_image_size, 'Large', false).'>'.esc_html__('Large','siteseo').'</option>
</select>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[twitter_tab]" value="1">';
}
static function facebook(){
global $siteseo;
if(!empty($_POST['submit'])){
self::save_settings();
}
// load seetings
//$options = $siteseo->social_settings;
$options = get_option('siteseo_social_option_name');
$option_fb_enable_og = !empty($options['social_facebook_og']) ? $options['social_facebook_og'] : '';
$option_fb_img = !empty($options['social_facebook_img']) ? $options['social_facebook_img'] : '';
$option_fb_defult_img = !empty($options['social_facebook_img_default']) ? $options['social_facebook_img_default'] : '';
$option_fb_ownership = !empty($options['social_facebook_link_ownership_id']) ? $options['social_facebook_link_ownership_id'] : '';
$option_fb_admin_id = !empty($options['social_facebook_admin_id']) ? $options['social_facebook_admin_id'] : '';
echo '<h3 class="siteseo-tabs">'.esc_html__('Facebook (Open Graph)','siteseo').'</h3>
<p class="description">'.esc_html__('Manage Open Graph data to enhance how your links appear on platforms like Facebook, Pinterest, LinkedIn, and WhatsApp when shared. Improve your click-through rate by including relevant details, such as an attention-grabbing image.','siteseo').'<p>
<div class="siteseo-notice">
<span class="dashicons dashicons-info"></span>
<div>
<p> '.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('We generate the %1$s OG:image %2$s meta in the following sequence:', 'siteseo'), '<strong>', '</strong>')).'</p>
<ol>
<li>'.esc_html__('Custom OG image from the SEO metabox', 'siteseo').'</li>
<li>'.esc_html__('Post thumbnail / Product category thumbnail (Featured image)', 'siteseo').'</li>
<li>'.esc_html__('First image in your post content', 'siteseo').'</li>
<li>'.esc_html__('Global OG:image set in SEO > Social > OG Card', 'siteseo').'</li>
</ol>
</div>
</div>
<table class="form-table">
<tbody>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Enable OG date','siteseo').'</th>
<td>
<label for="facebook_graph_enable">
<input id="facebook_graph_enable" type="checkbox" name="siteseo_options[enable_fb_og]" '.(!empty($option_fb_enable_og) ? 'checked="yes"' : 'value="1"').'>'. esc_html__('Enable OG data','siteseo') .'
</label>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Default Image','siteseo').'</th>
<td>
<input id="facebook_org_image_url" autocomplete="off" type="text" name="siteseo_options[fb_image]" value="'.esc_url($option_fb_img).'" palceholder="'.esc_html__('Select your default thumbnail','siteseo').'">
<button id="facebook_upload_logo" class="btn btnSecondary">'.esc_html__('Upload a image','siteseo').'</button>
<p class="description">'.esc_html__('Minimum size: 200x200px, ideal ratio 1.91:1, 8MB max. (e.g., 1640x856px or 3280x1712px for retina screens).','siteseo').'</p>
<p class="description">'.esc_html__('If no default image is set, we will use your site icon defined in the Customizer.','siteseo').'</p>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto;">'.esc_html__('Override Default Image','siteseo').'</th>
<td>
<div class="siteseo_wrap_label">
<label for="override_image_tag">
<input id="override_image_tag" type="checkbox" name="siteseo_options[fb_default_img]" '.(!empty($option_fb_defult_img) ? 'checked="yes"' : 'value="1"').' >'.esc_html__('Override all og:image tags with this default image, unless a custom og:image has been set in the SEO metabox.','siteseo').'
</label>
</div>
<br /><div class="siteseo-notice is-warning"><p>'.
/* translators: placeholders are just <strong> tag */
wp_kses_post(sprintf(__('Please define a default %1$s OG image %2$s using the field above.', 'siteseo'), '<strong>','</strong>')).'<p></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto">'.esc_html__('Link Ownership ID','siteseo').'</th>
<td>
<input type="text" placeholder="0123456789" name="siteseo_options[fb_owership_id]" value="'.esc_attr($option_fb_ownership).'">
<p class="description">'.esc_html__('Enter one or more Facebook Page IDs linked to a URL to enable link editing and instant article publishing.','siteseo').'</p>
<div class="siteseo-styles pre"><pre>'.esc_html('<meta property="fb:pages" content="page ID"/>').'</pre></div>
</td>
</tr>
<tr>
<th scope="row" style="user-select:auto">'.esc_html__('Admin ID','siteseo').'</th>
<td>
<input type="text" placeholder="0123456789" name="siteseo_options[fb_admin_id]" value="'.esc_attr($option_fb_admin_id).'">
<p class="description">'.esc_html__('The ID (or a comma-separated list for properties that support multiple IDs) of an app, user of the app, or Page Graph API object.', 'siteseo').'</p>
<div class="siteseo-styles pre"><pre>'.esc_html('<meta property="fb:admins" content="admins ID"/>').'</pre></div>
</td>
</tr>
</tbody>
</table><input type="hidden" name="siteseo_options[facebook_tab]" value="1">';
}
static function save_settings(){
global $siteseo;
check_admin_referer('siteseo_social_settings');
if(!siteseo_user_can('manage_social') || !is_admin()){
return;
}
$options = [];
if(empty($_POST['siteseo_options'])){
return;
}
if(isset($_POST['siteseo_options']['knowledge_graph_tab'])){
$options['social_knowledge_type'] = isset($_POST['siteseo_options']['org_type']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_type'])) : '';
$options['social_knowledge_name'] = isset($_POST['siteseo_options']['org_name']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_name'])) : '';
$options['social_knowledge_img'] = isset($_POST['siteseo_options']['org_logo']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_logo'])) : '';
$options['social_knowledge_phone'] = isset($_POST['siteseo_options']['org_contact_number']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_contact_number'])) : '';
$options['social_knowledge_contact_type'] = isset($_POST['siteseo_options']['org_contact_type']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_contact_type'])) : '';
$options['social_knowledge_contact_option'] = isset($_POST['siteseo_options']['org_contact_option']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['org_contact_option'])) : '';
}
if(isset($_POST['siteseo_options']['social_account_tab'])){
$options['social_accounts_facebook'] = isset($_POST['siteseo_options']['facebook']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['facebook'])) : '';
$options['social_accounts_twitter'] = isset($_POST['siteseo_options']['twitter']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['twitter'])) : '';
$options['social_accounts_instagram'] = isset($_POST['siteseo_options']['instagram']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['instagram'])) : '';
$options['social_accounts_youtube'] = isset($_POST['siteseo_options']['youtube']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['youtube'])) : '';
$options['social_accounts_pinterest'] = isset($_POST['siteseo_options']['pinterest']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['pinterest'])) : '';
$options['social_accounts_additional'] = isset($_POST['siteseo_options']['additional']) ? explode("\n", sanitize_textarea_field(wp_unslash($_POST['siteseo_options']['additional']))) : '';
$options['social_accounts_additional'] = Util::clean_url($options['social_accounts_additional']); // We accept 1 url per line.
}
if(isset($_POST['siteseo_options']['facebook_tab'])){
$options['social_facebook_og'] = isset($_POST['siteseo_options']['enable_fb_og']);
$options['social_facebook_img'] = isset($_POST['siteseo_options']['fb_image']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['fb_image'])) : '';
$options['social_facebook_img_default'] = isset($_POST['siteseo_options']['fb_default_img']);
$options['social_facebook_link_ownership_id'] = isset($_POST['siteseo_options']['fb_owership_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['fb_owership_id'])) : '';
$options['social_facebook_admin_id'] = isset($_POST['siteseo_options']['fb_admin_id']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['fb_admin_id'])) : '';
}
if(isset($_POST['siteseo_options']['twitter_tab'])){
$options['social_twitter_card'] = isset($_POST['siteseo_options']['enable_twitter_card']);
$options['social_twitter_card_img'] = isset($_POST['siteseo_options']['twitter_img']) ? sanitize_url(wp_unslash($_POST['siteseo_options']['twitter_img'])) : '';
$options['social_twitter_card_img_size'] = isset($_POST['siteseo_options']['image_size']) ? sanitize_text_field(wp_unslash($_POST['siteseo_options']['image_size'])) : '';
}
update_option('siteseo_social_option_name' , $options);
}
}
socialmetas.php 0000644 00000071035 15152641524 0007574 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class SocialMetas{
static function add_social_graph(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-social'])){
return;
}
$org_type = !empty($siteseo->social_settings['social_knowledge_type']) && $siteseo->social_settings['social_knowledge_type'] !== 'none' ? $siteseo->social_settings['social_knowledge_type'] : '';
$org_name = !empty($siteseo->social_settings['social_knowledge_name']) ? $siteseo->social_settings['social_knowledge_name'] : '';
$org_logo = !empty($siteseo->social_settings['social_knowledge_img']) ? $siteseo->social_settings['social_knowledge_img'] : '';
$org_number = !empty($siteseo->social_settings['social_knowledge_phone']) ? $siteseo->social_settings['social_knowledge_phone'] : '';
$org_contact_type = !empty($siteseo->social_settings['social_knowledge_contact_type']) ? $siteseo->social_settings['social_knowledge_contact_type'] : '';
$org_contact_option = !empty($siteseo->social_settings['social_knowledge_contact_option']) ? $siteseo->social_settings['social_knowledge_contact_option'] : '';
$fb_account = !empty($siteseo->social_settings['social_accounts_facebook']) ? $siteseo->social_settings['social_accounts_facebook'] : '';
$twitter_account = !empty($siteseo->social_settings['social_accounts_twitter']) ? $siteseo->social_settings['social_accounts_twitter'] : '';
$insta_account = !empty($siteseo->social_settings['social_accounts_instagram']) ? $siteseo->social_settings['social_accounts_instagram'] : '';
$yt_account = !empty($siteseo->social_settings['social_accounts_youtube']) ? $siteseo->social_settings['social_accounts_youtube'] : '';
$pt_account = !empty($siteseo->social_settings['social_accounts_pinterest']) ? $siteseo->social_settings['social_accounts_pinterest'] : '';
//description
$site_url = get_site_url();
$site_description = get_bloginfo('name');
$site_language = get_bloginfo('language');
// logo
$logo_id = attachment_url_to_postid($org_logo);
// Defaults
$logo_width = '';
$logo_height = '';
// Get image dimensions if attachment exists
if(!empty($logo_id)){
$image_data = wp_get_attachment_image_src($logo_id, 'full');
if(!empty($image_data)){
$logo_width = $image_data[1];
$logo_height = $image_data[2];
}
}
//JSON-LD data
$json_ld = [
'@context' => 'https://schema.org',
'@type' => $org_type ? esc_html($org_type) : 'Organization',
'@id' => esc_url(trailingslashit($site_url) . '#' . $org_type),
'name' => esc_html($org_name),
'url' => esc_url($site_url),
'logo' => array_filter([
'@type' => 'ImageObject',
'@id' => esc_url(trailingslashit($site_url) . '#logo'),
'url' => esc_url($org_logo),
'contentUrl' => esc_url($org_logo),
'caption' => esc_html($org_name),
'inLanguage' => esc_html($site_language),
'width' => $logo_width,
'height' => $logo_height,
]),
'description' => esc_html($site_description),
];
//contact point
if(!empty($org_contact_type) && !empty($org_number)){
$json_ld['contactPoint'] = [
'@type' => 'ContactPoint',
'contactType' => esc_html($org_contact_type),
'telephone' => esc_html($org_number),
];
if(!empty($org_contact_option) && $org_contact_option !== 'None'){
$contact_point['contactOption'] = esc_html($org_contact_option);
}
}
$x_url = 'https://x.com/'.$twitter_account;
$same_as = array_filter([
esc_url($fb_account),
esc_url($x_url),
esc_url($insta_account),
esc_url($yt_account),
esc_url($pt_account)
]);
if(!empty($same_as)){
$json_ld['sameAs'] = array_values($same_as);
}
// Output JSON-LD script
echo '<script type="application/ld+json">';
echo wp_json_encode($json_ld, JSON_UNESCAPED_SLASHES);
echo '</script>';
}
static function fb_graph(){
global $siteseo, $post;
if(empty($siteseo->setting_enabled['toggle-social']) || empty($siteseo->social_settings['social_facebook_og'])){
return;
}
$fb_page_id = !empty($siteseo->social_settings['social_facebook_link_ownership_id']) ? $siteseo->social_settings['social_facebook_link_ownership_id'] : '';
$fb_link_owership = !empty($siteseo->social_settings['social_facebook_admin_id']) ? $siteseo->social_settings['social_facebook_admin_id'] : '';
$og_url = get_home_url();
$og_sitename = get_bloginfo('name');
// Check
$post_id = isset($post) && is_object($post) ? $post->ID : '';
$og_title = get_the_title();
$og_description = get_bloginfo('description');
$og_img = !empty($siteseo->social_settings['social_facebook_img']) ? $siteseo->social_settings['social_facebook_img'] : '';
// Get post types and taxonomies
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
// home site page
if(is_home() && is_front_page()){
$og_title = !empty($siteseo->titles_settings['titles_home_site_title']) ? $siteseo->titles_settings['titles_home_site_title'] : $og_title;
$og_description = !empty($siteseo->titles_settings['titles_home_site_desc']) ? $siteseo->titles_settings['titles_home_site_desc'] : $og_description;
}
// single post types
foreach($post_types as $post_type){
// shop page woocommerces
if(function_exists('is_shop') && is_shop()){
$shop_page_id = !defined('SITEPAD') ? wc_get_page_id('shop') : kkart_get_page_id('shop');
$archive_title = '';
$archive_desc = '';
if(is_post_type_archive()){
$obj = get_queried_object();
if(!empty($obj) && isset($obj->name)){
$archive_title = !empty($obj->labels->name) ? $obj->labels->name : '';
$archive_desc = !empty($obj->description) ? $obj->description : '';
}
}
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_fb_title', true))){
$og_title = get_post_meta($shop_page_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($shop_page_id, '_siteseo_titles_title', true))){
$og_title = get_post_meta($shop_page_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_archive_titles']['product']['archive_title'])){
$og_title = $siteseo->titles_settings['titles_archive_titles']['product']['archive_title'];
} else {
$og_title = $archive_title;
}
$og_description = !empty(get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true)) ? get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true) : $og_description;
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true))){
$og_description = get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($shop_page_id, '_siteseo_titles_desc', true))){
$og_description = get_post_meta($shop_page_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_archive_titles']['product']['archive_desc'])){
$og_description = $siteseo->titles_settings['titles_archive_titles']['product']['archive_desc'];
} else {
$og_description = $archive_desc;
}
$og_description = esc_attr(\SiteSEO\TitlesMetas::replace_variables($og_description));
// OG:IMG
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_fb_img', true))){
$og_img = get_post_meta($shop_page_id, '_siteseo_social_fb_img', true);
} else if(get_the_post_thumbnail_url($post, 'full')){
$og_img = get_the_post_thumbnail_url($post, 'full');
} else {
$og_img = !empty($siteseo->social_settings['social_facebook_img']) ? $siteseo->social_settings['social_facebook_img'] : '';
}
$og_url = urldecode(get_permalink($shop_page_id));
break;
}
// archive page
if($post_type->has_archive && is_post_type_archive($post_type->name)){
$archive_title = '';
$archive_desc = '';
if(is_post_type_archive()){
$obj = get_queried_object();
if(!empty($obj) && isset($obj->name)){
$archive_title = !empty($obj->labels->name) ? $obj->labels->name : '';
$archive_desc = !empty($obj->description) ? $obj->description : '';
}
}
$og_title = !empty($siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_title']) ? $siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_title'] : $archive_title;
$og_description = !empty($siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_desc']) ? $siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_desc'] : $archive_desc;
}
// blog page
if(is_home() && !is_front_page()){
$post_id = get_option('page_for_posts');
//OG:title
if(!empty(get_post_meta($post_id, '_siteseo_social_fb_title', true))){
$og_title = get_post_meta($post_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_title', true))){
$og_title = get_post_meta($post_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'])){
$og_title = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'];
} else{
$og_title = $og_title;
}
// og:description
if(!empty(get_post_meta($post_id, '_siteseo_social_fb_desc', true))){
$og_description = get_post_meta($post_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_desc', true))){
$og_description = get_post_meta($post_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'])){
$og_description = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'];
} elseif(get_the_excerpt($post_id)){
$og_description = wp_trim_words(get_the_excerpt($post_id), 50);
}
}
if(is_singular($post_type->name)){
if(!empty(get_post_meta($post_id, '_siteseo_social_fb_title', true))){
$og_title = get_post_meta($post_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_title', true))){
$og_title = get_post_meta($post_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'])){
$og_title = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'];
} else{
$og_title = $og_title;
}
// og:description
if(!empty(get_post_meta($post_id, '_siteseo_social_fb_desc', true))){
$og_description = get_post_meta($post_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_desc', true))){
$og_description = get_post_meta($post_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'])){
$og_description = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'];
} elseif(get_the_excerpt($post_id)){
$og_description = wp_trim_words(get_the_excerpt($post_id), 50);
}
// OG:IMG
if(!empty(get_post_meta($post_id, '_siteseo_social_fb_img', true))){
$og_img = get_post_meta($post_id, '_siteseo_social_fb_img', true);
} else if(get_the_post_thumbnail_url($post, 'full')){
$og_img = get_the_post_thumbnail_url($post, 'full');
} else {
$og_img = !empty($siteseo->social_settings['social_facebook_img']) ? $siteseo->social_settings['social_facebook_img'] : '';
}
$og_url = urldecode(get_permalink($post_id));
break;
}
}
// taxonomies
foreach($taxonomies as $taxonomy){
if(is_tax($taxonomy->name) || is_category() || is_tag()){
$term = get_queried_object();
$term_id = $term->term_id;
// og:title
if(!empty(get_term_meta($term_id, '_siteseo_social_fb_title', true))){
$og_title = get_term_meta($term_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_term_meta($term_id, '_siteseo_titles_title', true))){
$og_title = get_term_meta($term_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['title'])){
$og_title = $siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['title'];
} else{
$og_title = $og_title;
}
// og:description
if(!empty(get_term_meta($term_id, '_siteseo_social_fb_desc', true))){
$og_description = get_term_meta($term_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_term_meta($term_id, '_siteseo_titles_desc', true))){
$og_description = get_term_meta($term_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['description'])){
$og_description = $siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['description'];
} else{
$og_description = wp_strip_all_tags(term_description($term_id));
}
$og_img = !empty(get_term_meta($term_id, '_siteseo_social_fb_img', true)) ? get_term_meta($term_id, '_siteseo_social_fb_img', true) : $og_img;
$og_url = urldecode(get_term_link($term_id));
break;
}
}
$og_title = esc_attr(\SiteSEO\TitlesMetas::replace_variables($og_title));
$og_description = esc_attr(\SiteSEO\TitlesMetas::replace_variables($og_description));
if(!empty($og_img)){
$og_img = sanitize_url($og_img);
$og_img_width = 0;
$og_img_height = 0;
if(!empty($og_img)){
$image_info = @getimagesize($og_img);
if($image_info !== false){
$og_img_width = $image_info[0];
$og_img_height = $image_info[1];
}
}
}
// Setting og:type
if(is_home() || is_front_page()){
$og_type = 'website'; // default website
} elseif(is_singular('product') || is_singular('download')){
$og_type = 'product';
} elseif(is_singular()){
$og_type = 'article';
} elseif(is_search() || is_archive() || is_404()){
$og_type = 'object';
}
if(!empty($og_url)){
echo '<meta property="og:url" content="'.esc_html($og_url).'" />';
}
if(!empty($og_sitename)){
echo '<meta property="og:site_name" content="'.esc_html($og_sitename).'" />';
}
if(function_exists('get_locale')){
echo '<meta property="og:locale" content="'.esc_html(get_locale()).'" />';
}
if(!empty($og_type)){
echo '<meta property="og:type" content="'.esc_attr($og_type).'" />';
}
if(!empty($og_title)){
echo '<meta property="og:title" content="'.esc_html($og_title).'" />';
}
if(!empty($og_description)){
echo '<meta property="og:description" content="'.esc_html($og_description).'" />';
}
if(!empty($og_img)){
echo '<meta property="og:image" content="'.esc_html($og_img).'" />';
if(is_ssl()){
echo '<meta property="og:secure_url" content="'.esc_html($og_img).'" />';
}
}
if(!empty($og_img_height)){
echo '<meta property="og:image:height" content="'.esc_attr($og_img_height).'" />';
}
if(!empty($og_img_width)){
echo '<meta property="og:image:width" content="'.esc_attr($og_img_width).'" />';
}
if(!empty($fb_page_id)){
echo '<meta property="fb:pages" content="'.esc_html($fb_page_id) .'" />';
}
if(!empty($fb_link_owership)){
echo '<meta property="fb:admins" content="'. esc_html($fb_link_owership).'" />';
}
}
static function twitter_card(){
global $siteseo, $post;
if(empty($siteseo->setting_enabled['toggle-social']) || empty($siteseo->social_settings['social_twitter_card'])){
return;
}
$site_url = get_home_url();
$twitter_user_name = !empty($siteseo->social_settings['social_accounts_twitter']) ? $siteseo->social_settings['social_accounts_twitter'] : '';
$post_id = isset($post) && is_object($post) ? $post->ID : '';
$site_title = get_the_title();
$site_description = get_bloginfo('description');
$twitter_img = !empty($siteseo->social_settings['social_twitter_card_img']) ? $siteseo->social_settings['social_twitter_card_img'] : '';
if(empty($twitter_img)){
$twitter_img = !empty($siteseo->social_settings['social_facebook_img']) ? $siteseo->social_settings['social_facebook_img'] : '';
}
// home site page
if(is_home() && is_front_page()){
$site_title = !empty($siteseo->titles_settings['titles_home_site_title']) ? $siteseo->titles_settings['titles_home_site_title'] : $site_title;
$site_description = !empty($siteseo->titles_settings['titles_home_site_desc']) ? $siteseo->titles_settings['titles_home_site_desc'] : $site_description;
}
// types and taxonomies
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
// single post types
foreach($post_types as $post_type){
// woocommerce
if(function_exists('is_shop') && is_shop()){
$shop_page_id = !defined('SITEPAD') ? wc_get_page_id('shop') : kkart_get_page_id('shop');
$archive_title = '';
$archive_desc = '';
// if all x-meta tags empty then use og option is enabled
$use_og = (empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_img', true)));
if(is_post_type_archive()){
$obj = get_queried_object();
if(!empty($obj) && isset($obj->name)){
$archive_title = !empty($obj->labels->name) ? $obj->labels->name : '';
$archive_desc = !empty($obj->description) ? $obj->description : '';
}
}
// twitter:title
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_twitter_title', true))){
$site_title = get_post_meta($shop_page_id, '_siteseo_social_twitter_title', true);
} elseif(!empty($use_og) && !empty(get_post_meta($shop_page_id, '_siteseo_social_fb_title', true))){
$site_title = get_post_meta($shop_page_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($shop_page_id, '_siteseo_titles_title', true))){
$site_title = get_post_meta($shop_page_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_archive_titles']['product']['archive_title'])){
$site_title = $siteseo->titles_settings['titles_archive_titles']['product']['archive_title'];
} else {
$site_title = $archive_title;
}
// twitter:description
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_twitter_desc', true))){
$site_description = get_post_meta($shop_page_id, '_siteseo_social_twitter_desc', true);
} elseif(!empty($use_og) && !empty(get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true))){
$site_description = get_post_meta($shop_page_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($shop_page_id, '_siteseo_titles_desc', true))){
$site_description = get_post_meta($shop_page_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_archive_titles']['product']['archive_desc'])){
$site_description = $siteseo->titles_settings['titles_archive_titles']['product']['archive_desc'];
} else {
$site_description = $archive_desc;
}
// twitter:image
if(!empty(get_post_meta($shop_page_id, '_siteseo_social_twitter_img', true))){
$twitter_img = get_post_meta($shop_page_id, '_siteseo_social_twitter_img', true);
} elseif(!empty($use_og) && !empty(get_post_meta($shop_page_id, '_siteseo_social_fb_img', true))){
$twitter_img = get_post_meta($shop_page_id, '_siteseo_social_fb_img', true);
} elseif(get_the_post_thumbnail_url($post, 'full')){
$twitter_img = get_the_post_thumbnail_url($post, 'full');
} else {
$twitter_img = isset($siteseo->social_settings['social_twitter_card_img']) ? $siteseo->social_settings['social_twitter_card_img'] : '';
}
$site_url = urldecode(get_permalink($shop_page_id));
break;
}
// archive page
if($post_type->has_archive && is_post_type_archive($post_type->name)){
$archive_title = '';
$archive_desc = '';
if(is_post_type_archive()){
$obj = get_queried_object();
if(!empty($obj) && isset($obj->name)){
$archive_title = !empty($obj->labels->name) ? $obj->labels->name : '';
$archive_desc = !empty($obj->description) ? $obj->description : '';
}
}
$site_title = !empty($siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_title']) ? $siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_title'] : $archive_title;
$site_description = !empty($siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_desc']) ? $siteseo->titles_settings['titles_archive_titles'][$post_type->name]['archive_desc'] : $archive_desc;
}
// blog page
if(is_home() && !is_front_page()){
$post_id = get_option('page_for_posts');
$use_og = (empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_img', true)));
// twitter:title
if(!empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_social_twitter_title', true);
} elseif(!empty($use_og) && !empty(get_post_meta($post_id, '_siteseo_social_fb_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'])){
$site_title = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'];
} else{
$site_title = $site_title;
}
// twitter:description
if(!empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_social_twitter_desc', true);
} elseif(!empty($use_og) && !empty(get_post_meta($post_id, '_siteseo_social_fb_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'])){
$site_description = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'];
} elseif(!empty(get_the_excerpt($post_id))){
$site_description = wp_trim_words(get_the_excerpt($post_id), 50);
}
}
if(is_singular($post_type->name)){
$use_og = (empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_img', true)));
// twitter:title
if(!empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_social_twitter_title', true);
} elseif(!empty($use_og) && !empty(get_post_meta($post_id, '_siteseo_social_fb_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_title', true))){
$site_title = get_post_meta($post_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'])){
$site_title = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['title'];
} else{
$site_title = $site_title;
}
// twitter:description
if(!empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_social_twitter_desc', true);
} elseif(!empty($use_og) && !empty(get_post_meta($post_id, '_siteseo_social_fb_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_post_meta($post_id, '_siteseo_titles_desc', true))){
$site_description = get_post_meta($post_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'])){
$site_description = $siteseo->titles_settings['titles_single_titles'][$post_type->name]['description'];
} else{
$site_description = wp_trim_words(get_the_excerpt($post_id), 50);
}
// twitter:image
if(!empty(get_post_meta($post_id, '_siteseo_social_twitter_img', true))){
$twitter_img = get_post_meta($post_id, '_siteseo_social_twitter_img', true);
} elseif(!empty($use_og) && !empty(get_post_meta($post_id, '_siteseo_social_fb_img', true))){
$twitter_img = get_post_meta($post_id, '_siteseo_social_fb_img', true);
} else if(get_the_post_thumbnail_url($post, 'full')){
$twitter_img = get_the_post_thumbnail_url($post, 'full');
} else {
$twitter_img = isset($siteseo->social_settings['social_twitter_card_img']) ? $siteseo->social_settings['social_twitter_card_img'] : '';
}
$site_url = urldecode(get_permalink($post_id));
break;
}
}
//taxonomies
foreach($taxonomies as $taxonomy){
if(is_tax($taxonomy->name) || is_category() || is_tag()){
$term = get_queried_object();
$term_id = $term->term_id;
$use_og = (empty(get_post_meta($post_id, '_siteseo_social_twitter_title', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_desc', true)) && empty(get_post_meta($post_id, '_siteseo_social_twitter_img', true)));
//twitter:title
if(!empty(get_term_meta($term_id, '_siteseo_social_twitter_title', true))){
$site_title = get_term_meta($term_id, '_siteseo_social_twitter_title', true);
} elseif(!empty($use_og) && !empty(get_term_meta($term_id, '_siteseo_social_fb_title', true))){
$site_title = get_term_meta($term_id, '_siteseo_social_fb_title', true);
} elseif(!empty(get_term_meta($term_id, '_siteseo_titles_title', true))){
$site_title = get_term_meta($term_id, '_siteseo_titles_title', true);
} elseif(!empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['title'])){
$site_title = $siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['title'];
} else{
$site_title = $site_title;
}
// twitter description
if(!empty(get_term_meta($term_id, '_siteseo_social_twitter_desc', true))){
$site_description = get_term_meta($term_id, '_siteseo_social_twitter_desc', true);
} elseif(!empty($use_og) && !empty(get_term_meta($term_id, '_siteseo_social_fb_desc', true))){
$site_description = get_term_meta($term_id, '_siteseo_social_fb_desc', true);
} elseif(!empty(get_term_meta($term_id, '_siteseo_titles_desc', true))){
$site_description = get_term_meta($term_id, '_siteseo_titles_desc', true);
} elseif(!empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['description'])){
$site_description = $siteseo->titles_settings['titles_tax_titles'][$taxonomy->name]['description'];
} else{
$site_description = wp_strip_all_tags(term_description($term_id));
}
$twitter_img = !empty(get_term_meta($term_id, '_siteseo_social_twitter_img', true)) ? get_term_meta($term_id, '_siteseo_social_twitter_img', true) : '';
if(empty($twitter_img) && !empty($use_og) && !empty(get_term_meta($term_id, '_siteseo_social_fb_img', true))){
$twitter_img = get_term_meta($term_id, '_siteseo_social_fb_img', true);
} else{
$twitter_img = $twitter_img;
}
$site_url = urldecode(get_term_link($term_id));
break;
}
}
$site_title = esc_attr(\SiteSEO\TitlesMetas::replace_variables($site_title));
$site_description = esc_attr(\SiteSEO\TitlesMetas::replace_variables($site_description));
$x_image_size = 'summary';
if(!empty($siteseo->social_settings['social_twitter_card_img_size']) && $siteseo->social_settings['social_twitter_card_img_size'] == 'Large'){
$x_image_size = 'summary_large_image';
}
echo '<meta name="twitter:card" content="'.esc_attr($x_image_size).'"/>';
echo '<meta name="twitter:locale" content="'.esc_html(get_locale()).'"/>';
if(!empty($site_title)){
echo '<meta name="twitter:title" content="'.esc_html($site_title).'"/>';
}
if(!empty($site_description)){
echo '<meta name="twitter:description" content="'.esc_html($site_description).'"/>';
}
if(!empty($site_url)){
echo '<meta name="twitter:url" content="'.esc_html($site_url).'"/>';
}
if(!empty($twitter_user_name)){
$twitter_user_name = trim($twitter_user_name, '@');
echo '<meta name="twitter:site" content="@'.esc_html($twitter_user_name).'"/>';
}
if(!empty($twitter_img)){
echo '<meta name="twitter:image" content="'.esc_html($twitter_img).'"/>';
}
}
}
tableofcontent.php 0000644 00000012407 15152641524 0010275 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
use DOMDocument;
use DOMXPath;
class TableofContent{
static function enable_toc(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced']) || empty($siteseo->advanced_settings['toc_enable'])){
return;
}
add_filter('the_content', '\SiteSEO\TableofContent::add_ids_to_headings');
}
static function render_toc(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced']) || empty($siteseo->advanced_settings['toc_enable'])){
return;
}
static $siteseo_toc_run = false;
if(!empty($siteseo_toc_run)){
return '<p style="padding: 1rem; background-color:#fff3cd; color:#664d03; border:1px solid #ffe69c; border-radius: 0.375rem">'.esc_html__('Table of content shortcode can be used only once on a page, this page is using the shortcode more than once. Please remove the extra table of content shortcodes for this warning to go away.', 'siteseo').'</p>';
}
$options = get_option('siteseo_advanced_option_name');
//$options = $siteseo->advanced_settings;
$content = get_the_content();
if(empty($content)){
return;
}
$heading_type = (!empty($options['toc_heading_type']) ? $options['toc_heading_type'] : 'ul');
$dom = new DOMDocument();
$internalErrors = libxml_use_internal_errors(true);
$dom->preserveWhiteSpace = false;
$html = '';
if($dom->loadHTML('<?xml encoding="utf-8" ?>' . $content)){
$xpath = new DOMXPath($dom);
$heading_list = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
$headings_to_scan = [];
foreach($heading_list as $h){
if(!empty($options['toc_excluded_headings']) && is_array($options['toc_excluded_headings']) && in_array($h, $options['toc_excluded_headings'])){
continue;
}
$headings_to_scan[] = '//'.$h;
}
if(empty($headings_to_scan)){
return;
}
$headings_to_scan = implode('|', $headings_to_scan);
// The imploded string will look like this //h1|//h2|//h3|//h4|//h5|//h6
$headings = $xpath->query($headings_to_scan);
if(empty($headings)){
return;
}
$last_h = 0;
$open_ul = 0;
$html .= '<style>.siteseo-toc-wrapper { padding: 20px; border: 1px solid #a2a9b1; background-color: #f8f9fa;}.siteseo-toc-wrapper p { display:flex; align-items:center; gap: 10px; font-size: 1.5rem; font-weight: 500; margin: 0 0 10px 0;}.siteseo-toc-wrapper > '.esc_html($heading_type).' { margin: 0; padding: 0;}.siteseo-toc-wrapper p>label { font-weight: 400; font-size: 0.9rem;}#siteseo-toc-toggle~span { cursor: pointer;}#siteseo-toc-toggle:checked~.siteseo-toc-hide,p:has(#siteseo-toc-toggle:checked) ~ '.esc_html($heading_type).' { display: none;}#siteseo-toc-toggle:not(:checked) ~ .siteseo-toc-hide{ display: inline;}#siteseo-toc-toggle:not(:checked) ~ .siteseo-toc-show { display: none;}</style>
<div class="siteseo-toc-wrapper">
<p>'.(!empty($options['toc_label']) ? esc_html($options['toc_label']) : esc_html__('Table of Content', 'siteseo')).' <label for="siteseo-toc-toggle">
<input type="checkbox" style="display:none;" id="siteseo-toc-toggle" name="siteseo-toc-toggle"/>
[<span class="siteseo-toc-hide">hide</span><span class="siteseo-toc-show">show</span>]</label></p>
<'.esc_html($heading_type).'>';
foreach($headings as $heading){
$title = trim(wp_strip_all_tags($heading->nodeValue));
$id = $heading->getAttribute('id');
$current_h = (int) substr($heading->tagName, 1);
if(empty($id)){
$id = '#'.self::title_to_id($title);
}else{
$id = '#'.$id;
}
if($current_h > $last_h){
$html .= '<'.esc_html($heading_type).'>';
$open_ul++;
}else{
while($current_h <= $open_ul){
$html .= '</'.esc_html($heading_type).'>';
$open_ul--;
}
}
$html .= '<li><a href="'.esc_attr($id).'">'.esc_html($title).'</a></li>';
$last_h = $current_h;
}
$html .= '</'.esc_html($heading_type).'></div>';
$siteseo_toc_run = true;
}
return $html;
}
// Converts heading text content to ID to be used as link
static function title_to_id($title){
$id = trim(wp_strip_all_tags($title));
$id = remove_accents($title);
$id = sanitize_title_with_dashes($id);
$id = urlencode($id);
return $id;
}
static function add_ids_to_headings($content){
if(empty($content)){
return $content;
}
// If the page does not have the shortcode then we don't need to update the id's in the heading.
if(!has_shortcode($content, 'siteseo_toc')){
return $content;
}
$dom = new DOMDocument();
$internalErrors = libxml_use_internal_errors(true);
$dom->preserveWhiteSpace = false;
$html = '';
if($dom->loadHTML('<?xml encoding="utf-8" ?>' . $content)){
$xpath = new DOMXPath($dom);
$headings = $xpath->query('//h1|//h2|//h3|//h4|//h5|//h6');
if(empty($headings)){
return;
}
foreach($headings as $heading){
$title = trim(wp_strip_all_tags($heading->nodeValue));
$id = $heading->getAttribute('id');
if(!empty($id)){
continue;
}
if(empty($title)){
continue;
}
$id = self::title_to_id($title);
$heading->setAttribute('id', $id);
}
$content = $dom->saveHTML($dom->documentElement);
}
return $content;
}
} instantindexing.php 0000644 00000021554 15152641524 0010477 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class InstantIndexing{
static function bing_txt_file(){
global $wp, $siteseo;
$request = home_url($wp->request);
if(empty($request)){
return;
}
$api_key = $siteseo->instant_settings['instant_indexing_bing_api_key'];
$api_url = trailingslashit(home_url()) . $api_key . '.txt';
if($request == $api_url){
header('X-Robots-Tag: noindex');
header('Content-Type: text/plain');
status_header(200);
echo esc_html($api_key);
die();
}
}
static function submit_urls_to_google($urls){
$access_token = self::get_google_auth_token();
if(empty($access_token)){
return;
}
$boundary = wp_rand();
$batch_body = '';
$options = get_option('siteseo_instant_indexing_option_name');
$type = !empty($options['instant_indexing_google_action']) ? $options['instant_indexing_google_action'] : 'URL_UPDATED';
switch($type){
case 'remove_urls':
$type = 'URL_DELETED';
break;
case 'update_urls':
$type = 'URL_UPDATED';
break;
}
// Creating a batch request
foreach($urls as $url){
$post_data = wp_json_encode(['url' => $url, 'type' => $type]);
$batch_body .= '--'.$boundary.PHP_EOL;
$batch_body .= 'Content-Type: application/http'.PHP_EOL;
$batch_body .= 'Content-Transfer-Encoding: binary'.PHP_EOL;
$batch_body .= 'Content-ID: <'.esc_url($url).'>'.PHP_EOL.PHP_EOL;
$batch_body .= 'POST /v3/urlNotifications:publish HTTP/1.1'.PHP_EOL;
$batch_body .= 'Content-Type: application/json' . PHP_EOL;
$batch_body .= 'accept: application/json'.PHP_EOL;
$batch_body .= 'content-length: '.strlen($post_data).PHP_EOL.PHP_EOL;
$batch_body .= $post_data.PHP_EOL;
}
$batch_body .= '--'.$boundary.'--';
$response = wp_remote_post('https://indexing.googleapis.com/batch', [
'body' => $batch_body,
'headers' => [
'Content-Type' => 'multipart/mixed; boundary='.$boundary,
'Authorization' => 'Bearer ' . $access_token
],
'timeout' => 30
]);
if(is_wp_error($response)){
$response = ['error' => $response->get_error_message()];
return;
}
$res_code = wp_remote_retrieve_response_code($response);
if($res_code > 299){
return $response;
}
$batch_response = self::parse_batch_response($response);
$response = [
'status_code' => wp_remote_retrieve_response_code($response),
'urls' => $batch_response,
'error' => is_wp_error($response) ? $response->get_error_message() : null
];
return $response;
}
static function parse_batch_response(&$response){
$response_headers = wp_remote_retrieve_headers($response);
$response_headers = $response_headers->getAll();
$content_type = $response_headers['content-type'];
$urls = [];
$content_type = explode(';', $content_type);
$boundary = false;
foreach($content_type as $part){
$part = explode('=', $part, 2);
if (isset($part[0]) && 'boundary' == trim($part[0])) {
$boundary = $part[1];
}
}
$res_body = wp_remote_retrieve_body($response);
$res_body = str_replace('--'.$boundary.'--', '--'.$boundary, $res_body);
$batch_responses = explode('--'.$boundary, $res_body);
$batch_responses = array_filter($batch_responses);
foreach($batch_responses as $batch_response){
$batch_response = trim($batch_response);
if(empty($batch_response)){
continue;
}
$batch_response = explode("\r\n\r\n", $batch_response);
if(empty($batch_response[2])){
continue;
}
$batch_body = json_decode($batch_response[2], true);
if(empty($batch_body)){
continue;
}
if(!empty($batch_body['urlNotificationMetadata']) && !empty($batch_body['urlNotificationMetadata']['url'])){
$urls[] = sanitize_url($batch_body['urlNotificationMetadata']['url']);
}
}
return $urls;
}
static function get_google_auth_token(){
global $siteseo;
$endpoint = 'https://oauth2.googleapis.com/token';
$scope = 'https://www.googleapis.com/auth/indexing';
if(!function_exists('openssl_sign')){
return false;
}
$google_api_data = isset($siteseo->instant_settings['instant_indexing_google_api_key']) ? $siteseo->instant_settings['instant_indexing_google_api_key'] : '';
if(empty($google_api_data)){
return false;
}
$google_api_data = json_decode($google_api_data, true);
if(empty($google_api_data)){
return;
}
// Header
$headers = wp_json_encode(['alg' => 'RS256', 'typ' => 'JWT']);
$headers = base64_encode($headers);
// Claim Set
$now = time();
$claims = wp_json_encode([
'iss' => $google_api_data['client_email'],
'scope' => 'https://www.googleapis.com/auth/indexing',
'aud' => 'https://oauth2.googleapis.com/token',
'exp' => $now + 3600,
'iat' => $now
]);
$claims = base64_encode($claims);
// Make sure base64 encoding is URL-safe
$headers = str_replace(['+', '/', '='], ['-', '_', ''], $headers);
$claim = str_replace(['+', '/', '='], ['-', '_', ''], $claims);
// Sign the JWT with the private key
$signature_input = "$headers.$claim";
openssl_sign($signature_input, $signature, $google_api_data['private_key'], OPENSSL_ALGO_SHA256);
$signature = base64_encode($signature);
$signature = str_replace(['+', '/', '='], ['-', '_', ''], $signature);
// JWT Token
$jwt_assertion = "$signature_input.$signature";
// OAuth2 Request
$post_data = http_build_query([
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt_assertion
]);
$response = wp_remote_post($endpoint, [
'body' => $post_data,
'headers' => [
'Content-Type' => 'application/x-www-form-urlencoded',
]
]);
if(is_wp_error($response)){
return false;
}
$body = json_decode(wp_remote_retrieve_body($response), true);
return isset($body['access_token']) ? $body['access_token'] : false;
}
/**
* Sends request to index now api with list of urls and key and key location.
*
* Key location is just the URL to a file which has the same name as the Key
* as key.txt and the content in it is the key as well. This is a virtual file.
*
* @param array $urls List of URLs to submit.
* @param string $api_key bing key.
*
* @return array with 'status_code' and response 'body'
*/
static function submit_urls_to_bing($urls, $api_key){
$host = wp_parse_url(home_url(), PHP_URL_HOST);
$key_location = trailingslashit(home_url()) . $api_key . '.txt';
$endpoint = 'https://api.indexnow.org/indexnow/';
$body = wp_json_encode([
'host' => $host,
'key' => $api_key,
'keyLocation' => $key_location,
'urlList' => $urls
]);
$response = wp_remote_post($endpoint, [
'body' => $body,
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json'
],
'timeout' => 30
]);
return [
'status_code' => wp_remote_retrieve_response_code($response),
'body' => wp_remote_retrieve_body($response)
];
}
// Sends request to bing when the status of post changes
// We will only do it only if the post is published.
static function on_status_change($new_status, $old_status, $post){
if($new_status == $old_status){
return;
}
if($new_status != 'publish'){
return;
}
if(empty($post) || empty($post->post_type)){
return;
}
$post_type_object = get_post_type_object($post->post_type);
// Need to make sure we submit posts whos post type is public
if(empty($post_type_object) || empty($post_type_object->public)){
return;
}
$options = get_option('siteseo_instant_indexing_option_name', []);
$bing_api_key = !empty($options['instant_indexing_bing_api_key']) ? $options['instant_indexing_bing_api_key'] : '';
$google_api_key = !empty($options['instant_indexing_google_api_key']) ? $options['instant_indexing_google_api_key'] : '';
$url = get_permalink($post);
$url_list = [$url];
$res_google = null;
$res_bing = null;
if(!empty($bing_api_key)){
$res_bing = self::submit_urls_to_bing($url_list, $bing_api_key);
}
if(!empty($google_api_key)){
$res_google = self::submit_urls_to_google($url_list);
}
self::save_index_history($url_list, $res_google, $res_bing , 'auto');
}
static function save_index_history($urls, $google_response, $bing_response, $source){
global $siteseo;
$history = $siteseo->instant_settings;
if(!isset($history['indexing_history'])){
$history['indexing_history'] = [];
}
array_unshift($history['indexing_history'], [
'time' => time(),
'urls' => $urls,
'google_status_code' => !empty($google_response['status_code']) ? $google_response['status_code'] : null,
'bing_status_code' => !empty($bing_response['status_code']) ? $bing_response['status_code'] : null,
'source' => !empty($source) ? $source : 'manual', // 'manual' or 'auto'
]);
$history['indexing_history'] = array_slice($history['indexing_history'], 0, 10);
update_option('siteseo_instant_indexing_option_name', $history);
}
}
googleanalytics.php 0000644 00000063353 15152641524 0010460 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class GoogleAnalytics{
static function ga_render(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-google-analytics'])){
return;
}
if(!empty($siteseo->analaytics_settings['google_analytics_clarity_enable']) && !empty($siteseo->analaytics_settings['google_analytics_clarity_project_id'])){
add_action('wp_head', '\SiteSEO\GoogleAnalytics::microsoft_clarity');
}
if(!empty($siteseo->analaytics_settings['google_analytics_enable']) && !empty($siteseo->analaytics_settings['google_analytics_ga4'])){
add_action('wp_head', '\SiteSEO\GoogleAnalytics::ga_tracking_code');
}
if(!empty($siteseo->analaytics_settings['google_analytics_enable'])){
add_action('wp_footer', '\SiteSEO\GoogleAnalytics::tracking');
}
if(!empty($siteseo->analaytics_settings['google_analytics_link_tracking_enable'])){
add_action('wp_footer', '\SiteSEO\GoogleAnalytics::add_tracking_script');
}
if(!empty($siteseo->analaytics_settings['google_analytics_matomo_enable']) && !empty($siteseo->analaytics_settings['google_analytics_matomo_site_id'])){
add_action('wp_footer', '\SiteSEO\GoogleAnalytics::matomo_tracking_code');
}
if(!empty($siteseo->analaytics_settings['google_analytics_other_tracking'])){
add_action('wp_head', '\SiteSEO\GoogleAnalytics::add_custom_head_script');
}
if(!empty($siteseo->analaytics_settings['google_analytics_other_tracking_body'])){
add_action('wp_body_open', '\SiteSEO\GoogleAnalytics::add_custom_body_script');
}
if(!empty($siteseo->analaytics_settings['google_analytics_other_tracking_footer'])){
add_action('wp_footer', '\SiteSEO\GoogleAnalytics::add_custom_footer_script');
}
if(!empty($siteseo->analaytics_settings['google_analytics_opt_out_edit_choice'])){
$load_cookies_bar = $siteseo->analaytics_settings['google_analytics_hook'];
add_action($load_cookies_bar, '\SiteSEO\GoogleAnalytics::render_cookie_bar');
}
}
static function render_cookie_bar(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-google-analytics']) || empty($siteseo->analaytics_settings['google_analytics_disable'])){
return;
}
// Plugin edit pages on which we should not show the cookie notice.
$page_builders = ['fl_builder', 'elementor-preview', 'ct_builder', 'vc_editable', 'brizy_edit', 'tve', 'pagelayer-live'];
foreach($page_builders as $builder){
if(isset($_GET[$builder])){
return;
}
}
// load setting
$auto_accept_cookies = !empty($siteseo->analaytics_settings['google_analytics_half_disable']) ? $siteseo->analaytics_settings['google_analytics_half_disable'] : '';
$cookies_msg = !empty($siteseo->analaytics_settings['google_analytics_opt_out_msg']) ? $siteseo->analaytics_settings['google_analytics_opt_out_msg'] : 'By visiting our site, you agree to our privacy policy regarding cookies, tracking statistics, etc.';
$accept_btn_msg = !empty($siteseo->analaytics_settings['google_analytics_opt_out_msg_ok']) ? $siteseo->analaytics_settings['google_analytics_opt_out_msg_ok'] : 'Accept';
$close_btn_msg = !empty($siteseo->analaytics_settings['google_analytics_opt_out_msg_close']) ? $siteseo->analaytics_settings['google_analytics_opt_out_msg_close'] : 'X';
$edit_btn_msg = !empty($siteseo->analaytics_settings['google_analytics_opt_out_msg_edit']) ? $siteseo->analaytics_settings['google_analytics_opt_out_msg_edit'] : 'Manage cookies';
$cookies_expir = !empty($siteseo->analaytics_settings['google_analytics_cb_exp_date']) ? $siteseo->analaytics_settings['google_analytics_cb_exp_date'] : '';
$bar_postion = !empty($siteseo->analaytics_settings['google_analytics_cb_pos']) ? $siteseo->analaytics_settings['google_analytics_cb_pos'] : '' ;
$bar_width = !empty($siteseo->analaytics_settings['google_analytics_cb_width']) ? $siteseo->analaytics_settings['google_analytics_cb_width'] : '';
$display_backrop = !empty($siteseo->analaytics_settings['google_analytics_cb_backdrop']) ? true : '';
// colors load
$backdrop_bg = !empty($siteseo->analaytics_settings['google_analytics_cb_backdrop_bg']) ? $siteseo->analaytics_settings['google_analytics_cb_backdrop_bg'] : '';
$cookiebar_bg = !empty($siteseo->analaytics_settings['google_analytics_cb_bg']) ? $siteseo->analaytics_settings['google_analytics_cb_bg'] : '#ffffff';
$cookiebar_bg_txt = !empty($siteseo->analaytics_settings['google_analytics_cb_txt_col']) ? $siteseo->analaytics_settings['google_analytics_cb_txt_col'] : '#000000';
$cookiesbar_bg_lk = !empty($siteseo->analaytics_settings['google_analytics_cb_lk_col']) ? $siteseo->analaytics_settings['google_analytics_cb_lk_col'] : '#0073aa';
$primary_btn_bg = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_bg']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_bg'] : '#0073aa';
$primary_btn_bg_hov = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_bg']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_bg'] : '#ffffff';
$primary_btn_txt = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_col']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_col'] : '#005177';
$primary_btn_txt_hov = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_col']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_col'] : '#ffffff';
$sec_btn_bg = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_sec_bg']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_sec_bg'] : '#cccccc';
$sec_btn_bg_txt = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_sec_col']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_sec_col'] : '#000000';
$sec_btn_bg_hov = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_sec_bg_hov']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_sec_bg_hov'] : '#aaaaaa';
$sec_btn_txt_hov = !empty($siteseo->analaytics_settings['google_analytics_cb_btn_sec_col_hov']) ? $siteseo->analaytics_settings['google_analytics_cb_btn_sec_col_hov'] : '#000000';
//position
$position_class = '';
$backdrop = false;
switch(strtolower($bar_postion)){
case 'middle':
$position_class = 'siteseo-cookie-bar-middle';
$backdrop = true;
break;
case 'top':
$position_class = 'siteseo-cookie-bar-top';
$backdrop = false;
break;
default:
$position_class = 'siteseo-cookie-bar-bottom';
$backdrop = false;
}
/* Translators: %s is the background color */
$bar_styles = sprintf(
'background-color: %s; color: %s;',
esc_attr($cookiebar_bg),
esc_attr($cookiebar_bg_txt)
);
$backdrop_html = '';
if(!empty($display_backrop) && $backdrop){
$backdrop_html = '<div id="siteseo-cookie-bar-backdrop" style="background-color:'.esc_attr($backdrop_bg).'" class="siteseo-cookie-bar-backdrop"></div>';
}
$css = '<style>
#siteseo-cookie-bar-accept{
--primary-btn-bg: '.esc_attr($primary_btn_bg).';
--primary-btn-text: '.esc_attr($primary_btn_txt).';
--primary-btn-hover-bg: '.esc_attr($primary_btn_bg_hov).';
--primary-btn-hover-text: '.esc_attr($primary_btn_txt_hov).';
}
#siteseo-cookie-bar-close{
--secondary-btn-bg: '.esc_attr($sec_btn_bg).';
--secondary-btn-text: '.esc_attr($sec_btn_bg_txt).';
--secondary-btn-hover-bg: '.esc_attr($sec_btn_bg_hov).';
--secondary-btn-hover-text: '.esc_attr($sec_btn_txt_hov).';
}
</style>';
$html = $backdrop_html;
$html .= '<div id="siteseo-cookie-bar" class="siteseo-cookie-bar '.esc_attr($position_class).'" style="'.esc_attr($bar_styles).'" data-half-disable="'.esc_attr($auto_accept_cookies).'">
<div class="siteseo-cookie-bar-content">
<span>'.wp_kses_post($cookies_msg).'</span>
<div class="siteseo-cookie-bar-buttons">
<button id="siteseo-cookie-bar-accept" class="siteseo-cookie-bar-button siteseo-cookie-bar-primary-btn" style="background-color: '.esc_attr($primary_btn_bg).'; color: '.esc_attr($primary_btn_txt).'">
'.esc_html($accept_btn_msg).'
</button>
<button id="siteseo-cookie-bar-close" class="siteseo-cookie-bar-button siteseo-cookie-bar-secondary-btn" style="background-color: '.esc_attr($sec_btn_bg).'; color: '.esc_attr($sec_btn_bg_txt).'">
'.esc_html($close_btn_msg).'
</button>
</div>
</div>
</div>
<button id="siteseo-cookie-bar-manage-btn" class="siteseo-cookie-bar-button siteseo-cookie-bar-primary-btn" style="background-color: '.$primary_btn_bg.'; color: '.esc_attr($primary_btn_txt).'">
'.esc_html($edit_btn_msg).'
</button>';
echo wp_kses_post($html);
}
static function update_src_tag($tag, $handle, $src){
global $siteseo;
$tracking_handles = [
'siteseo-gtag',
'siteseo-matomo-tracking',
'siteseo-microsoft-clarity',
'siteseo-microsoft-clarity-js-after',
'siteseo-ga-tracking'
];
if(!in_array($handle, $tracking_handles)){
return $tag;
}
if(!empty($siteseo->analaytics_settings['google_analytics_disable']) && !isset($_COOKIE['siteseo-user-consent-accept']) && !isset($_COOKIE['siteseo-user-consent-close'])){
$tag = str_replace(' src=', ' data-src-siteseo=', $tag);
}
return $tag;
}
static function process_script_src($scripts){
global $siteseo;
if(!empty($siteseo->analaytics_settings['google_analytics_disable']) && !isset($_COOKIE['siteseo-user-consent-accept']) && !isset($_COOKIE['siteseo-user-consent-close'])){
$scripts = preg_replace('/(<script[^>]*) src=(["\'])(.*?)\\2/i', '$1 data-src-siteseo=$2$3$2', $scripts);
}
return $scripts;
}
static function add_custom_head_script(){
global $siteseo;
$scripts = $siteseo->analaytics_settings['google_analytics_other_tracking'];
$scripts = self::process_script_src($scripts);
echo wp_kses($scripts, [
'script' => [
'async' => [],
'src' => [],
'data-src-siteseo' => [],
'type' => []
]
]);
}
static function add_custom_body_script(){
global $siteseo;
$scripts = $siteseo->analaytics_settings['google_analytics_other_tracking_body'];
$scripts = self::process_script_src($scripts);
echo wp_kses($scripts, [
'script' => [
'async' => [],
'src' => [],
'data-src-siteseo' => [],
'type' => []
]
]);
}
static function add_custom_footer_script(){
global $siteseo;
$scripts = $siteseo->analaytics_settings['google_analytics_other_tracking_footer'];
$scripts = self::process_script_src($scripts);
echo wp_kses($scripts, [
'script' => [
'async' => [],
'src' => [],
'data-src-siteseo' => [],
'type' => []
]
]);
}
static function exclude_user_tracking(){
global $siteseo;
if(!is_user_logged_in()){
return false;
}
$current_user = wp_get_current_user();
if(!$current_user){
return false;
}
$excluded_roles = isset($siteseo->analaytics_settings['google_analytics_roles']) ? $siteseo->analaytics_settings['google_analytics_roles'] : [];
if(empty($excluded_roles)){
return false;
}
foreach($current_user->roles as $user_role){
if(isset($excluded_roles[$user_role])){
return true;
}
}
return false;
}
static function custom_dimensions(){
global $siteseo;
$dimensions = [];
$settings = $siteseo->analaytics_settings;
// Track Authors
if(!empty($settings['track_authors']) && $settings['track_authors'] !== 'none'){
if(is_singular()){
$author_id = get_post_field('post_author', get_the_ID());
$author_name = get_the_author_meta('display_name', $author_id);
$dimensions[$settings['track_authors']] = $author_name;
}
}
// Track Categories
if(!empty($settings['track_categories']) && $settings['track_categories'] !== 'none'){
if(is_singular()){
$categories = get_the_category();
if(!empty($categories)){
$category_names = array_map(function($cat){
return $cat->name;
}, $categories);
$dimensions[$settings['track_categories']] = implode(', ', $category_names);
}
}
}
// Track Tags
if(!empty($settings['track_tags']) && $settings['track_tags'] !== 'none'){
if(is_singular()){
$tags = get_the_tags();
if(!empty($tags)){
$tag_names = array_map(function($tag){
return $tag->name;
}, $tags);
$dimensions[$settings['track_tags']] = implode(', ', $tag_names);
}
}
}
// Track Post Types
if(!empty($settings['track_post_types']) && $settings['track_post_types'] !== 'none'){
if(is_singular()){
$dimensions[$settings['track_post_types']] = get_post_type();
}
}
// Track Logged In Users
if(!empty($settings['track_user']) && $settings['track_user'] !== 'none'){
if(is_user_logged_in()){
$current_user = wp_get_current_user();
$dimensions[$settings['track_user']] = $current_user->roles[0];
}
}
return $dimensions;
}
static function matomo_tracking_code(){
global $siteseo;
if(self::exclude_user_tracking()){
return;
}
$settings = $siteseo->analaytics_settings;
$tracking_url = !empty($settings['google_analytics_matomo_id']) ? $settings['google_analytics_matomo_id'] : '';
$site_id = !empty($settings['google_analytics_matomo_site_id']) ? $settings['google_analytics_matomo_site_id'] : '';
$cross_domain = !empty($settings['google_analytics_matomo_cross_domain']) ? $settings['google_analytics_matomo_cross_domain'] : '';
$do_not_track = !empty($settings['google_analytics_matomo_dnt']) ? $settings['google_analytics_matomo_dnt'] : '';
$disable_cookies = !empty($settings['google_analytics_matomo_no_cookies']) ? $settings['google_analytics_matomo_no_cookies'] : '';
$disable_heatmaps = !empty($settings['google_analytics_matomo_no_heatmaps']) ? $settings['google_analytics_matomo_no_heatmaps'] : '';
$track_subdomains = !empty($settings['google_analytics_matomo_subdomains']) ? $settings['google_analytics_matomo_subdomains'] : '';
$track_js_disabled = !empty($settings['google_analytics_matomo_no_js']) ? $settings['google_analytics_matomo_no_js'] : '';
wp_register_script('siteseo-matomo-tracking', false, [], null, [
'strategy' => true,
'in_footer' => true,
]);
wp_enqueue_script('siteseo-matomo-tracking');
add_filter('script_loader_tag', '\SiteSEO\GoogleAnalytics::update_src_tag', 10, 3);
wp_add_inline_script('siteseo-matomo-tracking', "var _paq = _paq || [];
_paq.push(['setSiteId', '".esc_html($site_id)."']);
_paq.push(['setTrackerUrl', '".esc_html($tracking_url)."']);
if(".esc_html($cross_domain).") _paq.push(['enableCrossDomainLinking']);
if(".esc_html($do_not_track).") _paq.push(['setDoNotTrack', true]);
if(".esc_html($disable_cookies).") _paq.push(['disableCookies']);
if(".esc_html($disable_heatmaps).") _paq.push(['disableAllHeatmaps']);
if(".esc_html($track_subdomains).") _paq.push(['setDocumentTitle', document.domain + '/' + document.title]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function(){
var u=\"".esc_html($tracking_url)."\";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '".esc_html($site_id)."']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();");
if($track_js_disabled){
echo '<noscript><img src="'.esc_url($tracking_url.'/matomo.php?idsite='.$site_id.'&rec=1').'" style="border:0" alt="" /></noscript>';
}
}
static function add_tracking_script(){
global $siteseo;
if(self::exclude_user_tracking()){
return;
}
echo '<script>
document.addEventListener("DOMContentLoaded", function() {';
if(!empty($siteseo->analaytics_settings['google_analytics_link_tracking_enable'])){
echo 'document.querySelectorAll("a").forEach(function(link){
if(link.hostname !== location.hostname){
link.addEventListener("click", function(){
gtag("event", "click", { "event_category": "External Link", "event_label": link.href });
});
}
});';
}
if(!empty($siteseo->analaytics_settings['google_analytics_download_tracking_enable']) && !empty($siteseo->analaytics_settings['google_analytics_download_tracking'])) {
$fileExtensions = preg_replace('/\s+/', '', $siteseo->analaytics_settings['google_analytics_download_tracking']);
$fileExtensionsPattern = str_replace('|', '|\\.', $fileExtensions);
echo 'document.querySelectorAll("a[href$=\'.' .esc_js(str_replace('|', '\'], a[href$=\'.', $fileExtensions)) . '\']").forEach(function(link) {
link.addEventListener("click", function() {
gtag("event", "download", { "event_category": "Download", "event_label": link.href });
});
});';
}
if(!empty($siteseo->analaytics_settings['google_analytics_affiliate_tracking_enable']) && ! empty($siteseo->analaytics_settings['google_analytics_affiliate_tracking'])){
$keywords = wp_json_encode( explode( ',', $siteseo->analaytics_settings['google_analytics_affiliate_tracking']));
echo 'const keywords = '.esc_attr($keywords).';
document.querySelectorAll("a").forEach(function(link){
keywords.forEach(function(keyword){
if(link.href.includes(keyword.trim())){
link.addEventListener("click", function(){
gtag("event", "click", { "event_category": "Affiliate/Outbound Link", "event_label": link.href });
});
}
});
});';
}
if(!empty($siteseo->analaytics_settings['google_analytics_phone_tracking'])){
echo 'document.querySelectorAll("a[href^=\'tel:\']").forEach(function(link){
link.addEventListener("click", function() {
gtag("event", "click", { "event_category": "Telephone Link", "event_label": link.href });
});
});';
}
echo '});
</script>';
}
static function tracking(){
global $siteseo;
if(self::exclude_user_tracking()){
return;
}
$settings = $siteseo->analaytics_settings;
$ga_id = !empty($settings['google_analytics_optimize']) ? $settings['google_analytics_optimize'] : '';
$conversion_id = !empty($settings['google_analytics_ads']) ? $settings['google_analytics_ads'] : '';
$optimize_id = !empty($settings['google_analytics_ads']) ? $settings['google_analytics_ads'] : '';
$remarketing = !empty($settings['google_analytics_remarketing']) ? $settings['google_analytics_remarketing'] : '';
$anonymize_ip = !empty($settings['google_analytics_ip_anonymization']) ? $settings['google_analytics_ip_anonymization'] : '';
$enhanced_link = !empty($settings['google_analytics_link_attribution']) ? $settings['google_analytics_link_attribution'] : '';
$cross_domain = !empty($settings['google_analytics_cross_domain']) ? $settings['google_analytics_cross_domain'] : '';
$cross_domain_name = !empty($settings['google_analytics_remarketing']) ? $settings['google_analytics_remarketing'] : '';
//custom dimensions
$get_custom_dimensions = self::custom_dimensions();
wp_enqueue_script('siteseo-gtag', 'https://www.googletagmanager.com/gtag/js?id=' . esc_attr($ga_id), [], SITESEO_VERSION, [
'strategy' => 'async',
]);
add_filter('script_loader_tag', '\SiteSEO\GoogleAnalytics::update_src_tag', 10, 3);
$gtag_config = [
'anonymize_ip' => $anonymize_ip ? true : false,
'link_attribution' => $enhanced_link ? true : false,
];
if($cross_domain && $cross_domain_name){
$gtag_config['linker'] = [
'domains' => [$cross_domain_name]
];
}
// config
foreach($get_custom_dimensions as $dimension => $value){
$gtag_config[$dimension] = $value;
}
$inline_script = 'window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag("js", new Date());
window.addEventListener("load", function (){
var links = document.querySelectorAll("a");
for(let i = 0; i < links.length; i++){
links[i].addEventListener("click", function(e) {
var n = this.href.includes("' . wp_parse_url(home_url(), PHP_URL_HOST) . '");
if (n == false) {
gtag("event", "click", {"event_category": "external links","event_label" : this.href});
}
});
}
});
gtag("config", "'.esc_js($ga_id).'", '.wp_json_encode($gtag_config).');';
if($optimize_id){
$inline_script .= 'gtag("config", "'.esc_js($optimize_id).'");';
}
if($conversion_id){
$inline_script .= 'gtag("config", "'.esc_js($conversion_id).'");';
}
if($remarketing){
$inline_script .= 'gtag("set", "allow_google_signals", true);';
}
wp_add_inline_script('siteseo-gtag', $inline_script);
}
static function microsoft_clarity(){
global $siteseo;
if(self::exclude_user_tracking()){
return;
}
$project_id = !empty($siteseo->analaytics_settings['google_analytics_clarity_project_id']) ? $siteseo->analaytics_settings['google_analytics_clarity_project_id'] : '';
if(empty($project_id)){
return;
}
wp_register_script('siteseo-microsoft-clarity', '', [], SITESEO_VERSION, true);
wp_enqueue_script('siteseo-microsoft-clarity');
$inline_script = "(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src='https://www.clarity.ms/tag/'+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, 'clarity', 'script', '".esc_js($project_id)."');";
wp_add_inline_script('siteseo-microsoft-clarity', $inline_script);
add_filter('script_loader_tag', '\SiteSEO\GoogleAnalytics::update_src_tag', 10, 3);
}
static function ga_tracking_code(){
global $siteseo;
if(self::exclude_user_tracking()){
return;
}
$ga_id = isset($siteseo->analaytics_settings['google_analytics_ga4']) ? esc_attr($siteseo->analaytics_settings['google_analytics_ga4']) : '';
if(empty($ga_id)){
return;
}
wp_enqueue_script('siteseo-ga-tracking', 'https://www.googletagmanager.com/gtag/js?id=' . $ga_id, [], SITESEO_VERSION, true);
add_filter('script_loader_tag', '\SiteSEO\GoogleAnalytics::add_async_attribute', 10, 2);
$inline_script = "
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$ga_id}');
";
wp_add_inline_script('siteseo-ga-tracking', $inline_script);
}
static function add_async_attribute($tag, $handle){
global $siteseo;
if('siteseo-ga-tracking' === $handle){
if(!empty($siteseo->analaytics_settings['google_analytics_disable'])){
if(isset($_COOKIE['siteseo-user-consent-accept']) && $_COOKIE['siteseo-user-consent-accept'] === 'true'){
return str_replace(' src', ' async src', $tag);
} else{
return str_replace(' src', ' data-src-siteseo', $tag);
}
}
}
return $tag;
}
/** TODO:: temporary in this file*/
static function handle_custom_redirect(){
global $post;
// post types and taxonomies
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
$is_singular = false;
foreach($post_types as $post_type){
if(is_singular($post_type->name)){
$is_singular = true;
break;
}
}
$is_taxonomy = false;
foreach($taxonomies as $taxonomy){
if(is_tax($taxonomy->name)){
$is_taxonomy = true;
break;
}
}
if($is_singular || is_404() || $is_taxonomy || is_category() || is_tag()){
if(is_404()){
$args = array(
'post_type' => 'siteseo_404',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => '_siteseo_redirections_enabled',
'value' => 'yes',
'compare' => '='
)
)
);
$redirect_posts = get_posts($args);
if(empty($redirect_posts)){
return;
}
$post = $redirect_posts[0];
}
// Taxonomy archives
if($is_taxonomy || is_category() || is_tag()){
$term = get_queried_object();
$term_id = $term->term_id;
// Check redirection is enabled
$enable_redirect = get_term_meta($term_id, '_siteseo_redirections_enabled', true);
if(empty($enable_redirect)){
return;
}
$login_status = get_term_meta($term_id, '_siteseo_redirections_logged_status', true);
$redirect_type = get_term_meta($term_id, '_siteseo_redirections_type', true);
$redirect_url = get_term_meta($term_id, '_siteseo_redirections_value', true);
$param_handling = get_term_meta($term_id, '_siteseo_redirections_param', true);
}
// Singular posts, pages, and products
else{
$enable_redirect = get_post_meta($post->ID, '_siteseo_redirections_enabled', true);
if(empty($enable_redirect)){
return;
}
$login_status = get_post_meta($post->ID, '_siteseo_redirections_logged_status', true);
$redirect_type = get_post_meta($post->ID, '_siteseo_redirections_type', true);
$redirect_url = get_post_meta($post->ID, '_siteseo_redirections_value', true);
$param_handling = get_post_meta($post->ID, '_siteseo_redirections_param', true);
}
if($login_status === 'only_logged_in' && !is_user_logged_in()){
return;
}
if($login_status === 'only_not_logged_in' && is_user_logged_in()){
return;
}
if(!empty($redirect_url)){
$final_url = $redirect_url;
if(is_404() && !empty($_SERVER['QUERY_STRING'])){
switch($param_handling){
case 'exact_match':
$current_params = sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING']));
$redirect_params = wp_parse_url($redirect_url, PHP_URL_QUERY);
if($current_params !== $redirect_params){
return;
}
break;
case 'without_param':
$final_url = strtok($redirect_url, '?');
break;
case 'with_ignored_param':
$query_string = sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING']));
$final_url = $redirect_url;
if(!empty($query_string)){
$final_url .= (strpos($redirect_url, '?') !== false ? '&' : '?') . $query_string;
}
break;
}
}
$status_code = !empty($redirect_type) ? intval($redirect_type) : 301;
if(in_array($status_code, [410, 451]) && is_404()){
status_header($status_code);
nocache_headers();
include(get_query_template('404'));
exit;
}
wp_redirect($final_url, $status_code);
exit;
}
}
}
}
generatesitemap.php 0000644 00000061701 15152641524 0010444 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class GenerateSitemap{
private static $paged = 1;
static function settings(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-xml-sitemap'])){
return;
}
if(!empty($siteseo->sitemap_settings['xml_sitemap_html_enable'])){
add_shortcode('siteseo_html_sitemap', '\SiteSEO\GenerateSitemap::html_sitemap');
}
if(!empty($siteseo->sitemap_settings['xml_sitemap_general_enable'])){
self::xml_sitemap();
}
}
static function xml_sitemap(){
add_filter('query_vars', function($vars){
$vars[] = 'sitemap_type';
$vars[] = 'paged';
$vars[] = 'sitemap-stylesheet';
return $vars;
});
}
static function add_rewrite_rules(){
global $siteseo;
add_rewrite_rule('^sitemaps\.xsl$', 'index.php?sitemap-stylesheet=sitemap', 'top');
add_rewrite_rule('^sitemaps\.xml$', 'index.php?sitemap_type=general', 'top');
add_rewrite_rule('^author.xml$', 'index.php?sitemap_type=author', 'top');
add_rewrite_rule('^media-sitemap([0-9]+)?.xml$', 'index.php?sitemap_type=media&paged=$matches[1]', 'top');
add_rewrite_rule('^news([0-9]+)?.xml$', 'index.php?sitemap_type=news&paged=$matches[1]', 'top');
add_rewrite_rule('^video-sitemap([0-9]+)?.xml$', 'index.php?sitemap_type=video&paged=$matches[1]', 'top');
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
if(!empty($settings['include'])){
add_rewrite_rule('^'.$post_type.'-sitemap([0-9]+)?\.xml$', 'index.php?sitemap_type='.$post_type.'&paged=$matches[1]', 'top');
}
}
}
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'] as $taxonomy => $settings){
if(!empty($settings['include'])){
add_rewrite_rule('^'.$taxonomy.'-sitemap([0-9]+)?\.xml$', 'index.php?sitemap_type='.$taxonomy.'&paged=$matches[1]', 'top');
}
}
}
flush_rewrite_rules();
}
static function handle_sitemap_requests(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
self::maybe_redirect();
// Output the Sitemap style
if(get_query_var('sitemap-stylesheet') === 'sitemap'){
self::sitemap_xsl();
exit;
}
if(get_query_var('paged')){
self::$paged = get_query_var('paged');
}
$type = get_query_var('sitemap_type');
if(!empty($type)){
if($type === 'news' && !empty($pro_settings['google_news']) && !empty($pro_settings['toggle_state_google_news'])){
self::generate_google_news_sitemap();
exit;
}
if($type === 'video' && !empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
self::generate_video_sitemap();
exit;
}
// Custom post type
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'][$type]) && !empty($siteseo->sitemap_settings['xml_sitemap_post_types_list'][$type]['include'])){
self::generateSitemap($type);
exit;
}
//custom taxomies type
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'][$type]) && !empty($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'][$type]['include'])){
self::generate_term_sitemap($type);
exit;
}
switch($type){
case 'general':
self::generate_index_sitemap();
break;
case 'post':
self::generateSitemap('post');
break;
case 'page':
self::generateSitemap('page');
break;
case 'category':
self::generate_term_sitemap('category');
break;
case 'post_tag':
self::generate_term_sitemap('post_tag');
break;
case 'author':
self::generate_author_sitemap();
break;
case 'news':
self::generate_google_news_sitemap();
break;
case 'video':
self::generate_video_sitemap();
break;
default:
wp_die(esc_html__('Invalid sitemap type.', 'siteseo'));
}
}
}
static function generate_index_sitemap(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
header('Content-Type: application/xml; charset=UTF-8');
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
// Post types
if(isset($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
$posts = get_posts(
[
'post_type' => $post_type,
'fields'=> 'ids',
'numberposts' => -1,
'post_status' => 'publish',
'has_password' => false,
'no_found_rows' => true,
'ignore_sticky_posts' => true,
'update_post_term_cache' => false,
]
);
if(empty($posts)){
continue;
}
$total_pages = (int) ceil(count($posts) / 1000);
if(!empty($settings['include']) && !empty($total_pages)){
$last_post = get_posts([
'post_type' => $post_type,
'numberposts' => 1,
'post_status' => 'publish',
'orderby' => 'modified',
'order' => 'DESC',
'fields' => 'ids',
]);
$lastmod = !empty($last_post) ? get_post_modified_time('c', true, $last_post[0]) : current_time('c');
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/$post_type-sitemap$page.xml")).'</loc>
<lastmod>'.esc_xml($lastmod).'</lastmod>
</sitemap>';
}
}
}
}
// Taxonomies
if(isset($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_taxonomies_list'] as $taxonomy => $settings){
$args = [
'taxonomy' => $taxonomy,
'hide_empty' => true,
'fields' => 'count',
'hierarchical' => false,
'update_term_meta_cache' => false,
];
$tax_count = get_terms($args);
if(is_wp_error($tax_count) || $tax_count == 0){
continue;
}
$total_pages = (int) ceil($tax_count/2000);
if(!empty($settings['include']) && $total_pages > 0){
$terms = get_terms([
'taxonomy' => $taxonomy,
'number' => 1,
'orderby' => 'term_order',
'order' => 'DESC',
'fields' => 'ids',
]);
$lastmod = !empty($terms) ? current_time('c') : current_time('c'); // taxonomy terms don't have modified, fallback
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/$taxonomy-sitemap$page.xml")).'</loc>
<lastmod>'.esc_xml($lastmod).'</lastmod>
</sitemap>';
}
}
}
}
// Author
if(!empty($siteseo->sitemap_settings['xml_sitemap_author_enable'])){
echo '<sitemap>
<loc>'.esc_url(home_url('/author.xml')).'</loc>
<lastmod>'.esc_xml(current_time('c')).'</lastmod>
</sitemap>';
}
// Google News
if(!empty($pro_settings['google_news']) && !empty($pro_settings['toggle_state_google_news'])){
echo '<sitemap>
<loc>'.esc_url(home_url('/news.xml')).'</loc>
<lastmod>'.esc_xml(current_time('c')).'</lastmod>
</sitemap>';
}
// Video
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
$video_posts = get_posts([
'post_type' => $pro_settings['video_sitemap_posts'],
'fields' => 'ids',
'numberposts' => 1,
'orderby' => 'modified',
'order' => 'DESC',
'fields' => 'ids',
'meta_query' => [
[
'key' => '_siteseo_video_disabled',
'compare' => 'NOT EXISTS'
]
]
]);
$lastmod = !empty($video_posts) ? get_post_modified_time('c', true, $video_posts[0]) : current_time('c');
for($page = 1; $page <= $total_pages; $page++){
echo '<sitemap>
<loc>'.esc_url(home_url("/video-sitemap$page.xml")).'</loc>
<lastmod>'.esc_xml($lastmod).'</lastmod>
</sitemap>';
}
}
echo '</sitemapindex>';
exit;
}
// post
static function generate_post_sitemap(){
self::generateSitemap('post');
}
// page
static function generate_page_sitemap(){
self::generateSitemap('page');
}
// category
static function generate_category_sitemap(){
self::generate_term_sitemap('category');
}
//post tag
static function generate_post_tag_sitemap(){
self::generate_term_sitemap('post_tag');
}
// taxonomy
static function generate_taxonomy_sitemap(){
self::generate_term_sitemap('taxonomy');
}
// google news pro feature
static function generate_google_news_sitemap(){
if(class_exists('\SiteSEOPro\GoogleNews') && method_exists('\SiteSEOPro\GoogleNews', 'google_news_sitemap')){
\SiteSEOPro\GoogleNews::google_news_sitemap();
}
}
// video sitemap pro feature
static function generate_video_sitemap(){
if(class_exists('\SiteSEOPro\VideoSitemap') && method_exists('\SiteSEOPro\VideoSitemap', 'render_sitemap')){
\SiteSEOPro\VideoSitemap::render_sitemap();
}
}
static function generateSitemap($post_type){
global $siteseo;
header('Content-Type: application/xml; charset=utf-8');
$offset = (1000*(self::$paged - 1));
$posts = get_posts(
[
'post_type' => $post_type,
'post_status' => 'publish',
'numberposts' => 1000,
'offset' => $offset,
'order' => 'DESC',
'orderby' => 'modified',
'has_password' => false,
'no_found_rows' => true,
'lang' => 'all',
'meta_query' => [
[
'key' => '_siteseo_robots_index',
'compare' => 'NOT EXISTS'
]]
]);
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '.((!empty($siteseo->sitemap_settings['xml_sitemap_img_enable'])) ? 'xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"' : '').'>';
if(self::$paged == 1){
if(get_option('show_on_front') === 'page' && get_option('page_on_front')){
echo "\t".'<url>
<loc>'.esc_url(trailingslashit(home_url())).'</loc>
<lastmod>'.esc_html(get_the_modified_date('c', get_option('page_on_front'))).'</lastmod>
</url>';
} else{
echo "\t".'<url>
<loc>'.esc_url(trailingslashit(home_url())).'</loc>
</url>';
}
}
foreach($posts as $post){
if($post->ID == get_option('page_on_front')){
continue;
}
$image_xml = '';
if(!empty($siteseo->sitemap_settings['xml_sitemap_img_enable'])){
$images = self::get_page_images($post);
if(!empty($images)){
foreach($images as $image){
$image_xml .= "<image:image>\n";
$image_xml .= "\t\t\t<image:loc>".esc_url($image)."</image:loc>\n";
$image_xml .= "\t\t</image:image>";
}
}
}
echo "\t<url>
<loc>".esc_url(get_permalink($post->ID))."</loc>
<lastmod>".esc_html(get_the_modified_date('c', $post->ID))."</lastmod>
".$image_xml."
</url>";
}
echo '</urlset>';
exit;
}
static function generate_term_sitemap($taxonomy){
header('Content-Type: application/xml; charset=utf-8');
$offset = (2000*(self::$paged - 1));
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
'number' => 2000,
'offset' => $offset,
'hierarchical' => false,
'update_term_meta_cache' => false,
'lang' => 'all',
'meta_query' => [
[
'key' => '_siteseo_robots_index',
'compare' => 'NOT EXISTS'
]]
]);
foreach($terms as $term){
// most recent post in this term to determine lastmod date
$recent_posts = get_posts([
'tax_query' => [
[
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $term->term_id,
]
],
'numberposts' => 1,
'orderby' => 'modified',
'order' => 'DESC',
'post_status' => 'publish'
]);
$last_mod = '';
if(!empty($recent_posts)){
$last_mod = "\n\t\t".'<lastmod>'.esc_html(get_the_modified_date('c', $recent_posts[0]->ID)).'</lastmod>';
}
echo "\t". '<url>
<loc>'.esc_url(get_term_link($term)).'</loc>'.$last_mod.'
</url>';
}
echo '</urlset>';
exit;
}
static function generate_author_sitemap(){
header('Content-Type: application/xml; charset=utf-8');
if(get_option('permalink_structure')){
$xsl_url = home_url('/sitemaps.xsl');
} else {
$xsl_url = home_url('/?sitemaps-stylesheet=sitemap');
}
echo '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="' . esc_url($xsl_url) . '" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
// Fetch all authors
$authors = get_users(
['capability' => ['publish_posts']]
);
foreach($authors as $author){
// get the last modified date of the author's most recent post
$last_post = get_posts([
'author' => $author->ID,
'numberposts' => 1,
'orderby' => 'modified',
'order' => 'DESC',
'post_status' => 'publish'
]);
$lastmod_date = '';
if(!empty($last_post)){
$lastmod_date = get_the_modified_date('c', $last_post[0]->ID);
} else{
// user registration date if no posts
$lastmod_date = gmdate('c', strtotime($author->user_registered));
}
echo "\t".'<url>
<loc>'.esc_url(get_author_posts_url($author->ID)).'</loc>
<lastmod>'.esc_html($lastmod_date).'</lastmod>
</url>';
}
echo '</urlset>';
exit;
}
static function html_sitemap($atts = []){
global $siteseo;
$atts = shortcode_atts(
[
'cpt' => '', // Default
],
$atts,
'siteseo_html_sitemap'
);
$disable_date = !empty($siteseo->sitemap_settings['xml_sitemap_html_date']);
$order_by = !empty($siteseo->sitemap_settings['xml_sitemap_html_orderby']) ? $siteseo->sitemap_settings['xml_sitemap_html_orderby'] : 'date';
$order = !empty($siteseo->sitemap_settings['xml_sitemap_html_order']) ? $siteseo->sitemap_settings['xml_sitemap_html_order'] : 'DESC';
$exclude_string = isset($siteseo->sitemap_settings['xml_sitemap_html_exclude']) ? $siteseo->sitemap_settings['xml_sitemap_html_exclude'] : '';
$exclude_pages = [];
if(!empty($exclude_string)){
$exclude_pages = array_map('trim', explode(',', $exclude_string));
}
$output = '';
if($order !== 'ASC' && $order !== 'DESC'){
$order = 'DESC';
}
$orderby_map = [
'post_title' => 'title',
'modified_date' => 'modified',
'post_id' => 'ID',
'menu_order' => 'menu_order',
'date' => 'date', // Default
];
$orderby = !empty($orderby_map[$order_by]) ? $orderby_map[$order_by] : 'date';
$cpt_list = !empty($atts['cpt']) ? explode(',', $atts['cpt']) : [];
if(!empty($siteseo->sitemap_settings['xml_sitemap_post_types_list'])){
foreach($siteseo->sitemap_settings['xml_sitemap_post_types_list'] as $post_type => $settings){
if(!empty($settings['include']) && (empty($cpt_list) || in_array($post_type, $cpt_list))){
$output .= '<h2>'.esc_html(ucfirst($post_type)).'</h2>';
$args = [
'post_type' => $post_type,
'post_status' => 'publish',
'numberposts' => -1,
'orderby' => $orderby,
'order' => $order,
];
$posts = get_posts($args);
if(!empty($posts)){
$output .= '<ul>';
foreach($posts as $post){
if(in_array($post->ID, $exclude_pages)){
continue;
}
$post_title = get_the_title($post->ID) ?: $post->ID;
$output .= '<li><a href="'.esc_url(get_permalink($post->ID)).'">'.esc_html($post_title).'</a>';
if(!$disable_date){
$output .= '<span class="post-date"> - '.esc_html(get_the_modified_date('j F Y', $post->ID)).'</span>';
}
$output .= '</li>';
}
$output .= '</ul>';
}else{
$output .= '';
}
}
}
}
return $output;
}
static function sitemap_xsl(){
global $siteseo;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
$title = __('XML Sitemap', 'siteseo');
$generated_by = __('Generated by SiteSEO', 'siteseo');
$sitemap_index_txt = __('This XML Sitemap Index file contains', 'siteseo');
$sitemap_count_txt = __('This XML Sitemap contains', 'siteseo');
$image_count_txt = __('Images', 'siteseo');
$last_modified_txt = __('Last Modified', 'siteseo');
$index_sitemap_url = home_url('/sitemaps.xml');
$image_sitemap_enabled = !empty($siteseo->sitemap_settings['xml_sitemap_img_enable']) ? true : false;
$video_sitemap_enabled = !empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap']) ? true : false;
header('Content-Type: application/xml; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"';
if(!empty($pro_settings['toggle_state_google_news']) && !empty($pro_settings['google_news'])){
echo "\t" .'xmlns:news="https://www.google.com/schemas/sitemap-news/0.9/"';
}
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap'])){
echo "\t" .'xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"';
}
echo "\t" .'xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'.esc_xml($title).'</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* {
box-sizing: border-box;
}
body{
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
background-color: #f0f2f5;
margin: 0;
padding: 0;
overflow-x: hidden;
}
header{
background: linear-gradient(135deg, #022448, #034f84);
padding: 20px;
color: #ffffff;
text-align: center;
width: 100%;
margin-bottom:15px;
}
header h1{
font-size: 32px;
margin: 0;
}
header p{
margin: 5px 0 0;
font-size: 16px;
text-decoration: underline;
}
header .siteseo-index-link a{
color: #ffffff;
text-decoration: none;
}
header .siteseo-index-link a:hover{
text-decoration: underline;
}
.siteseo-sitemap-container{
width: 60%;
margin: 0 auto;
margin-bottom: 10px;
}
.siteseo-sitemap-container a{
color:#007bff;
text-decoration: none;
}
.siteseo-sitemap-table-wrap{
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
margin-top:10px;
overflow:auto;
}
table{
width: 100%;
border-collapse: collapse;
}
table thead tr{
background-color: #034f84;
color: #ffffff;
}
table th, table td{
padding: 10px;
text-align: left;
}
table tbody tr:nth-child(even){
background-color: #f9f9f9;
}
.siteseo-video-thumbnail{
max-width: 160px;
max-height: 120px;
border-radius: 4px;
}
.siteseo-video-info{
margin-left: 15px;
}
.siteseo-video-container{
display: flex;
align-items: center;
margin: 10px 0;
}
.siteseo-video-title{
font-weight: bold;
margin-bottom: 5px;
}
.siteseo-video-description{
color: #555;
font-size: 14px;
margin-bottom: 5px;
}
.siteseo-video-meta{
font-size: 13px;
color: #777;
}
.siteseo-video-url{
word-break: break-all;
font-size: 13px;
color: #007bff;
}
</style>
</head>
<body>
<header>
<h1>'.esc_xml($title).'</h1>
<span>'.esc_xml($generated_by).'</span>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) > 0">
<div class="siteseo-description" style="text-align:center;">'.esc_xml($sitemap_index_txt).' <xsl:value-of select="count(sitemap:sitemapindex/sitemap:sitemap)"/> sitemaps</div>
</xsl:if>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<div class="siteseo-description" style="text-align:center;">'.esc_xml($sitemap_count_txt).' <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> URLs</div>
</xsl:if>
</header>
<div class="siteseo-sitemap-container">
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<a href="'.esc_url($index_sitemap_url).'">Index Sitemap</a>
</xsl:if>
<div class="siteseo-sitemap-table-wrap">
<table>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) > 0">
<thead>
<tr>
<th>URL</th>
<th>Last Modified</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>
<td>
<xsl:value-of select="sitemap:lastmod"/>
<xsl:if test="not(sitemap:lastmod)">-</xsl:if>
</td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">';
if($video_sitemap_enabled && class_exists('\SiteSEOPro\VideoSitemap') && method_exists('\SiteSEOPro\VideoSitemap', 'render_video_xsl')){
echo'<xsl:if test="sitemap:urlset/sitemap:url/video:video">'
. \SiteSEOPro\VideoSitemap::render_video_xsl() .
'</xsl:if>
<xsl:if test="not(sitemap:urlset/sitemap:url/video:video)">
<thead>
<tr>
<th>URL</th>';
if(!empty($image_sitemap_enabled)){
echo'<th>'.esc_xml($image_count_txt).'</th>';
}
echo'<th>'.esc_xml($last_modified_txt).'</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>';
if(!empty($image_sitemap_enabled)){
echo'<td>
<xsl:value-of select="count(image:image)"/>
</td>';
}
echo'<td><xsl:value-of select="sitemap:lastmod"/></td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>';
} else {
echo'<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) < 1">
<thead>
<tr>
<th>URL</th>';
if(!empty($image_sitemap_enabled)){
echo'<th>'.esc_xml($image_count_txt).'</th>';
}
echo'<th>'.esc_xml($last_modified_txt).'</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td><a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a></td>';
if(!empty($image_sitemap_enabled)){
echo'<td>
<xsl:value-of select="count(image:image)"/>
</td>';
}
echo'<td><xsl:value-of select="sitemap:lastmod"/></td>
</tr>
</xsl:for-each>
</tbody>
</xsl:if>';
}
echo'</xsl:if>
</table>
</div>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>';
}
static function get_page_images($post){
$images = [];
$thumb = get_the_post_thumbnail_url($post->ID);
if(!empty($thumb)){
$images[] = $thumb;
}
if(!class_exists('DOMDocument') || empty($post->post_content)){
return $images;
}
libxml_use_internal_errors(true);
$dom = new \DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $post->post_content);
$dom->preserveWhiteSpace = false;
libxml_clear_errors();
$img_tags = $dom->getElementsByTagName('img');
if(empty($img_tags)){
return;
}
foreach($img_tags as $img_tag){
$url = $img_tag->getAttribute('src');
if(empty($url)){
continue;
}
$url = sanitize_url($url);
// The Image has some different URL which means it does not belongs to our site.
if(strpos($url, untrailingslashit(home_url())) === FALSE){
continue;
}
$images[] = $url;
}
return $images;
}
static function maybe_redirect(){
global $wp;
if(empty($wp) || empty($wp->request)){
return;
}
$redirects = ['sitemap.xml', 'wp-sitemap.xml', 'sitemap_index.xml'];
if(in_array($wp->request, $redirects)){
wp_safe_redirect(home_url('sitemaps.xml'), 301);
die();
}
}
}
columns.php 0000644 00000012237 15152641524 0006747 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Columns{
static function add_columns($colums){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return $colums; // toggle disable
}
$options = $siteseo->advanced_settings;
if(!empty($options['appearance_title_col'])){
$colums['seo_title'] = __('Title tag', 'siteseo');
}
if(!empty($options['appearance_meta_desc_col'])){
$colums['meta_description'] = __('Meta Desc' , 'siteseo');
}
if(!empty($options['appearance_redirect_enable_col'])){
$colums['redirect_enabled'] = __('Redirect?', 'siteseo');
}
if(!empty($options['appearance_redirect_url_col'])){
$colums['redirect_url'] = __('Redirect URL', 'siteseo');
}
if(!empty($options['appearance_canonical'])){
$colums['canonical_url'] = __('Canonical', 'siteseo');
}
if(!empty($options['appearance_target_kw_col'])){
$colums['target_keyword'] = __('Target Kw', 'siteseo');
}
if(!empty($options['appearance_noindex_col'])){
$colums['noindex'] = __('noindex?', 'siteseo');
}
if(!empty($options['appearance_nofollow_col'])){
$colums['nofollow'] = __('nofollow?', 'siteseo');
}
if(!empty($options['appearance_words_col'])){
$colums['word_count'] = __('Words', 'siteseo');
}
if(!empty($options['appearance_score_col'])){
$colums['seo_score'] = __('Score', 'siteseo');
}
return $colums;
}
static function populate_custom_seo_columns($column, $post_id){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return; // toggle disable
}
$options = $siteseo->advanced_settings;
switch($column){
case 'seo_title':
if(!empty($options['appearance_title_col'])){
$title = get_post_meta($post_id, '_siteseo_titles_title', true);
echo esc_html(\SiteSEO\TitlesMetas::replace_variables($title));
}
break;
case 'meta_description':
if(!empty($options['appearance_meta_desc_col'])){
$desc = get_post_meta($post_id, '_siteseo_titles_desc', true);
$replaced_desc = \SiteSEO\TitlesMetas::replace_variables($desc);
echo esc_html($replaced_desc);
}
break;
case 'redirect_enabled':
if(!empty($options['appearance_meta_desc_col'])){
$redirect_enabled = get_post_meta($post_id, 'siteseo_redirections_enabled', true);
echo $redirect_enabled ? esc_html__('Yes', 'siteseo') : esc_html__('No', 'siteseo');
}
break;
case 'redirect_url':
if(!empty($options['appearance_redirect_enable_col'])){
echo esc_url(get_post_meta($post_id, '_siteseo_redirections_value', true));
}
break;
case 'canonical_url':
if(!empty($options['appearance_redirect_url_col'])){
echo esc_url(get_post_meta($post_id, '_siteseo_robots_canonical', true));
}
break;
case 'target_keyword':
if(!empty($options['appearance_canonical'])){
$keywords = esc_html(get_post_meta($post_id, '_siteseo_analysis_target_kw', true));
echo !empty($keywords) ? esc_html($keywords) : '';
}
break;
case 'noindex':
if(!empty($options['appearance_noindex_col'])){
$noindex = get_post_meta($post_id, '_siteseo_robots_index', true);
echo $noindex ? esc_html__('Yes', 'siteseo') : esc_html__('No', 'siteseo');
}
break;
case 'nofollow':
if(!empty($options['appearance_nofollow_col'])){
$nofollow = get_post_meta($post_id, '_siteseo_robots_follow', true);
echo $nofollow ? esc_html__('Yes', 'siteseo') : esc_html__('No', 'siteseo');
}
break;
case 'word_count':
if(!empty($options['appearance_words_col'])){
$content = get_post_field('post_content', $post_id);
echo esc_html(str_word_count(wp_strip_all_tags($content)));
}
break;
case 'seo_score':
if(!empty($options['appearance_score_col'])){
$score = get_post_meta($post_id, '_siteseo_score', true);
echo !empty($score) ? esc_html($score) : '';
}
break;
}
}
static function make_seo_columns_sortable($columns){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return $columns; // toggle disable
}
$options = $siteseo->advanced_settings;
if(!empty($options['appearance_title_col'])){
$columns['seo_title'] = 'seo_title';
}
if(!empty($options['appearance_meta_desc_col'])){
$columns['meta_description'] = 'meta_description';
}
if(!empty($options['appearance_target_kw_col'])){
$columns['target_keyword'] = 'target_keyword';
}
if(!empty($options['appearance_words_col'])){
$columns['word_count'] = 'word_count';
}
if(!empty($options['appearance_score_col'])){
$columns['seo_score'] = 'seo_score';
}
return $columns;
}
static function hide_genesis_seo(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return; // toggle disable
}
$options = $siteseo->advanced_settings;
if(!empty($options['appearance_genesis_seo_menu'])){
remove_theme_support('genesis-seo-settings-menu');
}
if(!empty($options['appearance_genesis_seo_metaboxe'])){
remove_action('admin_menu', 'genesis_add_inpost_seo_box');
}
}
} metaboxes/analysis.php 0000644 00000156254 15152641524 0011111 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Metaboxes;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Analysis{
static function display_content_readibility($metabox_data){
if(empty($metabox_data) || !isset($metabox_data['post_id'])){
return; // Safeguard in case $metabox_data is incomplete or invalid.
}
$post_id = $metabox_data['post_id'];
$readability_data = get_post_meta($post_id, '_siteseo_readibility_data', true);
// Fetch and analyze readability data
$analyzes = self::analyze_content($readability_data);
// Render the readability data
self::render_readibility($analyzes, $readability_data);
}
static function analyze_content($data){
$analyzes = [];
// Analyze different aspects
$analyzes = self::analyze_power_word($analyzes, $data);
$analyzes = self::analyze_title_number($analyzes, $data);
$analyzes = self::analyze_passive_voice($analyzes, $data);
$analyzes = self::analyze_paragraph_length($analyzes, $data);
return $analyzes;
}
static function analyze_power_word($analyzes, $data){
if(!empty($data['power_words'])){
$analyzes['power_words'] = [
'desc' => '<p>'.__('Good: You have power words in your title.', 'siteseo').'</p>',
'impact' => 'good',
'title'=>'Power Word in title'
];
} else{
$analyzes['power_words'] = [
'desc' => '<p>'.__('Consider adding power words to your title for better impact.', 'siteseo').'</p>',
'impact' => 'low',
'title'=> __('Power Word in title', 'siteseo')
];
}
return $analyzes;
}
static function analyze_title_number($analyzes, $data){
if(!empty($data['number_found'])){
$analyzes['number_found'] = [
/* translators: %s is the number found in the title */
'desc' => '<p>'.sprintf(__('Good: Your title contains the number "%s".', 'siteseo'), $data['number_found']).'</p>',
'impact' => 'good',
'title' => 'Number in title'
];
} else{
$analyzes['number_found'] = [
'desc' => '<p>'.__('Consider adding a number to your title to improve CTR.', 'siteseo').'</p>',
'impact' => 'low',
'title' => 'Number in title'
];
}
return $analyzes;
}
static function analyze_passive_voice($analyzes, $data){
//$analyzes['title'] ='Passive Voice';
if(empty($data['passive_voice'])){
$analyzes['passive_voice'] = [
'desc' => '<p>'.__('Great: No passive voice detected.', 'siteseo').'</p>',
'impact' => 'good',
'title' => 'Passive Voice'
];
} else {
$percentage = round(($data['passive_voice']['passive_sentences'] * 100) / $data['passive_voice']['total_sentences']);
if($percentage <= 10){
$analyzes['passive_voice'] = [
/* translators: %s is the number found in the title */
'desc' => '<p>'.sprintf(__('Good: Only %s%% of sentences use passive voice.', 'siteseo'), $percentage).'</p>',
'impact' => 'good',
'title' => 'Passive Voice'
];
} elseif($percentage < 20){
$analyzes['passive_voice'] = [
/* translators: %s is the percentage of sentences using passive voice */
'desc' => '<p>'.sprintf(__('Okay: %s%% of sentences use passive voice. Try to reduce it.', 'siteseo'), $percentage).'</p>',
'impact' => 'medium',
'title' => 'Passive Voice'
];
} else{
$analyzes['passive_voice'] = [
/* translators: %s is the percentage of sentences using passive voice */
'desc' => '<p>'.sprintf(__('High: %s%% of sentences use passive voice. Consider revising.', 'siteseo'), $percentage).'</p>',
'impact' => 'high',
'title' => 'Passive Voice'
];
}
}
return $analyzes;
}
static function analyze_paragraph_length($analyzes, $data){
if(empty($data['paragraph_length']) || $data['paragraph_length'] < 150){
$analyzes['paragraph_length'] = [
'desc' => '<p>Good: Your paragraphs are concise.</p>',
'impact' => 'good',
'title' => 'Paragraph Length'
];
} else{
$analyzes['paragraph_length'] = [
/* translators: %s is the current paragraph length in words */
'desc' => '<p>'.sprintf(__('Consider reducing paragraph length. Current length: %s words.', 'siteseo'), $data['paragraph_length']) . '</p>',
'impact' => 'low',
'title' => 'Paragraph Length'
];
}
return $analyzes;
}
static function render_readibility($analyzes, $analysis_data, $echo = true){
$acceptable_svg = [
'svg' => [
'role' => true,
'aria-hidden' => true,
'focusable' => true,
'width' => true,
'height' => true,
'viewbox' => true,
'version' => true,
'xmlns' => true,
'fill' => true,
],
'path' => ['fill' => true, 'd' => true]
];
if(!empty($analyzes)){
$order = ['1' => 'high', '2' => 'medium', '3' => 'low', '4' => 'good'];
usort($analyzes, function ($a, $b) use ($order) {
return array_search($a['impact'], $order) - array_search($b['impact'], $order);
});
// Define SVG icons
$high_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>';
$medium_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>';
$good_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>';
// Generate HTML
$html = '<div id="siteseo-readibility-tabs">';
foreach($analyzes as $key => $value){
$impact_icon = '';
switch ($value['impact']) {
case 'high': $impact_icon = $high_icon; break;
case 'medium': case 'low': $impact_icon = $medium_icon; break;
case 'good': $impact_icon = $good_icon; break;
}
$html .= '<div class="siteseo-analysis-block">';
$html .= '<div class="siteseo-analysis-block-title">';
$html .= '<div><span class="impact ' . esc_attr($value['impact']) .'" aria-hidden="true">' . $impact_icon . '</span>' .
/* translators: %s represents the degree of severity */
'<span class="screen-reader-text">'. sprintf(esc_html__('Degree of severity: %s','siteseo'), esc_html($value['impact'])).'</span>' .
esc_html($value['title']) . '</div>';
$html .= '<span class="siteseo-arrow" aria-hidden="true"></span></div>';
$html .= '<div class="siteseo-analysis-block-content">' . wp_kses_post($value['desc']) . '</div>';
$html .= '</div>';
}
$html .= '</div>';
if($echo){
$allowed_html = array_merge(wp_kses_allowed_html('post'), $acceptable_svg);
echo wp_kses($html, $allowed_html);
return;
}
return $html;
}
}
// Analaysis
static function display_seo_analysis($post){
$seo_analysis = self::perform_seo_analysis($post);
echo '<div id="siteseo-analysis-tabs">
<div id="siteseo-analysis-tabs-1">
<div class="siteseo-analysis-summary">';
if(!empty($seo_analysis)){
// grp
usort($seo_analysis['checks'], function ($a, $b) {
$order = ['error' => 0, 'warning' => 1, 'good' => 2];
$a_status_class = isset($a['status_class']) ? $a['status_class'] : '';
$b_status_class = isset($b['status_class']) ? $b['status_class'] : '';
$a_order = isset($order[$a_status_class]) ? $order[$a_status_class] : 3;
$b_order = isset($order[$b_status_class]) ? $order[$b_status_class] : 3;
return $a_order - $b_order;
});
echo '<div class="siteseo-analysis-summary-pill">';
// counts logic
if(!empty($seo_analysis['error_count'])){
echo '<span><svg fill="#f33" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24 22h-24l12-20z"/></svg>'.esc_html($seo_analysis['error_count']). ' Errors</span>';
}
if(!empty($seo_analysis['warning_count'])){
echo '<span><svg xmlns="http://www.w3.org/2000/svg" fill="#fa3" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96z"/></svg>'.esc_html($seo_analysis['warning_count']). ' Warnings</span>';
}
if(!empty($seo_analysis['good_count'])){
echo '<span><svg xmlns="http://www.w3.org/2000/svg" fill="#0c6" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/></svg><span>'.esc_html($seo_analysis['good_count']). ' Good</span></span>';
}
echo '</div>
</div><!-- .analysis-score -->';
// A triangle with exclamation in it.
$medium_icon_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>';
// A check inside a solid circle
$good_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg>';
$high_icon_svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z"/></svg>';
$allowed_svg_tags = ['svg' => ['xmlns' => true, 'viewbox' => true, 'width' => true, 'height' => true, 'class' => true, 'fill' => true, 'stroke' => true, 'stroke-width' => true], 'path' => ['d' => true, 'fill' => true, 'stroke' => true, 'stroke-width' => true]];
foreach($seo_analysis['checks'] as $check){
echo '<div class="siteseo-analysis-block">';
if(isset($check['label'])){
echo'<div class="siteseo-analysis-block-title">';
if(isset($check['status_class'])){
$impact_icon = '';
switch($check['status_class']){
case 'good':
$impact_icon = $good_icon;
break;
case 'warning':
$impact_icon = $medium_icon_svg;
break;
case 'error':
$impact_icon = $high_icon_svg;
break;
}
echo '<div><span class="impact '.esc_attr($check['status_class']).'" aria-hidden="true">'.wp_kses($impact_icon, $allowed_svg_tags).'</span>
<span class="screen-reader-text">'.
/* translators: %s represents the degree of severity */
sprintf(esc_html__('Degree of severity: %s','siteseo'), esc_html($check['status_class'])).'</span>';
}
echo esc_html($check['label']).'</div>
<span class="siteseo-arrow" aria-hidden="true"></span>
</div>';
}
if(isset($check['details'])){
echo '<div class="siteseo-analysis-block-content" aria-hidden="true">'.wp_kses_post($check['details']).'</div>';
}
echo '</div><!-- .siteseo-analysis-block -->';
}
echo '</div><!-- #siteseo-analysis-tabs-1 -->
</div><!-- #siteseo-analysis-tabs -->';
}
}
static function perform_seo_analysis($post){
$content = $post->post_content;
$title = $post->post_title;
$title = !empty(get_post_meta($post->ID, '_siteseo_titles_title',true)) ? get_post_meta($post->ID, '_siteseo_titles_title', true) : $title;
$permalink = get_permalink($post->ID);
$keywords = get_post_meta($post->ID, '_siteseo_analysis_target_kw', true);
$meta_desc = get_post_meta($post->ID, '_siteseo_titles_desc', true);
// Bricks
if(defined('BRICKS_DB_PAGE_CONTENT')){
$is_bricks_page = get_post_meta($post->ID, BRICKS_DB_PAGE_CONTENT, true);
if(!empty($is_bricks_page) && is_array($is_bricks_page)){
$content = self::get_bricks_page_content($is_bricks_page);
}
}
if(empty($meta_desc)){
$meta_desc = '';
}
$analysis = [
'good_count' => 0,
'warning_count' => 0,
'error_count' => 0,
'checks' => []
];
$canonical_check = self::check_canonical_url($permalink);
$analysis['checks'][] = $canonical_check;
self::update_analysis_score($analysis, $canonical_check);
$word_count_check = self::check_word_count($content);
$analysis['checks'][] = $word_count_check;
self::update_analysis_score($analysis, $word_count_check);
$keywords_density_check = self::check_keywords_density($content, $keywords);
$analysis['checks'][] = $keywords_density_check;
self::update_analysis_score($analysis, $keywords_density_check);
$meta_title_check = self::check_meta_title($title);
$analysis['checks'][] = $meta_title_check;
self::update_analysis_score($analysis, $meta_title_check);
$meta_description_check = self::check_meta_description($content, $meta_desc);
$analysis['checks'][] = $meta_description_check;
self::update_analysis_score($analysis, $meta_description_check);
$image_alt_check = self::check_image_alt_texts($content);
$analysis['checks'][] = $image_alt_check;
self::update_analysis_score($analysis, $image_alt_check);
$links_outbound_check = self::analyze_outbound_links($content);
$analysis['checks'][] = $links_outbound_check;
self::update_analysis_score($analysis, $links_outbound_check);
$links_internal_check = self::analyze_internal_links($content);
$analysis['checks'][] = $links_internal_check;
self::update_analysis_score($analysis, $links_internal_check);
$headings_check = self::check_headings($content);
$analysis['checks'][] = $headings_check;
self::update_analysis_score($analysis, $headings_check);
$social_tags_check = self::check_social_meta_tags($post);
$analysis['checks'][] = $social_tags_check;
self::update_analysis_score($analysis, $social_tags_check);
$structured_data_check = self::check_structured_data($post);
$analysis['checks'][] = $structured_data_check;
self::update_analysis_score($analysis, $structured_data_check);
$permalink_keywords_check = self::check_keywords_in_permalink($permalink, $keywords);
$analysis['checks'][] = $permalink_keywords_check;
self::update_analysis_score($analysis, $permalink_keywords_check);
$meta_robots_check = self::check_meta_robots($post);
$analysis['checks'][] = $meta_robots_check;
self::update_analysis_score($analysis, $meta_robots_check);
$last_modified_check = self::check_last_modified_date($post);
$analysis['checks'][] = $last_modified_check;
self::update_analysis_score($analysis, $last_modified_check);
$nofollow_links_check = self::analyze_nofollow_links($content);
$analysis['checks'][] = $nofollow_links_check;
self::update_analysis_score($analysis, $nofollow_links_check);
$readability_data = [];
$readability_data = self::analyze_readability($content, $title);
update_post_meta($post->ID, '_siteseo_readibility_data', $readability_data);
$analysis['checks'][] = $readability_data;
return $analysis;
}
static function update_analysis_score(&$analysis, $check){
switch($check['status']){
case 'Good':
$analysis['good_count']++;
break;
case 'Warning':
$analysis['warning_count']++;
break;
case 'Error':
$analysis['error_count']++;
break;
}
}
static function check_canonical_url($permalink){
$response = wp_remote_get($permalink);
if(is_wp_error($response)){
return [
'label' => 'Canonical URL',
'status' => 'Error',
'status_class' => 'error',
'details' => '<p>' . __('Unable to check canonical URL.', 'siteseo') . '</p>'
];
}
$content = wp_remote_retrieve_body($response);
preg_match_all('/<link[^>]+rel=[\'"](canonical)[\'"][^>]+href=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $matches);
$canonical_urls = !empty($matches[2]) ? array_unique($matches[2]) : [];
$count = count($canonical_urls);
$details = '';
$status = 'Warning';
$details .= '<p>'. __('A canonical URL is required by search engines to handle duplicate content.', 'siteseo') .'</p>';
if($count > 0){
$details .= '<p>' .
sprintf(
/* translators: %s represents the degree of severity */
_n(
'We found %s canonical URL in your source code. Below, the list:',
'We found %s canonical URLs in your source code. Below, the list:',
$count,
'siteseo'
),
number_format_i18n($count)
) . '</p>';
$details .= '<ul>';
foreach($canonical_urls as $link){
$details .= '<li>' .
'<span class="dashicons dashicons-arrow-right"></span>' .
'<a href="' . esc_url($link) . '" target="_blank">' .
esc_url($link) .
'</a>' .
'<span class="dashicons dashicons-external"></span>' .
'</li>';
}
$details .= '</ul>';
if($count > 1){
$status = 'Error';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('You must fix this. Canonical URL duplication is bad for SEO.', 'siteseo') . '</p>';
} else{
$status = 'Good';
}
} else{
if(get_post_meta(get_the_ID(), '_siteseo_robots_index', true)){
$status = 'Good';
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' .
__('This page doesn\'t have any canonical URL because your post is set to <strong>noindex</strong>. This is normal.', 'siteseo') . '</p>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('This page doesn\'t have any canonical URL.', 'siteseo') . '</p>';
}
}
return [
'label' => 'Canonical URL',
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_word_count($content){
$word_count = str_word_count(wp_strip_all_tags($content));
$unique_words = count(array_unique(str_word_count(wp_strip_all_tags($content), 1)));
$details = '';
if($word_count != 0){
$details = '<p>'. __('Word count isn\'t a direct ranking factor, but it\'s important for your content to be high-quality, relevant, and unique. To meet these criteria, your article should include a sufficient number of paragraphs to ensure adequate word count.', 'siteseo') .'</p>';
$details .= '<ul>';
/* translators: %d represents the words found */
$details .= '<li>'. sprintf(__('%d words found', 'siteseo'), $word_count) .'</li>';
/* translators: %d represents the unique words found */
$details .= '<li>'. sprintf(__('%d unique words found', 'siteseo'), $unique_words) .'</li>';
$details .= '</ul>';
}
if($word_count == 0){
$status = 'Error';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('No content? Try adding a few more paragraphs.!', 'siteseo') . '</p>';
} elseif($word_count > 300){
$status = 'Good';
$details .= '<li><span class="dashicons dashicons-thumbs-up"></span>' . __('Your content contains over 300 words, which meets the minimum requirement for a post', 'siteseo') .'</li>';
} else{
$status = 'Error';
$details .= '<li><span class="dashicons dashicons-thumbs-down"></span>' . __('Your content is too brief. Consider adding a few more paragraphs!', 'siteseo') .'</li>';
}
return [
'label' => __('Word Count', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_keywords_density($content, $keywords){
$content = mb_strtolower(wp_strip_all_tags($content), 'UTF-8');
$keywords = array_filter(explode(',', trim($keywords)));
$content_words = str_word_count($content, 1);
$count_words = count($content_words);
$details = '';
if(empty($keywords) || empty($content_words)){
$details .= '<p>' . __('We couldn\'t calculate the keyword density. This may be because you haven\'t added any content or your target keywords are missing from the post.', 'siteseo') . '</p>';
return [
'label' => __('Keyword Density', 'siteseo'),
'status' => 'Error',
'status_class' => 'error',
'details' => $details
];
}
// calulate
$density_details = [];
$all_density = [];
foreach($keywords as $keyword){
$keyword_occurrence = 0;
$keyword = mb_strtolower(trim($keyword), 'UTF-8');
$keyword_words = preg_split('/\s+/u', $keyword, -1, PREG_SPLIT_NO_EMPTY);
$keyword_word_count = count($keyword_words);
// Count occurrences
if($keyword_word_count > 1){
$pattern = '/' . preg_quote($keyword, '/') . '/iu';
preg_match_all($pattern, $content, $matches);
$keyword_occurrence = count($matches[0]);
} else {
$word_counts = array_count_values($content_words);
$keyword_occurrence = isset($word_counts[$keyword]) ? $word_counts[$keyword] : 0;
}
// Calculate density
if($count_words > 0){
$kw_density = ($keyword_occurrence * $keyword_word_count * 100) / $count_words;
} else {
$kw_density = 0;
}
$all_density[] = number_format($kw_density, 2);
$density_details[] =
/* translators: %s represents the degree of severity */
sprintf(
'<ul><li><span class="dashicons dashicons-arrow-right"></span>%s</li></ul>',
sprintf(
/* translators: %s represents a keyword density of */
esc_html__('%1$s was found %2$d times in your content, a keyword density of %3$s%%', 'siteseo'),
esc_html($keyword),
$keyword_occurrence,
number_format($kw_density, 2)
)
);
}
$details .= implode('', $density_details);
$details .= '<p class="description">'.
sprintf(
__('Find out more about <a href="%s" target="_blank">keywords stuffing</a>', 'siteseo'),
'https://www.youtube.com/watch?v=Rk4qgQdp2UA'
) .
'</p>';
if(count($all_density) === 0){
return [
'label' => __('Keyword Density', 'siteseo'),
'status' => 'Error',
'status_class' => 'error',
'details' => $details
];
}
//avg density
$avg_density = array_sum($all_density)/count($all_density);
$status = ($avg_density > 1) ? 'Good' : 'Warning';
return [
'label' => __('Keyword Density', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_meta_title($title, $keywords = []){
$details = '';
$status = 'Good';
$status_class = 'good';
$title = \SiteSEO\TitlesMetas::replace_variables($title);
// mb_strlen for correct UTF-8
$title_length = mb_strlen($title, 'UTF-8');
// length
if(empty($title)){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('A custom title has not been set for this post. If the global meta title works for you, you can disregard this recommendation.', 'siteseo') . '</p>';
$status = 'Warning';
$status_class = 'warning';
} elseif($title_length > 60){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('Your custom title is too lengthy.', 'siteseo') . '</p>';
$status = 'Warning';
$status_class = 'warning';
} elseif($title_length >= 10 && $title_length <= 60){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' .
__('The length of your title is appropriate.', 'siteseo') . '</p>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('Your custom title is too short.', 'siteseo') . '</p>';
$status = 'Warning';
$status_class = 'warning';
}
if(!empty($keywords)){
$keyword_counts = [];
foreach($keywords as $kw_name){
$kw_count = substr_count(strtolower($title), strtolower($kw_name));
if($kw_count > 0){
$keyword_counts[] = $kw_count;
/* translators: %s represents the degree of severity */
$details .= '<ul><li><span class="dashicons dashicons-arrow-right"></span>'. sprintf(esc_html__('%1$s was found %2$d times.', 'siteseo'), $kw_name, $kw_count) . '</li></ul>';
}
}
if(!empty($keyword_counts)){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'.__('The target keywords are included in the Meta Title', 'siteseo').'</p>';
} else {
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'.__('None of your target keywords are present in the Meta Title.', 'siteseo').'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
}
}
return [
'label' => __('Meta Title', 'siteseo'),
'status' => $status,
'status_class' => $status_class,
'details' => $details
];
}
static function check_meta_description($content, $meta_description = '', $keywords = []){
$details = '';
$status = 'Good';
$status_class = 'good';
$desc = !empty($meta_description) ? $meta_description : wp_trim_words($content, 20);
$description = \SiteSEO\TitlesMetas::replace_variables($desc);
// UTF-8
$description_length = mb_strlen($description, 'UTF-8');
// desc length
if(empty($meta_description)){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('A custom meta description has not been set for this post. If the global meta description works for you, you can ignore this recommendation.', 'siteseo') . '</p>';
$status = 'Warning';
$status_class = 'warning';
} elseif($description_length > 160){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('Your custom meta description is too lengthy', 'siteseo') .'</p>';
$status = 'Warning';
$status_class = 'warning';
} elseif($description_length >= 50 && $description_length <= 160){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('The length of your meta description is appropriate.', 'siteseo').'</p>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('The description has been set properly.', 'siteseo').'</p>';
}
if(!empty($keywords)){
$keyword_counts = [];
foreach($keywords as $kw_name){
$kw_count = substr_count(strtolower($description), strtolower($kw_name));
if($kw_count > 0){
$keyword_counts[] = $kw_count;
$details .= '<li><span class="dashicons dashicons-arrow-right"></span>' .
/* translators: %s represents the key word count */
sprintf(esc_html__('%1$s was found %2$d times.', 'siteseo'), $kw_name, $kw_count) . '</li>';
}
}
if(!empty($keyword_counts)){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('The target keywords are included in the Meta description.', 'siteseo') . '</p>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('None of your target keywords are included in the Meta description.', 'siteseo') . '</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
}
}
return [
'label' => 'Meta Description',
'status' => $status,
'status_class' => $status_class,
'details' => $details
];
}
static function check_image_alt_texts($content){
$result = [
'label' => __('Alternative texts of images', 'siteseo'),
'status' => 'Good',
'status_class' => 'good',
'details' => ''
];
if(empty($content)){
$result['status'] = 'Warning';
$result['status_class'] = 'warning';
$result['details'] = '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('No content found to analyze. Please add some content to check for images and alt texts.', 'siteseo') . '</p>';
return $result;
}
preg_match_all('/<img[^>]+src=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $image_matches);
preg_match_all('/<img[^>]+alt=[\'"]([^\'"]+)[\'"][^>]*>/i', $content, $alt_matches);
$images_count = count($image_matches[0]);
$alt_text_count = count(array_filter($alt_matches[1], 'strlen'));
if($images_count === 0){
$result['status'] = 'Warning';
$result['status_class'] = 'warning';
$result['details'] = '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('We couldn\'t find any images in your content. Adding media can boost your SEO.', 'siteseo') . '</p>';
return $result;
}
if($images_count !== $alt_text_count){
$result['status'] = ($alt_text_count > 0) ? 'Warning' : 'Error';
$result['status_class'] = strtolower($result['status']);
$result['details'] = '<p><span class="dashicons dashicons-thumbs-down"></span>' .
esc_html__('No alternative text has been found for these images. Alt tags are essential for SEO and accessibility. Please edit your images in the media library or using your preferred page builder, and provide alternative text.', 'siteseo') . '</p>';
if(!empty($image_matches[1])){
$result['details'] .= '<ul class="attachments">';
foreach($image_matches[1] as $index => $img){
if(empty($alt_matches[1][$index])){
$result['details'] .= '<li class="attachment"><figure>' .
'<img src="' . esc_url($img) . '"/>' .
'<figcaption style="word-break: break-all;">' . esc_html($img) . '</figcaption>' .
'</figure></li>';
}
}
$result['details'] .= '</ul>';
}
$result['details'] .= '<p>'. __('Please note that we scan all your source code, which means some missing alternative text for images may be found in your header, sidebar, or footer.', 'siteseo') .'</p>';
} else{
$result['details'] = '<p><span class="dashicons dashicons-thumbs-up"></span>' .
__('All alternative tags have been completed. Great job!', 'siteseo') .'</p>';
}
return $result;
}
static function analyze_outbound_links($content){
preg_match_all('/<a[^>]+href=([\'"])(?!#)([^\'"]+)[\'"][^>]*>/i', $content, $links);
$outbound_links = array_filter($links[2], function($link){
return strpos($link, get_site_url()) === false;
});
$total_outbound = count($outbound_links);
$nofollow_count = preg_match_all('/rel=[\'"]nofollow[\'"]/', implode(' ', $links[0]));
$status = $total_outbound > 0 ? 'Good' : 'Warning';
$details = '';
$details .= '<p>'. __('The internet is based on the concept of hyperlinks, so linking to different websites is completely natural. However, avoid linking to low-quality or spammy sites. If youre uncertain about a site quality, add the "nofollow" attribute to your link.', 'siteseo') .'</p>';
if($total_outbound > 0){
/* translators: %s represents the detected outbound links on page */
$details .= '<p>'.sprintf(__('We detected %s outbound links on your page. Below is the list.', 'siteseo'), $total_outbound) .'</p>';
$details .= '<ul>';
foreach($outbound_links as $link){
$details .= '<li><span class="dashicons dashicons-arrow-right"></span>';
$details .= '<a href="'.esc_url($link).'" target="_blank">'.esc_url($link).'</a></li>';
}
$details .= '</ul>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('This page does not contain any outbound links.', 'siteseo') . '</p>';
}
return [
'label' => __('Outbound Links', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function analyze_internal_links($content){
preg_match_all('/<a[^>]+href=([\'"])(?!#)([^\'"]+)[\'"][^>]*>(.*?)<\/a>/i', $content, $links, PREG_SET_ORDER);
$internal_links = array_filter($links, function($link) {
return strpos($link[2], get_site_url()) !== false;
});
$total_internal = count($internal_links);
$status = $total_internal > 0 ? 'Good' : 'Warning';
$details = '';
$details .= '<p>'. __('Internal links are crucial for both SEO and user experience. Always aim to interconnect your content using meaningful and relevant anchor text.', 'siteseo') .'</p>';
if($total_internal > 0){
/* translators: %s represents the internal links pointing to page */
$details .= '<p>'. sprintf(__('We identified %s internal links pointing to this page.', 'siteseo'), $total_internal) .'</p>';
$details .= '<ul>';
foreach($internal_links as $link){
$url = $link[2];
$post_id = url_to_postid($url);
$details .= '<li><span class="dashicons dashicons-arrow-right"></span>';
$details .= '<a href="'.esc_url($url) .'" target="_blank">'. esc_html($url) . '</a>';
if($post_id){
$details .= '<a class="nounderline" href="' . get_edit_post_link($post_id) . '" ' .
'title="' .
/* translators: %s represents the degree of severity */
sprintf(__('edit %s', 'siteseo'), esc_html(get_the_title($post_id))) . '">' .
'<span class="dashicons dashicons-edit-large"></span></a>';
}
$details .= '</li>';
}
$details .= '</ul>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
__('This page has no internal links from other content. Links from archive pages are not counted as internal links because they lack contextual relevance.', 'siteseo') . '</p>';
}
return [
'label' => __('Internal Links', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function analyze_nofollow_links($content){
preg_match_all('/<a[^>]+href=([\'"])([^\'"]+)[\'"][^>]*>(.*?)<\/a>/i', $content, $all_links, PREG_SET_ORDER);
$nofollow_links = array_filter($all_links, function($link){
return preg_match('/rel=[\'"][^\'"]*nofollow[^\'"]*[\'"]/', $link[0]);
});
$total_nofollow = count($nofollow_links);
$status = $total_nofollow > 0 ? 'Warning' : 'Good';
$details = '';
if($total_nofollow > 0){
$details .= '<p>' .
/* translators: %d represents the number nofollow attribute */
sprintf( esc_html__('We found %d links with the nofollow attribute on your page. Avoid overusing the nofollow attribute in links. Below is the list:', 'siteseo'),
$total_nofollow
) . '</p>';
$details .= '<ul>';
foreach($nofollow_links as $link){
$href = $link[2];
$link_text = $link[3];
$details .= '<li>'.
'<span class="dashicons dashicons-arrow-right"></span>'.
'<a href="' . esc_url($href) . '" target="_blank">'.esc_html($link_text).'</a>'.
'<span class="dashicons dashicons-external"></span>'.
'</li>';
}
$details .= '</ul>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' .
__('This page does not contain any nofollow links.', 'siteseo') . '</p>';
}
return [
'label' => __('Nofollow Links', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_headings($content, $keywords = []) {
$details = '';
$status = 'Good';
$status_class = 'good';
if(empty(trim($content))){
return [
'label' => 'Headings',
'status' => 'Warning',
'status_class' => 'warning',
'details' => '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('No content available to check headings.', 'siteseo') . '</p>'
];
}
preg_match_all('/<h([1-6])([^>]*)>(.*?)<\/h\1>/is', $content, $heading_matches);
if(empty($heading_matches[0])){
return [
'label' => 'Headings',
'status' => 'Error',
'status_class' => 'error',
'details' => '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('No headings found in the content. Using headings is essential for both SEO and accessibility!', 'siteseo') . '</p>'
];
}
$heading_counts = array_count_values($heading_matches[1]);
$total_headings = count($heading_matches[0]);
$h1_count = isset($heading_counts[1]) ? $heading_counts[1] : 0;
if($h1_count > 0){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
/* translators: %d represents the number of h1 tags */
sprintf(esc_html__('We found %d Heading 1 (H1) tags in your content.', 'siteseo'), $h1_count+1) . '</p>';
$details .= '<p>' . __('You should avoid using more than one H1 heading in your post content. The rule is simple: each web page should have only one H1, which benefits both SEO and accessibility. Below is the list:', 'siteseo') . '</p>';
$details .= '<ul>';
foreach(array_keys($heading_matches[1], '1') as $index){
$details .= '<li><span class="dashicons dashicons-arrow-right"></span>' .
wp_strip_all_tags($heading_matches[0][$index]) . '</li>';
}
$details .= '</ul>';
$status = 'Warning';
$status_class = 'warning';
}
foreach([2, 3] as $level){
$level_count = isset($heading_counts[$level]) ? $heading_counts[$level] : 0;
$details .= '<p><span class="dashicons dashicons-info"></span>' .
/* translators: %d represents the heading */
sprintf(__('Found %1$d H%2$d heading(s)', 'siteseo'), $level_count, $level) . '</p>';
if($level_count > 0){
$details .= '<ul>';
foreach(array_keys($heading_matches[1], (string)$level) as $index){
$details .= '<li><span class="dashicons dashicons-arrow-right"></span>'.
wp_strip_all_tags($heading_matches[0][$index]) .'</li>';
}
$details .= '</ul>';
}
if(!empty($keywords) && $level_count > 0){
$keyword_found = false;
$keyword_details = '<ul>';
foreach($keywords as $kw_name){
$kw_count = 0;
foreach(array_keys($heading_matches[1], (string)$level) as $index){
$kw_count += substr_count(
strtolower(wp_strip_all_tags($heading_matches[0][$index])),
strtolower($kw_name)
);
}
if($kw_count > 0){
$keyword_found = true;
$keyword_details .= '<li><span class="dashicons dashicons-arrow-right"></span>' .
/* translators: %s represents the degree of severity */
sprintf(esc_html__('%1$s was found %2$d times.', 'siteseo'), $kw_name, $kw_count) . '</li>';
}
}
$keyword_details .= '</ul>';
if($keyword_found){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' .
/* translators: %s represents the target keywords */
sprintf(__('Target keywords were found in Heading %1$d (H%2$d).', 'siteseo'), $level, $level) . '</p>' .
$keyword_details;
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' .
/* translators: %d represents the target keywords */
sprintf(__('None of your target keywords were found in Heading %1$d (H%2$d).', 'siteseo'), $level, $level) . '</p>';
if($status === 'Good'){
$status = 'Warning';
$status_class = 'warning';
}
}
}
}
return [
'label' => 'Headings',
'status' => $status,
'status_class' => $status_class,
'details' => $details
];
}
static function check_social_meta_tags($post = null){
if(!$post){
$post = get_queried_object();
}
$details = '';
$status = 'Good';
$status_class = 'good';
$og_titles = get_post_meta($post->ID, '_siteseo_social_fb_title', true);
$og_title = $og_titles ? $og_titles : '';
if(empty($og_title)){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your Open Graph Title tag has not been set!', 'siteseo') .'</p>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your Open Graph Title is missing!', 'siteseo') .'</p>';
$status = 'Error';
$status_class = 'error';
} else{
$details .= '<h4>'. __('Open Graph Title', 'siteseo') . '</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('An Open Graph Title tag was found in your source code.', 'siteseo') . '</p>';
$details .= '<ul><li><span class="dashicons dashicons-arrow-right"></span>' . esc_html($og_title) . '</li></ul>';
}
$og_descriptions = get_post_meta($post->ID, '_siteseo_social_fb_desc', true);
$og_description = $og_descriptions ? $og_descriptions : '';
if(empty($og_description)){
$details .= '<h4>'. __('Open Graph Description', 'siteseo') .'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your Open Graph Description has not been set!','siteseo').'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
} else {
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' .
/* translators: %s represents the og description */
sprintf(esc_html__('We found %s og:description in your content.', 'siteseo'), $og_descriptions) . '</p>';
}
// OG Check
$og_images = get_post_meta($post->ID, '_siteseo_social_fb_img', true);
$og_image = $og_images ? $og_images : '';
if(empty($og_image)){
$details .= '<h4>'. __('Open Graph Image', 'siteseo') .'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your Open Graph Image has not been set!' ,'siteseo') .'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
} else{
/* translators: %s represents the og images */
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. sprintf(esc_html__('We found %s og:image in your content.', 'siteseo'), $og_images) . '</p>';
}
// Open Graph
$og_site_name = get_bloginfo('name');
if(empty($og_site_name)){
$details .= '<h4>'. __('Open Graph Site Name', 'siteseo') .'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your Open Graph Site Name has not been set!' ,'siteseo') .'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = ($status_class === 'good') ? 'warning' : $status_class;
}
// Twitter
$twitter_title = get_post_meta($post->ID, '_siteseo_social_twitter_title', true);
if(empty($twitter_title)){
$details .= '<h4>'. __('X Title', 'siteseo').'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your X Title has not been set!', 'siteseo').'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
}
$twitter_description = get_post_meta($post->ID, '_siteseo_social_twitter_desc', true);
if(empty($twitter_description)){
$details .= '<h4>'. __('X Description','siteseo').'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your X Description has not been set!','siteseo') .'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = $status_class === 'good' ? 'warning' : $status_class;
}
$twitter_image = get_post_meta($post->ID, '_siteseo_social_twitter_img', true);
if(empty($twitter_image)){
$details .= '<h4>'. __('X Image', 'siteseo') .'</h4>';
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('Your X Image has not been set!', 'siteseo').'</p>';
$status = $status === 'Good' ? 'Warning' : $status;
$status_class = ($status_class === 'good') ? 'warning' : $status_class;
}
return [
'label' => __('Social Meta Tags', 'siteseo'),
'status' => $status,
'status_class' => $status_class,
'details' => $details
];
}
static function check_structured_data($post){
$schema_type = get_post_meta($post->ID, '_siteseo_structured_data_type', true);
$status = !empty($schema_type) ? 'Good' : 'Warning';
return [
'label' => 'Structured Data',
'status' => $status,
'status_class' => strtolower($status),
'details' => !empty($schema_type) ? 'Schema Type: '.$schema_type : 'No schema defined'
];
}
static function check_keywords_in_permalink($permalink, $keywords){
$keywords = array_filter(explode(',', trim($keywords)));
$permalink = str_replace('-', ' ', strtolower(basename($permalink)));
$content_words = str_word_count($permalink, 1);
$count_words = count($content_words);
$kw_density = [];
$matching_keywords = [];
foreach($keywords as $keyword){
$keyword_occurrence = 0;
$keyword = strtolower(trim($keyword));
// If keyword has multiple words
if(str_word_count($keyword) > 1){
$pattern = '/\b' . preg_quote($keyword, '/') . '\b/i';
preg_match_all($pattern, $permalink, $matches);
$keyword_occurrence = count($matches[0]);
} else {
$word_counts = array_count_values($content_words);
$keyword_occurrence = isset($word_counts[$keyword]) ? $word_counts[$keyword] : 0;
}
// Calculate density as percentage
$kw_density[] = ($keyword_occurrence * str_word_count($keyword) * 100)/$count_words;
if(count($kw_density) > 0){
$matching_keywords[] = $keyword;
break;
}
}
$status = !empty($kw_density) ? 'Good' : 'Error';
$details = '';
if($status === 'Good'){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('Great! One of your target keywords is included in your permalink.', 'siteseo') .'</p>';
$details .= '<ul><li><span class="dashicons dashicons-arrow-right"></span>' . implode(', ', $matching_keywords) . '</li></ul>';
} elseif($permalink === get_home_url() || $permalink === home_url()){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('This is your homepage, so this check doesn\'t apply as there is no slug.', 'siteseo') . '</p>';
} else{
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('You should include one of your target keywords in your permalink.', 'siteseo') . '</p>';
}
return [
'label' => __('Keywords in Permalink', 'siteseo'),
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_meta_robots($post){
$noindex = get_post_meta($post->ID, '_siteseo_robots_index', true);
$nofollow = get_post_meta($post->ID, '_siteseo_robots_follow', true);
$noimageindex = get_post_meta($post->ID, '_siteseo_robots_imageindex', true);
$noarchive = get_post_meta($post->ID, '_siteseo_robots_archive', true);
$nosnippet = get_post_meta($post->ID, '_siteseo_robots_snippet', true);
$count_meta_robots = 0;
$details = '';
$meta_robots_checks = [
'noindex' => $noindex,
'nofollow' => $nofollow,
'noimageindex' => $noimageindex,
'noarchive' => $noarchive,
'nosnippet' => $nosnippet,
];
foreach($meta_robots_checks as $robot => $value){
if($value !== 'yes'){
continue;
}
$count_meta_robots++;
switch($robot){
case 'noindex':
$details .= '<p data-robots="noindex"><span class="dashicons dashicons-thumbs-down"></span>' . __('<strong>noindex</strong> is enabled! Search engines cannot index this page', 'siteseo') . '</p>';
break;
case 'nofollow':
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('<strong>nofollow</strong> is on! Search engines can\'t follow your links on this page.', 'siteseo') . '</p>';
break;
case 'noimageindex':
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('<strong>nofollow</strong> is enabled! Search engines cannot follow the links on this page.', 'siteseo').'</p>';
break;
case 'noarchive':
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('<strong>noarchive</strong> is enabled! Search engines will not cache your page.', 'siteseo') .'</p>';
break;
case 'nosnippet':
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>' . __('<strong>nosnippet</strong> is enabled! Search engines will not display a snippet of this page in the search results.', 'siteseo') .'</p>';
break;
}
}
if($count_meta_robots > 0){
/* translators: %s represents the robots tags */
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. sprintf(esc_html__('We found %s meta robots tags on your page. There may be an issue with your theme!', 'siteseo'), $count_meta_robots) .'</p>';
}
if($noindex !== 'yes'){
$details .= '<p data-robots="index"><span class="dashicons dashicons-thumbs-up"></span>'. __('<strong>noindex</strong> is disabled. Search engines will index this page.', 'siteseo') .'</p>';
}
if($nofollow !== 'yes'){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('<strong>nofollow</strong> is disabled. Search engines will follow links on this page.', 'siteseo') .'</p>';
}
if($noimageindex !== 'yes'){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('<strong>noimageindex</strong> is disabled. Google will index the images on this page.', 'siteseo') .'</p>';
}
if($noarchive !== 'yes'){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('<strong>noarchive</strong> is disabled. Search engines will probably cache your page.', 'siteseo') .'</p>';
}
if($nosnippet !== 'yes'){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>'. __('<strong>nosnippet</strong> is disabled. Search engines will display a snippet of this page in search results.', 'siteseo') .'</p>';
}
if($count_meta_robots === 0){
$details .= '<p><span class="dashicons dashicons-thumbs-up"></span>' . __('We found no meta robots on this page. It means, your page is index,follow. Search engines will index it, and follow links. ', 'siteseo') . '</p>';
}
$status = ($count_meta_robots === 0) ? 'Good' :
(($count_meta_robots <= 2) ? 'Warning' : 'Error');
return [
'label' => 'Meta Robots',
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function check_last_modified_date($post){
$last_modified = get_the_modified_date('Y-m-d', $post);
$days_since_modified = round((time() - strtotime($last_modified)) / (60 * 60 * 24));
$status = $days_since_modified < 30 ? 'Good' :
($days_since_modified < 90 ? 'Warning' : 'Error');
$details = '';
if($status == 'Error'){
$details .= '<p><span class="dashicons dashicons-thumbs-down"></span>'. __('This post is a little old!', 'siteseo') .'</p>';
}
if($days_since_modified < 365){
$details .='<p><span class="dashicons dashicons-thumbs-up"></span>'.__('The last modified date of this article is less than 1 year. Cool', 'siteseo') .'</p>';
}
$details .= '<p>'.__('Search engines love fresh content. Update regularly your articles without entirely rewriting your content and give them a boost in search rankings. SiteSEO takes care of the technical part', 'siteseo').'</p>';
return [
'label' => 'Last Modified Date',
'status' => $status,
'status_class' => strtolower($status),
'details' => $details
];
}
static function analyze_readability($post, $title){
$data = [];
// These are power words specifically for headlines.
// These are not hard rules, but they are perceived to have a higher CTR if used in the heading.
$power_words = ['exclusive', 'revealed', 'secrets', 'ultimate', 'proven', 'unleashed', 'discover', 'breakthrough', 'shocking', 'insider', 'elite', 'uncovered', 'powerful', 'guaranteed', 'transformative', 'instant', 'revolutionary', 'unbelievable', 'top', 'best', 'must-have', 'limited', 'rare', 'unique', 'unprecedented', 'premium', 'urgent', 'today', 'now', 'latest', 'new', 'free', 'bonus', 'offer', 'sensational', 'astonishing', 'incredible', 'jaw-dropping', 'unmissable', 'essential', 'critical', 'vital', 'pivotal', 'game-changer', 'spotlight', 'trending', 'hot', 'popular', 'featured', 'special', 'limited-time', 'hurry', 'last chance', 'countdown'];
if(!empty($title)){
// Checking power words.
$title_words = explode(' ', strtolower($title));
$present_power_words = array_intersect($title_words, $power_words);
if(!empty($present_power_words)){
$data['power_words'] = $present_power_words;
}
// Checking number in the Title
if(preg_match('/\s?\d+\s/', preg_quote($title), $number)){
$data['number_found'] = $number[0];
}
}
// We are checking paragarph length too.
if(!isset($data['paragraph_length'])){
$data['paragraph_length'] = 0;
}
if(!empty($post)){
preg_match_all('/<p>.*<\/p>/U', $post, $paragraphs);
foreach($paragraphs[0] as $paragraph){
$paragraph = normalize_whitespace(wp_strip_all_tags($paragraph));
$data['paragraph_length'] += substr_count($paragraph, ' ') + 1; // updating paragraph length
self::analyse_passive_voice($paragraph, $data);
}
}
return $data;
}
static function analyse_passive_voice($paragraph, &$data){
if(empty($paragraph)){
return;
}
$sentences = explode('.', $paragraph);
$passive_count = 0;
if(!isset($data['passive_voice']['passive_sentences'])){
$data['passive_voice']['passive_sentences'] = 0;
}
if(!isset($data['passive_voice']['total_sentences'])){
$data['passive_voice']['total_sentences'] = 0;
}
if(count($sentences) === 0){
return;
}
foreach($sentences as $sentence){
if(empty($sentence)){
continue;
}
$sentence = normalize_whitespace($sentence);
$is_passive = self::sentence_is_passive($sentence);
if($is_passive == true){
$passive_count++;
}
}
$data['passive_voice']['passive_sentences'] += $passive_count;
$data['passive_voice']['total_sentences'] += count($sentences);
}
static function sentence_is_passive($sentence){
$be_words = ['am', 'is', 'are', 'was', 'were', 'be', 'being', 'been'];
// TODO: We can check if "en" ending words are a comman pattern too, then we will remove the en ending words too from here.
$past_particles = ['gone' ,'done' ,'seen' ,'taken' ,'eaten' ,'written' ,'driven' ,'spoken' ,'broken' ,'chosen' ,'fallen' ,'forgotten' ,'forgiven' ,'hidden' ,'known' ,'grown' ,'drawn' ,'flown' ,'thrown' ,'blown' ,'shown' ,'worn' ,'sworn' ,'torn' ,'woken' ,'begun' ,'sung' ,'run' ,'swum' ,'shaken' ,'given' ,'proven' ,'ridden' ,'risen' ,'shone' ,'shot' ,'fought' ,'thought' ,'bought' ,'brought' ,'caught' ,'taught' ,'built' ,'felt' ,'kept' ,'slept' ,'left' ,'lost' ,'meant' ,'met' ,'read' ,'sold' ,'sent' ,'spent' ,'stood' ,'understood' ,'won' ,'held' ,'told' ,'heard' ,'paid' ,'laid' ,'said' ,'found' ,'made' ,'learned' ,'put'];
if(empty($sentence)){
return false;
}
$words = explode(' ', $sentence);
for($i = 0; $i < count($words); $i++){
// Checking if we have a be word
if(!in_array($words[$i], $be_words)){
continue;
}
// If be word is there then need to check if next one is past particle with mostly ends with ed.
if(strpos($words[$i+1], 'ed') != strlen($words[$i+1]) - 2){
if(!in_array($words[$i+1], $past_particles)){
continue;
}
}
return true;
}
return false;
}
static function get_bricks_page_content($bricks_page){
if(empty($bricks_page) || !is_array($bricks_page)){
return;
}
$content = \Bricks\Frontend::render_data($bricks_page);
$content = strip_shortcodes($content); // remove shortcodes
$content = wp_strip_all_tags($content); // remove HTML tags
return $content;
}
}
metaboxes/settings.php 0000644 00000215572 15152641524 0011125 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO\Metaboxes;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Settings{
static function render_metabox(){
global $siteseo;
$metabox_data = [];
$show_content_analysis = true;
if(is_user_logged_in()){
if(is_super_admin()){
$siteseo->display_ca_metaboxe = 1;
$show_content_analysis = true;
} else{
$user = wp_get_current_user();
$siteseo_user_role = current($user->roles);
$siteseo_options = get_option('siteseo_advanced_option_name');
$ca_metabox_roles = !empty($siteseo_options['security_metaboxe_ca_role']) ? $siteseo_options['security_metaboxe_ca_role'] : [];
if(array_key_exists($siteseo_user_role, $ca_metabox_roles)){
$siteseo->display_ca_metaboxe = 1;
$show_content_analysis = false;
}
}
}
$metabox_data = self::metabox_data();
self::metabox_form_html($metabox_data, $show_content_analysis);
}
static function metabox_data(){
global $post, $siteseo;
$metabox_data = [];
$metabox_data['title'] = $post->post_title;
$metabox_data['excerpt'] = $post->post_excerpt;
// Getting the first paragraph of the post
if(empty($metabox_data['excerpt'])){
$post_seperated = get_extended($post->post_content);
if(!empty($post_seperated['main'])){
$metabox_data['excerpt'] = wp_strip_all_tags($post_seperated['main']);
}
}
$metabox_data['keywords'] = get_post_meta($post->ID, 'siteseo_analysis_target_kw',true);
$metabox_data['meta_title'] = get_post_meta($post->ID, '_siteseo_titles_title', true);
$metabox_data['meta_desc'] = get_post_meta($post->ID, '_siteseo_titles_desc', true);
$metabox_data['robots_canonical'] = get_post_meta($post->ID, '_siteseo_robots_canonical', true);
$metabox_data['robots_primary_cat'] = get_post_meta($post->ID, '_siteseo_robots_primary_cat', true);
$metabox_data['fb_title'] = get_post_meta($post->ID, '_siteseo_social_fb_title', true);
$metabox_data['fb_desc'] = get_post_meta($post->ID, '_siteseo_social_fb_desc', true);
$metabox_data['fb_img'] = get_post_meta($post->ID, '_siteseo_social_fb_img', true);
$siteseo_social_fb_img_attachment_id = get_post_meta($post->ID, '_siteseo_social_fb_img_attachment_id', true);
$siteseo_social_fb_img_width = get_post_meta($post->ID, '_siteseo_social_fb_img_width', true);
$siteseo_social_fb_img_height = get_post_meta($post->ID, '_siteseo_social_fb_img_height', true);
$metabox_data['x_title'] = get_post_meta($post->ID, '_siteseo_social_twitter_title', true);
$metabox_data['x_desc'] = get_post_meta($post->ID, '_siteseo_social_twitter_desc', true);
$metabox_data['x_img'] = get_post_meta($post->ID, '_siteseo_social_twitter_img', true);
$siteseo_social_twitter_img_attachment_id = get_post_meta($post->ID, '_siteseo_social_twitter_img_attachment_id', true);
$siteseo_social_twitter_img_width = get_post_meta($post->ID, '_siteseo_social_twitter_img_width', true);
$siteseo_social_twitter_img_height = get_post_meta($post->ID, '_siteseo_social_twitter_img_height', true);
$metabox_data['redirections_enabled'] = get_post_meta($post->ID, '_siteseo_redirections_enabled', true);
$metabox_data['redirections_enabled_regex'] = get_post_meta($post->ID, '_siteseo_redirections_enabled_regex', true);
$metabox_data['redirections_logged_status'] = get_post_meta($post->ID, '_siteseo_redirections_logged_status', true);
$metabox_data['redirections_type'] = get_post_meta($post->ID, '_siteseo_redirections_type', true);
$metabox_data['redirections_value'] = get_post_meta($post->ID, '_siteseo_redirections_value', true);
$metabox_data['redirections_param'] = get_post_meta($post->ID, '_siteseo_redirections_param', true);
$title_options = get_option('siteseo_titles_option_name', []);
$metabox_data['disabled_robots'] = [
'robots_index' => '',
'robots_follow' => '',
'archive' => '',
'snippet' => '',
'imageindex' => '',
];
if(post_password_required($post->ID) === true || !empty($title_options['titles_noindex'])){
$metabox_data['robots_index'] = 'yes';
$metabox_data['disabled_robots']['robots_index'] = 'disabled';
} else{
$metabox_data['robots_index'] = get_post_meta($post->ID, '_siteseo_robots_index', true);
}
if(!empty($title_options['titles_nofollow'])){
$metabox_data['robots_follow'] = 'yes';
$metabox_data['disabled_robots']['robots_follow'] = 'disabled';
} else{
$metabox_data['robots_follow'] = get_post_meta($post->ID, '_siteseo_robots_follow', true);
}
if(!empty($title_options['titles_noarchive'])){
$metabox_data['robots_archive'] = 'yes';
$metabox_data['disabled_robots']['archive'] = 'disabled';
} else{
$metabox_data['robots_archive'] = get_post_meta($post->ID, '_siteseo_robots_archive', true);
}
if(!empty($title_options['titles_nosnippet'])){
$metabox_data['robots_snippet'] = 'yes';
$metabox_data['disabled_robots']['snippet'] = 'disabled';
} else{
$metabox_data['robots_snippet'] = get_post_meta($post->ID, '_siteseo_robots_snippet', true);
}
if(!empty($title_options['titles_noimageindex'])){
$metabox_data['robots_imageindex'] = 'yes';
$metabox_data['disabled_robots']['imageindex'] = 'disabled';
} else{
$metabox_data['robots_imageindex'] = get_post_meta($post->ID, '_siteseo_robots_imageindex', true);
}
return $metabox_data;
}
static function metabox_term_data($term){
global $tag;
$metabox_data = [];
$metabox_data['title'] = $tag->name;
$metabox_data['excerpt'] = $tag->description;
$metabox_data['meta_title'] = get_term_meta($term->term_id, '_siteseo_titles_title', true);
$metabox_data['meta_desc'] = get_term_meta($term->term_id, '_siteseo_titles_desc', true);
// Social Fields
$metabox_data['fb_title'] = get_term_meta($term->term_id, '_siteseo_social_fb_title', true);
$metabox_data['fb_desc'] = get_term_meta($term->term_id, '_siteseo_social_fb_desc', true);
$metabox_data['fb_img'] = get_term_meta($term->term_id, '_siteseo_social_fb_img', true);
$metabox_data['x_title'] = get_term_meta($term->term_id, '_siteseo_social_twitter_title', true);
$metabox_data['x_desc'] = get_term_meta($term->term_id, '_siteseo_social_twitter_desc', true);
$metabox_data['x_img'] = get_term_meta($term->term_id, '_siteseo_social_twitter_img', true);
// Social Dimensions
$fb_img_id = get_term_meta($term->term_id, '_siteseo_social_fb_img_attachment_id', true);
$fb_img_width = get_term_meta($term->term_id, '_siteseo_social_fb_img_width', true);
$fb_img_height = get_term_meta($term->term_id, '_siteseo_social_fb_img_height', true);
$x_img_id = get_term_meta($term->term_id, '_siteseo_social_twitter_img_attachment_id', true);
$x_img_width = get_term_meta($term->term_id, '_siteseo_social_twitter_img_width', true);
$x_img_height = get_term_meta($term->term_id, '_siteseo_social_twitter_img_height', true);
// Redirection fields
$metabox_data['redirections_enabled'] = get_term_meta($term->term_id, '_siteseo_redirections_enabled', true);
$metabox_data['redirections_logged_status'] = get_term_meta($term->term_id, '_siteseo_redirections_logged_status', true);
$metabox_data['redirections_type'] = get_term_meta($term->term_id, '_siteseo_redirections_type', true);
$metabox_data['redirections_value'] = get_term_meta($term->term_id, '_siteseo_redirections_value', true);
$metabox_data['robots_canonical']= get_term_meta($term->term_id, '_siteseo_robots_canonical', true);
$title_options = get_option('siteseo_titles_option_name', []);
$metabox_data['disabled_robots'] = [
'robots_index' => '',
'robots_follow' => '',
'archive' => '',
'snippet' => '',
'imageindex' => '',
];
if(!empty($title_options['titles_noindex'])){
$metabox_data['robots_index'] = 'yes';
$metabox_data['disabled_robots']['robots_index'] = 'disabled';
} else {
$metabox_data['robots_index'] = get_term_meta($term->term_id, '_siteseo_robots_index', true);
}
if(!empty($title_options['titles_nofollow'])){
$metabox_data['robots_follow'] = 'yes';
$metabox_data['disabled_robots']['robots_follow'] = 'disabled';
} else {
$metabox_data['robots_follow'] = get_term_meta($term->term_id, '_siteseo_robots_follow', true);
}
if(!empty($title_options['titles_noarchive'])){
$metabox_data['robots_archive'] = 'yes';
$metabox_data['disabled_robots']['archive'] = 'disabled';
} else {
$metabox_data['robots_archive'] = get_term_meta($term->term_id, '_siteseo_robots_archive', true);
}
if(!empty($title_options['titles_nosnippet'])){
$metabox_data['robots_snippet'] = 'yes';
$metabox_data['disabled_robots']['snippet'] = 'disabled';
} else {
$metabox_data['robots_snippet'] = get_term_meta($term->term_id, '_siteseo_robots_snippet', true);
}
if(!empty($title_options['titles_noimageindex'])){
$metabox_data['robots_imageindex'] = 'yes';
$metabox_data['disabled_robots']['imageindex'] = 'disabled';
} else {
$metabox_data['robots_imageindex'] = get_term_meta($term->term_id, '_siteseo_robots_imageindex', true);
}
return $metabox_data;
}
static function metabox_form_html(&$metabox_data, $show_content_analysis = false){
global $siteseo, $post, $pagenow, $typenow;
$pro_settings = isset($siteseo->pro) ? $siteseo->pro : '';
// Checked x is enabled global settings
$enable_x_card = !empty($siteseo->social_settings['social_twitter_card']);
$data_attr = [];
$data_attr['data_tax'] = '';
$data_attr['termId'] = '';
if('post-new.php' == $pagenow || 'post.php' == $pagenow){
$data_attr['current_id'] = $post->ID;
$data_attr['origin'] = 'post';
$data_attr['title'] = get_the_title($data_attr['current_id']);
} elseif('term.php' == $pagenow || 'edit-tags.php' == $pagenow){
global $tag;
$data_attr['current_id'] = $tag->term_id;
$data_attr['termId'] = $tag->term_id;
$data_attr['origin'] = 'term';
$data_attr['data_tax'] = $tag->taxonomy;
$data_attr['title'] = $tag->name;
}
$data_attr['isHomeId'] = get_option('page_on_front');
if($data_attr['isHomeId'] === '0'){
$data_attr['isHomeId'] = '';
}
// Static Data
$home_url = home_url();
$parsed_url = wp_parse_url($home_url);
$host_uri = $parsed_url['host'];
$social_placeholder = SITESEO_ASSETS_URL . '/img/social-placeholder.png';
$metabox_tag_drop_kses = [
'button' => [
'class' => true,
'type' => true,
],
'span' => [
'class' => true,
],
'div' => [
'class' => true,
'style' => true,
],
'input' => [
'type' => true,
'class' => true,
'name' => true,
'spellcheck' => true,
'placeholder' => true,
],
'ul' => true,
'li' => [
'class' => true,
'data-*' => true,
'tabindex' => true,
]
];
// Preview of social title and description
$current_screen = get_current_screen();
if(!empty($current_screen) && $current_screen->base === 'term'){
$term_id = isset($_GET['tag_ID']) ? (int)$_GET['tag_ID'] : 0;
$taxonomy = $current_screen->taxonomy;
} else{
$post_type = $current_screen->post_type;
}
$site_title_placeholder = '';
$site_desc_placeholder = '';
$social_preview_title = '';
$social_preview_desc = '';
if(!empty($post_type) && !empty($siteseo->titles_settings['titles_single_titles'][$post_type]['title'])){
$site_title_placeholder = $siteseo->titles_settings['titles_single_titles'][$post_type]['title'];
} elseif(!empty($taxonomy) && !empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy]['title'])){
$site_title_placeholder = $siteseo->titles_settings['titles_tax_titles'][$taxonomy]['title'];
} else{
$site_title_placeholder = $metabox_data['title'];
}
if(!empty($post_type) && !empty($siteseo->titles_settings['titles_single_titles'][$post_type]['description'])){
$site_desc_placeholder = $siteseo->titles_settings['titles_single_titles'][$post_type]['description'];
} elseif(!empty($taxonomy) && !empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy]['description'])){
$site_desc_placeholder = $siteseo->titles_settings['titles_tax_titles'][$taxonomy]['description'];
} else{
$site_desc_placeholder = $metabox_data['excerpt'];
}
if(!empty($metabox_data['meta_title'])){
$social_preview_title = $metabox_data['meta_title'];
} elseif(!empty($post_type) && !empty($siteseo->titles_settings['titles_single_titles'][$post_type]['title'])){
$social_preview_title = $siteseo->titles_settings['titles_single_titles'][$post_type]['title'];
} elseif(!empty($taxonomy) && !empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy]['title'])){
$social_preview_title = $siteseo->titles_settings['titles_tax_titles'][$taxonomy]['title'];
} else{
$social_preview_title = get_the_title();
}
if(!empty($metabox_data['meta_desc'])){
$social_preview_desc = $metabox_data['meta_desc'];
} elseif(!empty($post_type) && !empty($siteseo->titles_settings['titles_single_titles'][$post_type]['description'])){
$social_preview_desc = $siteseo->titles_settings['titles_single_titles'][$post_type]['description'];
} elseif(!empty($taxonomy) && !empty($siteseo->titles_settings['titles_tax_titles'][$taxonomy]['description'])){
$social_preview_desc = $siteseo->titles_settings['titles_tax_titles'][$taxonomy]['description'];
} else{
$social_preview_desc = get_bloginfo('description');
}
if(empty($siteseo->advanced_settings['appearance_ca_metaboxe']) && !empty($show_content_analysis)){
$siteseo_metabox_tabs = [
'content-analysis' => __('Content Analysis', 'siteseo')
];
}
$siteseo_metabox_tabs['title-settings'] = __('Title', 'siteseo');
$siteseo_metabox_tabs['social-settings'] = __('Social', 'siteseo');
$siteseo_metabox_tabs['advanced-settings'] = __('Advanced', 'siteseo');
$siteseo_metabox_tabs['redirect'] = __('Redirects', 'siteseo');
if(!empty($pro_settings['enable_structured_data']) && !empty($pro_settings['toggle_state_stru_data']) && !empty($show_content_analysis)){
$siteseo_metabox_tabs['structured-data-types'] = __('Structured Data Types', 'siteseo');
}
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap']) && !empty($show_content_analysis)){
$siteseo_metabox_tabs['video-sitemap'] = __('Video Sitemap', 'siteseo');
}
if(!empty($pro_settings['toggle_state_google_news']) && !empty($pro_settings['google_news']) && !empty($show_content_analysis)){
$siteseo_metabox_tabs['google-news'] = __('Google News', 'siteseo');
}
echo'<div id="siteseo-metabox-wrapper" class="siteseo-metabox-wrapper">
<div class="siteseo-metabox-tabs" data-home-id="'.esc_attr($data_attr['isHomeId']).'" data-term-id="'.esc_attr($data_attr['termId']).'" data_id="'.esc_attr($data_attr['current_id']).'" data_origin="'.esc_attr($data_attr['origin']).'" data_tax="'.esc_attr($data_attr['data_tax']).'">';
wp_nonce_field('siteseo_metabox_nonce', 'siteseo_metabox_nonce');
foreach($siteseo_metabox_tabs as $siteseo_metabox_tab => $siteseo_metabox_tab_title){
$selected_metabox_tab = '';
if($siteseo_metabox_tab === 'content-analysis'){
$selected_metabox_tab = 'siteseo-metabox-tab-label-active';
}
if(empty($siteseo->display_ca_metaboxe) && $siteseo_metabox_tab === 'title-settings'){
$selected_metabox_tab = 'siteseo-metabox-tab-label-active';
}
echo'<div class="siteseo-metabox-tab-label '.esc_attr($selected_metabox_tab).'" data-tab="siteseo-metabox-tab-'.esc_attr($siteseo_metabox_tab).'">';
if($siteseo_metabox_tab === 'advanced-settings' && !empty($metabox_data['robots_index'])){
echo'<span class="dashicons dashicons-hidden siteseo-noindex-warning"></span>';
}
echo esc_html($siteseo_metabox_tab_title).'</div>';
}
$home_url = home_url();
$parsed_home_url = wp_parse_url($home_url);
$ai_logo = SITESEO_ASSETS_URL . '/img/siteseo-ai.svg';
$meta_desc_percentage = '1';
if(!empty($metabox_data['meta_desc'])){
$meta_desc_percentage = (strlen($metabox_data['meta_desc'])/160)*100;
} elseif(!empty($metabox_data['excerpt'])){
$meta_desc_percentage = (strlen($metabox_data['excerpt'])/160)*100;
}
if(intval($meta_desc_percentage) > 100){
$meta_desc_percentage = '100';
}
$meta_title_percentage = '1';
if(!empty($metabox_data['meta_title'])){
$meta_title_percentage = (strlen($metabox_data['meta_title'])/60)*100;
} else if(!empty($metabox_data['title'])){
$meta_title_percentage = (strlen($metabox_data['title'])/60)*100;
}
if(intval($meta_title_percentage) > 100){
$meta_title_percentage = '100';
}
echo'</div>';
if(empty($siteseo->advanced_settings['appearance_ca_metaboxe']) && $show_content_analysis){
echo'<div class="siteseo-sidebar-tabs siteseo-sidebar-tabs-opened"><span>'.esc_html__('Content Analysis', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-content-analysis siteseo-metabox-tab" style="display:block;">';
self::content_analysis($post);
echo'</div>';
}
$allowed_suggestion_tags = array(
'button' => array(
'class' => array(),
'type' => array(),
),
'span' => array(
'id' => array(),
'class' => array(),
),
'div' => array(
'class' => array(),
'style' => array(),
),
'input' => array(
'type' => array(),
'class' => true,
'placeholder' => true,
)
);
// if all x-settings empty then use same as og option enabled
$use_og_settings = (empty($metabox_data['x_title']) && empty($metabox_data['x_desc']) && empty($metabox_data['x_img']));
// show image in preview
if(!empty($metabox_data['x_img'])){
$x_image = $metabox_data['x_img'];
} else if(!empty($metabox_data['fb_img']) && !empty($use_og_settings)){ // use og enabled
$x_image = $metabox_data['fb_img'];
} else{
$x_image = $social_placeholder;
}
// x preview title
if(!empty($metabox_data['x_title'])){
$x_title_preview = $metabox_data['x_title'];
} else if($metabox_data['fb_title'] && !empty($use_og_settings)){
$x_title_preview = $metabox_data['fb_title'];
} else {
$x_title_preview = $social_preview_title;
}
echo'<div class="siteseo-sidebar-tabs '.(empty($siteseo->display_ca_metaboxe) ? 'siteseo-sidebar-tabs-opened' : '').'"><span>'.esc_html__('Title', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-title-settings siteseo-metabox-tab" style="'.(empty($siteseo->display_ca_metaboxe) ? 'display:block;' : '').'">
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label>'.esc_html__('Search Preview','siteseo').'</label>
</div>
<div class="siteseo-metabox-search-preview">
<div class="siteseo-search-preview-toggle">
<span id="siteseo-metabox-search-pc" style="display:none">'.esc_html__('Show Desktop version', 'siteseo').'</span>
<span id="siteseo-metabox-search-mobile">'.esc_html__('Show Mobile version', 'siteseo').'</span>
</div>
<div class="siteseo-search-preview-desktop">
<div class="siteseo-search-preview-metadata">
<div style="background-color: #e2eeff; border: 1px solid #e2eeff; height:28px; width:28px; padding: 3px; border-radius: 50px; display:flex; align-items:center; justify-content:center;">
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#0060f0"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"></path></svg>
</div>
<div class="siteseo-search-preview-metadata-link">
<div>'.esc_url($parsed_home_url['host']).'</div>
<div><cite>'.esc_url(home_url()).'</cite></div>
</div>
<div>
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" width="20" viewBox="0 0 24 24"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></svg>
</div>
</div>
<h3>'.(!empty($metabox_data['meta_title']) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($metabox_data['meta_title'], true)) : (!empty($site_title_placeholder) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($site_title_placeholder, true)) : 'Post Title here')).'</h3>
<div class="siteseo-search-preview-description">
'.(!empty($metabox_data['meta_desc']) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($metabox_data['meta_desc'], true)) : (!empty($site_desc_placeholder) ? esc_html(substr(\SiteSEO\TitlesMetas::replace_variables($site_desc_placeholder, true), 0, 160)) : 'Post description')).'
</div>
</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_titles_title_meta">'.esc_html__('Title', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-metabox-tag" data-tag="%%post_title%%"><span class="dashicons dashicons-plus"></span> Post Title</button>
<button type="button" class="siteseo-metabox-tag" data-tag="%%sitetitle%%"><span class="dashicons dashicons-plus"></span> Site Title</button>
<button type="button" class="siteseo-metabox-tag" data-tag="%%sep%%"><span class="dashicons dashicons-plus"></span>Seperator</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="site-page" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
<input type="text" id="siteseo_titles_title_meta" class="siteseo_titles_title_meta" name="siteseo_titles_title" placeholder="'.(!empty($site_title_placeholder) ? esc_attr(\SiteSEO\TitlesMetas::replace_variables($site_title_placeholder, true)) : esc_html__('Enter title for this post', 'siteseo')).'" value="'.(!empty($metabox_data['meta_title']) ? esc_html($metabox_data['meta_title']) : '').'"/>
<div class="siteseo-metabox-limits">
<span class="siteseo-metabox-limits-meter"><span style="width:'.esc_attr($meta_title_percentage).'%"></span></span>
<span class="siteseo-metabox-limits-numbers"><em>'.esc_html(strlen($metabox_data['meta_title'])).'</em> out of 60 max recommended characters</span>
</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_titles_desc_meta">'.esc_html__('Meta Description', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-metabox-tag" data-tag="%%post_excerpt%%"><span class="dashicons dashicons-plus"></span> Post Excerpt</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="site-page" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
<textarea id="siteseo_titles_desc_meta" class="siteseo_titles_desc_meta" name="siteseo_titles_desc" rows="2" placeholder="'.(!empty($site_desc_placeholder) ? esc_attr(substr(\SiteSEO\TitlesMetas::replace_variables($site_desc_placeholder, true), 0, 160)) : esc_html__('Enter description for this post', 'siteseo')).'">'.(!empty($metabox_data['meta_desc']) ? esc_html($metabox_data['meta_desc']) : '').'</textarea>
<div class="siteseo-metabox-limits">
<span class="siteseo-metabox-limits-meter"><span style="width:'.esc_attr($meta_desc_percentage).'%"></span></span>
<span class="siteseo-metabox-limits-numbers"><em>'.esc_html(strlen($metabox_data['meta_desc'])).'</em> out of 160 max recommended characters</span>
</div>
</div>
</div>
</div>
<div class="siteseo-sidebar-tabs"><span>'.esc_html__('Social', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-social-settings siteseo-metabox-tab">
<div class="siteseo-metabox-subtabs">
<div class="siteseo-metabox-tab-label siteseo-metabox-tab-label-active" data-tab="siteseo-metabox-tab-fb-settings">Facebook</div>
<div class="siteseo-metabox-tab-label" data-tab="siteseo-metabox-tab-x-settings">X(Twitter)</div>
</div>
<div class="siteseo-metabox-tab-fb-settings siteseo-metabox-tab" style="display:block;">
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label>'.esc_html__('Preview', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-fb-preview">
<div class="siteseo-metabox-fb-image">
<img src="'.(!empty($metabox_data['fb_img']) ? esc_url($metabox_data['fb_img']) : esc_url($social_placeholder)).'" alt="Facebook preview"/>
</div>
<div class="siteseo-metabox-fb-data">
<div class="siteseo-metabox-fb-host">'.(!empty($host_uri) ? esc_html($host_uri) : '').'</div>
<div class="siteseo-metabox-fb-title">'.(!empty($metabox_data['fb_title']) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($metabox_data['fb_title'], true)) : esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_title, true))).'</div>
<div class="siteseo-metabox-fb-desc">'.(!empty($metabox_data['fb_desc']) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($metabox_data['fb_desc'], true)) : esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_desc, true))).'</div>
</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_fb_title_meta">'.esc_html__('Facebook Title', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<input type="text" id="siteseo_social_fb_title_meta" class="siteseo_social_fb_title_meta" name="siteseo_social_fb_title" placeholder="'.(!empty($social_preview_title) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_title, true)) : '').'" value="'.(!empty($metabox_data['fb_title']) ? esc_attr($metabox_data['fb_title']) : '').'" />
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-facebook-title" data-tag="%%post_title%%"><span class="dashicons dashicons-plus"></span> Post Title</button>
<button type="button" class="siteseo-facebook-title" data-tag="%%sitetitle%%"><span class="dashicons dashicons-plus"></span> Site Title</button>
<button type="button" class="siteseo-facebook-title" data-tag="%%sep%%"><span class="dashicons dashicons-plus"></span>Seperator</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="og" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_fb_desc_meta">'.esc_html__('Facebook description', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<textarea id="siteseo_social_fb_desc_meta" class="siteseo_social_fb_desc_meta" name="siteseo_social_fb_desc" rows="2" placeholder="'.(!empty($social_preview_desc) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_desc, true)) : '').'">'.(!empty($metabox_data['fb_desc']) ? esc_html($metabox_data['fb_desc']) : '').'</textarea>
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-facebook-desc" data-tag="%%post_excerpt%%"><span class="dashicons dashicons-plus"></span> Post Excerpt</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="og" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_fb_img_meta">'.esc_html__('Facebook Thumbnail', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<span style="color:red; font-weight:bold; display:none;"></span>
<input type="text" id="siteseo_social_fb_img_meta" name="siteseo_social_fb_img" class="siteseo_social_fb_img_meta" placeholder="'.esc_html__('Enter URL of the Image you want to be shown as the Facebook image', 'siteseo').'" value="'.(!empty($metabox_data['fb_img']) ? esc_url($metabox_data['fb_img']) : '').'"/>
<p class="description">'.esc_html__('Minimum size: 200x200px, ideal ratio 1.91:1, 8Mb max. (eg: 1640x856px or 3280x1712px for retina screens).', 'siteseo').'</p>
<input type="hidden" name="siteseo_social_fb_img_attachment_id" id="siteseo_social_fb_img_attachment_id" class="siteseo_social_fb_img_attachment_id" value="">
<input type="hidden" name="siteseo_social_fb_img_width" id="siteseo_social_fb_img_width" class="siteseo_social_fb_img_width" value="">
<input type="hidden" name="siteseo_social_fb_img_height" id="siteseo_social_fb_img_height" class="siteseo_social_fb_img_height" value="">
<button class="components-button is-secondary" id="siteseo_social_fb_img_upload">Upload Image</button>
</div>
</div>
</div>
<div class="siteseo-metabox-tab-x-settings siteseo-metabox-tab">
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label>'.esc_html__('Preview','siteseo').'</label>
</div>
<div>
<div class="siteseo-metabox-x-preview">
<div class="siteseo-metabox-x-image">
<img src="'.($x_image ? esc_url($x_image) : '').'" alt="X preview"/>
</div>
<div class="siteseo-metabox-x-data">
<div class="siteseo-metabox-x-title">'.(!empty($x_title_preview) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($x_title_preview, true)) : '').'</div>
</div>
</div>
<div class="siteseo-metabox-x-host">From '.(!empty($host_uri) ? esc_html($host_uri) : '').'</div>
</div>
</div>';
if(!empty($enable_x_card)){
echo'<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label>'.esc_html__('Use same as Facebook settings', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<label class="siteseo-x-toggle-switch">';
$checked = !empty($metabox_data['x_title'] || $metabox_data['x_desc'] || $metabox_data['x_img']) ? '' : "checked=checked";
echo'<input name="siteseo_social_use_og_settings" type="checkbox" '.esc_html($checked).'/>
<span class="siteseo-x-slider"></span>
</label>
</div>
</div>';
}
if(!empty($enable_x_card)){
echo'<div class="siteseo-x-settings" '.(!empty($use_og_settings) ? 'style="display:none;"' : '').'>';
}
echo'<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_twitter_title_meta">'.esc_html__('X Title', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<input type="text" id="siteseo_social_twitter_title_meta" class="siteseo_social_twitter_title_meta" name="siteseo_social_twitter_title" placeholder="'.(!empty($social_preview_title) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_title, true)) : '').'" value="'.(!empty($metabox_data['x_title']) ? esc_attr($metabox_data['x_title']) : '').'" />
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-x-title" data-tag="%%post_title%%"><span class="dashicons dashicons-plus"></span> Post Title</button>
<button type="button" class="siteseo-x-title" data-tag="%%sitetitle%%"><span class="dashicons dashicons-plus"></span> Site Title</button>
<button type="button" class="siteseo-x-title" data-tag="%%sep%%"><span class="dashicons dashicons-plus"></span>Seperator</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="twitter" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_twitter_desc_meta">'.esc_html__('X description', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<textarea id="siteseo_social_twitter_desc_meta" class="siteseo_social_twitter_desc_meta" name="siteseo_social_twitter_desc" rows="2" placeholder="'.(!empty($social_preview_desc) ? esc_html(\SiteSEO\TitlesMetas::replace_variables($social_preview_desc, true)) : '').'">'.(!empty($metabox_data['x_desc']) ? esc_attr($metabox_data['x_desc']) : '').'</textarea>
<div class="siteseo-metabox-tags">
<button type="button" class="siteseo-x-desc" data-tag="%%post_excerpt%%"><span class="dashicons dashicons-plus"></span> Post Excerpt</button>'.wp_kses(siteseo_suggestion_button_metabox(), $allowed_suggestion_tags);
if(defined('SITESEO_PRO_VERSION') && !defined('SITEPAD')){
echo'<span class="siteseo-ai-modal-open" data-context="twitter" title="SiteSEO AI Assistant"><img src="'.esc_url($ai_logo).'" alt="AI Assistant Icon">'.'<label class="siteseo-ai-modal-label">'.esc_html__('Ask AI', 'siteseo').'</label></span>';
}
echo'</div>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_twitter_img_meta">'.esc_html__('X Thumbnail', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<span style="color:red; font-weight:bold; display:none;"></span>
<input type="text" id="siteseo_social_twitter_img_meta" class="siteseo_social_twitter_img_meta" name="siteseo_social_twitter_img" placeholder="'.esc_html__('Enter URL of the Image you want to be shown as the X image', 'siteseo').'" value="'.(!empty($metabox_data['x_img']) ? esc_attr($metabox_data['x_img']) : '').'" />
<p class="description">'.esc_html__('Minimum size: 144x144px (300x157px with large card enabled), ideal ratio 1:1 (2:1 with large card), 5Mb max.', 'siteseo').'</p>
<input type="hidden" name="siteseo_social_twitter_img_attachment_id" id="siteseo_social_twitter_img_attachment_id" class="siteseo_social_twitter_img_attachment_id" value="">
<input type="hidden" name="siteseo_social_twitter_img_width" id="siteseo_social_twitter_img_width" class="siteseo_social_twitter_img_width" value="">
<input type="hidden" name="siteseo_social_twitter_img_height" id="siteseo_social_twitter_img_height" class="siteseo_social_twitter_img_height" value="">
<button class="components-button is-secondary" id="siteseo_social_twitter_img_upload">Upload Image</button>
</div>
</div>';
if(!empty($enable_x_card)){
echo'</div>';
}
echo'</div>
</div>';
if(!empty($pro_settings['enable_structured_data']) && !empty($pro_settings['toggle_state_stru_data']) && !empty($show_content_analysis)){
echo'<div class="siteseo-sidebar-tabs"><span>'.esc_html__('Structured Data Types', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-structured-data-types siteseo-metabox-tab">';
// Pro fearure
do_action('siteseo_display_structured_data_types');
echo'</div>';
}
// video sitemap
if(!empty($pro_settings['toggle_state_video_sitemap']) && !empty($pro_settings['enable_video_sitemap']) && !empty($show_content_analysis)){
echo'<div class="siteseo-sidebar-tabs"><span>'.esc_html__('Video Sitemap', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-video-sitemap siteseo-metabox-tab">';
do_action('siteseo_display_video_sitemap');
echo'</div>';
}
// gooogle news exclude
if(!empty($pro_settings['toggle_state_google_news']) && !empty($pro_settings['google_news']) && !empty($show_content_analysis)){
echo'<div class="siteseo-sidebar-tabs"><span>'.esc_html__('Google News', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-google-news siteseo-metabox-tab">';
do_action('siteseo_display_google_news');
echo'</div>';
}
echo'<div class="siteseo-sidebar-tabs"><span>';
if(!empty($metabox_data['robots_index'])){
echo'<span class="dashicons dashicons-hidden siteseo-noindex-warning"></span>';
}
echo esc_html__('Advanced', 'siteseo').'</span><span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span></span></div>
<div class="siteseo-metabox-tab-advanced-settings siteseo-metabox-tab">
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_social_twitter_img_meta">'.esc_html__('Meta Robots Settings', 'siteseo').'</label>
<p class="description">'.
/* translators: %s represents the degree of severity */
wp_kses_post(sprintf(__('You cannot uncheck a checkbox? This is normal, and it\'s most likely defined in the <a href="%s">global settings of the plugin.</a>', 'siteseo'), esc_url(admin_url('admin.php?page=siteseo-titles#tab=tab_siteseo_titles_single')))).'</p>
</div>
<div class="siteseo-metabox-input-wrap">';
$robots_options = [
'siteseo_robots_index_meta' => [
'desc' => __('Do not display this page in search engine results / Sitemaps', 'siteseo'),
'short' => 'noindex',
'name' => 'siteseo_robots_index',
'checked' => $metabox_data['robots_index'],
'disabled' => $metabox_data['disabled_robots']['robots_index']
],
'siteseo_robots_follow_meta' => [
'desc' => __('Do not follow links for this page', 'siteseo'),
'short' => 'nofollow',
'name' => 'siteseo_robots_follow',
'checked' => $metabox_data['robots_follow'],
'disabled' => $metabox_data['disabled_robots']['robots_follow']
],
'siteseo_robots_imageindex_meta' => [
'desc' => __('Do not index images for this page', 'siteseo'),
'short' => 'noimageindex',
'name' => 'siteseo_robots_imageindex',
'checked' => $metabox_data['robots_imageindex'],
'disabled' => $metabox_data['disabled_robots']['imageindex']
],
'siteseo_robots_archive_meta' => [
'desc' => __('Do not display a "Cached" link in the Google search results', 'siteseo'),
'short' => 'noarchive',
'name' => 'siteseo_robots_archive',
'checked' => $metabox_data['robots_archive'],
'disabled' => $metabox_data['disabled_robots']['archive']
],
'siteseo_robots_snippet_meta' => [
'desc' => __('Do not display a description in search results for this page', 'siteseo'),
'short' => 'nosnippet',
'name' => 'siteseo_robots_snippet',
'checked' => $metabox_data['robots_snippet'],
'disabled' => $metabox_data['disabled_robots']['snippet']
]
];
foreach($robots_options as $robots_id => $robots_option){
$checked = '';
if(!empty($robots_option['checked'])){
$checked = 'checked';
}
$disabled = '';
if(!empty($robots_option['disabled'])){
$disabled = 'disabled';
$robots_option['name'] = '';
}
echo'<label for="'.esc_attr($robots_id).'" style="display:block; margin-bottom:5px;">
<input type="checkbox" value="yes" id="'.esc_attr($robots_id).'" class="siteseo-metabox-robots-options" name="'.esc_attr($robots_option['name']).'" '.esc_attr($checked).' '.esc_attr($disabled).'/>
'.esc_html($robots_option['desc']).' ('.esc_html($robots_option['short']).')
</label>';
}
echo'</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_robots_canonical_meta">'.esc_html__('Canonical URL', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<input id="siteseo_robots_canonical_meta" type="text" name="siteseo_robots_canonical" placeholder="'.esc_url(get_the_permalink()).'" value="'.(!empty($metabox_data['robots_canonical']) ? esc_html($metabox_data['robots_canonical']) : '').'">
</div>
</div>';
if(!empty($pagenow) && !empty($typenow) && ($pagenow == 'post.php' || $pagenow == 'post-new.php') && ($typenow == 'post' || $typenow == 'product')){
$categories = (object)[];
if($typenow == 'product'){
$categories = get_the_terms($post, 'product_cat');
} else{
$categories = get_categories();
}
if(!empty($categories) && !is_wp_error($categories)){
echo'<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_robots_canonical_meta">'.esc_html__('Select a primary category', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<select id="siteseo_robots_primary_cat" name="siteseo_robots_primary_cat">';
foreach($categories as $category){
$selected = '';
if(!empty($metabox_data['robots_primary_cat']) && $metabox_data['robots_primary_cat'] == $category->term_id){
$selected = 'selected';
}
echo'<option value="'.esc_attr($category->term_id).'" '.esc_attr($selected).'>'.esc_html($category->name).'</option>';
}
echo'</select>
</div>
</div>';
}
}
echo'</div>
<div class="siteseo-sidebar-tabs"><span>'.esc_html__('Redirects', 'siteseo').'</span>
<span class="siteseo-sidebar-tabs-arrow"><span class="dashicons dashicons-arrow-down-alt2"></span>
</span></div>
<div class="siteseo-metabox-tab-redirect siteseo-metabox-tab">
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_redirections_enabled_meta">'.esc_html__('Enable redirection', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<input id="siteseo_redirections_enabled_meta" type="checkbox" name="siteseo_redirections_enabled" value="1" '.(!empty($metabox_data['redirections_enabled']) ? 'checked' : '').'>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_redirections_enabled_meta">'.esc_html__('Login status', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<select name="siteseo_redirections_logged_status" id="siteseo_redirections_logged_status">
<option value="both" '.(!empty($metabox_data['redirections_logged_status']) && $metabox_data['redirections_logged_status'] == 'both' ? 'selected' : '').'>'.esc_html__('All', 'siteseo').'</option>
<option value="only_logged_in" '.(!empty($metabox_data['redirections_logged_status']) && $metabox_data['redirections_logged_status'] == 'only_logged_in' ? 'selected' : '').'>'.esc_html__('Only when logged In', 'siteseo').'</option>
<option value="only_not_logged_in" '.(!empty($metabox_data['redirections_logged_status']) && $metabox_data['redirections_logged_status'] == 'only_not_logged_in' ? 'selected' : '').'>'.esc_html__('Only when not logged in', 'siteseo').'</option>
</select>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_redirections_type">'.esc_html__('Redirection Type', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<select name="siteseo_redirections_type" id="siteseo_redirections_type">
<option value="301" '.(!empty($metabox_data['redirections_type']) && $metabox_data['redirections_type'] == '301' ? 'selected' : '').'>'.esc_html__('301 Moved Permanently', 'siteseo').'</option>
<option value="302" '.(!empty($metabox_data['redirections_type']) && $metabox_data['redirections_type'] == '302' ? 'selected' : '').'>'.esc_html__('302 Found / Moved Temporarily', 'siteseo').'</option>
<option value="307" '.(!empty($metabox_data['redirections_type']) && $metabox_data['redirections_type'] == '307' ? 'selected' : '').'>'.esc_html__('307 Moved Temporarily', 'siteseo').'</option>';
if($typenow === 'siteseo_404'){
echo'<option value="410" '.(!empty($metabox_data['redirections_type']) && $metabox_data['redirections_type'] == '410' ? 'selected' : '').'>'.esc_html__('410 Gone', 'siteseo').'</option>
<option value="451" '.(!empty($metabox_data['redirections_type']) && $metabox_data['redirections_type'] == '451' ? 'selected' : '').'>'. esc_html__('451 Unavailable For Legal Reasons', 'siteseo').'</option>';
}
echo'</select>
</div>
</div>
<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_redirections_value_meta">'.esc_html__('Redirection URL', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<input id="siteseo_redirections_value_meta" type="text" name="siteseo_redirections_value" value="'.(!empty($metabox_data['redirections_value']) ? esc_attr($metabox_data['redirections_value']): '').'">
</div>
<input type="hidden" id="analysis_tabs" name="analysis_tabs" value="'.esc_html(wp_json_encode(array_keys($siteseo_metabox_tabs))).'">
</div>';
// Note
if($typenow === 'siteseo_404'){
echo'<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_redirections_param">'.esc_html__('Query parameters', 'siteseo').'</label>
</div>
<div class="siteseo-metabox-input-wrap">
<select name="siteseo_redirections_param" id="siteseo_redirections_param">
<option value="exact_match" '.(!empty($metabox_data['redirections_param']) && $metabox_data['redirections_param'] == 'exact_match' ? 'selected' : '').'>'.esc_html__('Exactly parameters with exact match', 'siteseo').'</option>
<option value="without_param" '.(!empty($metabox_data['redirections_param']) && $metabox_data['redirections_param'] == 'without_param' ? 'selected' : '').'>'.esc_html__('Exclude all parameters', 'siteseo').'</option>
<option value="with_ignored_param" '.(!empty($metabox_data['redirections_param']) && $metabox_data['redirections_param'] == 'with_ignored_param' ? 'selected' : '').'>'.esc_html__('Exclude all parameters and pass them to the redirection', 'siteseo').'</option>
</select>
</div>
</div>';
}
echo'</div>
</div>';
}
static function content_analysis($post){
wp_nonce_field('siteseo_ca_nonce', 'siteseo_content_analysis_nonce');
$siteseo_real_preview = [
'siteseo_nonce' => wp_create_nonce('siteseo_real_preview_nonce'),
'siteseo_real_preview' => admin_url('admin-ajax.php'),
'i18n' => ['progress' => __('Analysis in progress...', 'siteseo')],
'ajax_url' => admin_url('admin-ajax.php'),
'get_preview_meta_title' => wp_create_nonce('get_preview_meta_title'),
'realtime_nonce' => wp_create_nonce('siteseo_realtime_nonce'),
];
$metabox_data = [];
$metabox_data['analysis_target_kw'] = get_post_meta($post->ID, '_siteseo_analysis_target_kw', true);
$metabox_data['analysis_data'] = get_post_meta($post->ID, '_siteseo_analysis_data', true);
$metabox_data['readibility_data'] = get_post_meta($post->ID, '_siteseo_readibility_data', true);
$metabox_data['meta_title'] = get_post_meta($post->ID, '_siteseo_titles_title', true);
$metabox_data['meta_desc'] = get_post_meta($post->ID, '_siteseo_titles_desc', true);
$title_options = get_option('siteseo_titles_option_name', []);
if(self::titles_single_cpt_noindex_option() || !empty($title_options['titles_noindex']) || true === post_password_required($post->ID)){
$metabox_data['robots_index'] = 'yes';
} else {
$metabox_data['robots_index'] = get_post_meta($post->ID, '_siteseo_robots_index', true);
}
if(post_password_required($post->ID) === true || !empty($title_options['titles_noindex']) || self::titles_single_cpt_noindex_option()){
$metabox_data['robots_index'] = 'yes';
} else{
$metabox_data['robots_index'] = get_post_meta($post->ID, '_siteseo_robots_index', true);
}
if(!empty($title_options['titles_nofollow']) || self::titles_single_cpt_nofollow_option()){
$metabox_data['robots_follow'] = 'yes';
} else{
$metabox_data['robots_follow'] = get_post_meta($post->ID, '_siteseo_robots_follow', true);
}
if(!empty($title_options['titles_noarchive'])){
$metabox_data['robots_archive'] = 'yes';
} else{
$metabox_data['robots_archive'] = get_post_meta($post->ID, '_siteseo_robots_archive', true);
}
if(!empty($title_options['titles_nosnippet'])){
$metabox_data['robots_snippet'] = 'yes';
} else{
$metabox_data['robots_snippet'] = get_post_meta($post->ID, '_siteseo_robots_snippet', true);
}
if(!empty($title_options['titles_noimageindex'])){
$metabox_data['robots_imageindex'] = 'yes';
} else{
$metabox_data['robots_imageindex'] = get_post_meta($post->ID, '_siteseo_robots_imageindex', true);
}
$metabox_data['post_id'] = $post->ID;
$metabox_data['readibility_data'] = get_post_meta($post->ID, '_siteseo_readibility_data', true);
self::siteseo_content_analysis_tab($metabox_data);
}
static function titles_single_cpt_nofollow_option(){
$siteseo_get_current_cpt = get_post_type();
$options = get_option('siteseo_titles_option_name');
if(!empty($options) && isset($options['titles_single_titles'][$siteseo_get_current_cpt]['nofollow'])){
return $options['titles_single_titles'][$siteseo_get_current_cpt]['nofollow'];
}
}
static function btn_secondary_classes() {
//Classic Editor compatibility
global $pagenow;
$current_screen = null;
if(function_exists('get_current_screen')){
$current_screen = get_current_screen();
}
if(!empty($current_screen) && method_exists($current_screen, 'is_block_editor') && true === $current_screen->is_block_editor()){
$btn_classes_secondary = 'components-button is-secondary';
} elseif(isset($pagenow) && ($pagenow === 'term.php' || $pagenow === 'post.php' || $pagenow === 'post-new.php')){
$btn_classes_secondary = 'button button-secondary';
} else{
$btn_classes_secondary = 'btn btnSecondary';
}
return $btn_classes_secondary;
}
static function siteseo_content_analysis_tab(&$metabox_data){
global $post;
echo '<div class="siteseo-metabox-option-wrap">
<div class="siteseo-metabox-label-wrap">
<label for="siteseo_titles_title_meta">' . esc_html__('Focus Keywords', 'siteseo') . '</label>
</div>
<div class="siteseo-metabox-input-wrap">
<div id="siteseo_tags_wrapper" style="display: flex; flex-wrap: wrap; gap: 5px; padding: 5px; border: 1px solid #ccc; border-radius: 5px;">';
if(!empty($metabox_data['analysis_target_kw'])){
$tags_arr = explode(',', $metabox_data['analysis_target_kw']);
if(count($tags_arr) > 0){
foreach($tags_arr as $tag_name){
echo '<span class="siteseo-tag">'.esc_html($tag_name).'<span class="siteseo-remove-tag">×</span></span>';
}
}
}
echo '<input id="siteseo_analysis_target_kw_meta" class="siteseo_analysis_target_kw_meta" type="text" placeholder="' . esc_html__('Enter your target keywords', 'siteseo') . '" style="border: none; outline: none; flex: 1; min-width: 150px;" />
<input type="hidden" id="siteseo_tags_hidden" name="siteseo_analysis_target_kw" value="' . (!empty($metabox_data['analysis_target_kw']) ? esc_attr($metabox_data['analysis_target_kw']) : '') . '" />
</div>
<p class="description">Press <kbd>Enter</kbd> key on your keyboard to add keyword</p>
<button id="siteseo_refresh_seo_analysis" type="button" style="margin-top:10px;" class="'.esc_attr(self::btn_secondary_classes()).'" data_id="'.esc_attr(get_the_ID()).'" data_post_type="'.esc_attr(get_current_screen()->post_type).'"> '.esc_html__('Refresh analysis', 'siteseo').'</button>
<p class="description">'.esc_html__('Refresh analysis after saving the post to improve the accuracy of the analysis', 'siteseo').'</p>
</div>
</div>
<div id="siteseo-metabox-content-analysis">
<div id="siteseo-metabox-tabs-container">
<div class="siteseo-metabox-subtabs">
<div class="siteseo-metabox-tab-label siteseo-metabox-tab-label-active" data-tab="siteseo-metabox-seo-analysis-tab">'. esc_html__('SEO Analysis', 'siteseo').'</div>
<div class="siteseo-metabox-tab-label" data-tab="siteseo-metabox-readibility-analysis-tab">'.esc_html__('Content Readability', 'siteseo').'</div>
</div>
<div id="siteseo-metabox-tab-content">
<div class="siteseo-metabox-seo-analysis-tab siteseo-metabox-tab" style="display:block;">';
$post_id = isset($_POST['post_id']) ? intval($_POST['post_id']) : 0;
$post = get_post($post_id);
Analysis::display_seo_analysis($post);
echo'</div>
<div class="siteseo-metabox-readibility-analysis-tab siteseo-metabox-tab">
<p class="description">' .
esc_html__('This section works as a guide to help you write, better content for your user, this do not have a direct affect on SEO, but it will help you write better content for your users which will help user stay on your site longer, or will improve the Click Through rate.
Which will signal search engines about the userfulness and likeleyness of your content by your user which indirectly improve SEO of the page.', 'siteseo') .
'</p>';
Analysis::display_content_readibility($metabox_data);
echo'</div>
</div>
</div>
</div>';
}
static function titles_single_cpt_noindex_option(){
$siteseo_get_current_cpt = get_post_type();
$options = get_option('siteseo_titles_option_name');
if(!empty($options) && isset($options['titles_single_titles'][$siteseo_get_current_cpt]['noindex'])){
return $options['titles_single_titles'][$siteseo_get_current_cpt]['noindex'];
}
}
static function save_ca_metabox($post_id, $post){
if(!isset($_POST['siteseo_content_analysis_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['siteseo_content_analysis_nonce'])), 'siteseo_ca_nonce')){
return $post_id;
}
// Post type object
$post_type = get_post_type_object($post->post_type);
//Check permission
if(!current_user_can($post_type->cap->edit_post, $post_id) || !siteseo_user_can_metabox()){
return $post_id;
}
if('attachment' !== get_post_type($post_id)){
if(isset($_POST['siteseo_analysis_target_kw'])){
update_post_meta($post_id, '_siteseo_analysis_target_kw', self::clean_post('siteseo_analysis_target_kw'));
} else{
delete_post_meta($post_id, '_siteseo_analysis_target_kw');
}
}
}
static function save_metabox($post_id, $post){
global $siteseo;
// Security Check
if(!isset($_POST['siteseo_metabox_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['siteseo_metabox_nonce'])), 'siteseo_metabox_nonce')){
return $post_id;
}
//Post type object
$post_type = get_post_type_object($post->post_type);
//Check permission
if(!current_user_can($post_type->cap->edit_post, $post_id) || !siteseo_user_can_metabox()){
return $post_id;
}
if('attachment' !== get_post_type($post_id)){
$analysis_tabs = [];
$analysis_tabs = json_decode(self::clean_post('analysis_tabs'), true);
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('content-analysis', $analysis_tabs)){
if(!empty($_POST['siteseo_analysis_target_kw'])){
update_post_meta($post_id, '_siteseo_analysis_target_kw', self::clean_post('siteseo_analysis_target_kw'));
} else{
delete_post_meta($post_id, '_siteseo_analysis_target_kw');
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('title-settings', $analysis_tabs)){
if(!empty($_POST['siteseo_titles_title'])){
update_post_meta($post_id, '_siteseo_titles_title', self::clean_post('siteseo_titles_title'));
} else{
delete_post_meta($post_id, '_siteseo_titles_title');
}
if(!empty($_POST['siteseo_titles_desc'])){
update_post_meta($post_id, '_siteseo_titles_desc', self::clean_post('siteseo_titles_desc'));
} else{
delete_post_meta($post_id, '_siteseo_titles_desc');
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('advanced-settings', $analysis_tabs)){
if(isset($_POST['siteseo_robots_index'])){
update_post_meta($post_id, '_siteseo_robots_index', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_robots_index');
}
if(isset($_POST['siteseo_robots_follow'])){
update_post_meta($post_id, '_siteseo_robots_follow', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_robots_follow');
}
if(isset($_POST['siteseo_robots_imageindex'])){
update_post_meta($post_id, '_siteseo_robots_imageindex', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_robots_imageindex');
}
if(isset($_POST['siteseo_robots_archive'])){
update_post_meta($post_id, '_siteseo_robots_archive', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_robots_archive');
}
if(isset($_POST['siteseo_robots_snippet'])){
update_post_meta($post_id, '_siteseo_robots_snippet', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_robots_snippet');
}
if(!empty($_POST['siteseo_robots_canonical'])){
update_post_meta($post_id, '_siteseo_robots_canonical', self::clean_post('siteseo_robots_canonical'));
} else{
delete_post_meta($post_id, '_siteseo_robots_canonical');
}
if(!empty($_POST['siteseo_robots_primary_cat'])){
update_post_meta($post_id, '_siteseo_robots_primary_cat', self::clean_post('siteseo_robots_primary_cat'));
} else{
delete_post_meta($post_id, '_siteseo_robots_primary_cat');
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('social-settings', $analysis_tabs)){
//Facebook
if(!empty($_POST['siteseo_social_fb_title'])){
update_post_meta($post_id, '_siteseo_social_fb_title', self::clean_post('siteseo_social_fb_title'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_title');
}
if(!empty($_POST['siteseo_social_fb_desc'])){
update_post_meta($post_id, '_siteseo_social_fb_desc', self::clean_post('siteseo_social_fb_desc'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_desc');
}
if(!empty($_POST['siteseo_social_fb_img'])){
update_post_meta($post_id, '_siteseo_social_fb_img', self::clean_post('siteseo_social_fb_img'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_img');
}
if(!empty($_POST['siteseo_social_fb_img_attachment_id']) && !empty($_POST['siteseo_social_fb_img'])){
update_post_meta($post_id, '_siteseo_social_fb_img_attachment_id', self::clean_post('siteseo_social_fb_img_attachment_id'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_img_attachment_id');
}
if(!empty($_POST['siteseo_social_fb_img_width']) && !empty($_POST['siteseo_social_fb_img'])){
update_post_meta($post_id, '_siteseo_social_fb_img_width', self::clean_post('siteseo_social_fb_img_width'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_img_width');
}
if(!empty($_POST['siteseo_social_fb_img_height']) && !empty($_POST['siteseo_social_fb_img'])){
update_post_meta($post_id, '_siteseo_social_fb_img_height', self::clean_post('siteseo_social_fb_img_height'));
} else{
delete_post_meta($post_id, '_siteseo_social_fb_img_height');
}
//Twitter
if(!empty($_POST['siteseo_social_twitter_title'])){
update_post_meta($post_id, '_siteseo_social_twitter_title', self::clean_post('siteseo_social_twitter_title'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_title');
}
if(!empty($_POST['siteseo_social_twitter_desc'])){
update_post_meta($post_id, '_siteseo_social_twitter_desc', self::clean_post('siteseo_social_twitter_desc'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_desc');
}
if(!empty($_POST['siteseo_social_twitter_img'])){
update_post_meta($post_id, '_siteseo_social_twitter_img', self::clean_post('siteseo_social_twitter_img'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_img');
}
if(!empty($_POST['siteseo_social_twitter_img_attachment_id']) && !empty($_POST['siteseo_social_twitter_img'])){
update_post_meta($post_id, '_siteseo_social_twitter_img_attachment_id', self::clean_post('siteseo_social_twitter_img_attachment_id'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_img_attachment_id');
}
if(!empty($_POST['siteseo_social_twitter_img_width']) && !empty($_POST['siteseo_social_twitter_img'])){
update_post_meta($post_id, '_siteseo_social_twitter_img_width', self::clean_post('siteseo_social_twitter_img_width'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_img_width');
}
if(!empty($_POST['siteseo_social_twitter_img_height']) && !empty($_POST['siteseo_social_twitter_img'])){
update_post_meta($post_id, '_siteseo_social_twitter_img_height', self::clean_post('siteseo_social_twitter_img_height'));
} else{
delete_post_meta($post_id, '_siteseo_social_twitter_img_height');
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('redirect', $analysis_tabs)){
if(isset($_POST['siteseo_redirections_type'])){
update_post_meta($post_id, '_siteseo_redirections_type', self::clean_post('siteseo_redirections_type'));
}
if(!empty($_POST['siteseo_redirections_value'])){
update_post_meta($post_id, '_siteseo_redirections_value', self::clean_post('siteseo_redirections_value'));
} else{
delete_post_meta($post_id, '_siteseo_redirections_value');
}
if(isset($_POST['siteseo_redirections_param'])){
update_post_meta($post_id, '_siteseo_redirections_param', self::clean_post('siteseo_redirections_param'));
}
if(isset($_POST['siteseo_redirections_enabled'])){
update_post_meta($post_id, '_siteseo_redirections_enabled', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_redirections_enabled', '');
}
if(isset($_POST['siteseo_redirections_enabled_regex'])){
update_post_meta($post_id, '_siteseo_redirections_enabled_regex', 'yes');
} else{
delete_post_meta($post_id, '_siteseo_redirections_enabled_regex');
}
if(isset($_POST['siteseo_redirections_logged_status'])){
update_post_meta($post_id, '_siteseo_redirections_logged_status', self::clean_post('siteseo_redirections_logged_status'));
} else{
delete_post_meta($post_id, '_siteseo_redirections_logged_status');
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('structured-data-types', $analysis_tabs)){
if(class_exists('\SiteSEOPro\StructuredData') && method_exists('\SiteSEOPro\StructuredData', 'save_metabox')){
\SiteSEOPro\StructuredData::save_metabox($post_id, $post);
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('video-sitemap', $analysis_tabs)){
if(class_exists('\SiteSEOPro\VideoSitemap') && method_exists('\SiteSEOPro\VideoSitemap', 'save_video_sitemap')){
\SiteSEOPro\VideoSitemap::save_video_sitemap($post_id, $post);
}
}
if(!empty($analysis_tabs) && is_array($analysis_tabs) && in_array('google-news', $analysis_tabs)){
if(class_exists('\SiteSEOPro\GoogleNews') && method_exists('\SiteSEOPro\GoogleNews', 'save_google_news')){
\SiteSEOPro\GoogleNews::save_google_news($post_id, $post);
}
}
}
}
static function clean_post($name){
return self::clean_post_req($name);
}
static function clean_get($name){
return self::clean_post_req($name);
}
static function clean_post_req($name){
if(empty($name)){
return '';
}
if(!isset($_REQUEST[$name])){
return '';
}
if(is_array($_REQUEST[$name]) || is_object($_REQUEST[$name])){
return map_deep(wp_unslash($_REQUEST[$name]), 'sanitize_text_field');
}
return sanitize_text_field(wp_unslash($_REQUEST[$name]));
}
static function universal(){
global $siteseo, $pagenow, $post;
$post_id = !empty($_REQUEST['post']) ? (int) sanitize_text_field(wp_unslash($_REQUEST['post'])) : 0;
if(empty($post_id)){
return;
}
if(!current_user_can('edit_post', $post_id)){
wp_die(esc_html__('You do not have access to edit this post', 'siteseo'));
}
$tmp_post = $post;
$post = get_post($post_id);
$tmp_pagenow = $pagenow;
$pagenow = 'post.php';
if(empty($post)){
$post = $tmp_post;
return;
}
set_current_screen($post->post_type);
echo '<style>body{height: 100vh;} #wpcontent,#wpbody-content,html.wp-toolbar{padding:0;} .postbox .handle-order-higher, .postbox .handle-order-lower,#minor-publishing-actions,.site-menu-header{display:none !important;} #adminmenumain, #wpfooter, #wpadminbar, #wpwrap > :first-child, #wpwrap > :nth-child(2) .lnav-col{display:none;} #wpcontent{margin:auto;} #wpbody-content{position:relative;} .siteseo-metabox-tab{background-color:white;} .siteseo-meta-submit-container{position:fixed;bottom: 20px;right : 20px;} #siteseo_cpt form {position:relative;}.siteseo-btn{display: inline-flex;padding: 0.5rem 1rem;gap: 0.5rem;justify-content: center;align-items: center;border-radius: 0.375rem;font-size: 0.875rem;line-height: 1.25rem;font-weight: 500;white-space: nowrap;cursor:pointer;box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);border:none;text-decoration:none; text-align:center;}.siteseo-btn.primary{background-color:#141b38;color:white;} #wpwrap > :nth-child(2) > div:nth-child(2){max-width:100%}
.siteseo-spinner{display:none;border-radius:50%;animation: siteseo-spinner 1s linear infinite;height: 0.9375rem;width: 0.9375rem;border: 2px solid #dddcdc80;border-left-color: #e3e3e3;} .siteseo-spinner-active{display:inline-block;} @keyframes siteseo-spinner{ 0% { transform: rotate(0deg);} 100% {transform: rotate(360deg);}} .components-button{align-items: center; -webkit-appearance: none; background: none; border: 0; border-radius: 2px; box-sizing: border-box; color:#1e1e1e; cursor: pointer;display: inline-flex; font-family: inherit; font-size: 13px; font-weight: 400; height: 36px; margin: 0; padding: 6px 12px; text-decoration: none; transition: box-shadow .1s linear;}.components-button.is-secondary {background: #0000; box-shadow: inset 0 0 0 1px #3858e9; color:#3858e9; outline: 1px solid #0000; white-space: nowrap;}.siteseo-sidebar-tabs{display:none;} .notice, .update-nag{ display: none !important;}</style>
<div id="siteseo_cpt"><form id="siteseo-universal-post" action="post.php" method="post">
<input type="hidden" name="post_id" value="'.esc_attr($post_id).'"/>';
wp_nonce_field('siteseo_universal_nonce', 'security');
self::render_metabox();
echo '<div class="siteseo-meta-submit-container">
<button type="submit" class="siteseo-btn primary">'.esc_html__('Save Changes', 'siteseo').'<span class="siteseo-spinner"></span></button>
</div></form></div>
<script>
jQuery(document).ready(function(){
jQuery("#siteseo-universal-post").on("submit", function(event){
event.preventDefault();
let jEle = jQuery(event.target),
spinner = jEle.find(".siteseo-spinner"),
formData = {};
jQuery(this).serializeArray().forEach(field => {
formData[field.name] = field.value;
});
formData["action"] = "siteseo_save_universal_metabox";
spinner.addClass("siteseo-spinner-active");
jQuery.ajax({
method : "POST",
url : "'.esc_url(admin_url('admin-ajax.php')).'",
data : formData,
success : function(res){
//console.log(res);
}
}).always(function(){
spinner.removeClass("siteseo-spinner-active");
})
});
});
</script>';
$post = $tmp_post;
$pagenow = $tmp_pagenow;
global $wp_version;
if(!empty($wp_version) && version_compare($wp_version, '6.4', '>')){
remove_action('wp_footer', 'the_block_template_skip_link');
}
wp_footer();
exit;
}
static function render_term_metabox($term, $taxonomy_name = ''){
$metabox_data = self::metabox_term_data($term);
self::metabox_form_html($metabox_data);
}
static function save_meta_terms($term_id, $post_id = 0){
// Security Check
if(!isset($_POST['siteseo_metabox_nonce']) || !wp_verify_nonce(self::clean_post('siteseo_metabox_nonce'), 'siteseo_metabox_nonce') ){
return $term_id;
}
// Getting taxonomy
$term = get_term($term_id);
$taxonomy = get_taxonomy($term->taxonomy);
// Is this user allowed to make these changes
if(!current_user_can($taxonomy->cap->edit_terms, $term_id)) {
return $term_id;
}
$analysis_tabs = [];
$analysis_tabs = json_decode(self::clean_post('analysis_tabs'), true);
if(empty($analysis_tabs) || !is_array($analysis_tabs)){
return $term_id;
}
$tabs = [
'title-settings' => [
'siteseo_titles_title' => '_siteseo_titles_title',
'siteseo_titles_desc' => '_siteseo_titles_desc',
],
'advanced-settings' => [
'siteseo_robots_index' => '_siteseo_robots_index',
'siteseo_robots_follow' => '_siteseo_robots_follow',
'siteseo_robots_imageindex'=> '_siteseo_robots_imageindex',
'siteseo_robots_archive' => '_siteseo_robots_archive',
'siteseo_robots_snippet' => '_siteseo_robots_snippet',
'siteseo_robots_canonical' => '_siteseo_robots_canonical',
],
'social-settings' => [
'siteseo_social_fb_title' => '_siteseo_social_fb_title',
'siteseo_social_fb_desc' => '_siteseo_social_fb_desc',
'siteseo_social_fb_img' => '_siteseo_social_fb_img',
'siteseo_social_fb_img_attachment_id' => '_siteseo_social_fb_img_attachment_id',
'siteseo_social_fb_img_width' => '_siteseo_social_fb_img_width',
'siteseo_social_fb_img_height' => '_siteseo_social_fb_img_height',
'siteseo_social_twitter_title' => '_siteseo_social_twitter_title',
'siteseo_social_twitter_desc' => '_siteseo_social_twitter_desc',
'siteseo_social_twitter_img' => '_siteseo_social_twitter_img',
],
'redirect' => [
'siteseo_redirections_type' => '_siteseo_redirections_type',
'siteseo_redirections_logged_status' => '_siteseo_redirections_logged_status',
'siteseo_redirections_value' => '_siteseo_redirections_value',
'siteseo_redirections_enabled' => '_siteseo_redirections_enabled',
]
];
// Save the key for all the options which are checkboxes
$is_checkboxes = [
'siteseo_robots_index',
'siteseo_robots_follow',
'siteseo_robots_imageindex',
'siteseo_robots_archive',
'siteseo_robots_snippet',
'siteseo_redirections_enabled',
];
foreach($tabs as $tab => $fields){
if(!in_array($tab, $analysis_tabs)){
continue;
}
foreach($fields as $post_key => $meta_key){
if(!empty($_POST[$post_key])){
$value = in_array($post_key, $is_checkboxes) ? 'yes' : self::clean_post($post_key);
update_term_meta($term_id, $meta_key, $value);
} else {
delete_term_meta($term_id, $meta_key);
}
}
}
return $term_id;
}
}
import.php 0000644 00000113655 15152641524 0006607 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Import{
static function rank_math(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$robots = get_post_meta($post->ID, 'rank_math_robots', true);
$robots_array = is_array($robots) ? $robots : [];
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_title', true),'rank_math'),
'_siteseo_titles_desc' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_description', true),'rank_math'),
'_siteseo_social_fb_title' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_facebook_title', true),'rank_math'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_facebook_description', true),'rank_math'),
'_siteseo_social_fb_img' => get_post_meta($post->ID, 'rank_math_facebook_image', true),
'_siteseo_social_twitter_title' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_twitter_title', true),'rank_math'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars(get_post_meta($post->ID, 'rank_math_twitter_description', true),'rank_math'),
'_siteseo_social_twitter_img' => get_post_meta($post->ID, 'rank_math_twitter_image', true),
'_siteseo_robots_index' => in_array('noindex', $robots_array) ? '1' : '',
'_siteseo_robots_follow' => in_array('nofollow', $robots_array) ? '1' : '',
'_siteseo_robots_imageindex' => in_array('noimageindex', $robots_array) ? '1' : '',
'_siteseo_robots_archive' => in_array('noarchive', $robots_array) ? '1' : '',
'_siteseo_robots_snippet' => in_array('nosnippet', $robots_array) ? '1' : '',
'_siteseo_robots_canonical' => get_post_meta($post->ID, 'rank_math_canonical_url', true),
'_siteseo_analysis_target_kw' => get_post_meta($post->ID, 'rank_math_focus_keyword', true),
'_siteseo_robots_primary_cat' => get_post_meta($post->ID, 'rank_math_primary_category', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
foreach($terms as $term){
$term_robots = get_term_meta($term->term_id, 'rank_math_robots', true);
$term_robots_array = is_array($term_robots) ? $term_robots : [];
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_title', true),'rank_math'),
'_siteseo_titles_desc' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_description', true),'rank_math'),
'_siteseo_social_fb_title' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_facebook_title', true),'rank_math'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_facebook_description', true),'rank_math'),
'_siteseo_social_fb_img' => get_term_meta($term->term_id, 'rank_math_facebook_image', true),
'_siteseo_social_twitter_title' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_twitter_title', true),'rank_math'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars(get_term_meta($term->term_id, 'rank_math_twitter_description', true),'rank_math'),
'_siteseo_social_twitter_img' => get_term_meta($term->term_id, 'rank_math_twitter_image', true),
'_siteseo_robots_index' => in_array('noindex', $term_robots_array) ? '1' : '',
'_siteseo_robots_follow' => in_array('nofollow', $term_robots_array) ? '1' : '',
'_siteseo_robots_imageindex' => in_array('noimageindex', $term_robots_array) ? '1' : '',
'_siteseo_robots_archive' => in_array('noarchive', $term_robots_array) ? '1' : '',
'_siteseo_robots_snippet' => in_array('nosnippet', $term_robots_array) ? '1' : '',
'_siteseo_robots_canonical' => get_term_meta($term->term_id, 'rank_math_canonical_url', true),
'_siteseo_analysis_target_kw' => get_term_meta($term->term_id, 'rank_math_focus_keyword', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('Rank Math import completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function yoast_seo(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$yoast_robots = get_post_meta($post->ID, '_yoast_wpseo_meta-robots-adv', true);
$robots_array = $yoast_robots ? explode(',', $yoast_robots) : [];
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_title', true),'yoast_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_metadesc', true),'yoast_seo'),
'_siteseo_social_fb_title' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_opengraph-title', true),'yoast_seo'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_opengraph-description', true),'yoast_seo'),
'_siteseo_social_fb_img' => get_post_meta($post->ID, '_yoast_wpseo_opengraph-image', true),
'_siteseo_social_twitter_title' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_twitter-title', true),'yoast_seo'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars(get_post_meta($post->ID, '_yoast_wpseo_twitter-description', true),'yoast_seo'),
'_siteseo_social_twitter_img' => get_post_meta($post->ID, '_yoast_wpseo_twitter-image', true),
'_siteseo_robots_index' => get_post_meta($post->ID, '_yoast_wpseo_meta-robots-noindex', true) ? '1' : '',
'_siteseo_robots_follow' => get_post_meta($post->ID, '_yoast_wpseo_meta-robots-nofollow', true) ? '1' : '',
'_siteseo_robots_imageindex' => in_array('noimageindex', $robots_array) ? '1' : '',
'_siteseo_robots_archive' => in_array('noarchive', $robots_array) ? '1' : '',
'_siteseo_robots_snippet' => in_array('nosnippet', $robots_array) ? '1' : '',
'_siteseo_robots_canonical' => get_post_meta($post->ID, '_yoast_wpseo_canonical', true),
'_siteseo_analysis_target_kw' => get_post_meta($post->ID, '_yoast_wpseo_focuskw', true),
'_siteseo_robots_primary_cat' => get_post_meta($post->ID, '_yoast_wpseo_primary_category', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$yoastseo_term_meta = get_option('wpseo_taxonomy_meta');
foreach($yoastseo_term_meta as $taxonomy){
if(!is_array($taxonomy)){
continue;
}
foreach($taxonomy as $term_id => $term){
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars((!empty($term['wpseo_title']) ? $term['wpseo_title'] : ''),'yoast_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars((!empty($term['wpseo_desc']) ? $term['wpseo_desc'] : ''),'yoast_seo'),
'_siteseo_social_fb_title' => self::replace_snippet_vars((!empty($term['wpseo_opengraph-title']) ? $term['wpseo_opengraph-title'] : ''),'yoast_seo'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars((!empty($term['wpseo_opengraph-description']) ? $term['wpseo_opengraph-description'] : ''),'yoast_seo'),
'_siteseo_social_fb_img' => !empty($term['wpseo_opengraph-image']) ? $term['wpseo_opengraph-image'] : '',
'_siteseo_social_twitter_title' => self::replace_snippet_vars((!empty($term['wpseo_twitter-title']) ? $term['wpseo_twitter-title'] : ''),'yoast_seo'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars((!empty($term['wpseo_twitter-description']) ? $term['wpseo_twitter-description'] : ''),'yoast_seo'),
'_siteseo_social_twitter_img' => !empty($term['wpseo_twitter-image']) ? $term['wpseo_twitter-image'] : '',
'_siteseo_robots_index' => !empty($term['wpseo_noindex']) ? 'yes' : '',
'_siteseo_robots_follow' => !empty($term['wpseo_nofollow']) ? 'yes' : '',
'_siteseo_robots_imageindex' => !empty($term['wpseo_noimageindex']) ? 'yes' : '',
'_siteseo_robots_archive' => !empty($term['wpseo_noarchive']) ? 'yes' : '',
'_siteseo_robots_snippet' => !empty($term['wpseo_nosnippet']) ? 'yes' : '',
'_siteseo_analysis_target_kw' => !empty($term['wpseo_focuskw']) ? $term['wpseo_focuskw'] : '',
'_siteseo_robots_primary_cat' => !empty($term['wpseo_primary_category']) ? $term['wpseo_primary_category'] : '',
'_siteseo_robots_canonical' => !empty($term['wpseo_canonical']) ? $term['wpseo_canonical'] : '',
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('Yoast SEO import completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function aio_seo(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_title', true)),'aio_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_description', true)),'aio_seo'),
'_siteseo_social_fb_title' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_og_title', true)),'aio_seo'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_og_description', true)),'aio_seo'),
'_siteseo_social_fb_img' => get_post_meta($post->ID, '_aioseo_og_image', true),
'_siteseo_social_twitter_title' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_twitter_title', true)),'aio_seo'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars((get_post_meta($post->ID, '_aioseo_twitter_description', true)),'aio_seo'),
'_siteseo_social_twitter_img' => get_post_meta($post->ID, '_aioseo_twitter_image', true),
'_siteseo_robots_index' => get_post_meta($post->ID, '_aioseo_noindex', true) ? '1' : '',
'_siteseo_robots_follow' => get_post_meta($post->ID, '_aioseo_nofollow', true) ? '1' : '',
'_siteseo_robots_imageindex' => '1',
'_siteseo_robots_archive' => '1',
'_siteseo_robots_snippet' => '1', // Default to 1 if not specified
'_siteseo_robots_canonical' => get_post_meta($post->ID, '_aioseo_canonical_url', true),
'_siteseo_analysis_target_kw' => get_post_meta($post->ID, '_aioseo_keywords', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
foreach($terms as $term){
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_title', true)),'aio_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_description', true)),'aio_seo'),
'_siteseo_social_fb_title' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_og_title', true)),'aio_seo'),
'_siteseo_social_fb_desc' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_og_description', true)),'aio_seo'),
'_siteseo_social_fb_img' => get_term_meta($term->term_id, '_aioseo_og_image', true),
'_siteseo_social_twitter_title' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_twitter_title', true)),'aio_seo'),
'_siteseo_social_twitter_desc' => self::replace_snippet_vars((get_term_meta($term->term_id, '_aioseo_twitter_description', true)),'aio_seo'),
'_siteseo_social_twitter_img' => get_term_meta($term->term_id, '_aioseo_twitter_image', true),
'_siteseo_robots_index' => get_term_meta($term->term_id, '_aioseo_noindex', true) ? '1' : '',
'_siteseo_robots_follow' => get_term_meta($term->term_id, '_aioseo_nofollow', true) ? '1' : '',
'_siteseo_robots_canonical' => get_term_meta($term->term_id, '_aioseo_canonical_url', true),
'_siteseo_analysis_target_kw' => get_term_meta($term->term_id, '_aioseo_keywords', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('All In One SEO import completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function seo_framework(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$meta_mapping = [
'_siteseo_titles_title' => get_post_meta($post->ID, '_genesis_title', true),
'_siteseo_titles_desc' => get_post_meta($post->ID, '_genesis_description', true),
'_siteseo_social_fb_title' => get_post_meta($post->ID, '_open_graph_title', true),
'_siteseo_social_fb_desc' => get_post_meta($post->ID, '_open_graph_description', true),
'_siteseo_social_fb_img' => get_post_meta($post->ID, '_social_image_url', true),
'_siteseo_social_twitter_title' => get_post_meta($post->ID, '_twitter_title', true),
'_siteseo_social_twitter_desc' => get_post_meta($post->ID, '_twitter_description', true),
'_siteseo_social_twitter_img' => get_post_meta($post->ID, '_twitter_image', true),
'_siteseo_robots_index' => get_post_meta($post->ID, '_genesis_noindex', true) ? '1' : '',
'_siteseo_robots_follow' => get_post_meta($post->ID, '_genesis_nofollow', true) ? '1' : '',
'_siteseo_robots_imageindex' => '1',
'_siteseo_robots_archive' => '1',
'_siteseo_robots_snippet' => '1',
'_siteseo_robots_canonical' => get_post_meta($post->ID, '_genesis_canonical_uri', true),
'_siteseo_analysis_target_kw' => get_post_meta($post->ID, '_genesis_keywords', true)
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
foreach($terms as $term){
$term_data = get_term_meta($term->term_id, 'autodescription-term-settings', true);
if(empty($term_data) || !is_array($term_data)){
continue;
}
$meta_mapping = [
'_siteseo_titles_title' => !empty($term_data['doctitle']) ? $term_data['doctitle'] : '',
'_siteseo_titles_desc' => !empty($term_data['description']) ? $term_data['description'] : '',
'_siteseo_social_fb_title' => !empty($term_data['og_title']) ? $term_data['og_title'] : '',
'_siteseo_social_fb_desc' => !empty($term_data['og_description']) ? $term_data['og_description'] : '',
'_siteseo_social_fb_img' => !empty($term_data['social_image_url']) ? $term_data['social_image_url'] : '',
'_siteseo_social_twitter_title' => !empty($term_data['tw_title']) ? $term_data['tw_title'] : '',
'_siteseo_social_twitter_desc' => !empty($term_data['tw_description']) ? $term_data['tw_description'] : '',
'_siteseo_social_twitter_img' => !empty($term_data['social_image_url']) ? $term_data['social_image_url'] : '',
'_siteseo_robots_index' => !empty($term_data['noindex']) ? true : '',
'_siteseo_robots_follow' => !empty($term_data['nofollow'] ) ? true : '',
'_siteseo_robots_archive' => !empty($term_data['noarchive']) ? true : '',
'_siteseo_robots_canonical' => !empty($term_data['canonical']) ? $term_data['canonical'] : '',
'_siteseo_analysis_target_kw' => !empty($term_data['keywords']) ? $term_data['keywords'] : '',
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('SEO Framework import completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function seo_press(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$robots_index = get_post_meta($post->ID, '_seopress_robots_index', true);
$robots_follow = get_post_meta($post->ID, '_seopress_robots_follow', true);
$robots_imageindex = get_post_meta($post->ID, '_seopress_robots_imageindex', true);
$robots_archive = get_post_meta($post->ID, '_seopress_robots_archive', true);
$meta_mapping = [
'_siteseo_titles_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_post_meta($post->ID, '_seopress_titles_title', true)),
'_siteseo_titles_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($post->ID, '_seopress_titles_desc', true)),
'_siteseo_social_fb_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($post->ID, '_seopress_social_fb_title', true)),
'_siteseo_social_fb_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($post->ID, '_seopress_social_fb_desc', true)),
'_siteseo_social_fb_img' => get_post_meta($post->ID,'_seopress_social_fb_img',true),
'_siteseo_social_twitter_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($post->ID, '_seopress_social_twitter_title', true)),
'_siteseo_social_twitter_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($post->ID, '_seopress_social_twitter_desc', true)),
'_siteseo_social_twitter_img' => get_post_meta($post->ID, '_seopress_social_twitter_img', true),
'_siteseo_robots_index' => (!empty($robots_index) && $robots_index === 'yes') ? '1' : '0',
'_siteseo_robots_follow' => (!empty($robots_follow) && $robots_follow === 'yes') ? '1' : '0',
'_siteseo_robots_imageindex' => (!empty($robots_imageindex) && $robots_imageindex === 'yes') ? '1' : '0',
'_siteseo_robots_archive' => (!empty($robots_archive) && $robots_archive === 'yes') ? '1' : '0',
'_siteseo_robots_snippet' => get_post_meta($post->ID, '_seopress_robots_snippet', true),
'_siteseo_robots_canonical' => get_post_meta($post->ID, '_seopress_robots_canonical', true),
'_siteseo_analysis_target_kw' => get_post_meta($post->ID, '_seopress_analysis_target_kw', true),
'_siteseo_redirections_enabled' => get_post_meta($post->ID, '_seopress_redirections_enabled', true) ? '1' : '0',
'_siteseo_redirections_value' => get_post_meta($post->ID, '_seopress_redirections_value', true),
'_siteseo_redirections_type' => get_post_meta($post->ID, '_seopress_redirections_type', true),
'_siteseo_redirections_param' => get_post_meta($post->ID, '_seopress_redirections_param', true),
'_siteseo_redirections_logged_status' => get_post_meta($post->ID, '_seopress_redirections_logged_status', true),
'_siteseo_redirections_enabled_regex' => get_post_meta($post->ID, '_seopress_redirections_enabled_regex', true),
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
foreach($terms as $term){
$robots_index = get_term_meta($term->term_id, '_seopress_robots_index', true);
$robots_follow = get_term_meta($term->term_id, '_seopress_robots_follow', true);
$robots_imageindex = get_term_meta($term->term_id, '_seopress_robots_imageindex', true);
$robots_archive = get_term_meta($term->term_id, '_seopress_robots_archive', true);
$meta_mapping = [
'_siteseo_titles_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_titles_title', true)),
'_siteseo_titles_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_titles_desc', true)),
'_siteseo_social_fb_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_social_fb_title', true)),
'_siteseo_social_fb_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_social_fb_desc', true)),
'_siteseo_social_fb_img' => get_term_meta($term->term_id,'_seopress_social_fb_img',true),
'_siteseo_social_twitter_title' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_social_twitter_title', true)),
'_siteseo_social_twitter_desc' => str_replace('%%wc_single_price_exc_tax%%', '%%wc_single_price_exe_tax%%', get_term_meta($term->term_id, '_seopress_social_twitter_desc', true)),
'_siteseo_social_twitter_img' => get_term_meta($term->term_id, '_seopress_social_twitter_img', true),
'_siteseo_robots_index' => (!empty($robots_index) && $robots_index === 'yes') ? '1' : '0',
'_siteseo_robots_follow' => (!empty($robots_follow) && $robots_follow === 'yes') ? '1' : '0',
'_siteseo_robots_imageindex' => (!empty($robots_imageindex) && $robots_imageindex === 'yes') ? '1' : '0',
'_siteseo_robots_archive' => (!empty($robots_archive) && $robots_archive === 'yes') ? '1' : '0',
'_siteseo_robots_snippet' => get_term_meta($term->term_id, '_seopress_robots_snippet', true),
'_siteseo_robots_canonical' => get_term_meta($term->term_id, '_seopress_robots_canonical', true),
'_siteseo_analysis_target_kw' => get_term_meta($term->term_id, '_seopress_analysis_target_kw', true),
'_siteseo_redirections_enabled' => get_term_meta($term->term_id, '_seopress_redirections_enabled', true) ? '1' : '0',
'_siteseo_redirections_value' => get_term_meta($term->term_id, '_seopress_redirections_value', true),
'_siteseo_redirections_type' => get_term_meta($term->term_id, '_seopress_redirections_type', true),
'_siteseo_redirections_param' => get_term_meta($term->term_id, '_seopress_redirections_param', true),
'_siteseo_redirections_logged_status' => get_term_meta($term->term_id, '_seopress_redirections_logged_status', true),
'_siteseo_redirections_enabled_regex' => get_term_meta($term->term_id, '_seopress_redirections_enabled_regex', true),
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('SEOPress migration completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function slim_seo(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
$taxonomies = get_taxonomies(array('public' => true), 'objects');
foreach($posts as $post){
$post_data = get_post_meta($post->ID, 'slim_seo', true);
if(empty($post_data) || !is_array($post_data)){
continue;
}
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars((!empty($post_data['title']) ? $post_data['title'] : ''),'slim_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars((!empty($post_data['description']) ? $post_data['description'] : ''),'slim_seo'),
'_siteseo_social_fb_img' => !empty($post_data['facebook_image']) ? $post_data['facebook_image'] : '',
'_siteseo_social_twitter_img' => !empty($post_data['twitter_image']) ? $post_data['twitter_image'] : '',
'_siteseo_robots_index' => isset($post_data['noindex']) && $post_data['noindex'] ? '1' : '',
'_siteseo_robots_canonical' => !empty($post_data['canonical']) ? $post_data['canonical'] : '',
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_post_meta($post->ID, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
foreach($terms as $term){
$term_data = get_term_meta($term->term_id, 'slim_seo', true);
if(empty($term_data) || !is_array($term_data)){
continue;
}
$meta_mapping = [
'_siteseo_titles_title' => self::replace_snippet_vars((!empty($term_data['title']) ? $term_data['title'] : ''),'slim_seo'),
'_siteseo_titles_desc' => self::replace_snippet_vars((!empty($term_data['description']) ? $term_data['description'] : ''),'slim_seo'),
'_siteseo_social_fb_img' => !empty($term_data['facebook_image']) ? $term_data['facebook_image'] : '',
'_siteseo_social_twitter_img' => !empty($term_data['twitter_image']) ? $term_data['twitter_image'] : '',
'_siteseo_robots_index' => !empty($term_data['noindex']) ? true : '',
'_siteseo_robots_canonical' => !empty($term_data['canonical']) ? $term_data['canonical'] : '',
];
foreach($meta_mapping as $siteseo_key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $siteseo_key, $value);
$imported_count++;
}
}
$log[] = "Imported term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
/* translators: %d count of items imported */
'message' => sprintf(__('Slim SEO import completed. Imported %d items.', 'siteseo'), $imported_count)
];
}
static function replace_snippet_vars($string, $plugin){
if(empty($string)) return $string;
// We should not process the string if it does not have a variable
if(!preg_match('/%|{|#/', $string)){
return $string;
}
static $plugins = [
'rank_math' => [
'%sep%' => '%%sep%%',
'%sitename%' => '%%sitetitle%%',
'%sitedesc%' => '%%tagline%%',
'%title%' => '%%post_title%%',
'%excerpt%' => '%%post_excerpt%%',
'%excerpt_only%' => '%%post_excerpt%%',
'%post_thumbnail%' => '%%post_thumbnail_url%%',
'%url%' => '%%post_url%%',
'%date%' => '%%post_date%%',
'%modified%' => '%%post_modified_date%%',
'%name%' => '%%post_author%%',
'%category%' => '%%post_category%%',
'%tag%' => '%%post_tag%%',
'%term%' => '%%term_title%%',
'%term_description%' => '%%term_description%%',
'%search_query%' => '%%search_keywords%%',
'%pagenumber%' => '%%current_pagination%%',
'%page%' => '%%page%%',
'%archive_title%' => '%%archive_title%%',
'%sitename_with_sep%' => '%%sep%%%%sitetitle%%',
'%pt_plural%' => '%%cpt_plural%%',
'%wc_shortdesc%' => '%%wc_single_short_desc%%',
'%wc_price%' => '%%wc_single_price%%',
'%wc_sku%' => '%%wc_sku%%',
'%currentday%' => '%%currentday%%',
'%currentmonth%' => '%%currentmonth%%',
'%currentyear%' => '%%currentyear%%',
'%currentdate%' => '%%currentdate%%',
'%currenttime%' => '%%currenttime%%',
'%user_description%' => '%%author_bio%%',
'%focuskw%' => '%%target_keyword%%'
],
'yoast_seo' => [
'%%sitename%%' => '%%sitetitle%%',
'%%sitedesc%%' => '%%tagline%%',
'%%title%%' => '%%post_title%%',
'%%excerpt%%' => '%%post_excerpt%%',
'%%excerpt_only%%' => '%%post_excerpt%%',
'%%content%%' => '%%post_content%%',
'%%thumbnail%%' => '%%post_thumbnail_url%%',
'%%url%%' => '%%post_url%%',
'%%date%%' => '%%post_date%%',
'%%modified%%' => '%%post_modified_date%%',
'%%author%%' => '%%post_author%%',
'%%category%%' => '%%post_category%%',
'%%primary_category%%' => '%%post_category%%',
'%%tag%%' => '%%post_tag%%',
'%%category_description%%' => '%%_category_description%%',
'%%searchphrase%%' => '%%search_keywords%%',
'%%pagenumber%%' => '%%current_pagination%%',
'%%year%%' => '%%currentyear%%',
'%%month%%' => '%%currentmonth%%',
'%%day%%' => '%%currentday%%',
'%%author_firstname%%' => '%%author_first_name%%',
'%%author_lastname%%' => '%%author_last_name%%',
'%%author_description%%' => '%%author_bio%%',
'%%product_sku%%' => '%%wc_sku%%',
'%%product_price%%' => '%%wc_single_price%%',
'%%product_shortdesc%%' => '%%wc_single_short_desc%%',
'%%product_category%%' => '%%wc_single_cat%%',
'%%product_tag%%' => '%%wc_single_tag%%'
],
'aio_seo' => [
'#separator_sa' => '%%sep%%',
'#site_title' => '%%sitetitle%%',
'#tagline' => '%%tagline%%',
'#post_title' => '%%post_title%%',
'#post_excerpt' => '%%post_excerpt%%',
'#post_content' => '%%post_content%%',
'#post_thumbnail' => '%%post_thumbnail_url%%',
'#post_url' => '%%post_url%%',
'#post_date' => '%%post_date%%',
'#post_modified_date' => '%%post_modified_date%%',
'#categories' => '%%post_category%%',
'#post_tags' => '%%post_tag%%',
'#author_name' => '%%post_author%%',
'#taxonomy_title' => '%%post_category%%',
'#tag_title' => '%%post_tag%%',
'#term_name' => '%%term_title%%',
'#term_description' => '%%term_description%%',
'#search_query' => '%%search_keywords%%',
'#page_number' => '%%page%%',
'#pt_plural' => '%%cpt_plural%%',
'#wc_short_description' => '%%wc_single_short_desc%%',
'#wc_price' => '%%wc_single_price%%',
'#wc_sku' => '%%wc_sku%%',
'#current_day' => '%%currentday%%',
'#current_month' => '%%currentmonth%%',
'#current_year' => '%%currentyear%%',
'#current_date' => '%%currentdate%%',
'#current_time' => '%%currenttime%%',
'#author_first_name' => '%%author_first_name%%',
'#author_last_name' => '%%author_last_name%%',
'#author_description' => '%%author_bio%%',
'#focus_keyword' => '%%target_keyword%%',
'#custom_field' => '%%_cf_your_custom_field_name%%'
],
'slim_seo' => [
'{{ sep }}' => '%%sep%%',
'{{ site.title }}' => '%%sitetitle%%',
'{{ post.title }}' => '%%post_title%%',
'{{ post.excerpt }}' => '%%post_excerpt%%',
'{{ post.content }}' => '%%post_content%%',
'{{ post_type.plural }}' => '%%cpt_plural%%',
'{{ post.thumbnail }}' => '%%post_thumbnail_url%%',
'{{ post.url }}' => '%%post_url%%',
'{{ post.date }}' => '%%post_date%%',
'{{ post.modified_date }}' => '%%post_modified_date%%',
'{{ author.display_name }}' => '%%post_author%%',
'{{ post.categories }}' => '%%post_category%%',
'{{ post.tags }}' => '%%post_tag%%',
'{{ term.name }}' => '%%term_title%%',
'{{ term.description }}' => '%%term_description%%',
'{{ page }}' => '%%page%%',
'{{ current.month }}' => '%%currentmonth%%',
'{{ current.day }}' => '%%currentday%%',
'{{ current.year }}' => '%%currentyear%%',
'{{ author.first_name }}' => '%%author_first_name%%',
'{{ author.last_name }}' => '%%author_last_name%%',
'{{ author.website_url }}' => '%%author_website%%',
'{{ author.nickname }}' => '%%author_nickname%%',
'{{ author.description }}' => '%%author_bio%%'
],
'surerank' => [
'%site_name%'=> '%%sitetitle%%',
'%title%' => '%%post_title%%',
'%tagline%' => '%%tagline%%',
'%post_url%' => '%%post_url%%',
'%content%' => '%%post_content%%',
'%sep%' => '%%sep%%',
'%excerpt%' => '%%post_excerpt%%',
'%author_name%' => '%%post_author%%',
'%category%' => '%%post_category%%',
'%tag%' => '%%post_tag%%',
'%term_title%' => '%%term_title%%',
'%term_description%' => '%%term_description%%',
'%modified%' => '%%post_modified_date%%',
'%currentdate%' => '%%currentday%%',
'%currentmonth%' => '%%currentmonth%%',
'%currentyear%' => '%%currentyear%%',
]
];
if(!empty($plugins[$plugin])){
return str_replace(array_keys($plugins[$plugin]), array_values($plugins[$plugin]), $string);
}
return $string;
}
static function surerank(){
$imported_count = 0;
$log = [];
$posts = get_posts(['posts_per_page' => -1, 'post_type' => 'any', 'post_status' => 'any']);
foreach($posts as $post){
$general = get_post_meta($post->ID, 'surerank_settings_general', true);
$general = is_array($general) ? $general : [];
$social = get_post_meta($post->ID, 'surerank_settings_social', true);
$social = is_array($social) ? $social : [];
$noindex = get_post_meta($post->ID, 'surerank_settings_post_no_index', true);
$nofollow = get_post_meta($post->ID, 'surerank_settings_post_no_follow', true);
$noarchive = get_post_meta($post->ID, 'surerank_settings_post_no_archive', true);
$meta_mapping = [
'_siteseo_titles_title' => !empty($general['page_title']) ? self::replace_snippet_vars($general['page_title'], 'surerank') : '',
'_siteseo_titles_desc' => !empty($general['page_description']) ? self::replace_snippet_vars($general['page_description'], 'surerank') : '',
'_siteseo_robots_canonical' => !empty($general['canonical_url']) ? $general['canonical_url'] : '',
'_siteseo_social_fb_title' => !empty($social['facebook_title']) ? self::replace_snippet_vars($social['facebook_title'], 'surerank') : '',
'_siteseo_social_fb_desc' => !empty($social['facebook_description']) ? self::replace_snippet_vars($social['facebook_description'], 'surerank') : '',
'_siteseo_social_twitter_title' => !empty($social['twitter_title']) ? self::replace_snippet_vars($social['twitter_title'], 'surerank') : '',
'_siteseo_social_twitter_desc' => !empty($social['twitter_description']) ? self::replace_snippet_vars($social['twitter_description'], 'surerank') : '',
'_siteseo_social_fb_img' => !empty($social['facebook_image_url']) ? $social['facebook_image_url'] : '',
'_siteseo_social_twitter_img' => !empty($social['twitter_image_url']) ? $social['twitter_image_url'] : '',
// Robots
'_siteseo_robots_index' => ($noindex === 'yes') ? '1' : '',
'_siteseo_robots_follow' => ($nofollow === 'yes') ? '1' : '',
'_siteseo_robots_archive' => ($noarchive === 'yes') ? '1' : '',
];
foreach($meta_mapping as $key => $value){
if(!empty($value)){
update_post_meta($post->ID, $key, $value);
$imported_count++;
}
}
$log[] = "Imported SureRank post ID: {$post->ID}";
}
$taxonomies = get_taxonomies();
foreach($taxonomies as $taxonomy){
$terms = get_terms([
'taxonomy' => $taxonomy,
'hide_empty' => false,
]);
if(is_wp_error($terms) || empty($terms)){
continue;
}
foreach($terms as $term){
$general = get_term_meta($term->term_id, 'surerank_settings_general', true);
$general = is_array($general) ? $general : [];
$social = get_term_meta($term->term_id, 'surerank_settings_social', true);
$social = is_array($social) ? $social : [];
$noindex = get_term_meta($term->term_id, 'surerank_settings_term_no_index', true);
$nofollow = get_term_meta($term->term_id, 'surerank_settings_term_no_follow', true);
$noarchive = get_term_meta($term->term_id, 'surerank_settings_term_no_archive', true);
$meta_mapping = [
// Titles
'_siteseo_titles_title' => !empty($general['page_title']) ? self::replace_snippet_vars($general['page_title'], 'surerank') : '',
'_siteseo_titles_desc' => !empty($general['page_description']) ? self::replace_snippet_vars($general['page_description'], 'surerank') : '',
'_siteseo_robots_canonical' => !empty($general['canonical_url']) ? $general['canonical_url'] : '',
'_siteseo_social_fb_title' => !empty($social['facebook_title']) ? self::replace_snippet_vars($social['facebook_title'], 'surerank') : '',
'_siteseo_social_fb_desc' => !empty($social['facebook_description']) ? self::replace_snippet_vars($social['facebook_description'], 'surerank') : '',
'_siteseo_social_twitter_title' => !empty($social['twitter_title']) ? self::replace_snippet_vars($social['twitter_title'], 'surerank') : '',
'_siteseo_social_twitter_desc' => !empty($social['twitter_description']) ? self::replace_snippet_vars($social['twitter_description'], 'surerank') : '',
'_siteseo_social_fb_img' => !empty($social['facebook_image_url']) ? $social['facebook_image_url'] : '',
'_siteseo_social_twitter_img' => !empty($social['twitter_image_url']) ? $social['twitter_image_url'] : '',
// Robots
'_siteseo_robots_index' => ($noindex === 'yes') ? '1' : '',
'_siteseo_robots_follow' => ($nofollow === 'yes') ? '1' : '',
'_siteseo_robots_archive' => ($noarchive === 'yes') ? '1' : '',
];
foreach($meta_mapping as $key => $value){
if(!empty($value)){
update_term_meta($term->term_id, $key, $value);
$imported_count++;
}
}
$log[] = "Imported SureRank term ID: {$term->term_id}";
}
}
return [
'count' => $imported_count,
'log' => $log,
'message' => sprintf(__('SureRank import completed. Imported %d items.', 'siteseo'), $imported_count),
];
}
}
primarycategory.php 0000644 00000005151 15152641524 0010505 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class PrimaryCategory{
static function wc_primary_category($none_terms, $terms, $post){
$primary_cat = null;
if(!empty($post)){
$wc_primary_cat = get_post_meta($post->ID, '_siteseo_robots_primary_cat', true);
if(isset($wc_primary_cat) && '' != $wc_primary_cat && 'none' != $wc_primary_cat){
if(null != $post->post_type && 'product' == $post->post_type){
$primary_cat = get_term($wc_primary_cat, 'product_cat');
}
if(!is_wp_error($primary_cat) && null != $primary_cat){
return $primary_cat;
}
} else{
return $none_terms;
}
} else{
return $none_terms;
}
}
static function add_primary_category($none_cate, $cats, $post){
$primary_cat = null;
if(!empty($post)){
$robots_primary_cat = get_post_meta($post->ID, '_siteseo_robots_primary_cat', true);
if(isset($robots_primary_cat) && '' != $robots_primary_cat && 'none' != $robots_primary_cat){
if(null != $post->post_type && 'post' == $post->post_type){
$primary_cat = get_category($robots_primary_cat);
}
if(!is_wp_error($primary_cat) && null != $primary_cat){
return $primary_cat;
}
} else{
return $none_cate;
}
} else{
return $none_cate;
}
}
static function replace_breadcrumb_categories($crumbs, $breadcrumb){
if(!is_product()){
return $crumbs;
}
global $post;
$primary_cat_id = get_post_meta($post->ID, '_siteseo_robots_primary_cat', true);
if(!empty($primary_cat_id) && $primary_cat_id !== 'none'){
$primary_cat = get_term($primary_cat_id, 'product_cat');
if(!empty($primary_cat) && !is_wp_error($primary_cat)){
$new_crumbs = [];
foreach($crumbs as $key => $crumb){
if($key === 0 || (isset($crumb[1]) && strpos($crumb[1], '?post_type=product') !== false)){
$new_crumbs[] = $crumb;
}
}
$ancestors = get_ancestors($primary_cat->term_id, 'product_cat');
$ancestors = array_reverse($ancestors);
foreach($ancestors as $ancestor_id){
$ancestor = get_term($ancestor_id, 'product_cat');
if(!empty($ancestor) && !is_wp_error($ancestor)){
$new_crumbs[] = [
$ancestor->name,
get_term_link($ancestor)
];
}
}
if(!empty($primary_cat) && !is_wp_error($primary_cat)){
$new_crumbs[] = [
$primary_cat->name,
get_term_link($primary_cat)
];
}
if(count($crumbs) > 0){
$new_crumbs[] = $crumbs[count($crumbs) - 1];
}
return $new_crumbs;
}
}
return $crumbs;
}
} advanced.php 0000644 00000015554 15152641524 0007041 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Advanced{
static function tags(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return; // toggle disable
}
// meta tags
if(!empty($siteseo->advanced_settings['advanced_google'])){
echo '<meta name="google-site-verification" content="'.esc_attr($siteseo->advanced_settings['advanced_google']).'" />' . "\n";
}
if(!empty($siteseo->advanced_settings['advanced_bing'])){
echo '<meta name="msvalidate.01" content="'.esc_attr($siteseo->advanced_settings['advanced_bing']).'" />' . "\n";
}
if(!empty($siteseo->advanced_settings['advanced_pinterest'])){
echo '<meta name="p:domain_verify" content="'.esc_attr($siteseo->advanced_settings['advanced_pinterest']).'" />';
}
if(!empty($siteseo->advanced_settings['advanced_yandex'])){
echo '<meta name="yandex-verification" content="'.esc_attr($siteseo->advanced_settings['advanced_yandex']).'" />';
}
if(!empty($siteseo->advanced_settings['advanced_wp_rsd'])){
remove_action('wp_head', 'rsd_link');
}
}
static function remove_links(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-advanced'])){
return; // toggle disable
}
if(!empty($siteseo->advanced_settings['advanced_wp_rsd'])){
remove_action('wp_head', 'rsd_link');
}
if(!empty($siteseo->advanced_settings['advanced_wp_wlw'])){
remove_action('wp_head', 'wlwmanifest_link');
}
if(!empty($siteseo->advanced_settings['advanced_wp_shortlink'])){
remove_action('wp_head', 'wp_shortlink_wp_head');
}
if(!empty($siteseo->advanced_settings['advanced_wp_generator'])){
remove_action('wp_head', 'wp_generator');
}
if(!empty($siteseo->advanced_settings['advanced_comments_form_link'])){
add_filter('comment_form_default_fields', '\SiteSEO\Advanced::remove_comment_url_field');
}
if(!empty($siteseo->advanced_settings['advanced_comments_author_url'])){
add_filter('get_comment_author_link', '\SiteSEO\Advanced::remove_author_link_if_profile_url');
}
if(!empty($siteseo->advanced_settings['advanced_hentry'])){
add_filter('post_class', '\SiteSEO\Advanced::remove_hentry_post_class');
}
if(!empty($siteseo->advanced_settings['advanced_noreferrer'])){
add_filter('the_content', '\SiteSEO\Advanced::remove_noreferrer_from_post_content');
}
if(!empty($siteseo->advanced_settings['advanced_tax_desc_editor'])){
add_action('edit_term', '\SiteSEO\Advanced::add_wp_editor_to_taxonomy_description', 10, 2);
}
if(!empty($siteseo->advanced_settings['advanced_category_url'])){
add_action('init', '\SiteSEO\Advanced::remove_category_base', 111);
add_action('template_redirect', '\SiteSEO\Advanced::redirect_category');
}
}
static function add_wp_editor_to_taxonomy_description($tag, $tt_id = 0){
if('edit' !== get_current_screen()->base || 'edit-tags' !== get_current_screen()->id){
return;
}
if(isset($tag->description)){
$editor_settings = array(
'textarea_name' => 'description',
'textarea_rows' => 10,
'editor_class' => 'wp-editor-area',
'media_buttons' => true,
'tinymce' => true,
'quicktags' => true,
);
wp_editor($tag->description, 'description', $editor_settings);
}
}
static function remove_noreferrer_from_post_content($content){
$content = preg_replace('/(<a\s+[^>]*rel=["\'][^"\']*?)(\s*\bnoreferrer\b\s*)([^"\']*["\'][^>]*>)/i', '$1$3', $content);
return $content;
}
static function remove_hentry_post_class($classes){
$classes = array_diff($classes, array('hentry'));
return $classes;
}
static function remove_comment_url_field($fields){
if(isset($fields['url'])){
unset($fields['url']);
}
return $fields;
}
static function remove_author_link_if_profile_url($comment_author_link = '', $comment_author = '', $comment_id = 0){
if(empty($comment_id)){
return $comment_author;
}
$comment = get_comment($comment_id);
if(empty($comment) || !is_object($comment)){
return $comment_author;
}
$user_id = $comment->user_id;
if(!empty($user_id)){
$user_website = get_the_author_meta('user_url', $user_id);
if($user_website){
return get_comment_author($comment_id);
}
}
return $comment_author;
}
static function remove_category_base(){
$categories = get_categories(array('hide_empty' => false));
$category_slugs = wp_list_pluck($categories, 'slug');
if(empty($category_slugs)){
return;
}
$category_pattern = '(' . implode('|', $category_slugs) .')';
add_rewrite_rule(
'^'.$category_pattern.'/?$',
'index.php?category_name=$matches[1]',
'top'
);
// Add rule for handle pagination
add_rewrite_rule(
'^'.$category_pattern.'/page/([0-9]+)/?$',
'index.php?category_name=$matches[1]&paged=$matches[2]',
'top'
);
}
static function redirect_category(){
if(is_category() && !is_admin()){
$category = get_query_var('category_name');
$category_base = get_option('category_base');
$base_to_check = !empty($category_base) ? $category_base : 'category';
if(!empty($category) && strpos(sanitize_url($_SERVER['REQUEST_URI']), '/'.$base_to_check.'/') !== false){
wp_safe_redirect(home_url('/' . $category . '/'), 301);
exit;
}
}
}
static function remove_wc_category_base(){
global $siteseo;
if(empty($siteseo->advanced_settings['advanced_product_cat_url']) || empty($siteseo->setting_enabled['toggle-advanced'])){
return;
}
if(!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))){
return;
}
add_filter('term_link', '\SiteSEO\Advanced::remove_category_base_woo', 10, 3);
add_filter('request', '\SiteSEO\Advanced::category_url_request');
add_action('created_product_cat', 'flush_rewrite_rules');
add_action('delete_product_cat', 'flush_rewrite_rules');
add_action('edited_product_cat', 'flush_rewrite_rules');
add_action('parse_request', '\SiteSEO\Advanced::old_category_url_request');
}
static function remove_category_base_woo($termlink, $term, $taxonomy){
if($taxonomy === 'product_cat'){
$category_base = '/product-category/';
return str_replace($category_base, '/', $termlink);
}
return $termlink;
}
static function category_url_request($query_vars){
if(!isset($query_vars['product_cat']) && isset($query_vars['pagename'])){
$pagename = $query_vars['pagename'];
$term = get_term_by('slug', $pagename, 'product_cat');
if($term){
$query_vars['product_cat'] = $term->slug;
unset($query_vars['pagename']);
}
}
return $query_vars;
}
static function old_category_url_request($wp){
if(!isset($wp->query_vars['pagename'])){
return;
}
$pagename = $wp->query_vars['pagename'];
$term = get_term_by('slug', $pagename, 'product_cat');
if($term){
$wp->query_vars['product_cat'] = $term->slug;
unset($wp->query_vars['pagename']);
}
}
}
titlesmetas.php 0000644 00000100122 15152641524 0007614 0 ustar 00 <?php
/*
* SITESEO
* https://siteseo.io
* (c) SiteSEO Team
*/
namespace SiteSEO;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class TitlesMetas{
static function advanced_metas($robots){
global $siteseo, $post;
$disable_noindex = !empty($siteseo->advanced_settings['appearance_adminbar_noindex']) ? true : '';
if(empty($siteseo->setting_enabled['toggle-titles']) || !empty($disable_noindex)){
return $robots;
}
$settings = $siteseo->titles_settings;
//all post types and taxonomies
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
$post_id = isset($post) && is_object($post) ? $post->ID : 0;
$index_extras = [
'max-snippet' => '-1',
'max-image-preview' => 'large',
'max-video-preview' => '-1'
];
$robots = [
'noindex' => !empty($settings['titles_noindex']),
'nofollow' => !empty($settings['titles_nofollow']),
'nosnippet' => !empty($settings['titles_nosnippet']),
'noarchive' => !empty($settings['titles_noarchive']),
'noimageindex' => !empty($settings['titles_noimageindex'])
];
if(!empty($post_id) && !empty($post->post_password)){
$robots['noindex'] = true;
}
foreach($taxonomies as $taxonomy){
// taxonomies
$term_id = 0;
if(is_tax() || is_category() || is_tag()){
$queried_object = get_queried_object();
$term_id = $queried_object->term_id ? $queried_object->term_id : 0;
if($term_id){
$robots['noindex'] = !empty(get_term_meta($term_id, '_siteseo_robots_index', true)) || $robots['noindex'];
$robots['nofollow'] = !empty(get_term_meta($term_id, '_siteseo_robots_follow', true)) || $robots['nofollow'];
$robots['nosnippet'] = !empty(get_term_meta($term_id, '_siteseo_robots_snippet', true)) || $robots['nosnippet'];
$robots['noarchive'] = !empty(get_term_meta($term_id, '_siteseo_robots_archive', true)) || $robots['noarchive'];
$robots['noimageindex'] = !empty(get_term_meta($term_id, '_siteseo_robots_imageindex', true)) || $robots['noimageindex'];
}
if(!empty($settings['titles_tax_titles'][$taxonomy->name]['noindex'])){
if(isset($robots['index'])){
unset($robots['index']);
}
$robots['noindex'] = true;
}
if(!empty($settings['titles_tax_titles'][$taxonomy->name]['nofollow'])){
if(isset($robots['follow'])){
unset($robots['follow']);
}
$robots['nofollow'] = true;
}
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
if(!$robots['nofollow']){
$robots['follow'] = true;
}
return array_filter($robots);
}
}
// single post types
foreach($post_types as $post_type){
if($post_type->has_archive && is_post_type_archive($post_type->name)){
if(function_exists('is_shop') && is_shop()){
$post_id = !defined('SITEPAD') ? wc_get_page_id('shop') : kkart_get_page_id('shop');
}
if($post_id){
$robots['noindex'] = !empty(get_post_meta($post_id, '_siteseo_robots_index', true)) || $robots['noindex'];
$robots['nofollow'] = !empty(get_post_meta($post_id, '_siteseo_robots_follow', true)) || $robots['nofollow'];
$robots['nosnippet'] = !empty(get_post_meta($post_id, '_siteseo_robots_snippet', true)) || $robots['nosnippet'];
$robots['noarchive'] = !empty(get_post_meta($post_id, '_siteseo_robots_archive', true)) || $robots['noarchive'];
$robots['noimageindex'] = !empty(get_post_meta($post_id, '_siteseo_robots_imageindex', true)) || $robots['noimageindex'];
}
if(!empty($settings['titles_archive_titles'][$post_type->name]['archive_noindex'])){
if(isset($robots['index'])){
unset($robots['index']);
}
$robots['noindex'] = true;
}
if(!empty($settings['titles_archive_titles'][$post_type->name]['archive_nofollow'])){
if(isset($robots['follow'])){
unset($robots['follow']);
}
$robots['nofollow'] = true;
}
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
if(!$robots['nofollow']){
$robots['follow'] = true;
}
return array_filter($robots);
}
if(is_singular($post_type->name)){
if($post_id){
$robots['noindex'] = !empty(get_post_meta($post_id, '_siteseo_robots_index', true)) || $robots['noindex'];
$robots['nofollow'] = !empty(get_post_meta($post_id, '_siteseo_robots_follow', true)) || $robots['nofollow'];
$robots['nosnippet'] = !empty(get_post_meta($post_id, '_siteseo_robots_snippet', true)) || $robots['nosnippet'];
$robots['noarchive'] = !empty(get_post_meta($post_id, '_siteseo_robots_archive', true)) || $robots['noarchive'];
$robots['noimageindex'] = !empty(get_post_meta($post_id, '_siteseo_robots_imageindex', true)) || $robots['noimageindex'];
}
if(!empty($settings['titles_single_titles'][$post_type->name]['noindex'])){
if(isset($robots['index'])){
unset($robots['index']);
}
$robots['noindex'] = true;
}
if(!empty($settings['titles_single_titles'][$post_type->name]['nofollow'])){
if(isset($robots['follow'])){
unset($robots['follow']);
}
$robots['nofollow'] = true;
}
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
if(!$robots['nofollow']){
$robots['follow'] = true;
}
// woocommerce pages, cart page
if(function_exists('is_cart') && is_cart()){
unset($robots['index']);
$robots['noindex'] = true;
}
// checkout page
if(function_exists('is_checkout') && is_checkout()){
unset($robots['index']);
$robots['noindex'] = true;
}
// account page
if(function_exists('is_account_page') && is_account_page()){
unset($robots['index']);
$robots['noindex'] = true;
}
return array_filter($robots);
}
}
//archive pages
if(is_author()){
$robots['noindex'] = !empty($settings['titles_archives_author_noindex']);
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
}
if(is_date()){
$robots['noindex'] = !empty($settings['titles_archives_date_noindex']);
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
}
if(is_search()){
$robots['noindex'] = !empty($settings['titles_archives_search_title_noindex']);
if(!$robots['noindex']){
$robots['index'] = true;
$robots = array_merge($robots, $index_extras);
}
}
// default home page
if(is_front_page() && is_home()){
$robots = [
'index' => true,
'follow' => true
];
if(!empty($settings['titles_noindex'])){
$robots['noindex'] = true;
unset($robots['index']);
}
if(!empty($settings['titles_nofollow'])){
$robots['nofollow'] = true;
unset($robots['follow']);
}
if(!empty($settings['titles_nosnippet'])){
$robots['nosnippet'] = true;
}
if(!empty($settings['titles_noarchive'])){
$robots['noarchive'] = true;
}
if(!empty($settings['titles_noimageindex'])){
$robots['noimageindex'] = true;
}
$robots = array_merge($robots, $index_extras);
}
// static set posts page
if(is_home() && !is_front_page()){
$blog_page_id = get_option('page_for_posts');
$robots = [
'index' => true,
'follow' => true
];
if($blog_page_id){
// Check blog page specific meta settings
$robots['noindex'] = !empty(get_post_meta($blog_page_id, '_siteseo_robots_index', true));
$robots['nofollow'] = !empty(get_post_meta($blog_page_id, '_siteseo_robots_follow', true));
$robots['nosnippet'] = !empty(get_post_meta($blog_page_id, '_siteseo_robots_snippet', true));
$robots['noarchive'] = !empty(get_post_meta($blog_page_id, '_siteseo_robots_archive', true));
$robots['noimageindex'] = !empty(get_post_meta($blog_page_id, '_siteseo_robots_imageindex', true));
}
// Apply global settings as fallback
if(!empty($settings['titles_noindex'])){
$robots['noindex'] = true;
}
if(!empty($settings['titles_nofollow'])){
$robots['nofollow'] = true;
}
if(!empty($settings['titles_nosnippet'])){
$robots['nosnippet'] = true;
}
if(!empty($settings['titles_noarchive'])){
$robots['noarchive'] = true;
}
if(!empty($settings['titles_noimageindex'])){
$robots['noimageindex'] = true;
}
// Clean up conflicting directives
if(!empty($robots['noindex'])){
unset($robots['index']);
}
if(!empty($robots['nofollow'])){
unset($robots['follow']);
}
if(empty($robots['noindex'])){
$robots = array_merge($robots, $index_extras);
}
}
return array_filter($robots);
}
static function add_nositelinkssearchbox(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-titles'])){
return;
}
if(!empty($siteseo->titles_settings['titles_nositelinkssearchbox'])){
echo '<meta name="google" content="nositelinkssearchbox" >';
}
}
static function add_canonical_url(){
$post_types = siteseo_post_types();
foreach($post_types as $post_type){
if($post_type->has_archive && is_post_type_archive($post_type->name)){
$post_id = get_the_ID();
$archive_url = get_post_type_archive_link($post_type->name);
$canonical_meta = get_post_meta($post_id, '_siteseo_robots_canonical', true);
$canonical = !empty($canonical_meta) ? $canonical_meta : $archive_url;
if($archive_url){
echo '<link rel="canonical" href="'.esc_url($archive_url).'" />' . "\n";
}
}
if(is_singular($post_type->name)){
$post_id = get_the_ID();
$canonical_meta = get_post_meta($post_id, '_siteseo_robots_canonical', true);
$canonical = !empty($canonical_meta) ? $canonical_meta : urldecode(get_permalink($post_id));
if($canonical){
echo '<link rel="canonical" href="'.esc_url($canonical).'" />' . "\n";
}
}
}
//taxonomies
$taxonomies = get_taxonomies(array('public' => true), 'objects');
if(is_tag() || is_category() || is_tax()){
$term = get_queried_object();
if($term && isset($term->term_id, $term->taxonomy)){
$term_id = $term->term_id;
$taxonomy_name = $term->taxonomy;
$canonical_meta = get_term_meta($term_id, '_siteseo_robots_canonical', true);
$canonical = !empty($canonical_meta) ? $canonical_meta : urldecode(get_term_link($term_id, $taxonomy_name));
if($canonical){
echo '<link rel="canonical" href="'.esc_url($canonical).'" />' . "\n";
}
}
}
// default home page
if(is_front_page() && is_home()){
$canonical = trailingslashit(home_url());
echo '<link rel="canonical" href="'.esc_url($canonical).'" />' . "\n";
}
// if static posts set
if(is_home() && !is_front_page()){
$blog_page_id = get_option('page_for_posts');
if($blog_page_id){
$canonical_meta = get_post_meta($blog_page_id, '_siteseo_robots_canonical', true);
$canonical = !empty($canonical_meta) ? $canonical_meta : urldecode(get_permalink($blog_page_id));
if($canonical){
echo '<link rel="canonical" href="'.esc_url($canonical).'" />' . "\n";
}
} else{
$canonical = trailingslashit(home_url());
echo '<link rel="canonical" href="'.esc_url($canonical).'" />' . "\n";
}
}
}
static function replace_variables($content, $in_editor = false){
global $post, $siteseo, $wp_query, $term;
// Site info
$site_title = get_bloginfo('name');
$site_tagline = get_bloginfo('description');
$site_sep = !empty($siteseo->titles_settings['titles_sep']) ? $siteseo->titles_settings['titles_sep'] : '-';
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$page = get_query_var('page') ? get_query_var('page') : 1;
// Date info
$current_time = current_time('timestamp');
$archive_date = get_the_date('d');
$archive_month = get_the_date('M');
$archive_month_name = get_the_date('F');
$archive_year = get_the_date('Y');
// Author
$author_id = isset($post->post_author) ? $post->post_author : get_current_user_id();
$author_first_name = get_the_author_meta('first_name', $author_id);
$author_last_name = get_the_author_meta('last_name', $author_id);
$author_website = get_the_author_meta('url', $author_id);
$author_nickname = get_the_author_meta('nickname', $author_id);
$author_bio = get_the_author_meta('description', $author_id);
// WooCommerce
$wc_variables = [];
if(function_exists('wc_get_product') && is_singular('product')){
$product = wc_get_product($post->ID);
if($product){
$wc_variables = array(
'%%wc_single_cat%%' => wp_strip_all_tags(wc_get_product_category_list($post->ID)),
'%%wc_single_tag%%' => wp_strip_all_tags(wc_get_product_tag_list($post->ID)),
'%%wc_single_short_desc%%' => $product->get_short_description(),
'%%wc_single_price%%' => $product->get_price(),
'%%wc_single_price_exe_tax%%' => wc_get_price_excluding_tax($product),
'%%wc_sku%%' => $product->get_sku(),
'%%wc_parent_cat%%' => self::get_parent_category_name($post->ID),
);
}
}
//KKART
$kkart_variables = [];
if(function_exists('kkart_get_product') && is_singular('product')){
$product = kkart_get_product($post->ID);
if($product){
$kkart_variables = array(
'%%wc_single_cat%%' => wp_strip_all_tags(kkart_get_product_category_list($post->ID)),
'%%wc_single_tag%%' => wp_strip_all_tags(kkart_get_product_tag_list($post->ID)),
'%%wc_single_short_desc%%' => $product->get_short_description(),
'%%wc_single_price%%' => $product->get_price(),
'%%wc_single_price_exe_tax%%' => kkart_get_price_excluding_tax($product),
'%%wc_sku%%' => $product->get_sku(),
'%%wc_parent_cat%%' => self::get_parent_category_name($post->ID),
);
}
}
$replacements = array(
'%%sep%%' => $site_sep,
'%%sitetitle%%' => $site_title,
'%%tagline%%' => $site_tagline,
'%%post_title%%' => (is_singular() || $in_editor === TRUE) ? get_the_title() : (is_home() ? get_the_title(get_option('page_for_posts')) : ''),
'%%post_excerpt%%' => (is_singular() || $in_editor === TRUE) ? get_the_excerpt() : '',
'%%post_content%%' => (is_singular() || $in_editor === TRUE) ? wp_strip_all_tags(get_the_content()) : '',
'%%post_thumbnail_url%%' => get_the_post_thumbnail_url($post),
'%%post_url%%' => urldecode(get_permalink()),
'%%post_date%%' => get_the_date(),
'%%post_modified_date%%' => get_the_modified_date(),
'%%post_author%%' => get_the_author(),
'%%post_category%%' => wp_strip_all_tags(get_the_category_list(', ')),
'%%post_tag%%' => wp_strip_all_tags(get_the_tag_list('', ', ', '')),
'%%_category_title%%' => single_cat_title('', false),
'%%_category_description%%' => category_description(),
'%%tag_title%%' => single_tag_title('', false),
'%%tag_description%%' => tag_description(),
'%%term_title%%' => single_term_title('', false),
'%%term_description%%' => term_description(),
'%%search_keywords%%' => get_search_query(),
'%%current_pagination%%' => $paged,
'%%page%%' => $page,
'%%cpt_plural%%' => post_type_archive_title('', false),
'%%archive_title%%' => get_the_archive_title(),
'%%archive_date%%' => $archive_date,
'%%archive_date_day%%' => $archive_date,
'%%archive_date_month%%' => $archive_month,
'%%archive_date_month_name%%' => $archive_month_name,
'%%archive_date_year%%' => $archive_year,
'%%currentday%%' => date_i18n('j', $current_time),
'%%currentmonth%%' => date_i18n('F', $current_time),
'%%currentmonth_short%%' => date_i18n('M', $current_time),
'%%currentmonth_num%%' => date_i18n('n', $current_time),
'%%currentyear%%' => date_i18n('Y', $current_time),
'%%currentdate%%' => date_i18n(get_option('date_format'), $current_time),
'%%currenttime%%' => date_i18n(get_option('time_format'), $current_time),
'%%author_first_name%%' => $author_first_name,
'%%author_last_name%%' => $author_last_name,
'%%author_website%%' => $author_website,
'%%author_nickname%%' => $author_nickname,
'%%author_bio%%' => $author_bio,
);
//WooCommerces
if(!empty($wc_variables)){
$replacements = array_merge($replacements, $wc_variables);
}
//Kkart
if(!empty($kkart_variables)){
$replacements = array_merge($replacements, $kkart_variables);
}
$safe_list = [
'_siteseo_titles_title',
'_siteseo_titles_desc',
'_siteseo_social_fb_title',
'_siteseo_social_fb_desc',
'_siteseo_social_fb_img',
'_siteseo_social_twitter_title',
'_siteseo_social_twitter_desc',
'_siteseo_social_twitter_img',
// WooCommerce
'_price',
'_regular_price',
'_sale_price',
'_stock',
'_stock_status',
'_sku',
'_weight',
'_length',
'width',
'_height',
'total_sales',
];
if(preg_match_all('/%%_cf_(.*?)%%/', $content, $matches)){
foreach ($matches[1] as $custom_field) {
if(!in_array($custom_field, $safe_list, true)){
continue;
}
$meta_value = get_post_meta($post->ID, $custom_field, true);
$replacements["%%_cf_{$custom_field}%%"] = $meta_value;
}
}
if(preg_match_all('/%%_ct_(.*?)%%/', $content, $matches)){
foreach($matches[1] as $taxonomy){
if(!in_array($taxonomy, $safe_list, true)){
continue;
}
$terms = get_the_terms($post->ID, $taxonomy);
$term_names = is_array($terms) ? wp_list_pluck($terms, 'name') : [];
$replacements["%%_ct_{$taxonomy}%%"] = implode(', ', $term_names);
}
}
if(preg_match_all('/%%_ucf_(.*?)%%/', $content, $matches)){
foreach($matches[1] as $user_meta){
if(!in_array($user_meta, $safe_list, true)){
continue;
}
$meta_value = get_user_meta($author_id, $user_meta, true);
$replacements["%%_ucf_{$user_meta}%%"] = $meta_value;
}
}
$target_keywords = isset($siteseo->keywords_settings['tempory_set']) ? $siteseo->keywords_settings['tempory_set'] : '';
$replacements['%%target_keyword%%'] = $target_keywords;
$replacements = array_map(function($value){
if(is_array($value) || is_object($value)){
return '';
}
return is_null($value) ? '' : wp_strip_all_tags($value);
}, $replacements);
return str_replace(
array_keys($replacements),
array_values($replacements),
$content
);
}
static function get_parent_category_name($product_id){
if(!class_exists('WooCommerce') && !class_exists('KKART')){
return;
}
$terms = get_the_terms($product_id, 'product_cat');
if(empty($terms) || is_wp_error($terms)){
return '';
}
// Find the parent category (the one with parent = 0)
foreach($terms as $term){
if($term->parent == 0){
return $term->name;
}
}
}
static function modify_site_title($title, $sep = ''){
global $siteseo, $post;
// Check enabled
if(empty($siteseo->setting_enabled['toggle-titles'])){
return $title;
}
$settings = $siteseo->titles_settings;
// post types and taxonomies
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
// Check set by meta
$post_id = isset($post) && is_object($post) ? $post->ID : '';
$post_meta_title = !empty(get_post_meta($post_id, '_siteseo_titles_title', true)) ? get_post_meta($post_id, '_siteseo_titles_title', true) : '';
// default home page
if(is_front_page() && is_home()){
if(!empty($settings['titles_home_site_title'])){
$new_title = $settings['titles_home_site_title'];
}
if(!empty($new_title)){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
}
// static posts pages
if(is_home() && !is_front_page()){
$blog_page_id = get_option('page_for_posts');
if($blog_page_id){
$blog_meta_title = get_post_meta($blog_page_id, '_siteseo_titles_title', true);
$default_title = !empty($settings['titles_single_titles']['page']['title']) ? $settings['titles_single_titles']['page']['title'] : '';
$new_title = !empty($blog_meta_title) ? $blog_meta_title : $default_title;
if(!empty($new_title)){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
}
}
// single post types
foreach($post_types as $post_type){
if($post_type->has_archive && is_post_type_archive($post_type->name)){
$post_meta_title = '';
if(function_exists('is_shop') && is_shop()){
$shop_page_id = !defined('SITEPAD') ? wc_get_page_id('shop') : kkart_get_page_id('shop') ;
$post_meta_title = get_post_meta($shop_page_id, '_siteseo_titles_title', true);
}
$default_title = isset($settings['titles_archive_titles'][$post_type->name]['archive_title']) ? $settings['titles_archive_titles'][$post_type->name]['archive_title'] : '';
$new_title = !empty($post_meta_title) ? $post_meta_title : $default_title;
if(!empty($new_title)){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
}
if(is_singular($post_type->name)){
$default_title = isset($settings['titles_single_titles'][$post_type->name]['title']) ? $settings['titles_single_titles'][$post_type->name]['title'] : '';
$new_title = !empty($post_meta_title) ? $post_meta_title : $default_title;
if(!empty($new_title)){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
}
}
//taxonomies
foreach($taxonomies as $taxonomy){
if(is_category()){
$term = get_queried_object();
$term_id = $term->term_id;
$term_meta_title = get_term_meta($term_id, '_siteseo_titles_title', true);
$default_title = isset($settings['titles_tax_titles']['category']['title']) ? $settings['titles_tax_titles']['category']['title'] : '';
$disabled = !empty($settings['titles_tax_titles']['category']['disabled']);
$new_title = !empty($term_meta_title) ? $term_meta_title : $default_title;
if(!empty($new_title) && !$disabled){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
} elseif(is_tag()) {
$term = get_queried_object();
$term_id = $term->term_id;
$term_meta_title = get_term_meta($term_id, '_siteseo_titles_title', true);
$default_title = isset($settings['titles_tax_titles']['post_tag']['title']) ? $settings['titles_tax_titles']['post_tag']['title'] : '';
$disabled = !empty($settings['titles_tax_titles']['post_tag']['disabled']);
$new_title = !empty($term_meta_title) ? $term_meta_title : $default_title;
if(!empty($new_title) && !$disabled){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
} elseif(is_tax($taxonomy->name)) {
$term = get_queried_object();
$term_id = $term->term_id;
$term_meta_title = get_term_meta($term_id, '_siteseo_titles_title', true);
$default_title = isset($settings['titles_tax_titles'][$taxonomy->name]['title']) ? $settings['titles_tax_titles'][$taxonomy->name]['title'] : '';
$disabled = !empty($settings['titles_tax_titles'][$taxonomy->name]['disabled']);
$new_title = !empty($term_meta_title) ? $term_meta_title : $default_title;
if(!empty($new_title) && !$disabled){
$new_title = esc_attr(self::replace_variables($new_title));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
}
}
// author archive
if(is_author() && !empty($settings['titles_archives_author_title']) && empty($settings['titles_archives_author_disable'])) {
$new_title = esc_attr(self::replace_variables($settings['titles_archives_author_title']));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
//Date archive
if(is_date() && !empty($settings['titles_archives_date_title']) && empty($settings['titles_archives_date_disable'])){
$new_title = esc_attr(self::replace_variables($settings['titles_archives_date_title']));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
// Search archive
if(is_search() && !empty($settings['titles_archives_search_title'])){
$new_title = esc_attr(self::replace_variables($settings['titles_archives_search_title']));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
// 404 archive
if(is_404() && !empty($settings['titles_archives_404_title'])){
$new_title = esc_attr(self::replace_variables($settings['titles_archives_404_title']));
if(!empty($sep)){
$new_title .= " $sep " . get_bloginfo('name');
}
return $new_title;
}
return $title;
}
static function add_meta_description(){
global $siteseo, $post;
if(empty($siteseo->setting_enabled['toggle-titles'])){
return;
}
$settings = $siteseo->titles_settings;
// Get all registered post types
$post_types = siteseo_post_types();
$taxonomies = get_taxonomies(array('public' => true), 'objects');
$post_id = isset($post) && is_object($post) ? $post->ID : '';
// default home page
if(is_front_page() && is_home()){
if(!empty($settings['titles_home_site_desc'])){
$processed_desc = self::replace_variables($settings['titles_home_site_desc']);
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($processed_desc)) . '">';
} else{
$description = get_bloginfo('description');
if(!empty($description)){
echo '<meta name="description" content="' . esc_attr($description) . '">';
}
}
}
// if set static posts page
if(is_home() && !is_front_page()){
$blog_page_id = get_option('page_for_posts');
if($blog_page_id){
$meta_desc = get_post_meta($blog_page_id, '_siteseo_titles_desc', true);
if(!empty($meta_desc)){
$processed_desc = esc_attr(self::replace_variables($meta_desc));
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($processed_desc)) . '">';
} elseif(!empty($settings['titles_single_titles']['page']['description'])){
$processed_desc = self::replace_variables($settings['titles_single_titles']['page']['description']);
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($processed_desc)) . '">';
} else{
$description = get_bloginfo('description');
if(!empty($description)){
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($description)) . '">';
}
}
}
}
// single post types
foreach($post_types as $post_type){
if($post_type->has_archive && is_post_type_archive($post_type->name)){
$archive_desc = '';
if(is_post_type_archive()){
$obj = get_queried_object();
if(!empty($obj) && isset($obj->name)){
$archive_desc = !empty($obj->description) ? $obj->description : '';
}
}
$meta_desc = '';
if(function_exists('is_shop') && is_shop()){
$shop_page_id = !defined('SITEPAD') ? wc_get_page_id('shop') : kkart_get_page_id('shop');
$meta_desc = get_post_meta($shop_page_id, '_siteseo_titles_desc', true);
}
$description = !empty($settings['titles_archive_titles'][$post_type->name]['archive_desc']) ? $settings['titles_archive_titles'][$post_type->name]['archive_desc'] : $archive_desc;
$description = !empty($meta_desc) ? $meta_desc : $description;
if(!empty($description)){
$description = self::replace_variables($description);
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($description)) . '">';
}
}
if(is_singular($post_type->name)){
$meta_desc = get_post_meta($post_id, '_siteseo_titles_desc', true);
$default_desc = isset($settings['titles_single_titles'][$post_type->name]['description']) ? $settings['titles_single_titles'][$post_type->name]['description'] : '';
$description = !empty($meta_desc) ? $meta_desc : $default_desc;
if(!empty($description)){
$description = self::replace_variables($description);
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($description)) . '">';
}
}
}
if(is_category() || is_tag() || is_tax()){
$term = get_queried_object();
if($term){
$term_id = $term->term_id;
$term_meta_desc = get_term_meta($term_id, '_siteseo_titles_desc', true);
$default_desc = '';
$taxonomy_name = '';
if(is_category()){
$default_desc = isset($settings['titles_tax_titles']['category']['description']) ? $settings['titles_tax_titles']['category']['description'] : '';
$taxonomy_name = 'category';
} elseif(is_tag()){
$default_desc = isset($settings['titles_tax_titles']['post_tag']['description']) ? $settings['titles_tax_titles']['post_tag']['description'] : '';
$taxonomy_name = 'post_tag';
} else{
$taxonomy_name = $term->taxonomy;
$default_desc = isset($settings['titles_tax_titles'][$taxonomy_name]['description']) ? $settings['titles_tax_titles'][$taxonomy_name]['description'] : '';
}
$disabled = isset($settings['titles_tax_titles'][$taxonomy_name]['disabled']);
$description = !empty($term_meta_desc) ? $term_meta_desc : $default_desc;
if(!empty($disabled)){
$description = self::replace_variables($description);
echo '<meta name="description" content="' . esc_attr(self::truncate_desc($description)) . '">';
}
}
}
// Author archive
if(is_author() && !empty($settings['titles_archives_author_desc']) && empty($settings['titles_archives_author_disable'])){
$description = self::replace_variables($settings['titles_archives_author_desc']);
echo '<meta name="description" content="'.esc_attr(self::truncate_desc($description)).'" >';
}
// Date archive
if(is_date() && !empty($settings['titles_archives_date_desc']) && empty($settings['titles_archives_date_disable'])){
$description = self::replace_variables($settings['titles_archives_date_desc']);
echo '<meta name="description" content="'.esc_attr(self::truncate_desc($description)).'" >';
}
// Search archive
if(is_search() && !empty($settings['titles_archives_search_desc'])){
$description = self::replace_variables($settings['titles_archives_search_desc']);
echo '<meta name="description" content="'.esc_attr(self::truncate_desc($description)).'" >';
}
// 404 archives
if(is_404() && !empty($settings['titles_archives_404_desc'])){
$description = self::replace_variables($settings['titles_archives_404_desc']);
echo '<meta name="description" content="'.esc_attr(self::truncate_desc($description)).'" >';
}
}
static function add_rel_link_pages(){
global $siteseo, $paged;
if(empty($siteseo->setting_enabled['toggle-titles'])){
return;
}
if(!empty($siteseo->titles_settings['titles_paged_rel'])){
if(get_previous_posts_link()){
echo '<link rel="prev" href="'.esc_url(get_pagenum_link($paged - 1)).'" />';
}
if(get_next_posts_link()){
echo '<link rel="next" href="'.esc_url(get_pagenum_link($paged + 1)).'" />';
}
}
}
static function date_time_publish(){
global $siteseo;
if(empty($siteseo->setting_enabled['toggle-titles'])){
return;
}
if(!is_singular()){
return;
}
$current_post_type = get_post_type();
$type_settings = isset($siteseo->titles_settings['titles_single_titles'][$current_post_type]) ? $siteseo->titles_settings['titles_single_titles'][$current_post_type] : '';
// post type
if(!empty($type_settings['date'])){
$published_time = get_the_date('c');
$modified_time = get_the_modified_date('c');
echo '<meta property="article:published_time" content="'. esc_attr($published_time) .'">';
echo '<meta property="article:modified_time" content="'. esc_attr($modified_time) .'">';
}
// thumbnails
if(!empty($type_settings['thumb_gcs'])){
if(get_the_post_thumbnail_url(get_the_ID())){
echo '<meta name="thumbnail" content="'.esc_url(get_the_post_thumbnail_url(get_the_ID())).'">';
}
}
}
static function truncate_desc($desc){
return trim($desc);
}
}
media.php 0000644 00000057557 15152643500 0006360 0 ustar 00 <?php
namespace SoftWP;
// Are we being accessed directly ?
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Media{
static $compress_content_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp'];
static $edit_content_types = [
'image/jpeg', 'image/png', 'image/gif', 'image/svg+xml',
'image/x-ms-bmp', 'image/tiff', 'image/webp',
'image/vnd.adobe.photoshop', 'application/pdf',
'image/x-portable-pixmap', 'image/x-icon', 'image/vnd-ms.dds'
];
static $edit_quality_content_types = ['image/jpeg', 'image/png', 'image/webp'];
static function can_manage_media(){
global $post;
if(!is_admin() || !current_user_can('upload_files') || empty($post) || empty($post->ID) || $post->post_type != 'attachment'){
define('SOFTACULOUS_PRO_CAN_PHOTOPEA_EDIT', 0);
define('SOFTACULOUS_PRO_CAN_COMPRESS', 0);
define('SOFTACULOUS_PRO_CAN_REPLACE_MEDIA', 0);
return false;
}
define('SOFTACULOUS_PRO_CAN_REPLACE_MEDIA', 1);
$attachment_path = get_attached_file($post->ID);
$original_size = filesize($attachment_path);
$original_size_kb = round($original_size / 1024);
$attachment_mime_type = mime_content_type($attachment_path);
// The action buttons
if(in_array($attachment_mime_type, \SoftWP\Media::$edit_content_types)){
add_action('admin_enqueue_scripts', '\SoftWP\Media::enqueue_photopea_scripts');
define('SOFTACULOUS_PRO_CAN_PHOTOPEA_EDIT', 1);
}else{
define('SOFTACULOUS_PRO_CAN_PHOTOPEA_EDIT', 0);
}
if(0 && in_array($attachment_mime_type, \SoftWP\Media::$compress_content_types)){
add_action('admin_enqueue_scripts', '\SoftWP\Media::enqueue_compress_scripts');
define('SOFTACULOUS_PRO_CAN_COMPRESS', 1);
}else{
define('SOFTACULOUS_PRO_CAN_COMPRESS', 0);
}
return true;
}
static function can_photopea_edit(){
if(!defined('SOFTACULOUS_PRO_CAN_PHOTOPEA_EDIT')){
\SoftWP\Media::can_manage_media();
}
return SOFTACULOUS_PRO_CAN_PHOTOPEA_EDIT;
}
static function can_compress(){
if(!defined('SOFTACULOUS_PRO_CAN_COMPRESS')){
\SoftWP\Media::can_manage_media();
}
return SOFTACULOUS_PRO_CAN_COMPRESS;
}
static function can_replace_media(){
if(!defined('SOFTACULOUS_PRO_CAN_REPLACE_MEDIA')){
\SoftWP\Media::can_manage_media();
}
return SOFTACULOUS_PRO_CAN_REPLACE_MEDIA;
}
// Register the meta box
static function register_meta_box(){
if(!\SoftWP\Media::can_manage_media()){
return false;
}
add_meta_box(
'softaculous_pro_media_meta_box',
__('Action Buttons', 'softaculous-pro'),
'\SoftWP\Media::meta_box_callback',
'attachment',
'side',
'low'
);
}
// Callback function to render the meta box
static function meta_box_callback($post){
// Nonce field for security
//wp_nonce_field('softaculous_pro_media_meta_box_nonce', 'custom_nonce');
// The action buttons
if(\SoftWP\Media::can_photopea_edit()){
echo '<button type="button" class="button" id="edit_with_photopea" data-image-url="' . esc_url(wp_get_attachment_url($post->ID)) . '" data-original-image-url="' . esc_url(wp_get_attachment_url($post->ID)) . '" style="margin-right: 5px; margin-top: 10px;">'.__('Edit with Photopea', 'softaculous-pro').'</button>';
}
if(\SoftWP\Media::can_compress()){
$attachment_path = get_attached_file($post->ID);
$original_size = filesize($attachment_path);
$original_size_kb = round($original_size / 1024);
echo '<button type="button" class="button compress-image-button" data-image-id="' . $post->ID . '" data-original-size="' . $original_size_kb . '" data-image-type="' . esc_attr(get_post_mime_type($post)) . '" style="margin-right: 5px; margin-top: 10px;">'.__('Compress Image', 'softaculous-pro').'</button>';
}
if(\SoftWP\Media::can_replace_media()){
echo '<a href="' . esc_url(admin_url('upload.php?page=assistant&act=media-replace&id=' . $post->ID)) . '" class="button replace-media-button" style="margin-right: 5px; margin-top: 10px; display: inline-block;">'.__('Replace Media', 'softaculous-pro').'</a>';
}
}
//////////////////////////////////
// Edit with Photopea
//////////////////////////////////
// Function to enqueue scripts and styles for the Photopea modal
static function enqueue_photopea_scripts(){
if(!\SoftWP\Media::can_photopea_edit()){
return false;
}
add_action('admin_footer', '\SoftWP\Media::enqueue_photopea_button_script');
wp_enqueue_script('softaculous-pro-photopea-edit', SOFTACULOUS_PRO_PLUGIN_URL . 'assets/js/photopea_edit.js', ['jquery'], SOFTACULOUS_PRO_VERSION, true);
wp_localize_script('softaculous-pro-photopea-edit', 'spro_photopea', array('ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('softaculous_pro_js_nonce')));
}
// Enqueue the Photopea modal and button script in WordPress
static function enqueue_photopea_button_script(){
global $post;
if(!\SoftWP\Media::can_photopea_edit()){
return false;
}
?>
<style>
#softaculous-pro-photopea-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
z-index: 999999;
pointer-events: auto;
}
#softaculous-pro-photopea-white-bar {
position: relative;
top: 0;
left: 0;
width: 100%;
height: 30px;
background-color: white;
z-index: 1000;
}
#softaculous-pro-photopea-iframe {
width: 100%;
height: calc(100% - 80px);
border: none;
z-index: 9999;
pointer-events: auto;
}
#softaculous-pro-photopea-actions {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 50px;
background: #fff;
display: flex;
justify-content: flex-end;
align-items: center;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.2);
}
#softaculous-pro-photopea-actions .softaculous-pro-quality-section {
display: flex;
align-items: center;
margin-right: auto;
margin-left: 10px;
}
#softaculous-pro-photopea-actions .softaculous-pro-quality-section label {
margin-right: 5px;
font-size: 15px;
font-weight: bold;
color: black;
cursor:pointer;
}
#softaculous-pro-photopea-actions .softaculous-pro-quality-section input {
width: 70px;
padding: 3px;
text-align: center;
border: 1px solid #9fa1a6;
border-radius: 3px;
color:black;
}
#softaculous-pro-photopea-actions button {
padding: 8px 15px;
background-color: #0073aa;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
margin-left: 3px;
}
#softaculous-pro-photopea-actions button:hover {
background-color: #005177;
}
</style>
<div id="softaculous-pro-photopea-modal">
<div id="softaculous-pro-photopea-white-bar"></div>
<iframe id="softaculous-pro-photopea-iframe" src=""></iframe>
<div id="softaculous-pro-photopea-actions">
<div class="softaculous-pro-quality-section" id="softaculous-pro-quality-input-container" style="display: none;">
<label for="softaculous-pro-quality-input"><?php _e('Quality', 'softaculous-pro');?>: </label>
<input type="number" id="softaculous-pro-quality-input" value="100" min="1" max="100" />
</div>
<button id="softaculous-pro-save-photopea"><?php _e('Save', 'softaculous-pro');?></button>
<button id="softaculous-pro-save-close-photopea"><?php _e('Save & Close', 'softaculous-pro');?></button>
<button id="softaculous-pro-save-as-photopea"><?php _e('Save As', 'softaculous-pro');?></button>
<button id="softaculous-pro-cancel-photopea"><?php _e('Cancel', 'softaculous-pro');?></button>
</div>
</div>
<?php
}
static function upload_photopea_image() {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$jsonData = file_get_contents('php://input');
$p = json_decode($jsonData);
if(!is_admin() || !current_user_can('upload_files') || !isset($p->softaculous_pro_security) || !wp_verify_nonce(sanitize_text_field(wp_unslash($p->softaculous_pro_security)), 'softaculous_pro_js_nonce')){
wp_send_json_error(__('Security Check Failed!', 'softaculous-pro'));
}
// Check if a quality parameter is provided, defaulting to 100
$quality = isset($p->quality) ? intval($p->quality) : 100;
$quality = max(1, min($quality, 100));
$base64ImageData = $p->source;
$save_as_new = (isset($p->save_as_new) ? 1 : 0);
if(empty($save_as_new)){
$originalImageUrl = $p->original_image_url;
$attachment_id = attachment_url_to_postid($originalImageUrl);
if (!$attachment_id) {
wp_send_json_error(__("Original image attachment not found", 'softaculous-pro'));
return;
}
$filePath = get_attached_file($attachment_id);
if (!$filePath) {
wp_send_json_error(__("Original image path not found", 'softaculous-pro'));
return;
}
}else{
$newImageName = sanitize_file_name($p->new_image_name);
$extension = pathinfo($newImageName, PATHINFO_EXTENSION);
$baseFileName = pathinfo($newImageName, PATHINFO_FILENAME);
// Sanitize and create a proper path to save the new image in the uploads directory
$upload_dir = wp_upload_dir();
$filePath = $upload_dir['path'] . '/' . $newImageName;
$newFileName = basename($filePath);
if(file_exists($filePath)){
wp_send_json_error(__("File already exists. Please choose another file name", 'softaculous-pro'));
return;
}
}
// Decode the base64 image data
$imageData = base64_decode(preg_replace('/^data:image\/(jpeg|png);base64,/', '', $base64ImageData));
if ($imageData === false) {
wp_send_json_error(__("Failed to decode base64 image data", 'softaculous-pro'));
return;
}
if(empty($quality) || $quality > 99){
$saved = file_put_contents($filePath, $imageData);
}else{
// Create an image resource from the decoded data
$image = imagecreatefromstring($imageData);
if ($image === false) {
wp_send_json_error(__("Failed to create image from data", 'softaculous-pro'));
return;
}
$saved = false;
if (strpos($filePath, '.jpg') !== false || strpos($filePath, '.jpeg') !== false) {
$saved = imagejpeg($image, $filePath, $quality);
}elseif (strpos($filePath, '.png') !== false) {
$paletteImage = imagecreatetruecolor(imagesx($image), imagesy($image));
imagesavealpha($paletteImage, true);
imagealphablending($paletteImage, false);
$transparency = imagecolorallocatealpha($paletteImage, 0, 0, 0, 127);
imagecolortransparent($paletteImage, $transparency);
imagecopyresampled($paletteImage, $image, 0, 0, 0, 0, imagesx($image), imagesy($image), imagesx($image), imagesy($image));
// Reduce to a set number of colors to save space
$maxColors = ($quality < 100) ? max((int)($quality / 10), 20) : 256;
imagetruecolortopalette($paletteImage, true, $maxColors);
// Set compression level based on quality (0 = no compression, 9 = max compression)
$compressionLevel = round((100 - $quality) / 100 * 9);
// Don't pass 0 otherwise it will create image larger in size than the original one
if(empty($compressionLevel)){
$compressionLevel = 1;
}
$saved = imagepng($paletteImage, $filePath, $compressionLevel);
}elseif (strpos($filePath, '.webp') !== false) {
$saved = imagewebp($image, $filePath, $quality);
}else{
wp_send_json_error(__("Unsupported image format", 'softaculous-pro'));
return;
}
imagedestroy($image);
}
if (!$saved) {
wp_send_json_error(__("Failed to save the image", 'softaculous-pro'));
return;
}
if(!empty($save_as_new)){
// Attach the new file to the WordPress media library
$attachment = array(
'guid' => $upload_dir['url'] . '/' . basename($filePath),
'post_mime_type' => mime_content_type($filePath),
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filePath)),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment($attachment, $filePath);
if(is_wp_error($attachment_id)) {
wp_send_json_error(__("Failed to insert the new image as attachment", 'softaculous-pro'));
}
}
$metadata = wp_generate_attachment_metadata($attachment_id, $filePath);
if (is_wp_error($metadata)) {
wp_send_json_error(__("Failed to regenerate image sub-sizes", 'softaculous-pro'));
}
wp_update_attachment_metadata($attachment_id, $metadata);
$new_image_url = wp_get_attachment_url($attachment_id);
wp_send_json_success(array(
'new_image_url' => $new_image_url,
'message' => __('Image saved successfully', 'softaculous-pro'),
));
}
}
//////////////////////////////////
// Compress Image
//////////////////////////////////
static function enqueue_compress_scripts(){
if(!\SoftWP\Media::can_compress()){
return false;
}
wp_enqueue_script('softaculous_pro_enqueue_compress_scripts', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/js/compress_image.js', ['jquery'], SOFTACULOUS_PRO_VERSION, true);
wp_localize_script('softaculous_pro_enqueue_compress_scripts', 'spro_compress', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('softaculous_pro_js_nonce')
));
}
static function calculate_compressed_size() {
if(!is_admin() || !current_user_can('upload_files') || !isset($_POST['softaculous_pro_security']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['softaculous_pro_security'])), 'softaculous_pro_js_nonce')){
wp_send_json_error(__('Security Check Failed!', 'softaculous-pro'));
}
if (isset($_POST['image_id'])) {
$image_id = intval($_POST['image_id']);
$image_path = get_attached_file($image_id);
if ($image_path) {
$compressed_image_path = \SoftWP\Media::compress_image($image_path, 40, false);
$compressed_size = round(filesize($compressed_image_path) / 1024);
wp_send_json_success(array('compressed_size' => $compressed_size));
}else {
wp_send_json_error(__('Invalid image path.', 'softaculous-pro'));
}
}else {
wp_send_json_error(__('No image ID provided.', 'softaculous-pro'));
}
}
static function compress_image($image_path, $quality, $save_image = true) {
$info = getimagesize($image_path);
$compressed_image_path = '';
if ($info['mime'] == 'image/jpeg') {
$image = imagecreatefromjpeg($image_path);
$compressed_image_path = $save_image ? $image_path : str_replace('.jpg', '-temp.jpg', $image_path);
imagejpeg($image, $compressed_image_path, $quality);
}elseif ($info['mime'] == 'image/png') {
$image = imagecreatefrompng($image_path);
$compressed_image_path = $save_image ? $image_path : str_replace('.png', '-temp.png', $image_path);
// Convert to a palette-based image to reduce bit depth
$paletteImage = imagecreatetruecolor(imagesx($image), imagesy($image));
imagecopy($paletteImage, $image, 0, 0, 0, 0, imagesx($image), imagesy($image));
// Reduce to a set number of colors to save space
$maxColors = ($quality < 100) ? max((int)($quality / 10), 20) : 256;
imagetruecolortopalette($paletteImage, true, $maxColors);
// Set compression level based on quality (0 = no compression, 9 = max compression)
$compressionLevel = ($quality < 100) ? 9 - (int)($quality / 10) : 9;
imagepng($paletteImage, $compressed_image_path, $compressionLevel);
}elseif ($info['mime'] == 'image/webp') {
$image = imagecreatefromwebp($image_path);
$compressed_image_path = $save_image ? $image_path : str_replace('.webp', '-temp.webp', $image_path);
imagewebp($image, $compressed_image_path, $quality);
}else {
return __('Unsupported image type.', 'softaculous-pro');
}
return $compressed_image_path;
}
static function replace_compressed_image() {
if(!is_admin() || !current_user_can('upload_files') || !isset($_POST['softaculous_pro_security']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['softaculous_pro_security'])), 'softaculous_pro_js_nonce')){
wp_send_json_error(__('Security Check Failed!', 'softaculous-pro'));
}
if (isset($_POST['image_id'])) {
$image_id = intval($_POST['image_id']);
$image_path = get_attached_file($image_id);
if ($image_path) {
$compressed_image_path = \SoftWP\Media::compress_image($image_path, 40, true);
if ($compressed_image_path) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($image_id, $compressed_image_path);
wp_update_attachment_metadata($image_id, $attach_data);
$new_image_url = wp_get_attachment_url($image_id);
wp_send_json_success(array('message' => __('Image has been successfully compressed and replaced.', 'softaculous-pro'), 'new_image_url' => $new_image_url));
}else {
wp_send_json_error(__('Compression and replacement failed.', 'softaculous-pro'));
}
}else {
wp_send_json_error(__('Invalid image path.', 'softaculous-pro'));
}
}else {
wp_send_json_error(__('No image ID provided.', 'softaculous-pro'));
}
}
//////////////////////////////////
// Replace Media
//////////////////////////////////
// Add Replace Media link on Media page in List Mode
static function add_media_row_action($actions, $post){
if(!\SoftWP\Media::can_replace_media()){
return $actions;
}
$url = admin_url('upload.php');
$url = add_query_arg(array(
'page' => 'assistant',
'act' => 'media-replace',
'id' => $post->ID,
), $url);
$actions['softaculous_pro_replace_media'] = '<a href="'.esc_url($url).'" rel="permalink">'.esc_html__('Replace Media', 'softaculous_pro').'</a>';
// Remove it from Pagelayer as we are adding our own
if(isset($actions['pagelayer_replace_media'])){
unset($actions['pagelayer_replace_media']);
}
return $actions;
}
//function is called first to select the route
static function replace_media_page(){
global $pl_error;
if(!current_user_can('upload_files')){
wp_die(esc_html__('You do not have permission to upload files.', 'softaculous-pro'));
}
$post_id = (int) $_GET['id'];
if(empty($post_id)){
wp_die(esc_html__('Invalid Media ID', 'softaculous-pro'));
}
// Load the attachment
$post = get_post($post_id);
if(empty($post) || is_wp_error($post)){
wp_die(esc_html__('Media not found', 'softaculous-pro'));
}
// Process the POST !
if(isset($_FILES['userfile'])){
if(!check_admin_referer('softaculous-pro-media')){
wp_die('Invalid Nonce');
}
/** Check if file is uploaded properly **/
if(!is_uploaded_file($_FILES['userfile']['tmp_name'])){
$pl_error['upload_error'] = __('No file was uploaded ! Please try again.', 'softaculous-pro');
\SoftWP\Media::replace_media_theme();
return;
}
if(isset($_FILES['userfile']['error']) && $_FILES['userfile']['error'] > 0){
$pl_error['upload_error'] = __('There was some error uploading the file ! Please try again.', 'softaculous-pro');
\SoftWP\Media::replace_media_theme();
return;
}
$filedata = wp_check_filetype_and_ext($_FILES['userfile']['tmp_name'], $_FILES['userfile']['name']);
if ($filedata['ext'] == false){
$pl_error['ext_error'] = __('The File type could not be determined. Please upload a permitted file type.', 'softaculous-pro');
\SoftWP\Media::replace_media_theme();
return;
}
$result = \SoftWP\Media::replace_attachment($_FILES['userfile']['tmp_name'], $post_id, $err);
if(empty($result)){
$pl_error['replace_error'] = $err;
\SoftWP\Media::replace_media_theme();
return;
}
$redirect_success = admin_url('post.php');
$redirect_success = add_query_arg(array(
'action' => 'edit',
'post' => $post_id,
), $redirect_success);
echo '<meta http-equiv="refresh" content="0;url='.$redirect_success.'" />';
}
// Show the theme
\SoftWP\Media::replace_media_theme();
}
// Report an error
static function report_error($error = array()){
if(empty($error)){
return true;
}
$error_string = '<b>'.__('Please fix the below errors', 'softaculous-pro').' :</b> <br />';
foreach($error as $ek => $ev){
$error_string .= '* '.$ev.'<br />';
}
echo '<div id="message" class="error"><p>'
. __($error_string, 'softaculous-pro')
. '</p></div>';
}
// Theme of the page
static function replace_media_theme(){
global $pl_error;
\SoftWP\Media::report_error($pl_error);echo '<br />';
$id = (int) $_GET['id'];
?>
<div class="wrap">
<h1><?php echo esc_html__("Replace Media File", 'softaculous-pro'); ?></h1>
<form enctype="multipart/form-data" method="POST">
<div class="editor-wrapper">
<section class="image_chooser wrapper">
<input type="hidden" name="ID" id="ID" value="<?php echo $id ?>" />
<p><?php echo esc_html__("Choose a file to upload from your computer", 'softaculous-pro'); ?></p>
<div class="drop-wrapper">
<p><input type="file" name="userfile" id="userfile" /></p>
<?php wp_nonce_field('softaculous-pro-media'); ?>
</div>
</section>
<section class="form_controls wrapper">
<input id="submit" type="submit" class="button button-primary" name="submit" value="<?php echo esc_attr__("Upload", 'softaculous-pro');?>" />
</section>
</div>
</form>
<?php
}
// Replace the uploaded media with the new one
static function replace_attachment($file, $post_id, &$error = ''){
if(!current_user_can('upload_files')){
wp_die(esc_html__('You do not have permission to upload files.', 'softaculous-pro'));
}
if(function_exists('wp_get_original_image_path')){
$targetFile = wp_get_original_image_path($post_id);
}else{
$targetFile = trim(get_attached_file($post_id));
}
$fileparts = pathinfo($targetFile);
$filePath = isset($fileparts['dirname']) ? trailingslashit($fileparts['dirname']) : '';
$fileName = isset($fileparts['basename']) ? $fileparts['basename'] : '';
$filedata = wp_check_filetype_and_ext($targetFile, $fileName);
$fileMime = (isset($filedata['type'])) ? $filedata['type'] : false;
$permissions = fileperms($targetFile) & 0644;
if(empty($targetFile)){
$error = __('Failed to determine the media file path !', 'softaculous-pro');
return false;
}
if(empty($filePath)){
$error = __('No folder for the target found !', 'softaculous-pro');
return false;
}
// Remove the files of the original attachment
\SoftWP\Media::remove_attachment_files($post_id);
$result_moved = move_uploaded_file($file, $targetFile);
if (false === $result_moved){
$error = sprintf( esc_html__('The uploaded file could not be moved to %1$s. This is most likely an issue with permissions, or upload failed.', 'softaculous-pro'), $targetFile );
return false;
}
if ($permissions > 0){
chmod( $targetFile, $permissions ); // restore permissions
}
$updated = update_attached_file($post_id, $targetFile);
$target_url = wp_get_attachment_url($post_id);
// Run the filter, so other plugins can hook if needed.
$filtered = apply_filters( 'wp_handle_upload', array(
'file' => $targetFile,
'url' => $target_url,
'type' => $fileMime,
), 'sideload');
// Check if file changed during filter. Set changed to attached file meta properly.
if (isset($filtered['file']) && $filtered['file'] != $targetFile ){
update_attached_file($post_id, $filtered['file']);
}
$metadata = wp_generate_attachment_metadata($post_id, $targetFile);
wp_update_attachment_metadata($post_id, $metadata);
return true;
}
static function remove_attachment_files($post_id){
if(!current_user_can('upload_files')){
wp_die(esc_html__('You do not have permission to upload files.', 'softaculous-pro'));
}
$meta = wp_get_attachment_metadata( $post_id );
if (function_exists('wp_get_original_image_path')){ // WP 5.3+
$fullFilePath = wp_get_original_image_path($post_id);
}else{
$fullFilePath = trim(get_attached_file($post_id));
}
$backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
$file = $fullFilePath;
$result = wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
// If attached file is not the same path as file, this indicates a -scaled images is in play.
$attached_file = get_attached_file($post_id);
if ($file !== $attached_file && file_exists($attached_file)){
@unlink($attached_file);
}
}
}
setup.php 0000644 00000023414 15152643500 0006422 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
$steps = array(
'welcome' => __('Welcome', 'softaculous-pro'),
'type' => __('Business Type','softaculous-pro'),
'title' => __('Site Title','softaculous-pro'),
'features' => __('Goals','softaculous-pro'),
'import_theme' => __('Choose Template','softaculous-pro'),
);
$active_step = isset($_GET['step']) && array_key_exists($_GET['step'], $steps) ? $_GET['step'] : 'welcome';
include_once(dirname(__FILE__).'/onboarding.php');
$softaculous_pro['templates'] = softaculous_pro_get_templates_list();
$spro_setup_info = get_option('softaculous_pro_setup_info');
$spro_onboarding_done = get_option('softaculous_pro_onboarding_done');
update_option('softaculous_pro_onboarding_shown', time());
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$installed_plugins = get_plugins();
if(!empty($softaculous_pro['branding']['default_hf_bg'])){
echo '
<style>
.softaculous-pro-wizard-sidebar {
background-color:'.$softaculous_pro['branding']['default_hf_bg'].' !important;
}
</style>';
}
if(!empty($softaculous_pro['branding']['default_hf_text'])){
echo '
<style>
.softaculous-pro-wizard-steps li, .softaculous-pro-wizard-steps li::before {
color:'.$softaculous_pro['branding']['default_hf_text'].' !important;
border-color:'.$softaculous_pro['branding']['default_hf_text'].' !important;
}
.softaculous_pro_return_btn span, .dashicons-exit::before {
color:'.$softaculous_pro['branding']['default_hf_text'].' !important;
}
</style>';
}
?>
<style>
*,
*::before,
*::after {
box-sizing: content-box;
}
</style>
<div class="softaculous-pro-wizard">
<div class="softaculous-pro-wizard-sidebar">
<div class="softaculous-pro-setup-logo">
<a href="<?php echo admin_url('admin.php?page=assistant&act=onboarding'); ?>">
<img src="<?php echo esc_attr($softaculous_pro['branding']['logo_url']);?>" style="max-width:200px;" />
</a>
</div>
<div class="softaculous-pro-steps-holder">
<ol class="softaculous-pro-wizard-steps">
<?php foreach ($steps as $key => $name) : ?>
<a href="admin.php?page=assistant&act=onboarding&step=<?php echo $key; ?>"><li class="<?php echo ($key == $active_step ? 'active_step' : ''); ?>"><span
data-step="<?php echo $key; ?>"><?php echo $name; ?></span></li>
</a>
<?php endforeach; ?>
</ol>
</div>
<a class="softaculous_pro_return_btn" style="cursor:pointer;" onclick="return softaculous_pro_onboarding_dismiss(event);">
<span class="dashicons dashicons-exit"></span><span><?php _e('Exit', 'softaculous-pro'); ?></span></a>
</div>
<div class="softaculous-pro-wizard-content" data-active-panel="<?php echo $active_step; ?>">
<!-- Step Welcome -->
<div class="softaculous-pro-wizard-inner" data-panel="welcome">
<div class="softaculous-pro-wizard-inner-content">
<h1><?php _e('Welcome to the Onboarding process!', 'softaculous-pro'); ?></h1>
<p><?php _e('This process will help you choose a professional template for your website and install plugins that you might need to achieve your goal for creating this website', 'softaculous-pro'); ?>
</p>
<?php if (!empty($spro_onboarding_done)): ?>
<div class="softaculous-pro-wizard-buttons">
<input type="checkbox" id="onboarding_done_confirm" name="onboarding_done_confirm" style="margin:0px;" />
<label for="onboarding_done_confirm" style="cursor:pointer;"><?php _e('It looks like you have already completed the onboarding process. You might lose data if you run the onboarding process again. Select this checkbox to confirm that you agree.', 'softaculous-pro'); ?></label>
</div>
<?php endif; ?>
<div class="softaculous-pro-wizard-buttons">
<button class="step_btn step_next_btn" data-step="type"
onclick="softaculous_pro_next_handler(this)"><?php _e('Get Started', 'softaculous-pro'); ?><span
class="dashicons dashicons-arrow-right-alt"></span></button>
<button class="step_btn step_next_btn step_dismiss_btn" data-step="type"
onclick="softaculous_pro_onboarding_dismiss(event);"><?php _e('No, I don\'t want to try an easy setup process', 'softaculous-pro'); ?><span
class="dashicons dashicons-no-alt"></span></button>
</div>
</div>
</div>
<!-- Step Type -->
<div class="softaculous-pro-wizard-inner" data-panel="type">
<div class="softaculous-pro-wizard-inner-content">
<h1><?php _e('How would you categorize your website ?', 'softaculous-pro'); ?></h1>
<p><?php _e('This helps us recommend design and functionalities for your website', 'softaculous-pro'); ?></p>
</div>
<div class="softaculous-pro-category-input">
<input type="text" class="softaculous_pro_input" id="cat_input" placeholder="<?php _e('Search for a category', 'softaculous-pro'); ?>" />
</div>
<div class="softaculous-pro-category-holder">
<div class="softaculous-pro-categories-list">
<?php foreach ($softaculous_pro['templates']['categories'] as $cslug => $cdata) : ?>
<div class="category_btn">
<input type="button" id="cat_button_<?php echo $cslug; ?>" value= <?php echo esc_html($cdata['en']); ?> data-target=<?php echo $cslug; ?> />
</div>
<?php endforeach; ?>
<div id="spro_no_cat_results" style="display:none;">
<h3><i><?php echo __('No results match your search criteria', 'softaculous-pro'); ?></i></h3>
</div>
</div>
</div>
<br /><br />
<div class="softaculous-pro-wizard-buttons">
<button onclick="softaculous_pro_prev_handler(this)" data-step="welcome"
class="step_btn step_prev_btn"><?php _e('Previous Step', 'softaculous-pro'); ?></button>
<button class="step_btn step_next_btn" data-step="title"
onclick="softaculous_pro_next_handler(this)"><?php _e('Continue', 'softaculous-pro'); ?> <span
class="dashicons dashicons-arrow-right-alt"></span></button>
</div>
</div>
<!-- Step Title -->
<div class="softaculous-pro-wizard-inner" data-panel="title">
<div class="softaculous-pro-wizard-inner-content">
<h1><?php _e('Enter the title of your new site', 'softaculous-pro'); ?></h1>
<p><?php _e('Can be changed later', 'softaculous-pro'); ?></p>
</div>
<div class="softaculous-pro-title-input">
<input type="text" class="softaculous_pro_input" placeholder="<?php _e('Enter a title for your website', 'softaculous-pro'); ?>" value="<?php echo esc_html(get_bloginfo('name')); ?>" autocomplete="off"/>
</div>
<div class="softaculous-pro-wizard-buttons">
<button onclick="softaculous_pro_prev_handler(this)" data-step="type"
class="step_btn step_prev_btn"><?php _e('Previous Step', 'softaculous-pro'); ?></button>
<button class="step_btn step_next_btn" data-step="features"
onclick="softaculous_pro_next_handler(this)"><?php _e('Continue', 'softaculous-pro'); ?><span
class="dashicons dashicons-arrow-right-alt"></span></button>
</div>
</div>
<!-- Step Features -->
<div class="softaculous-pro-wizard-inner" data-panel="features">
<div class="softaculous-pro-wizard-inner-content">
<h1><?php _e('What are you looking to achieve with your new site ?', 'softaculous-pro'); ?></h1>
<p><?php _e('We will install the appropriate plugins that will add the required functionality to your website', 'softaculous-pro'); ?></p>
</div>
<div class="softaculous-pro-features-container">
<?php foreach(spro_get_features_list() as $slug => $feature):?>
<label for="<?php echo $slug;?>_input" style="cursor:pointer;">
<div class="softaculous-pro-features" data-slug="<?php echo $slug; ?>">
<div class="softaculous-pro-features-icon">
<span class="<?php echo $feature['icon']; ?>"></span>
</div>
<div class="softaculous-pro-features-text">
<h3><?php echo $feature['name']; ?></h3>
<p><?php echo $feature['info']; ?></p>
</div>
<div class="softaculous-pro-features-input">
<input type="checkbox" onclick="softaculous_pro_selected_features(this)" id="<?php echo $slug;?>_input" <?php echo (!empty($spro_setup_info) && !empty($spro_setup_info['features']) && in_array($slug, $spro_setup_info['features']) ? 'checked="checked"' : '') ;
foreach($feature['plugin'] as $info){
if (!empty($info['requires_php']) && version_compare(PHP_VERSION, $info['requires_php'], '<')) {
echo ' disabled';
echo ' spro-erro="'.sprintf(__('Requires PHP version %1$s or higher', 'softaculous-pro'), $info['requires_php']).'"';
break;
}
echo (!empty($installed_plugins[$info['plugin_init']]) ? 'checked="checked"' : '');
} ?>/>
</div>
</div>
</label>
<?php endforeach; ?>
</div>
<div class="softaculous-pro-wizard-buttons">
<button onclick="softaculous_pro_prev_handler(this)" data-step="title"
class="step_btn step_prev_btn"><?php _e('Previous Step', 'softaculous-pro'); ?> </button>
<button class="step_btn step_next_btn" data-step="import_theme"
onclick="softaculous_pro_next_handler(this)"><?php _e('Continue', 'softaculous-pro'); ?> <span
class="dashicons dashicons-arrow-right-alt"></span></button>
</div>
</div>
<!-- Step Import theme -->
<div class="softaculous-pro-wizard-inner" data-panel="import_theme">
<?php
softaculous_pro_templates();
?>
</div>
</div>
</div>
license.php 0000644 00000010167 15152643500 0006705 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
include_once SPEEDYCACHE_DIR . '/main/settings.php';
function speedycache_license_page(){
global $speedycache;
if(isset($_REQUEST['save_speedycache_license'])){
speedycache_license();
}
speedycache_add_javascript();
settings_errors('speedycache-notice');
?>
<div class="speedycache-setting-content">
<div class="speedycache-tab-group" style="width:78%">
<table class="wp-list-table fixed striped users speedycache-license-table" cellspacing="1" border="0" width="78%" cellpadding="10" align="center">
<tbody>
<tr>
<th align="left" width="25%"><?php esc_html_e('SpeedyCache Version', 'speedycache'); ?></th>
<td><?php
echo SPEEDYCACHE_PRO_VERSION.(defined('SPEEDYCACHE_PRO') ? ' (Pro Version)' : '');
?>
</td>
</tr>
<tr>
<th align="left" valign="top"><?php esc_html_e('SpeedyCache License', 'speedycache'); ?></th>
<td align="left">
<form method="post" action="">
<span style="color:var(--speedycache-red)">
<?php echo (defined('SPEEDYCACHE_PRO') && empty($speedycache->license) ? '<span style="color:var(--speedycache-red)">Unlicensed</span> ' : '')?>
</span>
<input type="hidden" name="speedycache_license_nonce" value="<?php echo wp_create_nonce('speedycache_license');?>"/>
<input type="text" name="speedycache_license" value="<?php echo (empty($speedycache->license) ? empty($_POST['speedycache_license']) ? '' : speedycache_optpost('speedycache_license') : $speedycache->license['license'])?>" size="30" placeholder="e.g. SPDFY-11111-22222-33333-44444" style="width:300px;">
<input name="save_speedycache_license" class="speedycache-btn speedycache-btn-primary" value="Update License" type="submit">
</form>
<?php if(!empty($speedycache->license)){
$expires = $speedycache->license['expires'];
$expires = substr($expires, 0, 4).'/'.substr($expires, 4, 2).'/'.substr($expires, 6);
echo '<div style="margin-top:10px;">License Status : '.(empty($speedycache->license['status_txt']) ? 'N.A.' : wp_kses_post($speedycache->license['status_txt'])).'
'.($speedycache->license['expires'] <= date('Ymd') ? 'License Expires : <span style="color:var(--speedycache-red)">'.esc_attr($expires).'</span>' : (empty($speedycache->license['has_plid']) ? 'License Expires : ' . esc_html($expires) : '')).'
</div>';
}?>
</td>
</tr>
<tr>
<th align="left">URL</th>
<td><?php echo get_site_url(); ?></td>
</tr>
<tr>
<th align="left">Path</th>
<td><?php echo ABSPATH; ?></td>
</tr>
<tr>
<th align="left">Server's IP Address</th>
<td><?php echo esc_html($_SERVER['SERVER_ADDR']); ?></td>
</tr>
<tr>
<th align="left">.htaccess is writable</th>
<td><?php echo (is_writable(ABSPATH.'/.htaccess') ? '<span style="color:var(--speedycache-red)">Yes</span>' : '<span style="color:green">No</span>');?></td>
</tr>
</tbody>
</table>
</div>
<?php speedycache_promotion_tmpl(); ?>
</div>
<?php
speedycache_page_footer(true);
}
function speedycache_license(){
global $speedycache, $lic_resp;
if(!wp_verify_nonce($_POST['speedycache_license_nonce'], 'speedycache_license')){
speedycache_notify(array(__('Security Check Failed', 'speedycache'),'error'));
return;
}
$license = sanitize_key($_POST['speedycache_license']);
if(empty($license)){
speedycache_notify(array(__('The license key was not submitted', 'speedycache'),'error'));
return;
}
speedycache_pro_load_license($license);
if(!is_array($lic_resp)){
speedycache_notify(array(__('The response was malformed<br>'.var_export($lic_resp, true), 'speedycache'), 'error'));
return;
}
$json = json_decode($lic_resp['body'], true);
// Save the License
if(empty($json['license'])){
speedycache_notify(array(__('The license key is invalid', 'speedycache'), 'error'));
return;
}
}
functions.php 0000644 00000065434 15152643500 0007302 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
$softaculous_pro_settings = get_option('softaculous_pro_settings', array());
if(!empty($softaculous_pro_settings['disable_comments'])){
include_once SOFTACULOUS_PRO_PLUGIN_PATH . '/main/disable-comments.php';
}
if(is_admin() && empty($softaculous_pro_settings['disable_ai'])){
add_action('enqueue_block_editor_assets', '\SoftWP\AI::enqueue_scripts');
// AJAX ACTIONS
add_action('wp_ajax_softaculous_ai_generation', '\SoftWP\AI::generate');
add_action('wp_ajax_softaculous_ai_history', '\SoftWP\AI::load_history');
}
$spro_page = softaculous_pro_optGET('page');
if(is_admin() && !empty($spro_page) && $spro_page == 'assistant'){
$spro_act = softaculous_pro_optGET('act');
if(!empty($spro_act) && $spro_act == 'onboarding'){
include_once(SOFTACULOUS_PRO_PLUGIN_PATH . '/main/onboarding.php');
}
}
function softaculous_pro_activation_hook(){
softaculous_pro_update_check();
}
function softaculous_pro_deactivation_hook() {
}
function softaculous_pro_uninstall_hook() {
delete_option('softaculous_pro_version');
delete_option('softaculous_pro_settings');
delete_option('softaculous_pro_onboarding_notice_dismiss');
delete_option('softaculous_pro_ai_notice_dismiss');
delete_option('softaculous_pro_onboarding_done');
delete_option('softaculous_pro_onboarding_dismiss');
delete_option('softaculous_pro_setup_info');
delete_option('softaculous_pro_onboarding_shown');
wp_clear_scheduled_hook('softaculous_pro_ai_history_cron');
}
function softaculous_pro_load_plugin(){
global $softaculous_pro, $softaculous_pro_settings, $spro_tours;
add_action('softaculous_pro_ai_history_cron', '\SoftWP\AI::delete_history'); // Cron for AI History deletion
if(!is_admin()){
return false;
}
// Do we have to redirect the user to onboarding ?
if(is_admin() && current_user_can('administrator') && !wp_doing_ajax() && (empty($_GET['act']) || ($_GET['act'] != 'onboarding' && $_GET['act'] != 'license'))){
$spro_is_dismissed = get_option('softaculous_pro_onboarding_dismiss');
$spro_is_done = get_option('softaculous_pro_onboarding_done');
$spro_is_shown = get_option('softaculous_pro_onboarding_shown');
if(empty($spro_is_dismissed) && empty($spro_is_done) && empty($spro_is_shown)){
wp_safe_redirect(admin_url('admin.php?page=assistant&act=onboarding'));
exit(0);
}
}
softaculous_pro_load_license();
softaculous_pro_rebranding();
// Show key details in Plugins data
add_filter('plugin_row_meta', 'softaculous_pro_add_plugin_row_links', 10, 2);
// Check for updates
include_once(SOFTACULOUS_PRO_PLUGIN_PATH.'/lib/plugin-update-checker.php');
$softaculous_pro_updater = SoftaculousPro_PucFactory::buildUpdateChecker(softaculous_pro_api_url().'updates.php?version='.SOFTACULOUS_PRO_VERSION.'&url='.rawurlencode(site_url()), SOFTACULOUS_PRO_FILE);
// Add the license key to query arguments
$softaculous_pro_updater->addQueryArgFilter('softaculous_pro_updater_filter_args');
// Show the text to install the license key
add_filter('puc_manual_final_check_link-softaculous-pro', 'softaculous_pro_updater_check_link', 10, 1);
softaculous_pro_update_check();
// Register AI Post type
add_action('init', 'softaculous_pro_register_post_type');
$spro_tours = array('assistant' => 'admin.php?page=assistant', 'sidebar' => 'admin.php?page=assistant', 'dashboard' => 'index.php', 'plugins' => 'plugins.php', 'themes' => 'themes.php', 'users' => 'users.php', 'pages' => 'edit.php?post_type=page', 'posts' => 'edit.php');
// Enqueues scripts and styles
if(softaculous_pro_can_enqueue_assets()){
add_action('admin_init', 'softaculous_pro_admin');
add_action('admin_enqueue_scripts', 'softaculous_pro_enqueue_scripts');
}
if(is_admin() && !empty($_GET['page']) && $_GET['page'] == 'assistant'){
add_filter('screen_options_show_screen', '__return_false');
}
add_action('admin_notices', 'softaculous_pro_license_notice');
// Are you the Admin ?
if(current_user_can('administrator')){
if(softaculous_pro_is_display_notice()){
add_action('admin_notices', 'softaculous_pro_admin_notice');
}
add_action('wp_ajax_softaculous_pro_dismissnotice', 'softaculous_pro_dismiss_notice');
// This adds the left menu in WordPress Admin page
add_action('admin_menu', 'softaculous_pro_admin_menu', 5);
include_once SOFTACULOUS_PRO_PLUGIN_PATH . '/main/admin.php';
add_action('admin_print_footer_scripts', 'softaculous_pro_assistant', 5);
add_action('wp_ajax_softaculous_pro_wp_ajax', 'softaculous_pro_wp_ajax');
add_action('admin_menu', 'softaculous_pro_remove_admin_elements');
// Template Installation related ajax calls
add_action('wp_ajax_softaculous_pro_template_info', 'softaculous_pro_templates_ajax');
add_action('wp_ajax_softaculous_pro_start_install_template', 'softaculous_pro_templates_ajax');
add_action('wp_ajax_softaculous_pro_selected_plugin_install', 'softaculous_pro_templates_ajax');
add_action('wp_ajax_softaculous_pro_download_template', 'softaculous_pro_templates_ajax');
add_action('wp_ajax_softaculous_pro_import_template', 'softaculous_pro_templates_ajax');
// Setup information
add_action('wp_ajax_softaculous_pro_setup_info', 'softaculous_pro_templates_ajax');
// dismiss
add_action('wp_ajax_softaculous_pro_onboarding_dismiss', 'softaculous_pro_templates_ajax');
add_action('wp_ajax_softaculous_pro_option_value', 'softaculous_pro_templates_ajax');
}
// Manage Media hooks
if(is_admin() && empty($softaculous_pro_settings['disable_manage_media']) && current_user_can('upload_files') /* && !empty($post) && !empty($post->post_type) && $post->post_type == 'attachment' */){
add_action('add_meta_boxes_attachment', '\SoftWP\Media::register_meta_box');
add_filter('media_row_actions', '\SoftWP\Media::add_media_row_action', 11, 2);
// ajax calls
add_action('wp_ajax_softaculous_pro_upload_photopea_image', '\SoftWP\Media::upload_photopea_image');
add_action('wp_ajax_softaculous_pro_calculate_compressed_size', '\SoftWP\Media::calculate_compressed_size');
add_action('wp_ajax_softaculous_pro_replace_compressed_image', '\SoftWP\Media::replace_compressed_image');
}
}
function softaculous_pro_templates_ajax() {
if(!current_user_can('administrator')){
return false;
}
include_once(dirname(__FILE__).'/onboarding.php');
if($_REQUEST['action'] == 'softaculous_pro_template_info'){
softaculous_pro_ajax_template_info();
}
if($_REQUEST['action'] == 'softaculous_pro_selected_plugin_install'){
softaculous_pro_ajax_selected_plugin();
}
if($_REQUEST['action'] == 'softaculous_pro_start_install_template'){
softaculous_pro_ajax_start_install_template();
}
if($_REQUEST['action'] == 'softaculous_pro_download_template'){
softaculous_pro_ajax_download_template();
}
if($_REQUEST['action'] == 'softaculous_pro_import_template'){
softaculous_pro_ajax_import_template();
}
if($_REQUEST['action'] == 'softaculous_pro_setup_info'){
softaculous_pro_save_setup_info();
}
if($_REQUEST['action'] == 'softaculous_pro_option_value'){
softaculous_pro_get_options();
}
if($_REQUEST['action'] == 'softaculous_pro_onboarding_dismiss'){
softaculous_pro_onboarding_dismiss();
}
}
function softaculous_pro_remove_admin_elements(){
if(!empty($_GET['page']) && $_GET['page'] === 'assistant'){
remove_all_actions('admin_notices');
remove_all_actions('all_admin_notices');
}
}
// Update check
function softaculous_pro_update_check(){
global $softaculous_pro_settings;
$current_version = get_option('softaculous_pro_version', 0);
$version = (int) str_replace('.', '', $current_version);
if($current_version == SOFTACULOUS_PRO_VERSION){
return true;
}
// AI is enabled by default so the cron to delete AI history should be added at activation.
wp_schedule_event(time(), 'daily', 'softaculous_pro_ai_history_cron');
if(empty($softaculous_pro_settings) || !isset($softaculous_pro_settings['ai_history_duration'])){
$softaculous_pro_settings['ai_history_duration'] = 90; // Setting default AI history duration.
update_option('softaculous_pro_settings', $softaculous_pro_settings);
}
// Save the new Version
update_option('softaculous_pro_version', SOFTACULOUS_PRO_VERSION);
}
function softaculous_pro_admin(){
global $spro_tours;
include_once SOFTACULOUS_PRO_PLUGIN_PATH . '/main/admin.php';
}
// Shows the admin menu of Softaculous
function softaculous_pro_admin_menu() {
$capability = 'activate_plugins';// TODO : Capability for accessing this page
// Add the menu page
add_menu_page(__('Assistant'), __('Assistant', 'softaculous-pro'), $capability, 'assistant', 'softaculous_pro_page_handler', 'dashicons-businessperson', 1);
}
// The Softaculous Settings Page
function softaculous_pro_page_handler(){
global $softaculous_pro;
if(!current_user_can('manage_options')){
wp_die(__('Sorry, but you do not have permissions to change settings.', 'softaculous-pro'));
}
$act = softaculous_pro_optGET('act');
switch($act){
case 'onboarding':
include_once(SOFTACULOUS_PRO_PLUGIN_PATH . '/main/setup.php');
break;
case 'license':
include_once(SOFTACULOUS_PRO_PLUGIN_PATH . '/main/license.php');
softaculous_pro_license();
break;
case 'manage-plugins':
include_once(SOFTACULOUS_PRO_PLUGIN_PATH . '/main/manage-plugins.php');
softaculous_pro_manage_plugins();
break;
case 'media-replace':
\SoftWP\Media::replace_media_page();
break;
default:
include_once(dirname(__FILE__).'/admin.php');
softaculous_pro_page_settings();
}
}
function softaculous_pro_can_enqueue_assets(){
global $spro_tours;
if(!is_admin()){
return false;
}
$current_page = basename($_SERVER['REQUEST_URI'], PHP_URL_PATH);
if(!empty($_COOKIE['spro-load-tour']) && (!empty($spro_tours)) && array_key_exists($_COOKIE['spro-load-tour'], $spro_tours) && $current_page == $spro_tours[$_COOKIE['spro-load-tour']]){
return $_COOKIE['spro-load-tour'];
}
$is_admin_page = basename(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
if(!empty($_GET['page']) && $_GET['page'] == 'assistant' && $is_admin_page == 'admin.php'){
return true;
}
return false;
}
function softaculous_pro_enqueue_scripts(){
wp_enqueue_style('softaculous-pro-style-admin', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/css/admin.css', [], SOFTACULOUS_PRO_VERSION);
wp_enqueue_style('softaculous-pro-style-intro', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/css/intro.css', [], SOFTACULOUS_PRO_VERSION);
wp_enqueue_style( 'softaculous-pro-style-font-awesome', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/font-awesome/css/all.min.css', [], SOFTACULOUS_PRO_VERSION, 'all' );
wp_enqueue_script('softaculous-pro-script-admin', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/js/admin.js', [], SOFTACULOUS_PRO_VERSION, true);
wp_enqueue_script('softaculous-pro-script-intro', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/js/intro.js', [], SOFTACULOUS_PRO_VERSION, false);
wp_localize_script('softaculous-pro-script-admin', 'soft_pro_obj', array(
'admin_url' => esc_url(admin_url()),
'site_url' => esc_url(site_url()),
'nonce' => wp_create_nonce('softaculous_pro_js_nonce'),
'ajax_url' => admin_url('admin-ajax.php')
));
}
/**
* Display Softaculous notice on the basis of last dismiss date. When user manually dismisses the notice, it remains for 1 month
*
* @since 1.0
*/
function softaculous_pro_is_display_notice(){
$soft_dismissable_notice_date = get_option('softaculous_pro_dismiss_notice_date');
if(empty($soft_dismissable_notice_date)){
return true;
}
$soft_dismissable_notice_date2 = new DateTime($soft_dismissable_notice_date);
$current_date = new DateTime(date('Y-m-d'));
$date_diff_month = $soft_dismissable_notice_date2->diff($current_date);
//Do not display notice again for a month
if($date_diff_month->m < 1){
return false;
}
return true;
}
/**
* Display Softaculous notice in dashboard
*
* @since 1.0
*/
function softaculous_pro_admin_notice($force = 0){
if(!empty($_GET['page']) && $_GET['page'] == 'softaculous' && empty($force)){
return '';
}
return '';
}
function softaculous_pro_license_notice(){
global $softaculous_pro;
if(is_admin() && current_user_can('activate_plugins') && !wp_doing_ajax()){
$spro_add_nonce_vars = 0;
if(empty($softaculous_pro['license']['license'])){
$msg = sprintf(__('Your SoftWP plugin is %1$sUnlicensed%2$s. Please enter the license key %3$s here%4$s.', 'softaculous-pro'),
'<font style="color:red;"><b>',
'</b></font>',
'<a href="'.admin_url('admin.php?page=assistant&act=license').'">',
'</a>'
);
}else{
if(!empty($softaculous_pro['license']['url_mismatch'])){
$msg = sprintf(__('Your SoftWP plugin license is %1$snot authorized%2$s to be used on %3$s. You can generate a new license for your domain from the %4$s panel.', 'softaculous-pro'),
'<b><font style="color:red;">',
'</font></b>',
'<b><i>'.site_url().'</i></b>',
'<b>'.($softaculous_pro['branding']['sn'] == 'SoftWP' ? 'Softaculous' : $softaculous_pro['branding']['sn']).'</b>'
);
}elseif(empty($softaculous_pro['license']['active'])){
$msg = sprintf(__('Your SoftWP plugin license has %1$sExpired%2$s. Please renew your license for uninterrupted updates and support.', 'softaculous-pro'),
'<font style="color:red;"><b>',
'</b></font>'
);
}
}
if(!empty($msg)){
echo '
<div class="notice notice-error is-dismissible">
<p>'.$msg.'</p>
</div>';
}
// The notice to complete onboarding
//$spro_is_shown = get_option('softaculous_pro_onboarding_shown');
$spro_is_done = get_option('softaculous_pro_onboarding_done');
$spro_is_dismissed = get_option('softaculous_pro_onboarding_notice_dismiss');
if(empty($spro_is_done) && empty($spro_is_dismissed)){
echo '
<div class="notice notice-error is-dismissible" id="softaculous-onboarding-notice">
<p>'.sprintf(__('Your Onboarding process is not completed yet! %1$sClick here%2$s to complete the simple setup process and build your site in a few steps.', 'softaculous-pro'),
'<a href="'.admin_url('admin.php?page=assistant&act=onboarding').'" target="_blank">',
'</a>').'</p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$("#softaculous-onboarding-notice").on("click", ".notice-dismiss", function() {
// Send an AJAX request to the server to dismiss the notice
jQuery.ajax({
type: "post",
url: softwp_obj.ajax_url,
data: {
action: "softaculous_pro_wp_ajax",
softaculous_pro_onboarding_notice_dismiss: 1,
softaculous_pro_security: softwp_obj.nonce,
data: [],
},
});
});
});
</script>
';
$spro_add_nonce_vars = 1;
}
$softwp_ai_is_dismissed = get_option('softaculous_pro_ai_notice_dismiss');
if(empty($softwp_ai_is_dismissed) && !empty($_GET['page']) && $_GET['page'] == 'assistant'){
echo '
<div class="notice notice-info is-dismissible" id="softaculous-ai-notice">
<h3 style="margin: 0.5em 0;">'.__('Enhance Content Writing with AI Assistant', 'softaculous-pro').'
</h3>
<p>'.__('Use cutting-edge AI to write blog posts or content for your pages. Create a table, write a paragraph, change tone, translate, fix spelling & grammar and so much more.', 'softaculous-pro').' <br />
<b>'.__('Start Exploring', 'softaculous-pro').'</b> :
<a href="'.admin_url('post-new.php?post_type=page').'" target="_blank" style="text-decoration:none;">'.__('New Page', 'softaculous-pro').'</a> ●
<a href="'.admin_url('post-new.php').'" target="_blank" style="text-decoration:none;">'.__('New Post', 'softaculous-pro').'</a> ●
<a href="'.admin_url('edit.php?post_type=page').'" target="_blank" style="text-decoration:none;">'.__('Existing Page', 'softaculous-pro').'</a> ●
<a href="'.admin_url('edit.php').'" target="_blank" style="text-decoration:none;">'.__('Existing Post', 'softaculous-pro').'</a>
</p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($){
$("#softaculous-ai-notice").on("click", ".notice-dismiss", function() {
// Send an AJAX request to the server to dismiss the notice
jQuery.ajax({
type: "post",
url: softwp_obj.ajax_url,
data: {
action: "softaculous_pro_wp_ajax",
softaculous_pro_ai_notice_dismiss: 1,
softaculous_pro_security: softwp_obj.nonce,
data: [],
},
});
});
});
</script>
';
$spro_add_nonce_vars = 1;
}
if(!empty($spro_add_nonce_vars)){
echo '<script type="text/javascript">
var softwp_obj = {
admin_url: "'.esc_url(admin_url()).'",
site_url: "'.esc_url(site_url()).'",
nonce: "'.wp_create_nonce('softaculous_pro_js_nonce').'",
ajax_url: "'.admin_url('admin-ajax.php').'"
};
</script>';
}
}
return '';
}
function softaculous_pro_get_option($option_name, $default_value = false, $site_id = null){
if($site_id !== null && is_multisite()){
return get_site_option($option_name, $default_value);
}
return get_option($option_name, $default_value);
}
/**
* Takes care of Slashes
*
* @param string $string The string that will be processed
* @return string A string that is safe to use for Database Queries, etc
* @since 1.0
*/
function softaculous_pro_inputsec($string){
//get_magic_quotes_gpc is deprecated in php 7.4
if(version_compare(PHP_VERSION, '7.4', '<')){
if(!get_magic_quotes_gpc()){
$string = addslashes($string);
}else{
$string = stripslashes($string);
$string = addslashes($string);
}
}else{
$string = addslashes($string);
}
// This is to replace ` which can cause the command to be executed in exec()
$string = str_replace('`', '\`', $string);
return $string;
}
/**
* Converts Special characters to html entities
*
* @param string $string The string containing special characters
* @return string A string containing special characters replaced by html entities of the format &#ASCIICODE;
* @since 1.0
*/
function softaculous_pro_htmlizer($string){
$string = htmlentities($string, ENT_QUOTES, 'UTF-8');
preg_match_all('/(&#(\d{1,7}|x[0-9a-fA-F]{1,6});)/', $string, $matches);
foreach($matches[1] as $mk => $mv){
$tmp_m = softaculous_pro_entity_check($matches[2][$mk]);
$string = str_replace($matches[1][$mk], $tmp_m, $string);
}
return $string;
}
/**
* Used in function htmlizer()
*
* @param string $string
* @return string
* @since 1.0
*/
function softaculous_pro_entity_check($string){
//Convert Hexadecimal to Decimal
$num = ((substr($string, 0, 1) === 'x') ? hexdec(substr($string, 1)) : (int) $string);
//Squares and Spaces - return nothing
$string = (($num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) || $num < 0x20) ? '' : '&#'.$num.';');
return $string;
}
/**
* OPTIONAL REQUEST of the given REQUEST Key
*
* @param string $name The key of the $_REQUEST array i.e. the name of the input / textarea text
* @param string $default The value to return if the $_REQUEST[$name] is NOT SET
* @return string Returns the string if the REQUEST is there otherwise the default value given.
* @since 1.0
*/
function softaculous_pro_optREQ($name, $default = ''){
global $softaculous_error;
//Check the POSTED NAME was posted
if(isset($_REQUEST[$name])){
return trim(sanitize_text_field($_REQUEST[$name]));
}else{
return $default;
}
}
/**
* OPTIONAL POST of the given POST Key
*
* @param string $name The key of the $_POST array i.e. the name of the input / textarea text
* @param string $default The value to return if the $_POST[$name] is NOT SET
* @return string Returns the string if the POST is there otherwise the default value given.
* @since 1.4.6
*/
function softaculous_pro_optPOST($name, $default = ''){
global $softaculous_error;
//Check the POSTED NAME was posted
if(isset($_POST[$name])){
if(is_array($_POST[$name])){
$values = array_map('trim', $_POST[$name]);
return array_map('sanitize_text_field', $values);
}
return trim(sanitize_text_field($_POST[$name]));
}else{
return $default;
}
}
/**
* OPTIONAL GET of the given GET Key i.e. dont throw a error if not there
*
* @param string $name The key of the $_GET array i.e. the name of the input / textarea text
* @param string $default The value to return if the $_GET[$name] is NOT SET
* @return string Returns the string if the GET is there otherwise the default value given.
* @since 1.0
*/
function softaculous_pro_optGET($name, $default = ''){
global $softaculous_error;
//Check the GETED NAME was GETed
if(isset($_GET[$name])){
return trim(sanitize_text_field($_GET[$name]));
}else{
return $default;
}
}
function softaculous_pro_sp_api_url($main_server = 0){
global $softaculous_pro;
return softaculous_pro_api_url($main_server, 'sitepad');
}
function softaculous_pro_pfx_api_url($main_server = 0){
global $softaculous_pro;
return softaculous_pro_api_url($main_server, 'popularfx');
}
function softaculous_pro_api_url($main_server = 0, $suffix = ''){
global $softaculous_pro;
$r = array(
'https://s0.softaculous.com/a/softwp/',
'https://s1.softaculous.com/a/softwp/',
'https://s2.softaculous.com/a/softwp/',
'https://s3.softaculous.com/a/softwp/',
'https://s4.softaculous.com/a/softwp/',
'https://s5.softaculous.com/a/softwp/',
'https://s7.softaculous.com/a/softwp/',
'https://s8.softaculous.com/a/softwp/'
);
$mirror = $r[array_rand($r)];
// If the license is newly issued, we need to fetch from API only
if(!empty($main_server) || empty($softaculous_pro['license']['last_edit']) ||
(!empty($softaculous_pro['license']['last_edit']) && (time() - 3600) < $softaculous_pro['license']['last_edit'])
){
$mirror = 'https://a.softaculous.com/softwp/';
}
// -1 indicates that we need to force the mirror server used for rendering static files e.g. screenshots
if(!empty($main_server) && $main_server == '-1'){
$mirror = $r[array_rand($r)];
}
if(!empty($suffix)){
$mirror = str_replace('/softwp', '/'.$suffix, $mirror);
}
return $mirror;
}
// Load license data
function softaculous_pro_load_license(){
global $softaculous_pro;
// Load license
$softaculous_pro['license'] = get_option('softaculous_pro_license', array());
if(empty($softaculous_pro['license'])){
return false;
}
$prods = apply_filters('softaculous_pro_products', []);
// Update license details as well
if(empty($softaculous_pro['license']['last_update']) ||
(!empty($softaculous_pro['license']['last_update']) && (time() - $softaculous_pro['license']['last_update']) >= 86400)
){
$resp = wp_remote_get(softaculous_pro_api_url(1).'license.php?license='.$softaculous_pro['license']['license'].'&prods='.implode(',', $prods).'&url='.rawurlencode(site_url()));
// Did we get a response ?
if(is_array($resp)){
$tosave = json_decode($resp['body'], true);
// Is it the license ?
if(!empty($tosave['license'])){
$softaculous_pro['license'] = $tosave;
}
}
// Save the old data only
if(empty($tosave['license'])){
$tosave = get_option('softaculous_pro_license', array());
}
$tosave['last_update'] = time();
update_option('softaculous_pro_license', $tosave);
}
return $softaculous_pro['license'];
}
add_filter('softaculous_pro_products', 'softaculous_softwp_pro_products', 10, 1);
function softaculous_softwp_pro_products($r = []){
$r['softwp'] = 'softwp';
return $r;
}
// Load Softaculous rebranding settings
function softaculous_pro_rebranding(){
global $softaculous_pro;
$softaculous_pro['branding']['sn'] = 'SoftWP';
$softaculous_pro['branding']['logo_url'] = SOFTACULOUS_PRO_PLUGIN_URL.'assets/images/logo-white.png';
$softaculous_pro['branding']['rebranded'] = 0;
//Getting info if Softaculous rebranding done or not?
$soft_rebranding = get_option('softaculous_pro_rebranding', '[]');
if(!empty($soft_rebranding['logo_url'])){
$softaculous_pro['branding']['logo_url'] = $soft_rebranding['logo_url'];
}
if(!empty($soft_rebranding['sn']) && $soft_rebranding['sn'] != 'Softaculous'){
$softaculous_pro['branding']['sn'] = $soft_rebranding['sn'];
$softaculous_pro['branding']['rebranded'] = 1;
}
if(!empty($soft_rebranding['default_hf_bg'])){
$softaculous_pro['branding']['default_hf_bg'] = $soft_rebranding['default_hf_bg'];
}
if(!empty($soft_rebranding['default_hf_text'])){
$softaculous_pro['branding']['default_hf_text'] = $soft_rebranding['default_hf_text'];
}
return true;
}
// Add our license key if ANY
function softaculous_pro_updater_filter_args($queryArgs) {
global $softaculous_pro;
if ( !empty($softaculous_pro['license']['license']) ) {
$queryArgs['license'] = $softaculous_pro['license']['license'];
}
return $queryArgs;
}
// Handle the Check for update link and ask to install license key
function softaculous_pro_updater_check_link($final_link){
global $softaculous_pro;
if(empty($softaculous_pro['license']['license'])){
return '<a href="'.admin_url('admin.php?page=assistant&act=license').'">'.__('Enter Pro License Key', 'softaculous-pro').'</a>';
}
return $final_link;
}
function softaculous_pro_report_error($error = array()) {
if(empty($error)){
return true;
}
$error_string = '<b>' . esc_html__('Please fix the below error(s):', 'softaculous-pro') . '</b><br />';
foreach($error as $ev){
$error_string .= '* ' . esc_html($ev) . '<br />';
}
echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
}
function softaculous_pro_add_plugin_row_links($links, $slug) {
if(is_multisite() && is_network_admin()){
return $links;
}
if ($slug !== SOFTACULOUS_PRO_BASE) {
return $links;
}
if(!current_user_can('activate_plugins')){
return $links;
}
$new_links = array(
'plugins' => '<a href="admin.php?page=assistant&act=manage-plugins"><font style="color:green;">'.__('Explore Pro Plugins', 'softaculous-pro').'</font></a>',
'tours' => '<a href="admin.php?page=assistant#tours">'.__('Tour', 'softaculous-pro').'</a>',
'ai' => '<a href="admin.php?page=assistant#ai"><font style="color:green;">'.__('AI', 'softaculous-pro').'</font></a>',
);
$links = array_merge($links, $new_links);
return $links;
}
function softaculous_pro_add_params($link){
global $softaculous_pro;
$link = rtrim($link, '?&');
$query = parse_url($link, PHP_URL_QUERY);
if ($query) {
$link .= '&';
} else {
$link .= '?';
}
$link .= 'version=latest&license='.$softaculous_pro['license']['license'].'&url='.site_url();
return $link;
}
function softaculous_pro_register_post_type(){
register_post_type(
'spro_ai_history',
[
'labels' => [
'name' => __('AI History', 'softaculous-pro'),
'singular_name' => __('AI History', 'softaculous-pro'),
],
'public' => false,
'map_meta_cap' => true,
'hierarchical' => false,
'rewrite' => false,
'query_var' => false,
'can_export' => false,
'delete_with_user' => true,
'supports' => array('author'),
]
);
}
intros.php 0000644 00000052361 15152643500 0006603 0 ustar 00 <?php
if(!defined('ABSPATH')){
exit;
}
$spro_tour_content = array();
////////////////////////////
// Assistant Tour
////////////////////////////
$spro_tour_content['assistant']['.spro-header-menu'] = array(
"title" => __("Assistant", "softaculous-pro"),
"intro" => __("Assistant adds AI to your site building process and lets you create content with just a few clicks (look for the AI option while editing your posts/pages).", "softaculous-pro")
.'<br /><br />'.
__("Assistant also helps you with several aspects of building and maintaning your WordPress website.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['assistant']['#spro-tours'] = array(
"title" => __("Tours", "softaculous-pro"),
"intro" => __("Tours highlights and explains important options in WordPress that you will need while managing your site.", "softaculous-pro")
.'<br /><br />'.
__("You can replay the tours when needed.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['assistant']['#spro-features'] = array(
"title" => __("Recommended Features", "softaculous-pro"),
"intro" => __("A recommended list of plugins to improve performace and extend functionalties for your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['assistant']['#spro-quick-links'] = array(
"title" => __("Quick Links", "softaculous-pro"),
"intro" => __("Here you will find important links compiled in a single section which can sometimes be difficult to find in WordPress.", "softaculous-pro"),
"position" => "left",
);
$spro_tour_content['assistant']['#spro-settings'] = array(
"title" => __("Settings", "softaculous-pro"),
"intro" => __("We have simplified complex WordPress settings that you can now manage with just a click via the Assistant.", "softaculous-pro"),
"position" => "left",
);
$spro_tour_content['assistant']['#spro-ai'] = array(
"title" => __("AI", "softaculous-pro"),
"intro" => __("Experience hassle-free site building with inbuilt AI in Assistant.", "softaculous-pro"),
"position" => "left",
);
$spro_tour_content['assistant']['#toplevel_page_assistant'] = array(
"title" => __("Your Assistant", "softaculous-pro"),
"intro" => __("Assistant resides here, when you are unable to find something or having a hard time understanding a feature in WordPress we should be able to help you.", "softaculous-pro")
.'<br /><br />'.
__("Visit this page anytime.", "softaculous-pro"),
"position" => "right",
);
///////////////////////////////////
// WordPress Sidebar
///////////////////////////////////
$spro_tour_content['sidebar']['#toplevel_page_assistant'] = array(
"title" => __("Your Assistant", "softaculous-pro"),
"intro" => __("Assistant resides here, when you are unable to find something or having a hard time understanding a feature in WordPress we should be able to help you.", "softaculous-pro")
.'<br /><br />'.
__("Visit this page anytime.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#wp-admin-bar-view-site'] = array(
"title" => __("Preview Site", "softaculous-pro"),
"intro" => __("You can use this link to preview your site as a visitor.", "softaculous-pro"),
"position" => "right",
"hover" => "true",
"hover_selector" => "#wp-admin-bar-site-name",
);
$spro_tour_content['sidebar']['#menu-dashboard'] = array(
"title" => __("Dashboard", "softaculous-pro"),
"intro" => __("The Dashboard is your website's command center, providing a concise summary of its activity, such as site health, recent updates, comments, and statistics.", "softaculous-pro")
.'<br /><br />'.
__("Several plugins also display quick summary like orders, products, etc within the dashboard.", "softaculous-pro")
.'<br /><br />'.
__("You can also check for Updates from the sub-menu.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-posts'] = array(
"title" => __("Posts", "softaculous-pro"),
"intro" => __("Manage your blog posts here.", "softaculous-pro")
.'<br /><br />'.
__("Posts are typically utilized for blog posts, news updates, or articles, organized in a chronological order.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-media'] = array(
"title" => __("Media Library", "softaculous-pro"),
"intro" => __("Manage media files like images, audio, videos, etc. here.", "softaculous-pro")
.'<br /><br />'.
__("Media uploaded from anywhere on your site can be managed here.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-pages'] = array(
"title" => __("Pages", "softaculous-pro"),
"intro" => __("Pages are static content sections such as Home, About Us, Contact, Services, etc.", "softaculous-pro")
.'<br /><br />'.
__("Use this menu to add, edit, delete your pages.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-comments'] = array(
"title" => __("Comments", "softaculous-pro"),
"intro" => __("Here you can moderate comments posted by visitors on your posts.", "softaculous-pro")
.'<br /><br />'.
__("You can one click disable comments for your entire site from the Assistant dashboard.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-appearance'] = array(
"title" => __("Appearance", "softaculous-pro"),
"intro" => __("Personalize your site's appearance effortlessly.", "softaculous-pro")
.'<br /><br />'.
__("Explore themes, customize headers, background, colors, manage widgets and menus to customize your site's look and feel.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-plugins'] = array(
"title" => __("Plugins", "softaculous-pro"),
"intro" => __("Unlock endless possibilities for your website with plugins.", "softaculous-pro")
.'<br /><br />'.
__("Easily search, add or delete plugins to enhance your site's functionality.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-users'] = array(
"title" => __("Users", "softaculous-pro"),
"intro" => __("Add or manage users to ensure smooth operation and collaboration.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-tools'] = array(
"title" => __("Tools", "softaculous-pro"),
"intro" => __("Import/Export site data, check site health or edit plugin/theme files from the Tools menu.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#menu-settings'] = array(
"title" => __("Settings", "softaculous-pro"),
"intro" => __("Advanced settings for your site can be managed here.", "softaculous-pro")
.'<br /><br />'.
__("These settings include site title, tagline, site url, writing, reading, discussion, media, permalinks and more.", "softaculous-pro")
.'<br /><br />'.
__("Some plugins also add their settings page in this menu.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#collapse-menu'] = array(
"title" => __("Toggle Menu", "softaculous-pro"),
"intro" => __("Expand or Collapse the sidebar menu using this option.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['sidebar']['#wp-admin-bar-user-info'] = array(
"title" => __("Edit Profile", "softaculous-pro"),
"intro" => __("Here you can edit your profile information like name, email, password, bio, profile picture and more.", "softaculous-pro"),
"position" => "left",
"hover" => "true",
"hover_selector" => "#wp-admin-bar-my-account",
);
$spro_tour_content['sidebar']['#wp-admin-bar-logout'] = array(
"title" => __("Log Out", "softaculous-pro"),
"intro" => __("Use this link to securely log out from your site.", "softaculous-pro"),
"position" => "left",
"hover" => "true",
"hover_selector" => "#wp-admin-bar-my-account",
);
////////////////////////////
// Plugins Page
////////////////////////////
$spro_tour_content['plugins']['#menu-plugins'] = array(
"title" => __("Plugins", "softaculous-pro"),
"intro" => __("Click here to add or manage plugins on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['plugins']['.page-title-action'] = array(
"title" => __("Add New Plugin", "softaculous-pro"),
"intro" => __("Here you can search wordpress.org plugins library or upload a custom plugin file to install a new plugin on your site.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['plugins']['tr[data-plugin]'] = array(
"title" => __("Installed Plugins List", "softaculous-pro"),
"intro" => __("All your installed plugins active as well as inactive will be listed here.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['plugins']['td.plugin-title'] = array(
"title" => __("Plugin Actions", "softaculous-pro"),
"intro" => __("You can perform actions for your plugins like Activate, Deactivate, Update, Delete, Plugin Settings and more..", "softaculous-pro")
.'<br /><br />'.
__("It is recommended to delete plugins that you do not plan to use and keep all your plugins up to date.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['plugins']['#bulk-action-selector-top'] = array(
"title" => __("Bulk Actions", "softaculous-pro"),
"intro" => __("Choose bulk action for selected plugins: Activate, Deactivate, Update, Delete, toggle auto updates and more", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['plugins']['.subsubsub'] = array(
"title" => __("Filter Installed Plugins", "softaculous-pro"),
"intro" => __("Filter your installed plugins list with Active, Inactive, Auto Updates Enabled or Disabled options", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['plugins']['#plugin-search-input'] = array(
"title" => __("Search Installed Plugins", "softaculous-pro"),
"intro" => __("Search a plugin from the installed plugins list.", "softaculous-pro"),
"position" => "bottom",
);
////////////////////////////
// Themes Page
////////////////////////////
$spro_tour_content['themes']['#menu-appearance'] = array(
"title" => __("Themes", "softaculous-pro"),
"intro" => __("Click here to add or manage themes on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['themes']['.page-title-action'] = array(
"title" => __("Add New Theme", "softaculous-pro"),
"intro" => __("Here you can search wordpress.org themes library or upload a custom theme file to install a new theme on your site.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['themes']['.theme-browser'] = array(
"title" => __("Installed Themes List", "softaculous-pro"),
"intro" => __("All your installed themes active as well as inactive will be listed here.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['themes']['.theme.active[data-slug]'] = array(
"title" => __("Active Theme", "softaculous-pro"),
"intro" => __("Your active theme will be listed here.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['themes']['.theme-actions'] = array(
"title" => __("Theme Actions", "softaculous-pro"),
"intro" => __("You can perform actions for your theme like Activate, Live Preview, Customize and more", "softaculous-pro")
.'<br /><br />'.
__("It is recommended to delete themes that you do not plan to use and keep all your themes up to date.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['themes']['.search-box'] = array(
"title" => __("Search Installed Themes", "softaculous-pro"),
"intro" => __("Search a theme from the installed themes list.", "softaculous-pro"),
"position" => "bottom",
);
////////////////////////////
// WordPress Dashboard Page
////////////////////////////
$spro_tour_content['dashboard']['#menu-dashboard'] = array(
"title" => __("Dashboard", "softaculous-pro"),
"intro" => __("The Dashboard is your website's command center, providing a concise summary of its activity, such as site health, recent updates, comments, and statistics.", "softaculous-pro")
.'<br /><br />'.
__("Several plugins also display quick summary like orders, products, etc within the dashboard.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['dashboard']['#dashboard_site_health'] = array(
"title" => __("Site Health", "softaculous-pro"),
"intro" => __("Here you can get insights on the overall performance and security of your website.", "softaculous-pro")
.'<br /><br />'.
__("It offers recommendations and troubleshooting tools to help you maintain an efficient and secure site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['dashboard']['#dashboard_right_now'] = array(
"title" => __("Info at a Glance", "softaculous-pro"),
"intro" => __("Here you will get the number of posts, pages, comments, current version of WordPress and theme that you are running.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['dashboard']['#dashboard_activity'] = array(
"title" => __("Activity", "softaculous-pro"),
"intro" => __("Here you will get a quick summary of recent activity like published posts and comments received on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['dashboard']['#dashboard_quick_press'] = array(
"title" => __("Quick Draft", "softaculous-pro"),
"intro" => __("Use this section for capturing ideas as they come to you, quickly jot down the ideas for new posts.", "softaculous-pro")
.'<br /><br />'.
__("You can later access these drafts from the Posts section and continue editing them in the full post editor.", "softaculous-pro"),
"position" => "left",
);
$spro_tour_content['dashboard']['#dashboard_primary'] = array(
"title" => __("Events and News", "softaculous-pro"),
"intro" => __("This widget is a valuable resource for staying informed about the latest happenings in the WordPress community and connecting with other WordPress enthusiasts.", "softaculous-pro")
.'<br /><br />'.
__("Here you will find updates on new releases, upcoming features, security updates, and general news about the WordPress community.", "softaculous-pro")
.'<br /><br />'.
__("This section also shows upcoming WordPress events such as WordCamps, local meetups, and other community gatherings.", "softaculous-pro"),
"position" => "left",
);
$spro_tour_content['dashboard']['#screen-options-link-wrap'] = array(
"title" => __("Screen Options", "softaculous-pro"),
"intro" => __("This useful feature allows you to select the screen elements that you would like to show or hide by using the checkboxes.", "softaculous-pro")
.'<br /><br />'.
__("You will find this option on several pages across your site.", "softaculous-pro"),
"position" => "bottom",
);
////////////////////////////
// Users Page
////////////////////////////
$spro_tour_content['users']['#menu-users'] = array(
"title" => __("Users", "softaculous-pro"),
"intro" => __("Click here to add or manage users on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['users']['.page-title-action'] = array(
"title" => __("Add New User", "softaculous-pro"),
"intro" => __("Add a new user for your site. You can enter user details, password, role, etc.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['users']['tbody > tr'] = array(
"title" => __("Users List", "softaculous-pro"),
"intro" => __("All your users with admin role as well as other roles will be listed here.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['users']['tbody > tr > td'] = array(
"title" => __("Edit User", "softaculous-pro"),
"intro" => __("You can edit the user information, change password, change role and much more with the Edit link here.", "softaculous-pro"),
"position" => "bottom",
"hover" => "true",
"hover_selector" => ".row-actions",
"hover_class" => "visible",
);
$spro_tour_content['users']['#bulk-action-selector-top'] = array(
"title" => __("Bulk Actions", "softaculous-pro"),
"intro" => __("Choose bulk action for selected users: Delete or send password reset link", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['users']['#new_role'] = array(
"title" => __("Change Role", "softaculous-pro"),
"intro" => __("Here you can bulk change role for the selected users", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['users']['.subsubsub'] = array(
"title" => __("Filter Users", "softaculous-pro"),
"intro" => __("Filter your users list with their roles", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['users']['.search-box'] = array(
"title" => __("Search Users", "softaculous-pro"),
"intro" => __("Search a user from the users list.", "softaculous-pro"),
"position" => "bottom",
);
////////////////////////////
// Posts Page
////////////////////////////
$spro_tour_content['posts']['#menu-posts'] = array(
"title" => __("Posts", "softaculous-pro"),
"intro" => __("Click here to add or manage blog posts on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['posts']['.page-title-action'] = array(
"title" => __("Add New Post", "softaculous-pro"),
"intro" => __("Start writing a new blog post for your site.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['tbody > tr'] = array(
"title" => __("Posts List", "softaculous-pro"),
"intro" => __("All the posts owned by all the users on your site will be listed here.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['tbody > tr > td'] = array(
"title" => __("Manage Post", "softaculous-pro"),
"intro" => __("You can view, edit or delete the posts with the links here.", "softaculous-pro"),
"position" => "bottom",
"hover" => "true",
"hover_selector" => ".row-actions",
"hover_class" => "visible"
);
$spro_tour_content['posts']['#bulk-action-selector-top'] = array(
"title" => __("Bulk Actions", "softaculous-pro"),
"intro" => __("Choose bulk action for selected posts: Quick Edit or Move to Trash.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['#filter-by-date'] = array(
"title" => __("Filter Posts by Date", "softaculous-pro"),
"intro" => __("Here you can filter the posts by date.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['#cat'] = array(
"title" => __("Filter Posts by Category", "softaculous-pro"),
"intro" => __("Here you can filter the posts by category.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['.subsubsub'] = array(
"title" => __("Filter Posts", "softaculous-pro"),
"intro" => __("Filter your posts list by their status like published, drafts, trash, etc.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['posts']['.search-box'] = array(
"title" => __("Search Posts", "softaculous-pro"),
"intro" => __("Search a post from the posts list.", "softaculous-pro"),
"position" => "bottom",
);
////////////////////////////
// Pages Page
////////////////////////////
$spro_tour_content['pages']['#menu-pages'] = array(
"title" => __("Pages", "softaculous-pro"),
"intro" => __("Click here to add or manage pages on your site.", "softaculous-pro"),
"position" => "right",
);
$spro_tour_content['pages']['.page-title-action'] = array(
"title" => __("Add New Page", "softaculous-pro"),
"intro" => __("Start creating a new page for your site.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['pages']['tbody > tr'] = array(
"title" => __("Pages List", "softaculous-pro"),
"intro" => __("All the pages on your site will be listed here.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['pages']['tbody > tr > td'] = array(
"title" => __("Manage Page", "softaculous-pro"),
"intro" => __("You can view, edit or delete the pages with the links here.", "softaculous-pro"),
"position" => "bottom",
"hover" => "true",
"hover_selector" => ".row-actions",
"hover_class" => "visible"
);
$spro_tour_content['pages']['#bulk-action-selector-top'] = array(
"title" => __("Bulk Actions", "softaculous-pro"),
"intro" => __("Choose bulk action for selected pages: Quick Edit or Move to Trash.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['pages']['#filter-by-date'] = array(
"title" => __("Filter Pages by Date", "softaculous-pro"),
"intro" => __("Here you can filter the pages by date.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['pages']['.subsubsub'] = array(
"title" => __("Filter Pages", "softaculous-pro"),
"intro" => __("Filter your pages list by their status like published, drafts, trash, etc.", "softaculous-pro"),
"position" => "bottom",
);
$spro_tour_content['pages']['.search-box'] = array(
"title" => __("Search Pages", "softaculous-pro"),
"intro" => __("Search a page from the pages list.", "softaculous-pro"),
"position" => "bottom",
);
ai.php 0000644 00000021533 15152643500 0005653 0 ustar 00 <?php
namespace SoftWP;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT');
}
class AI{
static function enqueue_scripts(){
global $softaculous_pro;
wp_enqueue_style('softaculous-pro-ai', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/css/ai.css', [], SOFTACULOUS_PRO_VERSION);
wp_enqueue_script('softaculous_ai_base', SOFTACULOUS_PRO_PLUGIN_URL . 'assets/js/ai/ai.js', ['jquery'], SOFTACULOUS_PRO_VERSION, ['strategy' => 'defer']);
$soft_ai = [
'i18n' => [],
'nonce' => wp_create_nonce('softaculous_ai_nonce'),
'ajax_url' => admin_url('admin-ajax.php'),
'ai_icon_url' => SOFTACULOUS_PRO_PLUGIN_URL .'/assets/images/softaculous-ai.svg',
'buy' => esc_url(SOFTACULOUS_PRO_AI_BUY.'&softwp_lic='.$softaculous_pro['license']['license'])
];
$tokens = get_option('softaculous_ai_tokens', []);
if(!empty($tokens)){
$soft_ai['tokens'] = $tokens;
}
wp_localize_script('softaculous_ai_base', 'soft_ai', $soft_ai);
// Loading the assets data
$asset_file = [];
$asset_file = include_once(SOFTACULOUS_PRO_PLUGIN_PATH . 'assets/js/ai/build/index.asset.php');
if(is_array($asset_file)){
array_push($asset_file['dependencies'], 'softaculous_ai_base'); // Adding the ai base js dep
}
wp_enqueue_script(
'softaculous_ai_gb',
SOFTACULOUS_PRO_PLUGIN_URL . 'assets/js/ai/build/index.js', // Load from the build directory
$asset_file['dependencies'],
$asset_file['version'],
['strategy' => 'defer']
);
// The API provides better output as markdown compared to html, thats why we need this markdown library to convert the markdown to html.
wp_enqueue_script(
'softaculous_ai_marked',
SOFTACULOUS_PRO_PLUGIN_URL . 'assets/js/marked.min.js',
array('softaculous_ai_base'),
SOFTACULOUS_PRO_VERSION,
['strategy' => 'defer']
);
}
static function generate(){
global $softaculous_pro, $softaculous_pro_settings;
check_admin_referer('softaculous_ai_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(__('You do not have required privilege', 'softaculous-pro'));
}
set_time_limit(100);
$content = !empty($_REQUEST['content']) ? wp_kses_post(wp_unslash($_REQUEST['content'])) : '';
$prompt = !empty($_REQUEST['prompt']) ? wp_kses_post(wp_unslash($_REQUEST['prompt'])) : '';
$shortcut = !empty($_REQUEST['shortcut']) ? sanitize_text_field(wp_unslash($_REQUEST['shortcut'])) : '';
$license = !empty($softaculous_pro['license']['license']) ? $softaculous_pro['license']['license'] : '';
if(empty($license)){
wp_send_json_error(__('Please link a license to keep using the AI feature', 'softaculous-pro'));
}
// We need atleast a prompt or a shortcut
if(empty($prompt) && empty($shortcut)){
wp_send_json_error(__('Please write a Prompt, for the AI to generate content', 'softaculous-pro'));
}
// Shortcut requires content, but a prompt does not,
// shortcuts are meant to be used to process content,
// where as a Prompt can be used to process as well as generate content.
if(!empty($shortcut) && empty($content)){
wp_send_json_error(__('AI shortcut can not be applied without any content.', 'softaculous-pro'));
}
$res = wp_remote_post(SOFTACULOUS_PRO_AI_API, [
'timeout' => 90,
'body' => [
'prompt' => $prompt,
'shortcut' => $shortcut,
'content' => $content,
'license' => $license,
'url' => site_url()
]
]);
if(empty($res)){
wp_send_json_error(__('Unable to complete this request', 'softaculous-pro'));
}
if(is_wp_error($res)){
$error_string = $res->get_error_message();
wp_send_json_error($error_string);
}
$res_code = wp_remote_retrieve_response_code($res);
$body = wp_remote_retrieve_body($res);
if(empty($body)){
wp_send_json_error(__('The AI API responsed with empty response, Response Code:', 'softaculous-pro') . $res_code);
}
$ai_content = json_decode($body, true);
if($res_code > 299){
$error = !empty($ai_content['error']) ? sanitize_text_field($ai_content['error']) : __('Unexpected response code returned from AI API: ', 'softaculous-pro') . $res_code;
wp_send_json_error($error);
}
// Building the history data
if(!isset($ai_content['error']) && isset($softaculous_pro_settings['ai_history_duration']) && $softaculous_pro_settings['ai_history_duration'] > 0 && !empty($ai_content['ai'])){
$history_data = [];
if(!empty($content)){
$history['content'] = wp_kses_post(wp_unslash($content));
$title = (strlen($content) > 100 ? substr($content, 100) : $content);
}
if(!empty($prompt)){
$history['prompt'] = wp_kses_post(wp_unslash($prompt));
$title = (strlen($prompt) > 100 ? substr($prompt, 100) : $prompt);
}
if(empty($prompt) && !empty($shortcut)){
$history['shortcut'] = sanitize_text_field($shortcut);
$title = self::parse_shortcuts($shortcut);
}
if(!empty($ai_content['ai'])){
$history['assistant'] = wp_kses_post(wp_unslash($ai_content['ai']));
}
if(!empty($ai_content['total_tokens'])){
$title .= '|||'.$ai_content['total_tokens'];
}
// Saving the history
wp_insert_post([
'post_title' => sanitize_text_field($title),
'post_type' => 'spro_ai_history',
'post_content' => serialize($history),
]);
}
// Saving token data
if(!empty($ai_content['remaining_tokens'])){
update_option('softaculous_ai_tokens', [
'remaining_tokens' => sanitize_text_field($ai_content['remaining_tokens'])
], false);
}
wp_send_json_success($ai_content);
}
static function load_history(){
check_admin_referer('softaculous_ai_nonce', 'nonce');
if(!current_user_can('manage_options')){
wp_send_json_error(__('You do not have required privilege', 'softaculous-pro'));
}
$history_id = !empty($_POST['history_id']) ? sanitize_text_field(wp_unslash($_POST['history_id'])) : 0;
$offset = !empty($_POST['offset']) ? (int) sanitize_text_field(wp_unslash($_POST['offset'])) : 0;
$history = [];
if(!empty($history_id)){
$query = new \WP_Query([
'post_type' => ['spro_ai_history'],
'page_id' => $history_id,
]);
if($query->have_posts()){
while($query->have_posts()){
$query->the_post();
$history = unserialize(get_the_content());
}
}
// Restore to original post
wp_reset_postdata();
wp_send_json_success($history);
} else {
$query = new \WP_Query([
'post_type' => ['spro_ai_history'],
'posts_per_page' => 20,
'offset' => $offset,
'orderby' => 'date',
'order' => 'DESC',
]);
}
if($query->have_posts()){
while($query->have_posts()){
$query->the_post();
$single['token_used'] = 0;
$single['title'] = get_the_title();
$single['date'] = get_the_date();
$single['id'] = get_the_ID();
if(strpos($single['title'], '|||') !== FALSE) {
$get_count = explode('|||', $single['title']);
$single['title'] = $get_count[0];
$single['token_used'] = $get_count[1];
}
array_push($history, $single);
}
}
// Restore to original post
wp_reset_postdata();
$total_count = wp_count_posts('spro_ai_history')->draft; // Getting the total count
wp_send_json_success(['history' => $history , 'total' => $total_count]);
}
static function parse_shortcuts($shortcut){
$supported_languages = ['arabic', 'chinese', 'czech', 'danish', 'dutch', 'english', 'finnish', 'french', 'german', 'greek', 'hindi', 'hebrew', 'hungarian', 'indonesian', 'italian', 'japanese', 'korean', 'marathi', 'punjabi', 'persian', 'polish', 'portuguese', 'russian', 'spanish', 'swedish', 'thai', 'turkish', 'vietnamese'];
$supported_tones = ['casual', 'confidence', 'formal', 'friendly', 'inspirational', 'motivational', 'nostalgic', 'playful', 'professional', 'scientific', 'straightforward', 'witty'];
$other_shortcuts = ['shorter' => 'Make it shorter', 'longer' => 'Make it longer', 'simplify' => 'Simplify the language', 'grammar' => 'Fix Spelling and Grammar'];
if(in_array($shortcut, $supported_languages)){
return 'Translate to ' . ucfirst($shortcut);
}
if(in_array($shortcut, $supported_tones)){
return 'Change the tone of the content to ' . ucfirst($shortcut);
}
if(array_key_exists($shortcut, $other_shortcuts)){
return $other_shortcuts[$shortcut];
}
return $shortcut;
}
static function delete_history($delete_all = false){
$settings = get_option('softaculous_pro_settings', []);
$history_duration = (int) $settings['ai_history_duration'];
// If it is off then we wont delete the history.
if($history_duration < 1){
return;
}
$x_days_ago = date('Y-m-d', strtotime('-'.$history_duration.' days'));
$query = new \WP_Query([
'post_type' => 'spro_ai_history',
'post_status' => 'draft',
'date_query'=> [
[
'column' => 'post_date',
'before' => $x_days_ago,
],
],
'posts_per_page' => 100,
]);
if($query->have_posts()){
while($query->have_posts()){
$query->the_post();
wp_delete_post(get_the_ID(), true);
}
wp_reset_postdata();
}
}
}
manage-plugins.php 0000644 00000010767 15152643500 0010200 0 ustar 00 <?php
//////////////////////////////////////////////////////////////
//===========================================================
// license.php
//===========================================================
// softaculous-pro
// Inspired by the DESIRE to be the BEST OF ALL
// ----------------------------------------------------------
// Started by: Pulkit Gupta
// Date: 12 Sep 2024
// Time: 23:00 hrs
// Site: https://www.softaculous.com/
// ----------------------------------------------------------
// Please Read the Terms of use at http://softaculous.com/
// ----------------------------------------------------------
//===========================================================
// (c)softaculous Team
//===========================================================
//////////////////////////////////////////////////////////////
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
if(defined('SOFTACULOUS_PRO_VERSION')) {
return;
}
function softaculous_pro_manage_plugins(){
global $spro_error;
softaculous_pro_header(0);
include_once(SOFTACULOUS_PRO_PLUGIN_PATH.'main/onboarding.php');
$spro_manage_features = spro_get_features_list();
$manage_installed_plugins = get_plugins();
if(!empty($softaculous_pro_error)){
echo '<div id="message" class="error"><p>'.esc_html($softaculous_pro_error).'</p></div>';
}
if(!empty($softaculous_pro_msg)){
echo '<div id="message" class="updated"><p>'.esc_html($softaculous_pro_msg).'</p></div>';
}
echo '
<div class="spro-box-heading"><h3 class="smb-2 spb-1 sml-2">
'.__('Manage Plugins', 'softaculous-pro').'</h3>
<hr />
<br />
</div>
<div class="spro-container">
<div class="srow">';
foreach($spro_manage_features as $feature => $info){
foreach($info['plugin'] as $pslug => $data){
if(empty($data['featured'])) continue;
$disabled = '';
if (!empty($data['requires_php']) && version_compare(PHP_VERSION, $data['requires_php'], '<')) {
$data['plugin_desc'] .= '<br><span style="color: red;">'.sprintf(__('Requires PHP version %1$s or higher', 'softaculous-pro'), $data['requires_php']).'</span>';
$disabled ='disabled';
}
echo '
<div class="scol-6 spro-box-holder">
<div class="spro-mng-plugin-header spx-2">
<img src="'.(!empty($data['plugin_img']) ? $data['plugin_img'] : SOFTACULOUS_PRO_PLUGIN_URL.'/assets/images/plugins/'.$pslug.'.png').'" width="50" />
<div class="spro-plugin-info-con sp-2">
<div class="spro-manage-plugin-title spx-2">'.$data['plugin_name'].'</div>
<div class="sp-2 spro-manage-plugin-desc">'.$data['plugin_desc'].'</div>
</div>
</div>
<div class="spro-rec-plugin spx-2 smy-1">';
$i_pending = $a_pending = 0;
if(!empty($data['plugin_init'])){
if(empty($manage_installed_plugins[$data['plugin_init']])){
$status_free = __('Not Installed', 'softaculous-pro');
$i_pending = 1;
}elseif(!is_plugin_active($data['plugin_init'])){
$status_free = __('Installed', 'softaculous-pro');
$a_pending = 1;
}else{
$status_free = __('Active', 'softaculous-pro');
}
echo '<span class="spro-status"><b>'.__('Free', 'softaculous-pro').'</b>: '.$status_free.'</span>';
}
if(!empty($data['plugin_init_pro'])){
if(empty($manage_installed_plugins[$data['plugin_init_pro']])){
$status_pro = __('Not Installed', 'softaculous-pro');
$i_pending = 1;
}elseif(!is_plugin_active($data['plugin_init_pro'])){
$status_pro = __('Installed', 'softaculous-pro');
$a_pending = 1;
}else{
$status_pro = __('Active', 'softaculous-pro');
}
echo '<br /><span class="spro-status"><b>'.__('Pro', 'softaculous-pro').'</b>: '.$status_pro.'</span>';
}
echo '<span style="float:right;">';
if(!empty($i_pending)){
echo '<input type="button" name="'.$pslug.'" class="spro-plugin-install-btn sp-2" value="'.__('Install for Free', 'softaculous-pro').'" '.$disabled.'>';
}elseif(!empty($a_pending)){
echo '<input type="submit" name="'.$pslug.'" class="spro-plugin-install-btn spro-active-plugin sp-2" value="'.__('Activate', 'softaculous-pro').'" '.$disabled.'>';
}else{
echo '<p class="spro-plugin-active"><i class="fa-solid fa-check"></i> '.__('Active', 'softaculous-pro').'</p>';
}
echo '</span>';
echo '
</div>
<i style="color:green;" class="spl-2">'.__('Pro included with your subscription', 'softaculous-pro').'</i>
</div>';
}
}
echo '
</div>
</div>';
softaculous_pro_footer();
}
onboarding.php 0000644 00000147353 15152643500 0007415 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
add_action('admin_print_styles', 'softaculous_pro_admin_print_styles');
function softaculous_pro_admin_print_styles() {
$act = softaculous_pro_optGET('act');
$page = softaculous_pro_optGET('page');
// Check if the current page is the onboarding wizard
if($page == 'assistant' && $act == 'onboarding'){
echo '<style>
#adminmenuback, #adminmenuwrap, #wpadminbar { display: none !important; }
</style>';
}
}
add_action('admin_menu', 'softaculous_pro_onboarding_admin_menu', 6);
function softaculous_pro_onboarding_admin_menu() {
$capability = 'activate_plugins';
// Onboarding
//add_submenu_page('assistant', __('Onboarding', 'softaculous-pro'), __('Onboarding', 'softaculous-pro'), $capability, 'softaculous_pro_onboarding', 'softaculous_pro_page_handler');
$act = softaculous_pro_optGET('act');
$page = softaculous_pro_optGET('page');
// Check if the current page is the onboarding wizard
if($page == 'assistant' && $act == 'onboarding'){
// Remove admin menu
remove_menu_page('index.php'); // Dashboard
remove_menu_page('edit.php'); // Posts
remove_menu_page('upload.php'); // Media
remove_menu_page('edit.php?post_type=page'); // Pages
remove_menu_page('edit-comments.php'); // Comments
remove_menu_page('themes.php'); // Appearance
remove_menu_page('plugins.php'); // Plugins
remove_menu_page('users.php'); // Users
remove_menu_page('tools.php'); // Tools
remove_menu_page('options-general.php'); // Settings
add_filter('show_admin_bar', '__return_false');
remove_filter('update_footer', 'core_update_footer');
add_filter('screen_options_show_screen', '__return_false');
add_filter('admin_footer_text', '__return_empty_string');
remove_all_actions( 'admin_notices' );
remove_all_actions( 'all_admin_notices');
}
}
// Add the action to load the plugin
add_action('plugins_loaded', 'softaculous_pro_onboarding_load_plugin');
// The function that will be called when the plugin is loaded
function softaculous_pro_onboarding_load_plugin(){
global $pagelayer, $softaculous_pro;
add_action('admin_enqueue_scripts', 'softaculous_pro_onboarding_enqueue_scripts');
/* // Load the freemium widgets
if(!defined('PAGELAYER_PREMIUM')){
add_action('pagelayer_load_custom_widgets', 'spro_freemium_shortcodes');
} */
// Are we to setup a template ?
$slug = get_option('softaculous_pro_setup_template');
if(!empty($slug)){
add_action('after_setup_theme', 'spro_setup_template_import');
}
}
function softaculous_pro_onboarding_enqueue_scripts(){
$softwp_onboarding_lang = array(
'conf_data_loss' => __( 'Please confirm that you accept data loss since you have already run the onboarding process previously', 'softaculous-pro' ),
'select_atleast_one' => __( 'Please select atleast one page to import', 'softaculous-pro' ),
'downloading_installing_plugins' => __( "Downloading and installing required plugins", 'softaculous-pro' ),
'wordpress_require_ftp' => __( "WordPress requires FTP details, without them you won't be able to install a plugin/theme", 'softaculous-pro' ),
'downloading_template' => __( "Downloading the template", 'softaculous-pro' ),
'buildWebsite' => __( 'Building your website...', 'softaculous-pro' ),
'checkRequirements' => __( 'Checking the requirements ...', 'softaculous-pro' ),
'importTemplate' => __( 'Importing the template', 'softaculous-pro' ),
'setupCompleted' => __( 'Your website setup is completed', 'softaculous-pro' ),
'congratulations' => __( 'Congratulations', 'softaculous-pro'),
);
if(!empty($_GET['act']) && $_GET['act'] === 'onboarding') {
wp_enqueue_script('softaculous-pro-script-onboarding', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/js/onboarding.js', array('jquery'), SOFTACULOUS_PRO_VERSION, false);
wp_localize_script('softaculous-pro-script-onboarding', 'softwp_onboarding_lang', $softwp_onboarding_lang);
wp_enqueue_style( 'softaculous-pro-style-onboarding', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/css/onboarding.css', [], SOFTACULOUS_PRO_VERSION, 'all' );
wp_enqueue_style( 'softaculous-pro-style-font-awesome', SOFTACULOUS_PRO_PLUGIN_URL . '/assets/font-awesome/css/all.min.css', [], SOFTACULOUS_PRO_VERSION, 'all' );
}
}
function spro_get_features_list(){
$features_list = array(
"seo" => array(
"name" => __('Increase Website Traffic (SEO)','softaculous-pro'),
"info" => __("Improve your site's ranking on search engines","softaculous-pro"),
"icon" => 'dashicons dashicons-chart-bar',
"plugin"=> array(
"siteseo" => array(
"plugin_name" => __("SiteSEO – One Click SEO for WordPress","softaculous-pro"),
"plugin_url"=> "https://siteseo.io/",
'plugin_init' => 'siteseo/siteseo.php',
'plugin_download_url' => softaculous_pro_api_url(0, 'siteseo').'files/versions/latest-stable-free.zip',
'plugin_init_pro' => 'siteseo-pro/siteseo-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'siteseo').'download.php',
'plugin_desc' => __('Boost your website\'s search rankings today with the most powerful WordPress SEO plugin. Its lightweight, optimized, and delivers exceptional performance.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 7.2,
),
)
),
"speedycache" => array(
"name" => __("Improve Page Speed","softaculous-pro"),
"info" => __("Improve speed by cache, minify, compress", 'softaculous-pro'),
"icon" => "fa-solid fa-gauge-high",
"plugin"=> array(
"speedycache" => array(
"plugin_name" => __("SpeedyCache – Cache, Optimization, Performance","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/speedycache/",
'plugin_init' => 'speedycache/speedycache.php',
'plugin_init_pro' => 'speedycache-pro/speedycache-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'speedycache').'download.php',
'plugin_desc' => __('SpeedyCache is an easy to use and powerful WordPress Cache Plugin, it helps you reduce page load time improving User Experience and boosting your Google PageSpeed.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 7.3,
),
)
),
"backuply" => array(
"name" => __("Schedule Backups","softaculous-pro"),
"info" => __("Backup your site on local or remote servers","softaculous-pro"),
"icon" => "fa-regular fa-file-zipper",
"plugin"=> array(
"backuply" => array(
"plugin_name" => __("Backuply – Backup, Restore, Migrate and Clone","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/backuply/",
'plugin_init' => 'backuply/backuply.php',
'plugin_init_pro' => 'backuply-pro/backuply-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'backuply').'download.php',
'plugin_desc' => __('Backuply is a WordPress backup plugin that helps you backup your WordPress website, saving you from loss of data because of server crashes, hacks, dodgy updates, or bad plugins.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 5.5,
),
)
),
"sell_products" => array(
"name" => __("Sell Products","softaculous-pro"),
"info" => __("Sell physical or digital products","softaculous-pro"),
"icon" => "fa-solid fa-tag",
"plugin"=> array(
"woocommerce" => array(
"plugin_name" => __("WooCommerce","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/woocommerce/",
'plugin_init' => 'woocommerce/woocommerce.php',
),
)
),
"loginizer" => array(
"name" => __("Limit Login Attempts","softaculous-pro"),
"info" => __("Brute force protection, 2FA, login captcha", 'softaculous-pro'),
"icon" => "fa-solid fa-user-lock",
"plugin"=> array(
"loginizer" => array(
"plugin_name" => __("Loginizer","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/loginizer/",
'plugin_init' => 'loginizer/loginizer.php',
'plugin_init_pro' => 'loginizer-security/loginizer-security.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'loginizer').'download.php',
'plugin_desc' => __('Loginizer is a simple and effortless solution that takes care of all your security problems. It comes with default optimal configuration to protect your site from Brute Force attacks.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 5.5,
),
)
),
"pagelayer" => array(
"name" => __("Page Builder","softaculous-pro"),
"info" => __("Page Builder, Drag and Drop website builder", 'softaculous-pro'),
"icon" => "fa-solid fa-paintbrush",
"plugin"=> array(
"pagelayer" => array(
"plugin_name" => __("Pagelayer","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/pagelayer/",
'plugin_init' => 'pagelayer/pagelayer.php',
'plugin_init_pro' => 'pagelayer-pro/pagelayer-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'pagelayer').'download.php',
'plugin_desc' => __('Pagelayer is an awesome page builder that allows you to create and design your website instantly in the simplest way possible. Take control over your page content with the most advanced page builder plugin available.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 5.5,
),
)
),
"gosmtp" => array(
"name" => __("Send Email with SMTP","softaculous-pro"),
"info" => __("Providers: Gmail, Outlook, AWS SES & more", 'softaculous-pro'),
"icon" => "fa-solid fa-envelope-circle-check",
"plugin"=> array(
"gosmtp" => array(
"plugin_name" => __("GoSMTP – SMTP for WordPress","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/gosmtp/",
'plugin_init' => 'gosmtp/gosmtp.php',
'plugin_init_pro' => 'gosmtp-pro/gosmtp-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'gosmtp').'download.php',
'plugin_desc' => __('GoSMTP allows you to send emails from your WordPress over SMTP or many popular outgoing email service providers. Using these improves your email deliverability.', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 5.5,
),
)
),
"fileorganizer" => array(
"name" => __("File Manager","softaculous-pro"),
"info" => __("Manage files with drag & drop editor", 'softaculous-pro'),
"icon" => "fa-regular fa-folder-open",
"plugin"=> array(
"fileorganizer" => array(
"plugin_name" => __("FileOrganizer – Manage WordPress and Website Files","softaculous-pro"),
"plugin_url"=> "https://wordpress.org/plugins/fileorganizer/",
'plugin_init' => 'fileorganizer/fileorganizer.php',
'plugin_init_pro' => 'fileorganizer-pro/fileorganizer-pro.php',
'plugin_download_url_pro' => softaculous_pro_api_url(0, 'fileorganizer').'download.php',
'plugin_desc' => __('FileOrganizer is a lightweight and easy-to-use file management plugin for WordPress. Organize and manage your WordPress files with FileOrganizer without any control panel or FTP access. ', 'softaculous-pro'),
'pro' => 1,
'featured' => 1,
'requires_php' => 5.5,
),
)
),
);
$features_list = apply_filters('softaculous_pro_features_list', $features_list);
return $features_list;
}
function softaculous_pro_ajax_output($data){
echo json_encode($data);
wp_die();
}
function softaculous_pro_ajax_output_xmlwrap($data){
echo '<softaculous-pro-xmlwrap>'.json_encode($data).'</softaculous-pro-xmlwrap>';
wp_die();
}
function softaculous_pro_import_template($slug, $items = array()){
global $pl_error;
$data = [];
$destination = popularfx_templates_dir(false).'/'.$slug;
include_once(PAGELAYER_DIR.'/main/import.php');
// Our function needs to efficiently replace the variables
$GLOBALS['softaculous_pro_template_import_slug'] = $slug;
add_filter('pagelayer_start_insert_content', 'softaculous_pro_pagelayer_start_insert_content', 10);
// Now import the template
if(!pagelayer_import_theme($slug, $destination, $items)){
$data['error']['import_err'] = __('Could not import the template !', 'softaculous-pro');
$data['error'] = array_merge($data['error'], $pl_error);
return $data;
}
// Save the name of the slug
set_theme_mod('popularfx_template', $slug);
// onboarding done
update_option('softaculous_pro_onboarding_done', time());
// Set default left menu folded
//set_user_setting('mfold', 'f');
$data['done'] = 1;
return $data;
}
// Download the template
function softaculous_pro_download_template($slug){
global $softaculous_pro, $pl_error;
set_time_limit(300);
$data = [];
// Now lets download the templates
if(!function_exists( 'download_url' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
$spro_setup_info = get_option('softaculous_pro_setup_info');
$url = softaculous_pro_pfx_api_url().'/givetemplate.php?slug='.$spro_setup_info['theme_slug'].'&license='.@$softaculous_pro['license']['license'].'&url='.site_url();
//echo $url;
$popular_fx_dir = popularfx_templates_dir(false);
$destination = $popular_fx_dir.'/'.$slug;
// Check if FTP is required
ob_start();
$credentials = request_filesystem_credentials('');
ob_end_clean();
if(false === $credentials || !WP_Filesystem($credentials)){
$data['error']['download'] = __('Theme template can only be uploaded using FTP !', 'softaculous-pro');
return $data;
}
global $wp_filesystem;
// For FTP have to use relative paths
if(is_array($credentials)){
$abspath_relative = $wp_filesystem->find_folder(ABSPATH);
$replacer = str_replace($abspath_relative, '', ABSPATH);
if($replacer !== ABSPATH){
$popular_fx_dir = str_replace($replacer, '', $popular_fx_dir);
$destination = str_replace($replacer, '', $destination);
}
}
$tmp_file = download_url($url);
//echo filesize($tmp_file);
//var_dump($tmp_file);
// Error downloading
if(is_wp_error($tmp_file) || filesize($tmp_file) < 1){
if(!empty($tmp_file->errors)){
$data['error']['download_err'] = __('Could not download the theme !', 'softaculous-pro').var_export($tmp_file->errors, true);
return $data;
}
}
$wp_filesystem->mkdir($popular_fx_dir);
$wp_filesystem->mkdir($destination);
//echo $destination;
$ret = unzip_file($tmp_file, $destination);
//r_print($ret);
// Try to delete
@unlink($tmp_file);
// Error downloading
if(is_wp_error($ret) || !file_exists($destination.'/style.css')){
if(!empty($ret->errors)){
$data['error']['download'] = __('Could not extract the template !', 'softaculous-pro').var_export($ret->errors, true);
return $data;
}
}
return $data;
}
// Get list of templates
function softaculous_pro_get_templates_list(){
$data = get_transient('softaculous_pro_templates');
// Get any existing copy of our transient data
if(false === $data){
// Start checking for an update
$send_for_check = array(
'timeout' => 90,
'user-agent' => 'WordPress'
);
$raw_response = wp_remote_post( softaculous_pro_pfx_api_url().'templates.json', $send_for_check );
//pagelayer_print($raw_response);die();
// Is the response valid ?
if ( !is_wp_error( $raw_response ) && ( $raw_response['response']['code'] == 200 ) ){
$data = json_decode($raw_response['body'], true);
}
//pagelayer_print($data);die();
// Feed the updated data into the transient
if(!empty($data['list']) && count($data['list']) > 10){
set_transient('softaculous_pro_templates', $data, 2 * HOUR_IN_SECONDS);
}
}
return $data;
}
// Get the template info from our servers
function softaculous_pro_onboarding_dismiss(){
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
if(isset($_REQUEST['dismiss'])){
update_option('softaculous_pro_onboarding_dismiss', time());
}
$data['done'] = 1;
softaculous_pro_ajax_output($data);
}
// Get the template info from our servers
function softaculous_pro_ajax_template_info(){
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
$data = [];
if(isset($_REQUEST['slug'])){
$resp = wp_remote_get(softaculous_pro_pfx_api_url().'template-info.php?slug='.$_REQUEST['slug'], array('timeout' => 30));
// Is the response valid ?
if ( !is_wp_error( $resp ) && ( $resp['response']['code'] == 200 ) ){
$data = json_decode($resp['body'], true);
}
}
$setup_info = get_option('softaculous_pro_setup_info');
$setup_info = !empty($setup_info) ? $setup_info : array();
$setup_info['theme_slug'] = $_REQUEST['slug'];
update_option('softaculous_pro_setup_info',$setup_info);
softaculous_pro_ajax_output($data);
}
// Start the installation of the template
function softaculous_pro_ajax_start_install_template(){
global $softaculous_pro;
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
set_time_limit(300);
// Handling Access through FTP
ob_start();
// Check if FTP is required
$have_credentials = request_filesystem_credentials('');
if(false === $have_credentials){
$form_html = ob_get_clean();
$ftp_modal = '<div id="request-filesystem-credentials-dialog" class="notification-dialog-wrap request-filesystem-credentials-dialog">
<div class="notification-dialog-background"></div>
<div class="notification-dialog" role="dialog" aria-labelledby="request-filesystem-credentials-title" tabindex="0">
<div class="request-filesystem-credentials-dialog-content">'. $form_html . '</div></div></div>';
wp_send_json_error(['form' => $ftp_modal]);
}
ob_end_clean(); // Just in case there was any output till now it will be cleaned.
$data = [];
//pagelayer_print($_POST);die();
$license = softaculous_pro_optPOST('softaculous_pro_license');
// Check if its a valid license
if(!empty($license)){
$resp = wp_remote_get(softaculous_pro_api_url(1).'license.php?license='.$license.'&url='.rawurlencode(site_url()), array('timeout' => 30));
if(is_array($resp)){
$json = json_decode($resp['body'], true);
//print_r($json);
}else{
$data['error']['resp_invalid'] = __('The response from the server was malformed. Please try again in sometime !', 'softaculous-pro').var_export($resp, true);
softaculous_pro_ajax_output($data);
}
// Save the License
if(empty($json['license'])){
$data['error']['lic_invalid'] = __('The license key is invalid', 'softaculous-pro');
softaculous_pro_ajax_output($data);
}else{
update_option('softaculous_pro_license', $json);
// Load license
spro_load_license();
}
}
// Load templates
$softaculous_pro['templates'] = softaculous_pro_get_templates_list();
$slug = softaculous_pro_optPOST('theme');
if(!defined('PAGELAYER_VERSION')){
$res = spro_install_required_plugin('pagelayer', array('plugin_init' => 'pagelayer/pagelayer.php'));
if(empty($res['success'])){
$data['error']['pl_req'] = __('Pagelayer is required to use the templates !', 'softaculous-pro');
softaculous_pro_ajax_output($data);
}
}
if(!defined('PFX_VERSION')){
$res = spro_install_required_plugin('popularfx-templates', array('plugin_init' => 'popularfx-templates/popularfx-templates.php', 'plugin_download_url' => softaculous_pro_api_url(0, 'popularfx').'update2.php?give=1'));
if(empty($res['success'])){
$data['error']['pl_req'] = __('PopularFX plugin is required to use the templates !', 'softaculous-pro');
softaculous_pro_ajax_output($data);
}
}
if(!function_exists('popularfx_templates_dir')){
$res = spro_install_required_theme('popularfx');
if(empty($res['success'])){
$data['error']['pfx_req'] = __('PopularFX theme is required to use the templates !', 'softaculous-pro');
softaculous_pro_ajax_output($data);
}
}
if(empty($softaculous_pro['templates']['list'][$slug])){
$data['error']['template_invalid'] = __('The template you submitted is invalid !', 'softaculous-pro');
softaculous_pro_ajax_output($data);
}
$template = $softaculous_pro['templates']['list'][$slug];
// Do we have the req PL version ?
if(!empty($template['pl_ver']) && version_compare(PAGELAYER_VERSION, $template['pl_ver'], '<')){
$data['error']['pl_ver'] = sprintf(__('Your Pagelayer version is %1$s while the template requires Pagelayer version higher than or equal to %2$s ', 'softaculous-pro'), PAGELAYER_VERSION, $template['pl_ver']);
softaculous_pro_ajax_output($data);
}
// Do we have the req PL version ?
if(version_compare(PAGELAYER_VERSION, '1.8.9', '<')){
$data['error']['pl_ver'] = sprintf(__('Your Pagelayer version is %1$s while the onboarding requires Pagelayer version higher than or equal to 1.8.9', 'softaculous-pro'), PAGELAYER_VERSION);
softaculous_pro_ajax_output($data);
}
// Do we have the req PFX Plugin version ?
if(!empty($template['pfx_ver']) && version_compare(PFX_VERSION, $template['pfx_ver'], '<')){
$data['error']['pfx_ver'] = sprintf(__('Your PopularFX Plugin version is %1$s while the template requires PopularFX version higher than or equal to %2$s', 'softaculous-pro'), PFX_VERSION, $template['pfx_ver']);
softaculous_pro_ajax_output($data);
}
// Is it a pro template ?
if($template['type'] > 1 && empty($softaculous_pro['license']['active'])){
$data['error']['template_pro'] = sprintf(__('The selected template is a Pro template and you have a free or expired license. Please enter your license key %1$shere%2$s.', 'softaculous-pro'),
'<a href="'.admin_url('admin.php?page=assistant&act=license').'" target="_blank" style="color:blue;">',
'</a>'
);
softaculous_pro_ajax_output($data);
}
$do_we_have_pro = defined('PAGELAYER_PREMIUM');
// Do we need to install Pagelayer or Pagelayer PRO ?
if(!function_exists('pagelayer_theme_import_notices') || (empty($do_we_have_pro) && $template['type'] > 1)){
if($template['type'] > 1){
$download_url = SOFTACULOUS_PRO_PAGELAYER_API.'download.php?version=latest&license='.$softaculous_pro['license']['license'].'&url='.rawurlencode(site_url());
$installed = spro_install_required_plugin('pagelayer-pro', array('plugin_init' => 'pagelayer-pro/pagelayer-pro.php', 'plugin_download_url' => $download_url));
}else{
$installed = spro_install_required_plugin('pagelayer', array('plugin_init' => 'pagelayer/pagelayer.php'));
}
// Did we fail to install ?
if(is_wp_error($installed) || empty($installed)){
$install_url = admin_url('admin.php?page=softaculous_pro_install_pagelayer&license=').@$softaculous_pro['license']['license'];
$data['error']['pagelayer'] = sprintf(__('There was an error in installing Pagelayer which is required by this template. Please install Pagelayer manually by clicking %1$shere%2$s and then install the template !', 'softaculous-pro'), '<a href="%1$s" target="_blank">'.$install_url, '</a>');
if(!empty($installed->errors)){
$data['error']['pagelayer_logs'] = var_export($installed->errors, true);
}
softaculous_pro_ajax_output_xmlwrap($data);
}
}
// Lets notify to download
// $data['download'] = 1;
$data['sel_plugin'] = 1;
softaculous_pro_ajax_output_xmlwrap($data);
}
function softaculous_pro_ajax_selected_plugin (){
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error();
}
$results = array();
$options = get_option('softaculous_pro_setup_info');
$sel_features = $options['features'];
if(!empty($sel_features)){
$feature_list = spro_get_features_list();
foreach($feature_list as $slug => $features){
if (in_array($slug, $sel_features)) {
foreach($features['plugin'] as $plugin_slug => $plugin_data){
$res = spro_install_required_plugin($plugin_slug, $plugin_data);
$results[] = array(
'plugin_slug' => $plugin_slug,
'status' => $res,
);
}
}
}
foreach ($results as $item) {
if (isset($item['status']['error'])) {
$data['failed_plugin'][$item['plugin_slug']] = $item['status']['error'];
}
}
$data['download'] = 1;
softaculous_pro_ajax_output($data);
}
}
// Download template
function softaculous_pro_ajax_download_template(){
global $softaculous_pro;
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
$slug = softaculous_pro_optPOST('theme');
// Do the download
$data = softaculous_pro_download_template($slug);
// Any error ?
if(!empty($data['error'])){
softaculous_pro_ajax_output($data);
}
// Lets import then
$data['import'] = 1;
softaculous_pro_ajax_output($data);
}
// Import template
function softaculous_pro_ajax_import_template(){
global $softaculous_pro, $pl_error;
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
$slug = softaculous_pro_optPOST('theme');
$to_import = softaculous_pro_optPOST('to_import');
$_POST['set_home_page'] = 1;
if(!empty($to_import)){
$to_import[] = 'blog';
$items = ['page' => $to_import];
}else{
$items = [];
}
// Import the template
$data = softaculous_pro_import_template($slug, $items);
softaculous_pro_ajax_output($data);
}
function softaculous_pro_save_setup_info(){
// Some AJAX security
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
$step = $_POST['step'];
$post_data = wp_unslash($_POST['data']);
$setup_info = get_option('softaculous_pro_setup_info');
$setup_info = !empty($setup_info) ? $setup_info : array();
if($step === 'type' && !empty($post_data) ){
$setup_info['type'] = strtolower(str_replace(" ", "", $post_data));
}
if($step === 'title' && !empty($post_data)){
update_option('blogname', $post_data);
}
if($step === 'features' && !empty($post_data)){
$setup_info['features'] = $post_data;
}
$steps = array( 'type', 'title', 'features', 'import');
update_option('softaculous_pro_setup_info', $setup_info);
}
function softaculous_pro_get_options(){
check_ajax_referer('softaculous_pro_ajax', 'softaculous_pro_nonce');
$options = get_option('softaculous_pro_setup_info');
wp_send_json($options);
}
function spro_install_required_plugin($slug, $plugin, $pro = 0){
require_once ABSPATH . 'wp-admin/includes/plugin.php';
require_once ABSPATH . 'wp-admin/includes/update.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
$res = array();
try{
if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin['plugin_init'] ) && is_plugin_inactive( $plugin['plugin_init'] ) ) {
activate_plugin($plugin['plugin_init']);
$res['success'] = __("Plugin activated successfully.", 'softaculous-pro');
}
elseif ( ! file_exists( WP_PLUGIN_DIR . '/' . $plugin['plugin_init'] ) ){
if (!empty($plugin['requires_php']) && version_compare(PHP_VERSION, $plugin['requires_php'], '<')) {
throw new Exception(sprintf(__('Plugin installation failed. %1$s requires PHP version %2$s or higher. Your PHP version is %3$s.', 'softaculous-pro'),
$plugin['plugin_name'],
$plugin->requires_php,
PHP_VERSION
));
}
if(!empty($plugin['plugin_download_url'])){
$download_url = $plugin['plugin_download_url'];
}else{
$api = plugins_api(
'plugin_information',
array(
'slug' => sanitize_key( wp_unslash( $slug ) ),
'fields' => array(
'sections' => false,
),
)
);
$download_url = $api->download_link;
}
$skin = new WP_Ajax_Upgrader_Skin();
$upgrader = new Plugin_Upgrader( $skin );
$result = $upgrader->install($download_url);
if ( is_wp_error($result) ) {
throw new Exception(sprintf(__("Plugin installation failed. %1$s", 'softaculous-pro'), $result->get_error_message()));
}
elseif ( is_wp_error( $skin->result ) ) {
throw new Exception(sprintf(__("Plugin installation failed. %1$s", 'softaculous-pro'), $skin->result->get_error_message()));
}
elseif ( $skin->get_errors()->has_errors() ) {
throw new Exception(sprintf(__("Plugin installation failed. %1$s", 'softaculous-pro'), $skin->get_error_messages()));
} else {
activate_plugin($plugin['plugin_init']);
$res['success'] = __("Plugin installed and activated successfully.", 'softaculous-pro');
}
}else{
$res['success'] = __("Plugin already installed.", 'softaculous-pro');
}
}
catch( Exception $e){
$res['error'] = $e->getMessage();
}
// Do we need to install the pro plugin as well ?
if(empty($pro)){
if(!empty($plugin['pro']) && !empty($plugin['plugin_download_url_pro'])){
$plugin['plugin_download_url'] = softaculous_pro_add_params($plugin['plugin_download_url_pro']);
$plugin['plugin_init'] = $plugin['plugin_init_pro'];
$res['pro'] = spro_install_required_plugin($slug, $plugin, 1);
}
}
return $res;
}
function spro_install_required_theme($slug, $theme = array()){
$res = [];
try {
// Check if user is an admin and has appropriate permissions
if(!current_user_can('install_themes')){
throw new Exception(__("You do not have enough permissions to install theme", 'softaculous-pro'));
return [];
}
if(!empty($theme['theme_download_url'])){
$download_url = $theme['theme_download_url'];
}else{
$api = themes_api(
'theme_information',
array(
'slug' => sanitize_key( wp_unslash( $slug ) ),
'fields' => array(
'sections' => false,
'downloadlink' => true,
),
)
);
$download_url = $api->download_link;
}
$theme_name = $slug;
if(wp_get_theme($theme_name)->exists()){
// Activate the theme
switch_theme($theme_name);
$res['success'] = __("Theme activated successfully.", 'softaculous-pro');
return $res;
}
// Use WP Filesystem API to manage theme installation
if(!function_exists('WP_Filesystem')){
require_once(ABSPATH . 'wp-admin/includes/file.php');
}
// Check if FTP is required
ob_start();
$credentials = request_filesystem_credentials('');
ob_end_clean();
if(false === $credentials || !WP_Filesystem($credentials)){
$res['error'] = __('The filesystem could not write files to the server!', 'softaculous-pro');
return $res;
}
global $wp_filesystem;
// The directory where themes are installed
$theme_dir = $wp_filesystem->wp_themes_dir();
// Download the theme zip file
$theme_zip = download_url($download_url);
// Check for errors during download
if(is_wp_error($theme_zip)){
throw new Exception(sprintf(__('Error downloading theme: %1$s', 'softaculous-pro'), $theme_zip->get_error_message()));
}
// Unzip the downloaded theme file
$unzip_result = unzip_file($theme_zip, $theme_dir);
// Check for errors during unzip
if(is_wp_error($unzip_result)){
throw new Exception(sprintf(__('Error unzipping theme: ', 'softaculous-pro'), $unzip_result->get_error_message()));
}
// Delete the temporary zip file
unlink($theme_zip);
// Activate the theme after installation
switch_theme($theme_name);
}catch(\Exception $e){
$res['error'] = __('Theme installation failed ', 'softaculous-pro') . $e->getMessage();
return $res;
}
$res['success'] = __("Theme installed and activated successfully.", 'softaculous-pro');
return $res;
}
// This is to replace the image variables for the template URL
function softaculous_pro_pagelayer_start_insert_content($post){
$url = popularfx_templates_dir_url().'/'.$GLOBALS['softaculous_pro_template_import_slug'].'/';
$replacers['{{theme_url}}/images/'] = $url.'images/';
$replacers['{{theme_url}}'] = $url;
$replacers['{{theme_images}}'] = $url.'images/';
$replacers['{{themes_dir}}'] = dirname(get_stylesheet_directory_uri());
foreach($replacers as $key => $val){
$post['post_content'] = str_replace($key, $val, $post['post_content']);
}
return $post;
}
if(!function_exists('softaculous_pro_templates')){
// The Templates Page
function softaculous_pro_templates(){
global $softaculous_pro, $pl_error, $spro_setup_info;
$softaculous_pro['templates'] = softaculous_pro_get_templates_list();
$spro_setup_info = get_option('softaculous_pro_setup_info');
if(isset($_REQUEST['install'])){
check_admin_referer('softaculous-pro-template');
}
// Is there a license key ?
if(isset($_POST['install'])){
$done = 1;
}
softaculous_pro_templates_T();
}
// The License Page - THEME
function softaculous_pro_templates_T(){
global $softaculous_pro, $pagelayer, $pl_error, $spro_setup_info;
// Any errors ?
if(!empty($pl_error)){
pagelayer_report_error($pl_error);echo '<br />';
}
?>
<div id="softaculous_pro_theme_title">
<h1 style="text-align:center;"><?php _e('Choose a design', 'softaculous-pro'); ?></h1><br /><br />
</div>
<div id="softaculous_pro_search" class="softaculous-pro-row">
<div class="softaculous-pro-search">
<input type="text" class="softaculous-pro-search-field" placeholder="<?php _e('Search for theme', 'softaculous-pro'); ?>" />
<div id="softaculous-pro-suggestion"></div>
</div>
<div class="softaculous-pro-dropdown softaculous-pro-categories">
<div class="softaculous-pro-current-cat"><?php _e('All', 'softaculous-pro'); ?></div><span class="dashicons dashicons-arrow-down-alt2"></span>
<div class="softaculous-pro-dropdown-content"><div class="softaculous-pro-cat-holder softaculous-pro-row" style="justify-content:flex-start;"></div></div>
</div>
</div>
<div class="softaculous-pro-page" id="softaculous-pro-templates-holder">
<div id="softaculous-pro-pagination"></div>
<div id="softaculous-pro-templates" class="softaculous-pro-row" style="justify-content:flex-start"></div>
<div id="softaculous-pro-single-template">
<div style="margin-bottom: 20px; margin-top: 10px; text-align: left;">
<h1 style="display: inline-block;margin: 0px;vertical-align: middle;" id="softaculous-pro-template-name"></h1>
<?php if (empty($softaculous_pro['branding']['rebranded'])): ?>
<a href="" id="softaculous-pro-demo" class="button softaculous-pro-demo-btn" target="_blank"><?php _e('Demo', 'softaculous-pro'); ?></a>
<?php endif; ?>
</div>
<div style="margin: 0px; vertical-align: top;" class="single-template-div">
<div style="text-align: center; position:relative; width:80%;">
<div style="width: 100%; max-height: 500px; overflow: auto; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);" class="single-templates-content">
<div class="loader-container" >
<div class="loader" style="display:none"></div>
</div>
<img id="softaculous_pro_display_image" src="" width="100%" style="position:relative; z-index:2;">
</div>
</div>
<div class="softaculous_pro_single_content">
<h1 style="font-size:16px;"><?php _e('Select pages to import', 'softaculous-pro'); ?></h1><br />
<div id="softaculous_pro_screenshots"></div>
<div class="softaculous_pro_import_img_notice">
<form id="softaculous-pro-import-form" method="post" enctype="multipart/form-data">
<?php wp_nonce_field('softaculous-pro-template');?>
<input name="theme" id="softaculous-pro-template-install" value="" type="hidden" />
<input type="checkbox" name="download_imgs" id="download_imgs" value="1" checked/> <label for="download_imgs" class="spro-tool-tip" style="cursor:pointer;"><?php _e('Import stock images ?', 'softaculous-pro'); ?></label><br />
<i>
<?php _e('We try our best to use images that are free to use from legal perspectives. However, we are not liable for any copyright infringement for your site.', 'softaculous-pro'); ?>
</i>
<input name="install" value="1" type="hidden" />
</form>
</div>
</div>
</div>
<div style="position:fixed; bottom: 15px; right: 20px; z-index: 10;">
<div class="button button-softaculous-pro softaculous-pro-back" style="display:none;"><?php _e('Go Back', 'softaculous-pro'); ?></div>
<input name="import_theme" class="button button-softaculous-pro" id="spro_import_content" value="<?php _e('Import Theme Content', 'softaculous-pro'); ?>" type="button" onclick="softaculous_pro_modal('#SproTemplatesModal')" style="display:none;"/>
</div>
</div>
</div>
<!-- The Modal -->
<div id="SproTemplatesModal" class="softaculous-pro-modal">
<!-- Modal holder -->
<div class="softaculous-pro-modal-holder">
<!-- Modal header -->
<div class="softaculous-pro-modal-header">
<h1><?php _e('Import Theme Contents', 'softaculous-pro'); ?></h1>
<!-- <span class="softaculous-pro-modal-close">×</span> -->
</div>
<!-- Modal content -->
<div class="softaculous-pro-modal-content">
<div class="softaculous-pro-import">
<div id="softaculous-pro-error-template"></div>
<div id="softaculous-pro-progress-template">
<img src="<?php echo esc_attr(SOFTACULOUS_PRO_PLUGIN_URL) .'assets/images/progress.svg';?>" width="20" /> <span id="softaculous-pro-progress-txt"></span>
</div>
</div>
<div class="softaculous-pro-done" style="display: block;">
<h3 style="margin-top: 0px;"><?php _e('Congratulations, the template was imported successfully !', 'softaculous-pro'); ?></h3>
<?php _e('You can now customize the website as per your requirements with the help of Pagelayer or the Customizer.', 'softaculous-pro')
.'<br /><br />
<b>Note</b> : '.
_e('We strongly recommend you change all images and media. We try our best to use images which are copyright free or are allowed under their licensing. However, we take no responsibilities for the same and recommend you change all media and images !', 'softaculous-pro'); ?>
</div>
</div>
<!-- Modal footer -->
<div class="softaculous-pro-modal-footer">
<div class="softaculous-pro-done">
<a class="button softaculous-pro-demo-btn" href="<?php echo site_url();?>" target="_blank"><?php _e('Visit Website', 'softaculous-pro'); ?></a>
<a class="button softaculous-pro-demo-btn" href="<?php echo admin_url();?>" target="_blank"><?php _e('WordPress Dashboard', 'softaculous-pro'); ?></a>
<a class="button softaculous-pro-demo-btn" href="<?php echo admin_url('admin.php?page=assistant');?>" target="_blank"><?php _e('Assistant', 'softaculous-pro'); ?></a>
</div>
</div>
</div>
</div>
<script>
var softaculous_pro_setup_info = JSON.parse('<?php echo json_encode((!empty($spro_setup_info) ? $spro_setup_info : array())); ?>');
// Add to tabs override
jQuery(document).ready(function(){
softaculous_pro_templates_fn(jQuery);
if(softaculous_pro_setup_info && softaculous_pro_setup_info.type){
softaculous_pro_setup_info.type = softaculous_pro_setup_info.type.replace("-", "");
jQuery('#cat_button_'+softaculous_pro_setup_info.type).trigger("click");
}
});
var softaculous_pro_ajax_nonce = '<?php echo wp_create_nonce('softaculous_pro_ajax');?>';
var softaculous_pro_ajax_url = '<?php echo admin_url( 'admin-ajax.php' );?>?&';
var softaculous_pro_demo = 'https://demos.popularfx.com/';
softaculous_pro_templates = <?php echo json_encode($softaculous_pro['templates']);?>;
var themes = softaculous_pro_templates['list'];
var categories = softaculous_pro_templates['categories'];
var mirror = '<?php echo softaculous_pro_sp_api_url("-1");?>files/themes/';
function softaculous_pro_update_cat_input(other_cat){
jQuery('#cat_input').val(other_cat);
}
function softaculous_pro_templates_fn($){
// Back button handler
jQuery('.softaculous-pro-back').click(function(){
softaculous_pro_show_themes(softaculous_pro_setup_info.type !== undefined ? softaculous_pro_setup_info.type.toLowerCase() : '');
jQuery("#spro_import_content").hide();
jQuery(".softaculous-pro-back").hide();
});
jQuery('.softaculous-pro-back-theme').click(function(){
jQuery('#softaculous-pro-templates-holder').show();
jQuery(this).parent().hide();
jQuery('#SproTemplatesModal').hide();
});
jQuery('#cat_input').keyup(function() {
var query = jQuery(this).val().toLowerCase();
var cat_displayed = 0;
jQuery(".category_btn").each(function( index ){
var cslug = jQuery(this).find("input").attr("data-target");
if(cslug.toLowerCase().includes(query)){
jQuery(this).show();
cat_displayed++;
}else{
jQuery(this).hide();
}
if(cat_displayed > 0){
jQuery("#spro_no_cat_results").hide();
}else{
jQuery("#spro_no_cat_results").show();
}
});
});
// Fill the categories
var chtml = '<div class="softaculous-pro-md-4 softaculous-pro-cat" data-cat="">All</div>';
for(var x in categories){
chtml += '<div class="softaculous-pro-md-4 softaculous-pro-cat" data-cat="'+x+'">'+categories[x]['en']+'</div>';
}
jQuery('.softaculous-pro-cat-holder').html(chtml);
jQuery('.softaculous-pro-cat-holder').find('.softaculous-pro-cat').click(function(){
softaculous_pro_show_themes(jQuery(this).data('cat'));
});
jQuery('.softaculous-pro-categories-list').find('.category_btn').click(function(){
var childEle = jQuery(this).children('input');
var jEle_parent = jQuery(this).parent().find(".active_category");
var real_val = jQuery(this).children('input').val();
var val = jQuery(this).children('input').val().toLowerCase();
var inputSection = jQuery(".softaculous-pro-category-input");
if (jQuery(this).hasClass("active_category")) {
jQuery(this).removeClass("active_category");
inputSection.find('input').val('')
return;
}
jEle_parent.removeClass("active_category");
jQuery(this).addClass("active_category");
if(real_val){
inputSection.find('input').val(real_val)
}
softaculous_pro_show_themes(val);
});
// Search Clear
jQuery('.softaculous-pro-sf-empty').click(function(){
jQuery('.softaculous-pro-search-field').val('');
softaculous_pro_show_themes();
});
// Search
jQuery('.softaculous-pro-search-field').on('keyup', function(e){
softaculous_pro_show_themes('', jQuery(this).val());
});
// Sort themes
jQuery('.softaculous-pro-sortby').change(function(){
softaculous_pro_show_themes(jQuery('.softaculous-pro-current-cat').data('cat'), jQuery('.softaculous-pro-search-field').val());
});
};
// Show the themes
function softaculous_pro_show_themes(cat, search, page){
softaculous_pro_show_themes_loaded = 1;
var sortby = 'latest';
jQuery("#softaculous_pro_search").show();
jQuery("#softaculous_pro_theme_title").show();
jQuery("#softaculous-pro-suggestion").hide();
jQuery("#softaculous-pro-single-template").hide();
jQuery("#softaculous-pro-pagination").show();
jQuery("#softaculous-pro-templates").show();
// Blank html
jQuery('#softaculous-pro-templates').html('');
jQuery('#softaculous-pro-pagination').html('');
var search = search || "";
var cat = cat || softaculous_pro_setup_info.type || "";
var cat = cat.replace("-", "");
softaculous_pro_setup_info.type = cat;
var cat = (categories[cat] === undefined && (cat && cat.length) > 0 ? 'others' : cat) || "" ;
var num = 60;
var page = page || 1;
var start = num * (page - 1);
var end = num + start;
var i = 0;
var cat_appender = categories[cat] === undefined ? 'Others' : categories[cat]['en']
if(cat.length > 0){
jQuery('.softaculous-pro-current-cat').html(cat_appender);
jQuery('.softaculous-pro-current-cat').data('cat', cat);
}else{
jQuery('.softaculous-pro-current-cat').html('All');
jQuery('.softaculous-pro-current-cat').data('cat', '');
}
var allowed_list = [];
if(search.length > 0){
search = search.toLowerCase();
for(var x in softaculous_pro_templates['tags']){
if(x.toLowerCase().indexOf(search) >= 0){
allowed_list = allowed_list.concat(softaculous_pro_templates['tags'][x]);
}
}
}
if(allowed_list.length > 0){
allowed_list = Array.from(new Set(allowed_list));
}
var themeids = [];
var sorted = {};
var rsorted = {};
for(var x in themes){
themeids.push(parseInt(themes[x].thid));
}
if(sortby == "latest"){
var datatheme = Object.values(themes);
var rsorted_ids = themeids.sort().reverse();
for(var x of rsorted_ids){
for( var y in datatheme){
if(datatheme[y].thid == x){
rsorted[datatheme[y].slug] = datatheme[y];
}
}
}
themes = rsorted;
}else if(sortby == "oldest"){
var datatheme = Object.values(themes);
var sorted_ids = themeids.sort();
for(var x of sorted_ids){
for( var y in datatheme){
if(datatheme[y].thid == x){
sorted[datatheme[y].slug] = datatheme[y];
}
}
}
themes = sorted;
}else{
themes = softaculous_pro_templates['list'];
}
for(var x in themes){
// Is it same category
if(cat.length > 0 && cat != themes[x].category){
continue;
}
// Is it a searched item
if(search.length > 0 && themes[x].name.toLowerCase().indexOf(search) === -1 && allowed_list.indexOf(themes[x].thid) === -1){
continue;
}
if(i >= start && i < end){
//console.log(x+' '+i+' '+start+' '+end);
softaculous_pro_show_theme_tile(themes[x], x);
}
i++;
}
jQuery('.softaculous-pro-theme-details').click(function(){
var jEle = jQuery(this);
softaculous_pro_show_theme_details(jEle.attr('slug'));
});
var pages = Math.ceil(i/num);
if(pages > 1){
var html = '<ul class="pagination">';
for(var p = 1; p <= pages; p++){
html += '<li class="page-item '+(page == p ? 'active' : '')+'"><a class="page-link" href="#" data-cat="'+cat+'" data-search="'+search+'" data-page="'+p+'">'+p+'</a></li>';
}
html += '</ul>';
jQuery('#softaculous-pro-pagination').html(html);
jQuery('#softaculous-pro-pagination').find('.page-link').click(function(){
var j = jQuery(this);
softaculous_pro_show_themes(j.data('cat'), j.data('search'), j.data('page'));
});
}
}
function softaculous_pro_show_theme_tile(theme, x){
var html = '<div class="softaculous-pro-md-4">'+
'<div class="softaculous-pro-theme-details" slug="'+theme['slug']+'" thid="'+theme['thid']+'">'+
'<div class="softaculous-pro-theme-screenshot">'+
'<img src="'+mirror+'/'+theme['slug']+'/screenshot.jpg" loading="lazy" alt="" />'+
'</div>'+
'<div class="softaculous-pro-theme-name">'+theme['name']+'</div>'+
'</div>'+
'</div>';
jQuery('#softaculous-pro-templates').append(html);
}
function softaculous_pro_strip_extension(str){
return str.substr(0,str.lastIndexOf('.'));
}
// Show the theme details
function softaculous_pro_show_theme_details(slug){
var theme = themes[slug];
jQuery("#softaculous-pro-suggestion").hide();
jQuery("#softaculous_pro_search").hide();
jQuery("#softaculous_pro_theme_title").hide();
jQuery("#softaculous-pro-single-template").show();
jQuery("#softaculous-pro-pagination").hide();
jQuery("#softaculous-pro-templates").hide();
// Set install value
jQuery('#softaculous-pro-template-install').val(slug);
// Set name
jQuery("#softaculous-pro-template-name").html(theme['name']);
// Demo URL
jQuery("#softaculous-pro-demo").attr("href", softaculous_pro_demo+(theme['name'].replace(' ', '_')));
// Blank screenshots
jQuery("#softaculous_pro_screenshots").html('');
// Is the license PRO ?
if(theme['type'] >= 2){
jQuery('#softaculous_pro_license_div').css('display', 'inline-block');
}else{
jQuery('#softaculous_pro_license_div').hide();
}
var url = mirror+'/'+theme['slug'];
// Show home image
jQuery("#softaculous_pro_display_image").attr("src", "");
jQuery("#softaculous_pro_display_image").attr("src", url+'/screenshots/home.jpg');
jQuery("#softaculous_pro_display_image").parent().scrollTop(0);
// Make the call
jQuery.ajax({
url: softaculous_pro_ajax_url+'action=softaculous_pro_template_info',
type: 'POST',
data: {
softaculous_pro_nonce: softaculous_pro_ajax_nonce,
slug: slug
},
dataType: 'json',
success:function(theme) {
jQuery("#spro_import_single").addClass("hidden");
var sc = '';
// var test= '';
// Show the screenshots
for(var x in theme['screenshots']){
var page_name = softaculous_pro_strip_extension(theme['screenshots'][x]);
sc += '<div class="softaculous_pro_img_screen" page="'+x+'" page-name="'+page_name+'">'+
'<div class="spro_page_selector"><input type="checkbox" checked="checked" class="checkbox" id="'+page_name+'">'+
'<label for="'+page_name+'" class="softaculous_pro_img_name">'+page_name+'</label></div>'+
'<a href="'+url+'/screenshots/'+theme['screenshots'][x] +'" class="softaculous_pro_img_views view-'+page_name+' dashicons dashicons-visibility"></a>'+
'</div>';
}
jQuery("#softaculous_pro_screenshots").html(sc);
jQuery("#spro_import_content").show();
jQuery(".softaculous-pro-back").show();
jQuery('.softaculous_pro_img_screen:first').children('a').addClass('spro_img_inview');
jQuery("#softaculous_pro_screenshots").find('.softaculous_pro_img_views').click(function(e){
e.preventDefault();
var jEle = jQuery(this);
jQuery("#softaculous_pro_display_image").hide();
jQuery(".loader").show();
if(jQuery('.softaculous_pro_img_screen .softaculous_pro_img_views').hasClass('spro_img_inview')){
jQuery('.softaculous_pro_img_screen .softaculous_pro_img_views').removeClass('spro_img_inview');
}
var newImageSrc = jEle.attr("href");
jQuery("#softaculous_pro_display_image").attr("src", newImageSrc);
// Handle image load event
jQuery("#softaculous_pro_display_image").on('load', function() {
jQuery(".loader").hide(); // Hide loader
jQuery(this).show(); // Show image
});
// In case the image is cached and loads immediately
if (jQuery("#softaculous_pro_display_image")[0].complete) {
jQuery(".loader").hide(); // Hide loader
jQuery("#softaculous_pro_display_image").show(); // Show image
}
jQuery("#softaculous_pro_display_image").parent().scrollTop(0);
jEle.addClass('spro_img_inview');
});
// need to refactor it its create multiple in html
jQuery("#softaculous_pro_screenshots").find('.softaculous_pro_img_views').on('mouseenter',function(e){
var imgUrl = jQuery(this).attr('href');
if(!jQuery(this).attr('loaded')){
jQuery('<img>').attr('src', imgUrl).on('load', function() {}).appendTo('body').css('display', 'none');
}
jQuery(this).attr('loaded',true);
});
jQuery("#softaculous_pro_screenshots").find('.spro_page_selector').click(function(event){
var jEle = jQuery(this);
jQuery("#softaculous_pro_display_image").hide();
jQuery(".loader").show();
var checkbox = jQuery(this).find('.checkbox');
if (jQuery(event.target).is('.checkbox') || jQuery(event.target).is('.softaculous_pro_img_name')) {
return;
}
jEle.siblings('.softaculous_pro_img_views').trigger('click');
});
// Change event on the checkbox
jQuery("#softaculous_pro_screenshots").find('.checkbox').change(function() {
var checked_div = jQuery(this).siblings('.softaculous_pro_img_name');
if(jQuery('.softaculous_pro_img_screen .softaculous_pro_img_views').hasClass('spro_img_inview')){
jQuery('.softaculous_pro_img_screen .softaculous_pro_img_views').removeClass('spro_img_inview');
}
var newImageSrc = jQuery(this).parent().siblings('.softaculous_pro_img_views').attr("href");
jQuery(this).parent().siblings('.softaculous_pro_img_views').addClass('spro_img_inview');
jQuery("#softaculous_pro_display_image").attr("src", newImageSrc);
jQuery("#softaculous_pro_display_image").on('load', function() {
jQuery(".loader").hide(); // Hide loader
jQuery(this).show(); // Show image
});
if (jQuery(this).is(':checked')) {
checked_div.addClass("softaculous_pro_img_selected");
} else {
checked_div.removeClass("softaculous_pro_img_selected");
}
});
}
});
}
function softaculous_pro_onboarding_dismiss(e){
jQuery.ajax({
type: 'post',
url: soft_pro_obj.ajax_url,
data: {
action: 'softaculous_pro_onboarding_dismiss',
dismiss: 1,
softaculous_pro_nonce: softaculous_pro_ajax_nonce,
data: [],
},
complete: function (response) {
window.location = soft_pro_obj.admin_url+"admin.php?page=assistant";
},
});
}
</script>
<?php
}
} disable-comments.php 0000644 00000002752 15152643500 0010512 0 ustar 00 <?php
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
add_action('admin_init', function () {
// Redirect any user trying to access comments page
global $pagenow;
if ($pagenow === 'edit-comments.php') {
wp_safe_redirect(admin_url());
exit;
}
// Disable support for comments and trackbacks in post types
foreach (get_post_types() as $post_type) {
if (post_type_supports($post_type, 'comments')) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
}
});
// Return 0 comments
add_filter('the_comments', 'softaculous_pro_the_comments', 10, 1);
function softaculous_pro_the_comments( $comments ) {
return array();
}
// Return 0 comments number
add_filter('get_comments_number', 'softaculous_pro_get_comments_number', 10, 1);
function softaculous_pro_get_comments_number( $comments_number ) {
return 0;
}
// Close comments on the front-end
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
// Hide existing comments
add_filter('comments_array', '__return_empty_array', 10, 2);
// Remove comments page in menu
add_action('admin_menu', function () {
remove_menu_page('edit-comments.php');
});
// Remove comments links from admin bar
add_action('add_admin_bar_menus', function () {
if (is_admin_bar_showing()) {
remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
}
}); bloat.php 0000644 00000024224 15152643507 0006372 0 ustar 00 <?php
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('HACKING ATTEMPT!');
}
class Bloat{
static function actions(){
global $speedycache;
// Add the filters / actions
if(!empty($speedycache->bloat['disable_xmlrpc'])){
add_filter('xmlrpc_enabled', '__return_null');
add_filter('bloginfo_url', '\SpeedyCache\Bloat::xmlrpc_remove_pingback_url', 10000, 2);
add_action('wp_loaded', '\SpeedyCache\Bloat::xmlrpc_disable');
}
// Disable DashIcons
if(!empty($speedycache->bloat['disable_dashicons'])){
add_action('wp_print_styles', '\SpeedyCache\Bloat::disable_dashicons');
}
if(!is_admin()){
// Remove jQuery migrate
if(!empty($speedycache->bloat['disable_jmigrate'])){
add_action('wp_default_scripts', '\SpeedyCache\Bloat::remove_jquery_migrate');
}
// Remove Block CSS
if(!empty($speedycache->bloat['disable_block_css'])){
add_action('wp_enqueue_scripts', '\SpeedyCache\Bloat::disable_block_editor_css');
}
// Disable Cart Fragment
if(!empty($speedycache->bloat['disable_cart_fragment'])){
add_action('wp_enqueue_scripts', '\SpeedyCache\Bloat::disable_cart_fragment', 11);
}
// Disable WooCommerce Assets
if(!empty($speedycache->bloat['disable_woo_assets'])){
add_action('wp_enqueue_scripts', '\SpeedyCache\Bloat::disable_woocommerce_assets', 99);
}
// Disale RSS Feeds
if(!empty($speedycache->bloat['disable_rss'])){
add_action('do_feed_rdf', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
add_action('do_feed_rss', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
add_action('do_feed_rss2', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
add_action('do_feed_atom', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
add_action('do_feed_rss2_comments', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
add_action('do_feed_atom_comments', '\SpeedyCache\Bloat::disable_wp_feeds', 1);
// Remove links
remove_action( 'wp_head', 'feed_links_extra', 3 );
remove_action( 'wp_head', 'feed_links', 2 );
}
}
// Disable OEmbeds
if(!empty($speedycache->bloat['disable_oembeds'])){
add_action('init', '\SpeedyCache\Bloat::disable_oembeds');
}
if(!empty($speedycache->bloat['disable_gutenberg'])){
add_filter('use_block_editor_for_post_type', '__return_false', 100);
add_filter('after_setup_theme', '\SpeedyCache\Bloat::disable_gutenberg_hooks');
}
// Limit Post revisions
if(!empty($speedycache->bloat['limit_post_revision'])){
add_filter('wp_revisions_to_keep', '\SpeedyCache\Bloat::limit_post_revisions');
}
// Update Heartbeat
if(!empty($speedycache->bloat['update_heartbeat'])){
add_action('init', '\SpeedyCache\Bloat::disable_heartbeat');
add_action('wp_enqueue_scripts', '\SpeedyCache\Bloat::disable_heartbeat');
add_action('admin_enqueue_scripts', '\SpeedyCache\Bloat::disable_heartbeat');
add_filter('heartbeat_settings', '\SpeedyCache\Bloat::change_heartbeat_interval', 100);
}
}
// Disbale XML request
static function xmlrpc_disable(){
global $pagenow;
// Is it xmlrpc.php ?
if ($pagenow === 'xmlrpc.php'){
echo 'XML-RPC is disabled';
exit();
}
}
// Disables the XML-RPC functionality
static function xmlrpc_remove_pingback_url($output, $show) {
if($show == 'pingback_url'){
$output = '';
}
return $output;
}
// Disable Dashicons
static function disable_dashicons(){
if(!is_admin_bar_showing() && !is_customize_preview()){
wp_dequeue_style('dashicons');
wp_deregister_style('dashicons');
}
}
// Remove jQuery Migrate
static function remove_jquery_migrate($scripts){
if(!is_admin() && isset($scripts->registered['jquery'])){
$script = $scripts->registered['jquery'];
if($script->deps){
$script->deps = array_diff($script->deps, array('jquery-migrate'));
}
}
}
// Disable OEmbeds
static function disable_oembeds(){
// Remove oEmbed REST API endpoint
remove_action('rest_api_init', 'wp_oembed_register_route');
// Disable oEmbed auto-discovery links
remove_action('wp_head', 'wp_oembed_add_discovery_links');
// Disable oEmbed-specific JavaScript from the front-end and back-end
remove_action('wp_head', 'wp_oembed_add_host_js');
// Remove oEmbed provider fetch URL rewriting
remove_filter('oembed_fetch_url', 'wp_oembed_rewrite_url');
// Disable oEmbed in TinyMCE editor
add_filter('tiny_mce_plugins', '\SpeedyCache\Bloat::disable_tiny_mce_oembed');
}
static function disable_tiny_mce_oembed($plugins){
return array_diff($plugins, array('wpembed'));
}
// Remove Block Editor CSS
static function disable_block_editor_css(){
wp_dequeue_style('wp-block-library');
wp_dequeue_style('wp-block-library-theme');
wp_dequeue_style('wp-block-style');
}
// Updates the count of number of post revesions.
static function limit_post_revisions($num){
global $speedycache;
if(!empty($speedycache->bloat['post_revision_count']) && $speedycache->bloat['post_revision_count'] === 'disable'){
$num = 0;
} elseif(!empty($speedycache->bloat['post_revision_count']) && is_numeric($speedycache->bloat['post_revision_count'])){
$num = intval($speedycache->bloat['post_revision_count']);
}
return $num;
}
// Updating the Heartbeat interval.
static function change_heartbeat_interval($settings){
global $speedycache;
if(!empty($speedycache->bloat['heartbeat_frequency'])){
$settings['interval'] = $speedycache->bloat['heartbeat_frequency'];
$settings['minimalInterval'] = $speedycache->bloat['heartbeat_frequency'];
}
return $settings;
}
static function disable_cart_fragment(){
if(function_exists('is_woocommerce')){
if(!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()){
wp_dequeue_script('wc-cart-fragments');
}
}
}
static function disable_woocommerce_assets(){
if(!class_exists('WooCommerce')){
return;
}
if(!is_woocommerce() && !is_cart() && !is_checkout() && !is_account_page() && !is_product() && !is_product_category() && !is_shop()){
// Disable WooCommerce stylesheets
wp_dequeue_style('woocommerce-general');
wp_dequeue_style('woocommerce-layout');
wp_dequeue_style('woocommerce-smallscreen');
wp_dequeue_style('woocommerce_frontend_styles');
wp_dequeue_style('woocommerce_fancybox_styles');
wp_dequeue_style('woocommerce_chosen_styles');
wp_dequeue_style('woocommerce_prettyPhoto_css');
// Disable WooCommerce scripts
wp_dequeue_script('wc_price_slider');
wp_dequeue_script('wc-single-product');
wp_dequeue_script('wc-add-to-cart');
wp_dequeue_script('wc-checkout');
wp_dequeue_script('wc-add-to-cart-variation');
wp_dequeue_script('wc-single-product');
wp_dequeue_script('wc-cart');
wp_dequeue_script('wc-chosen');
wp_dequeue_script('woocommerce');
wp_dequeue_script('prettyPhoto');
wp_dequeue_script('prettyPhoto-init');
wp_dequeue_script('jquery-blockui');
wp_dequeue_script('jquery-placeholder');
wp_dequeue_script('fancybox');
wp_dequeue_script('jqueryui');
}
}
static function disable_wp_feeds(){
wp_die(sprintf(esc_html__('No feed available, please visit our %1$shomepage%2$s!'),
' <a href="' . esc_url( home_url( '/' ) ) . '">',
'</a>'));
}
static function disable_heartbeat(){
global $speedycache, $pagenow;
if(empty($speedycache->bloat['disable_heartbeat'])) {
return;
}
$remove_heartbeat = false;
switch($speedycache->bloat['disable_heartbeat']){
case 'disable':
$remove_heartbeat = true;
break;
case 'editor':
if($pagenow != 'post.php' && $pagenow != 'post-new.php'){
$remove_heartbeat = true;
}
}
if(!empty($remove_heartbeat)){
wp_deregister_script('heartbeat');
//We have replaced heartbeat with an empty heartbeat to prevent any errors
wp_enqueue_script('heartbeat', SPEEDYCACHE_PRO_URL . '/assets/js/heartbeat.js', null, SPEEDYCACHE_PRO_VERSION, true);
}
}
// Disable Gutenberg
static function disable_gutenberg_hooks(){
remove_action('admin_menu', 'gutenberg_menu');
remove_action('admin_init', 'gutenberg_redirect_demo');
remove_filter('wp_refresh_nonces', 'gutenberg_add_rest_nonce_to_heartbeat_response_headers');
remove_filter('get_edit_post_link', 'gutenberg_revisions_link_to_editor');
remove_filter('wp_prepare_revision_for_js', 'gutenberg_revisions_restore');
remove_action('rest_api_init', 'gutenberg_register_rest_routes');
remove_action('rest_api_init', 'gutenberg_add_taxonomy_visibility_field');
remove_filter('rest_request_after_callbacks', 'gutenberg_filter_oembed_result');
remove_filter('registered_post_type', 'gutenberg_register_post_prepare_functions');
remove_action('do_meta_boxes', 'gutenberg_meta_box_save', 1000);
remove_action('submitpost_box', 'gutenberg_intercept_meta_box_render');
remove_action('submitpage_box', 'gutenberg_intercept_meta_box_render');
remove_action('edit_page_form', 'gutenberg_intercept_meta_box_render');
remove_action('edit_form_advanced', 'gutenberg_intercept_meta_box_render');
remove_filter('redirect_post_location', 'gutenberg_meta_box_save_redirect');
remove_filter('filter_gutenberg_meta_boxes', 'gutenberg_filter_meta_boxes');
remove_action('admin_notices', 'gutenberg_build_files_notice');
remove_filter('body_class', 'gutenberg_add_responsive_body_class');
remove_filter('admin_url', 'gutenberg_modify_add_new_button_url'); // old
remove_action('admin_enqueue_scripts', 'gutenberg_check_if_classic_needs_warning_about_blocks');
remove_filter('register_post_type_args', 'gutenberg_filter_post_type_labels');
remove_action('admin_init', 'gutenberg_add_edit_link_filters');
remove_action('admin_print_scripts-edit.php', 'gutenberg_replace_default_add_new_button');
remove_filter('redirect_post_location', 'gutenberg_redirect_to_classic_editor_when_saving_posts');
remove_filter('display_post_states', 'gutenberg_add_gutenberg_post_state');
remove_action('edit_form_top', 'gutenberg_remember_classic_editor_when_saving_posts');
}
}
googlefonts.php 0000644 00000013112 15152643507 0007611 0 ustar 00 <?php
/*
* SPEEDYCACHE
* https://speedycache.com/
* (c) SpeedyCache Team
*/
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('Hacking Attempt');
}
class GoogleFonts{
// Plucks out the google font urls from the content
static function get($content){
preg_match_all('/<link.*href=(["\'])(.*fonts\.googleapis\.com\/css.*?)\1/m', $content, $font_rels);
//We just need the index 2
if(empty($font_rels[2])){
return $content;
}
$fonts = array();
for($i = 0; $i < count($font_rels[2]); $i++){
if(empty($font_rels[2][$i])){
continue;
}
$fonts[md5($font_rels[2][$i])] = $font_rels[2][$i];
}
if(empty($fonts)){
return;
}
self::fetch($fonts);
}
// Reads the font css and saves it to /speedycache/fonts/font-name/
static function fetch($fonts){
$html = '<!DOCTYPE html>
<html>
<body>
<a href="https://speedycache.com">SpeedyCache</a>
</body>
</html>';
foreach($fonts as $font_name => $url){
$url = esc_url($url);
if(substr($url, 0, 2) === '//'){
$url = 'https:' . $url;
}
$response = wp_remote_get($url, array('user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'));
if(is_wp_error($response) || !is_array($response)){
continue;
}
$css = wp_remote_retrieve_body($response);
if(is_wp_error($css) || empty($css)){
continue;
}
if(!file_exists(speedycache_cache_path('fonts'))){
@mkdir(speedycache_cache_path('fonts'));
}
if(!file_exists(speedycache_cache_path('fonts/index.html'))){
file_put_contents(speedycache_cache_path('fonts/index.html'), $html);
}
if(!file_exists(speedycache_cache_path('fonts/').$font_name)){
@mkdir(speedycache_cache_path('fonts/').$font_name);
}
if(!file_exists(speedycache_cache_path('fonts/').$font_name . '/index.html')){
file_put_contents(speedycache_cache_path('fonts/').$font_name . '/index.html', $html);
}
preg_match_all('/url\((.*?)\)/m', $response['body'], $urls); // Get URL from the CSS we got
if(empty($urls) || empty($urls[1])){
continue;
}
foreach($urls[1] as $url){
$file_name = basename($url);
if(file_exists(speedycache_cache_path('fonts/') . $font_name . '/' . $file_name)){
continue;
}
if(strpos($url, 'display=swap') === FALSE){
$url_to_hit = add_query_arg(array('display' => 'swap'), $url);
}
$response = wp_remote_get($url_to_hit);
if(is_wp_error($response) || !is_array($response)){
continue;
}
$font = wp_remote_retrieve_body($response);
if(is_wp_error($font) || empty($font)){
continue;
}
file_put_contents(speedycache_cache_path('fonts/').$font_name.'/'.$file_name, $font); // Creating the font file
$css = str_replace($url, SPEEDYCACHE_CACHE_URL .'/'. SPEEDYCACHE_SERVER_HOST . '/fonts/'. $font_name .'/'. $file_name, $css);
}
if(file_exists(speedycache_cache_path('fonts/').$font_name.'/'.$font_name . '.css')){
return;
}
//If we need to add swap then either we failed to add display=swap to the url or it didnt return what we expected.
if(strpos($css, 'swap') === FALSE){
$css = preg_replace('/(^@font-face\s{)/m', "$1\n font-display: swap;", $css);
}
file_put_contents(speedycache_cache_path('fonts/').$font_name.'/'.$font_name . '.css', $css);
}
}
// Replaces font url to the local font url
static function replace($content){
$cache_dir = speedycache_cache_path();
if(!is_dir($cache_dir . '/fonts')){
@mkdir($cache_dir . '/fonts', 0755, true);
}
$fonts = array_diff(@scandir($cache_dir . 'fonts'), array('..', '.'));
if(empty($fonts)){
return $content;
}
// To remove any preload or dns-fetch or preconnect for google fonts
preg_match_all('/<link(?:[^>]+)?href=(["\'])([^>]*?fonts\.(gstatic|googleapis)\.com.*?)\1.*?>/i', $content, $google_links, PREG_SET_ORDER);
if(!empty($google_links)){
foreach($google_links as $google_link){
preg_match('/rel=(["\'])(.*?(preload|preconnect|dns-fetch).*?)\1/i', $google_link[2], $removeable_link);
if(!empty($removeable_link)){
$content = str_replace($google, '', $html);
}
}
}
/**
* Our Font css name is in md5(created from the font URL) and we dont have URL in this function to get
* all the google fonts url to replace the fonts .
*/
preg_match_all('/<link.*href=(["\'])(.*fonts\.googleapis\.com\/css.*?)\1/m', $content, $font_rels);
if(empty($font_rels[2])){
return $content;
}
foreach($font_rels[2] as $url){
foreach($fonts as $font){
if(in_array($font, array('.', '..'))){
continue;
}
if(!file_exists($cache_dir . 'fonts/' . $font . '/' . $font . '.css')){
continue;
}
$css_url = SPEEDYCACHE_CACHE_URL .'/'. SPEEDYCACHE_SERVER_HOST . '/fonts/' . $font . '/' . $font . '.css';
if(md5($url) === $font){
$content = preg_replace('/<link(.*)href=(["\'])(.*fonts\.googleapis\.com\/css.*?)\2/m', '<link$1 href="'.$css_url .'" ', $content);
}
}
}
return $content;
}
static function add_swap($content){
$content = str_replace('&display=swap', '', $content);
$content = str_replace('&display=swap', '', $content);
// Add font-display=swap as a querty parameter to Google fonts
$content = str_replace('googleapis.com/css?family', 'googleapis.com/css?display=swap&family', $content);
return $content;
}
}
commoncss.php 0000644 00000007154 15152643507 0007275 0 ustar 00 <?php
/*
* SPEEDYCACHE
* https://speedycache.com/
* (c) SpeedyCache Team
*/
namespace SpeedyCache;
if(!defined('ABSPATH')){
die('Hacking Attempt!');
}
class CommonCss{
static function get_endpoint($is_unusedcss = false){
global $speedycache;
$endpoints = get_transient('speedycache_ccss_endpoint');
$target_file = empty($is_unusedcss) ? 'index.php' : 'ucss.php';
$mirror = 'https://s4.softaculous.com/a/speedycache/critical-css/' . $target_file;
$license = strpos($speedycache->license['license'], 'SPDFY') !== 0 ? '' : $speedycache->license['license'];
if(empty($endpoints)){
$res = wp_remote_get(SPEEDYCACHE_API.'license.php?license='.$license.'&url='.rawurlencode(site_url()));
// Did we get a response ?
if(!is_array($res)){
return $mirror;
}
if(empty($res['body'])){
return $mirror;
}
$body = json_decode($res['body'], true);
if(empty($body['fast_mirrors'])){
return $mirror;
}
$endpoints = $body['fast_mirrors'];
if(empty($endpoints) || !is_array($endpoints)){
return $mirror;
}
}
$index = floor(rand(0, count($endpoints) - 1));
if(empty($endpoints[$index])){
return $mirror;
}
set_transient('speedycache_ccss_endpoint', $endpoints, 180);
$mirror = str_replace('a/softaculous', 'a/speedycache/critical-css/'.$target_file, $endpoints[$index]);
return $mirror;
}
static function schedule($schedule_name, $urls){
$scheduled = self::get_schedule(array($schedule_name));
$time = time();
if(!empty($scheduled) && isset(end($scheduled)['time'])){
// getting the last index to get the last scheduled event
$time = end($scheduled)['time'] + 10;
}
$final_schd_time = $time;
if(!wp_next_scheduled($schedule_name, array('urls' => $urls))){
wp_schedule_single_event($final_schd_time, $schedule_name, array('urls' => $urls));
}
}
// Returns an array of cron event "speedycache_unused_css"
static function get_schedule($event_name){
$cron = _get_cron_array();
if(empty($cron)){
return false;
}
$scheduled = array();
foreach($cron as $key => $crn){
foreach($crn as $e_key => $event){
if(!in_array($e_key, $event_name)){
continue;
}
$args = [];
foreach($event as $evt){
if(!empty($evt['args'][0])){
$args = $evt['args'][0];
}
}
array_push($scheduled, array('name' => get_the_title($args), 'time' => $key));
}
}
return $scheduled;
}
// Adds the Critical CSS to the cache file
static function update_cached($file, $css){
global $speedycache;
if(!file_exists($file)){
return;
}
$content = file_get_contents($file);
if(empty($content)){
return;
}
$content = static::update_content($content, $css);
// Updates the .html.gz file
if(!empty($speedycache->options['gzip'])){
self::update_gzip($file, $content);
}
// Updates the .html file
file_put_contents($file, $content);
}
static function update_gzip($file, $content){
$gz_file = str_replace('.html', '.html.gz', $file);
if(file_exists($gz_file)){
unlink($gz_file);
}
$content = gzencode($content, 6);
if(!empty($content)){
file_put_contents($gz_file, $content);
}
}
static function log($log_name, $message, $url = '-'){
$ccss_logs = get_option($log_name, []);
if(count($ccss_logs) > 10){
array_shift($ccss_logs);
}
$ccss_logs[$url] = array('time' => date('h:i:s'), 'message' => $message);
update_option($log_name, $ccss_logs);
}
} youtube.html 0000644 00000004451 15152643507 0007142 0 ustar 00 <html>
<head>
<style type="text/css">
body{background-color:#000;color:#fff;font:12px Roboto,Arial,sans-serif;height:100%;margin:0;overflow:hidden;padding:0;position:absolute;width:100%}
.y{background-position:center center;background-repeat:no-repeat;background-size:cover;height:100%;position:absolute;width:100%}
.yb{position:absolute;cursor:pointer;width:90px;height:60px;background-color:#333;box-shadow:0 0 30px rgba(0,0,0,0.6);z-index:1;opacity:.8;border-radius:6px}
.yb:before{content:"";border-style:solid;border-width:15px 0 15px 26px;border-color:transparent transparent transparent #fff}
.yb, .yb:before{position:absolute;top:50%;left:50%;transform:translate3d(-50%,-50%,0)}
.yb:hover{background-color:#ff0000;}
iframe{position:absolute;height:100%;width:100%;top:0;left:0;}
</style>
<script type="text/javascript">
var i=location.hash.match(/\#([^\?]+)/);
function img(){
var q = window.innerWidth < 321 ? "mqdefault" : (window.innerWidth > 320 && window.innerWidth < 481 ? "hqdefault" : (window.innerWidth > 480 && window.innerWidth < 750 ? "sddefault" : "maxresdefault"));
var img = document.createElement("IMG");
img.setAttribute( "src", 'https://i.ytimg.com/vi/' + i[1] + '/' + q + '.webp');
img.addEventListener('load', function(e){
if(e.target.width == 120 && e.target.height == 90 && window.innerWidth > 320){
e.target.setAttribute( 'src', 'https://i.ytimg.com/vi/' + i[1] + '/' + "hqdefault" + '.jpg');
}
document.getElementById("d").style['background-image'] = 'url(' + e.target.src + ')';
});
document.getElementById('d').addEventListener('click', function(){
var start = window.location.hash.match(/[^a-zA-Z\d\s:](start\=\d+)/i);
var hash = ["rel=0", "showinfo=0", "autoplay=1"];
var ifrm = document.createElement("iframe");
if(start){hash.push(start[1]);}
ifrm.setAttribute("frameborder", "0");
ifrm.setAttribute("allowfullscreen", "");
ifrm.setAttribute("allow", "autoplay");
ifrm.setAttribute( "src", "https://www.youtube.com/embed/"+ i[1] +"?" + hash.join("&"));
this.innerHTML = "";
this.appendChild(ifrm);
});
};
window.addEventListener('resize', function(){img();});
window.addEventListener('load', function(){img();});
</script>
</head>
<body>
<div id="d" class="y">
<div class="yb"></div>
</div>
</body>
</html>