WP Meta SEO - Version 4.0.2

Version Description

  • Fix : Title undefined in gutenberg editor
  • Fix : Compatible with Oxygen Builder
  • Fix : Error when save post
Download this release

Release Info

Developer JoomUnited
Plugin Icon 128x128 WP Meta SEO
Version 4.0.2
Comparing to
See all releases

Code changes from version 4.0.1 to 4.0.2

assets/css/main.css CHANGED
@@ -52,7 +52,7 @@
52
  border-color: #ff8726;
53
  }
54
 
55
- .description {
56
  margin-top: 10px;
57
  display: inline-block;
58
  width: 100%;
52
  border-color: #ff8726;
53
  }
54
 
55
+ .ju-description {
56
  margin-top: 10px;
57
  display: inline-block;
58
  width: 100%;
assets/css/metabox-tabs.css CHANGED
@@ -657,4 +657,17 @@ div.wpmseo-tab-content {
657
  height: 3px;
658
  will-change: left, right;
659
  background-color: #ff8726;
 
 
 
 
 
 
 
 
 
 
 
 
 
660
  }
657
  height: 3px;
658
  will-change: left, right;
659
  background-color: #ff8726;
660
+ }
661
+
662
+ #wpmseo_meta .description {
663
+ margin-top: 10px;
664
+ display: inline-block;
665
+ width: 100%;
666
+ font-size: 15px !important;
667
+ font-weight: normal;
668
+ font-style: normal !important;
669
+ font-stretch: normal;
670
+ line-height: 1.88;
671
+ letter-spacing: 0.8px;
672
+ color: #5f879b !important;
673
  }
assets/js/wp-metaseo-metabox.js CHANGED
@@ -289,7 +289,7 @@ var replacedVars = []; // jshint ignore:line
289
  var wpmsdivtitle = '';
