Headline
CVE-2023-1028: Diff [2869205:2870465] for wp-meta-seo/trunk – WordPress Plugin Repository
The WP Meta SEO plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 4.5.3. This is due to missing or incorrect nonce validation on the setIgnore function. This makes it possible for unauthenticated attackers to update plugin options via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.
11<?php 22/* Prohibit direct script loading */ 33defined(‘ABSPATH’) || die(‘No direct script access allowed!’); 44 55/** 66 * Class MetaSeoAdmin 77 * Class that holds most of the admin functionality for Meta SEO. 88 */ 99class MetaSeoAdmin 1010{ 1111 1212 /** 1313 * Current page 1414 * 1515 * @var mixed 1616 */ 1717 private $pagenow; 1818 /** 1919 * Max length meta description 2020 * 2121 * @var integer 2222 */ 2323 public static $desc_length = 158; 2424 /** 2525 * Max length meta title 2626 * 2727 * @var integer 2828 */ 2929 public static $title_length = 60; 3030 /** 3131 * Google client 3232 * 3333 * @var object 3434 */ 3535 public $client; 3636 /** 3737 * Default access to connect to google 3838 * 3939 * @var array 4040 */ 4141 public $access = array(WPMS_CLIENTID, WPMS_CLIENTSECRET); 4242 /** 4343 * Error timeout 4444 * 4545 * @var integer 4646 */ 4747 public $error_timeout; 4848 /** 4949 * List google analytics options 5050 * 5151 * @var array 5252 */ 5353 public $ga_tracking; 5454 /** 5555 * Option to check connect status 5656 * 5757 * @var array 5858 */ 5959 public $gaDisconnect; 6060 /** 6161 * Google alanytics options 6262 * 6363 * @var array 6464 */ 6565 public $google_alanytics; 6666 6767 /** 6868 * Google Tag Manager options setting 6969 * 7070 * @var Google tag manager options 7171 */ 7272 public $google_tagmanager; 7373 7474 /** 7575 * All settings for meta seo 7676 * 7777 * @var array 7878 */ 7979 public $settings; 8080 8181 /** 8282 * Google service 8383 * 8484 * @var object 8585 */ 8686 public $service; 8787 8888 /** 8989 * MetaSeoAdmin constructor. 9090 */ 9191 public function __construct() 9292 { 9393 $this->pagenow = $GLOBALS[‘pagenow’]; 9494 $this->setErrorTimeout(); 9595 $this->initSettings(); 9696 $this->initGaSettings(); 9797 $this->initGADisconnect(); 9898 if (!get_option('_wpms_dash_last_update’, false)) { 9999 update_option('_wpms_dash_last_update’, time()); 100100 } 101101 102102 add_action('admin_init’, array($this, ‘adminRedirects’)); 103103 add_action('init’, array($this, ‘install’)); 104104 add_action('admin_init’, array($this, ‘adminInit’)); 105105 add_action('init’, array($this, ‘loadLangguage’)); 106106 add_action('admin_menu’, array($this, ‘addMenuPage’)); 107107 /** 108108 * Load admin js 109109 */ 110110 add_action('admin_enqueue_scripts’, array($this, ‘loadAdminScripts’)); 111111 112112 if (!class_exists(‘MetaSeoContentListTable’)) { 113113 require_once(WPMETASEO_PLUGIN_DIR . ‘/inc/class.metaseo-content-list-table.php’); 114114 } 115115 add_action('added_post_meta’, array('MetaSeoContentListTable’, ‘updateMetaSync’), 99, 4); 116116 add_action('updated_post_meta’, array('MetaSeoContentListTable’, ‘updateMetaSync’), 99, 4); 117117 add_action('deleted_post_meta’, array('MetaSeoContentListTable’, ‘deleteMetaSync’), 99, 4); 118118 119119 if (!get_option('wpms_set_ignore’, false)) { 120120 add_option('wpms_set_ignore’, 1, '’, ‘yes’); 121121 } 122122 123123 add_action('wp_ajax_wpms_set_ignore’, array($this, ‘setIgnore’)); 124124 if (0 === (int)get_option(‘blog_public’)) { 125125 add_action('admin_notices’, array($this, ‘publicWarning’)); 126126 } 127127 add_action('wp_enqueue_editor’, array($this, ‘linkTitleField’), 20); 128128 129129 if (!class_exists(‘MetaSeoBrokenLinkTable’)) { 130130 require_once(WPMETASEO_PLUGIN_DIR . ‘/inc/class.metaseo-broken-link-table.php’); 131131 } 132132 add_action('post_updated’, array('MetaSeoBrokenLinkTable’, ‘updatePost’), 10, 3); 133133 add_action('delete_post’, array('MetaSeoBrokenLinkTable’, ‘deletePost’)); 134134 add_action('edit_comment’, array('MetaSeoBrokenLinkTable’, ‘updateComment’)); 135135 add_action('deleted_comment’, array('MetaSeoBrokenLinkTable’, ‘deletedComment’)); 136136 add_action('admin_head’, array('MetaSeoContentListTable’, ‘customStyles’)); 137137 138138 add_action('admin_footer’, array($this, ‘editorFooter’)); 139139 add_action('wp_dashboard_setup’, array($this, ‘addDashboardWidgets’)); 140140 add_action('category_add_form_fields’, array($this, ‘categoryField’), 10, 2); 141141 add_action('category_edit_form_fields’, array($this, ‘editCategoryFields’)); 142142 add_action('edited_category’, array($this, ‘saveCategoryMeta’), 10, 2); 143143 add_action('create_category’, array($this, ‘saveCategoryMeta’), 10, 2); 144144 145145 if (!class_exists(‘MetaSeoImageListTable’)) { 146146 require_once(WPMETASEO_PLUGIN_DIR . ‘/inc/class.metaseo-image-list-table.php’); 147147 } 148148 add_action('post_updated’, array('MetaSeoImageListTable’, ‘updatePost’), 10, 3); 149149 add_action('delete_post’, array('MetaSeoImageListTable’, ‘deletePost’)); 150150 151151 // Category meta hook 152152 add_action('admin_head’, array('WPMSCategoryMetaTable’, ‘customStyles’)); 153153 154154 if (is_plugin_active(WPMSEO_ADDON_FILENAME)) { 155155 add_action('product_cat_add_form_fields’, array($this, ‘categoryField’)); 156156 add_action('product_cat_edit_form_fields’, array($this, ‘editCategoryFields’), 10); 157157 add_action('created_term’, array($this, ‘saveCategoryMeta’), 10, 3); 158158 add_action('edit_term’, array($this, ‘saveCategoryMeta’), 10, 3); 159159 } 160160 add_action('wp_ajax_wpms’, array($this, ‘startProcess’)); 161161 add_action('wp_ajax_wpms_gg_save_information’, array($this, ‘wpmsGGSaveInformation’)); 162162 add_filter('wpms_the_content’, array($this, ‘wpmsTheContent’), 10, 2); 163163 164164 $settings = get_option(‘_metaseo_settings’); 165165 if (isset($settings[‘metaseo_removecatprefix’]) && $settings[‘metaseo_removecatprefix’] === ‘1’) { 166166 add_action('created_category’, array($this, ‘wpmsScheduleRewriteFlush’)); 167167 add_action('edited_category’, array($this, ‘wpmsScheduleRewriteFlush’)); 168168 add_action('delete_category’, array($this, ‘wpmsScheduleRewriteFlush’)); 169169 } 170170 } 171171 172172 /** 173173 * Init Meta seo settings 174174 * 175175 * @return void 176176 */ 177177 public function initSettings() 178178 { 179179 $this->settings = wpmsGetDefaultSettings(); 180180 $settings = get_option(‘_metaseo_settings’); 181181 182182 if (is_array($settings)) { 183183 $this->settings = array_merge($this->settings, $settings); 184184 } 185185 186186 if ((isset($this->settings[‘metaseo_showtmetablock’]) && (int)$this->settings[‘metaseo_showtmetablock’] === 1)) { 187187 $this->loadMetaBoxes(); 188188 } 189189 } 190190 191191 /** 192192 * Init google analytics tracking options 193193 * 194194 * @return void 195195 */ 196196 public function initGaSettings() 197197 { 198198 $this->ga_tracking = array( 199199 ‘wpmsga_dash_tracking’ => 1, 200200 ‘wpmsga_dash_tracking_type’ => 'universal’, 201201 ‘wpmsga_dash_anonim’ => 0, 202202 ‘wpmsga_dash_remarketing’ => 0, 203203 ‘wpmsga_event_tracking’ => 0, 204204 ‘wpmsga_event_downloads’ => 'zip|mp3*|mpe*g|pdf|docx*|pptx*|xlsx*|rar*’, 205205 ‘wpmsga_aff_tracking’ => 0, 206206 ‘wpmsga_event_affiliates’ => '/out/’, 207207 ‘wpmsga_hash_tracking’ => 0, 208208 ‘wpmsga_author_dimindex’ => 0, 209209 ‘wpmsga_pubyear_dimindex’ => 0, 210210 ‘wpmsga_category_dimindex’ => 0, 211211 ‘wpmsga_user_dimindex’ => 0, 212212 ‘wpmsga_tag_dimindex’ => 0, 213213 ‘wpmsga_speed_samplerate’ => 1, 214214 ‘wpmsga_event_bouncerate’ => 0, 215215 ‘wpmsga_enhanced_links’ => 0, 216216 ‘wpmsga_dash_adsense’ => 0, 217217 ‘wpmsga_crossdomain_tracking’ => 0, 218218 ‘wpmsga_crossdomain_list’ => '’, 219219 ‘wpmsga_cookiedomain’ => '’, 220220 ‘wpmsga_cookiename’ => '’, 221221 ‘wpmsga_cookieexpires’ => '’, 222222 ‘wpmsga_track_exclude’ => array(), 223223 ‘wpmsga_code_tracking’ => ‘’ 224224 ); 225225 } 226226 227227 /** 228228 * Init GTM setting 229229 * 230230 * @return void 231231 */ 232232 public function initGADisconnect() 233233 { 234234 $this->gaDisconnect = array( 235235 ‘wpms_gg_service_tracking_id’ => '’, 236236 ‘wpms_gg_service_tracking_type’ => 'universal’, 237237 ‘wpmsga_code_tracking’ => '’, 238238 ‘wpmstm_header_code_tracking’ => '’, 239239 ‘wpmstm_body_code_tracking’ => ‘’ 240240 ); 241241 } 242242 243243 /** 244244 * Ajax request google tag manager containers list 245245 * 246246 * @return mixed 247247 */ 248248 public function tagmanagerContainersReport() 249249 { 250250 if (empty($_POST[‘wpms_nonce’]) 251251 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 252252 die(); 253253 } 254254 $accont_id = $_POST[‘accountID’]; 255255 if (isset($accont_id) && $accont_id) { 256256 $accont_id = sanitize_text_field($accont_id); 257257 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/google-tag-manager/wpms-tagmanager-api.php’); 258258 $wpmstm = new WpmsTagManagerController(); 259259 $list_containers = $wpmstm->getListContainers($accont_id); 260260 $this->google_tagmanager = get_option(‘wpms_tagmanager_setting’); 261261 $listsContainer = $list_containers->getContainer(); 262262 $lists = array(); 263263 foreach ($listsContainer as $container) { 264264 $lists[] = array( 265265 ‘containerId’ => $container->getContainerId(), 266266 ‘name’ => $container->getName(), 267267 ‘path’ => $container->getPath(), 268268 ‘publicId’ => $container->getPublicId(), 269269 ‘usageContext’ => $container->getUsageContext(), 270270 ‘notes’ => $container->getNotes(), 271271 ); 272272 } 273273 $this->google_tagmanager[‘list_containers’] = $lists; 274274 update_option('wpms_tagmanager_setting’, $this->google_tagmanager); 275275 return wp_send_json($list_containers->getContainer()); 276276 } 277277 } 278278 279279 /** 280280 * Ajax return tag manager container information 281281 * 282282 * @return mixed 283283 */ 284284 public function tagmanagerContainerInfo() 285285 { 286286 if (empty($_POST[‘wpms_nonce’]) 287287 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 288288 die(); 289289 } 290290 $container_id = $_POST[‘containerID’]; 291291 if (isset($container_id) && $container_id) { 292292 $container_id = sanitize_text_field($container_id); 293293 $gg_tagmanager = get_option(‘wpms_tagmanager_setting’); 294294 $gg_tagmanager_containers = $gg_tagmanager[‘list_containers’]; 295295 $containerIndex = 0; 296296 foreach ($gg_tagmanager_containers as $container) { 297297 if ($container[‘containerId’] === $container_id) { 298298 break; 299299 } 300300 $containerIndex++; 301301 } 302302 303303 return wp_send_json($gg_tagmanager_containers[$containerIndex]); 304304 } 305305 } 306306 307307 /** 308308 * Ajax refresh tag manager connect 309309 * 310310 * @return mixed 311311 */ 312312 public function tagmanagerRefreshConnect() 313313 { 314314 // Update list accounts tag managers 315315 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/google-tag-manager/wpms-tagmanager-api.php’); 316316 $wpmstm_controller = new WpmsTagManagerController(); 317317 $wpmstm_listAccounts = $wpmstm_controller->getListAccounts(); 318318 $wpmstm_accounts = $wpmstm_listAccounts->getAccount(); 319319 if (isset($wpmstm_accounts[0])) { 320320 $lists_acc = array(); 321321 foreach ($wpmstm_accounts as $account) { 322322 $lists_acc[] = array( 323323 ‘accountId’ => $account->getAccountId(), 324324 ‘name’ => $account->getName(), 325325 ‘path’ => $account->getPath(), 326326 ); 327327 } 328328 $this->google_tagmanager[‘list_accounts’] = $lists_acc; 329329 update_option('wpms_tagmanager_setting’, $this->google_tagmanager); 330330 return wp_send_json($this->google_tagmanager[‘list_accounts’]); 331331 } else { 332332 return false; 333333 } 334334 } 335335 336336 /** 337337 * Admin init 338338 * 339339 * @return void 340340 */ 341341 public function adminInit() 342342 { 343343 $this->createDatabase(); 344344 $this->updateLinksTable(); 345345 346346 // Column Content. 347347 $this->registerPostColumns(); 348348 add_filter('metaseo_seokeywords_details_column’, array($this, ‘getColumnSeoKeywordsDetails’), 5); 349349 } 350350 351351 /** 352352 * Add category meta field 353353 * 354354 * @return void 355355 */ 356356 public function categoryField() 357357 { 358358 wp_enqueue_style(‘wpms-tippy-style’); 359359 wp_enqueue_script(‘wpms-tippy-core’); 360360 wp_enqueue_script(‘wpms-tippy’); 361361 wp_enqueue_script(‘wpms-my-tippy’); 362362 363363 wp_enqueue_style(‘wpms-category-field’); 364364 wp_enqueue_script(‘wpms-category-field’); 365365 // this will add the custom meta field to the add new term page 366366 ?> 367367 <div class="form-field"> 368368 <label class="wpms_custom_cat_field" 369369 data-tippy="<?php esc_attr_e('This is the title of your content that may be displayed in search engine 370370 results (meta title). By default it’s the content title (page title, post title…). 371371 69 characters max allowed.’, ‘wp-meta-seo’) ?>"> 372372 <?php esc_html_e('Search engine title’, ‘wp-meta-seo’); ?> 373373 </label> 374374 <label> 375375 <textarea name="wpms_category_metatitle" class="wpms_category_metatitle"></textarea> 376376 <br/> 377377 </label> 378378 <div class="cat-title-len"><?php echo esc_html(MPMSCAT_TITLE_LENGTH); ?></div> 379379 </div> 380380 381381 <?php 382382 $settings = get_option(‘_metaseo_settings’); 383383 if (isset($settings[‘metaseo_showkeywords’]) && (int)$settings[‘metaseo_showkeywords’] === 1) : 384384 ?> 385385 <div class="form-field" style="margin-top: 20px;margin-bottom: 20px;"> 386386 <label class="wpms_custom_cat_field" 387387 data-tippy="<?php esc_attr_e('This is the keywords of your content that may be 388388 displayed in search engine results (meta keywords).’, ‘wp-meta-seo’) ?>"> 389389 <?php esc_html_e('Search engine keywords’, ‘wp-meta-seo’); ?> 390390 </label> 391391 <label> 392392 <textarea name="wpms_category_metakeywords" class="wpms_cat_keywords"></textarea><br/> 393393 </label> 394394 <div class="cat-keywords-len"><?php echo esc_html(MPMSCAT_KEYWORDS_LENGTH); ?></div> 395395 </div> 396396 <?php endif; ?> 397397 <div class="form-field" style="margin-top: 20px;margin-bottom: 20px;"> 398398 <label for="extra1" class="wpms_custom_cat_field" 399399 data-tippy="<?php esc_attr_e('This is the title of your content that may be displayed in search 400400 engine results (meta title). By default it’s the content title (page title, post title…). 401401 69 characters max allowed.’, ‘wp-meta-seo’) ?>"> 402402 <?php esc_html_e('Search engine description’, ‘wp-meta-seo’); ?> 403403 </label> 404404 <label> 405405 <textarea name="wpms_category_metadesc" class="wpms_category_metadesc"></textarea><br/> 406406 <input type="hidden" name="wpms_nonce" value="<?php echo esc_attr(wp_create_nonce(‘wpms_nonce’)) ?>"> 407407 </label> 408408 <div class="cat-desc-len"><?php echo esc_html(MPMSCAT_DESC_LENGTH); ?></div> 409409 </div> 410410 <?php 411411 if (isset($settings[‘metaseo_canonical’]) && (int)$settings[‘metaseo_canonical’] === 1) : ?> 412412 <div class="form-field" style="margin-top: 20px;margin-bottom: 20px;"> 413413 <label class="wpms_custom_cat_field" 414414 data-tippy="<?php esc_attr_e('Put the canonical URL which this page should point to. By default, it\’s the permalink’, ‘wp-meta-seo’) ?>"> 415415 <?php esc_html_e('Canonical URL’, ‘wp-meta-seo’); ?> 416416 </label> 417417 <label> 418418 <textarea name="wpms_category_canonical" class="wpms_category_canonical"></textarea><br/> 419419 </label> 420420 </div> 421421 <?php endif; 422422 } 423423 424424 /** 425425 * Save category meta 426426 * 427427 * @param integer $term_id Current category id 428428 * 429429 * @return void 430430 */ 431431 public function saveCategoryMeta($term_id) 432432 { 433433 global $pagenow; 434434 // phpcs:disable WordPress.Security.NonceVerification.Missing – Nonce used in next lines 435435 if ($pagenow === ‘edit-tags.php’ || (isset($_POST[‘action’], $_POST[‘screen’]) && $_POST[‘action’] === ‘add-tag’ && ($_POST[‘screen’] === ‘edit-category’ || $_POST[‘screen’] === ‘edit-product_cat’))) { 436436 if (isset($_POST[‘taxonomy’]) && ($_POST[‘taxonomy’] === ‘product_cat’ || $_POST[‘taxonomy’] === ‘category’)) { 437437 if (empty($_POST[‘wpms_nonce’]) 438438 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 439439 die(); 440440 } 441441 442442 if (isset($_POST[‘wpms_category_metatitle’])) { 443443 update_term_meta($term_id, 'wpms_category_metatitle’, $_POST[‘wpms_category_metatitle’]); 444444 } 445445 446446 if (isset($_POST[‘wpms_category_metadesc’])) { 447447 update_term_meta($term_id, 'wpms_category_metadesc’, $_POST[‘wpms_category_metadesc’]); 448448 } 449449 450450 $settings = get_option(‘_metaseo_settings’); 451451 if (isset($settings[‘metaseo_showkeywords’]) && (int)$settings[‘metaseo_showkeywords’] === 1) { 452452 if (isset($_POST[‘wpms_category_metakeywords’])) { 453453 update_term_meta($term_id, 'wpms_category_metakeywords’, $_POST[‘wpms_category_metakeywords’]); 454454 } 455455 } 456456 457457 if (isset($settings[‘metaseo_canonical’]) && (int)$settings[‘metaseo_canonical’] === 1) { 458458 if (isset($_POST[‘wpms_category_canonical’])) { 459459 // Set link to field 460460 $canonical = self::convertCanonicalUrlToSave($_POST[‘wpms_category_canonical’]); 461461 462462 update_term_meta($term_id, 'wpms_category_canonical’, $canonical); 463463 } 464464 } 465465 } 466466 } 467467 //phpcs:enable 468468 } 469469 470470 /** 471471 * Add extra fields to category edit form callback function 472472 * 473473 * @param object $tag Current category 474474 * 475475 * @return void 476476 */ 477477 public function editCategoryFields($tag) 478478 { 479479 wp_enqueue_style(‘wpms-tippy-style’); 480480 wp_enqueue_script(‘wpms-tippy-core’); 481481 wp_enqueue_script(‘wpms-tippy’); 482482 wp_enqueue_script(‘wpms-my-tippy’); 483483 484484 wp_enqueue_style(‘wpms-category-field’); 485485 wp_enqueue_script(‘wpms-category-field’); 486486 $t_id = $tag->term_id; 487487 $metatitle = get_term_meta($t_id, 'wpms_category_metatitle’, true); 488488 $metadesc = get_term_meta($t_id, 'wpms_category_metadesc’, true); 489489 $metakeywords = get_term_meta($t_id, 'wpms_category_metakeywords’, true); 490490 $metacanonical = get_term_meta($t_id, 'wpms_category_canonical’, true); 491491 $metacanonical = self::convertCanonicalUrlToDisplay($metacanonical); 492492 ?> 493493 <tr class="form-field"> 494494 <th scope="row" valign="top"> 495495 <label class="wpms_custom_cat_field" data-tippy="<?php esc_attr_e('This is the title of your content that may 496496 be displayed in search engine results (meta title). By default it’s the content title 497497 (page title, post title…).69 characters max allowed.’, ‘wp-meta-seo’) ?>"> 498498 <?php esc_html_e('Search engine title’, ‘wp-meta-seo’); ?> 499499 </label> 500500 </th> 501501 <td> 502502 <label> 503503 <?php if ((!empty($metatitle))) : ?> 504504 <textarea name="wpms_category_metatitle" 505505 class="wpms_category_metatitle"><?php echo esc_textarea($metatitle); ?></textarea> 506506 <?php else : ?> 507507 <textarea name="wpms_category_metatitle" 508508 class="wpms_category_metatitle"></textarea> 509509 <?php endif; ?> 510510 <br/> 511511 </label> 512512 <div class="cat-title-len"> 513513 <?php 514514 echo esc_html($metatitle ? MPMSCAT_TITLE_LENGTH - strlen($metatitle) : MPMSCAT_TITLE_LENGTH); 515515 ?> 516516 </div> 517517 </td> 518518 </tr> 519519 520520 <?php 521521 $settings = get_option(‘_metaseo_settings’); 522522 if (isset($settings[‘metaseo_showkeywords’]) && (int)$settings[‘metaseo_showkeywords’] === 1) : 523523 ?> 524524 <tr class="form-field"> 525525 <th scope="row" valign="top"> 526526 <label for="extra1" class="wpms_custom_cat_field" 527527 data-tippy="<?php esc_attr_e('This is the keywords of your content that may be 528528 displayed in search engine results (meta keywords).’, ‘wp-meta-seo’) ?>"> 529529 <?php esc_html_e('Search engine keywords’, ‘wp-meta-seo’); ?> 530530 </label> 531531 </th> 532532 <td> 533533 <label> 534534 <?php if ((!empty($metakeywords))) : ?> 535535 <textarea name="wpms_category_metakeywords" 536536 class="wpms_cat_keywords"><?php echo esc_textarea($metakeywords); ?></textarea> 537537 <?php else : ?> 538538 <textarea name="wpms_category_metakeywords" 539539 class="wpms_cat_keywords"></textarea> 540540 <?php endif; ?> 541541 <br/> 542542 </label> 543543 544544 <div class="cat-keywords-len"> 545545 <?php 546546 echo esc_html($metakeywords ? MPMSCAT_KEYWORDS_LENGTH - strlen($metakeywords) : MPMSCAT_KEYWORDS_LENGTH); 547547 ?> 548548 </div> 549549 </td> 550550 </tr> 551551 <?php endif; ?> 552552 <tr class="form-field"> 553553 <th scope="row" valign="top"> 554554 <label for="extra1" class="wpms_custom_cat_field" 555555 data-tippy="<?php esc_attr_e('This is the title of your content that may be displayed in 556556 search engine results (meta title). By default it’s the content title (page title, post title…). 557557 69 characters max allowed.’, ‘wp-meta-seo’) ?>"> 558558 <?php esc_html_e('Search engine description’, ‘wp-meta-seo’); ?> 559559 </label> 560560 </th> 561561 <td> 562562 <label> 563563 <?php if ((!empty($metadesc))) : ?> 564564 <textarea name="wpms_category_metadesc" 565565 class="wpms_category_metadesc"><?php echo esc_textarea($metadesc); ?></textarea> 566566 <?php else : ?> 567567 <textarea name="wpms_category_metadesc" 568568 class="wpms_category_metadesc"></textarea> 569569 <?php endif; ?> 570570 <br/> 571571 </label> 572572 <input type="hidden" name="wpms_nonce" value="<?php echo esc_attr(wp_create_nonce(‘wpms_nonce’)) ?>"> 573573 <div class="cat-desc-len"> 574574 <?php echo esc_html($metadesc ? MPMSCAT_DESC_LENGTH - strlen($metadesc) : MPMSCAT_DESC_LENGTH); ?> 575575 </div> 576576 </td> 577577 </tr> 578578 <?php 579579 if (isset($settings[‘metaseo_canonical’]) && (int)$settings[‘metaseo_canonical’] === 1) : ?> 580580 <tr class="form-field"> 581581 <th scope="row" valign="top"> 582582 <label for="extra1" class="wpms_custom_cat_field" 583583 data-tippy="<?php esc_attr_e('Put the canonical URL which this page should point to. By default, it\’s the permalink’, ‘wp-meta-seo’) ?>"> 584584 <?php esc_html_e('Canonical URL’, ‘wp-meta-seo’); ?> 585585 </label> 586586 </th> 587587 <td> 588588 <label> 589589 <?php if ((!empty($metacanonical))) : ?> 590590 <textarea name="wpms_category_canonical" 591591 class="wpms_category_canonical"><?php echo esc_textarea($metacanonical); ?></textarea> 592592 <?php else : ?> 593593 <textarea name="wpms_category_canonical" 594594 class="wpms_category_canonical"></textarea> 595595 <?php endif; ?> 596596 <br/> 597597 </label> 598598 </td> 599599 </tr> 600600 <?php endif; 601601 } 602602 603603 /** 604604 * Function that outputs the contents of the dashboard widget 605605 * 606606 * @return void 607607 */ 608608 public function dashboardWidget() 609609 { 610610 wp_enqueue_style(‘wpms-tippy-style’); 611611 wp_enqueue_style(‘wpms-mytippy-style’); 612612 wp_enqueue_script(‘wpms-tippy-core’); 613613 wp_enqueue_script(‘wpms-tippy’); 614614 wp_enqueue_script(‘wpms-my-tippy’); 615615 wp_enqueue_style(‘wpms-dashboard-widgets’); 616616 wp_enqueue_script( 617617 'wpms-dashboard-widgets’, 618618 plugins_url('assets/js/dashboard_widgets/dashboard_widgets.js’, dirname(__FILE__)), 619619 array(‘jquery’), 620620 WPMSEO_VERSION 621621 ); 622622 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/dashboard-widgets/dashboard_widgets.php’); 623623 } 624624 625625 /** 626626 * Generate dasboard Analytics widget 627627 * 628628 * @return void 629629 */ 630630 public function dashboardAnalyticsWidget() 631631 { 632632 // Jsapi 633633 $lang = get_bloginfo(‘language’); 634634 $lang = explode('-', $lang); 635635 $lang = $lang[0]; 636636 wp_enqueue_script( 637637 'wpmsgooglejsapi’, 638638 ‘https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22language%22%3A%22’ . $lang . '%22%2C%22packages%22%3A%5B%22corechart%22%2C%20%22imagechart%22%2C%20%22table%22%2C%20%22orgchart%22%2C%20%22geochart%22%5D%7D%5D%7D’, 639639 array(), 640640 null 641641 ); 642642 // WPMS style 643643 wp_enqueue_style( 644644 'wpms-dashboard-analytics-widgets’, 645645 plugins_url('assets/css/dashboard-widgets/analytics-widgets.css’, dirname(__FILE__)), 646646 array(), 647647 WPMSEO_VERSION 648648 ); 649649 // WPMS script 650650 wp_enqueue_script( 651651 'wpms-dashboard-analytics-widgets’, 652652 plugins_url('assets/js/dashboard_widgets/analytics-widgets.js’, dirname(__FILE__)), 653653 array(‘jquery’), 654654 WPMSEO_VERSION, 655655 true 656656 ); 657657 658658 wp_localize_script('wpms-dashboard-analytics-widgets’, 'wpmsDashboardAnalytics’, $this->localizeDashoardWidgets()); 659659 660660 $requestDates = array( 661661 array(‘value’ => 'today’, ‘html’ => ‘TODAY’), 662662 array(‘value’ => 'yesterday’, ‘html’ => ‘YESTERDAY’), 663663 array(‘value’ => '7daysAgo’, ‘html’ => ‘LAST 7 DAYS’), 664664 array(‘value’ => '14daysAgo’, ‘html’ => ‘LAST 14 DAYS’), 665665 array(‘value’ => '30daysAgo’, ‘html’ => ‘LAST 30 DAYS’), 666666 array(‘value’ => '90daysAgo’, ‘html’ => ‘LAST 90 DAYS’), 667667 array(‘value’ => '365daysAgo’, ‘html’ => ‘ONE YEAR’), 668668 array(‘value’ => '1095daysAgo’, ‘html’ => ‘THREE YEARS’), 669669 ); 670670 $requestQuery = array( 671671 array(‘value’ => 'sessions’, ‘html’ => ‘SESSIONS’), 672672 array(‘value’ => 'users’, ‘html’ => ‘USERS’), 673673 array(‘value’ => 'pageviews’, ‘html’ => ‘PAGE VIEWS’), 674674 array(‘value’ => 'visitBounceRate’, ‘html’ => ‘ENGAGEMENT’), 675675 array(‘value’ => 'organicSearches’, ‘html’ => ‘TRANSACTIONS’), 676676 array(‘value’ => 'contentpages’, ‘html’ => ‘PAGES’), 677677 array(‘value’ => 'locations’, ‘html’ => ‘LOCATION’), 678678 array(‘value’ => 'referrers’, ‘html’ => ‘REFERRERS’), 679679 array(‘value’ => 'searches’, ‘html’ => ‘SEARCHES’), 680680 array(‘value’ => 'channelGrouping’, ‘html’ => ‘TRAFFIC’), 681681 array(‘value’ => 'deviceCategory’, ‘html’ => ‘TECHNOLOGY’) 682682 ); 683683 $google_analytics = get_option(‘wpms_google_alanytics’); 684684 if (!empty($google_analytics[‘tableid_jail’])) { 685685 require_once WPMETASEO_PLUGIN_DIR . 'inc/google_analytics/wpmstools.php’; 686686 $profile = WpmsGaTools::getSelectedProfile($google_analytics[‘profile_list’], $google_analytics[‘tableid_jail’]); 687687 if (!empty($profile[4]) && $profile[4] === ‘UA’) { 688688 $requestQuery[3] = array(‘value’ => 'visitBounceRate’, ‘html’ => ‘BOUNCE RATE’); 689689 $requestQuery[4] = array(‘value’ => 'organicSearches’, ‘html’ => ‘ORGANIC’); 690690 } 691691 } 692692 693693 $selectedDate = 'today’; 694694 $selectedQuery = 'sessions’; 695695 if (!empty($google_analytics[‘dashboard_analytics_widgets’])) { 696696 $selectedDate = $google_analytics[‘dashboard_analytics_widgets’][‘requestDate’]; 697697 $selectedQuery = $google_analytics[‘dashboard_analytics_widgets’][‘requestQuery’]; 698698 } 699699 700700 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/dashboard-widgets/analytics_widgets.php’); 701701 } 702702 703703 /** 704704 * Function used in the action hook 705705 * 706706 * @return void 707707 */ 708708 public function addDashboardWidgets() 709709 { 710710 wp_add_dashboard_widget( 711711 'wpms_dashboard_widget’, 712712 esc_html__('WP Meta SEO: Quick SEO preview’, ‘wp-meta-seo’), 713713 array( 714714 $this, 715715 ‘dashboardWidget’ 716716 ) 717717 ); 718718 719719 // Add Google Analytics Overview dashboard widget 720720 wp_add_dashboard_widget( 721721 'wpms_dashboard_analytics_widget’, 722722 esc_html__('Google Analytics Overview’, ‘wp-meta-seo’), 723723 array( 724724 $this, 725725 ‘dashboardAnalyticsWidget’ 726726 ) 727727 ); 728728 } 729729 730730 /** 731731 * Localize dashboard widget 732732 * 733733 * @return array 734734 */ 735735 public function localizeDashoardWidgets() 736736 { 737737 return array( 738738 ‘ajaxUrl’ => admin_url(‘admin-ajax.php’), 739739 ‘wpms_nonce’ => wp_create_nonce(‘wpms_nonce’), 740740 ‘wpms_security’ => wp_create_nonce(‘dashboard_analytics_widgets_security’), 741741 ‘colorVariations’ => array( 742742 esc_attr(‘#1e73be’), 743743 esc_attr(‘#0459a4’), 744744 esc_attr(‘#378cd7’), 745745 esc_attr(‘#51a6f1’), 746746 esc_attr(‘#00408b’), 747747 esc_attr(‘#6abfff’), 748748 esc_attr(‘#002671’) 749749 ), 750750 ‘region’ => false, 751751 ‘language’ => get_bloginfo(‘language’), 752752 ‘viewList’ => false 753753 ); 754754 } 755755 756756 /** 757757 * Create link dialog 758758 * 759759 * @return void 760760 */ 761761 public function editorFooter() 762762 { 763763 if (!class_exists('_WP_Editors’, false)) { 764764 require_once ABSPATH . 'wp-includes/class-wp-editor.php’; 765765 _WP_Editors::wp_link_dialog(); 766766 } 767767 } 768768 769769 /** 770770 * Create or update 404 page 771771 * 772772 * @param string $title Old page title 773773 * @param string $newtitle New page title 774774 * 775775 * @return void 776776 */ 777777 public function create404Page($title, $newtitle) 778778 { 779779 global $wpdb; 780780 $post_if = $wpdb->get_results($wpdb->prepare( 781781 'SELECT * FROM ' . $wpdb->prefix . 'posts 782782 WHERE post_title = %s AND post_excerpt = %s AND post_type = %s’, 783783 array($title, 'metaseo_404_page’, ‘page’) 784784 )); 785785 786786 if (empty($post_if)) { 787787 $content = ‘<div class="wall" 788788 style="background-color: #F2F3F7; border: 30px solid #fff; width: 90%; height: 90%; margin: 0 auto;"> 789789 790790 <h1 style="text-align: center; font-family:\’open-sans\’, arial; 791791 color: #444; font-size: 60px; padding: 50px;">ERROR 404 <br />-<br />NOT FOUND</h1> 792792 <p style="text-align: center; font-family:\’open-sans\’, arial; color: #444; 793793 font-size: 40px; padding: 20px; line-height: 55px;"> 794794 // You may have mis-typed the URL,<br /> 795795 // Or the page has been removed,<br /> 796796 // Actually, there is nothing to see here…</p> 797797 <p style="text-align: center;"><a style=" font-family:\’open-sans\’, arial; color: #444; 798798 font-size: 20px; padding: 20px; line-height: 30px; text-decoration: none;" 799799 href="’ . get_home_url() . '"><< Go back to home page >></a></p> 800800 </div>’; 801801 $_page404 = array( 802802 ‘post_title’ => $newtitle, 803803 ‘post_content’ => $content, 804804 ‘post_status’ => 'publish’, 805805 ‘post_excerpt’ => 'metaseo_404_page’, 806806 ‘post_type’ => ‘page’ 807807 ); 808808 wp_insert_post($_page404); 809809 } else { 810810 $my_post = array( 811811 ‘ID’ => $post_if[0]->ID, 812812 ‘post_title’ => $newtitle 813813 ); 814814 815815 wp_update_post($my_post); 816816 } 817817 } 818818 819819 /** 820820 * Update links table 821821 * 822822 * @return void 823823 */ 824824 public function updateLinksTable() 825825 { 826826 global $wpdb; 827827 $option_v = 'metaseo_db_version3.7.2’; 828828 $db_installed = get_option($option_v, false); 829829 if (!$db_installed) { 830830 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . ‘wpms_links MODIFY `link_url` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL’); 831831 update_option($option_v, true); 832832 } 833833 834834 // Add index for wpms links 835835 $option_v = 'metaseo_db_version4.0.4’; 836836 $db_installed = get_option($option_v, false); 837837 if (!$db_installed) { 838838 // Add index for wpms_links table; 839839 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . 'wpms_links ADD INDEX linkurl(link_url(256))'); 840840 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . 'wpms_links ADD INDEX typeurl(type(50))'); 841841 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . 'wpms_links ADD INDEX sourceid(source_id)'); 842842 843843 // Add index for metaseo_images table; 844844 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . 'metaseo_images ADD INDEX postid(post_id)'); 845845 // Update option metaseo_db 846846 update_option($option_v, true); 847847 } 848848 } 849849 850850 /** 851851 * Create wpms_links table 852852 * 853853 * @return void 854854 */ 855855 public function createDatabase() 856856 { 857857 global $wpdb; 858858 $option_v = 'metaseo_db_version3.3.0’; 859859 $db_installed = get_option($option_v, false); 860860 if (!$db_installed) { 861861 // create table wpms_links 862862 $sql = 'CREATE TABLE IF NOT EXISTS ' . $wpdb->prefix . 'wpms_links( 863863 `id` int(20) unsigned NOT NULL AUTO_INCREMENT, 864864 `link_url` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL, 865865 `link_final_url` text CHARACTER SET latin1 COLLATE latin1_general_cs, 866866 `link_url_redirect` text CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL, 867867 `link_text` text NOT NULL DEFAULT "", 868868 `source_id` int(20) DEFAULT "0", 869869 `type` varchar(100) DEFAULT "", 870870 `status_code` varchar(100) DEFAULT "", 871871 `status_text` varchar(250) DEFAULT "", 872872 `hit` int(20) NOT NULL DEFAULT "1", 873873 `redirect` tinyint(1) NOT NULL DEFAULT "0", 874874 `broken_indexed` tinyint(1) unsigned NOT NULL DEFAULT "0", 875875 `broken_internal` tinyint(1) unsigned NOT NULL DEFAULT "0", 876876 `warning` tinyint(1) unsigned NOT NULL DEFAULT "0", 877877 `dismissed` tinyint(1) NOT NULL DEFAULT "0", 878878 PRIMARY KEY (id))'; 879879 880880 881881 require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’); 882882 dbDelta($sql); 883883 884884 $row = $wpdb->get_results($wpdb->prepare( 885885 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 886886 WHERE table_name = %s AND column_name = %s AND TABLE_SCHEMA = %s’, 887887 array($wpdb->prefix . 'wpms_links’, 'follow’, $wpdb->dbname) 888888 )); 889889 890890 if (empty($row)) { 891891 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . ‘wpms_links ADD follow tinyint(1) DEFAULT 1’); 892892 } 893893 894894 $row = $wpdb->get_results($wpdb->prepare( 895895 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 896896 WHERE table_name = %s AND column_name = %s AND TABLE_SCHEMA = %s’, 897897 array($wpdb->prefix . 'wpms_links’, 'meta_title’, $wpdb->dbname) 898898 )); 899899 900900 if (empty($row)) { 901901 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . ‘wpms_links ADD meta_title varchar(250) DEFAULT ""’); 902902 } 903903 904904 $row = $wpdb->get_results($wpdb->prepare( 905905 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 906906 WHERE table_name = %s AND column_name = %s AND TABLE_SCHEMA = %s’, 907907 array($wpdb->prefix . 'wpms_links’, 'internal’, $wpdb->dbname) 908908 )); 909909 910910 if (empty($row)) { 911911 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . ‘wpms_links ADD internal tinyint(1) DEFAULT 1’); 912912 } 913913 914914 // create page 404 915915 $this->create404Page('WP Meta SEO 404 Page’, ‘404 error page’); 916916 // create sitemap page 917917 $post_if = $wpdb->get_var( 918918 $wpdb->prepare('SELECT COUNT(*) FROM ' . $wpdb->prefix . 'posts 919919 WHERE post_title = %s AND post_excerpt = %s AND post_type = %s’, array( 920920 'WPMS HTML Sitemap’, 921921 'metaseo_html_sitemap’, 922922 ‘page’ 923923 )) 924924 ); 925925 if ($post_if < 1) { 926926 $_sitemap_page = array( 927927 ‘post_title’ => 'WPMS HTML Sitemap’, 928928 ‘post_content’ => '’, 929929 ‘post_status’ => 'publish’, 930930 ‘post_excerpt’ => 'metaseo_html_sitemap’, 931931 ‘post_type’ => 'page’, 932932 ); 933933 wp_insert_post($_sitemap_page); 934934 } 935935 936936 update_option($option_v, true); 937937 } 938938 939939 940940 $option_v = 'metaseo_db_version3.7.3’; 941941 $db_installed = get_option($option_v, false); 942942 if (!$db_installed) { 943943 // create page 404 944944 $this->create404Page('404 error page’, ‘404 Error, content does not exist anymore’); 945945 update_option($option_v, true); 946946 } 947947 948948 $option_v = 'metaseo_db_version4.0.0’; 949949 $db_installed = get_option($option_v, false); 950950 if (!$db_installed) { 951951 $row = $wpdb->get_results($wpdb->prepare( 952952 'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 953953 WHERE table_name = %s AND column_name = %s AND TABLE_SCHEMA = %s’, 954954 array($wpdb->prefix . 'wpms_links’, 'referrer’, $wpdb->dbname) 955955 )); 956956 957957 if (empty($row)) { 958958 $wpdb->query('ALTER TABLE ' . $wpdb->prefix . ‘wpms_links ADD referrer text DEFAULT ""’); 959959 } 960960 update_option($option_v, true); 961961 } 962962 963963 $option_v = 'metaseo_db_version4.0.4’; 964964 $db_installed = get_option($option_v, false); 965965 $wpms_db_version = get_option('metaseo_db_version’, false); 966966 // update plugin v4.3.5 967967 if ($db_installed && !$wpms_db_version) { 968968 // Get old settings 969969 $gaDisconnect = get_option(‘_metaseo_ggtracking_disconnect_settings’); 970970 971971 // Update value to new ga parameters 972972 if ($gaDisconnect) { 973973 $this->gaDisconnect[‘wpms_gg_service_tracking_id’] = $gaDisconnect[‘wpms_ga_uax_reference’]; 974974 $this->gaDisconnect[‘wpms_gg_service_tracking_type’] = $gaDisconnect[‘wpmsga_dash_tracking_type’]; 975975 $this->gaDisconnect[‘wpmsga_code_tracking’] = $gaDisconnect[‘wpmsga_code_tracking’]; 976976 $this->gaDisconnect[‘wpmstm_header_code_tracking’] = '’; 977977 $this->gaDisconnect[‘wpmstm_body_code_tracking’] = '’; 978978 update_option('_metaseo_ggtracking_disconnect_settings’, $this->gaDisconnect); 979979 } 980980 update_option('metaseo_db_version’, WPMSEO_VERSION); 981981 } 982982 } 983983 984984 /** 985985 * Add field title in dialog link when edit a link 986986 * 987987 * @return void 988988 */ 989989 public function linkTitleField() 990990 { 991991 if (isset($this->settings[‘metaseo_linkfield’]) && (int)$this->settings[‘metaseo_linkfield’] === 1) { 992992 wp_enqueue_script( 993993 'wpmslinkTitle’, 994994 plugins_url('assets/js/wpms-link-title-field.js’, dirname(__FILE__)), 995995 array(‘wplink’), 996996 WPMSEO_VERSION, 997997 true 998998 ); 999999 wp_localize_script('wpmslinkTitle’, 'wpmsLinkTitleL10n’, array( 10001000 ‘titleLabel’ => esc_html__('Title’, ‘wp-meta-seo’), 10011001 )); 10021002 } 10031003 } 10041004 10051005 /** 10061006 * Update option wpms_set_ignore 10071007 * 10081008 * @return void 10091009 */ 10101010 public function setIgnore() 10111011 {
10121016 if (!current_user_can(‘manage_options’)) { 10131017 wp_send_json(false); 10141018 } 10151019 update_option('wpms_set_ignore’, 0); 10161020 wp_send_json(true); 10171021 } 10181022 10191023 /** 10201024 * Render message error when disable search engines from indexing this site 10211025 * 10221026 * @return void 10231027 */ 10241028 public function publicWarning() 10251029 { 10261030 if ((function_exists(‘is_network_admin’) && is_network_admin())) { 10271031 return; 10281032 } 10291033 10301034 if ((int)get_option(‘wpms_set_ignore’) === 0) { 10311035 return; 10321036 } 10331037 10341038 printf( 10351039 ‘<div id="robotsmessage" class="error"> 10361040 <p> 10371041 <strong>%1$s</strong> 10381042 %2$s 10391043 <a href="javascript:wpmsIgnore(\’wpms_public_warning\’,\’robotsmessage\’,\’%3$s\’);" 10401044 class="button">%4$s</a> 10411045 </p> 10421046 </div>’, 10431047 esc_html__('Your website is not indexed by search engine because of your WordPress settings.’, ‘wp-meta-seo’), 10441048 sprintf( 10451049 esc_html__('%1$sFix it now%2$s’, ‘wp-meta-seo’), 10461050 sprintf('<a href="%s">’, esc_url(admin_url(‘options-reading.php’))), 10471051 ‘</a>’ 10481052 ), 10491053 esc_js(wp_create_nonce(‘wpseo-ignore’)), 10501054 esc_html__('OK I know that.’, ‘wp-meta-seo’) 10511055 ); 10521056 } 10531057 10541058 /** 10551059 * Loads translated strings. 10561060 * 10571061 * @return void 10581062 */ 10591063 public function loadLangguage() 10601064 { 10611065 load_plugin_textdomain( 10621066 'wp-meta-seo’, 10631067 false, 10641068 dirname(plugin_basename(__FILE__)) . DIRECTORY_SEPARATOR . ‘languages’ . DIRECTORY_SEPARATOR 10651069 ); 10661070 } 10671071 10681072 /** 10691073 * Handle redirects to setup/welcome page after install and updates. 10701074 * 10711075 * For setup wizard, transient must be present, the user must have access rights, and we must ignore the network/bulk plugin updaters. 10721076 * 10731077 * @return void 10741078 */ 10751079 public function adminRedirects() 10761080 { 10771081 // Disable all admin notice for page belong to plugin 10781082 add_action('admin_print_scripts’, function () { 10791083 global $wp_filter; 10801084 // phpcs:ignore WordPress.Security.NonceVerification.Recommended – No action, nonce is not required 10811085 if ((!empty($_GET[‘page’]) && in_array($_GET[‘page’], array('wpms-setup’, 'metaseo_settings’, ‘metaseo_console’)))) { 10821086 if (is_user_admin()) { 10831087 if (isset($wp_filter[‘user_admin_notices’])) { 10841088 unset($wp_filter[‘user_admin_notices’]); 10851089 } 10861090 } elseif (isset($wp_filter[‘admin_notices’])) { 10871091 unset($wp_filter[‘admin_notices’]); 10881092 } 10891093 if (isset($wp_filter[‘all_admin_notices’])) { 10901094 unset($wp_filter[‘all_admin_notices’]); 10911095 } 10921096 } 10931097 }); 10941098 10951099 // Setup wizard redirect 10961100 if (is_null(get_option('_wpmf_activation_redirect’, null)) && is_null(get_option('wpms_version’, null))) { 10971101 // phpcs:ignore WordPress.Security.NonceVerification.Recommended – View request, no action 10981102 if ((!empty($_GET[‘page’]) && in_array($_GET[‘page’], array(‘wpms-setup’)))) { 10991103 return; 11001104 } 11011105 update_option('wpms_version’, WPMSEO_VERSION); 11021106 wp_safe_redirect(admin_url(‘index.php?page=wpms-setup’)); 11031107 exit; 11041108 } 11051109 } 11061110 11071111 /** 11081112 * Includes WP Media Folder setup 11091113 * 11101114 * @return void 11111115 */ 11121116 public function install() 11131117 { 11141118 // phpcs:ignore WordPress.Security.NonceVerification.Recommended – View request, no action 11151119 if (!empty($_GET[‘page’])) { 11161120 // phpcs:ignore WordPress.Security.NonceVerification.Recommended – View request, no action 11171121 switch ($_GET[‘page’]) { 11181122 case 'wpms-setup’: 11191123 require_once WPMETASEO_PLUGIN_DIR . '/inc/install-wizard/install-wizard.php’; 11201124 break; 11211125 } 11221126 } 11231127 } 11241128 11251129 /** 11261130 * Create field analysis 11271131 * 11281132 * @param string $data_title Title 11291133 * @param string $alt Alt text 11301134 * @param string $dashicon Type 11311135 * @param string $label Label 11321136 * @param string $value_hidden Value 11331137 * 11341138 * @return string 11351139 */ 11361140 public function createFieldAnalysis($data_title, $alt, $dashicon, $label, $value_hidden) 11371141 { 11381142 $output = ‘<div class="metaseo_analysis metaseo_tool" data-title="’ . esc_attr($data_title) . ‘" data-tippy="’ . esc_attr($alt) . '">’; 11391143 if ($dashicon === ‘done’) { 11401144 $output .= '<i class="metaseo-dashicons material-icons dashicons-before icons-mboxdone">done</i>’; 11411145 } else { 11421146 $output .= '<i class="metaseo-dashicons material-icons dashicons-before icons-mboxwarning">error_outline</i>’; 11431147 } 11441148 11451149 $output .= esc_html($label); 11461150 $output .= '</div>’; 11471151 $output .= ‘<input type="hidden" class="wpms_analysis_hidden" 11481152 name="’ . esc_attr('wpms[' . $data_title . ']') . ‘" value="’ . esc_attr($value_hidden) . '">’; 11491153 return $output; 11501154 } 11511155 11521156 /** 11531157 * Get content 11541158 * 11551159 * @param string $content Post content 11561160 * @param integer $post_id Post ID 11571161 * 11581162 * @return string 11591163 */ 11601164 public function wpmsTheContent($content, $post_id) 11611165 { 11621166 $content = apply_filters( 11631167 'the_content’, 11641168 $content, 11651169 $post_id 11661170 ); 11671171 11681172 if (is_plugin_active(‘oxygen/functions.php’)) { 11691173 $shortcodes = get_post_meta($post_id, 'ct_builder_shortcodes’, true); 11701174 $cf = do_shortcode($shortcodes); 11711175 $content = $content . $cf; 11721176 } 11731177 11741178 return $content; 11751179 } 11761180 11771181 /** 11781182 * Get all the values of an array 11791183 * 11801184 * @param array $array List array to get value 11811185 * 11821186 * @return array|string 11831187 */ 11841188 public function getValues($array) 11851189 { 11861190 if (is_array($array)) { 11871191 $array = array_values($array); 11881192 } 11891193 11901194 return $array; 11911195 } 11921196 11931197 /** 11941198 * Check strpos with list array 11951199 * 11961200 * @param string $haystack String to compare 11971201 * @param array $needle List array need compare 11981202 * @param integer $offset Offset value 11991203 * 12001204 * @return boolean 12011205 */ 12021206 public function strPosArray($haystack, $needle, $offset = 0) 12031207 { 12041208 if (!is_array($needle)) { 12051209 $needle = array($needle); 12061210 } 12071211 foreach ($needle as $query) { 12081212 // stop on first true result 12091213 if (strpos($haystack, $query, $offset) !== false) { 12101214 return true; 12111215 } 12121216 } 12131217 return false; 12141218 } 12151219 12161220 /** 12171221 * Recursion to get specific value of file 12181222 * 12191223 * @param array $fields List specific value of field 12201224 * 12211225 * @return string 12221226 */ 12231227 public function getACFData($fields) 12241228 { 12251229 $values = $this->getValues($fields); 12261230 $data = '’; 12271231 12281232 if (is_array($values)) { 12291233 foreach ($values as $item) { 12301234 switch (gettype($item)) { 12311235 case 'array’: 12321236 $data .= $this->getACFData($item); 12331237 break; 12341238 case 'string’: 12351239 // Check link 12361240 if (filter_var($item, FILTER_VALIDATE_URL)) { 12371241 $checkImageLink = $this->strPosArray($item, array('.jpg’, '.png’, '.jpeg’, 'svg’, ‘gif’)); 12381242 if (!$checkImageLink) { 12391243 $item = ‘<a href="’ . $item . ‘">’ . $item . '</a>’; 12401244 } 12411245 } 12421246 $data .= ' ' . $item; 12431247 break; 12441248 } 12451249 } 12461250 } 12471251 if (is_string($values)) { 12481252 $data .= ' ' . $values; 12491253 } 12501254 return $data; 12511255 } 12521256 12531257 /** 12541258 * Inject ACF field to content 12551259 * 12561260 * @param string $content Post content 12571261 * @param integer $post_id Post ID 12581262 * 12591263 * @return string 12601264 */ 12611265 public function injectAcfField($content, $post_id) 12621266 { 12631267 if (class_exists(‘ACF’)) { 12641268 $fields = get_field_objects($post_id); 12651269 12661270 if (!empty($fields)) { 12671271 $inject = '’; 12681272 foreach ($fields as $name => $field) { 12691273 if ($field[‘type’] === ‘image’) { 12701274 $size = $field[‘preview_size’]; 12711275 if (is_array($field[‘value’])) { 12721276 $caption = $field[‘value’][‘caption’]; 12731277 // Get image link if field is array 12741278 if ($caption) { 12751279 $inject .= ‘<div class="wp-caption">’; 12761280 } 12771281 $inject = ‘<a href="’ . $field[‘value’][‘url’] . ‘" title="’ . $field[‘value’][‘title’] . ‘">’; 12781282 $inject .= ‘<img src="’ . $field[‘value’][‘sizes’][$size] . ‘" alt="’ . $field[‘value’][‘alt’] . ‘" width="’ . $field[‘value’][‘sizes’][$size . '-width’] . ‘" height="’ . $field[‘value’][‘sizes’][$size . '-height’] . '" />’; 12791283 $inject .= '</a>’; 12801284 if ($caption) { 12811285 $inject .= ‘<p class="wp-caption-text">’ . $caption . '</p>’; 12821286 } 12831287 $inject .= '</div>’; 12841288 } elseif (is_string($field[‘value’])) { 12851289 $inject = ‘<img src="’ . $field[‘value’] . '" />’; 12861290 } else { 12871291 $inject = wp_get_attachment_image($field[‘value’], $size); 12881292 } 12891293 } elseif ($field[‘type’] === ‘link’) { 12901294 // Get link if field is array 12911295 if (is_array($field[‘value’])) { 12921296 $inject = ‘<a class="link-url" href="’ . $field[‘value’][‘url’] . ‘" target="’ . ($field[‘value’][‘target’] ? $field[‘value’][‘target’] : ‘_self’) . ‘">’ . esc_html($field[‘value’][‘title’]) . '</a>’; 12931297 } else { 12941298 $inject = ‘<a class="link-url" href="’ . $field[‘value’] . ‘">’ . esc_html($field[‘value’]) . '</a>’; 12951299 } 12961300 } else { 12971301 $inject = $this->getACFData($field[‘value’]); 12981302 } 12991303 13001304 $content .= ' ' . $inject; 13011305 } 13021306 } 13031307 } 13041308 13051309 return $content; 13061310 } 13071311 13081312 /** 13091313 * Inject Woocommerce short description to content 13101314 * 13111315 * @param string $content Post content 13121316 * @param integer $post_id Post ID 13131317 * 13141318 * @return string 13151319 */ 13161320 public function injectWooCommerce($content, $post_id) 13171321 { 13181322 if (class_exists(‘WooCommerce’)) { 13191323 $post = get_post($post_id); 13201324 13211325 if (!empty($post->post_excerpt)) { 13221326 $content .= ‘’ . $post->post_excerpt; 13231327 } 13241328 } 13251329 13261330 return $content; 13271331 } 13281332 13291333 /** 13301334 * Ajax load page analysis 13311335 * 13321336 * @return void 13331337 */ 13341338 public function reloadAnalysis() 13351339 { 13361340 if (empty($_POST[‘wpms_nonce’]) 13371341 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 13381342 die(); 13391343 } 13401344 13411345 if (!current_user_can(‘edit_posts’)) { 13421346 wp_send_json(array(‘status’ => false)); 13431347 } 13441348 $tooltip_page = array(); 13451349 $tooltip_page[‘title_in_heading’] = esc_attr__('Check if a word of this content title 13461350 is also in a title heading (h1, h2…)', ‘wp-meta-seo’); 13471351 $tooltip_page[‘title_in_content’] = esc_attr__('Check if a word of this content 13481352 title is also in the text’, ‘wp-meta-seo’); 13491353 $tooltip_page[‘page_url’] = esc_attr__('Does the page title match with the permalink (URL structure)', ‘wp-meta-seo’); 13501354 $tooltip_page[‘meta_title’] = esc_attr__('Is the meta title of this page filled?’, ‘wp-meta-seo’); 13511355 $tooltip_page[‘meta_desc’] = esc_attr__('Is the meta description of this page filled?’, ‘wp-meta-seo’); 13521356 $tooltip_page[‘image_resize’] = esc_attr__('Check for image HTML resizing in content 13531357 (usually image resized using handles)', ‘wp-meta-seo’); 13541358 $tooltip_page[‘image_alt’] = esc_attr__('Check for image Alt text and title’, ‘wp-meta-seo’); 13551359 if (empty($_POST[‘datas’])) { 13561360 wp_send_json(false); 13571361 } 13581362 13591363 if (isset($_POST[‘datas’][‘post_id’]) && empty($_POST[‘datas’][‘first_load’])) { 13601364 update_post_meta($_POST[‘datas’][‘post_id’], 'wpms_validate_analysis’, ‘’); 13611365 } 13621366 13631367 $meta_analysis = get_post_meta((int)$_POST[‘datas’][‘post_id’], 'wpms_validate_analysis’, true); 13641368 $check = 0; 13651369 $output = '’; 13661370 13671371 // title heading 13681372 $words_post_title = preg_split( 13691373 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 13701374 strtolower($_POST[‘datas’][‘title’]), 13711375 -1, 13721376 PREG_SPLIT_NO_EMPTY 13731377 ); 13741378 13751379 // do shortcode js_composer plugin 13761380 if (is_plugin_active(‘js_composer_theme/js_composer.php’)) { 13771381 add_shortcode('mk_fancy_title’, ‘vc_do_shortcode’); 13781382 } 13791383 13801384 $content = apply_filters( 13811385 'wpms_the_content’, 13821386 ‘<div>’ . html_entity_decode(stripcslashes($_POST[‘datas’][‘content’]), ENT_COMPAT, ‘UTF-8’) . '</div>’, 13831387 $_POST[‘datas’][‘post_id’] 13841388 ); 13851389 13861390 $content = $this->injectAcfField($content, $_POST[‘datas’][‘post_id’]); 13871391 13881392 $content = $this->injectWooCommerce($content, $_POST[‘datas’][‘post_id’]); 13891393 13901394 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘heading_title’])) { 13911395 $output .= $this->createFieldAnalysis( 13921396 'heading_title’, 13931397 $tooltip_page[‘title_in_heading’], 13941398 'done’, 13951399 esc_html__('Page title word in content heading’, ‘wp-meta-seo’), 13961400 1 13971401 ); 13981402 $check++; 13991403 } else { 14001404 if ($content === ‘’) { 14011405 $output .= $this->createFieldAnalysis( 14021406 'heading_title’, 14031407 $tooltip_page[‘title_in_heading’], 14041408 'warning’, 14051409 esc_html__('Page title word in content heading’, ‘wp-meta-seo’), 14061410 0 14071411 ); 14081412 } else { 14091413 // Extracting the specified elements from the web page 14101414 $tags_h1 = wpmsExtractTags($content, 'h1’, false, true); 14111415 $tags_h2 = wpmsExtractTags($content, 'h2’, false, true); 14121416 $tags_h3 = wpmsExtractTags($content, 'h3’, false, true); 14131417 $tags_h4 = wpmsExtractTags($content, 'h4’, false, true); 14141418 $tags_h5 = wpmsExtractTags($content, 'h5’, false, true); 14151419 $tags_h6 = wpmsExtractTags($content, 'h6’, false, true); 14161420 14171421 // extract heading tags from WPBakery plugin shortcode 14181422 if (is_plugin_active(‘js_composer/js_composer.php’) && isset($_POST[‘datas’][‘content’])) { 14191423 $textContent = $_POST[‘datas’][‘content’]; 14201424 $textContent = html_entity_decode(stripcslashes($textContent), ENT_COMPAT, ‘UTF-8’); 14211425 $msPostTitle = isset($_POST[‘datas’][‘title’]) ? $_POST[‘datas’][‘title’] : '’; 14221426 $vcCustomHeading = $this->wpmsShortcodeExtract($msPostTitle, $textContent, array('h1’, 'h2’, 'h3’, 'h4’, 'h5’, ‘h6’)); 14231427 if (!empty($vcCustomHeading)) { 14241428 $tags_h1 = array_merge($tags_h1, $vcCustomHeading[‘h1’]); 14251429 $tags_h2 = array_merge($tags_h2, $vcCustomHeading[‘h2’]); 14261430 $tags_h3 = array_merge($tags_h3, $vcCustomHeading[‘h3’]); 14271431 $tags_h4 = array_merge($tags_h4, $vcCustomHeading[‘h4’]); 14281432 $tags_h5 = array_merge($tags_h5, $vcCustomHeading[‘h5’]); 14291433 $tags_h6 = array_merge($tags_h6, $vcCustomHeading[‘h6’]); 14301434 } 14311435 } 14321436 $test = false; 14331437 if (empty($tags_h1) && empty($tags_h2) && empty($tags_h3) 14341438 && empty($tags_h4) && empty($tags_h5) && empty($tags_h6)) { 14351439 $test = false; 14361440 } else { 14371441 // check tag h1 14381442 if (!empty($tags_h1)) { 14391443 foreach ($tags_h1 as $order => $tagh1) { 14401444 $words_tagh1 = preg_split( 14411445 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 14421446 strtolower($tagh1[‘contents’]), 14431447 -1, 14441448 PREG_SPLIT_NO_EMPTY 14451449 ); 14461450 14471451 if (is_array($words_tagh1) && is_array($words_post_title)) { 14481452 foreach ($words_tagh1 as $mh) { 14491453 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 14501454 $test = true; 14511455 } 14521456 } 14531457 } 14541458 } 14551459 } 14561460 14571461 // check tag h2 14581462 if (!empty($tags_h2)) { 14591463 foreach ($tags_h2 as $order => $tagh2) { 14601464 $words_tagh2 = preg_split( 14611465 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 14621466 strtolower($tagh2[‘contents’]), 14631467 -1, 14641468 PREG_SPLIT_NO_EMPTY 14651469 ); 14661470 if (is_array($words_tagh2) && is_array($words_post_title)) { 14671471 foreach ($words_tagh2 as $mh) { 14681472 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 14691473 $test = true; 14701474 } 14711475 } 14721476 } 14731477 } 14741478 } 14751479 14761480 // check tag h3 14771481 if (!empty($tags_h3)) { 14781482 foreach ($tags_h3 as $order => $tagh3) { 14791483 $words_tagh3 = preg_split( 14801484 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 14811485 strtolower($tagh3[‘contents’]), 14821486 -1, 14831487 PREG_SPLIT_NO_EMPTY 14841488 ); 14851489 if (is_array($words_tagh3) && is_array($words_post_title)) { 14861490 foreach ($words_tagh3 as $mh) { 14871491 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 14881492 $test = true; 14891493 } 14901494 } 14911495 } 14921496 } 14931497 } 14941498 14951499 // check tag h4 14961500 if (!empty($tags_h4)) { 14971501 foreach ($tags_h4 as $order => $tagh4) { 14981502 $words_tagh4 = preg_split( 14991503 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 15001504 strtolower($tagh4[‘contents’]), 15011505 -1, 15021506 PREG_SPLIT_NO_EMPTY 15031507 ); 15041508 if (is_array($words_tagh4) && is_array($words_post_title)) { 15051509 foreach ($words_tagh4 as $mh) { 15061510 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 15071511 $test = true; 15081512 } 15091513 } 15101514 } 15111515 } 15121516 } 15131517 15141518 // check tag h5 15151519 if (!empty($tags_h5)) { 15161520 foreach ($tags_h5 as $order => $tagh5) { 15171521 $words_tagh5 = preg_split( 15181522 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 15191523 strtolower($tagh5[‘contents’]), 15201524 -1, 15211525 PREG_SPLIT_NO_EMPTY 15221526 ); 15231527 if (is_array($words_tagh5) && is_array($words_post_title)) { 15241528 foreach ($words_tagh5 as $mh) { 15251529 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 15261530 $test = true; 15271531 } 15281532 } 15291533 } 15301534 } 15311535 } 15321536 15331537 // check tag h6 15341538 if (!empty($tags_h6)) { 15351539 foreach ($tags_h6 as $order => $tagh6) { 15361540 $words_tagh6 = preg_split( 15371541 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 15381542 strtolower($tagh6[‘contents’]), 15391543 -1, 15401544 PREG_SPLIT_NO_EMPTY 15411545 ); 15421546 if (is_array($words_tagh6) && is_array($words_post_title)) { 15431547 foreach ($words_tagh6 as $mh) { 15441548 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 15451549 $test = true; 15461550 } 15471551 } 15481552 } 15491553 } 15501554 } 15511555 } 15521556 15531557 if ($test) { 15541558 $output .= $this->createFieldAnalysis( 15551559 'heading_title’, 15561560 $tooltip_page[‘title_in_heading’], 15571561 'done’, 15581562 esc_html__('Page title word in content heading’, ‘wp-meta-seo’), 15591563 1 15601564 ); 15611565 $check++; 15621566 } else { 15631567 $output .= $this->createFieldAnalysis( 15641568 'heading_title’, 15651569 $tooltip_page[‘title_in_heading’], 15661570 'warning’, 15671571 esc_html__('Page title word in content heading’, ‘wp-meta-seo’), 15681572 0 15691573 ); 15701574 } 15711575 } 15721576 } 15731577 15741578 // title content 15751579 $words_title = preg_split( 15761580 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 15771581 strtolower($_POST[‘datas’][‘title’]), 15781582 -1, 15791583 PREG_SPLIT_NO_EMPTY 15801584 ); 15811585 $words_post_content = preg_split( 15821586 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 15831587 strtolower(strip_tags($content)), 15841588 -1, 15851589 PREG_SPLIT_NO_EMPTY 15861590 ); 15871591 15881592 $test1 = false; 15891593 if (is_array($words_title) && is_array($words_post_content)) { 15901594 foreach ($words_title as $mtitle) { 15911595 if (in_array($mtitle, $words_post_content) && $mtitle !== ‘’) { 15921596 $test1 = true; 15931597 break; 15941598 } 15951599 } 15961600 } else { 15971601 $test1 = false; 15981602 } 15991603 16001604 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘content_title’])) { 16011605 $output .= $this->createFieldAnalysis( 16021606 'content_title’, 16031607 $tooltip_page[‘title_in_content’], 16041608 'done’, 16051609 esc_html__('Page title word in content’, ‘wp-meta-seo’), 16061610 1 16071611 ); 16081612 $check++; 16091613 } else { 16101614 if ($test1) { 16111615 $output .= $this->createFieldAnalysis( 16121616 'content_title’, 16131617 $tooltip_page[‘title_in_content’], 16141618 'done’, 16151619 esc_html__('Page title word in content’, ‘wp-meta-seo’), 16161620 1 16171621 ); 16181622 $check++; 16191623 } else { 16201624 $output .= $this->createFieldAnalysis( 16211625 'content_title’, 16221626 $tooltip_page[‘title_in_content’], 16231627 'warning’, 16241628 esc_html__('Page title word in content’, ‘wp-meta-seo’), 16251629 0 16261630 ); 16271631 } 16281632 } 16291633 16301634 // page url matches page title 16311635 $mtitle = $_POST[‘datas’][‘title’]; 16321636 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘pageurl’])) { 16331637 $output .= $this->createFieldAnalysis( 16341638 'pageurl’, 16351639 $tooltip_page[‘page_url’], 16361640 'done’, 16371641 esc_html__('Page url matches with page title’, ‘wp-meta-seo’), 16381642 1 16391643 ); 16401644 $check++; 16411645 } else { 16421646 $mpageurl = '’; 16431647 if (isset($_POST[‘datas’][‘mpageurl’])) { 16441648 $infos = pathinfo($_POST[‘datas’][‘mpageurl’]); 16451649 $mpageurl = $infos[‘filename’]; 16461650 if ($mpageurl[0] === ‘?’) { 16471651 $mpageurl = ltrim($mpageurl, ‘?’); // remove ? from ?page=abc 16481652 } 16491653 } 16501654 16511655 //check is home page 16521656 $home_url = home_url(); 16531657 $home_url_1 = explode('//’, $home_url); 16541658 $is_home = false; 16551659 if (!empty($home_url_1[1]) && isset($_POST[‘datas’][‘mpageurl’])) { 16561660 $home_url_2 = explode($home_url_1[1], $_POST[‘datas’][‘mpageurl’]); 16571661 if (!isset($home_url_2[1]) || (!empty($home_url_2[1]) && $home_url_2[1] === ‘/’)) { 16581662 $is_home = true; 16591663 } 16601664 } 16611665 16621666 if ((isset($_POST[‘datas’][‘mpageurl’]) && $is_home) || (!empty($mpageurl) && !empty($mtitle) && strpos(sanitize_title($mtitle), sanitize_title($mpageurl)) !== false)) { 16631667 $output .= $this->createFieldAnalysis( 16641668 'pageurl’, 16651669 $tooltip_page[‘page_url’], 16661670 'done’, 16671671 esc_html__('Page url matches with page title’, ‘wp-meta-seo’), 16681672 1 16691673 ); 16701674 $check++; 16711675 } else { 16721676 $output .= $this->createFieldAnalysis( 16731677 'pageurl’, 16741678 $tooltip_page[‘page_url’], 16751679 'warning’, 16761680 esc_html__('Page url matches with page title’, ‘wp-meta-seo’), 16771681 0 16781682 ); 16791683 } 16801684 } 16811685 16821686 // meta title filled 16831687 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘metatitle’])) { 16841688 $output .= $this->createFieldAnalysis( 16851689 'metatitle’, 16861690 $tooltip_page[‘meta_title’], 16871691 'done’, 16881692 esc_html__('Meta title filled’, ‘wp-meta-seo’), 16891693 1 16901694 ); 16911695 $check++; 16921696 } else { 16931697 if (($_POST[‘datas’][‘meta_title’] !== ‘’ 16941698 && mb_strlen($_POST[‘datas’][‘meta_title’], ‘UTF-8’) <= self::$title_length)) { 16951699 $output .= $this->createFieldAnalysis( 16961700 'metatitle’, 16971701 $tooltip_page[‘meta_title’], 16981702 'done’, 16991703 esc_html__('Meta title filled’, ‘wp-meta-seo’), 17001704 1 17011705 ); 17021706 $check++; 17031707 } else { 17041708 $output .= $this->createFieldAnalysis( 17051709 'metatitle’, 17061710 $tooltip_page[‘meta_title’], 17071711 'warning’, 17081712 esc_html__('Meta title filled’, ‘wp-meta-seo’), 17091713 0 17101714 ); 17111715 } 17121716 } 17131717 17141718 // desc filled 17151719 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘metadesc’])) { 17161720 $output .= $this->createFieldAnalysis( 17171721 'metadesc’, 17181722 $tooltip_page[‘meta_desc’], 17191723 'done’, 17201724 esc_html__('Meta description filled’, ‘wp-meta-seo’), 17211725 1 17221726 ); 17231727 $check++; 17241728 } else { 17251729 if ($_POST[‘datas’][‘meta_desc’] !== ‘’ 17261730 && mb_strlen($_POST[‘datas’][‘meta_desc’], ‘UTF-8’) <= self::$desc_length) { 17271731 $output .= $this->createFieldAnalysis( 17281732 'metadesc’, 17291733 $tooltip_page[‘meta_desc’], 17301734 'done’, 17311735 esc_html__('Meta description filled’, ‘wp-meta-seo’), 17321736 1 17331737 ); 17341738 $check++; 17351739 } else { 17361740 $output .= $this->createFieldAnalysis( 17371741 'metadesc’, 17381742 $tooltip_page[‘meta_desc’], 17391743 'warning’, 17401744 esc_html__('Meta description filled’, ‘wp-meta-seo’), 17411745 0 17421746 ); 17431747 } 17441748 } 17451749 17461750 // image resize 17471751 if ($content === ‘’) { 17481752 $output .= $this->createFieldAnalysis( 17491753 'imgresize’, 17501754 $tooltip_page[‘image_resize’], 17511755 'done’, 17521756 esc_html__('Wrong image resize’, ‘wp-meta-seo’), 17531757 1 17541758 ); 17551759 $output .= $this->createFieldAnalysis( 17561760 'imgalt’, 17571761 $tooltip_page[‘image_alt’], 17581762 'done’, 17591763 esc_html__('Image alt information filled’, ‘wp-meta-seo’), 17601764 1 17611765 ); 17621766 $check += 2; 17631767 } else { 17641768 // Extracting the specified elements from the web page 17651769 $img_tags = wpmsExtractTags($content, 'img’, true, true); 17661770 $img_wrong = false; 17671771 $img_wrong_alt = false; 17681772 foreach ($img_tags as $order => $tag) { 17691773 if (!isset($tag[‘attributes’][‘src’])) { 17701774 continue; 17711775 } 17721776 17731777 $src = $tag[‘attributes’][‘src’]; 17741778 $imgpath = str_replace(site_url(), ABSPATH, $src); 17751779 if (!file_exists($imgpath)) { 17761780 continue; 17771781 } 17781782 if (!list($width_origin, $height_origin) = getimagesize($imgpath)) { 17791783 continue; 17801784 } 17811785 17821786 if (empty($tag[‘attributes’][‘width’]) && empty($tag[‘attributes’][‘height’])) { 17831787 $img_wrong = false; 17841788 } else { 17851789 if (!empty($width_origin) && !empty($height_origin)) { 17861790 if ((isset($tag[‘attributes’][‘width’]) && (int)$width_origin !== (int)$tag[‘attributes’][‘width’]) 17871791 || (isset($tag[‘attributes’][‘height’]) && (int)$height_origin !== (int)$tag[‘attributes’][‘height’])) { 17881792 $img_wrong = true; 17891793 } 17901794 } 17911795 } 17921796 17931797 if (empty($tag[‘attributes’][‘alt’])) { 17941798 $img_wrong_alt = true; 17951799 } 17961800 } 17971801 17981802 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘imgresize’])) { 17991803 $output .= $this->createFieldAnalysis( 18001804 'imgresize’, 18011805 $tooltip_page[‘image_resize’], 18021806 'done’, 18031807 esc_html__('Wrong image resize’, ‘wp-meta-seo’), 18041808 1 18051809 ); 18061810 $check++; 18071811 } else { 18081812 if (!$img_wrong) { 18091813 $output .= $this->createFieldAnalysis( 18101814 'imgresize’, 18111815 $tooltip_page[‘image_resize’], 18121816 'done’, 18131817 esc_html__('Wrong image resize’, ‘wp-meta-seo’), 18141818 1 18151819 ); 18161820 $check++; 18171821 } else { 18181822 $output .= $this->createFieldAnalysis( 18191823 'imgresize’, 18201824 $tooltip_page[‘image_resize’], 18211825 'warning’, 18221826 esc_html__('Wrong image resize’, ‘wp-meta-seo’), 18231827 0 18241828 ); 18251829 } 18261830 } 18271831 18281832 if (isset($_POST[‘datas’][‘first_load’]) && !empty($meta_analysis) && !empty($meta_analysis[‘imgalt’])) { 18291833 $output .= $this->createFieldAnalysis( 18301834 'imgalt’, 18311835 $tooltip_page[‘image_alt’], 18321836 'done’, 18331837 esc_html__('Image alt information filled’, ‘wp-meta-seo’), 18341838 1 18351839 ); 18361840 $check++; 18371841 } else { 18381842 if (!$img_wrong_alt) { 18391843 $output .= $this->createFieldAnalysis( 18401844 'imgalt’, 18411845 $tooltip_page[‘image_alt’], 18421846 'done’, 18431847 esc_html__('Image alt information filled’, ‘wp-meta-seo’), 18441848 1 18451849 ); 18461850 $check++; 18471851 } else { 18481852 $output .= $this->createFieldAnalysis( 18491853 'imgalt’, 18501854 $tooltip_page[‘image_alt’], 18511855 'warning’, 18521856 esc_html__('Image alt information filled’, ‘wp-meta-seo’), 18531857 0 18541858 ); 18551859 } 18561860 } 18571861 18581862 $output .= $this->createFieldAnalysis( 18591863 'seokeyword’, 18601864 esc_html__('At least one of the SEO keywords are found in the page title OR meta title OR SEO meta description OR page content heading OR the page content’, ‘wp-meta-seo’), 18611865 'warning’, 18621866 esc_html__('SEO keywords are found’, ‘wp-meta-seo’), 18631867 0 18641868 ); 18651869 18661870 $right_output = ‘<div class="metaseo_analysis metaseo_tool"><span style="font-weight: 700">’ . esc_html__('Page SEO keywords check’, ‘wp-meta-seo’) . '</span></div>’; 18671871 18681872 $right_output .= $this->createFieldAnalysis( 18691873 'keyintitle’, 18701874 esc_html__('The SEO keywords are found in page title’, ‘wp-meta-seo’), 18711875 'warning’, 18721876 esc_html__('The keywords are found in page title’, ‘wp-meta-seo’), 18731877 0 18741878 ); 18751879 18761880 $right_output .= $this->createFieldAnalysis( 18771881 'keyincontent’, 18781882 esc_html__('The SEO keywords are found in page content’, ‘wp-meta-seo’), 18791883 'warning’, 18801884 esc_html__('The keywords are found in page content’, ‘wp-meta-seo’), 18811885 0 18821886 ); 18831887 18841888 18851889 $right_output .= $this->createFieldAnalysis( 18861890 'keyinmetatitle’, 18871891 esc_html__('The SEO keywords are found in meta title’, ‘wp-meta-seo’), 18881892 'warning’, 18891893 esc_html__('The keywords are found in meta title’, ‘wp-meta-seo’), 18901894 0 18911895 ); 18921896 18931897 $right_output .= $this->createFieldAnalysis( 18941898 'keyinmetadescription’, 18951899 esc_html__('The SEO keywords are found in meta description’, ‘wp-meta-seo’), 18961900 'warning’, 18971901 esc_html__('The keywords are found in meta description’, ‘wp-meta-seo’), 18981902 0 18991903 ); 19001904 19011905 $right_output .= $this->createFieldAnalysis( 19021906 'keyincontentheading’, 19031907 esc_html__('The SEO keywords are found in page content heading’, ‘wp-meta-seo’), 19041908 'warning’, 19051909 esc_html__('The keywords are found in page content heading’, ‘wp-meta-seo’), 19061910 0 19071911 ); 19081912 } 19091913 $total_check = 7; 19101914 if (isset($_POST[‘datas’][‘seo_keywords’]) && !empty($_POST[‘datas’][‘seo_keywords’])) { 19111915 $total_check++; 19121916 } 19131917 $circliful = ceil(100 * ($check) / $total_check); 19141918 /** 19151919 * Reload analytics 19161920 * 19171921 * @param integer Post ID 19181922 * @param array All the datas 19191923 */ 19201924 do_action('wpms_reload_analytics’, $_POST[‘datas’][‘post_id’], $_POST[‘datas’]); 19211925 wp_send_json(array(‘circliful’ => $circliful, ‘output’ => $output, ‘check’ => $check, ‘right_output’ => $right_output)); 19221926 } 19231927 19241928 /** 19251929 * Extract html heading tags from WPBakery Page Builder shortcode 19261930 * 19271931 * @param string $postTitle Post title 19281932 * @param string $textContent Text content page/post 19291933 * @param array $search Html heading tags to extract 19301934 * 19311935 * @return array 19321936 */ 19331937 public function wpmsShortcodeExtract($postTitle, $textContent, $search) 19341938 { 19351939 $extracted = array(); 19361940 // Capture vc_custom_heading shortcode from post content 19371941 if (preg_match_all('/\[vc_custom_heading(.*?)\]/i’, $textContent, $matches)) { 19381942 if (!empty($matches)) { 19391943 foreach ($matches[1] as $vcCustomHeading) { 19401944 $attrs = shortcode_parse_atts(trim($vcCustomHeading)); 19411945 if (!empty($attrs[‘font_container’])) { 19421946 foreach ($search as $s) { 19431947 if (strpos($attrs[‘font_container’], ‘tag:’ . $s . ‘|’) !== false) { 19441948 $tag = $s; 19451949 break; // find out html tag 19461950 } 19471951 } 19481952 } else { 19491953 $tag = 'h2’; // default by WPBakery page builder if empty font_container attr 19501954 } 19511955 19521956 // Check case source="post_title" 19531957 $content = '’; 19541958 if (isset($attrs[‘source’]) && $attrs[‘source’] === ‘post_title’) { 19551959 $content = $postTitle; 19561960 } elseif (isset($attrs[‘text’]) && !empty($attrs[‘text’])) { 19571961 $content = $attrs[‘text’]; 19581962 } 19591963 19601964 if (!empty($attrs) && isset($tag)) { 19611965 $extracted[$tag][] = array( 19621966 ‘tag_name’ => $tag, 19631967 ‘offset’ => '’, 19641968 ‘contents’ => $content, 19651969 ‘attributes’ => array(), 19661970 ‘full_tag’ => '[vc_custom_heading ' . $vcCustomHeading . ']' 19671971 ); 19681972 } 19691973 } 19701974 } 19711975 } 19721976 19731977 // Capture trx_sc_title shortcode from post content 19741978 if (preg_match_all('/\[trx_sc_title(.*?)\]/i’, $textContent, $matches)) { 19751979 if (!empty($matches)) { 19761980 foreach ($matches[1] as $trxScTitle) { 19771981 $attrs = shortcode_parse_atts(trim($trxScTitle)); 19781982 if (!empty($attrs[‘title_tag’])) { 19791983 $titleTag = $attrs[‘title_tag’]; 19801984 } else { 19811985 $titleTag = 'h2’; // default by WPBakery page builder if empty title_tag attr 19821986 } 19831987 19841988 // Check case source="post_title" 19851989 $title = '’; 19861990 if (isset($attrs[‘title’])) { 19871991 $title = $attrs[‘title’]; 19881992 } 19891993 19901994 if (!empty($attrs) && !empty($title)) { 19911995 $extracted[$titleTag][] = array( 19921996 ‘tag_name’ => $titleTag, 19931997 ‘offset’ => '’, 19941998 ‘contents’ => $title, 19951999 ‘attributes’ => array(), 19962000 ‘full_tag’ => '[trx_sc_title ' . $trxScTitle . ']' 19972001 ); 19982002 } 19992003 } 20002004 } 20012005 } 20022006 20032007 return $extracted; 20042008 } 20052009 /** 20062010 * Validate propertyin page optimization 20072011 * 20082012 * @return void 20092013 */ 20102014 public function validateAnalysis() 20112015 { 20122016 if (empty($_POST[‘wpms_nonce’]) 20132017 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 20142018 die(); 20152019 } 20162020 20172021 if (!current_user_can(‘manage_options’)) { 20182022 wp_send_json(false); 20192023 } 20202024 $post_id = $_POST[‘post_id’]; 20212025 $key = 'wpms_validate_analysis’; 20222026 $analysis = get_post_meta($post_id, $key, true); 20232027 if (empty($analysis)) { 20242028 $analysis = array(); 20252029 } 20262030 20272031 $analysis[$_POST[‘field’]] = 1; 20282032 update_post_meta($post_id, $key, $analysis); 20292033 wp_send_json(true); 20302034 } 20312035 20322036 /** 20332037 * Remove link in source 404 20342038 * 20352039 * @return void 20362040 */ 20372041 public function removeLink() 20382042 { 20392043 if (empty($_POST[‘wpms_nonce’]) 20402044 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 20412045 die(); 20422046 } 20432047 20442048 if (!current_user_can(‘manage_options’)) { 20452049 wp_send_json(array(‘status’ => false)); 20462050 } 20472051 20482052 global $wpdb; 20492053 if (isset($_POST[‘link_id’])) { 20502054 $wpdb->delete($wpdb->prefix . 'wpms_links’, array(‘id’ => (int)$_POST[‘link_id’])); 20512055 wp_send_json(array(‘status’ => true)); 20522056 } 20532057 20542058 wp_send_json(array(‘status’ => false)); 20552059 } 20562060 20572061 /** 20582062 * Ajax update link meta title and content editor 20592063 * 20602064 * @param string $type Action type 20612065 * @param string $link_detail Link details 20622066 * @param string $title Title value 20632067 * @param integer $link_id Link ID 20642068 * 20652069 * @return void 20662070 */ 20672071 public function updateLink1($type, $link_detail, $title, $link_id) 20682072 { 20692073 global $wpdb; 20702074 global $wp_version; 20712075 // Purge title 20722076 $title = strip_tags($title); 20732077 $title = str_replace(“’", '’, $title); 20742078 $title = str_replace('"’, '’, $title); 20752079 20762080 $value = array(‘meta_title’ => $title); 20772081 $wpdb->update( 20782082 $wpdb->prefix . 'wpms_links’, 20792083 $value, 20802084 array(‘id’ => (int)$link_id) 20812085 ); 20822086 $post = get_post($link_detail->source_id); 20832087 20842088 if (!empty($post)) { 20852089 if (version_compare($wp_version, '5.0’, ‘>=’)) { 20862090 if (function_exists(‘has_blocks’)) { 20872091 if (has_blocks((int)$link_detail->source_id)) { 20882092 // Gutenberg 20892093 $post_content = $this->gutenbergUpdateContent($post->post_content, $link_detail, $title); 20902094 } else { 20912095 // Classic editor 20922096 $post_content = $this->replaceNewTitle($post->post_content, $link_detail, $title); 20932097 } 20942098 } 20952099 } else { 20962100 // Classic editor 20972101 $post_content = $this->replaceNewTitle($post->post_content, $link_detail, $title); 20982102 } 20992103 21002104 $my_post = array( 21012105 ‘ID’ => (int)$link_detail->source_id, 21022106 ‘post_content’ => $post_content 21032107 ); 21042108 remove_action('post_updated’, array('MetaSeoBrokenLinkTable’, ‘updatePost’)); 21052109 wp_update_post($my_post); 21062110 if ($type === ‘ajax’) { 21072111 wp_send_json(array(‘status’ => true)); 21082112 } 21092113 } 21102114 } 21112115 21122116 /** 21132117 * Update link meta title and content editor in gutenberg 21142118 * 21152119 * @param string $post_content Content of posts 21162120 * @param string $link_detail Link details 21172121 * @param string $title Title value 21182122 * 21192123 * @return string 21202124 */ 21212125 public function gutenbergUpdateContent($post_content, $link_detail, $title) 21222126 { 21232127 $blocks = parse_blocks($post_content); 21242128 // phpcs:disable Generic.PHP.LowerCaseConstant.Found – In special case the block returns NULL 21252129 $allowed_blocks = array( 21262130 // Classic blocks have their blockName set to null. 21272131 null, 21282132 NULL, 21292133 'core/button’, 21302134 'core/paragraph’, 21312135 'core/heading’, 21322136 'core/list’, 21332137 'core/quote’, 21342138 'core/cover’, 21352139 'core/html’, 21362140 'core/verse’, 21372141 'core/preformatted’, 21382142 'core/pullquote’, 21392143 'core/table’, 21402144 ‘core/media-text’ 21412145 ); 21422146 // phpcs:enable 21432147 foreach ($blocks as $block) { 21442148 // Gutenberg block 21452149 if (in_array($block[‘blockName’], $allowed_blocks, true)) { 21462150 if (!empty($block[‘innerBlocks’])) { 21472151 // Skip the block if it has disallowed or nested inner blocks. 21482152 foreach ($block[‘innerBlocks’] as $inner_block) { 21492153 if (!in_array($inner_block[‘blockName’], $allowed_blocks, true) || 21502154 !empty($inner_block[‘innerBlocks’]) 21512155 ) { 21522156 continue; 21532157 } 21542158 } 21552159 } 21562160 21572161 if (strpos($block[‘innerHTML’], $link_detail->link_text) !== false) { 21582162 $post_content = $this->replaceNewTitle($post_content, $link_detail, $title); 21592163 } 21602164 } 21612165 } 21622166 21632167 return $post_content; 21642168 } 21652169 21662170 /** 21672171 * Filter and replace new title 21682172 * 21692173 * @param string $post_content Content of posts 21702174 * @param string $link_detail Link details 21712175 * @param string $title Title value 21722176 * 21732177 * @return string 21742178 */ 21752179 protected function replaceNewTitle($post_content, $link_detail, $title) 21762180 { 21772181 $links = wpmsExtractTags($post_content, 'a’, false, true); 21782182 $title_tag = sprintf('%s="%s"’, 'title’, esc_attr($title)); 21792183 if (!empty($links)) { 21802184 foreach ($links as $link) { 21812185 if ($link[‘contents’] === $link_detail->link_text) { 21822186 if (!isset($link[‘attributes’][‘title’])) { 21832187 // Not titlte, add new 21842188 $new_html = preg_replace( 21852189 '/<a/is’, 21862190 ‘<a ' . $title_tag, 21872191 $link[‘full_tag’] 21882192 ); 21892193 } else { 21902194 $new_html = preg_replace( 21912195 ‘/title=(["\’])(.*?)["\’]/is’, 21922196 $title_tag, 21932197 $link[‘full_tag’] 21942198 ); 21952199 } 21962200 // Replace tag 21972201 $post_content = str_replace($link[‘full_tag’], $new_html, $post_content); 21982202 } 21992203 } 22002204 } 22012205 22022206 return $post_content; 22032207 } 22042208 22052209 /** 22062210 * Ajax update link meta title and content editor 22072211 * 22082212 * @return void 22092213 */ 22102214 public function updateLink() 22112215 { 22122216 if (empty($_POST[‘wpms_nonce’]) 22132217 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 22142218 die(); 22152219 } 22162220 22172221 if (!current_user_can(‘manage_options’)) { 22182222 wp_send_json(false); 22192223 } 22202224 if (isset($_POST[‘link_id’])) { 22212225 global $wpdb; 22222226 $link_detail = $wpdb->get_row($wpdb->prepare( 22232227 'SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE id=%d’, 22242228 array( 22252229 (int)$_POST[‘link_id’] 22262230 ) 22272231 )); 22282232 if (empty($link_detail)) { 22292233 wp_send_json(false); 22302234 } 22312235 $this->updateLink1('ajax’, $link_detail, $_POST[‘meta_title’], $_POST[‘link_id’]); 22322236 } 22332237 wp_send_json(false); 22342238 } 22352239 22362240 /** 22372241 * Ajax update meta index for page 22382242 * 22392243 * @return void 22402244 */ 22412245 public function updatePageIndex() 22422246 { 22432247 if (empty($_POST[‘wpms_nonce’]) 22442248 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 22452249 die(); 22462250 } 22472251 22482252 if (!current_user_can(‘manage_options’)) { 22492253 wp_send_json(array(‘status’ => false)); 22502254 } 22512255 if (isset($_POST[‘page_id’]) && isset($_POST[‘index’])) { 22522256 update_post_meta($_POST[‘page_id’], '_metaseo_metaindex’, $_POST[‘index’]); 22532257 /** 22542258 * Update index/noindex for robots meta tag of a page 22552259 * 22562260 * @param integer Page ID 22572261 * @param string Page meta index 22582262 * @param integer Page index value 22592263 */ 22602264 do_action('wpms_update_page_index’, $_POST[‘page_id’], '_metaseo_metaindex’, $_POST[‘index’]); 22612265 wp_send_json(array(‘status’ => true)); 22622266 } 22632267 wp_send_json(array(‘status’ => false)); 22642268 } 22652269 22662270 /** 22672271 * Ajax update meta follow for page 22682272 * 22692273 * @return void 22702274 */ 22712275 public function updatePageFollow() 22722276 { 22732277 if (empty($_POST[‘wpms_nonce’]) 22742278 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 22752279 die(); 22762280 } 22772281 22782282 if (!current_user_can(‘manage_options’)) { 22792283 wp_send_json(array(‘status’ => false)); 22802284 } 22812285 if (isset($_POST[‘page_id’]) && isset($_POST[‘follow’])) { 22822286 update_post_meta((int)$_POST[‘page_id’], '_metaseo_metafollow’, $_POST[‘follow’]); 22832287 22842288 /** 22852289 * Update follow/nofollow for robots meta tag of a page 22862290 * 22872291 * @param integer Page ID 22882292 * @param string Page meta follow 22892293 * @param integer Page follow value 22902294 */ 22912295 do_action('wpms_update_page_follow’, $_POST[‘page_id’], '_metaseo_metafollow’, $_POST[‘follow’]); 22922296 wp_send_json(array(‘status’ => true)); 22932297 } 22942298 wp_send_json(array(‘status’ => false)); 22952299 } 22962300 22972301 /** 22982302 * Ajax update meta follow for link 22992303 * 23002304 * @return void 23012305 */ 23022306 public function updateFollow() 23032307 { 23042308 if (empty($_POST[‘wpms_nonce’]) 23052309 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 23062310 die(); 23072311 } 23082312 23092313 if (!current_user_can(‘manage_options’)) { 23102314 wp_send_json(array(‘status’ => false)); 23112315 } 23122316 if (isset($_POST[‘link_id’])) { 23132317 $this->doUpdateFollow($_POST[‘link_id’], $_POST[‘follow’]); 23142318 /** 23152319 * Update follow/nofollow for rel attribute of a link 23162320 * 23172321 * @param integer Link ID 23182322 * @param integer Link follow 23192323 */ 23202324 do_action('wpms_update_link_follow’, $_POST[‘link_id’], $_POST[‘follow’]); 23212325 wp_send_json(array(‘status’ => true)); 23222326 } 23232327 wp_send_json(array(‘status’ => false)); 23242328 } 23252329 23262330 /** 23272331 * Ajax update multitle meta follow for link 23282332 * 23292333 * @return void 23302334 */ 23312335 public function updateMultipleFollow() 23322336 { 23332337 if (empty($_POST[‘wpms_nonce’]) 23342338 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 23352339 die(); 23362340 } 23372341 23382342 if (!current_user_can(‘manage_options’)) { 23392343 wp_send_json(array(‘status’ => false)); 23402344 } 23412345 global $wpdb; 23422346 $action_name = $_POST[‘action_name’]; 23432347 $limit = 20; 23442348 23452349 switch ($action_name) { 23462350 case 'copy_title_selected’: 23472351 if (empty($_POST[‘linkids’])) { 23482352 wp_send_json(array(‘status’ => true)); 23492353 } 23502354 foreach ($_POST[‘linkids’] as $linkId) { 23512355 $link = $wpdb->get_row( 23522356 $wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE id = %d’, $linkId) 23532357 ); 23542358 $link_text = $link->link_text; 23552359 if ($link_text !== ‘’) { 23562360 $this->updateLink1('bulk’, $link, $link_text, $linkId); 23572361 } 23582362 } 23592363 23602364 break; 23612365 case 'copy_title_all’: 23622366 $links = $wpdb->get_results( 23632367 'SELECT * FROM ' . $wpdb->prefix . ‘wpms_links WHERE type="url"’ 23642368 ); 23652369 foreach ($links as $link) { 23662370 $link_text = $link->link_text; 23672371 if ($link_text !== ‘’) { 23682372 $this->updateLink1('bulk’, $link, $link_text, $link->id); 23692373 } 23702374 } 23712375 break; 23722376 case 'follow_selected’: 23732377 if (empty($_POST[‘linkids’])) { 23742378 wp_send_json(array(‘status’ => true)); 23752379 } 23762380 23772381 $follow = 1; 23782382 foreach ($_POST[‘linkids’] as $linkId) { 23792383 $this->doUpdateFollow($linkId, $follow); 23802384 /** 23812385 * Update follow/nofollow for rel attribute of a link 23822386 * 23832387 * @param integer Link ID 23842388 * @param integer Link follow 23852389 * 23862390 * @ignore Hook already documented 23872391 */ 23882392 do_action('wpms_update_link_follow’, $linkId, $follow); 23892393 } 23902394 break; 23912395 case 'follow_all’: 23922396 $follow = 1; 23932397 $i = 0; 23942398 $links = $wpdb->get_results( 23952399 'SELECT * FROM ' . $wpdb->prefix . ‘wpms_links WHERE follow=0 AND type="url"’ 23962400 ); 23972401 foreach ($links as $link) { 23982402 if ($i > $limit) { 23992403 wp_send_json(array(‘status’ => false, ‘message’ => ‘limit’)); 24002404 } else { 24012405 $this->doUpdateFollow($link->id, $follow); 24022406 $i++; 24032407 /** 24042408 * Update follow/nofollow for rel attribute of a link 24052409 * 24062410 * @param integer Link ID 24072411 * @param integer Link follow 24082412 * 24092413 * @ignore Hook already documented 24102414 */ 24112415 do_action('wpms_update_link_follow’, $link->id, $follow); 24122416 } 24132417 } 24142418 break; 24152419 case 'nofollow_selected’: 24162420 $follow = 0; 24172421 if (empty($_POST[‘linkids’])) { 24182422 wp_send_json(array(‘status’ => true)); 24192423 } 24202424 24212425 foreach ($_POST[‘linkids’] as $linkId) { 24222426 $this->doUpdateFollow($linkId, $follow); 24232427 /** 24242428 * Update follow/nofollow for rel attribute of a link 24252429 * 24262430 * @param integer Link ID 24272431 * @param integer Link follow 24282432 * 24292433 * @ignore Hook already documented 24302434 */ 24312435 do_action('wpms_update_link_follow’, $linkId, $follow); 24322436 } 24332437 break; 24342438 case 'nofollow_all’: 24352439 $follow = 0; 24362440 $i = 0; 24372441 $links = $wpdb->get_results( 24382442 'SELECT * FROM ' . $wpdb->prefix . ‘wpms_links WHERE follow=1 AND type="url"’ 24392443 ); 24402444 foreach ($links as $link) { 24412445 if ($i > $limit) { 24422446 wp_send_json(array(‘status’ => false, ‘message’ => ‘limit’)); 24432447 } else { 24442448 $this->doUpdateFollow($link->id, $follow); 24452449 $i++; 24462450 /** 24472451 * Update follow/nofollow for rel attribute of a link 24482452 * 24492453 * @param integer Link ID 24502454 * @param integer Link follow 24512455 * 24522456 * @ignore Hook already documented 24532457 */ 24542458 do_action('wpms_update_link_follow’, $link->id, $follow); 24552459 } 24562460 } 24572461 break; 24582462 } 24592463 wp_send_json(array(‘status’ => true)); 24602464 } 24612465 24622466 /** 24632467 * Ajax update meta follow for link 24642468 * 24652469 * @param integer $linkId Link id 24662470 * @param integer $follow Follow value 24672471 * 24682472 * @return void 24692473 */ 24702474 public function doUpdateFollow($linkId, $follow) 24712475 { 24722476 global $wpdb; 24732477 $link_detail = $wpdb->get_row($wpdb->prepare( 24742478 'SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE id=%d’, 24752479 array((int)$linkId) 24762480 )); 24772481 if (empty($link_detail)) { 24782482 wp_send_json(array(‘status’ => false)); 24792483 } 24802484 24812485 $value = array(‘follow’ => $follow); 24822486 $wpdb->update( 24832487 $wpdb->prefix . 'wpms_links’, 24842488 $value, 24852489 array(‘id’ => (int)$linkId) 24862490 ); 24872491 24882492 $post = get_post($link_detail->source_id); 24892493 if (!empty($post)) { 24902494 $old_value = $post->post_content; 24912495 $edit_result = $this->editLinkHtml( 24922496 $old_value, 24932497 $link_detail->link_url, 24942498 $link_detail->link_url, 24952499 $link_detail->meta_title, 24962500 $follow 24972501 ); 24982502 $my_post = array( 24992503 ‘ID’ => (int)$link_detail->source_id, 25002504 ‘post_content’ => $edit_result[‘content’] 25012505 ); 25022506 remove_action('post_updated’, array('MetaSeoBrokenLinkTable’, ‘updatePost’)); 25032507 wp_update_post($my_post); 25042508 } 25052509 } 25062510 25072511 /** 25082512 * Render new content when edit a link 25092513 * 25102514 * @param string $content Post content 25112515 * @param string $new_url New url 25122516 * @param string $old_url Old url 25132517 * @param string $meta_title Meta title 25142518 * @param integer $follow Follow value 25152519 * @param null $new_text New text of link 25162520 * 25172521 * @return array 25182522 */ 25192523 public function editLinkHtml($content, $new_url, $old_url, $meta_title, $follow, $new_text = null) 25202524 { 25212525 //Save the old & new URLs for use in the edit callback. 25222526 $args = array( 25232527 ‘old_url’ => $old_url, 25242528 ‘new_url’ => $new_url, 25252529 ‘new_text’ => $new_text, 25262530 ‘meta_title’ => $meta_title, 25272531 ‘follow’ => $follow 25282532 ); 25292533 25302534 //Find all links and replace those that match $old_url. 25312535 $content = MetaSeoBrokenLinkTable::multiEdit( 25322536 $content, 25332537 array( 25342538 'MetaSeoBrokenLinkTable’, 25352539 ‘editHtmlCallback’ 25362540 ), 25372541 $args 25382542 ); 25392543 25402544 $result = array( 25412545 ‘content’ => $content, 25422546 ‘raw_url’ => $new_url, 25432547 ); 25442548 if (isset($new_text)) { 25452549 $result[‘link_text’] = $new_text; 25462550 } 25472551 return $result; 25482552 } 25492553 25502554 /** 25512555 * Update option wpms_settings_404 25522556 * 25532557 * @return void 25542558 */ 25552559 public function save404Settings() 25562560 { 25572561 if (empty($_POST[‘wpms_nonce’]) 25582562 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 25592563 die(); 25602564 } 25612565 25622566 if (!current_user_can(‘manage_options’)) { 25632567 wp_send_json(false); 25642568 } 25652569 25662570 if (isset($_POST[‘wpms_redirect’])) { 25672571 update_option('wpms_settings_404’, $_POST[‘wpms_redirect’]); 25682572 } 25692573 25702574 if (is_plugin_active(WPMSEO_ADDON_FILENAME)) { 25712575 $params = array('enable’, 'numberFrequency’, ‘showlinkFrequency’); 25722576 $settinglink = array(); 25732577 foreach ($params as $param) { 25742578 if (isset($_POST[$param])) { 25752579 $settinglink[$param] = $_POST[$param]; 25762580 } 25772581 } 25782582 25792583 if (empty($settinglink[‘wpms_lastRun_scanlink’])) { 25802584 $settinglink[‘wpms_lastRun_scanlink’] = time(); 25812585 } 25822586 update_option('wpms_link_settings’, $settinglink); 25832587 } 25842588 25852589 wp_send_json(true); 25862590 } 25872591 25882592 /** 25892593 * Update breadcrumb settings 25902594 * 25912595 * @return void 25922596 */ 25932597 public function saveBreadcrumbSettings() 25942598 { 25952599 if (empty($_POST[‘wpms_nonce’]) 25962600 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 25972601 die(); 25982602 } 25992603 26002604 if (!current_user_can(‘manage_options’)) { 26012605 wp_send_json(false); 26022606 } 26032607 26042608 $params = array('separator’, 'include_home’, 'home_text’, 'clickable’, ‘home_text_default’); 26052609 $settinglink = array(); 26062610 foreach ($params as $param) { 26072611 if (isset($_POST[$param])) { 26082612 $settinglink[$param] = $_POST[$param]; 26092613 } 26102614 } 26112615 26122616 update_option('_metaseo_breadcrumbs’, $settinglink); 26132617 wp_send_json(true); 26142618 } 26152619 26162620 /** 26172621 * Show meta box in single post, on elementor plugin 26182622 * 26192623 * @return void 26202624 */ 26212625 private function loadMetaBoxes() 26222626 { 26232627 if (in_array($this->pagenow, array( 26242628 'edit.php’, 26252629 'post.php’, 26262630 'post-new.php’, 26272631 )) || apply_filters('wpmseo_always_register_metaboxes_on_admin’, false) 26282632 ) { 26292633 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/class.metaseo-metabox.php’); 26302634 $GLOBALS[‘wpmseo_metabox’] = new WPMSEOMetabox; 26312635 } 26322636 } 26332637 26342638 /** 26352639 * Update meta title , meta description , meta keyword for content 26362640 * 26372641 * @return void 26382642 */ 26392643 public function updateContentMetaCallback() 26402644 { 26412645 if (empty($_POST[‘wpms_nonce’]) 26422646 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 26432647 die(); 26442648 } 26452649 26462650 if (!current_user_can(‘manage_options’)) { 26472651 wp_send_json(array(‘status’ => false)); 26482652 } 26492653 $_POST = stripslashes_deep($_POST); 26502654 $response = new stdClass(); 26512655 $metakey = strtolower(trim($_POST[‘metakey’])); 26522656 $postID = intval($_POST[‘postid’]); 26532657 $value = trim($_POST[‘value’]); 26542658 $response->msg = esc_html__('Modification was saved’, ‘wp-meta-seo’); 26552659 if ($metakey === ‘metatitle’) { 26562660 if (!update_post_meta($postID, '_metaseo_metatitle’, $value)) { 26572661 $response->updated = false; 26582662 $response->msg = esc_html__('Meta title was not saved’, ‘wp-meta-seo’); 26592663 } else { 26602664 $response->updated = true; 26612665 $response->msg = esc_html__('Meta title was saved’, ‘wp-meta-seo’); 26622666 } 26632667 } 26642668 26652669 if ($metakey === ‘metadesc’) { 26662670 if (!update_post_meta($postID, '_metaseo_metadesc’, $value)) { 26672671 $response->updated = false; 26682672 $response->msg = esc_html__('Meta description was not saved’, ‘wp-meta-seo’); 26692673 } else { 26702674 $response->updated = true; 26712675 $response->msg = esc_html__('Meta description was saved’, ‘wp-meta-seo’); 26722676 } 26732677 } 26742678 26752679 if ($metakey === ‘metakeywords’) { 26762680 if (!update_post_meta($postID, '_metaseo_metakeywords’, $value)) { 26772681 $response->updated = false; 26782682 $response->msg = esc_html__('Meta keywords was not saved’, ‘wp-meta-seo’); 26792683 } else { 26802684 $response->updated = true; 26812685 $response->msg = esc_html__('Meta keywords was saved’, ‘wp-meta-seo’); 26822686 } 26832687 } 26842688 update_option('wpms_last_update_post’, time()); 26852689 echo json_encode($response); 26862690 wp_die(); 26872691 } 26882692 26892693 /** 26902694 * Loads js/ajax scripts 26912695 * 26922696 * @return void 26932697 */ 26942698 public function loadAdminScripts() 26952699 { 26962700 global $pagenow, $current_screen; 26972701 wp_enqueue_script(‘jquery’); 26982702 $array_menu = array( 26992703 'wp-meta-seo_page_metaseo_dashboard’, 27002704 'wp-meta-seo_page_metaseo_image_optimize’, 27012705 'wp-meta-seo_page_metaseo_google_sitemap’, 27022706 'wp-meta-seo_page_metaseo_image_compression’, 27032707 'wp-meta-seo_page_metaseo_broken_link’, 27042708 'wp-meta-seo_page_metaseo_settings’, 27052709 'wp-meta-seo_page_metaseo_content_meta’, 27062710 'wp-meta-seo_page_metaseo_category_meta’, 27072711 'wp-meta-seo_page_metaseo_image_meta’, 27082712 ‘wp-meta-seo_page_metaseo_link_meta’ 27092713 ); 27102714 27112715 $lists_pages = array( 27122716 'toplevel_page_metaseo_dashboard’, 27132717 'wp-meta-seo_page_metaseo_content_meta’, 27142718 'wp-meta-seo_page_metaseo_category_meta’, 27152719 'wp-meta-seo_page_metaseo_google_sitemap’, 27162720 'wp-meta-seo_page_metaseo_image_meta’, 27172721 'wp-meta-seo_page_metaseo_link_meta’, 27182722 'wp-meta-seo_page_metaseo_broken_link’, 27192723 'wp-meta-seo_page_metaseo_console’, 27202724 'wp-meta-seo_page_metaseo_google_analytics’, 27212725 'wp-meta-seo_page_metaseo_sendemail’, 27222726 ‘wp-meta-seo_page_metaseo_settings’ 27232727 ); 27242728 27252729 wp_enqueue_style( 27262730 'metaseo-google-icon’, 27272731 ‘//fonts.googleapis.com/icon?family=Material+Icons’ 27282732 ); 27292733 27302734 if (!empty($current_screen) && in_array($current_screen->base, $lists_pages)) { 27312735 wp_enqueue_style( 27322736 'wpms-magnific-popup-style’, 27332737 plugins_url('assets/css/magnific-popup.css’, dirname(__FILE__)), 27342738 array(), 27352739 WPMSEO_VERSION 27362740 ); 27372741 27382742 wp_enqueue_style( 27392743 'wpms_ju_waves_css’, 27402744 plugins_url('assets/wordpress-css-framework/css/waves.min.css’, dirname(__FILE__)), 27412745 array(), 27422746 WPMSEO_VERSION 27432747 ); 27442748 27452749 wp_enqueue_script( 27462750 'wpms-magnific-popup-script’, 27472751 plugins_url('assets/js/jquery.magnific-popup.min.js’, dirname(__FILE__)), 27482752 array(), 27492753 WPMSEO_VERSION 27502754 ); 27512755 27522756 wp_enqueue_style( 27532757 'wpms_ju_framework_styles’, 27542758 plugins_url('assets/wordpress-css-framework/css/style.min.css’, dirname(__FILE__)), 27552759 array(), 27562760 WPMSEO_VERSION 27572761 ); 27582762 27592763 wp_enqueue_script( 27602764 'wpms_ju_velocity_js’, 27612765 plugins_url('assets/wordpress-css-framework/js/velocity.min.js’, dirname(__FILE__)), 27622766 array(), 27632767 WPMSEO_VERSION 27642768 ); 27652769 wp_enqueue_script( 27662770 'wpms_ju_waves_js’, 27672771 plugins_url('assets/wordpress-css-framework/js/waves.min.js’, dirname(__FILE__)), 27682772 array(), 27692773 WPMSEO_VERSION 27702774 ); 27712775 27722776 wp_enqueue_script( 27732777 'wpms_ju_tabs_js’, 27742778 plugins_url('assets/wordpress-css-framework/js/tabs.js’, dirname(__FILE__)), 27752779 array(), 27762780 WPMSEO_VERSION 27772781 ); 27782782 27792783 wp_enqueue_script( 27802784 'wpms_ju_framework_js’, 27812785 plugins_url('assets/wordpress-css-framework/js/script.js’, dirname(__FILE__)), 27822786 array(‘wpms_ju_tabs_js’), 27832787 WPMSEO_VERSION 27842788 ); 27852789 27862790 if ($current_screen->base !== ‘wp-meta-seo_page_metaseo_settings’) { 27872791 wp_enqueue_style( 27882792 'wpms_materialize_style’, 27892793 plugins_url('assets/css/materialize/materialize.css’, dirname(__FILE__)), 27902794 array(), 27912795 WPMSEO_VERSION 27922796 ); 27932797 } else { 27942798 // Register CSS 27952799 wp_enqueue_style( 27962800 'wpms-settings-styles’, 27972801 plugins_url('assets/css/settings.css’, dirname(__FILE__)), 27982802 array(‘wpms_main’), 27992803 WPMSEO_VERSION 28002804 ); 28012805 28022806 wp_enqueue_script( 28032807 'wpms-settings-script’, 28042808 plugins_url('assets/js/settings.js’, dirname(__FILE__)), 28052809 array(‘jquery’), 28062810 WPMSEO_VERSION, 28072811 true 28082812 ); 28092813 28102814 wp_localize_script('wpms-settings-script’, 'wpmsSettingsL10n’, array( 28112815 ‘choose_image’ => esc_html__('Use Image’, ‘wp-meta-seo’) 28122816 )); 28132817 } 28142818 28152819 wp_enqueue_style( 28162820 'wpms_main’, 28172821 plugins_url('assets/css/main.css’, dirname(__FILE__)), 28182822 array(), 28192823 WPMSEO_VERSION 28202824 ); 28212825 } 28222826 28232827 wp_enqueue_script( 28242828 'wpmetaseoAdmin’, 28252829 plugins_url('assets/js/metaseo_admin.js’, dirname(__FILE__)), 28262830 array(‘jquery’), 28272831 WPMSEO_VERSION, 28282832 true 28292833 ); 28302834 28312835 if (!empty($current_screen) && (in_array($current_screen->base, $array_menu) || $pagenow === ‘post.php’ || $pagenow === ‘post-new.php’)) { 28322836 wp_enqueue_style( 28332837 'wpmetaseoAdmin’, 28342838 plugins_url('assets/css/metaseo_admin.css’, dirname(__FILE__)), 28352839 array(), 28362840 WPMSEO_VERSION 28372841 ); 28382842 wp_enqueue_style( 28392843 'tooltip-metaimage’, 28402844 plugins_url('assets/css/tooltip-metaimage.css’, dirname(__FILE__)), 28412845 array(), 28422846 WPMSEO_VERSION 28432847 ); 28442848 28452849 wp_enqueue_style('style’, plugins_url('assets/css/style.css’, dirname(__FILE__)), array(), WPMSEO_VERSION); 28462850 } 28472851 28482852 if (!empty($current_screen) && ($current_screen->base === ‘wp-meta-seo_page_metaseo_image_meta’ 28492853 || $current_screen->base === ‘wp-meta-seo_page_metaseo_content_meta’)) { 28502854 wp_enqueue_script( 28512855 'wpms-bulk’, 28522856 plugins_url('assets/js/wpms-bulk-action.js’, dirname(__FILE__)), 28532857 array(‘jquery’), 28542858 WPMSEO_VERSION, 28552859 true 28562860 ); 28572861 wp_localize_script('wpms-bulk’, 'wpmseobulkL10n’, $this->localizeScript()); 28582862 } 28592863 28602864 if (!empty($current_screen) && $current_screen->base === ‘wp-meta-seo_page_metaseo_broken_link’) { 28612865 wp_enqueue_style( 28622866 'wpms_brokenlink_style’, 28632867 plugins_url('assets/css/broken_link.css’, dirname(__FILE__)), 28642868 array(), 28652869 WPMSEO_VERSION 28662870 ); 28672871 28682872 wp_enqueue_style( 28692873 'wpms-bootstrap-style’, 28702874 plugins_url('assets/css/bootstrap/bootstrap.min.css’, dirname(__FILE__)), 28712875 array(), 28722876 WPMSEO_VERSION 28732877 ); 28742878 28752879 wp_enqueue_style( 28762880 'wpms-bootstrap-multiselect-style’, 28772881 plugins_url('assets/css/bootstrap/bootstrap-multiselect.css’, dirname(__FILE__)), 28782882 array(), 28792883 WPMSEO_VERSION 28802884 ); 28812885 28822886 wp_enqueue_script( 28832887 'wpms-bootstrap-multiselect-script’, 28842888 plugins_url('assets/css/bootstrap/bootstrap-multiselect.js’, dirname(__FILE__)), 28852889 array(‘jquery’), 28862890 WPMSEO_VERSION, 28872891 true 28882892 ); 28892893 } 28902894 28912895 if (!empty($current_screen) && $current_screen->base === ‘toplevel_page_metaseo_dashboard’) { 28922896 wp_enqueue_script( 28932897 'metaseo-dashboard’, 28942898 plugins_url('assets/js/dashboard.js’, dirname(__FILE__)), 28952899 array(‘jquery’), 28962900 WPMSEO_VERSION, 28972901 true 28982902 ); 28992903 29002904 wp_enqueue_style( 29012905 'metaseo-quirk’, 29022906 plugins_url('assets/css/metaseo-quirk.css’, dirname(__FILE__)) 29032907 ); 29042908 29052909 wp_enqueue_style( 29062910 'm-style-dashboard’, 29072911 plugins_url('assets/css/dashboard.css’, dirname(__FILE__)), 29082912 array(), 29092913 WPMSEO_VERSION 29102914 ); 29112915 29122916 wp_enqueue_style( 29132917 'wpms-ju-css-framwork’, 29142918 plugins_url('assets/css/main.css’, dirname(__FILE__)), 29152919 array(), 29162920 WPMSEO_VERSION 29172921 ); 29182922 29192923 if (class_exists(‘MetaSeoAddonAdmin’)) { 29202924 wp_enqueue_style( 29212925 'msaddon-style-dashboard’, 29222926 WPMETASEO_ADDON_PLUGIN_URL . 'assets/css/dashboard.css’, 29232927 array(), 29242928 WPMSEO_ADDON_VERSION 29252929 ); 29262930 } 29272931 } 29282932 29292933 if (!empty($current_screen) && $current_screen->base === ‘wp-meta-seo_page_metaseo_better_ranking’) { 29302934 wp_enqueue_style( 29312935 'wpms-better-seo’, 29322936 plugins_url('assets/css/better_seo.css’, dirname(__FILE__)), 29332937 array(), 29342938 WPMSEO_VERSION 29352939 ); 29362940 29372941 wp_enqueue_style( 29382942 'wpms-ju-css-framwork’, 29392943 plugins_url('assets/css/main.css’, dirname(__FILE__)), 29402944 array(), 29412945 WPMSEO_VERSION 29422946 ); 29432947 } 29442948 29452949 $lists_pages = array( 29462950 'toplevel_page_metaseo_dashboard’, 29472951 'wp-meta-seo_page_metaseo_google_sitemap’, 29482952 'wp-meta-seo_page_metaseo_link_meta’, 29492953 'wp-meta-seo_page_metaseo_broken_link’, 29502954 ‘wp-meta-seo_page_metaseo_google_analytics’ 29512955 ); 29522956 if (!empty($current_screen) && in_array($current_screen->base, $lists_pages)) { 29532957 wp_enqueue_style( 29542958 'wpms_notification_style’, 29552959 plugins_url('assets/css/notification.css’, dirname(__FILE__)), 29562960 array(), 29572961 WPMSEO_VERSION 29582962 ); 29592963 wp_enqueue_script( 29602964 'wpms_notification_script’, 29612965 plugins_url('assets/js/notification.js’, dirname(__FILE__)), 29622966 array(), 29632967 WPMSEO_VERSION 29642968 ); 29652969 } 29662970 29672971 wp_register_style( 29682972 'wpms-dashboard-widgets’, 29692973 plugins_url('assets/css/dashboard-widgets/dashboard_widgets.css’, dirname(__FILE__)), 29702974 null, 29712975 WPMSEO_VERSION 29722976 ); 29732977 wp_register_style( 29742978 'wpms-category-field’, 29752979 plugins_url('assets/css/category_field.css’, dirname(__FILE__)), 29762980 null, 29772981 WPMSEO_VERSION 29782982 ); 29792983 wp_register_script( 29802984 'wpms-category-field’, 29812985 plugins_url('assets/js/category_field.js’, dirname(__FILE__)), 29822986 array(‘jquery’), 29832987 WPMSEO_VERSION, 29842988 true 29852989 ); 29862990 29872991 // Enqueue for category meta page 29882992 if (!empty($current_screen) && $current_screen->base === ‘wp-meta-seo_page_metaseo_category_meta’) { 29892993 wp_enqueue_style( 29902994 'wpmsCategoryMeta’, 29912995 plugins_url('assets/css/metaseo-category-meta-bulk.css’, dirname(__FILE__)), 29922996 array(), 29932997 WPMSEO_VERSION 29942998 ); 29952999 29963000 wp_enqueue_script( 29973001 'wpmsCategoryMeta’, 29983002 plugins_url('assets/js/wpms-category-meta.js’, dirname(__FILE__)), 29993003 array(‘jquery’), 30003004 WPMSEO_VERSION, 30013005 true 30023006 ); 30033007 wp_enqueue_script(‘wpms-category-field’); 30043008 } 30053009 30063010 wp_register_style( 30073011 'wpms-tippy-style’, 30083012 plugins_url('assets/tippy/tippy.css’, dirname(__FILE__)), 30093013 array(), 30103014 WPMSEO_VERSION 30113015 ); 30123016 30133017 wp_register_script( 30143018 'wpms-tippy-core’, 30153019 plugins_url('assets/tippy/tippy-core.js’, dirname(__FILE__)), 30163020 array(‘jquery’), 30173021 '2.2.1’, 30183022 true 30193023 ); 30203024 30213025 wp_register_script( 30223026 'wpms-tippy’, 30233027 plugins_url('assets/tippy/tippy.js’, dirname(__FILE__)), 30243028 array(‘jquery’), 30253029 '2.2.1’, 30263030 true 30273031 ); 30283032 30293033 wp_register_script( 30303034 'wpms-my-tippy’, 30313035 plugins_url('assets/tippy/my-tippy.js’, dirname(__FILE__)), 30323036 array(‘jquery’), 30333037 WPMSEO_VERSION, 30343038 true 30353039 ); 30363040 30373041 wp_enqueue_style( 30383042 'wpms-mytippy-style’, 30393043 plugins_url('assets/tippy/my-tippy.css’, dirname(__FILE__)), 30403044 array(), 30413045 WPMSEO_VERSION 30423046 ); 30433047 // Register snackbar script alert 30443048 wp_register_script( 30453049 'wpms-snackbar-script’, 30463050 plugins_url('assets/js/snackbar.js’, dirname(__FILE__)), 30473051 array(‘jquery’), 30483052 WPMSEO_VERSION, 30493053 true 30503054 ); 30513055 // Register snackbar style alert 30523056 wp_register_style( 30533057 'wpms-snackbar-style’, 30543058 plugins_url('assets/css/snackbar.css’, dirname(__FILE__)), 30553059 array(), 30563060 WPMSEO_VERSION 30573061 ); 30583062 wp_register_script( 30593063 'wpms-broken-link’, 30603064 plugins_url('assets/js/wpms-broken-link.js’, dirname(__FILE__)), 30613065 array(‘jquery’), 30623066 WPMSEO_VERSION, 30633067 true 30643068 ); 30653069 30663070 wp_register_style('metaseo-google-icon’, ‘//fonts.googleapis.com/icon?family=Material+Icons’); 30673071 if (!empty($current_screen) && $current_screen->base === ‘wp-meta-seo_page_metaseo_google_analytics’) { 30683072 $lang = get_bloginfo(‘language’); 30693073 $lang = explode('-', $lang); 30703074 $lang = $lang[0]; 30713075 wp_enqueue_style( 30723076 'wpms-nprogress’, 30733077 plugins_url('assets/css/google-analytics/nprogress.css’, dirname(__FILE__)), 30743078 null, 30753079 WPMSEO_VERSION 30763080 ); 30773081 30783082 wp_register_style( 30793083 'wpms-backend-item-reports’, 30803084 plugins_url('assets/css/google-analytics/admin-widgets.css’, dirname(__FILE__)), 30813085 null, 30823086 WPMSEO_VERSION 30833087 ); 30843088 wp_register_style( 30853089 'wpms-backend-tracking-code’, 30863090 plugins_url('assets/css/google-analytics/wpms-tracking-code.css’, dirname(__FILE__)), 30873091 null, 30883092 WPMSEO_VERSION 30893093 ); 30903094 30913095 wp_register_style( 30923096 'jquery-ui-tooltip-html’, 30933097 plugins_url('assets/css/google-analytics/jquery.ui.tooltip.html.css’, dirname(__FILE__)) 30943098 ); 30953099 30963100 wp_enqueue_style(‘jquery-ui-tooltip-html’); 30973101 30983102 wp_enqueue_script( 30993103 'wpmsgooglejsapi’, 31003104 ‘https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22language%22%3A%22’ . $lang . '%22%2C%22packages%22%3A%5B%22corechart%22%2C%20%22imagechart%22%2C%20%22table%22%2C%20%22orgchart%22%2C%20%22geochart%22%5D%7D%5D%7D’, 31013105 array(), 31023106 null 31033107 ); 31043108 31053109 wp_enqueue_script( 31063110 'wpms-nprogress’, 31073111 plugins_url('assets/js/google-analytics/nprogress.js’, dirname(__FILE__)), 31083112 array(‘jquery’), 31093113 WPMSEO_VERSION 31103114 ); 31113115 31123116 wp_enqueue_script( 31133117 'wpms-google-analytics’, 31143118 plugins_url('assets/js/google-analytics/google_analytics.js’, dirname(__FILE__)), 31153119 array(‘jquery’), 31163120 WPMSEO_VERSION, 31173121 true 31183122 ); 31193123 31203124 // Select toolbar 31213125 require_once 'google_analytics/wpmstools.php’; 31223126 $wpms_google_analytics = get_option(‘wpms_google_alanytics’); 31233127 if (isset($wpms_google_analytics[‘tableid_jail’]) && isset($wpms_google_analytics[‘profile_list’])) { 31243128 $wpms_profile = WpmsGaTools::getSelectedProfile($wpms_google_analytics[‘profile_list’], $wpms_google_analytics[‘tableid_jail’]); 31253129 } 31263130 if (isset($wpms_profile[4])) { 31273131 $property_type = $wpms_profile[4]; 31283132 } else { 31293133 $property_type = 'UA’; 31303134 } 31313135 /* @formatter:off */ 31323136 wp_localize_script( 31333137 'wpms-google-analytics’, 31343138 'wpmsItemData’, 31353139 array( 31363140 ‘ajaxurl’ => admin_url(‘admin-ajax.php’), 31373141 ‘security’ => wp_create_nonce(‘wpms_backend_item_reports’), 31383142 ‘dateList’ => array( 31393143 ‘realtime’ => esc_html__('Real-Time’, ‘wp-meta-seo’), 31403144 ‘today’ => esc_html__('Today’, ‘wp-meta-seo’), 31413145 ‘yesterday’ => esc_html__('Yesterday’, ‘wp-meta-seo’), 31423146 ‘7daysAgo’ => sprintf(esc_html__('Last %d Days’, ‘wp-meta-seo’), 7), 31433147 ‘14daysAgo’ => sprintf(esc_html__('Last %d Days’, ‘wp-meta-seo’), 14), 31443148 ‘30daysAgo’ => sprintf(esc_html__('Last %d Days’, ‘wp-meta-seo’), 30), 31453149 ‘90daysAgo’ => sprintf(esc_html__('Last %d Days’, ‘wp-meta-seo’), 90), 31463150 ‘365daysAgo’ => sprintf(_n('%s Year’, '%s Years’, 1, ‘wp-meta-seo’), esc_html__('One’, ‘wp-meta-seo’)), 31473151 ‘1095daysAgo’ => sprintf( 31483152 _n('%s Year’, '%s Years’, 3, ‘wp-meta-seo’), 31493153 esc_html__('Three’, ‘wp-meta-seo’) 31503154 ), 31513155 ), 31523156 ‘property_type’ => $property_type, 31533157 ‘reportList’ => array( 31543158 ‘sessions’ => esc_html__('Sessions’, ‘wp-meta-seo’), 31553159 ‘users’ => esc_html__('Users’, ‘wp-meta-seo’), 31563160 ‘organicSearches’ => esc_html__('Organic’, ‘wp-meta-seo’), 31573161 ‘pageviews’ => esc_html__('Page Views’, ‘wp-meta-seo’), 31583162 ‘visitBounceRate’ => esc_html__('Bounce Rate’, ‘wp-meta-seo’), 31593163 ‘locations’ => esc_html__('Location’, ‘wp-meta-seo’), 31603164 ‘contentpages’ => esc_html__('Pages’, ‘wp-meta-seo’), 31613165 ‘referrers’ => esc_html__('Referrers’, ‘wp-meta-seo’), 31623166 ‘searches’ => esc_html__('Searches’, ‘wp-meta-seo’), 31633167 ‘trafficdetails’ => esc_html__('Traffic’, ‘wp-meta-seo’), 31643168 ‘technologydetails’ => esc_html__('Technology’, ‘wp-meta-seo’), 31653169 ), 31663170 ‘reportList_ga4’ => array( 31673171 ‘sessions’ => esc_html__('Sessions’, ‘wp-meta-seo’), 31683172 ‘users’ => esc_html__('Users’, ‘wp-meta-seo’), 31693173 ‘pageviews’ => esc_html__('Page Views’, ‘wp-meta-seo’), 31703174 ‘visitBounceRate’ => esc_html__('Engagement’, ‘wp-meta-seo’), 31713175 ‘organicSearches’ => esc_html__('Transactions’, ‘wp-meta-seo’), 31723176 ‘locations’ => esc_html__('Location’, ‘wp-meta-seo’), 31733177 ‘contentpages’ => esc_html__('Pages’, ‘wp-meta-seo’), 31743178 ‘referrers’ => esc_html__('Referrers’, ‘wp-meta-seo’), 31753179 ‘searches’ => esc_html__('Searches’, ‘wp-meta-seo’), 31763180 ‘trafficdetails’ => esc_html__('Traffic’, ‘wp-meta-seo’), 31773181 ‘technologydetails’ => esc_html__('Technology’, ‘wp-meta-seo’), 31783182 ), 31793183 ‘i18n’ => array( 31803184 esc_html__('A JavaScript Error is blocking plugin resources!’, ‘wp-meta-seo’), //0 31813185 esc_html__('Traffic Mediums’, ‘wp-meta-seo’), 31823186 esc_html__('Visitor Type’, ‘wp-meta-seo’), 31833187 esc_html__('Search Engines’, ‘wp-meta-seo’), 31843188 esc_html__('Social Networks’, ‘wp-meta-seo’), 31853189 esc_html__('Sessions’, ‘wp-meta-seo’), //5 31863190 esc_html__('Users’, ‘wp-meta-seo’), 31873191 esc_html__('Page Views’, ‘wp-meta-seo’), 31883192 esc_html__('Bounce Rate’, ‘wp-meta-seo’), 31893193 esc_html__('Organic Search’, ‘wp-meta-seo’), 31903194 esc_html__('Pages/Session’, ‘wp-meta-seo’), //10 31913195 esc_html__('Invalid response’, ‘wp-meta-seo’), 31923196 esc_html__('Not enough data collected’, ‘wp-meta-seo’), 31933197 esc_html__('This report is unavailable’, ‘wp-meta-seo’), 31943198 esc_html__('report generated by’, ‘wp-meta-seo’), //14 31953199 esc_html__(‘This plugin needs an authorization:’, ‘wp-meta-seo’) . ' 31963200 <a href="’ . esc_html(admin_url(‘admin.php?page=metaseo_google_analytics&view=wpmsga_trackcode’)) . '"> 31973201 ' . esc_html__('authorize the plugin’, ‘wp-meta-seo’) . '</a>.’, 31983202 esc_html__('Browser’, ‘wp-meta-seo’), //16 31993203 esc_html__('Operating System’, ‘wp-meta-seo’), 32003204 esc_html__('Screen Resolution’, ‘wp-meta-seo’), 32013205 esc_html__('Mobile Brand’, ‘wp-meta-seo’), 32023206 esc_html__('REFERRALS’, ‘wp-meta-seo’), //20 32033207 esc_html__('KEYWORDS’, ‘wp-meta-seo’), 32043208 esc_html__('SOCIAL’, ‘wp-meta-seo’), 32053209 esc_html__('CAMPAIGN’, ‘wp-meta-seo’), 32063210 esc_html__('DIRECT’, ‘wp-meta-seo’), 32073211 esc_html__('NEW’, ‘wp-meta-seo’), //25 32083212 esc_html__(‘You need select a profile:’, ‘wp-meta-seo’) . ' 32093213 <a href="’ . esc_html(admin_url(‘admin.php?page=metaseo_google_analytics&view=wpmsga_trackcode’)) . '"> 32103214 ' . esc_html__('authorize the plugin’, ‘wp-meta-seo’) . '</a>.’, 32113215 esc_html__('Engagement’, ‘wp-meta-seo’), 32123216 esc_html__('Transactions’, ‘wp-meta-seo’), 32133217 ), 32143218 ‘rtLimitPages’ => 10, 32153219 ‘colorVariations’ => array( 32163220 '#1e73be’, 32173221 '#0459a4’, 32183222 '#378cd7’, 32193223 '#51a6f1’, 32203224 '#00408b’, 32213225 '#6abfff’, 32223226 ‘#002671’ 32233227 ), 32243228 ‘region’ => false, 32253229 ‘language’ => get_bloginfo(‘language’), 32263230 ‘viewList’ => false, 32273231 ‘scope’ => 'admin-widgets’, 32283232 ‘admin_url’ => admin_url() 32293233 ) 32303234 ); 32313235 32323236 wp_enqueue_script( 32333237 'wpms-cookie’, 32343238 plugins_url('assets/js/jquery.cookie.js’, dirname(__FILE__)), 32353239 array(), 32363240 ‘1.4.1’ 32373241 ); 32383242 } 32393243 32403244 // Add intro text on each wpms topic 32413245 $tippy_pages = array( 32423246 'wp-meta-seo_page_metaseo_content_meta’, 32433247 'wp-meta-seo_page_metaseo_category_meta’, 32443248 'wp-meta-seo_page_metaseo_image_meta’, 32453249 'wp-meta-seo_page_metaseo_google_sitemap’, 32463250 'wp-meta-seo_page_metaseo_link_meta’, 32473251 'wp-meta-seo_page_metaseo_broken_link’, 32483252 'wp-meta-seo_page_metaseo_google_analytics’, 32493253 ‘wp-meta-seo_page_metaseo_sendemail’ 32503254 ); 32513255 if (!empty($current_screen) && in_array($current_screen->base, $tippy_pages)) { 32523256 wp_enqueue_style(‘wpms-tippy-style’); 32533257 wp_enqueue_script(‘wpms-tippy-core’); 32543258 wp_enqueue_script(‘wpms-tippy’); 32553259 wp_enqueue_script(‘wpms-my-tippy’); 32563260 } 32573261 32583262 if (is_plugin_active(WPMSEO_ADDON_FILENAME)) { 32593263 $addon_active = 1; 32603264 } else { 32613265 $addon_active = 0; 32623266 } 32633267 // in JavaScript, object properties are accessed as ajax_object.ajax_url, ajax_object.we_value 32643268 wp_localize_script('wpmetaseoAdmin’, 'wpms_localize’, array( 32653269 ‘filter_by’ => esc_html__('Select to filter’, ‘wp-meta-seo’), 32663270 ‘replaced’ => esc_html__('Replaced’, ‘wp-meta-seo’), 32673271 ‘index_link’ => esc_html__('Loading…’, ‘wp-meta-seo’), 32683272 ‘addon_active’ => $addon_active, 32693273 ‘ajax_url’ => admin_url(‘admin-ajax.php’), 32703274 ‘settings’ => $this->settings, 32713275 ‘wpms_cat_metatitle_length’ => MPMSCAT_TITLE_LENGTH, 32723276 ‘wpms_cat_metadesc_length’ => MPMSCAT_DESC_LENGTH, 32733277 ‘wpms_cat_metakeywords_length’ => MPMSCAT_KEYWORDS_LENGTH, 32743278 ‘wpms_nonce’ => wp_create_nonce(‘wpms_nonce’), 32753279 ‘home_url’ => home_url(), 32763280 ‘images_url’ => WPMETASEO_PLUGIN_URL . 'assets/images/’, 32773281 ‘dashboard_tooltips’ => array( 32783282 ‘url_rewwrite’ => esc_html__('Optimized at: ', ‘wp-meta-seo’), 32793283 ‘images_resized’ => esc_html__('HTML image resized (using handles) count: ', ‘wp-meta-seo’), 32803284 ‘metatitle’ => esc_html__('Meta title filled: ', ‘wp-meta-seo’), 32813285 ‘image_alt’ => esc_html__('Image data filled (in content): ', ‘wp-meta-seo’), 32823286 ‘metadesc’ => esc_html__('Meta description filled: ', ‘wp-meta-seo’), 32833287 ‘link_title’ => esc_html__('Links title completed: ', ‘wp-meta-seo’), 32843288 ‘fresh_content’ => esc_html__('Last month new or updated content: ', ‘wp-meta-seo’), 32853289 ‘elements’ => esc_html__(' elements’, ‘wp-meta-seo’), 32863290 ‘duplicate_title’ => esc_html__('Duplicate Meta Titles: ', ‘wp-meta-seo’), 32873291 ‘duplicate_desc’ => esc_html__('Duplicate Meta Descriptions: ', ‘wp-meta-seo’), 32883292 ‘404’ => esc_html__('Redirected 404 errors: ', ‘wp-meta-seo’) 32893293 ), 32903294 ‘gg_disconnect_title’ => array ( 32913295 ‘universal’ => esc_html__('UA-Tracking ID’, ‘wp-meta-seo’), 32923296 ‘ga4’ => esc_html__('Measurement ID’, ‘wp-meta-seo’), 32933297 ‘tagmanager’ => esc_html__('Container ID’, ‘wp-meta-seo’), 32943298 ) 32953299 )); 32963300 32973301 32983302 $this->columnsEnqueue(); 32993303 } 33003304 33013305 /** 33023306 * Enqueue styles and scripts. 33033307 * 33043308 * @return void 33053309 */ 33063310 public function columnsEnqueue() 33073311 { 33083312 if (function_exists(‘get_current_screen’)) { 33093313 $screen = get_current_screen(); 33103314 $allowed_post_types = self::getAccessiblePostTypes(); 33113315 33123316 if (!empty($current_screen) && !in_array($screen->post_type, $allowed_post_types, true)) { 33133317 return; 33143318 } 33153319 } 33163320 33173321 wp_enqueue_style( 33183322 'wpms-post-bulk-edit’, 33193323 plugins_url('assets/css/wpms-post-bulk-edit.css’, dirname(__FILE__)), 33203324 null, 33213325 WPMSEO_VERSION 33223326 ); 33233327 33243328 wp_enqueue_script( 33253329 'wpms-post-bulk-edit-js’, 33263330 plugins_url('assets/js/wpms-post-bulk-edit.js’, dirname(__FILE__)), 33273331 array(‘jquery’), 33283332 WPMSEO_VERSION, 33293333 true 33303334 ); 33313335 wp_localize_script('wpms-post-bulk-edit-js’, 'wpms_post_bulk’, array( 33323336 ‘title’ => esc_attr__('Bulk Edit This Field’, ‘wp-meta-seo’), 33333337 ‘saveAll’ => esc_attr__('Save all’, ‘wp-meta-seo’), 33343338 ‘cancelButton’ => esc_attr__('Cancel all’, ‘wp-meta-seo’), 33353339 ‘nonce’ => wp_create_nonce(‘wpms_nonce’) 33363340 )); 33373341 } 33383342 33393343 /** 33403344 * Add content for title column. 33413345 * 33423346 * @param integer $post_id The current post ID. 33433347 * 33443348 * @return void 33453349 */ 33463350 public function getColumnSeoKeywordsDetails($post_id) 33473351 { 33483352 $score = get_post_meta($post_id, 'wp_metaseo_seoscore’, true); 33493353 $keywords = get_post_meta($post_id, '_metaseo_metaspecific_keywords’, true); 33503354 $class = !empty($score) ? $this->getScoreClass((int)$score) : ‘wpms-no-score’; 33513355 $score = !empty($score) ? $score . ' / 100’ : 'N/A’; 33523356 33533357 ?> 33543358 <span class="wpms-column-display score <?php echo esc_attr($class); ?> <?php echo empty($score) ? ‘disabled’ : '’; ?>"> 33553359 <strong><?php echo esc_html($score); ?></strong> 33563360 </span> 33573361 <span class="wpms-column-display keyword” <?php echo (empty($keywords)) ? ‘style="display:none"’ : '’; ?> > 33583362 <strong title="SEO Keyword" class="title"><?php esc_html_e('Keyword’, ‘wp-meta-seo’); ?>:</strong> 33593363 <span><?php echo $keywords ? esc_html($keywords) : '’; ?></span> 33603364 </span> 33613365 <span class="wpms-column-value" data-field="seo_keyword" contenteditable="true" tabindex="11"> 33623366 <span><?php echo esc_html($keywords); ?></span> 33633367 </span> 33643368 <div class="wpms-column-edit"> 33653369 <a href="#" class="wpms-column-save"><?php esc_html_e('Save’, ‘wp-meta-seo’); ?></a> 33663370 <a href="#" class="button-link-delete wpms-column-cancel"><?php esc_html_e('Cancel’, ‘wp-meta-seo’); ?></a> 33673371 </div> 33683372 <?php 33693373 } 33703374 33713375 /** 33723376 * Get SEO score rating string: great/good/bad. 33733377 * 33743378 * @param integer $score Score. 33753379 * 33763380 * @return string 33773381 */ 33783382 private function getScoreClass($score) 33793383 { 33803384 if ($score > 75) { 33813385 return 'wpms-great-score’; 33823386 } 33833387 33843388 return 'wpms-bad-score’; 33853389 } 33863390 33873391 /** 33883392 * Register post column hooks. 33893393 * 33903394 * @return void 33913395 */ 33923396 public function registerPostColumns() 33933397 { 33943398 foreach (self::getAccessiblePostTypes() as $post_type) { 33953399 add_filter('edd_download_columns’, array($this, ‘addColumns’), 11); 33963400 add_filter(‘manage_’ . $post_type . '_posts_columns’, array($this, ‘addColumns’), 11); 33973401 33983402 33993403 add_action(‘manage_’ . $post_type . '_posts_custom_column’, array($this, ‘columnsContents’), 11, 2); 34003404 add_filter('manage_edit-' . $post_type . '_sortable_columns’, array($this, ‘sortableColumns’), 11); 34013405 } 34023406 } 34033407 34043408 /** 34053409 * Make the SEO Score column sortable. 34063410 * 34073411 * @param array $columns Array of column names. 34083412 * 34093413 * @return array 34103414 */ 34113415 public function sortableColumns($columns) 34123416 { 34133417 34143418 $columns[‘metaseo_seokeywords_details_column’] = 'wp_metaseo_seoscore’; 34153419 34163420 return $columns; 34173421 } 34183422 34193423 /** 34203424 * Add content for custom column. 34213425 * 34223426 * @param string $column_name The name of the column to display. 34233427 * @param integer $post_id The current post ID. 34243428 * 34253429 * @return void 34263430 */ 34273431 public function columnsContents($column_name, $post_id) 34283432 { 34293433 do_action($column_name, $post_id); 34303434 } 34313435 34323436 /** 34333437 * Add new columns for SEO title, description and focus keywords. 34343438 * 34353439 * @param array $columns Array of column names. 34363440 * 34373441 * @return array 34383442 */ 34393443 public function addColumns($columns) 34403444 { 34413445 $columns[‘metaseo_seokeywords_details_column’] = esc_html__('SEO score’, ‘wp-meta-seo’); 34423446 34433447 return $columns; 34443448 } 34453449 34463450 /** 34473451 * Get post types that are public and not set to noindex. 34483452 * 34493453 * @codeCoverageIgnore 34503454 * 34513455 * @return array All the accessible post types. 34523456 */ 34533457 public static function getAccessiblePostTypes() 34543458 { 34553459 static $accessible_post_types; 34563460 34573461 if (isset($accessible_post_types) && did_action(‘wp_loaded’)) { 34583462 return $accessible_post_types; 34593463 } 34603464 34613465 $accessible_post_types = get_post_types(array(‘public’ => true)); 34623466 $accessible_post_types = array_filter($accessible_post_types, ‘is_post_type_viewable’); 34633467 34643468 if (!is_array($accessible_post_types)) { 34653469 $accessible_post_types = array(); 34663470 } 34673471 34683472 if (isset($accessible_post_types[‘elementor_library’])) { 34693473 unset($accessible_post_types[‘elementor_library’]); 34703474 } 34713475 34723476 return $accessible_post_types; 34733477 } 34743478 34753479 /** 34763480 * Update post meta keywords 34773481 * 34783482 * @return void 34793483 */ 34803484 public function updateSeokeywordBulkEdit() 34813485 { 34823486 if (empty($_POST[‘wpms_nonce’]) 34833487 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 34843488 die(); 34853489 } 34863490 34873491 if (!isset($_POST[‘listData’]) || empty($_POST[‘listData’])) { 34883492 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 34893493 wp_die(__('Unspecified list data’, ‘wp-meta-seo’)); 34903494 } 34913495 34923496 $result = array(); 34933497 foreach ($_POST[‘listData’] as $data) { 34943498 if (empty($data[‘idpost’])) { 34953499 continue; 34963500 } 34973501 34983502 $circliful = $this->doAnalysisFromBulkEdit((int)$data[‘idpost’], $data[‘keyword’]); 34993503 update_post_meta((int)$data[‘idpost’], '_metaseo_metaspecific_keywords’, $data[‘keyword’]); 35003504 update_post_meta((int)$data[‘idpost’], 'wp_metaseo_seoscore’, $circliful); 35013505 $result[(int)$data[‘idpost’]] = array($circliful, $data[‘keyword’]); 35023506 } 35033507 35043508 wp_send_json(array(‘status’ => true, ‘res_back’ => $result)); 35053509 } 35063510 35073511 /** 35083512 * Ajax load analysis from post edit 35093513 * 35103514 * @param integer $post_id Id post 35113515 * @param string $keywords Keyword search 35123516 * 35133517 * @return mixed 35143518 */ 35153519 public function doAnalysisFromBulkEdit($post_id, $keywords) 35163520 { 35173521 if (empty($_POST[‘wpms_nonce’]) || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 35183522 die(); 35193523 } 35203524 35213525 if (!current_user_can(‘edit_posts’)) { 35223526 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 35233527 wp_die(__('There is no edit permission here’, ‘wp-meta-seo’)); 35243528 } 35253529 35263530 $content_post = get_post($post_id); 35273531 $content = apply_filters('the_content’, $content_post->post_content); 35283532 $title = !(empty($content_post->post_title)) ? $content_post->post_title : null; 35293533 $meta_title = get_post_meta($post_id, '_metaseo_metatitle’, true); 35303534 $meta_desc = get_post_meta($post_id, '_metaseo_metadesc’, true); 35313535 $check = 0; 35323536 35333537 // title heading 35343538 $words_post_title = preg_split( 35353539 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 35363540 strtolower($title), 35373541 -1, 35383542 PREG_SPLIT_NO_EMPTY 35393543 ); 35403544 35413545 // do shortcode js_composer plugin 35423546 if (is_plugin_active(‘js_composer_theme/js_composer.php’)) { 35433547 add_shortcode('mk_fancy_title’, ‘vc_do_shortcode’); 35443548 } 35453549 35463550 $content = apply_filters('wpms_the_content’, ‘<div>’ . html_entity_decode(stripcslashes($content), ENT_COMPAT, ‘UTF-8’) . '</div>’, $post_id); 35473551 $content = $this->injectAcfField($content, $post_id); 35483552 $content = $this->injectWooCommerce($content, $post_id); 35493553 35503554 if ($content !== ‘’) { 35513555 // Extracting the specified elements from the web page 35523556 $tags_h1 = wpmsExtractTags($content, 'h1’, false, true); 35533557 $tags_h2 = wpmsExtractTags($content, 'h2’, false, true); 35543558 $tags_h3 = wpmsExtractTags($content, 'h3’, false, true); 35553559 $tags_h4 = wpmsExtractTags($content, 'h4’, false, true); 35563560 $tags_h5 = wpmsExtractTags($content, 'h5’, false, true); 35573561 $tags_h6 = wpmsExtractTags($content, 'h6’, false, true); 35583562 35593563 $test = false; 35603564 if (empty($tags_h1) && empty($tags_h2) && empty($tags_h3) 35613565 && empty($tags_h4) && empty($tags_h5) && empty($tags_h6)) { 35623566 $test = false; 35633567 } else { 35643568 // check tag h1 35653569 if (!empty($tags_h1)) { 35663570 foreach ($tags_h1 as $order => $tagh1) { 35673571 $words_tagh1 = preg_split( 35683572 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 35693573 utf8_decode(strtolower($tagh1[‘contents’])), 35703574 -1, 35713575 PREG_SPLIT_NO_EMPTY 35723576 ); 35733577 35743578 if (is_array($words_tagh1) && is_array($words_post_title)) { 35753579 foreach ($words_tagh1 as $mh) { 35763580 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 35773581 $test = true; 35783582 } 35793583 } 35803584 } 35813585 } 35823586 } 35833587 35843588 // check tag h2 35853589 if (!empty($tags_h2)) { 35863590 foreach ($tags_h2 as $order => $tagh2) { 35873591 $words_tagh2 = preg_split( 35883592 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 35893593 utf8_decode(strtolower($tagh2[‘contents’])), 35903594 -1, 35913595 PREG_SPLIT_NO_EMPTY 35923596 ); 35933597 if (is_array($words_tagh2) && is_array($words_post_title)) { 35943598 foreach ($words_tagh2 as $mh) { 35953599 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 35963600 $test = true; 35973601 } 35983602 } 35993603 } 36003604 } 36013605 } 36023606 36033607 // check tag h3 36043608 if (!empty($tags_h3)) { 36053609 foreach ($tags_h3 as $order => $tagh3) { 36063610 $words_tagh3 = preg_split( 36073611 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36083612 utf8_decode(strtolower($tagh3[‘contents’])), 36093613 -1, 36103614 PREG_SPLIT_NO_EMPTY 36113615 ); 36123616 if (is_array($words_tagh3) && is_array($words_post_title)) { 36133617 foreach ($words_tagh3 as $mh) { 36143618 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 36153619 $test = true; 36163620 } 36173621 } 36183622 } 36193623 } 36203624 } 36213625 36223626 // check tag h4 36233627 if (!empty($tags_h4)) { 36243628 foreach ($tags_h4 as $order => $tagh4) { 36253629 $words_tagh4 = preg_split( 36263630 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36273631 utf8_decode(strtolower($tagh4[‘contents’])), 36283632 -1, 36293633 PREG_SPLIT_NO_EMPTY 36303634 ); 36313635 if (is_array($words_tagh4) && is_array($words_post_title)) { 36323636 foreach ($words_tagh4 as $mh) { 36333637 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 36343638 $test = true; 36353639 } 36363640 } 36373641 } 36383642 } 36393643 } 36403644 36413645 // check tag h5 36423646 if (!empty($tags_h5)) { 36433647 foreach ($tags_h5 as $order => $tagh5) { 36443648 $words_tagh5 = preg_split( 36453649 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36463650 utf8_decode(strtolower($tagh5[‘contents’])), 36473651 -1, 36483652 PREG_SPLIT_NO_EMPTY 36493653 ); 36503654 if (is_array($words_tagh5) && is_array($words_post_title)) { 36513655 foreach ($words_tagh5 as $mh) { 36523656 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 36533657 $test = true; 36543658 } 36553659 } 36563660 } 36573661 } 36583662 } 36593663 36603664 // check tag h6 36613665 if (!empty($tags_h6)) { 36623666 foreach ($tags_h6 as $order => $tagh6) { 36633667 $words_tagh6 = preg_split( 36643668 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36653669 utf8_decode(strtolower($tagh6[‘contents’])), 36663670 -1, 36673671 PREG_SPLIT_NO_EMPTY 36683672 ); 36693673 if (is_array($words_tagh6) && is_array($words_post_title)) { 36703674 foreach ($words_tagh6 as $mh) { 36713675 if (in_array($mh, $words_post_title) && $mh !== ‘’) { 36723676 $test = true; 36733677 } 36743678 } 36753679 } 36763680 } 36773681 } 36783682 } 36793683 36803684 if ($test) { 36813685 $check++; 36823686 } 36833687 } 36843688 36853689 // title content 36863690 $words_title = preg_split( 36873691 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36883692 strtolower($title), 36893693 -1, 36903694 PREG_SPLIT_NO_EMPTY 36913695 ); 36923696 $words_post_content = preg_split( 36933697 '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/’, 36943698 strtolower(strip_tags($content)), 36953699 -1, 36963700 PREG_SPLIT_NO_EMPTY 36973701 ); 36983702 36993703 $test1 = false; 37003704 if (is_array($words_title) && is_array($words_post_content)) { 37013705 foreach ($words_title as $mtitle) { 37023706 if (in_array($mtitle, $words_post_content) && $mtitle !== ‘’) { 37033707 $test1 = true; 37043708 break; 37053709 } 37063710 } 37073711 } else { 37083712 $test1 = false; 37093713 } 37103714 37113715 if ($test1) { 37123716 $check++; 37133717 } 37143718 37153719 // page url matches page title 37163720 $mtitle = $title; 37173721 $pageurl = pathinfo(get_permalink($post_id)); 37183722 $mpageurl = $pageurl[‘filename’]; 37193723 37203724 if (!empty($mpageurl) && !empty($mtitle) && $mpageurl === sanitize_title($mtitle)) { 37213725 $check++; 37223726 } 37233727 37243728 // meta title filled 37253729 if (($meta_title !== ‘’ && mb_strlen($meta_title, ‘UTF-8’) <= self::$title_length)) { 37263730 $check++; 37273731 } 37283732 37293733 // desc filled 37303734 if ($meta_desc !== ‘’ && mb_strlen($meta_desc, ‘UTF-8’) <= self::$desc_length) { 37313735 $check++; 37323736 } 37333737 37343738 // image resize 37353739 if ($content === ‘’) { 37363740 $check += 2; 37373741 } else { 37383742 // Extracting the specified elements from the web page 37393743 $img_tags = wpmsExtractTags($content, 'img’, true, true); 37403744 $img_wrong = false; 37413745 $img_wrong_alt = false; 37423746 foreach ($img_tags as $order => $tag) { 37433747 if (!isset($tag[‘attributes’][‘src’])) { 37443748 continue; 37453749 } 37463750 37473751 $src = $tag[‘attributes’][‘src’]; 37483752 $imgpath = str_replace(site_url(), ABSPATH, $src); 37493753 if (!file_exists($imgpath)) { 37503754 continue; 37513755 } 37523756 if (!list($width_origin, $height_origin) = getimagesize($imgpath)) { 37533757 continue; 37543758 } 37553759 37563760 if (empty($tag[‘attributes’][‘width’]) && empty($tag[‘attributes’][‘height’])) { 37573761 $img_wrong = false; 37583762 } else { 37593763 if (!empty($width_origin) && !empty($height_origin)) { 37603764 if ((isset($tag[‘attributes’][‘width’]) && (int)$width_origin !== (int)$tag[‘attributes’][‘width’]) 37613765 || (isset($tag[‘attributes’][‘height’]) && (int)$height_origin !== (int)$tag[‘attributes’][‘height’])) { 37623766 $img_wrong = true; 37633767 } 37643768 } 37653769 } 37663770 37673771 if (empty($tag[‘attributes’][‘alt’])) { 37683772 $img_wrong_alt = true; 37693773 } 37703774 } 37713775 37723776 if (!$img_wrong) { 37733777 $check++; 37743778 } 37753779 37763780 37773781 if (!$img_wrong_alt) { 37783782 $check++; 37793783 } 37803784 } 37813785 37823786 $total_check = 7; 37833787 if (!empty($keywords)) { 37843788 $total_check++; 37853789 37863790 $listkeywords = array_map('trim’, explode(',’, strtolower($keywords))); 37873791 37883792 foreach ($listkeywords as $key) { 37893793 if (strpos(strtolower($title), $key) !== false) { 37903794 $check++; 37913795 break; 37923796 } 37933797 37943798 if (strpos(strtolower($content), $key) !== false) { 37953799 $check++; 37963800 break; 37973801 } 37983802 37993803 if (strpos(strtolower($meta_title), $key) !== false) { 38003804 $check++; 38013805 break; 38023806 } 38033807 38043808 if (strpos(strtolower($meta_desc), $key) !== false) { 38053809 $check++; 38063810 break; 38073811 } 38083812 38093813 $pattern = ‘/<h[2-6][^>]*>.*’ . $key . '.*<\/h[2-6]>/’; 38103814 if (preg_match($pattern, $content)) { 38113815 $check++; 38123816 break; 38133817 } 38143818 } 38153819 } 38163820 38173821 $circliful = ceil(100 * ($check) / $total_check); 38183822 38193823 return $circliful; 38203824 } 38213825 38223826 /** 38233827 * Localize a script. 38243828 * 38253829 * Works only if the script has already been added. 38263830 * 38273831 * @return array 38283832 */ 38293833 public function localizeScript() 38303834 { 38313835 return array( 38323836 ‘metaseo_message_false_copy’ => esc_html__('Warning, you\’re about to replace existing image 38333837 alt or tile content, are you sire about that?’, ‘wp-meta-seo’), 38343838 ); 38353839 } 38363840 38373841 /** 38383842 * Add a top-level menu page. 38393843 * 38403844 * This function takes a capability which will be used to determine whether 38413845 * or not a page is included in the menu. 38423846 * 38433847 * @return void 38443848 */ 38453849 public function addMenuPage() 38463850 { 38473851 // Add main page 38483852 add_menu_page( 38493853 esc_html__('WP Meta SEO: Dashboard’, ‘wp-meta-seo’), 38503854 esc_html__('WP Meta SEO’, ‘wp-meta-seo’), 38513855 'manage_options’, 38523856 'metaseo_dashboard’, 38533857 array( 38543858 $this, 38553859 ‘loadPage’ 38563860 ), 38573861 ‘dashicons-chart-area’ 38583862 ); 38593863 38603864 /** 38613865 * Allow changing the capability users need to view the settings pages 38623866 * 38633867 * @return string 38643868 * @api string Default capability 38653869 */ 38663870 $manage_options_cap = apply_filters('metaseo_manage_options_capability’, ‘manage_options’); 38673871 38683872 // Sub menu pages 38693873 $submenu_pages = array( 38703874 array( 38713875 'metaseo_dashboard’, 38723876 '’, 38733877 esc_html__('Dashboard’, ‘wp-meta-seo’), 38743878 $manage_options_cap, 38753879 'metaseo_dashboard’, 38763880 array($this, ‘loadPage’), 38773881 null 38783882 ), 38793883 array( 38803884 'metaseo_dashboard’, 38813885 '’, 38823886 esc_html__('Content meta’, ‘wp-meta-seo’), 38833887 $manage_options_cap, 38843888 'metaseo_content_meta’, 38853889 array($this, ‘loadPage’), 38863890 null 38873891 ), 38883892 array( 38893893 'metaseo_dashboard’, 38903894 '’, 38913895 esc_html__('Category meta’, ‘wp-meta-seo’), 38923896 $manage_options_cap, 38933897 'metaseo_category_meta’, 38943898 array($this, ‘loadPage’), 38953899 null 38963900 ), 38973901 array( 38983902 'metaseo_dashboard’, 38993903 '’, 39003904 esc_html__('Image editor’, ‘wp-meta-seo’), 39013905 $manage_options_cap, 39023906 'metaseo_image_meta’, 39033907 array($this, ‘loadPage’), 39043908 null 39053909 ), 39063910 array( 39073911 'metaseo_dashboard’, 39083912 '’, 39093913 esc_html__('Sitemap’, ‘wp-meta-seo’), 39103914 $manage_options_cap, 39113915 'metaseo_google_sitemap’, 39123916 array($this, ‘loadPage’), 39133917 null, 39143918 ), 39153919 array( 39163920 'metaseo_dashboard’, 39173921 '’, 39183922 esc_html__('Link editor’, ‘wp-meta-seo’), 39193923 $manage_options_cap, 39203924 'metaseo_link_meta’, 39213925 array($this, ‘loadPage’), 39223926 null 39233927 ), 39243928 array( 39253929 'metaseo_dashboard’, 39263930 '’, 39273931 esc_html__('404 & Redirects’, ‘wp-meta-seo’), 39283932 $manage_options_cap, 39293933 'metaseo_broken_link’, 39303934 array($this, ‘loadPage’), 39313935 null 39323936 ), 39333937 array( 39343938 'metaseo_dashboard’, 39353939 '’, 39363940 esc_html__('Google Analytics’, ‘wp-meta-seo’), 39373941 $manage_options_cap, 39383942 'metaseo_google_analytics’, 39393943 array($this, ‘loadPage’), 39403944 null 39413945 ) 39423946 ); 39433947 39443948 if (is_plugin_active(WPMSEO_ADDON_FILENAME)) { 39453949 global $metaseo_addon; 39463950 $submenu_pages[] = array( 39473951 'metaseo_dashboard’, 39483952 esc_html__('WP Meta SEO Send email’, ‘wp-meta-seo’), 39493953 esc_html__('Email report’, ‘wp-meta-seo’), 39503954 $manage_options_cap, 39513955 'metaseo_sendemail’, 39523956 array($metaseo_addon, ‘loadPageSendEmail’), 39533957 null 39543958 ); 39553959 39563960 // REMOVE SEARCH CONSOLE TAB, WAIT NEW API FROM GOOGLE GUYS 39573961 // 39583962 // 39593963 // 39603964// $submenu_pages[] = array( 39613965// 'metaseo_dashboard’, 39623966// esc_html__('Search Console’, ‘wp-meta-seo’), 39633967// esc_html__('Search Console’, ‘wp-meta-seo’), 39643968// $manage_options_cap, 39653969// 'metaseo_console’, 39663970// array($metaseo_addon->admin_features[‘metaseo_gsc’], ‘display’), 39673971// null 39683972// ); 39693973 } 39703974 39713975 $submenu_pages[] = array( 39723976 'metaseo_dashboard’, 39733977 '’, 39743978 esc_html__('Settings’, ‘wp-meta-seo’), 39753979 $manage_options_cap, 39763980 'metaseo_settings’, 39773981 array($this, ‘loadPage’), 39783982 null 39793983 ); 39803984 39813985 if (!is_plugin_active(WPMSEO_ADDON_FILENAME)) { 39823986 $submenu_pages[] = array( 39833987 'metaseo_dashboard’, 39843988 '’, 39853989 ‘<span style="color:orange">’ . esc_html__('Better SEO ranking’, ‘wp-meta-seo’) . '</span>’, 39863990 $manage_options_cap, 39873991 'metaseo_better_ranking’, 39883992 array($this, ‘loadPage’), 39893993 null 39903994 ); 39913995 } 39923996 39933997 // Allow submenu pages manipulation 39943998 $submenu_pages = apply_filters('metaseo_submenu_pages’, $submenu_pages); 39953999 39964000 // Loop through submenu pages and add them 39974001 if (count($submenu_pages)) { 39984002 foreach ($submenu_pages as $submenu_page) { 39994003 // Add submenu page 40004004 $admin_page = add_submenu_page( 40014005 $submenu_page[0], 40024006 $submenu_page[2] . ' - ' . esc_html__('WP Meta SEO:’, ‘wp-meta-seo’), 40034007 $submenu_page[2], 40044008 $submenu_page[3], 40054009 $submenu_page[4], 40064010 $submenu_page[5] 40074011 ); 40084012 40094013 // Check if we need to hook 40104014 if (isset($submenu_page[6]) && null !== $submenu_page[6] 40114015 && is_array($submenu_page[6]) && count($submenu_page[6]) > 0) { 40124016 foreach ($submenu_page[6] as $submenu_page_action) { 40134017 add_action('load-' . $admin_page, $submenu_page_action); 40144018 } 40154019 } 40164020 } 40174021 } 40184022 } 40194023 40204024 /** 40214025 * Set error time out 40224026 * 40234027 * @return void 40244028 */ 40254029 public function setErrorTimeout() 40264030 { 40274031 $midnight = strtotime(‘tomorrow 00:00:00’); // UTC midnight 40284032 $midnight = $midnight + 8 * 3600; // UTC 8 AM 40294033 $this->error_timeout = $midnight - time(); 40304034 } 40314035 40324036 /** 40334037 * Load the form for a WPSEO admin page 40344038 * 40354039 * @return void 40364040 */ 40374041 public function loadPage() 40384042 { 40394043 if (isset($_GET[‘page’])) { 40404044 // phpcs:ignore WordPress.Security.NonceVerification.Recommended – No action, nonce is not required 40414045 switch ($_GET[‘page’]) { 40424046 case 'metaseo_google_analytics’: 40434047 $this->google_alanytics = get_option(‘wpms_google_alanytics’); 40444048 if (isset($this->google_alanytics[‘setting_success’]) && $this->google_alanytics[‘setting_success’] === 1) { 40454049 echo ‘<div id="setting-error-settings_updated" 40464050 class="updated settings-error notice is-dismissible"> 40474051<p><strong>’ . esc_html__('Settings saved.’, ‘wp-meta-seo’) . '</strong></p><button type="button" class="notice-dismiss"> 40484052<span class="screen-reader-text">Dismiss this notice.</span></button></div>’; 40494053 $this->google_alanytics[‘setting_success’] = 0; 40504054 update_option('wpms_google_alanytics’, $this->google_alanytics); 40514055 } 40524056 if (isset($_POST[‘_metaseo_ggtracking_settings’])) { 40534057 if (empty($_POST[‘gadash_security’]) 40544058 || !wp_verify_nonce($_POST[‘gadash_security’], ‘gadash_form’)) { 40554059 die(); 40564060 } 40574061 update_option('_metaseo_ggtracking_settings’, $_POST[‘_metaseo_ggtracking_settings’]); 40584062 echo ‘<div id="setting-error-settings_updated" 40594063 class="updated settings-error notice is-dismissible"> 40604064<p><strong>’ . esc_html__('Settings saved.’, ‘wp-meta-seo’) . '</strong></p><button type="button" class="notice-dismiss"> 40614065<span class="screen-reader-text">Dismiss this notice.</span></button></div>’; 40624066 } 40634067 40644068 // Update selected profile 40654069 if (!empty($_POST[‘tableid_jail’])) { 40664070 if (empty($_POST[‘wpms_nonce’]) 40674071 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 40684072 die(); 40694073 } 40704074 if ($this->google_alanytics[‘tableid_jail’] !== $_POST[‘tableid_jail’]) { 40714075 $this->google_alanytics[‘tableid_jail’] = $_POST[‘tableid_jail’]; 40724076 $this->google_alanytics[‘setting_success’] = 1; 40734077 update_option('wpms_google_alanytics’, $this->google_alanytics); 40744078 wp_redirect($_SERVER[‘HTTP_REFERER’]); 40754079 } 40764080 } 40774081 40784082 $ga_tracking = get_option(‘_metaseo_ggtracking_settings’); 40794083 if (is_array($ga_tracking)) { 40804084 $this->ga_tracking = array_merge($this->ga_tracking, $ga_tracking); 40814085 } 40824086 include_once(WPMETASEO_PLUGIN_DIR . ‘inc/google_analytics/wpmstools.php’); 40834087 include_once(WPMETASEO_PLUGIN_DIR . ‘inc/google_analytics/wpmsgapi.php’); 40844088 wp_enqueue_style(‘wpms-tippy-style’); 40854089 wp_enqueue_script(‘wpms-tippy-core’); 40864090 wp_enqueue_script(‘wpms-tippy’); 40874091 // Enqueue snackbar 40884092 wp_enqueue_style(‘wpms-snackbar-style’); 40894093 wp_enqueue_script(‘wpms-snackbar-script’); 40904094 40914095 // WPMS Google Analytics Data 40924096 if (isset($_GET[‘view’]) && $_GET[‘view’] === ‘wpms_gg_service_data’) { 40934097 wp_enqueue_style(‘wpms-backend-tracking-code’); 40944098 wp_enqueue_style(‘wpms-backend-item-reports’); 40954099 40964100 // When user save access code 40974101 if (isset($_POST[‘wpmsga_dash_clientid’]) && isset($_POST[‘wpmsga_dash_clientsecret’])) { 40984102 // Check nonce field 40994103 if (empty($_POST[‘wpms_nonce’]) 41004104 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 41014105 die(); 41024106 } 41034107 $this->google_alanytics[‘wpmsga_dash_clientid’] = $_POST[‘wpmsga_dash_clientid’]; 41044108 $this->google_alanytics[‘wpmsga_dash_clientsecret’] = $_POST[‘wpmsga_dash_clientsecret’]; 41054109 update_option('wpms_google_alanytics’, $this->google_alanytics); 41064110 } 41074111 41084112 require_once WPMETASEO_PLUGIN_DIR . 'inc/google_analytics/wpmstools.php’; 41094113 if (!empty($this->google_alanytics[‘wpmsga_dash_clientid’]) && !empty($this->google_alanytics[‘wpmsga_dash_clientsecret’])) { 41104114 $this->client = WpmsGaTools::initClient($this->google_alanytics[‘wpmsga_dash_clientid’], $this->google_alanytics[‘wpmsga_dash_clientsecret’]); 41114115 $controller = new WpmsGapiController(); 41124116 $this->service = new \WPMSGoogle\Service\Analytics($this->client); 41134117 } 41144118 41154119 $this->setErrorTimeout(); 41164120 41174121 if (!empty($_POST[‘wpms_gg_access_code’])) { 41184122 $wpms_gg_access_code = $_POST[‘wpms_gg_access_code’]; 41194123 if (!stripos(‘x’ . $wpms_gg_access_code, 'UA-', 1)) { 41204124 WpmsGaTools::deleteCache(‘gapi_errors’); 41214125 WpmsGaTools::deleteCache(‘last_error’); 41224126 WpmsGaTools::clearCache(); 41234127 try { 41244128 $this->client->authenticate($wpms_gg_access_code); 41254129 $getAccessToken = $this->client->getAccessToken(); 41264130 if ($getAccessToken) { 41274131 try { 41284132 $this->client->setAccessToken($getAccessToken); 41294133 $this->google_alanytics[‘googleCredentials’] 41304134 = $this->client->getAccessToken(); 41314135 } catch (WPMSGoogle\Service\Exception $e) { 41324136 WpmsGaTools::setCache( 41334137 'wpmsga_dash_lasterror’, 41344138 date(‘Y-m-d H:i:s’) . ': ' . esc_html('(' . $e->getCode() . ') ' . $e->getMessage()), 41354139 $this->error_timeout 41364140 ); 41374141 WpmsGaTools::setCache( 41384142 'wpmsga_dash_gapi_errors’, 41394143 $e->getCode(), 41404144 $this->error_timeout 41414145 ); 41424146 } catch (Exception $e) { 41434147 WpmsGaTools::setCache( 41444148 'wpmsga_dash_lasterror’, 41454149 date(‘Y-m-d H:i:s’) . ': ' . esc_html($e), 41464150 $this->error_timeout 41474151 ); 41484152 } 41494153 } 41504154 41514155 if (!empty($this->google_alanytics[‘profile_list’])) { 41524156 $profiles = $this->google_alanytics[‘profile_list’]; 41534157 } else { 41544158 $profiles = WpmsGaTools::refreshProfiles($this->service, $getAccessToken[‘access_token’], $this->error_timeout); 41554159 } 41564160 41574161 $this->google_alanytics[‘code’] = $wpms_gg_access_code; 41584162 $this->google_alanytics[‘googleCredentials’] = $getAccessToken; 41594163 $this->google_alanytics[‘profile_list’] = $profiles; 41604164 update_option('wpms_google_alanytics’, $this->google_alanytics); 41614165 } catch (WPMSGoogle\Service\Exception $e) { 41624166 echo '’; 41634167 } catch (Exception $e) { 41644168 echo '’; 41654169 } 41664170 } else { 41674171 echo ‘<div class="error"><p>’ . esc_html__('The access code is 41684172<strong>NOT</strong> your <strong>Tracking ID</strong> 41694173 (UA-XXXXX-X). Try again, and use the red link to get your access code’, ‘wp-meta-seo’) . '.</p></div>’; 41704174 } 41714175 update_option('wpms_google_alanytics’, $this->google_alanytics); 41724176 wp_redirect($_SERVER[‘HTTP_REFERER’]); 41734177 exit; 41744178 } 41754179 $gg_analytcis = get_option(‘wpms_google_alanytics’); 41764180 if (is_array($gg_analytcis)) { 41774181 $this->google_alanytics = array_merge($gg_analytcis, $this->google_alanytics); 41784182 } 41794183 // If user have google credentials 41804184 if (!empty($this->google_alanytics[‘googleCredentials’])) { 41814185 // WPMS google analytics setting 41824186 include_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/google-services/ga-trackcode.php’); 41834187 // Google analytics data 41844188 if (!empty($this->google_alanytics[‘tableid_jail’])) { 41854189 echo ‘<h1 class="wpms-top-h1">’ . esc_html__(‘Google Analytics Report’, ‘wp-meta-seo’) . ' 41864190 <i class="material-icons intro-topic-tooltip" data-tippy="’ . esc_html__('Create a Google Analytics property then connect WordPress to this Analytics property. You can then follow your traffic and include the data in your Email report (Pro Addon)', ‘wp-meta-seo’) . '">help_outline</i> 41874191 </h1>’; 41884192 echo '<div id="wpms-window-1"> 41894193 <!-- WPMS Google analytics response using JS --> 41904194 41914195 </div>’; 41924196 } 41934197 } else { 41944198 include_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/google-services/gg-services-connect.php’); 41954199 } 41964200 } else { 41974201 // WPMS Google Service Tracking - when user don’t have Google cloud credentials 41984202 $gaDisconnect = get_option(‘_metaseo_ggtracking_disconnect_settings’); 41994203 if (is_array($gaDisconnect)) { 42004204 $this->gaDisconnect = array_merge( 42014205 $this->gaDisconnect, 42024206 $gaDisconnect 42034207 ); 42044208 } 42054209 42064210 // When user submit tracking options 42074211 if (isset($_POST[‘_metaseo_gg_service_disconnect’])) { 42084212 // Check none field 42094213 if (empty($_POST[‘wpms_nonce’]) 42104214 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 42114215 die(); 42124216 } 42134217 // Sanitizing submit data and save options 42144218 $_metaseo_ga_disconnect = $_POST[‘_metaseo_gg_service_disconnect’]; 42154219 $_metaseo_ga_disconnect[‘wpms_gg_service_tracking_id’] = sanitize_text_field($_metaseo_ga_disconnect[‘wpms_gg_service_tracking_id’]); 42164220 $_metaseo_ga_disconnect[‘wpms_gg_service_tracking_type’] = sanitize_text_field($_metaseo_ga_disconnect[‘wpms_gg_service_tracking_type’]); 42174221 $_metaseo_ga_disconnect[‘wpmsga_code_tracking’] = stripslashes($_metaseo_ga_disconnect[‘wpmsga_code_tracking’]); 42184222 $_metaseo_ga_disconnect[‘wpmstm_header_code_tracking’] = stripslashes($_metaseo_ga_disconnect[‘wpmstm_header_code_tracking’]); 42194223 $_metaseo_ga_disconnect[‘wpmstm_body_code_tracking’] = stripslashes($_metaseo_ga_disconnect[‘wpmstm_body_code_tracking’]); 42204224 update_option( 42214225 '_metaseo_ggtracking_disconnect_settings’, 42224226 $_metaseo_ga_disconnect 42234227 ); 42244228 $gaDisconnect = get_option(‘_metaseo_ggtracking_disconnect_settings’); 42254229 if (is_array($gaDisconnect)) { 42264230 $this->gaDisconnect = array_merge( 42274231 $this->gaDisconnect, 42284232 $gaDisconnect 42294233 ); 42304234 } 42314235 } 42324236 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/google-services/google-services.php’); 42334237 } 42344238 42354239 $w = '99%’; 42364240 $text = esc_html__('Bring your WordPress website SEO to the next level with the PRO Addon: Email Report, 42374241 Google Search Console Connect, Automatic Redirect, Advanced Sitemaps and more!’, ‘wp-meta-seo’); 42384242 $class_btn_close = 'close_gga’; 42394243 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/notification.php’); 42404244 break; 42414245 case 'metaseo_google_sitemap’: 42424246 if (is_plugin_active(WPMSEO_ADDON_FILENAME)) { 42434247 // remove filter by lang 42444248 if (is_plugin_active(‘sitepress-multilingual-cms/sitepress.php’)) { 42454249 global $sitepress; 42464250 remove_filter('terms_clauses’, array($sitepress, ‘terms_clauses’)); 42474251 } elseif (is_plugin_active(‘polylang/polylang.php’)) { 42484252 global $polylang; 42494253 $filters_term = $polylang->filters_term; 42504254 remove_filter('terms_clauses’, array($filters_term, ‘terms_clauses’)); 42514255 } 42524256 } 42534257 42544258 if (!class_exists(‘MetaSeoSitemap’)) { 42554259 require_once(WPMETASEO_PLUGIN_DIR . ‘/inc/class.metaseo-sitemap.php’); 42564260 } 42574261 42584262 $sitemap = new MetaSeoSitemap(); 42594263 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/sitemaps/metaseo-google-sitemap.php’); 42604264 break; 42614265 case 'metaseo_broken_link’: 42624266 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/metaseo-broken-link.php’); 42634267 break; 42644268 case 'metaseo_settings’: 42654269 if (isset($_POST[‘_metaseo_settings’])) { 42664270 if (empty($_POST[‘wpms_nonce’]) 42674271 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 42684272 die(); 42694273 } 42704274 update_option('_metaseo_settings’, $_POST[‘_metaseo_settings’]); 42714275 if (isset($_POST[‘_metaseo_settings’][‘wpms_save_general’])) { 42724276 $_SESSION[‘_metaseo_settings_general’] = 1; 42734277 } 42744278 if (isset($_POST[‘_metaseo_settings’][‘wpms_save_social’])) { 42754279 $_SESSION[‘_metaseo_settings_social’] = 1; 42764280 } 42774281 if (isset($_POST[‘gscapi’][‘save’])) { 42784282 $_SESSION[‘_metaseo_settings_search_console’] = 1; 42794283 } 42804284 } 42814285 42824286 $posts = get_posts(array(‘post_type’ => 'page’, ‘posts_per_page’ => -1, ‘numberposts’ => -1)); 42834287 $types_404 = array( 42844288 ‘none’ => 'None’, 42854289 ‘wp-meta-seo-page’ => esc_html__('WP Meta SEO page’, ‘wp-meta-seo’), 42864290 ‘custom_page’ => esc_html__('Custom page’, ‘wp-meta-seo’) 42874291 ); 42884292 42894293 // get settings 404 42904294 $defaul_settings_404 = array( 42914295 ‘wpms_redirect_homepage’ => 0, 42924296 ‘wpms_type_404’ => 'none’, 42934297 ‘wpms_page_redirected’ => ‘none’ 42944298 ); 42954299 $wpms_settings_404 = get_option(‘wpms_settings_404’); 42964300 if (is_array($wpms_settings_404)) { 42974301 $defaul_settings_404 = array_merge($defaul_settings_404, $wpms_settings_404); 42984302 } 42994303 43004304 // get settings breadcrumb 43014305 $home_title = get_the_title(get_option(‘page_on_front’)); 43024306 if (empty($home_title)) { 43034307 $home_title = get_bloginfo(‘title’); 43044308 } 43054309 $breadcrumbs = array( 43064310 ‘separator’ => ' > ', 43074311 ‘include_home’ => 1, 43084312 ‘home_text’ => $home_title, 43094313 ‘home_text_default’ => 0, 43104314 ‘clickable’ => 1 43114315 ); 43124316 $breadcrumb_settings = get_option(‘_metaseo_breadcrumbs’); 43134317 if (is_array($breadcrumb_settings)) { 43144318 $breadcrumbs = array_merge($breadcrumbs, $breadcrumb_settings); 43154319 } 43164320 43174321 // email settings 43184322 $email_settings = array( 43194323 ‘enable’ => 0, 43204324 ‘host’ => 'smtp.gmail.com’, 43214325 ‘type_encryption’ => 'ssl’, 43224326 ‘port’ => '465’, 43234327 ‘autentication’ => 'yes’, 43244328 ‘username’ => '’, 43254329 ‘password’ => '’, 43264330 ); 43274331 43284332 $mailsettings = get_option(‘wpms_email_settings’); 43294333 if (is_array($mailsettings)) { 43304334 $email_settings = array_merge($email_settings, $mailsettings); 43314335 } 43324336 43334337 $html_tabemail = apply_filters('wpmsaddon_emailsettings’, '’, $email_settings); 43344338 43354339 // link settings 43364340 $link_settings = array( 43374341 ‘enable’ => 0, 43384342 ‘numberFrequency’ => 1, 43394343 ‘showlinkFrequency’ => ‘month’ 43404344 ); 43414345 43424346 $linksettings = get_option(‘wpms_link_settings’); 43434347 if (is_array($linksettings)) { 43444348 $link_settings = array_merge($link_settings, $linksettings); 43454349 } 43464350 43474351 $link_settings_html = apply_filters('wpmsaddon_linksettings’, '’, $link_settings); 43484352 43494353 // local business settings 43504354 $local_business = array( 43514355 ‘enable’ => 0, 43524356 ‘logo’ => '’, 43534357 ‘type_name’ => '’, 43544358 ‘country’ => '’, 43554359 ‘address’ => '’, 43564360 ‘city’ => '’, 43574361 ‘state’ => '’, 43584362 ‘phone’ => '’, 43594363 ‘pricerange’ => ‘$$’ 43604364 ); 43614365 43624366 $business = get_option(‘wpms_local_business’); 43634367 if (is_array($business)) { 43644368 $local_business = array_merge($local_business, $business); 43654369 } 43664370 $countrys = apply_filters('wpms_get_countryList’, array()); 43674371 $local_business_html = apply_filters('wpmsaddon_local_business’, '’, $local_business, $countrys); 43684372 43694373 $search_console_html = apply_filters('wpmsaddon_search_console’, ‘’); 43704374 43714375 $default_settings = wpmsGetDefaultSettings(); 43724376 $settings = get_option(‘_metaseo_settings’); 43734377 if (is_array($settings)) { 43744378 $settings = array_merge($default_settings, $settings); 43754379 } else { 43764380 $settings = $default_settings; 43774381 } 43784382 43794383 foreach ($settings as $setting_name => $setting_value) { 43804384 ${$setting_name} = $setting_value; 43814385 } 43824386 43834387 $home_meta_active = wpmsGetOption(‘home_meta_active’); 43844388 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/settings.php’); 43854389 break; 43864390 43874391 case 'metaseo_content_meta’: 43884392 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/content-meta.php’); 43894393 break; 43904394 43914395 case 'metaseo_category_meta’: 43924396 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/category-meta.php’); 43934397 break; 43944398 43954399 case 'metaseo_image_meta’: 43964400 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/image-meta.php’); 43974401 break; 43984402 43994403 case 'metaseo_link_meta’: 44004404 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/link-meta.php’); 44014405 break; 44024406 44034407 case 'metaseo_image_optimize’: 44044408 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/image-optimize.php’); 44054409 break; 44064410 44074411 case 'metaseo_better_ranking’: 44084412 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/better_seo.php’); 44094413 break; 44104414 case 'metaseo_dashboard’: 44114415 default: 44124416 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/pages/dashboard.php’); 44134417 break; 44144418 } 44154419 } 44164420 } 44174421 44184422 /** 44194423 * Ajax check attachment have alt empty 44204424 * 44214425 * @return void 44224426 */ 44234427 public function checkExist() 44244428 { 44254429 if (empty($_POST[‘wpms_nonce’]) 44264430 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 44274431 die(); 44284432 } 44294433 44304434 if (isset($_POST[‘action_name’])) { 44314435 switch ($_POST[‘action_name’]) { 44324436 case 'img-copy-alt’: 44334437 $margs = array( 44344438 ‘posts_per_page’ => -1, 44354439 ‘post_type’ => 'attachment’, 44364440 ‘post_status’ => 'any’, 44374441 ‘meta_query’ => array( 44384442 ‘relation’ => 'OR’, 44394443 array( 44404444 ‘key’ => '_wp_attachment_image_alt’, 44414445 ‘value’ => '’, 44424446 ‘compare’ => ‘!=’ 44434447 ) 44444448 ) 44454449 ); 44464450 44474451 $m_newquery = new WP_Query($margs); 44484452 $mposts_empty_alt = $m_newquery->get_posts(); 44494453 if (!empty($mposts_empty_alt)) { 44504454 wp_send_json(true); 44514455 } else { 44524456 wp_send_json(false); 44534457 } 44544458 break; 44554459 44564460 case 'img-copy-title’: 44574461 global $wpdb; 44584462 $check_title = $wpdb->get_var('SELECT COUNT(posts.ID) as total FROM ' . $wpdb->prefix . ‘posts as posts 44594463 WHERE posts.post_type = “attachment” AND post_title != ""’); 44604464 if ($check_title > 0) { 44614465 wp_send_json(true); 44624466 } else { 44634467 wp_send_json(false); 44644468 } 44654469 break; 44664470 case 'img-copy-desc’: 44674471 global $wpdb; 44684472 $check_title = $wpdb->get_var('SELECT COUNT(posts.ID) as total FROM ' . $wpdb->prefix . ‘posts as posts 44694473 WHERE posts.post_type = “attachment” AND post_content != ""’); 44704474 if ($check_title > 0) { 44714475 wp_send_json(true); 44724476 } else { 44734477 wp_send_json(false); 44744478 } 44754479 break; 44764480 } 44774481 } 44784482 } 44794483 44804484 /** 44814485 * Ajax update image alt and image title 44824486 * 44834487 * @return void 44844488 */ 44854489 public function bulkImageCopy() 44864490 { 44874491 if (empty($_POST[‘wpms_nonce’]) 44884492 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 44894493 die(); 44904494 } 44914495 44924496 global $wpdb; 44934497 if (empty($_POST[‘action_name’])) { 44944498 wp_send_json(false); 44954499 } 44964500 44974501 if (isset($_POST[‘sl_bulk’]) && $_POST[‘sl_bulk’] === ‘all’) { 44984502 // select all 44994503 $limit = 500; 45004504 // query attachment and update meta 45014505 $total = $wpdb->get_var('SELECT COUNT(posts.ID) as total FROM ' . $wpdb->prefix . ‘posts as posts 45024506 WHERE posts.post_type = "attachment"’); 45034507 45044508 $j = ceil((int)$total / $limit); 45054509 for ($i = 0; $i <= $j; $i++) { 45064510 $ofset = $i * $limit; 45074511 $attachments = $wpdb->get_results($wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . 'posts as posts 45084512 WHERE posts.post_type = %s LIMIT %d OFFSET %d’, array('attachment’, $limit, $ofset))); 45094513 45104514 foreach ($attachments as $attachment) { 45114515 $i_info_url = pathinfo($attachment->guid); 45124516 switch ($_POST[‘action_name’]) { 45134517 case 'img-copy-alt’: 45144518 $value = $i_info_url[‘filename’]; 45154519 /** 45164520 * Filter before update meta for image 45174521 * 45184522 * @param string Meta value 45194523 * @param integer Image ID 45204524 * @param string Meta key 45214525 * @param array Extra informations 45224526 * 45234527 * @return string 45244528 */ 45254529 $value = apply_filters('wpms_update_image_meta’, $value, $attachment->ID, '_wp_attachment_image_alt’, array(‘source’ => ‘bulk_copy_alt’)); 45264530 update_post_meta($attachment->ID, '_wp_attachment_image_alt’, $value); 45274531 break; 45284532 45294533 case 'img-copy-title’: 45304534 $value = $i_info_url[‘filename’]; 45314535 /** 45324536 * Filter before update meta for image 45334537 * 45344538 * @param string Meta value 45354539 * @param integer Image ID 45364540 * @param string Post title field name 45374541 * @param array Extra informations 45384542 * 45394543 * @return string 45404544 * 45414545 * @ignore Hook already documented 45424546 */ 45434547 $value = apply_filters('wpms_update_image_meta’, $value, $attachment->ID, 'post_title’, array(‘source’ => ‘bulk_copy_title’)); 45444548 wp_update_post(array(‘ID’ => $attachment->ID, ‘post_title’ => $value)); 45454549 break; 45464550 case 'img-copy-desc’: 45474551 wp_update_post(array(‘ID’ => $attachment->ID, ‘post_content’ => $i_info_url[‘filename’])); 45484552 break; 45494553 } 45504554 } 45514555 } 45524556 45534557 wp_send_json(true); 45544558 } else { 45554559 // selected 45564560 if (isset($_POST[‘ids’])) { 45574561 $ids = (array)$_POST[‘ids’]; 45584562 $ids = array_map('absint’, $ids); 45594563 switch ($_POST[‘action_name’]) { 45604564 case 'img-copy-alt’: 45614565 $margs = array( 45624566 ‘posts_per_page’ => -1, 45634567 ‘post_type’ => 'attachment’, 45644568 ‘post_status’ => 'any’, 45654569 ‘post__in’ => $ids 45664570 ); 45674571 45684572 $m_newquery = new WP_Query($margs); 45694573 $mposts_empty_alt = $m_newquery->get_posts(); 45704574 if (!empty($mposts_empty_alt)) { 45714575 foreach ($mposts_empty_alt as $post) { 45724576 $i_info_url = pathinfo($post->guid); 45734577 $value = $i_info_url[‘filename’]; 45744578 /** 45754579 * Filter before update meta for image 45764580 * 45774581 * @param string Meta value 45784582 * @param integer Image ID 45794583 * @param string Meta key 45804584 * @param array Extra informations 45814585 * 45824586 * @return string 45834587 * 45844588 * @ignore Hook already documented 45854589 */ 45864590 $value = apply_filters('wpms_update_image_meta’, $value, $post->ID, '_wp_attachment_image_alt’, array(‘source’ => ‘bulk_copy_alt’)); 45874591 update_post_meta($post->ID, '_wp_attachment_image_alt’, $value); 45884592 } 45894593 } else { 45904594 wp_send_json(false); 45914595 } 45924596 break; 45934597 45944598 case 'img-copy-title’: 45954599 $posts_result = $wpdb->get_results($wpdb->prepare('SELECT * 45964600 FROM ' . $wpdb->posts . ' WHERE post_type = %s 45974601 AND post_mime_type LIKE %s AND ID IN (' . implode(',’, esc_sql($ids)) . ') 45984602 ', array('attachment’, ‘%image%’))); 45994603 46004604 if (!empty($posts_result)) { 46014605 foreach ($posts_result as $post) { 46024606 $i_info_url = pathinfo($post->guid); 46034607 $value = $i_info_url[‘filename’]; 46044608 /** 46054609 * Filter before update meta for image 46064610 * 46074611 * @param string Meta value 46084612 * @param integer Image ID 46094613 * @param string Post title field name 46104614 * @param array Extra informations 46114615 * 46124616 * @return string 46134617 * 46144618 * @ignore Hook already documented 46154619 */ 46164620 $value = apply_filters('wpms_update_image_meta’, $value, $post->ID, 'post_title’, array(‘source’ => ‘bulk_copy_title’)); 46174621 wp_update_post(array(‘ID’ => $post->ID, ‘post_title’ => $value)); 46184622 } 46194623 } else { 46204624 wp_send_json(false); 46214625 } 46224626 break; 46234627 case 'img-copy-desc’: 46244628 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared – Variable has been prepare 46254629 $sql = $wpdb->prepare('SELECT * FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_mime_type LIKE %s AND ID IN ('.implode(‘,’, $ids).’)', array('attachment’, ‘%image%’ )); 46264630 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared – Variable has been prepare 46274631 $posts_result = $wpdb->get_results($sql); 46284632 if (!empty($posts_result)) { 46294633 foreach ($posts_result as $post) { 46304634 $i_info_url = pathinfo($post->guid); 46314635 wp_update_post(array(‘ID’ => $post->ID, ‘post_content’ => $i_info_url[‘filename’])); 46324636 } 46334637 } else { 46344638 wp_send_json(false); 46354639 } 46364640 break; 46374641 } 46384642 wp_send_json(true); 46394643 } else { 46404644 wp_send_json(false); 46414645 } 46424646 } 46434647 } 46444648 46454649 /** 46464650 * Ajax bulk update meta title for a post/page 46474651 * 46484652 * @return void 46494653 */ 46504654 public function bulkPostCopy() 46514655 { 46524656 if (empty($_POST[‘wpms_nonce’]) 46534657 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 46544658 die(); 46554659 } 46564660 46574661 $post_types = get_post_types(array(‘public’ => true, ‘exclude_from_search’ => false)); 46584662 unset($post_types[‘attachment’]); 46594663 $margs = array(); 46604664 46614665 switch ($_POST[‘action_name’]) { 46624666 case 'post-copy-title’: 46634667 $key = '_metaseo_metatitle’; 46644668 break; 46654669 case 'post-copy-desc’: 46664670 $key = '_metaseo_metadesc’; 46674671 break; 46684672 } 46694673 46704674 if (isset($_POST[‘sl_bulk’]) && $_POST[‘sl_bulk’] === ‘all’) { // for select a;; 46714675 $margs = array( 46724676 ‘posts_per_page’ => -1, 46734677 ‘post_type’ => $post_types, 46744678 ‘post_status’ => ‘any’ 46754679 ); 46764680 } else { // for select some post 46774681 if (isset($_POST[‘ids’])) { 46784682 $ids = $_POST[‘ids’]; 46794683 $margs = array( 46804684 ‘posts_per_page’ => -1, 46814685 ‘post_type’ => $post_types, 46824686 ‘post_status’ => 'any’, 46834687 ‘post__in’ => $ids 46844688 ); 46854689 } else { 46864690 wp_send_json(false); 46874691 } 46884692 } 46894693 46904694 $m_newquery = new WP_Query($margs); 46914695 $mposts = $m_newquery->get_posts(); 46924696 if (!empty($mposts)) { 46934697 foreach ($mposts as $post) { 46944698 $value = $post->post_title; 46954699 /** 46964700 * Filter before update meta for post/page 46974701 * 46984702 * @param string Meta value 46994703 * @param integer Post ID 47004704 * @param string Meta key 47014705 * @param array Extra informations 47024706 * 47034707 * @return string 47044708 * 47054709 * @ignore Hook already documented 47064710 */ 47074711 $value = apply_filters('wpms_update_content_meta’, $value, $post->ID, $key, array(‘source’ => ‘copy_meta’)); 47084712 update_post_meta($post->ID, $key, $value); 47094713 } 47104714 wp_send_json(true); 47114715 } else { 47124716 wp_send_json(false); 47134717 } 47144718 } 47154719 47164720 /** 47174721 * Set cookie notification 47184722 * 47194723 * @return void 47204724 */ 47214725 public function setcookieNotification() 47224726 { 47234727 if (empty($_POST[‘wpms_nonce’]) 47244728 || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 47254729 die(); 47264730 } 47274731 47284732 if (isset($_POST[‘page’])) { 47294733 setcookie($_POST[‘page’], time(), time() + (86400 * 30), ‘/’); 47304734 wp_send_json(true); 47314735 } 47324736 wp_send_json(false); 47334737 } 47344738 47354739 47364740 /** 47374741 * Ajax save ga information 47384742 * 47394743 * @return void 47404744 */ 47414745 public function wpmsGGSaveInformation() 47424746 { 47434747 check_ajax_referer('wpms_nonce’, ‘wpms_nonce’);
47444752 47454753 $google_alanytics = array( 47464754 ‘wpmsga_dash_clientid’ => isset($_POST[‘wpmsga_dash_clientid’]) ? trim($_POST[‘wpmsga_dash_clientid’]) : '’, 47474755 ‘wpmsga_dash_clientsecret’ => isset($_POST[‘wpmsga_dash_clientsecret’]) ? trim($_POST[‘wpmsga_dash_clientsecret’]) : ‘’ 47484756 ); 47494757 47504758 update_option('wpms_google_alanytics’, $google_alanytics); 47514759 47524760 require_once WPMETASEO_PLUGIN_DIR . 'inc/google_analytics/wpmstools.php’; 47534761 $client = WpmsGaTools::initClient($google_alanytics[‘wpmsga_dash_clientid’], $google_alanytics[‘wpmsga_dash_clientsecret’]); 47544762 $authUrl = $client->createAuthUrl(); 47554763 47564764 if (!empty($authUrl)) { 47574765 echo json_encode(array(‘status’ => 'true’, ‘authUrl’ => $authUrl)); 47584766 die(); 47594767 } 47604768 47614769 echo json_encode(array(‘status’ => 'false’, ‘authUrl’ => ‘’)); 47624770 die(); 47634771 } 47644772 47654773 /** 47664774 * Run ajax 47674775 * 47684776 * @return void 47694777 */ 47704778 public function startProcess() 47714779 { 47724780 if (empty($_POST[‘wpms_nonce’]) || !wp_verify_nonce($_POST[‘wpms_nonce’], ‘wpms_nonce’)) { 47734781 die(); 47744782 } 47754783 if (!current_user_can(‘edit_posts’)) { 47764784 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 47774785 wp_die(__('There is no edit permission here’, ‘wp-meta-seo’)); 47784786 } 47794787 if (isset($_REQUEST[‘task’])) { 47804788 switch ($_REQUEST[‘task’]) { 47814789 case 'updateContentMeta’: 47824790 $this->updateContentMetaCallback(); 47834791 break; 47844792 case 'scanPosts’: 47854793 MetaSeoImageListTable::scanPostsCallback(); 47864794 break; 47874795 case 'load_posts’: 47884796 MetaSeoImageListTable::loadPostsCallback(); 47894797 break; 47904798 case 'optimize_imgs’: 47914799 MetaSeoImageListTable::optimizeImages(); 47924800 break; 47934801 case 'updateMeta’: 47944802 MetaSeoImageListTable::updateMetaCallback(); 47954803 break; 47964804 case 'import_meta_data’: 47974805 MetaSeoContentListTable::importMetaData(); 47984806 break; 47994807 case 'dismiss_import_meta’: 48004808 MetaSeoContentListTable::dismissImport(); 48014809 break; 48024810 case 'bulk_post_copy’: 48034811 $this->bulkPostCopy(); 48044812 break; 48054813 case 'bulk_image_copy’: 48064814 $this->bulkImageCopy(); 48074815 break; 48084816 case 'ajax_check_exist’: 48094817 $this->checkExist(); 48104818 break; 48114819 case 'reload_analysis’: 48124820 $this->reloadAnalysis(); 48134821 break; 48144822 case 'wpmsElementorSavePost’: 48154823 require_once(WPMETASEO_PLUGIN_DIR . ‘inc/class.metaseo-metabox.php’); 48164824 WPMSEOMetabox::savePostByElementor(); 48174825 break; 48184826 case 'validate_analysis’: 48194827 $this->validateAnalysis(); 48204828 break; 48214829 case 'update_link’: 48224830 $this->updateLink(); 48234831 break; 48244832 case 'remove_link’: 48254833 $this->removeLink(); 48264834 break; 48274835 case 'save_settings404’: 48284836 $this->save404Settings(); 48294837 break; 48304838 case 'save_settings_breadcrumb’: 48314839 $this->saveBreadcrumbSettings(); 48324840 break; 48334841 case 'update_link_redirect’: 48344842 MetaSeoBrokenLinkTable::updateLinkRedirect(); 48354843 break; 48364844 case 'add_custom_redirect’: 48374845 MetaSeoBrokenLinkTable::addCustomRedirect(); 48384846 break; 48394847 case 'unlink’: 48404848 MetaSeoBrokenLinkTable::unlink(); 48414849 break; 48424850 case 'recheck_link’: 48434851 MetaSeoBrokenLinkTable::reCheckLink(); 48444852 break; 48454853 case 'scan_link’: 48464854 MetaSeoBrokenLinkTable::scanLink(); 48474855 break; 48484856 case 'flush_link’: 48494857 MetaSeoBrokenLinkTable::flushLink(); 48504858 break; 48514859 case 'update_follow’: 48524860 $this->updateFollow(); 48534861 break; 48544862 case 'update_multiplefollow’: 48554863 $this->updateMultipleFollow(); 48564864 break; 48574865 case 'update_pagefollow’: 48584866 $this->updatePageFollow(); 48594867 break; 48604868 case 'update_pageindex’: 48614869 $this->updatePageIndex(); 48624870 break; 48634871 case 'backend_item_reports’: 48644872 MetaSeoGoogleAnalytics::itemsReport(); 48654873 break; 48664874 case 'analytics_widgets_data’: 48674875 MetaSeoGoogleAnalytics::analyticsWidgetsData(); 48684876 break; 48694877 case 'wpms_tagmanager_request_containers’: 48704878 $this->tagmanagerContainersReport(); 48714879 break; 48724880 case 'wpms_tagmanager_container_info’: 48734881 $this->tagmanagerContainerInfo(); 48744882 break; 48754883 case 'wpms_tagmanager_refresh_connect’: 48764884 $this->tagmanagerRefreshConnect(); 48774885 break; 48784886 case 'ga_clearauthor’: 48794887 MetaSeoGoogleAnalytics::clearAuthor(); 48804888 break; 48814889 case 'ga_update_option’: 48824890 MetaSeoGoogleAnalytics::updateOption(); 48834891 break; 48844892 case 'dash_permalink’: 48854893 MetaSeoDashboard::dashboardPermalink(); 48864894 break; 48874895 case 'dash_newcontent’: 48884896 MetaSeoDashboard::dashboardNewContent(); 48894897 break; 48904898 case 'dash_linkmeta’: 48914899 MetaSeoDashboard::dashboardLinkMeta(); 48924900 break; 48934901 case 'dash_metatitle’: 48944902 MetaSeoDashboard::dashboardMetaTitle(); 48954903 break; 48964904 case 'dash_metadesc’: 48974905 MetaSeoDashboard::dashboardMetaDesc(); 48984906 break; 48994907 case 'dash_imgsmeta’: 49004908 MetaSeoDashboard::dashImgsMeta(); 49014909 break; 49024910 case 'reload-web’: 49034911 MetaSeoDashboard::reloadWeb(); 49044912 break; 49054913 case 'setcookie_notification’: 49064914 $this->setcookieNotification(); 49074915 break; 49084916 case 'image_scan_meta’: 49094917 MetaSeoImageListTable::imageScanMeta(); 49104918 break; 49114919 case 'update_seokeyword_bulk_edit’: 49124920 $this->updateSeokeywordBulkEdit(); 49134921 break; 49144922 case 'updateCategoryContent’: 49154923 WPMSCategoryMetaTable::updateCategoryContent(); 49164924 break; 49174925 case 'wpmsDeleteCat’: 49184926 WPMSCategoryMetaTable::wpmsDeleteCat(); 49194927 break; 49204928 case 'wpmsBulkCatCopy’: 49214929 WPMSCategoryMetaTable::wpmsBulkCatCopy(); 49224930 break; 49234931 } 49244932 } 49254933 } 49264934 49274935 49284936 /** 49294937 * Convert canonical url 49304938 * 49314939 * @param string $url Url 49324940 * 49334941 * @return string 49344942 */ 49354943 public static function convertCanonicalUrlToSave($url) 49364944 { 49374945 if (empty($url)) { 49384946 return $url; 49394947 } 49404948 49414949 $url = preg_replace('/\s+/’, '’, $url); 49424950 49434951 if (substr($url, 0, 2) === ‘//’) { 49444952 $url = (is_ssl() ? ‘https:’ : ‘http:’) . $url; 49454953 } 49464954 49474955 // Remove / in first 49484956 $url = ltrim($url, ‘/’); 49494957 49504958 // Full link 49514959 if (preg_match('#http(s?)://#i’, $url)) { 49524960 if (strpos($url, trim(home_url(), ‘/’)) !== false) { 49534961 $url = str_replace(trim(home_url(), ‘/’), '’, $url); 49544962 return (empty($url) ? ‘/’ : $url); 49554963 } else { 49564964 // External link 49574965 return $url; 49584966 } 49594967 } 49604968 49614969 $parseHome = parse_url(home_url()); 49624970 $host = (!empty($parseHome[‘host’]) ? $parseHome[‘host’] : ‘’); 49634971 $host .= (!empty($parseHome[‘path’]) ? $parseHome[‘path’] : ‘’); 49644972 49654973 if ($host && $url && strpos($url, $host) !== false) { 49664974 $url = str_replace($host, '’, $url); 49674975 } 49684976 49694977 return ‘/’ . ltrim($url, ‘/’); 49704978 } 49714979 49724980 /** 49734981 * Convert canonical url to display 49744982 * 49754983 * @param string $url Url 49764984 * 49774985 * @return string 49784986 */ 49794987 public static function convertCanonicalUrlToDisplay($url) 49804988 { 49814989 if (empty($url)) { 49824990 return $url; 49834991 } 49844992 49854993 if (preg_match('#http(s?)://#i’, $url)) { 49864994 // External link 49874995 return $url; 49884996 } 49894997 49904998 return trim(home_url(), ‘/’) . $url; 49914999 } 49925000 49935001 /** 49945002 * Schedules a rewrite flush. 49955003 * 49965004 * @return void 49975005 */ 49985006 public function wpmsScheduleRewriteFlush() 49995007 { 50005008 // Bail if this is a multisite installation and the site has been switched. 50015009 if (is_multisite() && ms_is_switched()) { 50025010 return; 50035011 } 50045012 50055013 add_action('shutdown’, ‘flush_rewrite_rules’); 50065014 } 50075015}