290
  jQuery(document).ready(function ($) {
291
  // title
292
- if (wpmseoMetaboxL10n.plugin_active.indexOf('gutenberg.php') !== -1 && typeof wp.blocks !== "undefined") {
293
  wpmsdivtitle = '.editor-post-title__input';
294
  } else {
295
  wpmsdivtitle = '#title';
289
  var wpmsdivtitle = '';
290
  jQuery(document).ready(function ($) {
291
  // title
292
+ if (typeof wp.blocks !== "undefined") {
293
  wpmsdivtitle = '.editor-post-title__input';
294
  } else {
295
  wpmsdivtitle = '#title';
inc/class.image-helper.php CHANGED
@@ -168,32 +168,36 @@ class ImageHelper
168
  public static function IScan($content, $imgs = array())
169
  {
170
  $ifound = array();
171
- $doc = new DOMDocument();
172
- libxml_use_internal_errors(true);
173
- $doc->loadHtml($content);
174
- $tags = $doc->getElementsByTagName('img');
175
-
176
  //For standard images names, convert spaces to -
177
  $_imgs = array();
178
  foreach ($imgs as $iname => $iid) {
179
  $iname = preg_replace('/(\s{1,})/', '-', $iname);
180
  $_imgs[$iname] = $iid;
181
  }
182
- if ($tags->length > 0) {
183
- foreach ($tags as $order => $tag) {
184
  // only find img tag have source
185
- $obj = $tag->getAttribute('src');
186
- if ($obj === '') {
 
 
 
 
 
 
 
 
187
  continue;
188
  }
189
- $img_name = self::IHasClone(array_keys($_imgs), $obj);
190
  if ($img_name) {
191
  if (!empty($_imgs[$img_name])) {
192
  $ifound[$order]['id'] = $_imgs[$img_name];
193
- $ifound[$order]['src'] = $obj;
194
- $ifound[$order]['width'] = $tag->getAttribute('width');
195
- $ifound[$order]['height'] = $tag->getAttribute('height');
196
- $ifound[$order]['alt'] = trim($tag->getAttribute('alt'));
197
  } else {
198
  continue;
199
  }
168
  public static function IScan($content, $imgs = array())
169
  {
170
  $ifound = array();
171
+ $img_tags = wpmsExtractTags($content, 'img', true, true);
 
 
 
 
172
  //For standard images names, convert spaces to -
173
  $_imgs = array();
174
  foreach ($imgs as $iname => $iid) {
175
  $iname = preg_replace('/(\s{1,})/', '-', $iname);
176
  $_imgs[$iname] = $iid;
177
  }
178
+ if (!empty($img_tags)) {
179
+ foreach ($img_tags as $order => $tag) {
180
  // only find img tag have source
181
+ $attrs = array('src', 'width', 'height', 'alt');
182
+ foreach ($attrs as $attr) {
183
+ if (empty($tag['attributes'][$attr])) {
184
+ ${$attr} = false;
185
+ } else {
186
+ ${$attr} = $tag['attributes'][$attr];
187
+ }
188
+ }
189
+
190
+ if (!$src) {
191
  continue;
192
  }
193
+ $img_name = self::IHasClone(array_keys($_imgs), $src);
194
  if ($img_name) {
195
  if (!empty($_imgs[$img_name])) {
196
  $ifound[$order]['id'] = $_imgs[$img_name];
197
+ $ifound[$order]['src'] = $src;
198
+ $ifound[$order]['width'] = $width;
199
+ $ifound[$order]['height'] = $height;
200
+ $ifound[$order]['alt'] = trim($alt);
201
  } else {
202
  continue;
203
  }
inc/class.metaseo-admin.php CHANGED
@@ -124,7 +124,7 @@ class MetaSeoAdmin
124
  add_action('edited_category', array($this, 'saveCategoryMeta'), 10, 2);
125
  add_action('create_category', array($this, 'saveCategoryMeta'), 10, 2);
126
  add_action('post_updated', array('MetaSeoImageListTable', 'updatePost'), 10, 3);
127
- add_action('delete_post', array('MetaSeoImageListTable', 'deleteAttachment'));
128
 
129
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
130
  add_action('product_cat_add_form_fields', array($this, 'categoryField'));
@@ -133,6 +133,7 @@ class MetaSeoAdmin
133
  add_action('edit_term', array($this, 'saveCategoryMeta'), 10, 3);
134
  }
135
  add_action('wp_ajax_wpms', array($this, 'startProcess'));
 
136
  }
137
 
138
  /**
@@ -815,6 +816,31 @@ class MetaSeoAdmin
815
  return $output;
816
  }
817
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
818
  /**
819
  * Ajax load page analysis
820
  *
@@ -868,7 +894,14 @@ class MetaSeoAdmin
868
 
869
  $content = apply_filters(
870
  'the_content',
871
- '<div>' . html_entity_decode(stripcslashes($_POST['datas']['content'])) . '</div>'
 
 
 
 
 
 
 
872
  );
873
 
874
  if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['heading_title'])) {
@@ -890,155 +923,144 @@ class MetaSeoAdmin
890
  0
891
  );
892
  } else {
893
- $dom = new DOMDocument;
894
- libxml_use_internal_errors(true);
895
- if ($dom->loadHTML($content)) {
896
- // Extracting the specified elements from the web page
897
- $tags_h1 = $dom->getElementsByTagName('h1');
898
- $tags_h2 = $dom->getElementsByTagName('h2');
899
- $tags_h3 = $dom->getElementsByTagName('h3');
900
- $tags_h4 = $dom->getElementsByTagName('h4');
901
- $tags_h5 = $dom->getElementsByTagName('h5');
902
- $tags_h6 = $dom->getElementsByTagName('h6');
903
-
904
  $test = false;
905
- if (empty($tags_h1) && empty($tags_h2) && empty($tags_h3)
906
- && empty($tags_h4) && empty($tags_h5) && empty($tags_h6)) {
907
- $test = false;
908
- } else {
909
- // check tag h1
910
- if (!empty($tags_h1)) {
911
- foreach ($tags_h1 as $order => $tagh1) {
912
- $words_tagh1 = preg_split(
913
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
914
- utf8_decode(strtolower($tagh1->nodeValue)),
915
- - 1,
916
- PREG_SPLIT_NO_EMPTY
917
- );
918
- if (is_array($words_tagh1) && is_array($words_post_title)) {
919
- foreach ($words_tagh1 as $mh) {
920
- if (in_array($mh, $words_post_title) && $mh !== '') {
921
- $test = true;
922
- }
923
  }
924
  }
925
  }
926
  }
 
927
 
928
- // check tag h2
929
- if (!empty($tags_h2)) {
930
- foreach ($tags_h2 as $order => $tagh2) {
931
- $words_tagh2 = preg_split(
932
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
933
- utf8_decode(strtolower($tagh2->nodeValue)),
934
- - 1,
935
- PREG_SPLIT_NO_EMPTY
936
- );
937
- if (is_array($words_tagh2) && is_array($words_post_title)) {
938
- foreach ($words_tagh2 as $mh) {
939
- if (in_array($mh, $words_post_title) && $mh !== '') {
940
- $test = true;
941
- }
942
  }
943
  }
944
  }
945
  }
 
946
 
947
- // check tag h3
948
- if (!empty($tags_h3)) {
949
- foreach ($tags_h3 as $order => $tagh3) {
950
- $words_tagh3 = preg_split(
951
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
952
- utf8_decode(strtolower($tagh3->nodeValue)),
953
- - 1,
954
- PREG_SPLIT_NO_EMPTY
955
- );
956
- if (is_array($words_tagh3) && is_array($words_post_title)) {
957
- foreach ($words_tagh3 as $mh) {
958
- if (in_array($mh, $words_post_title) && $mh !== '') {
959
- $test = true;
960
- }
961
  }
962
  }
963
  }
964
  }
 
965
 
966
- // check tag h4
967
- if (!empty($tags_h4)) {
968
- foreach ($tags_h4 as $order => $tagh4) {
969
- $words_tagh4 = preg_split(
970
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
971
- utf8_decode(strtolower($tagh4->nodeValue)),
972
- - 1,
973
- PREG_SPLIT_NO_EMPTY
974
- );
975
- if (is_array($words_tagh4) && is_array($words_post_title)) {
976
- foreach ($words_tagh4 as $mh) {
977
- if (in_array($mh, $words_post_title) && $mh !== '') {
978
- $test = true;
979
- }
980
  }
981
  }
982
  }
983
  }
 
984
 
985
- // check tag h5
986
- if (!empty($tags_h5)) {
987
- foreach ($tags_h5 as $order => $tagh5) {
988
- $words_tagh5 = preg_split(
989
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
990
- utf8_decode(strtolower($tagh5->nodeValue)),
991
- - 1,
992
- PREG_SPLIT_NO_EMPTY
993
- );
994
- if (is_array($words_tagh5) && is_array($words_post_title)) {
995
- foreach ($words_tagh5 as $mh) {
996
- if (in_array($mh, $words_post_title) && $mh !== '') {
997
- $test = true;
998
- }
999
  }
1000
  }
1001
  }
1002
  }
 
1003
 
1004
- // check tag h6
1005
- if (!empty($tags_h6)) {
1006
- foreach ($tags_h6 as $order => $tagh6) {
1007
- $words_tagh6 = preg_split(
1008
- '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
1009
- utf8_decode(strtolower($tagh6->nodeValue)),
1010
- - 1,
1011
- PREG_SPLIT_NO_EMPTY
1012
- );
1013
- if (is_array($words_tagh6) && is_array($words_post_title)) {
1014
- foreach ($words_tagh6 as $mh) {
1015
- if (in_array($mh, $words_post_title) && $mh !== '') {
1016
- $test = true;
1017
- }
1018
  }
1019
  }
1020
  }
1021
  }
1022
  }
 
1023
 
1024
- if ($test) {
1025
- $output .= $this->createFieldAnalysis(
1026
- 'heading_title',
1027
- $tooltip_page['title_in_heading'],
1028
- 'done',
1029
- esc_html__('Page title word in content heading', 'wp-meta-seo'),
1030
- 1
1031
- );
1032
- $check ++;
1033
- } else {
1034
- $output .= $this->createFieldAnalysis(
1035
- 'heading_title',
1036
- $tooltip_page['title_in_heading'],
1037
- 'warning',
1038
- esc_html__('Page title word in content heading', 'wp-meta-seo'),
1039
- 0
1040
- );
1041
- }
1042
  } else {
1043
  $output .= $this->createFieldAnalysis(
1044
  'heading_title',
@@ -1228,41 +1250,51 @@ class MetaSeoAdmin
1228
  );
1229
  $check += 2;
1230
  } else {
1231
- $dom = new DOMDocument;
1232
- libxml_use_internal_errors(true);
1233
- if ($dom->loadHTML($content)) {
1234
- // Extracting the specified elements from the web page
1235
- $tags = $dom->getElementsByTagName('img');
1236
- $img_wrong = false;
1237
- $img_wrong_alt = false;
1238
- foreach ($tags as $order => $tag) {
1239
- $src = $tag->getAttribute('src');
1240
- $imgpath = str_replace(site_url(), ABSPATH, $src);
1241
- if (!file_exists($imgpath)) {
1242
- continue;
1243
- }
1244
- if (!list($width_origin, $height_origin) = getimagesize($imgpath)) {
1245
- continue;
1246
- }
1247
 
1248
- if ((int) $tag->getAttribute('width') === 0 && (int) $tag->getAttribute('height') === 0) {
1249
- $img_wrong = false;
1250
- } else {
1251
- if (!empty($width_origin) && !empty($height_origin)) {
1252
- if (((int) $width_origin !== (int) $tag->getAttribute('width'))
1253
- || ((int) $height_origin !== (int) $tag->getAttribute('height'))) {
1254
- $img_wrong = true;
1255
- }
 
 
 
 
 
 
 
 
1256
  }
1257
  }
 
1258
 
1259
- $image_alt = $tag->getAttribute('alt');
1260
- if ($image_alt === '') {
1261
- $img_wrong_alt = true;
1262
- }
1263
  }
 
1264
 
1265
- if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['imgresize'])) {
 
 
 
 
 
 
 
 
 
 
1266
  $output .= $this->createFieldAnalysis(
1267
  'imgresize',
1268
  $tooltip_page['image_resize'],
@@ -1272,27 +1304,27 @@ class MetaSeoAdmin
1272
  );
1273
  $check ++;
1274
  } else {
1275
- if (!$img_wrong) {
1276
- $output .= $this->createFieldAnalysis(
1277
- 'imgresize',
1278
- $tooltip_page['image_resize'],
1279
- 'done',
1280
- esc_html__('Wrong image resize', 'wp-meta-seo'),
1281
- 1
1282
- );
1283
- $check ++;
1284
- } else {
1285
- $output .= $this->createFieldAnalysis(
1286
- 'imgresize',
1287
- $tooltip_page['image_resize'],
1288
- 'warning',
1289
- esc_html__('Wrong image resize', 'wp-meta-seo'),
1290
- 0
1291
- );
1292
- }
1293
  }
 
1294
 
1295
- if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['imgalt'])) {
 
 
 
 
 
 
 
 
 
 
1296
  $output .= $this->createFieldAnalysis(
1297
  'imgalt',
1298
  $tooltip_page['image_alt'],
@@ -1302,40 +1334,14 @@ class MetaSeoAdmin
1302
  );
1303
  $check ++;
1304
  } else {
1305
- if (!$img_wrong_alt) {
1306
- $output .= $this->createFieldAnalysis(
1307
- 'imgalt',
1308
- $tooltip_page['image_alt'],
1309
- 'done',
1310
- esc_html__('Image have meta alt', 'wp-meta-seo'),
1311
- 1
1312
- );
1313
- $check ++;
1314
- } else {
1315
- $output .= $this->createFieldAnalysis(
1316
- 'imgalt',
1317
- $tooltip_page['image_alt'],
1318
- 'warning',
1319
- esc_html__('Image have meta alt', 'wp-meta-seo'),
1320
- 0
1321
- );
1322
- }
1323
  }
1324
- } else {
1325
- $output .= $this->createFieldAnalysis(
1326
- 'imgresize',
1327
- $tooltip_page['image_resize'],
1328
- 'warning',
1329
- esc_html__('Wrong image resize', 'wp-meta-seo'),
1330
- 0
1331
- );
1332
- $output .= $this->createFieldAnalysis(
1333
- 'imgalt',
1334
- $tooltip_page['image_alt'],
1335
- 'warning',
1336
- esc_html__('Image have meta alt', 'wp-meta-seo'),
1337
- 0
1338
- );
1339
  }
1340
  }
1341
 
@@ -1425,7 +1431,7 @@ class MetaSeoAdmin
1425
  $post = get_post($link_detail->source_id);
1426
  if (!empty($post)) {
1427
  $content = $post->post_content;
1428
- $links = MetaSeoBrokenLinkTable::extractTags($post->post_content, 'a', false, true);
1429
  foreach ($links as $link) {
1430
  if ($link['contents'] === $link_detail->link_text) {
1431
  $new_html = '<a';
@@ -1601,7 +1607,7 @@ class MetaSeoAdmin
1601
  }
1602
  global $wpdb;
1603
  $action_name = $_POST['action_name'];
1604
- $limit = 20;
1605
 
1606
  switch ($action_name) {
1607
  case 'copy_title_selected':
@@ -1609,7 +1615,7 @@ class MetaSeoAdmin
1609
  wp_send_json(array('status' => true));
1610
  }
1611
  foreach ($_POST['linkids'] as $linkId) {
1612
- $link = $wpdb->get_row(
1613
  $wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE id = %d', $linkId)
1614
  );
1615
  $link_text = $link->link_text;
@@ -1620,7 +1626,7 @@ class MetaSeoAdmin
1620
 
1621
  break;
1622
  case 'copy_title_all':
1623
- $links = $wpdb->get_results(
1624
  'SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE type="url"'
1625
  );
1626
  foreach ($links as $link) {
@@ -3040,7 +3046,7 @@ class MetaSeoAdmin
3040
  $local_business_html = apply_filters('wpmsaddon_local_business', '', $local_business, $countrys);
3041
 
3042
  $default_settings = wpmsGetDefaultSettings();
3043
- $settings = get_option('_metaseo_settings');
3044
  if (is_array($settings)) {
3045
  $settings = array_merge($default_settings, $settings);
3046
  } else {
@@ -3190,7 +3196,7 @@ class MetaSeoAdmin
3190
  *
3191
  * @return string
3192
  */
3193
- $value = apply_filters('wpms_update_image_meta', $value, $attachment->ID, '_wp_attachment_image_alt', array('source'=>'bulk_copy_alt'));
3194
  update_post_meta($attachment->ID, '_wp_attachment_image_alt', $value);
3195
  break;
3196
 
@@ -3208,7 +3214,7 @@ class MetaSeoAdmin
3208
  *
3209
  * @ignore Hook already documented
3210
  */
3211
- $value = apply_filters('wpms_update_image_meta', $value, $attachment->ID, 'post_title', array('source'=>'bulk_copy_title'));
3212
  wp_update_post(array('ID' => $attachment->ID, 'post_title' => $value));
3213
  break;
3214
  case 'img-copy-desc':
@@ -3222,7 +3228,7 @@ class MetaSeoAdmin
3222
  } else {
3223
  // selected
3224
  if (isset($_POST['ids'])) {
3225
- $ids = $_POST['ids'];
3226
  switch ($_POST['action_name']) {
3227
  case 'img-copy-alt':
3228
  $margs = array(
@@ -3237,7 +3243,7 @@ class MetaSeoAdmin
3237
  if (!empty($mposts_empty_alt)) {
3238
  foreach ($mposts_empty_alt as $post) {
3239
  $i_info_url = pathinfo($post->guid);
3240
- $value = $i_info_url['filename'];
3241
  /**
3242
  * Filter before update meta for image
3243
  *
@@ -3250,7 +3256,7 @@ class MetaSeoAdmin
3250
  *
3251
  * @ignore Hook already documented
3252
  */
3253
- $value = apply_filters('wpms_update_image_meta', $value, $post->ID, '_wp_attachment_image_alt', array('source'=>'bulk_copy_alt'));
3254
  update_post_meta($post->ID, '_wp_attachment_image_alt', $value);
3255
  }
3256
  } else {
@@ -3267,7 +3273,7 @@ class MetaSeoAdmin
3267
  if (!empty($posts_result)) {
3268
  foreach ($posts_result as $post) {
3269
  $i_info_url = pathinfo($post->guid);
3270
- $value = $i_info_url['filename'];
3271
  /**
3272
  * Filter before update meta for image
3273
  *
@@ -3280,7 +3286,7 @@ class MetaSeoAdmin
3280
  *
3281
  * @ignore Hook already documented
3282
  */
3283
- $value = apply_filters('wpms_update_image_meta', $value, $post->ID, 'post_title', array('source'=>'bulk_copy_title'));
3284
  wp_update_post(array('ID' => $post->ID, 'post_title' => $value));
3285
  }
3286
  } else {
@@ -3371,7 +3377,7 @@ class MetaSeoAdmin
3371
  *
3372
  * @ignore Hook already documented
3373
  */
3374
- $value = apply_filters('wpms_update_content_meta', $value, $post->ID, $key, array('source'=>'copy_meta'));
3375
  update_post_meta($post->ID, $key, $value);
3376
  }
3377
  wp_send_json(true);
124
  add_action('edited_category', array($this, 'saveCategoryMeta'), 10, 2);
125
  add_action('create_category', array($this, 'saveCategoryMeta'), 10, 2);
126
  add_action('post_updated', array('MetaSeoImageListTable', 'updatePost'), 10, 3);
127
+ add_action('delete_post', array('MetaSeoImageListTable', 'deletePost'));
128
 
129
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
130
  add_action('product_cat_add_form_fields', array($this, 'categoryField'));
133
  add_action('edit_term', array($this, 'saveCategoryMeta'), 10, 3);
134
  }
135
  add_action('wp_ajax_wpms', array($this, 'startProcess'));
136
+ add_filter('wpms_the_content', array($this, 'wpmsTheContent'), 10, 2);
137
  }
138
 
139
  /**
816
  return $output;
817
  }
818
 
819
+ /**
820
+ * Get content
821
+ *
822
+ * @param string $content Post content
823
+ * @param integer $post_id Post ID
824
+ *
825
+ * @return string
826
+ */
827
+ public function wpmsTheContent($content, $post_id)
828
+ {
829
+ $content = apply_filters(
830
+ 'the_content',
831
+ $content,
832
+ $post_id
833
+ );
834
+
835
+ if (is_plugin_active('oxygen/functions.php')) {
836
+ $shortcodes = get_post_meta($post_id, 'ct_builder_shortcodes', true);
837
+ $cf = do_shortcode($shortcodes);
838
+ $content = $content.$cf;
839
+ }
840
+
841
+ return $content;
842
+ }
843
+
844
  /**
845
  * Ajax load page analysis
846
  *
894
 
895
  $content = apply_filters(
896
  'the_content',
897
+ '<div>' . html_entity_decode(stripcslashes($content)) . '</div>',
898
+ $post_id
899
+ );
900
+
901
+ $content = apply_filters(
902
+ 'wpms_the_content',
903
+ '<div>' . html_entity_decode(stripcslashes($_POST['datas']['content'])) . '</div>',
904
+ $_POST['datas']['post_id']
905
  );
906
 
907
  if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['heading_title'])) {
923
  0
924
  );
925
  } else {
926
+ // Extracting the specified elements from the web page
927
+ $tags_h1 = wpmsExtractTags($content, 'h1', false, true);
928
+ $tags_h2 = wpmsExtractTags($content, 'h2', false, true);
929
+ $tags_h3 = wpmsExtractTags($content, 'h3', false, true);
930
+ $tags_h4 = wpmsExtractTags($content, 'h4', false, true);
931
+ $tags_h5 = wpmsExtractTags($content, 'h5', false, true);
932
+ $tags_h6 = wpmsExtractTags($content, 'h6', false, true);
933
+
934
+ $test = false;
935
+ if (empty($tags_h1) && empty($tags_h2) && empty($tags_h3)
936
+ && empty($tags_h4) && empty($tags_h5) && empty($tags_h6)) {
937
  $test = false;
938
+ } else {
939
+ // check tag h1
940
+ if (!empty($tags_h1)) {
941
+ foreach ($tags_h1 as $order => $tagh1) {
942
+ $words_tagh1 = preg_split(
943
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
944
+ utf8_decode(strtolower($tagh1['contents'])),
945
+ - 1,
946
+ PREG_SPLIT_NO_EMPTY
947
+ );
948
+
949
+ if (is_array($words_tagh1) && is_array($words_post_title)) {
950
+ foreach ($words_tagh1 as $mh) {
951
+ if (in_array($mh, $words_post_title) && $mh !== '') {
952
+ $test = true;
 
 
 
953
  }
954
  }
955
  }
956
  }
957
+ }
958
 
959
+ // check tag h2
960
+ if (!empty($tags_h2)) {
961
+ foreach ($tags_h2 as $order => $tagh2) {
962
+ $words_tagh2 = preg_split(
963
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
964
+ utf8_decode(strtolower($tagh2['contents'])),
965
+ - 1,
966
+ PREG_SPLIT_NO_EMPTY
967
+ );
968
+ if (is_array($words_tagh2) && is_array($words_post_title)) {
969
+ foreach ($words_tagh2 as $mh) {
970
+ if (in_array($mh, $words_post_title) && $mh !== '') {
971
+ $test = true;
 
972
  }
973
  }
974
  }
975
  }
976
+ }
977
 
978
+ // check tag h3
979
+ if (!empty($tags_h3)) {
980
+ foreach ($tags_h3 as $order => $tagh3) {
981
+ $words_tagh3 = preg_split(
982
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
983
+ utf8_decode(strtolower($tagh3['contents'])),
984
+ - 1,
985
+ PREG_SPLIT_NO_EMPTY
986
+ );
987
+ if (is_array($words_tagh3) && is_array($words_post_title)) {
988
+ foreach ($words_tagh3 as $mh) {
989
+ if (in_array($mh, $words_post_title) && $mh !== '') {
990
+ $test = true;
 
991
  }
992
  }
993
  }
994
  }
995
+ }
996
 
997
+ // check tag h4
998
+ if (!empty($tags_h4)) {
999
+ foreach ($tags_h4 as $order => $tagh4) {
1000
+ $words_tagh4 = preg_split(
1001
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
1002
+ utf8_decode(strtolower($tagh4['contents'])),
1003
+ - 1,
1004
+ PREG_SPLIT_NO_EMPTY
1005
+ );
1006
+ if (is_array($words_tagh4) && is_array($words_post_title)) {
1007
+ foreach ($words_tagh4 as $mh) {
1008
+ if (in_array($mh, $words_post_title) && $mh !== '') {
1009
+ $test = true;
 
1010
  }
1011
  }
1012
  }
1013
  }
1014
+ }
1015
 
1016
+ // check tag h5
1017
+ if (!empty($tags_h5)) {
1018
+ foreach ($tags_h5 as $order => $tagh5) {
1019
+ $words_tagh5 = preg_split(
1020
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
1021
+ utf8_decode(strtolower($tagh5['contents'])),
1022
+ - 1,
1023
+ PREG_SPLIT_NO_EMPTY
1024
+ );
1025
+ if (is_array($words_tagh5) && is_array($words_post_title)) {
1026
+ foreach ($words_tagh5 as $mh) {
1027
+ if (in_array($mh, $words_post_title) && $mh !== '') {
1028
+ $test = true;
 
1029
  }
1030
  }
1031
  }
1032
  }
1033
+ }
1034
 
1035
+ // check tag h6
1036
+ if (!empty($tags_h6)) {
1037
+ foreach ($tags_h6 as $order => $tagh6) {
1038
+ $words_tagh6 = preg_split(
1039
+ '/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/',
1040
+ utf8_decode(strtolower($tagh6['contents'])),
1041
+ - 1,
1042
+ PREG_SPLIT_NO_EMPTY
1043
+ );
1044
+ if (is_array($words_tagh6) && is_array($words_post_title)) {
1045
+ foreach ($words_tagh6 as $mh) {
1046
+ if (in_array($mh, $words_post_title) && $mh !== '') {
1047
+ $test = true;
 
1048
  }
1049
  }
1050
  }
1051
  }
1052
  }
1053
+ }
1054
 
1055
+ if ($test) {
1056
+ $output .= $this->createFieldAnalysis(
1057
+ 'heading_title',
1058
+ $tooltip_page['title_in_heading'],
1059
+ 'done',
1060
+ esc_html__('Page title word in content heading', 'wp-meta-seo'),
1061
+ 1
1062
+ );
1063
+ $check ++;
 
 
 
 
 
 
 
 
 
1064
  } else {
1065
  $output .= $this->createFieldAnalysis(
1066
  'heading_title',
1250
  );
1251
  $check += 2;
1252
  } else {
1253
+ // Extracting the specified elements from the web page
1254
+ $img_tags = wpmsExtractTags($content, 'img', true, true);
1255
+ $img_wrong = false;
1256
+ $img_wrong_alt = false;
1257
+ foreach ($img_tags as $order => $tag) {
1258
+ if (!isset($tag['attributes']['src'])) {
1259
+ continue;
1260
+ }
 
 
 
 
 
 
 
 
1261
 
1262
+ $src = $tag['attributes']['src'];
1263
+ $imgpath = str_replace(site_url(), ABSPATH, $src);
1264
+ if (!file_exists($imgpath)) {
1265
+ continue;
1266
+ }
1267
+ if (!list($width_origin, $height_origin) = getimagesize($imgpath)) {
1268
+ continue;
1269
+ }
1270
+
1271
+ if (empty($tag['attributes']['width']) && empty($tag['attributes']['height'])) {
1272
+ $img_wrong = false;
1273
+ } else {
1274
+ if (!empty($width_origin) && !empty($height_origin)) {
1275
+ if (((int) $width_origin !== (int) $tag['attributes']['width'])
1276
+ || ((int) $height_origin !== (int) $tag['attributes']['height'])) {
1277
+ $img_wrong = true;
1278
  }
1279
  }
1280
+ }
1281
 
1282
+ if (empty($tag['attributes']['alt'])) {
1283
+ $img_wrong_alt = true;
 
 
1284
  }
1285
+ }
1286
 
1287
+ if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['imgresize'])) {
1288
+ $output .= $this->createFieldAnalysis(
1289
+ 'imgresize',
1290
+ $tooltip_page['image_resize'],
1291
+ 'done',
1292
+ esc_html__('Wrong image resize', 'wp-meta-seo'),
1293
+ 1
1294
+ );
1295
+ $check ++;
1296
+ } else {
1297
+ if (!$img_wrong) {
1298
  $output .= $this->createFieldAnalysis(
1299
  'imgresize',
1300
  $tooltip_page['image_resize'],
1304
  );
1305
  $check ++;
1306
  } else {
1307
+ $output .= $this->createFieldAnalysis(
1308
+ 'imgresize',
1309
+ $tooltip_page['image_resize'],
1310
+ 'warning',
1311
+ esc_html__('Wrong image resize', 'wp-meta-seo'),
1312
+ 0
1313
+ );
 
 
 
 
 
 
 
 
 
 
 
1314
  }
1315
+ }
1316
 
1317
+ if (isset($_POST['datas']['first_load']) && !empty($meta_analysis) && !empty($meta_analysis['imgalt'])) {
1318
+ $output .= $this->createFieldAnalysis(
1319
+ 'imgalt',
1320
+ $tooltip_page['image_alt'],
1321
+ 'done',
1322
+ esc_html__('Image have meta alt', 'wp-meta-seo'),
1323
+ 1
1324
+ );
1325
+ $check ++;
1326
+ } else {
1327
+ if (!$img_wrong_alt) {
1328
  $output .= $this->createFieldAnalysis(
1329
  'imgalt',
1330
  $tooltip_page['image_alt'],
1334
  );
1335
  $check ++;
1336
  } else {
1337
+ $output .= $this->createFieldAnalysis(
1338
+ 'imgalt',
1339
+ $tooltip_page['image_alt'],
1340
+ 'warning',
1341
+ esc_html__('Image have meta alt', 'wp-meta-seo'),
1342
+ 0
1343
+ );
 
 
 
 
 
 
 
 
 
 
 
1344
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1345
  }
1346
  }
1347
 
1431
  $post = get_post($link_detail->source_id);
1432
  if (!empty($post)) {
1433
  $content = $post->post_content;
1434
+ $links = wpmsExtractTags($post->post_content, 'a', false, true);
1435
  foreach ($links as $link) {
1436
  if ($link['contents'] === $link_detail->link_text) {
1437
  $new_html = '<a';
1607
  }
1608
  global $wpdb;
1609
  $action_name = $_POST['action_name'];
1610
+ $limit = 20;
1611
 
1612
  switch ($action_name) {
1613
  case 'copy_title_selected':
1615
  wp_send_json(array('status' => true));
1616
  }
1617
  foreach ($_POST['linkids'] as $linkId) {
1618
+ $link = $wpdb->get_row(
1619
  $wpdb->prepare('SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE id = %d', $linkId)
1620
  );
1621
  $link_text = $link->link_text;
1626
 
1627
  break;
1628
  case 'copy_title_all':
1629
+ $links = $wpdb->get_results(
1630
  'SELECT * FROM ' . $wpdb->prefix . 'wpms_links WHERE type="url"'
1631
  );
1632
  foreach ($links as $link) {
3046
  $local_business_html = apply_filters('wpmsaddon_local_business', '', $local_business, $countrys);
3047
 
3048
  $default_settings = wpmsGetDefaultSettings();
3049
+ $settings = get_option('_metaseo_settings');
3050
  if (is_array($settings)) {
3051
  $settings = array_merge($default_settings, $settings);
3052
  } else {
3196
  *
3197
  * @return string
3198
  */
3199
+ $value = apply_filters('wpms_update_image_meta', $value, $attachment->ID, '_wp_attachment_image_alt', array('source' => 'bulk_copy_alt'));
3200
  update_post_meta($attachment->ID, '_wp_attachment_image_alt', $value);
3201
  break;
3202
 
3214
  *
3215
  * @ignore Hook already documented
3216
  */
3217
+ $value = apply_filters('wpms_update_image_meta', $value, $attachment->ID, 'post_title', array('source' => 'bulk_copy_title'));
3218
  wp_update_post(array('ID' => $attachment->ID, 'post_title' => $value));
3219
  break;
3220
  case 'img-copy-desc':
3228
  } else {
3229
  // selected
3230
  if (isset($_POST['ids'])) {
3231
+ $ids = $_POST['ids'];
3232
  switch ($_POST['action_name']) {
3233
  case 'img-copy-alt':
3234
  $margs = array(
3243
  if (!empty($mposts_empty_alt)) {
3244
  foreach ($mposts_empty_alt as $post) {
3245
  $i_info_url = pathinfo($post->guid);
3246
+ $value = $i_info_url['filename'];
3247
  /**
3248
  * Filter before update meta for image
3249
  *
3256
  *
3257
  * @ignore Hook already documented
3258
  */
3259
+ $value = apply_filters('wpms_update_image_meta', $value, $post->ID, '_wp_attachment_image_alt', array('source' => 'bulk_copy_alt'));
3260
  update_post_meta($post->ID, '_wp_attachment_image_alt', $value);
3261
  }
3262
  } else {
3273
  if (!empty($posts_result)) {
3274
  foreach ($posts_result as $post) {
3275
  $i_info_url = pathinfo($post->guid);
3276
+ $value = $i_info_url['filename'];
3277
  /**
3278
  * Filter before update meta for image
3279
  *
3286
  *
3287
  * @ignore Hook already documented
3288
  */
3289
+ $value = apply_filters('wpms_update_image_meta', $value, $post->ID, 'post_title', array('source' => 'bulk_copy_title'));
3290
  wp_update_post(array('ID' => $post->ID, 'post_title' => $value));
3291
  }
3292
  } else {
3377
  *
3378
  * @ignore Hook already documented
3379
  */
3380
+ $value = apply_filters('wpms_update_content_meta', $value, $post->ID, $key, array('source' => 'copy_meta'));
3381
  update_post_meta($post->ID, $key, $value);
3382
  }
3383
  wp_send_json(true);
inc/class.metaseo-broken-link-table.php CHANGED
@@ -76,7 +76,9 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
76
  max="999" min="1" step="1">
77
  </label>
78
 
79
- <button type="submit" name="btn_perpage" class="button_perpage ju-button orange-button waves-effect waves-light" id="button_perpage"><?php esc_html_e('Apply', 'wp-meta-seo') ?></button>
 
 
80
  </div>
81
  <?php endif ?>
82
 
@@ -130,9 +132,9 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
130
  $total_pages_after = '</span></span>';
131
 
132
  $disable_first = false;
133
- $disable_last = false;
134
- $disable_prev = false;
135
- $disable_next = false;
136
 
137
  if ($current === 1) {
138
  $disable_first = true;
@@ -368,7 +370,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
368
  global $wpdb;
369
  $where = array('1=1');
370
  // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- No action, nonce is not required
371
- $where[] = "type IN ('url', 'comment', '404_automaticaly')";
372
  $where_or = array();
373
  if (!empty($_REQUEST['sl_broken'])) {
374
  if (in_array('custom_redirect_url', $_REQUEST['sl_broken'])) {
@@ -398,7 +400,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
398
  }
399
 
400
  $where_or_string = implode(' OR ', $where_or);
401
- $where[] = '(' . $where_or_string . ')';
402
 
403
  $keyword = !empty($_GET['txtkeyword']) ? $_GET['txtkeyword'] : '';
404
  if (isset($keyword) && $keyword !== '') {
@@ -510,8 +512,10 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
510
  ?>
511
  <p class="search-box">
512
  <label>
513
- <input type="search" id="image-search-input" class="wpms-search-input" name="txtkeyword" class="form-control"
514
- value="<?php echo esc_attr(stripslashes($txtkeyword)); ?>" placeholder="<?php esc_html_e('Search URL', 'wp-meta-seo') ?>"/>
 
 
515
  </label>
516
 
517
  <button type="submit" id="search-submit"><span class="dashicons dashicons-search"></span></button>
@@ -535,7 +539,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
535
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
536
  $brokens['custom_redirect_url'] = esc_html__('Custom redirect URL', 'wp-meta-seo');
537
  }
538
- $brokens['valid_links'] = esc_html__('Valid links', 'wp-meta-seo');
539
  $brokens['not_yet_redirect'] = esc_html__('Not yet redirected', 'wp-meta-seo');
540
  // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- No action, nonce is not required
541
  if (empty($_REQUEST['sl_broken'])) {
@@ -548,7 +552,8 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
548
  <label for="filter-by-broken"
549
  class="screen-reader-text"><?php esc_html_e('Filter by broken', 'wp-meta-seo'); ?></label>
550
  <div class="form-group form-group-broken">
551
- <select multiple name="<?php echo esc_attr($name) ?>" id="filter-by-broken" class="broken_filter form-control">
 
552
  <?php
553
  foreach ($brokens as $k => $broken) {
554
  if (in_array($k, $selected)) {
@@ -560,7 +565,8 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
560
  ?>
561
  </select>
562
  <input type="submit" name="filter_type_action" id="broken-submit"
563
- class="ju-button orange-button wpms-small-btn wpms_right" style="height: 45px" value="<?php esc_attr_e('Filter', 'wp-meta-seo') ?>">
 
564
  </div>
565
  <?php
566
  }
@@ -605,7 +611,8 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
605
  }
606
  ?>
607
  </select>
608
- <input type="button" class="ju-button orange-button wpms_flush_link" value="<?php esc_html_e('Flush', 'wp-meta-seo') ?>">
 
609
  <span class="spinner wpms-spinner wpms-spinner-flush"></span>
610
  <span class="wpms-msg-success flush-msg-success"><?php esc_html_e('URLs removed!', 'wp-meta-seo') ?></span>
611
  <span class="wpms-msg-error flush-msg-error"><?php esc_html_e('Please select a remove URL option to flush', 'wp-meta-seo') ?></span>
@@ -766,9 +773,9 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
766
  } else {
767
  ?>
768
  <div class="form-group">
769
- <label class="title">
770
- <?php esc_html_e('Status', 'wp-meta-seo') ?>
771
- </label>
772
  <label>
773
  <select name="custom_redirect_status" class="custom_redirect_status">
774
  <option value="301" <?php selected($rec->meta_title, 301) ?>>301
@@ -797,7 +804,8 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
797
  </div>
798
  <div class="form-group">
799
  <label class="title"><?php esc_html_e('Redirect', 'wp-meta-seo'); ?></label>
800
- <input type="text" name="link_url_redirect" class="wpms-link-redirect-field form-control" style="margin-right: 0"
 
801
  value="<?php echo esc_attr($rec->link_url_redirect); ?>"/>
802
  <span class="wlink-btn">
803
  <i class="mce-ico mce-i-link link-btn" id="link-btn"></i>
@@ -999,7 +1007,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
999
  if (isset($_POST['filter_type_action'])) {
1000
  $current_url = add_query_arg(
1001
  array(
1002
- 'sl_broken' => $_POST['sl_broken']
1003
  ),
1004
  $current_url
1005
  );
@@ -1125,7 +1133,9 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
1125
  if ($type === 'update_post') {
1126
  return 'HTTP/1.1 200 OK';
1127
  }
1128
- $status = get_headers($url, 0);
 
 
1129
  if (isset($status[0])) {
1130
  return $status[0];
1131
  } else {
@@ -1411,27 +1421,33 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
1411
  }
1412
 
1413
  global $wpdb;
1414
- $post = $post_after;
1415
- $dom = new DOMDocument;
1416
- libxml_use_internal_errors(true);
1417
  $linkscontent = array();
1418
-
1419
  if ($post->post_excerpt !== 'metaseo_404_page') {
1420
  if ($post->post_status === 'publish') {
1421
  if (isset($post->post_content) && $post->post_content !== '') {
1422
- // find <a> tag in current post content
1423
- preg_match_all('#<a[^>]*>.*?</a>#si', $post->post_content, $matches, PREG_PATTERN_ORDER);
1424
- foreach (array_unique($matches[0]) as $i => $content) {
1425
- $dom->loadHTML($content);
1426
- $tags = $dom->getElementsByTagName('a');
1427
- $meta_title = $tags->item(0)->getAttribute('title');
1428
- $rel = $tags->item(0)->getAttribute('rel');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1429
 
1430
- preg_match('/< *a[^>]*href *= *["\']?([^"\']*)/i', $content, $matches);
1431
- $href = $matches[1];
1432
- $status = self::getUrlStatus($href, 'update_post');
1433
- $status_type = self::getUrlStatusType($status);
1434
- $link_text = preg_replace('/<a\s(.+?)>(.+?)<\/a>/is', '$2', $content);
1435
  $source_link = '<a href="' . get_edit_post_link($post->ID) . '">';
1436
  $source_link .= '<b>' . $post->post_title . '</b>';
1437
  $source_link .= '</a>';
@@ -1450,18 +1466,18 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
1450
  }
1451
 
1452
  // find <img> tag in current post content
1453
- preg_match_all(
1454
- '/(<img[\s]+[^>]*src\s*=\s*)([\"\'])([^>]+?)\2([^<>]*>)/i',
1455
- $post->post_content,
1456
- $matches,
1457
- PREG_PATTERN_ORDER
1458
- );
1459
- foreach (array_unique($matches[0]) as $content) {
1460
  $source_link = '<a href="' . get_edit_post_link($post->ID) . '">';
1461
  $source_link .= '<b>' . $post->post_title . '</b>';
1462
  $source_link .= '</a>';
1463
- preg_match('/< *img[^>]*src *= *["\']?([^"\']*)/i', $content, $matches);
1464
- $src = $matches[1];
 
 
 
 
 
1465
  $status = self::getUrlStatus($src, 'update_post');
1466
  $status_type = self::getUrlStatusType($status);
1467
  $link_text = '';
@@ -1501,7 +1517,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
1501
  $wpdb->query(
1502
  $wpdb->prepare(
1503
  'DELETE FROM ' . $wpdb->prefix . 'wpms_links
1504
- WHERE source_id = %d AND (type = %s || type = %s)',
1505
  array(
1506
  $post->ID,
1507
  'image',
@@ -1868,20 +1884,15 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
1868
  */
1869
  public static function checkInternalLink($link, $siteUrl, $value)
1870
  {
1871
- $info_link = parse_url($link);
1872
- if (empty($info_link['path'])) {
1873
- $value['internal'] = 0;
1874
- return $value;
1875
- }
1876
-
1877
- if (empty($info_link['host'])) {
1878
  $value['internal'] = 0;
1879
  return $value;
1880
  }
1881
 
1882
- $info_site_url = parse_url($siteUrl);
1883
- $domain_link = $info_link['host'] . $info_link['path'] . '/';
1884
- $domain_site = $info_site_url['host'] . $info_site_url['path'] . '/';
1885
  if (strpos($domain_link, $domain_site) !== false) {
1886
  $value['internal'] = 1;
1887
  } else {
@@ -2633,132 +2644,6 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
2633
  return $content;
2634
  }
2635
 
2636
- /**
2637
- * Extract specific HTML tags and their attributes from a string.
2638
- *
2639
- * You can either specify one tag, an array of tag names, or a regular expression that matches the tag name(s).
2640
- * If multiple tags are specified you must also set the $selfclosing parameter and it must be the same for
2641
- * all specified tags (so you can't extract both normal and self-closing tags in one go).
2642
- *
2643
- * The function returns a numerically indexed array of extracted tags. Each entry is an associative array
2644
- * with these keys :
2645
- * tag_name - the name of the extracted tag, e.g. "a" or "img".
2646
- * offset - the numberic offset of the first character of the tag within the HTML source.
2647
- * contents - the inner HTML of the tag. This is always empty for self-closing tags.
2648
- * attributes - a name -> value array of the tag's attributes, or an empty array if the tag has none.
2649
- * full_tag - the entire matched tag, e.g. '<a href="http://example.com">example.com</a>'. This key
2650
- * will only be present if you set $return_the_entire_tag to true.
2651
- *
2652
- * @param string $html The HTML code to search for tags.
2653
- * @param string|array $tag The tag(s) to extract.
2654
- * @param boolean $selfclosing Whether the tag is self-closing or not.
2655
- * Setting it to null will force the script to try and make an educated guess.
2656
- * @param boolean $return_the_entire_tag Return the entire matched tag in 'full_tag' key of the results array.
2657
- * @param string $charset The character set of the HTML code. Defaults to ISO-8859-1.
2658
- *
2659
- * @return array An array of extracted tags, or an empty array if no matching tags were found.
2660
- */
2661
- public static function extractTags(
2662
- $html,
2663
- $tag,
2664
- $selfclosing = null,
2665
- $return_the_entire_tag = false,
2666
- $charset = 'ISO-8859-1'
2667
- ) {
2668
-
2669
- if (is_array($tag)) {
2670
- $tag = implode('|', $tag);
2671
- }
2672
-
2673
- $selfclosing_tags = array(
2674
- 'area',
2675
- 'base',
2676
- 'basefont',
2677
- 'br',
2678
- 'hr',
2679
- 'input',
2680
- 'img',
2681
- 'link',
2682
- 'meta',
2683
- 'col',
2684
- 'param'
2685
- );
2686
- if (is_null($selfclosing)) {
2687
- $selfclosing = in_array($tag, $selfclosing_tags);
2688
- }
2689
-
2690
- if ($selfclosing) {
2691
- $tag_pattern = '@<(?P<tag>' . $tag . ') # <tag
2692
- (?P<attributes>\s[^>]+)? # attributes, if any
2693
- \s*/?> # /> or just >, being lenient here
2694
- @xsi';
2695
- } else {
2696
- $tag_pattern = '@<(?P<tag>' . $tag . ') # <tag
2697
- (?P<attributes>\s[^>]+)? # attributes, if any
2698
- \s*> # >
2699
- (?P<contents>.*?) # tag contents
2700
- </(?P=tag)> # the closing </tag>
2701
- @xsi';
2702
- }
2703
-
2704
- $attribute_pattern = '@
2705
- (?P<name>\w+) # attribute name
2706
- \s*=\s*
2707
- (
2708
- (?P<quote>[\"\'])(?P<value_quoted>.*?)(?P=quote) # a quoted value
2709
- | # or
2710
- (?P<value_unquoted>[^\s"\']+?)(?:\s+|$) # an unquoted value (terminated by whitespace or EOF)
2711
- )
2712
- @xsi';
2713
-
2714
- //Find all tags
2715
- if (!preg_match_all($tag_pattern, $html, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
2716
- //Return an empty array if we didn't find anything
2717
- return array();
2718
- }
2719
-
2720
- $tags = array();
2721
- foreach ($matches as $match) {
2722
- //Parse tag attributes, if any
2723
- $attributes = array();
2724
- if (!empty($match['attributes'][0])) {
2725
- if (preg_match_all($attribute_pattern, $match['attributes'][0], $attribute_data, PREG_SET_ORDER)) {
2726
- //Turn the attribute data into a name->value array
2727
- foreach ($attribute_data as $attr) {
2728
- if (!empty($attr['value_quoted'])) {
2729
- $value = $attr['value_quoted'];
2730
- } elseif (!empty($attr['value_unquoted'])) {
2731
- $value = $attr['value_unquoted'];
2732
- } else {
2733
- $value = '';
2734
- }
2735
-
2736
- //Passing the value through html_entity_decode is handy when you want
2737
- //to extract link URLs or something like that. You might want to remove
2738
- //or modify this call if it doesn't fit your situation.
2739
- $value = html_entity_decode($value, ENT_QUOTES, $charset);
2740
-
2741
- $attributes[$attr['name']] = $value;
2742
- }
2743
- }
2744
- }
2745
-
2746
- $tag = array(
2747
- 'tag_name' => $match['tag'][0],
2748
- 'offset' => $match[0][1],
2749
- 'contents' => !empty($match['contents']) ? $match['contents'][0] : '', //empty for self-closing tags
2750
- 'attributes' => $attributes,
2751
- );
2752
- if ($return_the_entire_tag) {
2753
- $tag['full_tag'] = $match[0][0];
2754
- }
2755
-
2756
- $tags[] = $tag;
2757
- }
2758
-
2759
- return $tags;
2760
- }
2761
-
2762
  /**
2763
  * Apply a callback function to all HTML links found in a string and return the results.
2764
  *
@@ -2783,7 +2668,7 @@ class MetaSeoBrokenLinkTable extends WP_List_Table
2783
  $results = array();
2784
 
2785
  //Find all links
2786
- $links = self::extractTags($content, 'a', false, true);
2787
 
2788
  //Iterate over the links and apply $callback to each
2789
  foreach ($links as $link) {
76
  max="999" min="1" step="1">
77
  </label>
78
 
79
+ <button type="submit" name="btn_perpage"
80
+ class="button_perpage ju-button orange-button waves-effect waves-light"
81
+ id="button_perpage"><?php esc_html_e('Apply', 'wp-meta-seo') ?></button>
82
  </div>
83
  <?php endif ?>
84
 
132
  $total_pages_after = '</span></span>';
133
 
134
  $disable_first = false;
135
+ $disable_last = false;
136
+ $disable_prev = false;
137
+ $disable_next = false;
138
 
139
  if ($current === 1) {
140
  $disable_first = true;
370
  global $wpdb;
371
  $where = array('1=1');
372
  // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- No action, nonce is not required
373
+ $where[] = "type IN ('url', 'comment', '404_automaticaly', 'add_custom')";
374
  $where_or = array();
375
  if (!empty($_REQUEST['sl_broken'])) {
376
  if (in_array('custom_redirect_url', $_REQUEST['sl_broken'])) {
400
  }
401
 
402
  $where_or_string = implode(' OR ', $where_or);
403
+ $where[] = '(' . $where_or_string . ')';
404
 
405
  $keyword = !empty($_GET['txtkeyword']) ? $_GET['txtkeyword'] : '';
406
  if (isset($keyword) && $keyword !== '') {
512
  ?>
513
  <p class="search-box">
514
  <label>
515
+ <input type="search" id="image-search-input" class="wpms-search-input" name="txtkeyword"
516
+ class="form-control"
517
+ value="<?php echo esc_attr(stripslashes($txtkeyword)); ?>"
518
+ placeholder="<?php esc_html_e('Search URL', 'wp-meta-seo') ?>"/>
519
  </label>
520
 
521
  <button type="submit" id="search-submit"><span class="dashicons dashicons-search"></span></button>
539
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
540
  $brokens['custom_redirect_url'] = esc_html__('Custom redirect URL', 'wp-meta-seo');
541
  }
542
+ $brokens['valid_links'] = esc_html__('Valid links', 'wp-meta-seo');
543
  $brokens['not_yet_redirect'] = esc_html__('Not yet redirected', 'wp-meta-seo');
544
  // phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- No action, nonce is not required
545
  if (empty($_REQUEST['sl_broken'])) {
552
  <label for="filter-by-broken"
553
  class="screen-reader-text"><?php esc_html_e('Filter by broken', 'wp-meta-seo'); ?></label>
554
  <div class="form-group form-group-broken">
555
+ <select multiple name="<?php echo esc_attr($name) ?>" id="filter-by-broken"
556
+ class="broken_filter form-control">
557
  <?php
558
  foreach ($brokens as $k => $broken) {
559
  if (in_array($k, $selected)) {
565
  ?>
566
  </select>
567
  <input type="submit" name="filter_type_action" id="broken-submit"
568
+ class="ju-button orange-button wpms-small-btn wpms_right" style="height: 45px"
569
+ value="<?php esc_attr_e('Filter', 'wp-meta-seo') ?>">
570
  </div>
571
  <?php
572
  }
611
  }
612
  ?>
613
  </select>
614
+ <input type="button" class="ju-button orange-button wpms_flush_link"
615
+ value="<?php esc_html_e('Flush', 'wp-meta-seo') ?>">
616
  <span class="spinner wpms-spinner wpms-spinner-flush"></span>
617
  <span class="wpms-msg-success flush-msg-success"><?php esc_html_e('URLs removed!', 'wp-meta-seo') ?></span>
618
  <span class="wpms-msg-error flush-msg-error"><?php esc_html_e('Please select a remove URL option to flush', 'wp-meta-seo') ?></span>
773
  } else {
774
  ?>
775
  <div class="form-group">
776
+ <label class="title">
777
+ <?php esc_html_e('Status', 'wp-meta-seo') ?>
778
+ </label>
779
  <label>
780
  <select name="custom_redirect_status" class="custom_redirect_status">
781
  <option value="301" <?php selected($rec->meta_title, 301) ?>>301
804
  </div>
805
  <div class="form-group">
806
  <label class="title"><?php esc_html_e('Redirect', 'wp-meta-seo'); ?></label>
807
+ <input type="text" name="link_url_redirect"
808
+ class="wpms-link-redirect-field form-control" style="margin-right: 0"
809
  value="<?php echo esc_attr($rec->link_url_redirect); ?>"/>
810
  <span class="wlink-btn">
811
  <i class="mce-ico mce-i-link link-btn" id="link-btn"></i>
1007
  if (isset($_POST['filter_type_action'])) {
1008
  $current_url = add_query_arg(
1009
  array(
1010
+ 'sl_broken' => $_POST['sl_broken']
1011
  ),
1012
  $current_url
1013
  );
1133
  if ($type === 'update_post') {
1134
  return 'HTTP/1.1 200 OK';
1135
  }
1136
+
1137
+ // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- fix warning
1138
+ $status = @get_headers($url, 0);
1139
  if (isset($status[0])) {
1140
  return $status[0];
1141
  } else {
1421
  }
1422
 
1423
  global $wpdb;
1424
+ $post = $post_after;
 
 
1425
  $linkscontent = array();
 
1426
  if ($post->post_excerpt !== 'metaseo_404_page') {
1427
  if ($post->post_status === 'publish') {
1428
  if (isset($post->post_content) && $post->post_content !== '') {
1429
+ $a_tags = wpmsExtractTags($post->post_content, 'a', false, true);
1430
+ foreach ($a_tags as $a_tag) {
1431
+ $meta_title = '';
1432
+ $rel = '';
1433
+ $href = '';
1434
+ if (isset($a_tag['attributes']['title'])) {
1435
+ $meta_title = $a_tag['attributes']['title'];
1436
+ }
1437
+
1438
+ if (isset($a_tag['attributes']['rel'])) {
1439
+ $rel = $a_tag['attributes']['rel'];
1440
+ }
1441
+
1442
+ if (isset($a_tag['attributes']['href'])) {
1443
+ $href = $a_tag['attributes']['href'];
1444
+ }
1445
+
1446
+ $link_text = $a_tag['contents'];
1447
+
1448
+ $status = self::getUrlStatus($href, 'update_post');
1449
+ $status_type = self::getUrlStatusType($status);
1450
 
 
 
 
 
 
1451
  $source_link = '<a href="' . get_edit_post_link($post->ID) . '">';
1452
  $source_link .= '<b>' . $post->post_title . '</b>';
1453
  $source_link .= '</a>';
1466
  }
1467
 
1468
  // find <img> tag in current post content
1469
+ $img_tags = wpmsExtractTags($post->post_content, 'img', true, true);
1470
+ foreach ($img_tags as $tag) {
 
 
 
 
 
1471
  $source_link = '<a href="' . get_edit_post_link($post->ID) . '">';
1472
  $source_link .= '<b>' . $post->post_title . '</b>';
1473
  $source_link .= '</a>';
1474
+
1475
+ if (empty($tag['attributes']['src'])) {
1476
+ $src = '';
1477
+ } else {
1478
+ $src = $tag['attributes']['src'];
1479
+ }
1480
+
1481
  $status = self::getUrlStatus($src, 'update_post');
1482
  $status_type = self::getUrlStatusType($status);
1483
  $link_text = '';
1517
  $wpdb->query(
1518
  $wpdb->prepare(
1519
  'DELETE FROM ' . $wpdb->prefix . 'wpms_links
1520
+ WHERE source_id = %d AND (type = %s || type = %s)',
1521
  array(
1522
  $post->ID,
1523
  'image',
1884
  */
1885
  public static function checkInternalLink($link, $siteUrl, $value)
1886
  {
1887
+ $info_link = parse_url($link);
1888
+ $info_site_url = parse_url($siteUrl);
1889
+ if (empty($info_link['path']) || $info_site_url['path'] || empty($info_link['host'])) {
 
 
 
 
1890
  $value['internal'] = 0;
1891
  return $value;
1892
  }
1893
 
1894
+ $domain_link = $info_link['host'] . $info_link['path'] . '/';
1895
+ $domain_site = $info_site_url['host'] . $info_site_url['path'] . '/';
 
1896
  if (strpos($domain_link, $domain_site) !== false) {
1897
  $value['internal'] = 1;
1898
  } else {
2644
  return $content;
2645
  }
2646
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2647
  /**
2648
  * Apply a callback function to all HTML links found in a string and return the results.
2649
  *
2668
  $results = array();
2669
 
2670
  //Find all links
2671
+ $links = wpmsExtractTags($content, 'a', false, true);
2672
 
2673
  //Iterate over the links and apply $callback to each
2674
  foreach ($links as $link) {
inc/class.metaseo-dashboard.php CHANGED
@@ -52,21 +52,20 @@ class MetaSeoDashboard
52
  // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Variable has been prepare
53
  $posts = $wpdb->get_results('SELECT ID,post_content FROM ' . $wpdb->posts . ' WHERE ' . implode(' AND ', $where) . ' ORDER BY ID');
54
  if (count($posts) > 0) {
55
- $doc = new DOMDocument();
56
- libxml_use_internal_errors(true);
57
  $upload_dir = wp_upload_dir();
58
-
59
  foreach ($posts as $post) {
60
  $meta_analysis = get_post_meta($post->ID, 'wpms_validate_analysis', true);
61
  if (empty($meta_analysis)) {
62
  $meta_analysis = array();
63
  }
64
 
65
- $doc->loadHTML($post->post_content);
66
- $tags = $doc->getElementsByTagName('img');
67
- foreach ($tags as $tag) {
68
- $img_src = $tag->getAttribute('src');
 
69
 
 
70
  if (!preg_match('/\.(jpg|png|gif)$/i', $img_src, $matches)) {
71
  continue;
72
  }
@@ -76,8 +75,15 @@ class MetaSeoDashboard
76
  continue;
77
  }
78
 
79
- $width = $tag->getAttribute('width');
80
- $height = $tag->getAttribute('height');
 
 
 
 
 
 
 
81
  if (list($real_width, $real_height) = getimagesize($img_path)) {
82
  $ratio_origin = $real_width / $real_height;
83
  //Check if img tag is missing with/height attribute value or not
@@ -95,7 +101,7 @@ class MetaSeoDashboard
95
  $imgs_are_good ++;
96
  }
97
 
98
- if (trim($tag->getAttribute('alt'))
99
  || (!empty($meta_analysis) && !empty($meta_analysis['imgalt']))) {
100
  $imgs_metas_are_good['alt'] ++;
101
  }
@@ -592,8 +598,6 @@ class MetaSeoDashboard
592
  $offset
593
  )));
594
  if (count($posts) > 0) {
595
- $doc = new DOMDocument();
596
- libxml_use_internal_errors(true);
597
  $upload_dir = wp_upload_dir();
598
 
599
  foreach ($posts as $post) {
@@ -601,12 +605,14 @@ class MetaSeoDashboard
601
  if (empty($meta_analysis)) {
602
  $meta_analysis = array();
603
  }
604
- // load dom html
605
- $doc->loadHTML($post->post_content);
606
- $tags = $doc->getElementsByTagName('img');
607
- foreach ($tags as $tag) {
608
- $img_src = $tag->getAttribute('src');
609
 
 
 
 
 
 
 
 
610
  if (!preg_match('/\.(jpg|png|gif)$/i', $img_src, $matches)) {
611
  continue;
612
  }
@@ -616,8 +622,16 @@ class MetaSeoDashboard
616
  continue;
617
  }
618
 
619
- $width = $tag->getAttribute('width');
620
- $height = $tag->getAttribute('height');
 
 
 
 
 
 
 
 
621
  if (list($real_width, $real_height) = getimagesize($img_path)) {
622
  $ratio_origin = $real_width / $real_height;
623
  //Check if img tag is missing with/height attribute value or not
@@ -635,7 +649,7 @@ class MetaSeoDashboard
635
  $imgs_are_good ++;
636
  }
637
  foreach ($meta_keys as $meta_key) {
638
- if (trim($tag->getAttribute($meta_key))
639
  || (!empty($meta_analysis) && !empty($meta_analysis['imgalt']))) {
640
  $imgs_metas_are_good[$meta_key] ++;
641
  }
52
  // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Variable has been prepare
53
  $posts = $wpdb->get_results('SELECT ID,post_content FROM ' . $wpdb->posts . ' WHERE ' . implode(' AND ', $where) . ' ORDER BY ID');
54
  if (count($posts) > 0) {
 
 
55
  $upload_dir = wp_upload_dir();
 
56
  foreach ($posts as $post) {
57
  $meta_analysis = get_post_meta($post->ID, 'wpms_validate_analysis', true);
58
  if (empty($meta_analysis)) {
59
  $meta_analysis = array();
60
  }
61
 
62
+ $img_tags = wpmsExtractTags($post->post_content, 'img', true, true);
63
+ foreach ($img_tags as $tag) {
64
+ if (empty($tag['attributes']['src'])) {
65
+ continue;
66
+ }
67
 
68
+ $img_src = $tag['attributes']['src'];
69
  if (!preg_match('/\.(jpg|png|gif)$/i', $img_src, $matches)) {
70
  continue;
71
  }
75
  continue;
76
  }
77
 
78
+ $attrs = array('width', 'height', 'alt');
79
+ foreach ($attrs as $attr) {
80
+ if (empty($tag['attributes'][$attr])) {
81
+ ${$attr} = false;
82
+ } else {
83
+ ${$attr} = $tag['attributes'][$attr];
84
+ }
85
+ }
86
+
87
  if (list($real_width, $real_height) = getimagesize($img_path)) {
88
  $ratio_origin = $real_width / $real_height;
89
  //Check if img tag is missing with/height attribute value or not
101
  $imgs_are_good ++;
102
  }
103
 
104
+ if ($alt && trim($alt)
105
  || (!empty($meta_analysis) && !empty($meta_analysis['imgalt']))) {
106
  $imgs_metas_are_good['alt'] ++;
107
  }
598
  $offset
599
  )));
600
  if (count($posts) > 0) {
 
 
601
  $upload_dir = wp_upload_dir();
602
 
603
  foreach ($posts as $post) {
605
  if (empty($meta_analysis)) {
606
  $meta_analysis = array();
607
  }
 
 
 
 
 
608
 
609
+ $img_tags = wpmsExtractTags($post->post_content, 'img', true, true);
610
+ foreach ($img_tags as $tag) {
611
+ if (empty($tag['attributes']['src'])) {
612
+ continue;
613
+ }
614
+
615
+ $img_src = $tag['attributes']['src'];
616
  if (!preg_match('/\.(jpg|png|gif)$/i', $img_src, $matches)) {
617
  continue;
618
  }
622
  continue;
623
  }
624
 
625
+ $width = false;
626
+ $height = false;
627
+ if (isset($tag['attributes']['width'])) {
628
+ $width = $tag['attributes']['width'];
629
+ }
630
+
631
+ if (isset($tag['attributes']['height'])) {
632
+ $height = $tag['attributes']['height'];
633
+ }
634
+
635
  if (list($real_width, $real_height) = getimagesize($img_path)) {
636
  $ratio_origin = $real_width / $real_height;
637
  //Check if img tag is missing with/height attribute value or not
649
  $imgs_are_good ++;
650
  }
651
  foreach ($meta_keys as $meta_key) {
652
+ if (isset($tag['attributes'][$meta_key])
653
  || (!empty($meta_analysis) && !empty($meta_analysis['imgalt']))) {
654
  $imgs_metas_are_good[$meta_key] ++;
655
  }
inc/class.metaseo-image-list-table.php CHANGED
@@ -63,7 +63,7 @@ class MetaSeoImageListTable extends WP_List_Table
63
  }
64
 
65
  echo '<button type="submit" class="ju-button orange-button wpms-middle m-r-3 wpms_left"
66
- >'.esc_html__('Filter', 'wp-meta-seo').'</button>';
67
  echo '<a href="#TB_inline?width=600&height=550&inlineId=meta-bulk-actions" title="' . esc_html__('Bulk Actions', 'wp-meta-seo') . '"
68
  class="ju-button orange-button thickbox wpms-middle wpms_left m-r-3" style="height: 17px">' . esc_html__('Meta Bulk Actions', 'wp-meta-seo') . '</a>';
69
  ?>
@@ -71,9 +71,9 @@ class MetaSeoImageListTable extends WP_List_Table
71
  <?php
72
  if ($which === 'top') {
73
  echo '<div class="wpms_left">';
74
- echo '<div data-comment_paged="1" data-paged="1" alt="'.esc_attr__('Index images is required to use the Images filtering system above.
75
  Beware it may take a while depending of the quantity of images you got.
76
- Check the progress bar and be patient :)', 'wp-meta-seo').'" class="ju-button orange-button image_scan_meta wpms_scan">';
77
  esc_html_e('Index images', 'wp-meta-seo');
78
  echo '<div class="wpms_process ju-button" data-w="0"></div>';
79
  echo '</div></div>';
@@ -87,7 +87,9 @@ class MetaSeoImageListTable extends WP_List_Table
87
  value="<?php echo esc_attr($this->_pagination_args['per_page']) ?>"
88
  maxlength="3" name="metaseo_imgs_per_page" class="metaseo_imgs_per_page screen-per-page"
89
  max="999" min="1" step="1">
90
- <button type="submit" name="btn_perpage" class="button_perpage ju-button orange-button waves-effect waves-light" id="button_perpage" value="Apply"><?php esc_html_e('Apply', 'wp-meta-seo'); ?></button>
 
 
91
  </label>
92
  </div>
93
  <?php endif ?>
@@ -148,9 +150,9 @@ class MetaSeoImageListTable extends WP_List_Table
148
  $total_pages_after = '</span></span>';
149
 
150
  $disable_first = false;
151
- $disable_last = false;
152
- $disable_prev = false;
153
- $disable_next = false;
154
 
155
  if ($current === 1) {
156
  $disable_first = true;
@@ -570,8 +572,9 @@ class MetaSeoImageListTable extends WP_List_Table
570
  // phpcs:enable
571
  ?>
572
  <p class="search-box">
573
- <input type="text" id="image-search-input" class="wpms-search-input" name="txtkeyword"
574
- value="<?php echo esc_attr(stripslashes($txtkeyword)); ?>" placeholder="<?php esc_html_e('Search image', 'wp-meta-seo') ?>"/>
 
575
  <button type="submit" id="search-submit"><span class="dashicons dashicons-search"></span></button>
576
  </p>
577
  <?php
@@ -746,13 +749,13 @@ class MetaSeoImageListTable extends WP_List_Table
746
  break;
747
 
748
  case 'col_image_name':
749
- $ext = strtoupper(str_replace('.', '', $type));
750
  $info = '<div class="img-name-wrapper">';
751
  $info .= '<input type="text" name="' . esc_attr('name_image[' . $rec->ID . ']') . '"
752
  class="metaseo-img-meta metaseo-img-name" data-meta-type="change_image_name"
753
  id="' . esc_attr('img-name-' . $rec->ID) . '" data-post-id="' . esc_attr($rec->ID) . '" rows="2"
754
  data-extension="' . esc_attr($type) . '" value="' . esc_attr($img_name) . '">';
755
- $info .= '<p>' . esc_html($ext) .esc_html__(' Size: ', 'wp-meta-seo') . esc_html($img_size . $img_sizes) . '</p>';
756
  $info .= '<p>' . esc_html($img_width) . 'x' . esc_html($img_height) . '</p>';
757
  $info .= '<p>' . esc_html($img_date) . '</p>';
758
  $info .= '<span class="saved-info" style="position:relative">
@@ -922,12 +925,12 @@ class MetaSeoImageListTable extends WP_List_Table
922
  <div class="content-box">
923
  <table class="wp-list-table widefat fixed posts">
924
  <thead>
925
- <tr class="metaseo-border-bottom">
926
- <td colspan="1"><?php esc_html_e('ID', 'wp-meta-seo') ?></td>
927
- <td colspan="2"><?php esc_html_e('Post title', 'wp-meta-seo') ?></td>
928
- <td colspan="2"><?php esc_html_e('Image', 'wp-meta-seo') ?></td>
929
- <td colspan="5"><?php esc_html_e('Image information', 'wp-meta-seo') ?></td>
930
- </tr>
931
  </thead>
932
  <tbody>
933
  <?php $alternate = ''; ?>
@@ -991,7 +994,8 @@ class MetaSeoImageListTable extends WP_List_Table
991
  </div>
992
 
993
  <?php if (trim($value) === '' && trim($alt) !== '') : ?>
994
- <a class="meta-default ju-button orange-button waves-effect waves-light" href="#"
 
995
  data-default-value="<?php echo esc_attr($alt) ?>"
996
  title="Add to input box"
997
  onclick="add_meta_default(this)"><?php esc_html_e('Copy ', 'wp-meta-seo'); ?></a>
@@ -1032,13 +1036,13 @@ class MetaSeoImageListTable extends WP_List_Table
1032
  <div class="content-box">
1033
  <table class="wp-list-table widefat fixed posts">
1034
  <thead>
1035
- <tr class="metaseo-border-bottom">
1036
- <td colspan="1"><?php esc_html_e('ID', 'wp-meta-seo') ?></td>
1037
- <td colspan="3"><?php esc_html_e('Title', 'wp-meta-seo') ?></td>
1038
- <td colspan="4"><?php esc_html_e('Current Images', 'wp-meta-seo') ?></td>
1039
- <td colspan="2" class="metaseo-action"><?php esc_html_e('Action', 'wp-meta-seo') ?></td>
1040
- <td colspan="4"><?php esc_html_e('After Replacing', 'wp-meta-seo') ?></td>
1041
- </tr>
1042
  </thead>
1043
  <tbody>
1044
  <?php
@@ -1052,7 +1056,7 @@ class MetaSeoImageListTable extends WP_List_Table
1052
  <p class="wpms-text"><?php echo esc_html($post['title']) ?></p>
1053
  </td>
1054
  <td colspan="4">
1055
- <?php foreach ($post['img_before_optm'] as $key => $src) :?>
1056
  <div class="metaseo-img-wrapper checked">
1057
  <div class="metaseo-img">
1058
  <img width="<?php echo esc_attr($src['width']); ?>"
@@ -1113,7 +1117,8 @@ class MetaSeoImageListTable extends WP_List_Table
1113
  </table>
1114
  </div>
1115
  <div class="wpms_width_100 wpms_left m-tb-30">
1116
- <a href="javascript:void(0);" id="metaseo-replace-all" class="ju-button orange-button waves-effect waves-light"
 
1117
  onclick="optimize_imgs_group(this)">
1118
  <?php esc_html_e('Replace All', 'wp-meta-seo') ?>
1119
  </a>
@@ -1473,7 +1478,7 @@ class MetaSeoImageListTable extends WP_List_Table
1473
  *
1474
  * @ignore Hook already documented
1475
  */
1476
- $meta_value = apply_filters('wpms_update_image_meta', $meta_value, $post_id, $aliases[$meta_type], array('source'=>'ajax_update'));
1477
 
1478
  $data = array('ID' => $post_id, $aliases[$meta_type] => $meta_value);
1479
  if (wp_update_post($data)) {
@@ -1493,7 +1498,7 @@ class MetaSeoImageListTable extends WP_List_Table
1493
  *
1494
  * @ignore Hook already documented
1495
  */
1496
- $meta_value = apply_filters('wpms_update_image_meta', $meta_value, $post_id, $aliases[$meta_type], array('source'=>'ajax_update'));
1497
 
1498
  update_post_meta($post_id, $aliases[$meta_type], $meta_value);
1499
  $settings = get_option('_metaseo_settings');
@@ -1984,7 +1989,7 @@ class MetaSeoImageListTable extends WP_List_Table
1984
  *
1985
  * @return void
1986
  */
1987
- public static function deleteAttachment($pid)
1988
  {
1989
  $post = get_post($pid);
1990
  if (!empty($post)) {
@@ -1995,14 +2000,15 @@ class MetaSeoImageListTable extends WP_List_Table
1995
  }
1996
 
1997
  if (in_array($post_type, $post_types)) {
1998
- $dom = new DOMDocument();
1999
- libxml_use_internal_errors(true);
2000
- $dom->loadHtml($post->post_content);
2001
- $tags = $dom->getElementsByTagName('img');
2002
- if (!empty($tags)) {
2003
- foreach ($tags as $tag) {
2004
- $url = $tag->getAttribute('src');
2005
- $postid = self::getAttachmentId($url);
 
2006
  $path = get_attached_file($postid);
2007
  $infos = pathinfo($path);
2008
  $img_name = $infos['basename'];
@@ -2049,42 +2055,41 @@ class MetaSeoImageListTable extends WP_List_Table
2049
 
2050
  $old_imgs = self::getImagesInContent($post_before); // return list img in post before
2051
  $new_imgs = array(); // return list img in post after
2052
- $dom = new DOMDocument();
2053
- libxml_use_internal_errors(true);
2054
  if ($post_after->post_content !== '') {
2055
- $dom->loadHtml($post_after->post_content);
2056
- $tags = $dom->getElementsByTagName('img');
2057
-
2058
- if (!empty($tags)) {
2059
- foreach ($tags as $tag) {
2060
- $url = $tag->getAttribute('src');
2061
- $postid = self::getAttachmentId($url);
2062
- $new_imgs[] = $postid;
2063
- $post = get_post($postid);
2064
- if (!empty($post)) {
2065
- $path = get_attached_file($postid);
2066
- $infos = pathinfo($path);
2067
- $img_name = $infos['basename'];
2068
- $imgs = array('name' => $img_name, 'img_post_id' => $postid);
2069
- $results = self::scanPostsMeta($imgs, false, 0);
2070
 
2071
- // update or delete meta
2072
- if ($results['msg'][$postid]['imNotGood']['warning']) {
2073
- update_post_meta($postid, 'wpms_missing_information', 1);
2074
- } else {
2075
- delete_post_meta($postid, 'wpms_missing_information');
2076
- }
2077
- if ($results['msg'][$postid]['iNotGood']['warning']) {
2078
- update_post_meta($postid, 'wpms_resizeimages', 1);
2079
- } else {
2080
- delete_post_meta($postid, 'wpms_resizeimages');
2081
- }
 
 
 
 
 
 
 
 
 
 
2082
  }
2083
  }
2084
  }
2085
  }
2086
 
2087
- // remove post meta
2088
  $imgs_diff = array_diff($old_imgs, $new_imgs);
2089
  if (!empty($imgs_diff)) {
2090
  foreach ($imgs_diff as $id) {
@@ -2118,22 +2123,31 @@ class MetaSeoImageListTable extends WP_List_Table
2118
  */
2119
  public static function getImagesInContent($post_before)
2120
  {
2121
- $dom = new DOMDocument();
2122
- libxml_use_internal_errors(true);
2123
  if ($post_before->post_content === '') {
2124
  return array();
2125
  }
2126
- $dom->loadHtml($post_before->post_content);
2127
- $tags = $dom->getElementsByTagName('img');
 
 
 
 
 
 
2128
  $ids = array();
2129
- if (empty($tags)) {
2130
- return $ids;
2131
- }
2132
- foreach ($tags as $tag) {
2133
- $url = $tag->getAttribute('src');
2134
- $postid = self::getAttachmentId($url);
2135
- $ids[] = $postid;
 
 
 
 
2136
  }
 
2137
  return $ids;
2138
  }
2139
 
63
  }
64
 
65
  echo '<button type="submit" class="ju-button orange-button wpms-middle m-r-3 wpms_left"
66
+ >' . esc_html__('Filter', 'wp-meta-seo') . '</button>';
67
  echo '<a href="#TB_inline?width=600&height=550&inlineId=meta-bulk-actions" title="' . esc_html__('Bulk Actions', 'wp-meta-seo') . '"
68
  class="ju-button orange-button thickbox wpms-middle wpms_left m-r-3" style="height: 17px">' . esc_html__('Meta Bulk Actions', 'wp-meta-seo') . '</a>';
69
  ?>
71
  <?php
72
  if ($which === 'top') {
73
  echo '<div class="wpms_left">';
74
+ echo '<div data-comment_paged="1" data-paged="1" alt="' . esc_attr__('Index images is required to use the Images filtering system above.
75
  Beware it may take a while depending of the quantity of images you got.
76
+ Check the progress bar and be patient :)', 'wp-meta-seo') . '" class="ju-button orange-button image_scan_meta wpms_scan">';
77
  esc_html_e('Index images', 'wp-meta-seo');
78
  echo '<div class="wpms_process ju-button" data-w="0"></div>';
79
  echo '</div></div>';
87
  value="<?php echo esc_attr($this->_pagination_args['per_page']) ?>"
88
  maxlength="3" name="metaseo_imgs_per_page" class="metaseo_imgs_per_page screen-per-page"
89
  max="999" min="1" step="1">
90
+ <button type="submit" name="btn_perpage"
91
+ class="button_perpage ju-button orange-button waves-effect waves-light"
92
+ id="button_perpage" value="Apply"><?php esc_html_e('Apply', 'wp-meta-seo'); ?></button>
93
  </label>
94
  </div>
95
  <?php endif ?>
150
  $total_pages_after = '</span></span>';
151
 
152
  $disable_first = false;
153
+ $disable_last = false;
154
+ $disable_prev = false;
155
+ $disable_next = false;
156
 
157
  if ($current === 1) {
158
  $disable_first = true;
572
  // phpcs:enable
573
  ?>
574
  <p class="search-box">
575
+ <input type="text" id="image-search-input" class="wpms-search-input" name="txtkeyword"
576
+ value="<?php echo esc_attr(stripslashes($txtkeyword)); ?>"
577
+ placeholder="<?php esc_html_e('Search image', 'wp-meta-seo') ?>"/>
578
  <button type="submit" id="search-submit"><span class="dashicons dashicons-search"></span></button>
579
  </p>
580
  <?php
749
  break;
750
 
751
  case 'col_image_name':
752
+ $ext = strtoupper(str_replace('.', '', $type));
753
  $info = '<div class="img-name-wrapper">';
754
  $info .= '<input type="text" name="' . esc_attr('name_image[' . $rec->ID . ']') . '"
755
  class="metaseo-img-meta metaseo-img-name" data-meta-type="change_image_name"
756
  id="' . esc_attr('img-name-' . $rec->ID) . '" data-post-id="' . esc_attr($rec->ID) . '" rows="2"
757
  data-extension="' . esc_attr($type) . '" value="' . esc_attr($img_name) . '">';
758
+ $info .= '<p>' . esc_html($ext) . esc_html__(' Size: ', 'wp-meta-seo') . esc_html($img_size . $img_sizes) . '</p>';
759
  $info .= '<p>' . esc_html($img_width) . 'x' . esc_html($img_height) . '</p>';
760
  $info .= '<p>' . esc_html($img_date) . '</p>';
761
  $info .= '<span class="saved-info" style="position:relative">
925
  <div class="content-box">
926
  <table class="wp-list-table widefat fixed posts">
927
  <thead>
928
+ <tr class="metaseo-border-bottom">
929
+ <td colspan="1"><?php esc_html_e('ID', 'wp-meta-seo') ?></td>
930
+ <td colspan="2"><?php esc_html_e('Post title', 'wp-meta-seo') ?></td>
931
+ <td colspan="2"><?php esc_html_e('Image', 'wp-meta-seo') ?></td>
932
+ <td colspan="5"><?php esc_html_e('Image information', 'wp-meta-seo') ?></td>
933
+ </tr>
934
  </thead>
935
  <tbody>
936
  <?php $alternate = ''; ?>
994
  </div>
995
 
996
  <?php if (trim($value) === '' && trim($alt) !== '') : ?>
997
+ <a class="meta-default ju-button orange-button waves-effect waves-light"
998
+ href="#"
999
  data-default-value="<?php echo esc_attr($alt) ?>"
1000
  title="Add to input box"
1001
  onclick="add_meta_default(this)"><?php esc_html_e('Copy ', 'wp-meta-seo'); ?></a>
1036
  <div class="content-box">
1037
  <table class="wp-list-table widefat fixed posts">
1038
  <thead>
1039
+ <tr class="metaseo-border-bottom">
1040
+ <td colspan="1"><?php esc_html_e('ID', 'wp-meta-seo') ?></td>
1041
+ <td colspan="3"><?php esc_html_e('Title', 'wp-meta-seo') ?></td>
1042
+ <td colspan="4"><?php esc_html_e('Current Images', 'wp-meta-seo') ?></td>
1043
+ <td colspan="2" class="metaseo-action"><?php esc_html_e('Action', 'wp-meta-seo') ?></td>
1044
+ <td colspan="4"><?php esc_html_e('After Replacing', 'wp-meta-seo') ?></td>
1045
+ </tr>
1046
  </thead>
1047
  <tbody>
1048
  <?php
1056
  <p class="wpms-text"><?php echo esc_html($post['title']) ?></p>
1057
  </td>
1058
  <td colspan="4">
1059
+ <?php foreach ($post['img_before_optm'] as $key => $src) : ?>
1060
  <div class="metaseo-img-wrapper checked">
1061
  <div class="metaseo-img">
1062
  <img width="<?php echo esc_attr($src['width']); ?>"
1117
  </table>
1118
  </div>
1119
  <div class="wpms_width_100 wpms_left m-tb-30">
1120
+ <a href="javascript:void(0);" id="metaseo-replace-all"
1121
+ class="ju-button orange-button waves-effect waves-light"
1122
  onclick="optimize_imgs_group(this)">
1123
  <?php esc_html_e('Replace All', 'wp-meta-seo') ?>
1124
  </a>
1478
  *
1479
  * @ignore Hook already documented
1480
  */
1481
+ $meta_value = apply_filters('wpms_update_image_meta', $meta_value, $post_id, $aliases[$meta_type], array('source' => 'ajax_update'));
1482
 
1483
  $data = array('ID' => $post_id, $aliases[$meta_type] => $meta_value);
1484
  if (wp_update_post($data)) {
1498
  *
1499
  * @ignore Hook already documented
1500
  */
1501
+ $meta_value = apply_filters('wpms_update_image_meta', $meta_value, $post_id, $aliases[$meta_type], array('source' => 'ajax_update'));
1502
 
1503
  update_post_meta($post_id, $aliases[$meta_type], $meta_value);
1504
  $settings = get_option('_metaseo_settings');
1989
  *
1990
  * @return void
1991
  */
1992
+ public static function deletePost($pid)
1993
  {
1994
  $post = get_post($pid);
1995
  if (!empty($post)) {
2000
  }
2001
 
2002
  if (in_array($post_type, $post_types)) {
2003
+ $img_tags = wpmsExtractTags($post->post_content, 'img', true, true);
2004
+ if (!empty($img_tags)) {
2005
+ foreach ($img_tags as $tag) {
2006
+ if (empty($tag['attributes']['src'])) {
2007
+ continue;
2008
+ }
2009
+
2010
+ $src = $tag->getAttribute('src');
2011
+ $postid = self::getAttachmentId($src);
2012
  $path = get_attached_file($postid);
2013
  $infos = pathinfo($path);
2014
  $img_name = $infos['basename'];
2055
 
2056
  $old_imgs = self::getImagesInContent($post_before); // return list img in post before
2057
  $new_imgs = array(); // return list img in post after
 
 
2058
  if ($post_after->post_content !== '') {
2059
+ // find <img> tag in current post content
2060
+ $img_tags = wpmsExtractTags($post_after->post_content, 'img', true, true);
2061
+ foreach ($img_tags as $tag) {
2062
+ if (empty($tag['attributes']['src'])) {
2063
+ continue;
2064
+ }
 
 
 
 
 
 
 
 
 
2065
 
2066
+ $src = $tag['attributes']['src'];
2067
+ $postid = self::getAttachmentId($src);
2068
+ $new_imgs[] = $postid;
2069
+ $post = get_post($postid);
2070
+ if (!empty($post)) {
2071
+ $path = get_attached_file($postid);
2072
+ $infos = pathinfo($path);
2073
+ $img_name = $infos['basename'];
2074
+ $imgs = array('name' => $img_name, 'img_post_id' => $postid);
2075
+ $results = self::scanPostsMeta($imgs, false, 0);
2076
+
2077
+ // update or delete meta
2078
+ if ($results['msg'][$postid]['imNotGood']['warning']) {
2079
+ update_post_meta($postid, 'wpms_missing_information', 1);
2080
+ } else {
2081
+ delete_post_meta($postid, 'wpms_missing_information');
2082
+ }
2083
+ if ($results['msg'][$postid]['iNotGood']['warning']) {
2084
+ update_post_meta($postid, 'wpms_resizeimages', 1);
2085
+ } else {
2086
+ delete_post_meta($postid, 'wpms_resizeimages');
2087
  }
2088
  }
2089
  }
2090
  }
2091
 
2092
+ // update post meta for old image
2093
  $imgs_diff = array_diff($old_imgs, $new_imgs);
2094
  if (!empty($imgs_diff)) {
2095
  foreach ($imgs_diff as $id) {
2123
  */
2124
  public static function getImagesInContent($post_before)
2125
  {
 
 
2126
  if ($post_before->post_content === '') {
2127
  return array();
2128
  }
2129
+
2130
+ preg_match_all(
2131
+ '/(<img[\s]+[^>]*src\s*=\s*)([\"\'])([^>]+?)\2([^<>]*>)/i',
2132
+ $post_before->post_content,
2133
+ $matches,
2134
+ PREG_PATTERN_ORDER
2135
+ );
2136
+
2137
  $ids = array();
2138
+ if (!empty($matches[0])) {
2139
+ if (empty($matches[0])) {
2140
+ return array();
2141
+ }
2142
+
2143
+ foreach (array_unique($matches[0]) as $tag) {
2144
+ preg_match('/< *img[^>]*src *= *["\']?([^"\']*)/i', $tag, $matches);
2145
+ $src = $matches[1];
2146
+ $postid = self::getAttachmentId($src);
2147
+ $ids[] = $postid;
2148
+ }
2149
  }
2150
+
2151
  return $ids;
2152
  }
2153
 
inc/class.metaseo-sitemap.php CHANGED
@@ -956,9 +956,7 @@ class MetaSeoSitemap
956
  $lastmod = $gglstmp_url->appendChild($xml->createElement('lastmod'));
957
 
958
  $now = $wpdb->get_var(
959
- $wpdb->prepare('SELECT post_modified FROM ' . $wpdb->posts . ', ' . $wpdb->term_relationships . '
960
- WHERE post_status = %s AND term_taxonomy_id = %d
961
- AND $wpdb->posts.ID = $wpdb->term_relationships.object_id ORDER BY post_modified DESC', array(
962
  'publish',
963
  $term_value->term_taxonomy_id
964
  ))
956
  $lastmod = $gglstmp_url->appendChild($xml->createElement('lastmod'));
957
 
958
  $now = $wpdb->get_var(
959
+ $wpdb->prepare('SELECT post_modified FROM ' . $wpdb->posts . ', ' . $wpdb->term_relationships . ' WHERE post_status = %s AND term_taxonomy_id = %d AND $wpdb->posts.ID = $wpdb->term_relationships.object_id ORDER BY post_modified DESC', array(
 
 
960
  'publish',
961
  $term_value->term_taxonomy_id
962
  ))
inc/install-wizard/content/viewEvironment.php CHANGED
@@ -74,9 +74,24 @@ defined('ABSPATH') || die('No direct script access allowed!');
74
  </p>
75
  <?php endif; ?>
76
 
77
- <?php if (!function_exists('gd_info')) : ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  <p class="description text_left">
79
- <?php esc_html_e('GD library is not detected. GD is an open source library related to image creation. The Watermark feature won’t work.', 'wp-meta-seo'); ?>
80
  </p>
81
  <?php endif; ?>
82
  </div>
74
  </p>
75
  <?php endif; ?>
76
 
77
+ <div class="ju-settings-option wpms_width_100">
78
+ <div class="wpms_row_full">
79
+ <label class="ju-setting-label"><?php esc_html_e('Libxml', 'wp-meta-seo'); ?></label>
80
+ <div class="right-checkbox">
81
+ <?php if (!extension_loaded('libxml')) : ?>
82
+ <img src="<?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information.png') ?>"
83
+ srcset="<?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information@2x.png') ?> 2x, <?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information@3x.png') ?> 3x"
84
+ class="img_warning">
85
+ <?php else : ?>
86
+ <input type="checkbox" id="libxml" name="libxml" checked
87
+ value="libxml" disabled class="filled-in media_checkbox"/>
88
+ <?php endif; ?>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ <?php if (!extension_loaded('libxml')) : ?>
93
  <p class="description text_left">
94
+ <?php esc_html_e('PHP libxml extension has not been detected. You need to activate in order to load site screenshot homepage image in dashboard', 'wp-meta-seo'); ?>
95
  </p>
96
  <?php endif; ?>
97
  </div>
inc/install-wizard/content/viewGoogleAnalytics.php CHANGED
@@ -26,7 +26,7 @@ $authUrl = $client->createAuthUrl();
26
  <input type="hidden" name="wpms_save_step" value="1"/>
27
  <div class="wizard-header">
28
  <div class="title font-size-35"><?php esc_html_e('Google Analytics', 'wp-meta-seo'); ?></div>
29
- <p class="description"><?php esc_html_e('Enable Google Analytics tracking and reports using a Google Analytics direct connection. It require a Google Analytics account creation first', 'wp-meta-seo') ?></p>
30
  <a target="_blank" href="<?php echo esc_url($authUrl) ?>"
31
  class="ju-button orange-button no-background generate-access-code m-tb-20"><?php esc_html_e('Generate access code', 'wp-meta-seo'); ?></a>
32
  </div>
26
  <input type="hidden" name="wpms_save_step" value="1"/>
27
  <div class="wizard-header">
28
  <div class="title font-size-35"><?php esc_html_e('Google Analytics', 'wp-meta-seo'); ?></div>
29
+ <p class="ju-description"><?php esc_html_e('Enable Google Analytics tracking and reports using a Google Analytics direct connection. It require a Google Analytics account creation first', 'wp-meta-seo') ?></p>
30
  <a target="_blank" href="<?php echo esc_url($authUrl) ?>"
31
  class="ju-button orange-button no-background generate-access-code m-tb-20"><?php esc_html_e('Generate access code', 'wp-meta-seo'); ?></a>
32
  </div>
inc/pages/google-analytics/google-analytics.php CHANGED
@@ -3,7 +3,7 @@
3
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/google-analytics/menu.php');
4
  ?>
5
  <h2 class="wpms_uppercase"><?php esc_html_e('Google Analytics tracking & report', 'wp-meta-seo') ?></h2>
6
- <p class="description"><?php esc_html_e('Enable Google Analytics tracking and reports using a Google Analytics
7
  direct connection. Require a Google Analytics login', 'wp-meta-seo') ?></p>
8
  <p>
9
  <a class="ju-button" href="<?php echo esc_url($authUrl) ?>"
@@ -28,8 +28,8 @@
28
  <td colspan="2">
29
  <div class="pure-checkbox">
30
  <input id="wpmsga_dash_userapi" type="checkbox" name="wpmsga_dash_userapi"
31
- value="1" <?php checked($this->google_alanytics['wpmsga_dash_userapi'], 1) ?>>
32
- <label class="metaseo_tool description" for="wpmsga_dash_userapi"
33
  data-alt="<?php esc_attr_e('You have the option to create your own Google developer
34
  project and use your own API key for tracking (optional)', 'wp-meta-seo') ?>">
35
  <?php esc_html_e(' Use your own API Project credentials', 'wp-meta-seo') ?></label>
@@ -41,9 +41,9 @@
41
  <hr class="wpms_hr">
42
  </div>
43
  <h2 class="wpms_uppercase"><?php esc_html_e('Google analytics tracking only', 'wp-meta-seo') ?></h2>
44
- <p class="description"><?php esc_html_e('Enable Google Analytics tracking only. You won\'t be
45
  able to display statistics in your', 'wp-meta-seo') ?></p>
46
- <p class="description"><?php esc_html_e('Wordpress admin, only on Google Analytics website', 'wp-meta-seo') ?></p>
47
 
48
  <table class="wpms-settings-options">
49
  <tr>
@@ -78,15 +78,15 @@
78
  </td>
79
  </tr>
80
  </table>
81
- <p class="description">
82
  <?php esc_html_e('If you are using Universal Analytics make sure
83
  you have changed your account to a Universal Analytics', 'wp-meta-seo') ?>
84
  </p>
85
- <p class="description">
86
  <?php esc_html_e('property in Google Analytics Read more about Universal Analytics ', 'wp-meta-seo') ?>
87
  <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/upgrade/">here</a>
88
  </p>
89
- <p class="description"><?php esc_html_e('OR use Analytics JS code', 'wp-meta-seo') ?></p>
90
  <label>
91
  <textarea name="_metaseo_ga_disconnect[wpmsga_code_tracking]"
92
  class="wpmsga_code_tracking">
3
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/google-analytics/menu.php');
4
  ?>
5
  <h2 class="wpms_uppercase"><?php esc_html_e('Google Analytics tracking & report', 'wp-meta-seo') ?></h2>
6
+ <p class="ju-description"><?php esc_html_e('Enable Google Analytics tracking and reports using a Google Analytics
7
  direct connection. Require a Google Analytics login', 'wp-meta-seo') ?></p>
8
  <p>
9
  <a class="ju-button" href="<?php echo esc_url($authUrl) ?>"
28
  <td colspan="2">
29
  <div class="pure-checkbox">
30
  <input id="wpmsga_dash_userapi" type="checkbox" name="wpmsga_dash_userapi"
31
+ value="1">
32
+ <label class="metaseo_tool ju-description" for="wpmsga_dash_userapi"
33
  data-alt="<?php esc_attr_e('You have the option to create your own Google developer
34
  project and use your own API key for tracking (optional)', 'wp-meta-seo') ?>">
35
  <?php esc_html_e(' Use your own API Project credentials', 'wp-meta-seo') ?></label>
41
  <hr class="wpms_hr">
42
  </div>
43
  <h2 class="wpms_uppercase"><?php esc_html_e('Google analytics tracking only', 'wp-meta-seo') ?></h2>
44
+ <p class="ju-description"><?php esc_html_e('Enable Google Analytics tracking only. You won\'t be
45
  able to display statistics in your', 'wp-meta-seo') ?></p>
46
+ <p class="ju-description"><?php esc_html_e('Wordpress admin, only on Google Analytics website', 'wp-meta-seo') ?></p>
47
 
48
  <table class="wpms-settings-options">
49
  <tr>
78
  </td>
79
  </tr>
80
  </table>
81
+ <p class="ju-description">
82
  <?php esc_html_e('If you are using Universal Analytics make sure
83
  you have changed your account to a Universal Analytics', 'wp-meta-seo') ?>
84
  </p>
85
+ <p class="ju-description">
86
  <?php esc_html_e('property in Google Analytics Read more about Universal Analytics ', 'wp-meta-seo') ?>
87
  <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/upgrade/">here</a>
88
  </p>
89
+ <p class="ju-description"><?php esc_html_e('OR use Analytics JS code', 'wp-meta-seo') ?></p>
90
  <label>
91
  <textarea name="_metaseo_ga_disconnect[wpmsga_code_tracking]"
92
  class="wpmsga_code_tracking">
inc/pages/settings.php CHANGED
@@ -131,7 +131,7 @@ $setting_switch_fields = array(
131
  title="<?php echo esc_attr($tab['title']) ?>"><?php echo esc_html($tab['title']) ?></span>
132
  <?php
133
  if ($tab['id'] === 'system_check') {
134
- if (version_compare(PHP_VERSION, '7.2.0', '<') || !in_array('curl', get_loaded_extensions()) || !function_exists('gd_info')) {
135
  echo '<i class="material-icons system-checkbox material-icons-menu-alert" style="float: right;vertical-align: text-bottom;">info</i>';
136
  }
137
  }
131
  title="<?php echo esc_attr($tab['title']) ?>"><?php echo esc_html($tab['title']) ?></span>
132
  <?php
133
  if ($tab['id'] === 'system_check') {
134
+ if (version_compare(PHP_VERSION, '7.2.0', '<') || !in_array('curl', get_loaded_extensions()) || !extension_loaded('libxml')) {
135
  echo '<i class="material-icons system-checkbox material-icons-menu-alert" style="float: right;vertical-align: text-bottom;">info</i>';
136
  }
137
  }
inc/pages/settings/general.php CHANGED
@@ -19,7 +19,7 @@ defined('ABSPATH') || die('No direct script access allowed!');
19
  <span class="slider round"></span>
20
  </label>
21
  </div>
22
- <p class="description text_left p-tb-20 border-top-e4e8ed">
23
  <?php esc_html_e('Force Home page meta title and description here', 'wp-meta-seo'); ?>
24
  </p>
25
  </div>
@@ -75,7 +75,7 @@ defined('ABSPATH') || die('No direct script access allowed!');
75
  <span class="slider round"></span>
76
  </label>
77
  </div>
78
- <p class="description text_left p-tb-20 border-top-e4e8ed">
79
  <?php echo esc_html($setting_switch_details['help']); ?>
80
  </p>
81
  </div>
19
  <span class="slider round"></span>
20
  </label>
21
  </div>
22
+ <p class="ju-description text_left p-tb-20 border-top-e4e8ed">
23
  <?php esc_html_e('Force Home page meta title and description here', 'wp-meta-seo'); ?>
24
  </p>
25
  </div>
75
  <span class="slider round"></span>
76
  </label>
77
  </div>
78
+ <p class="ju-description text_left p-tb-20 border-top-e4e8ed">
79
  <?php echo esc_html($setting_switch_details['help']); ?>
80
  </p>
81
  </div>
inc/pages/settings/redirections_404.php CHANGED
@@ -27,7 +27,7 @@ defined('ABSPATH') || die('No direct script access allowed!');
27
  <span class="slider round"></span>
28
  </label>
29
  </div>
30
- <p class="description text_left p-tb-20 border-top-e4e8ed">
31
  <?php esc_html_e('Redirect all 404 errors to home page', 'wp-meta-seo'); ?>
32
  </p>
33
  </div>
27
  <span class="slider round"></span>
28
  </label>
29
  </div>
30
+ <p class="ju-description text_left p-tb-20 border-top-e4e8ed">
31
  <?php esc_html_e('Redirect all 404 errors to home page', 'wp-meta-seo'); ?>
32
  </p>
33
  </div>
inc/pages/settings/social.php CHANGED
@@ -18,7 +18,7 @@ defined('ABSPATH') || die('No direct script access allowed!');
18
  <span class="slider round"></span>
19
  </label>
20
  </div>
21
- <p class="description text_left p-tb-20 border-top-e4e8ed">
22
  <?php esc_html_e('Customize social networks apparence when sharing a content', 'wp-meta-seo') ?>
23
  </p>
24
  </div>
18
  <span class="slider round"></span>
19
  </label>
20
  </div>
21
+ <p class="ju-description text_left p-tb-20 border-top-e4e8ed">
22
  <?php esc_html_e('Customize social networks apparence when sharing a content', 'wp-meta-seo') ?>
23
  </p>
24
  </div>
inc/pages/settings/system_check.php CHANGED
@@ -3,7 +3,7 @@
3
  defined('ABSPATH') || die('No direct script access allowed!');
4
  ?>
5
  <div class="content-box wpms_width_80">
6
- <p class="description text_center" style="margin: 0">
7
  <?php esc_html_e('We have checked your server environment.
8
  If you see some warning below it means that some plugin features may not work properly.
9
  Reload the page to refresh the results', 'wp-meta-seo'); ?>
@@ -35,13 +35,13 @@ defined('ABSPATH') || die('No direct script access allowed!');
35
  </div>
36
 
37
  <?php if (version_compare(PHP_VERSION, '7.2.0', '<')) : ?>
38
- <p class="description text_left p_warning">
39
  <?php esc_html_e('Your PHP version is ', 'wp-meta-seo'); ?>
40
  <?php echo esc_html(PHP_VERSION) ?>
41
  <?php esc_html_e('. For performance and security reasons it better to run PHP 7.2+. Comparing to previous versions the execution time of PHP 7.X is more than twice as fast and has 30 percent lower memory consumption', 'wp-meta-seo'); ?>
42
  </p>
43
  <?php else : ?>
44
- <p class="description text_center">
45
  <?php esc_html_e('Great ! Your PHP version is ', 'wp-meta-seo'); ?>
46
  <?php echo esc_html(PHP_VERSION) ?>
47
  </p>
@@ -65,8 +65,29 @@ defined('ABSPATH') || die('No direct script access allowed!');
65
  </div>
66
  </div>
67
  <?php if (!in_array('curl', get_loaded_extensions())) : ?>
68
- <p class="description p_warning">
69
  <?php esc_html_e('PHP Curl extension has not been detected. You need to activate in order to load video in media library and for all the cloud connections (like Google Drive, Dropbox...)', 'wp-meta-seo'); ?>
70
  </p>
71
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  </div>
3
  defined('ABSPATH') || die('No direct script access allowed!');
4
  ?>
5
  <div class="content-box wpms_width_80">
6
+ <p class="ju-description text_center" style="margin: 0">
7
  <?php esc_html_e('We have checked your server environment.
8
  If you see some warning below it means that some plugin features may not work properly.
9
  Reload the page to refresh the results', 'wp-meta-seo'); ?>
35
  </div>
36
 
37
  <?php if (version_compare(PHP_VERSION, '7.2.0', '<')) : ?>
38
+ <p class="ju-description text_left p_warning">
39
  <?php esc_html_e('Your PHP version is ', 'wp-meta-seo'); ?>
40
  <?php echo esc_html(PHP_VERSION) ?>
41
  <?php esc_html_e('. For performance and security reasons it better to run PHP 7.2+. Comparing to previous versions the execution time of PHP 7.X is more than twice as fast and has 30 percent lower memory consumption', 'wp-meta-seo'); ?>
42
  </p>
43
  <?php else : ?>
44
+ <p class="ju-description text_center">
45
  <?php esc_html_e('Great ! Your PHP version is ', 'wp-meta-seo'); ?>
46
  <?php echo esc_html(PHP_VERSION) ?>
47
  </p>
65
  </div>
66
  </div>
67
  <?php if (!in_array('curl', get_loaded_extensions())) : ?>
68
+ <p class="ju-description p_warning">
69
  <?php esc_html_e('PHP Curl extension has not been detected. You need to activate in order to load video in media library and for all the cloud connections (like Google Drive, Dropbox...)', 'wp-meta-seo'); ?>
70
  </p>
71
  <?php endif; ?>
72
+
73
+ <div class="ju-settings-option wpms_width_100">
74
+ <div class="wpms_row_full">
75
+ <label class="ju-setting-label"><?php esc_html_e('Libxml', 'wp-meta-seo'); ?></label>
76
+ <div class="right-checkbox">
77
+ <?php if (!extension_loaded('libxml')) : ?>
78
+ <img src="<?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information.png') ?>"
79
+ srcset="<?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information@2x.png') ?> 2x, <?php echo esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/icon-information/icon-information@3x.png') ?> 3x"
80
+ class="img_warning">
81
+ <?php else : ?>
82
+ <input type="checkbox" id="libxml" name="libxml" checked
83
+ value="libxml" disabled class="filled-in media_checkbox"/>
84
+ <?php endif; ?>
85
+ </div>
86
+ </div>
87
+ </div>
88
+ <?php if (!extension_loaded('libxml')) : ?>
89
+ <p class="ju-description p_warning">
90
+ <?php esc_html_e('PHP libxml extension has not been detected. You need to activate in order to load site screenshot homepage image in dashboard', 'wp-meta-seo'); ?>
91
+ </p>
92
+ <?php endif; ?>
93
  </div>
jutranslation/jutranslation.php CHANGED
@@ -248,7 +248,7 @@ class Jutranslation
248
 
249
  //Check if a translation exists for each entry
250
  foreach ($mo->entries as $entry) {
251
- if (is_countable($entry->translations)) { // phpcs:ignore -- We created it in line 198
252
  if (count($entry->translations)) {
253
  $language->overrided ++;
254
  }
248
 
249
  //Check if a translation exists for each entry
250
  foreach ($mo->entries as $entry) {
251
+ if (is_array($entry->translations) || $entry->translations instanceof Countable) {
252
  if (count($entry->translations)) {
253
  $language->overrided ++;
254
  }
languages/wp-meta-seo-en_US.mo CHANGED
Binary file
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: JoomUnited
3
  Tags: google, webmaster tools, keywords, meta, meta description, meta keywords, meta title, robots meta, search engine optimization, seo, wordpress seo, yahoo, image optimization, image resize, custom post seo, redirect, redirection, 301, broken link
4
  Requires at least: 4.0
5
- Tested up to: 4.9.8
6
- Stable tag: 4.0.1
7
  Requires PHP: 5.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -277,6 +277,11 @@ Yes WP Meta SEO is compatible with Gutenberg editor since 3.7 version.
277
 
278
  == Changelog ==
279
 
 
 
 
 
 
280
  = 4.0.1 =
281
  * Fix : Email report doesn't work
282
  * Fix : Css conflict in meta box
2
  Contributors: JoomUnited
3
  Tags: google, webmaster tools, keywords, meta, meta description, meta keywords, meta title, robots meta, search engine optimization, seo, wordpress seo, yahoo, image optimization, image resize, custom post seo, redirect, redirection, 301, broken link
4
  Requires at least: 4.0
5
+ Tested up to: 5.0.0
6
+ Stable tag: 4.0.2
7
  Requires PHP: 5.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
277
 
278
  == Changelog ==
279
 
280
+ = 4.0.2 =
281
+ * Fix : Title undefined in gutenberg editor
282
+ * Fix : Compatible with Oxygen Builder
283
+ * Fix : Error when save post
284
+
285
  = 4.0.1 =
286
  * Fix : Email report doesn't work
287
  * Fix : Css conflict in meta box
requirements.php ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WP Meta SEO
4
+ *
5
+ * @package WP Meta SEO
6
+ * @author Joomunited
7
+ * @version 1.0
8
+ */
9
+ namespace Joomunited\WPMS;
10
+
11
+ defined('ABSPATH') || die('No direct script access allowed!');
12
+
13
+ /**
14
+ * Class JUCheckRequirements
15
+ */
16
+ class JUCheckRequirements
17
+ {
18
+ /**
19
+ * Error string
20
+ *
21
+ * @var string
22
+ */
23
+ private static $error = '';
24
+ /**
25
+ * Warning string
26
+ *
27
+ * @var string
28
+ */
29
+ private static $warning = '';
30
+ /**
31
+ * Information string
32
+ *
33
+ * @var string
34
+ */
35
+ private static $info = '';
36
+ /**
37
+ * If requirements are pass return true
38
+ *
39
+ * @var boolean
40
+ */
41
+ public static $isMeetRequirements = true;
42
+ /**
43
+ * Plugins name
44
+ *
45
+ * @var string
46
+ */
47
+ public static $name = '';
48
+ /**
49
+ * Plugin Domain name
50
+ *
51
+ * @var string
52
+ */
53
+ public static $namedomain = '';
54
+ /**
55
+ * Plugins path to disable
56
+ *
57
+ * @var string
58
+ */
59
+ public static $path = '';
60
+ /**
61
+ * Plugin current version
62
+ *
63
+ * @var string
64
+ */
65
+ public static $version = '';
66
+ /**
67
+ * Minimum php version are requirement
68
+ *
69
+ * @var string
70
+ */
71
+ public static $requirePhpVersion = '';
72
+ /**
73
+ * Requirement classes
74
+ *
75
+ * @var array
76
+ */
77
+ public static $requireClasses = array();
78
+ /**
79
+ * Requirement functions
80
+ *
81
+ * @var array
82
+ */
83
+ public static $requireFunctions = array();
84
+ /**
85
+ * Requirement php modules
86
+ *
87
+ * @var array
88
+ */
89
+ public static $requirePhpModules = array();
90
+ /**
91
+ * Requirement plugins
92
+ *
93
+ * @var array
94
+ */
95
+ public static $requirePlugins = array();
96
+ /**
97
+ * Minimum addons version
98
+ *
99
+ * @var array
100
+ */
101
+ public static $addonsVersion = array();
102
+ /**
103
+ * Addons meet requirements to load
104
+ *
105
+ * @var array
106
+ */
107
+ public static $loadAddons = array();
108
+
109
+ /**
110
+ * Class JUCheckRequirements constructor.
111
+ *
112
+ * @param array $args Options
113
+ *
114
+ * @return array
115
+ */
116
+ public static function init($args)
117
+ {
118
+
119
+ if (is_array($args) && !empty($args)) {
120
+ foreach ($args as $key => $value) {
121
+ switch ($key) {
122
+ case 'plugin_name':
123
+ self::$name = $value;
124
+ break;
125
+ case 'plugin_path':
126
+ self::$path = $value;
127
+ break;
128
+ case 'plugin_textdomain':
129
+ self::$namedomain = $value;
130
+ break;
131
+ case 'requirements':
132
+ if (is_array($value) && !empty($value)) {
133
+ // Requirement plugins
134
+ if (isset($value['plugins']) && is_array($value['plugins'])) {
135
+ self::$requirePlugins = $value['plugins'];
136
+ }
137
+ // Requirement minimum php version
138
+ if (isset($value['php_version']) && $value['php_version'] !== '') {
139
+ self::$requirePhpVersion = $value['php_version'];
140
+ }
141
+ // Requirement php modules
142
+ if (isset($value['php_modules']) && is_array($value['php_modules'])) {
143
+ self::$requirePhpModules = $value['php_modules'];
144
+ }
145
+ // Requirement php classes
146
+ if (isset($value['classes']) && is_array($value['classes'])) {
147
+ self::$requireClasses = $value['classes'];
148
+ }
149
+ // Requirement php functions
150
+ if (isset($value['functions']) && is_array($value['functions'])) {
151
+ self::$requireFunctions = $value['functions'];
152
+ }
153
+ // Requirement addons version
154
+ if (isset($value['addons_version']) && is_array($value['addons_version'])) {
155
+ self::$addonsVersion = $value['addons_version'];
156
+ }
157
+ }
158
+ break;
159
+ default:
160
+ break;
161
+ }
162
+ }
163
+ if (!function_exists('get_plugin_data')) {
164
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
165
+ }
166
+ $addonData = get_plugin_data(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . self::$path);
167
+ self::$version = isset($addonData['Version']) ? $addonData['Version'] : null;
168
+ }
169
+
170
+ // self::checkPhpVersion();
171
+ self::checkRequirementModules();
172
+ self::checkRequirementClasses();
173
+ self::checkRequirementFunctions();
174
+ self::checkRequiredPlugins();
175
+ self::checkMinimumAddonsVersion();
176
+ if (is_admin() && !wp_doing_ajax()) {
177
+ self::displayNotify();
178
+ }
179
+
180
+ return array(
181
+ 'success' => self::$isMeetRequirements,
182
+ 'load' => self::$loadAddons
183
+ );
184
+ }
185
+
186
+ /**
187
+ * Check requirement php modules
188
+ *
189
+ * @return void
190
+ */
191
+ private static function checkRequirementModules()
192
+ {
193
+ $modules = self::$requirePhpModules;
194
+ if (is_array($modules) && !empty($modules)) {
195
+ foreach ($modules as $module => $type) {
196
+ if (function_exists('extension_loaded')) {
197
+ if (!extension_loaded($module)) {
198
+ $additionsMessage = '';
199
+ if ($type === 'warning') {
200
+ $additionsMessage = ' Some function may not work correctly!';
201
+ }
202
+ /* translators: Plugins name and requirement module name */
203
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
204
+ $message = __('<strong>%s</strong> requires php extension <strong>%s</strong> installed.' . $additionsMessage, self::$namedomain);
205
+ self::addText(
206
+ $type,
207
+ sprintf(strip_tags($message, '<strong>'), self::$name, $module)
208
+ );
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+ /**
215
+ * Check requirement classes
216
+ *
217
+ * @return void
218
+ */
219
+ private static function checkRequirementClasses()
220
+ {
221
+ $classes = self::$requireClasses;
222
+ if (is_array($classes) && !empty($classes)) {
223
+ foreach ($classes as $class => $type) {
224
+ if (!class_exists($class)) {
225
+ $additionsMessage = '';
226
+ if ($type === 'warning') {
227
+ $additionsMessage = ' Some function may not work correctly!';
228
+ }
229
+ /* translators: Plugins name and requirement class name */
230
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
231
+ $message = __('<strong>%s</strong> requires php class <strong>%s</strong> to be enable.' . $additionsMessage, self::$namedomain);
232
+ self::addText(
233
+ $type,
234
+ sprintf(strip_tags($message, '<strong>'), self::$name, $class)
235
+ );
236
+ }
237
+ }
238
+ }
239
+ }
240
+ /**
241
+ * Check requirement functions
242
+ *
243
+ * @return void
244
+ */
245
+ private static function checkRequirementFunctions()
246
+ {
247
+ $functions =self::$requireFunctions;
248
+ if (is_array($functions) && !empty($functions)) {
249
+ foreach ($functions as $function => $type) {
250
+ if (!function_exists($function)) {
251
+ $additionsMessage = '';
252
+ if ($type === 'warning') {
253
+ $additionsMessage = ' Some function may not work correctly!';
254
+ }
255
+ /* translators: Plugins name and requirement function name */
256
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
257
+ $message = __('<strong>%s</strong> requires php function <strong>%s</strong> to be enable.' . $additionsMessage, self::$namedomain);
258
+ self::addText(
259
+ $type,
260
+ sprintf(strip_tags($message, '<strong>'), self::$name, $function)
261
+ );
262
+ }
263
+ }
264
+ }
265
+ }
266
+ /**
267
+ * Check for php version is meet requirements
268
+ *
269
+ * @return void
270
+ */
271
+ private static function checkPhpVersion()
272
+ {
273
+ if (self::$requirePhpVersion !== '') {
274
+ if (version_compare(PHP_VERSION, self::$requirePhpVersion, '<')) {
275
+ /* translators: Plugins name and version */
276
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
277
+ $message = __('<strong>%1$s</strong> need at least PHP %2$s version, please update php before installing the plugin.', self::$namedomain);
278
+ self::addText(
279
+ 'error',
280
+ sprintf(strip_tags($message, '<strong>'), self::$name, self::$requirePhpVersion)
281
+ );
282
+ }
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Check requirement plugins
288
+ *
289
+ * @return void
290
+ */
291
+ private static function checkRequiredPlugins()
292
+ {
293
+ if (!function_exists('is_plugin_active') || !function_exists('get_plugin_data')) {
294
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
295
+ }
296
+ $plugins = self::$requirePlugins;
297
+ if (is_array($plugins) && !empty($plugins)) {
298
+ foreach ($plugins as $plugin) {
299
+ if (function_exists('is_plugin_active')) {
300
+ if (!is_plugin_active($plugin['path'])) {
301
+ /* translators: Plugins name and plugin requirement name */
302
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
303
+ $message = __('<strong>%1$s</strong> requires <strong>%2$s</strong> plugin to be activated.', self::$namedomain);
304
+ self::addText(
305
+ isset($plugin['type']) ? $plugin['type'] : 'error',
306
+ sprintf(strip_tags($message, '<strong>'), self::$name, $plugin['name'])
307
+ );
308
+ } else {
309
+ $pluginPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin['path'];
310
+ if (file_exists($pluginPath)) {
311
+ // Check minimum of require plugin version if set
312
+ if (isset($plugin['requireVersion']) && $plugin['requireVersion'] !== '') {
313
+ $requireVersion = $plugin['requireVersion'];
314
+ $addonData = get_plugin_data($pluginPath);
315
+ $installedVersion = (isset($addonData['Version']) && strpos($addonData['Version'], '{{version') === false) ? $addonData['Version'] : null;
316
+ if ($installedVersion !== null) {
317
+ if (self::versionCompare((string) $installedVersion, '<', (string) $requireVersion)) {
318
+ /* translators: Plugins name and requirement function name */
319
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
320
+ $message = __('<strong>%1$s %2$s</strong> requires at least <strong>%3$s %4$s</strong>.', self::$namedomain);
321
+ self::addText(
322
+ 'error',
323
+ sprintf(strip_tags($message, '<strong>'), self::$name, self::$version, $plugin['name'], $requireVersion)
324
+ );
325
+ }
326
+ }
327
+ }
328
+ }
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+ /**
335
+ * Check minimum requirement version of addons
336
+ *
337
+ * @return void
338
+ */
339
+ public static function checkMinimumAddonsVersion()
340
+ {
341
+
342
+ if (!empty(self::$addonsVersion)) {
343
+ if (!function_exists('get_plugin_data') || !function_exists('deactivate_plugins') || !function_exists('is_plugin_active')) {
344
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
345
+ }
346
+
347
+ foreach (self::$addonsVersion as $addonName => $requireVersion) {
348
+ $addonPath = '';
349
+ if (function_exists($addonName.'_getPath')) {
350
+ $addonPath = call_user_func($addonName.'_getPath');
351
+ }
352
+
353
+ if (!is_plugin_active($addonPath)) {
354
+ continue;
355
+ }
356
+ if (function_exists('get_plugin_data')) {
357
+ $pluginPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $addonPath;
358
+ if (file_exists($pluginPath)) {
359
+ $addonData = get_plugin_data($pluginPath);
360
+ $addonVersion = (isset($addonData['Version']) && strpos($addonData['Version'], '{{version') === false) ? $addonData['Version'] : null;
361
+ if ($addonVersion !== null) {
362
+ if (self::versionCompare($addonVersion, '<', $requireVersion)) {
363
+ /* translators: Plugins name and requirement function name */
364
+ // phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain,WordPress.WP.I18n.NonSingularStringLiteralText
365
+ $message = __('Minimum required version of <strong>%1$s is %2$s</strong> to work with <strong>%3$s %4$s</strong>. Please update the plugin.', self::$namedomain);
366
+ self::addText(
367
+ 'warning',
368
+ sprintf(strip_tags($message, '<strong>'), $addonData['Name'], $requireVersion, self::$name, self::$version)
369
+ );
370
+ //deactivate_plugins(array($path));
371
+ } else {
372
+ // Load this addons
373
+ self::$loadAddons[] = $addonName;
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ /**
382
+ * Disable plugin
383
+ *
384
+ * @return void
385
+ */
386
+ public static function disablePlugin()
387
+ {
388
+ if (!function_exists('is_plugin_active') || !function_exists('deactivate_plugins')) {
389
+ require_once(ABSPATH . 'wp-admin/includes/plugin.php');
390
+ }
391
+ if (current_user_can('activate_plugins') && is_plugin_active(plugin_basename(self::$path))) {
392
+ deactivate_plugins(array(self::$path));
393
+ }
394
+ }
395
+
396
+ /**
397
+ * Add notify text
398
+ *
399
+ * @param string $type Type of notify
400
+ * @param string $string Notify message
401
+ *
402
+ * @return void
403
+ */
404
+ private static function addText($type, $string)
405
+ {
406
+ switch ($type) {
407
+ case 'error':
408
+ self::$error .= '<p>'. $string .'</p>';
409
+ self::$isMeetRequirements = false;
410
+ break;
411
+ case 'warning':
412
+ self::$warning .= '<p>'. $string .'</p>';
413
+ break;
414
+ case 'info':
415
+ self::$info .= '<p>'. $string .'</p>';
416
+ break;
417
+ default:
418
+ break;
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Add notify text to admin_notices
424
+ *
425
+ * @return void
426
+ */
427
+ private static function displayNotify()
428
+ {
429
+ if (self::$error !== '') {
430
+ add_action('admin_notices', array(__NAMESPACE__ . '\JUCheckRequirements', 'printError'));
431
+ }
432
+ if (self::$warning !== '') {
433
+ add_action('admin_notices', array(__NAMESPACE__ . '\JUCheckRequirements', 'printWarning'));
434
+ }
435
+ if (self::$info !== '') {
436
+ add_action('admin_notices', array(__NAMESPACE__ . '\JUCheckRequirements', 'printInfo'));
437
+ }
438
+ if (!self::$isMeetRequirements) {
439
+ add_action('admin_init', array(__NAMESPACE__ . '\JUCheckRequirements', 'disablePlugin'));
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Render Error text
445
+ *
446
+ * @return void
447
+ */
448
+ public static function printError()
449
+ {
450
+ ?>
451
+ <div class="notice notice-error is-dismissible">
452
+ <?php echo self::$error; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Notify text?>
453
+ </div>
454
+ <?php
455
+ }
456
+
457
+ /**
458
+ * Render Warning text
459
+ *
460
+ * @return void
461
+ */
462
+ public static function printWarning()
463
+ {
464
+ ?>
465
+ <div class="notice notice-warning is-dismissible">
466
+ <?php echo self::$warning; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Notify text?>
467
+ </div>
468
+ <?php
469
+ }
470
+
471
+ /**
472
+ * Render Info text
473
+ *
474
+ * @return void
475
+ */
476
+ public static function printInfo()
477
+ {
478
+ ?>
479
+ <div class="notice notice-info is-dismissible">
480
+ <?php echo self::$info; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Notify text?>
481
+ </div>
482
+ <?php
483
+ }
484
+
485
+ /**
486
+ * Compare version
487
+ *
488
+ * @param string $version1 Version 1
489
+ * @param string $operator Operator
490
+ * @param string $version2 Version 2
491
+ *
492
+ * @return boolean
493
+ */
494
+ private static function versionCompare($version1, $operator, $version2)
495
+ {
496
+ $_fv = intval(trim(str_replace('.', '', $version1)));
497
+ $_sv = intval(trim(str_replace('.', '', $version2)));
498
+
499
+ if (strlen($_fv) > strlen($_sv)) {
500
+ $_sv = str_pad($_sv, strlen($_fv), 0);
501
+ }
502
+
503
+ if (strlen($_fv) < strlen($_sv)) {
504
+ $_fv = str_pad($_fv, strlen($_sv), 0);
505
+ }
506
+
507
+ return version_compare((string) $_fv, (string) $_sv, $operator);
508
+ }
509
+ }
wp-meta-seo.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: WP Meta SEO
5
  * Plugin URI: http://www.joomunited.com/wordpress-products/wp-meta-seo
6
  * Description: WP Meta SEO is a plugin for WordPress to fill meta for content, images and main SEO info in a single view.
7
- * Version: 4.0.1
8
  * Text Domain: wp-meta-seo
9
  * Domain Path: /languages
10
  * Author: JoomUnited
@@ -65,6 +65,37 @@ call_user_func(
65
  'languages' . DIRECTORY_SEPARATOR . 'wp-meta-seo-en_US.mo'
66
  );
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  if (!defined('WPMETASEO_PLUGIN_URL')) {
69
  /**
70
  * Url to WP Meta SEO plugin
@@ -90,7 +121,7 @@ if (!defined('WPMSEO_VERSION')) {
90
  /**
91
  * Plugin version
92
  */
93
- define('WPMSEO_VERSION', '4.0.1');
94
  }
95
 
96
  if (!defined('WPMS_CLIENTID')) {
@@ -215,6 +246,132 @@ function wpmsRetrieveDate($current_post)
215
  return $replacement;
216
  }
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  if (is_admin()) {
219
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-content-list-table.php');
220
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-image-list-table.php');
4
  * Plugin Name: WP Meta SEO
5
  * Plugin URI: http://www.joomunited.com/wordpress-products/wp-meta-seo
6
  * Description: WP Meta SEO is a plugin for WordPress to fill meta for content, images and main SEO info in a single view.
7
+ * Version: 4.0.2
8
  * Text Domain: wp-meta-seo
9
  * Domain Path: /languages
10
  * Author: JoomUnited
65
  'languages' . DIRECTORY_SEPARATOR . 'wp-meta-seo-en_US.mo'
66
  );
67
 
68
+ if (!class_exists('\Joomunited\WPMS\JUCheckRequirements')) {
69
+ require_once(trailingslashit(dirname(__FILE__)) . 'requirements.php');
70
+ }
71
+
72
+ if (class_exists('\Joomunited\WPMS\JUCheckRequirements')) {
73
+ // Plugins name for translate
74
+ $args = array(
75
+ 'plugin_name' => esc_html__('WP Meta SEO', 'wp-meta-seo'),
76
+ 'plugin_path' => 'wp-meta-seo/wp-meta-seo.php',
77
+ 'plugin_textdomain' => 'wp-meta-seo',
78
+ 'requirements' => array(
79
+ 'php_version' => '5.3',
80
+ 'php_modules' => array(
81
+ 'curl' => 'warning',
82
+ 'libxml' => 'warning'
83
+ ),
84
+ // Minimum addons version
85
+ 'addons_version' => array(
86
+ 'wpmsAddons' => '1.3.7'
87
+ )
88
+ ),
89
+ );
90
+ $wpmsCheck = call_user_func('\Joomunited\WPMS\JUCheckRequirements::init', $args);
91
+
92
+ if (!$wpmsCheck['success']) {
93
+ // Do not load anything more
94
+ unset($_GET['activate']);
95
+ return;
96
+ }
97
+ }
98
+
99
  if (!defined('WPMETASEO_PLUGIN_URL')) {
100
  /**
101
  * Url to WP Meta SEO plugin
121
  /**
122
  * Plugin version
123
  */
124
+ define('WPMSEO_VERSION', '4.0.2');
125
  }
126
 
127
  if (!defined('WPMS_CLIENTID')) {
246
  return $replacement;
247
  }
248
 
249
+ /**
250
+ * Extract specific HTML tags and their attributes from a string.
251
+ *
252
+ * You can either specify one tag, an array of tag names, or a regular expression that matches the tag name(s).
253
+ * If multiple tags are specified you must also set the $selfclosing parameter and it must be the same for
254
+ * all specified tags (so you can't extract both normal and self-closing tags in one go).
255
+ *
256
+ * The function returns a numerically indexed array of extracted tags. Each entry is an associative array
257
+ * with these keys :
258
+ * tag_name - the name of the extracted tag, e.g. "a" or "img".
259
+ * offset - the numberic offset of the first character of the tag within the HTML source.
260
+ * contents - the inner HTML of the tag. This is always empty for self-closing tags.
261
+ * attributes - a name -> value array of the tag's attributes, or an empty array if the tag has none.
262
+ * full_tag - the entire matched tag, e.g. '<a href="http://example.com">example.com</a>'. This key
263
+ * will only be present if you set $return_the_entire_tag to true.
264
+ *
265
+ * @param string $html The HTML code to search for tags.
266
+ * @param string|array $tag The tag(s) to extract.
267
+ * @param boolean $selfclosing Whether the tag is self-closing or not.
268
+ * Setting it to null will force the script to try and make an educated guess.
269
+ * @param boolean $return_the_entire_tag Return the entire matched tag in 'full_tag' key of the results array.
270
+ * @param string $charset The character set of the HTML code. Defaults to ISO-8859-1.
271
+ *
272
+ * @return array An array of extracted tags, or an empty array if no matching tags were found.
273
+ */
274
+ function wpmsExtractTags(
275
+ $html,
276
+ $tag,
277
+ $selfclosing = null,
278
+ $return_the_entire_tag = false,
279
+ $charset = 'ISO-8859-1'
280
+ ) {
281
+
282
+ if (is_array($tag)) {
283
+ $tag = implode('|', $tag);
284
+ }
285
+
286
+ $selfclosing_tags = array(
287
+ 'area',
288
+ 'base',
289
+ 'basefont',
290
+ 'br',
291
+ 'hr',
292
+ 'input',
293
+ 'img',
294
+ 'link',
295
+ 'meta',
296
+ 'col',
297
+ 'param'
298
+ );
299
+ if (is_null($selfclosing)) {
300
+ $selfclosing = in_array($tag, $selfclosing_tags);
301
+ }
302
+
303
+ if ($selfclosing) {
304
+ $tag_pattern = '@<(?P<tag>' . $tag . ') # <tag
305
+ (?P<attributes>\s[^>]+)? # attributes, if any
306
+ \s*/?> # /> or just >, being lenient here
307
+ @xsi';
308
+ } else {
309
+ $tag_pattern = '@<(?P<tag>' . $tag . ') # <tag
310
+ (?P<attributes>\s[^>]+)? # attributes, if any
311
+ \s*> # >
312
+ (?P<contents>.*?) # tag contents
313
+ </(?P=tag)> # the closing </tag>
314
+ @xsi';
315
+ }
316
+
317
+ $attribute_pattern = '@
318
+ (?P<name>\w+) # attribute name
319
+ \s*=\s*
320
+ (
321
+ (?P<quote>[\"\'])(?P<value_quoted>.*?)(?P=quote) # a quoted value
322
+ | # or
323
+ (?P<value_unquoted>[^\s"\']+?)(?:\s+|$) # an unquoted value (terminated by whitespace or EOF)
324
+ )
325
+ @xsi';
326
+
327
+ //Find all tags
328
+ if (!preg_match_all($tag_pattern, $html, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
329
+ //Return an empty array if we didn't find anything
330
+ return array();
331
+ }
332
+
333
+ $tags = array();
334
+ foreach ($matches as $match) {
335
+ //Parse tag attributes, if any
336
+ $attributes = array();
337
+ if (!empty($match['attributes'][0])) {
338
+ if (preg_match_all($attribute_pattern, $match['attributes'][0], $attribute_data, PREG_SET_ORDER)) {
339
+ //Turn the attribute data into a name->value array
340
+ foreach ($attribute_data as $attr) {
341
+ if (!empty($attr['value_quoted'])) {
342
+ $value = $attr['value_quoted'];
343
+ } elseif (!empty($attr['value_unquoted'])) {
344
+ $value = $attr['value_unquoted'];
345
+ } else {
346
+ $value = '';
347
+ }
348
+
349
+ //Passing the value through html_entity_decode is handy when you want
350
+ //to extract link URLs or something like that. You might want to remove
351
+ //or modify this call if it doesn't fit your situation.
352
+ $value = html_entity_decode($value, ENT_QUOTES, $charset);
353
+
354
+ $attributes[$attr['name']] = $value;
355
+ }
356
+ }
357
+ }
358
+
359
+ $tag = array(
360
+ 'tag_name' => $match['tag'][0],
361
+ 'offset' => $match[0][1],
362
+ 'contents' => !empty($match['contents']) ? $match['contents'][0] : '', //empty for self-closing tags
363
+ 'attributes' => $attributes,
364
+ );
365
+ if ($return_the_entire_tag) {
366
+ $tag['full_tag'] = $match[0][0];
367
+ }
368
+
369
+ $tags[] = $tag;
370
+ }
371
+
372
+ return $tags;
373
+ }
374
+
375
  if (is_admin()) {
376
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-content-list-table.php');
377
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-image-list-table.php');