WP Meta SEO - Version 4.4.0

Version Description

  • Add : Meta SEO meta box on Elementor
    • Add : Bulk editor for post/product categories
Download this release

Release Info

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

Code changes from version 4.3.7 to 4.4.0

assets/css/elementor/wpms-elementor.css ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #wpms-metabox-on-elementor .wpms-top-h2{
2
+ font-size: 20px !important;
3
+ font-weight: 600 !important;
4
+ font-style: normal;
5
+ font-stretch: normal;
6
+ line-height: normal !important;
7
+ letter-spacing: 1.3px;
8
+ color: #394857;
9
+ margin: 20px 0 !important;
10
+ }
11
+ input, select, textarea, button {
12
+ font-family: inherit;
13
+ }
14
+ #wpms-metabox-on-elementor .wpmstabs .wpmstab {
15
+ display: inline-block;
16
+ text-align: center;
17
+ line-height: 48px;
18
+ height: 48px;
19
+ padding: 0;
20
+ margin: 0 auto;
21
+ min-width: 170px;
22
+ width: 100%;
23
+ }
24
+ #wpms-metabox-on-elementor .wpmstabs .wpmstab a .active {
25
+ background-color: #0b2e13;
26
+ }
27
+ #reload_analysis {
28
+ font-size: 10px;
29
+ padding: 8px 10px;
30
+ min-width: 130px;
31
+ }
32
+ #wpms-metabox-on-elementor .ju-setting-label {
33
+ font-size: 14px !important;
34
+ font-weight: 600;
35
+ font-style: normal;
36
+ font-stretch: normal;
37
+ line-height: normal;
38
+ letter-spacing: 0.5px;
39
+ color: #404852;
40
+ }
41
+ #wpms-metabox-on-elementor .description {
42
+ font-size: 12px !important;
43
+ margin-top: 10px;
44
+ display: inline-block;
45
+ width: 100%;
46
+ font-weight: normal;
47
+ font-style: normal !important;
48
+ font-stretch: normal;
49
+ line-height: 1.88;
50
+ letter-spacing: 0.8px;
51
+ color: #5f879b !important;
52
+ }
53
+ #wpms-metabox-on-elementor .wpmseo_general .description {
54
+ padding-right: 20px;
55
+ }
56
+ #wpms-metabox-on-elementor .container-snippet{
57
+ width: calc(100% - 55px) !important;
58
+ min-width: 150px !important;
59
+ }
60
+
61
+ #wpms-metabox-on-elementor .metabox-snippet-description textarea {
62
+ width: calc(100% - 55px) !important;
63
+ min-width: 150px !important;
64
+ }
65
+ #wpms-metabox-on-elementor .wpmseotab {
66
+ margin-bottom: 30px !important;
67
+ }
68
+ #wpms-metabox-on-elementor .mpns-clear-float {
69
+ float: none !important;
70
+ width: 100%;
71
+ }
72
+ #wpms-metabox-on-elementor .wpms-full-width {
73
+ width: 100% !important;
74
+ }
75
+ #wpms-metabox-on-elementor .wpms-width-50 {
76
+ width: 50% !important;
77
+ }
78
+ #wpms-metabox-on-elementor .wpms-width100-elementor {
79
+ width: 100% !important;
80
+ margin-left: 30px;
81
+ }
82
+ #wpms-metabox-on-elementor #metaseo_wpmseo_opengraph-image_button,#metaseo_wpmseo_twitter-image_button {
83
+ padding: 0 !important;
84
+ }
85
+
86
+ #wpms-metabox-on-elementor .wpmseotab .optimization-row-box {
87
+ width: 100% !important;
88
+ }
89
+ #wpms-metabox-on-elementor .optimization-row-box input[type="text"],
90
+ #wpms-metabox-on-elementor .optimization-row-box textarea {
91
+ font-size: 14px !important;
92
+ }
93
+ .wpmseotab wpmseo_social .optimization-row-box input[type="text"] {
94
+ border-color: #d5dadf !important;
95
+ }
96
+ .wpmseotab wpmseo_social .optimization-row-box input:focus {
97
+ border-color: #a4afb7 !important;
98
+ }
99
+ #metaseo_wpmseo_keywords,
100
+ #metaseo_wpmseo_metaseo_canonical {
101
+ border: solid 1px #d5dadf !important;
102
+ }
103
+ #metaseo_wpmseo_keywords:focus,
104
+ #metaseo_wpmseo_metaseo_canonical:focus {
105
+ border: solid 1px #a4afb7 !important;
106
+ }
107
+
108
+ #wpms-metabox-on-elementor .wpms-bootstrap-tagsinput {
109
+ border-color: #d5dadf !important;
110
+ }
111
+ #wpms-metabox-on-elementor .focus{
112
+ border: solid 1px #a4afb7 !important;
113
+ }
114
+ #wpms-metabox-on-elementor .metabox-snippet-title .length-box-meta,
115
+ #wpms-metabox-on-elementor .metabox-snippet-description .length-box-meta,
116
+ #wpms-metabox-on-elementor .metabox-snippet-title .length-box-meta span,
117
+ #wpms-metabox-on-elementor .metabox-snippet-description .length-box-meta span {
118
+ height: 32px !important;
119
+ line-height: 32px !important;
120
+ width: 50px !important;
121
+ float: right !important;
122
+ }
123
+ #wpms-metabox-on-elementor .metaseo-progress-bar canvas {
124
+ width: 220px;
125
+ height: 220px;
126
+ }
127
+ #wpms-metabox-on-elementor .metaseo-progress-bar strong {
128
+ top: 90px !important;
129
+ }
130
+ #wpms-metabox-on-elementor .metaseo_left {
131
+ float: none !important;
132
+ width: 100% !important;
133
+ }
134
+ .wpms-mouseover-frame {
135
+ border-color: #2271b1;
136
+ box-shadow: 0 0 0 1px #2271b1;
137
+ outline: 2px solid transparent;
138
+ }
139
+
140
+ .p_index_folder .wpmslabel {
141
+ width: 180px;
142
+ float: left;
143
+ text-align: left;
144
+ color: #23282d;
145
+ line-height: 1.3;
146
+ font-weight: 600;
147
+ font-size: 14px;
148
+ }
149
+
150
+ .p_index_folder .wpmslabel label {
151
+ line-height: 45px;
152
+ }
153
+ .p_index_folder .wpmslabel i.metaseo_help {
154
+ line-height: 45px;
155
+ float: right;
156
+ }
157
+ .p_index_folder .metaseo_metabox_follow,
158
+ .p_index_folder .metaseo_metabox_index {
159
+ width: 120px;
160
+ margin-left: 20px;
161
+ }
assets/css/main.css CHANGED
@@ -644,7 +644,7 @@ input[type=checkbox]:focus {
644
 
645
  .wpms-form-table .wp-list-table tbody > tr td,
646
  .wpms-form-table .wp-list-table tbody > tr th {
647
- padding: 20px 10px;
648
  }
649
 
650
  .wp-meta-seo_page_metaseo_content_meta .wpms-form-table .wp-list-table tbody > tr td:nth-child(3),
@@ -751,6 +751,7 @@ input[type=checkbox]:focus {
751
  letter-spacing: 2px;
752
  color: #394857;
753
  margin: 20px 0 !important;
 
754
  }
755
 
756
  .wpms-top-h2 {
644
 
645
  .wpms-form-table .wp-list-table tbody > tr td,
646
  .wpms-form-table .wp-list-table tbody > tr th {
647
+ padding: 20px 10px !important;
648
  }
649
 
650
  .wp-meta-seo_page_metaseo_content_meta .wpms-form-table .wp-list-table tbody > tr td:nth-child(3),
751
  letter-spacing: 2px;
752
  color: #394857;
753
  margin: 20px 0 !important;
754
+ display: block !important;
755
  }
756
 
757
  .wpms-top-h2 {
assets/css/metabox-tabs.css CHANGED
@@ -140,12 +140,6 @@
140
  vertical-align: top;
141
  }
142
 
143
- .wpms-mouseover-frame {
144
- border-color: #007cba;
145
- box-shadow: 0 0 0 1px #007cba;
146
- outline: 2px solid transparent;
147
- }
148
-
149
  #wpmseosnippet .metabox-snippet-title {
150
  margin-bottom: 5px;
151
  }
@@ -159,7 +153,7 @@
159
  #wpmseosnippet .metabox-snippet-title input,
160
  #wpmseosnippet .metabox-snippet-description textarea
161
  {
162
- border: none;
163
  }
164
 
165
  #metaseo_wpmseo_keywords:focus,
@@ -243,7 +237,6 @@
243
  box-shadow: 0 0 0 1px #007cba;
244
  outline: 2px solid transparent;
245
  }
246
-
247
  #wpmseosnippet .desc {
248
  font-size: 14px;
249
  line-height: 1.4;
@@ -995,7 +988,7 @@ input.obtain{
995
  flex: 0 0 100%;
996
  }
997
 
998
- .wpmseo-metabox-tabs-div ul.wpmseo-metabox-tabs li.wpmstab a.active{
999
  background-color: #ff8726 !important;
1000
  color: #fff !important;
1001
  }
@@ -1078,4 +1071,7 @@ input.obtain{
1078
  .metaseo-tippy {
1079
  min-width: 100px !important;
1080
  }
 
 
 
1081
  }
140
  vertical-align: top;
141
  }
142
 
 
 
 
 
 
 
143
  #wpmseosnippet .metabox-snippet-title {
144
  margin-bottom: 5px;
145
  }
153
  #wpmseosnippet .metabox-snippet-title input,
154
  #wpmseosnippet .metabox-snippet-description textarea
155
  {
156
+ border: 1px solid #EEE;
157
  }
158
 
159
  #metaseo_wpmseo_keywords:focus,
237
  box-shadow: 0 0 0 1px #007cba;
238
  outline: 2px solid transparent;
239
  }
 
240
  #wpmseosnippet .desc {
241
  font-size: 14px;
242
  line-height: 1.4;
988
  flex: 0 0 100%;
989
  }
990
 
991
+ .wpmseo-metabox-tabs-div ul.wpmseo-metabox-tabs li.wpmstab a.active:not(#wpms-metabox-on-elementor .wpmseo-metabox-tabs-div ul.wpmseo-metabox-tabs li.wpmstab a.active){
992
  background-color: #ff8726 !important;
993
  color: #fff !important;
994
  }
1071
  .metaseo-tippy {
1072
  min-width: 100px !important;
1073
  }
1074
+ }
1075
+ .icon-mousedown {
1076
+ color: #0f8c0dc4;
1077
  }
assets/css/metaseo-category-meta-bulk.css ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpms-category-title {
2
+ height: 32px;
3
+ margin-bottom: 4px;
4
+ }
5
+ .wpms-category-title .wpms-category-title-input {
6
+ height: 32px !important;
7
+ line-height: 32px !important;
8
+ color: #1a0dab !important;
9
+ width: 100% !important;
10
+ }
11
+ .wpms-category-title input[type="text"]::placeholder,
12
+ .wpms-category-desc textarea::placeholder {
13
+ opacity: 0.6;
14
+ }
15
+ .wpms-category-desc textarea {
16
+ height: 100%;
17
+ padding-right: 68px !important;
18
+ padding-left: 10px;
19
+ font-weight: normal !important;
20
+ width: 100% !important;
21
+ }
22
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wpms-category-title .wpms-category-title-input,
23
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wpms-category-desc .wpms-category-desc-textarea{
24
+ opacity: 1 !important;
25
+ border: 1px solid #EEE !important;
26
+ }
27
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wpms-category-title .wpms-category-title-input:hover {
28
+ border-color: #2271b1;
29
+ box-shadow: 0 0 0 1px #2271b1;
30
+ outline: 2px solid transparent;
31
+ }
32
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wpms-category-title .wpms-category-title-input {
33
+ font-size: 20px !important;
34
+ }
35
+
36
+ .wpms-cat-title-len {
37
+ height: 32px !important;
38
+ line-height: 32px!important;
39
+ }
40
+ .wpms-cat-desc-len {
41
+ height: 45px !important;
42
+ line-height: 45px !important;
43
+ }
44
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wp-list-table tbody > tr td:nth-child(3),
45
+ .wp-meta-seo_page_metaseo_category_meta .wpms-form-table .wp-list-table tbody > tr th:nth-child(3){
46
+ padding: 5px 10px;
47
+ }
48
+ .snippet_metalink {
49
+ display: inline-block;
50
+ width: 100%;
51
+ }
assets/css/metaseo_admin.css CHANGED
@@ -30,10 +30,6 @@ and open the template in the editor.
30
  width: 10%;
31
  }
32
 
33
- .metaseo_post_follow, .metaseo_post_index {
34
- margin-top: 20px !important;
35
- }
36
-
37
  .title-len, .desc-len, .word-exceed, .keywords-len {
38
  min-width: 15px;
39
  text-align: center;
@@ -878,12 +874,16 @@ span.wpms-seoImgRemove {
878
 
879
  .custom-bulk-metaseo-metatitle,
880
  .custom-bulk-metaseo-metadesc{
881
- border: none !important;
882
- box-shadow: none;
883
- outline: none;
884
  opacity: 1 !important;
 
 
 
 
 
 
885
  }
886
 
 
887
  .custom-bulk-metaseo-metatitle::placeholder,
888
  .custom-bulk-metaseo-metadesc::placeholder {
889
  opacity: 0.5;
@@ -945,11 +945,12 @@ span.wpms-seoImgRemove {
945
 
946
 
947
  .wpms-mouseover-frame {
948
- border-color: #007cba !important;
949
- box-shadow: 0 0 0 1px #007cba !important;
950
  outline: 2px solid transparent;
951
  }
952
 
 
953
  @media screen and (max-width: 782px) {
954
  #col_image_name, .col_image_name.column-col_image_name,
955
  #col_image_title, .col_image_title.column-col_image_title,
30
  width: 10%;
31
  }
32
 
 
 
 
 
33
  .title-len, .desc-len, .word-exceed, .keywords-len {
34
  min-width: 15px;
35
  text-align: center;
874
 
875
  .custom-bulk-metaseo-metatitle,
876
  .custom-bulk-metaseo-metadesc{
 
 
 
877
  opacity: 1 !important;
878
+ border: 1px solid #EEE !important;
879
+ }
880
+ .custom-bulk-metaseo-metatitle:hover {
881
+ border-color: #2271b1;
882
+ box-shadow: 0 0 0 1px #2271b1;
883
+ outline: 2px solid transparent;
884
  }
885
 
886
+
887
  .custom-bulk-metaseo-metatitle::placeholder,
888
  .custom-bulk-metaseo-metadesc::placeholder {
889
  opacity: 0.5;
945
 
946
 
947
  .wpms-mouseover-frame {
948
+ border-color: #2271b1;
949
+ box-shadow: 0 0 0 1px #2271b1;
950
  outline: 2px solid transparent;
951
  }
952
 
953
+
954
  @media screen and (max-width: 782px) {
955
  #col_image_name, .col_image_name.column-col_image_name,
956
  #col_image_title, .col_image_title.column-col_image_title,
assets/css/metaseo_sitemap.css CHANGED
@@ -65,6 +65,7 @@
65
  color: #394857;
66
  margin: 30px 0;
67
  text-transform: capitalize;
 
68
  }
69
 
70
  .wpms_source_menu , .wpms_source_posts , .wpms_source_pages{
65
  color: #394857;
66
  margin: 30px 0;
67
  text-transform: capitalize;
68
+ display: block !important;
69
  }
70
 
71
  .wpms_source_menu , .wpms_source_posts , .wpms_source_pages{
assets/images/spinner.gif ADDED
Binary file
assets/js/elementor/cliffpyles.js ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var elementorTitle = '';
2
+ var elementorContent = '';
3
+ jQuery(document).ready(function ($) {
4
+ var mcheck = 0;
5
+ if (typeof wpmscliffpyles !== 'undefined' && typeof wpmscliffpyles.use_validate !== "undefined" && parseInt(wpmscliffpyles.use_validate) === 1) {
6
+ wpms_validate_analysis();
7
+ }
8
+
9
+ function reload_analysis(first_load) {
10
+ var mpageurl = '', current_editor = '';
11
+ var meta_title = $('#metaseo_wpmseo_title').val();
12
+ var meta_desc = $('#metaseo_wpmseo_desc').val();
13
+ var seo_keywords = $("input#metaseo_wpmseo_specific_keywords").val();
14
+
15
+ mpageurl = location.protocol + $('#wpmseosnippet').find('a').text();
16
+ elementorTitle = document.title;
17
+ if (typeof elementorTitle !== 'undefined' && elementorTitle.length) {
18
+ elementorTitle = elementorTitle.replace("Elementor |", "");
19
+ elementorTitle = elementorTitle.trim();
20
+ }
21
+ if (meta_title === '') meta_title = elementorTitle;
22
+
23
+ // get content html from elementor frontend
24
+ elementorContent = elementor.$previewElementorEl.html();
25
+
26
+ $('#wpms-elementor-spinner-gif').css({'display': 'flex'});
27
+ $('.metaseo_right .panel-left, .metaseo_right .panel-right').html('');
28
+ $.ajax({
29
+ dataType: 'json',
30
+ method: 'POST',
31
+ url: ajaxurl,
32
+ data: {
33
+ 'action': 'wpms',
34
+ 'task': 'reload_analysis',
35
+ 'datas': {
36
+ 'editor': current_editor,
37
+ 'first_load': first_load,
38
+ 'post_id': jQuery('.metaseo-progress-bar').data('post_id'),
39
+ 'title': elementorTitle,
40
+ 'meta_title': meta_title,
41
+ 'mpageurl': mpageurl,
42
+ 'meta_desc': meta_desc,
43
+ 'content': elementorContent,
44
+ 'seo_keywords': seo_keywords
45
+ },
46
+ 'wpms_nonce': wpmscliffpyles.wpms_nonce
47
+ },
48
+ success: function (res) {
49
+ if (res) {
50
+ $('#wpms-elementor-spinner-gif').css({'display': 'none'});
51
+ $('.metaseo_right .panel-left').html(res.output);
52
+ $('.metaseo_right .panel-right').html(res.right_output);
53
+ mcheck = parseInt(res.check);
54
+ tippy('.metaseo_tool', {
55
+ animation: 'scale',
56
+ duration: 0,
57
+ arrow: false,
58
+ placement: 'top',
59
+ theme: 'metaseo-tippy tippy-rounded',
60
+ onShow(instance) {
61
+ instance.popper.hidden = instance.reference.dataset.tippy ? false : true;
62
+ instance.setContent(instance.reference.dataset.tippy);
63
+ }
64
+ });
65
+
66
+ drawInactive(res.circliful);
67
+
68
+ }
69
+ }
70
+ });
71
+ }
72
+
73
+ // init load analysis
74
+ $(document).on('click', '#wpms-onelementor-tab', function (e) {
75
+ reload_analysis(1);
76
+ })
77
+ .on('click', '#reload_analysis', function (e) {
78
+ reload_analysis(0); // reload when click reload button
79
+ });
80
+
81
+ function drawInactive(circliful) {
82
+ $('.metaseo-progress-bar').circleProgress({
83
+ value: circliful / 100,
84
+ size: 250,
85
+ thickness: 8,
86
+ fill: {
87
+ gradient: ["#34e0ff", "#5dadff"]
88
+ }
89
+ }).on('circle-animation-progress', function (event, progress) {
90
+ $(this).find('strong').html(Math.round(circliful) + '<i>%</i>');
91
+ });
92
+ }
93
+
94
+ function wpms_validate_analysis() {
95
+ jQuery(document).on('click', '.metaseo-dashicons.icons-mboxwarning', function () {
96
+ var seo_keywords = $("input#metaseo_wpmseo_specific_keywords").val();
97
+ var $this = $(this);
98
+ $this.html('done').removeClass('icons-mboxwarning').addClass('icons-mboxdone');
99
+ if (mcheck === 0) {
100
+ mcheck = jQuery('#metaseo_alanysis_ok').val();
101
+ mcheck++;
102
+ } else {
103
+ mcheck++;
104
+ }
105
+
106
+ var total = 7;
107
+ if (seo_keywords !== '') {
108
+ total++;
109
+ }
110
+
111
+ var circliful = Math.ceil((mcheck * 100) / total);
112
+ jQuery.ajax({
113
+ dataType: 'json',
114
+ method: 'POST',
115
+ url: ajaxurl,
116
+ data: {
117
+ 'action': 'wpms',
118
+ 'task': 'validate_analysis',
119
+ 'post_id': jQuery('.metaseo-progress-bar').data('post_id'),
120
+ 'field': $this.parent('.metaseo_analysis').data('title'),
121
+ 'wpms_nonce': wpms_localize.wpms_nonce
122
+ },
123
+ success: function (res) {
124
+ if (res !== false) {
125
+ drawInactive(circliful);
126
+ }
127
+ }
128
+ });
129
+
130
+ });
131
+ }
132
+ });
assets/js/elementor/wpms-elementor.js ADDED
@@ -0,0 +1,635 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function ($) {
2
+ // This is short syntax for (function($) {} (jQuery);
3
+
4
+ var tmpData = [];
5
+ $(document).ready(function () {
6
+ $(document).on('input', '#metaseo_wpmseo_desc', function () {
7
+ this.style.width = this.value.length + "ch";
8
+ });
9
+ $('.metabox-snippet-title .container-snippet .input').on('input', function () {
10
+ $('.metabox-snippet-title .container-snippet .text').text($(this).val());
11
+ }).trigger('input');
12
+ });
13
+
14
+ var replacedVars = []; // jshint ignore:line
15
+ var wpmsdivtitle = '';
16
+
17
+ // load js for element when Meta Seo tab active
18
+ function initMetaboxEvent() {
19
+ // title
20
+ wpmsdivtitle = '.entry-title';
21
+
22
+ $.fn.focusTextToEnd = function () {
23
+ this.focus();
24
+ var $thisVal = this.val();
25
+ this.val('').val($thisVal);
26
+ return this;
27
+ }
28
+
29
+ $('.snippet-preview').on('click', function (e) {
30
+ e.preventDefault();
31
+ });
32
+
33
+ $('#metaseo_snippet_title').on('focus', function () {
34
+ $(this).hide();
35
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'title').removeAttr('type').focusTextToEnd();
36
+ });
37
+
38
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'title').on('focusout', function () {
39
+ $(this).attr('type', 'hidden');
40
+ $('#metaseo_snippet_title').show();
41
+ });
42
+
43
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'title').keyup(function () {
44
+ msUpdateTitle();
45
+ });
46
+
47
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'keywords').keyup(function () {
48
+ msUpdateKeywords();
49
+ });
50
+
51
+ $('body').on('keyup', wpmsdivtitle, function (event) {
52
+ msUpdateTitle();
53
+ msUpdateDesc();
54
+ });
55
+
56
+ // DON'T 'optimize' this to use descElm! descElm might not be defined and will cause js errors (Soliloquy issue)
57
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'desc').keyup(function () {
58
+ msUpdateDesc();
59
+ });
60
+
61
+ // Set time out because of tinymce is initialized later then this is done
62
+ setTimeout(
63
+ function () {
64
+ msUpdateSnippet();
65
+
66
+ // Adding events to content and excerpt
67
+ if (typeof tinyMCE !== 'undefined' && tinyMCE.get('content') !== null) {
68
+ tinyMCE.get('content').on('blur', msUpdateDesc);
69
+ }
70
+
71
+ if (typeof tinyMCE !== 'undefined' && tinyMCE.get('excerpt') !== null) {
72
+ tinyMCE.get('excerpt').on('blur', msUpdateDesc);
73
+ }
74
+ },
75
+ 500
76
+ );
77
+
78
+ tippy('.metaseo_tool, .metaseo_help', {
79
+ animation: 'scale',
80
+ duration: 0,
81
+ arrow: false,
82
+ placement: 'top',
83
+ theme: 'metaseo-tippy tippy-rounded',
84
+ onShow(instance) {
85
+ instance.popper.hidden = instance.reference.dataset.tippy ? false : true;
86
+ instance.setContent(instance.reference.dataset.tippy);
87
+ }
88
+ });
89
+
90
+ $('#metaseo_wpmseo_title, #metaseo_wpmseo_desc, #metaseo_snippet_title').on('mouseover', function () {
91
+ $(this).addClass('wpms-mouseover-frame ');
92
+ }).on('mouseout', function () {
93
+ $(this).removeClass('wpms-mouseover-frame ');
94
+ });
95
+ }
96
+
97
+ // Save Meta box data
98
+ var onChangeWpms = false;
99
+ var uploadImg = '#metaseo_wpmseo_twitter-image_button, #metaseo_wpmseo_opengraph-image_button';
100
+
101
+ $(document).on("click", ".editor-post-permalink-editor__save", function () {
102
+ var url;
103
+ if ($('.editor-post-permalink-editor__edit').length) {
104
+ var slug = $('.editor-post-permalink-editor__edit').val();
105
+ url = wpmseoMetaboxL10n.wpmseo_permalink_template.replace('%postname%', slug).replace('http://', '');
106
+ }
107
+
108
+ $('#wpmseosnippet').find('.url').html(url);
109
+ })
110
+ .on("keypress", ".editor-post-permalink-editor__edit", function (e) {
111
+ if (e.which === 13) {
112
+ var slug = $(this).val();
113
+ var url = wpmseoMetaboxL10n.wpmseo_permalink_template.replace('%postname%', slug).replace('http://', '');
114
+ $('#wpmseosnippet').find('.url').html(url);
115
+ }
116
+ })
117
+
118
+ // On change WPMS element on Elementor
119
+
120
+ .on('keyup', '#metaseo_wpmseo_title, #metaseo_wpmseo_desc', function () {
121
+ onChangeWpms = true;
122
+ tmpData['title'] = $('#metaseo_wpmseo_title').val();
123
+ tmpData['desc'] = $('#metaseo_wpmseo_desc').val();
124
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
125
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
126
+ })
127
+ .on('itemAdded itemRemoved', '#metaseo_wpmseo_specific_keywords', function () {
128
+ onChangeWpms = true;
129
+ tmpData['keyword'] = $('#metaseo_wpmseo_specific_keywords').tagsinput('items').join(', ');
130
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
131
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
132
+ })
133
+ .on('keyup', '#metaseo_wpmseo_keywords', function () {
134
+ onChangeWpms = true;
135
+ tmpData['sEKeyword'] = $('#metaseo_wpmseo_keywords').val();
136
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
137
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
138
+ })
139
+ .on('keyup', '#metaseo_wpmseo_metaseo_canonical', function () {
140
+ onChangeWpms = true;
141
+ tmpData['canonicalUrl'] = $('#metaseo_wpmseo_metaseo_canonical').val();
142
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
143
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
144
+ })
145
+ .on('keyup', '#metaseo_wpmseo_opengraph-title', function () {
146
+ onChangeWpms = true;
147
+ tmpData['fbTitle'] = $('#metaseo_wpmseo_opengraph-title').val();
148
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
149
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
150
+ })
151
+ .on('keyup', '#metaseo_wpmseo_opengraph-desc', function () {
152
+ onChangeWpms = true;
153
+ tmpData['fbDesc'] = $('#metaseo_wpmseo_opengraph-desc').val();
154
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
155
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
156
+ })
157
+ .on('keyup', '#metaseo_wpmseo_opengraph-image', function () {
158
+ onChangeWpms = true;
159
+ tmpData['fbImg'] = $('#metaseo_wpmseo_opengraph-image').val();
160
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
161
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
162
+ })
163
+ .on('keyup', '#metaseo_wpmseo_twitter-title', function () {
164
+ onChangeWpms = true;
165
+ tmpData['twTitle'] = $('#metaseo_wpmseo_twitter-title').val();
166
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
167
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
168
+ })
169
+ .on('keyup', '#metaseo_wpmseo_twitter-desc', function () {
170
+ onChangeWpms = true;
171
+ tmpData['twDesc'] = $('#metaseo_wpmseo_twitter-desc').val();
172
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
173
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
174
+ })
175
+ .on('keyup', '#metaseo_wpmseo_twitter-image', function () {
176
+ onChangeWpms = true;
177
+ tmpData['fbImg'] = $('#metaseo_wpmseo_opengraph-image').val();
178
+ tmpData['twImg'] = $('#metaseo_wpmseo_twitter-image').val();
179
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
180
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
181
+ })
182
+ .on('click', uploadImg, function () {
183
+ onChangeWpms = true;
184
+ $('#elementor-panel-saver-button-publish').removeClass('elementor-disabled');
185
+ $('#elementor-panel-saver-button-save-options').removeClass('elementor-disabled');
186
+ });
187
+
188
+ $(document).on('click', '#elementor-panel-saver-button-publish', function () {
189
+ if (onChangeWpms) {
190
+ // call ajax to save post
191
+ const postID = parseInt($('#wpms-metabox-on-elementor .metaseo-progress-bar').data('post_id'));
192
+ // get data from metabox on elementor to save
193
+ let title, desc, keyword, sEKeyword, canonicalUrl, fTitle, fDesc, fImage, tTitle, tDesc,
194
+ tImage, scoreProgress;
195
+ title = $('#metaseo_wpmseo_title').val();
196
+ desc = $('#metaseo_wpmseo_desc').val();
197
+ keyword = $('#metaseo_wpmseo_specific_keywords').tagsinput('items');
198
+ keyword = keyword.join(', ');
199
+ sEKeyword = $('#metaseo_wpmseo_keywords').val();
200
+ canonicalUrl = $('#metaseo_wpmseo_metaseo_canonical').val();
201
+ fTitle = $('#metaseo_wpmseo_opengraph-title').val();
202
+ fDesc = $('#metaseo_wpmseo_opengraph-desc').val();
203
+ fImage = $('#metaseo_wpmseo_opengraph-image').val();
204
+ tTitle = $('#metaseo_wpmseo_twitter-title').val();
205
+ tDesc = $('#metaseo_wpmseo_twitter-desc').val();
206
+ tImage = $('#metaseo_wpmseo_twitter-image').val();
207
+ scoreProgress = $('#wpmetaseo_seo_keywords_result').val();
208
+ var datas = {
209
+ 'title': title,
210
+ 'desc': desc,
211
+ 'specific_keywords': keyword,
212
+ 'keywords': sEKeyword,
213
+ 'metaseo_canonical': canonicalUrl,
214
+ 'opengraph-title': fTitle,
215
+ 'opengraph-desc': fDesc,
216
+ 'opengraph-image': fImage,
217
+ 'twitter-title': tTitle,
218
+ 'twitter-desc': tDesc,
219
+ 'twitter-image': tImage,
220
+ 'wp_metaseo_seoscore': scoreProgress
221
+ };
222
+ $.ajax({
223
+ dataType: 'json',
224
+ method: 'POST',
225
+ url: ajaxurl,
226
+ data: {
227
+ 'action': 'wpms',
228
+ 'task': 'wpmsElementorSavePost',
229
+ 'elementorPostID': postID,
230
+ 'wpms_nonce': wpmseoMetaboxL10n.wpms_nonce,
231
+ 'datas': datas
232
+ },
233
+ success: function (res) {
234
+ if (res) {
235
+ }
236
+ }
237
+ });
238
+ }
239
+ });
240
+
241
+ // Active Meta SEO tab
242
+
243
+ $(document).on('click', '#wpms-onelementor-tab', function (e) {
244
+ $('#elementor-panel-elements-navigation .elementor-panel-navigation-tab').removeClass('elementor-active');
245
+ $('#wpms-onelementor-tab').addClass('elementor-active');
246
+
247
+ $('#elementor-panel-elements-search-area').hide();
248
+ $('#elementor-panel-elements-wrapper').hide();
249
+ $('#wpms-metabox-on-elementor').show();
250
+
251
+ // Active SEO page optimation
252
+ $('#elementor-wpms-general').addClass('active');
253
+ $('#elementor-wpms-social').removeClass('active');
254
+ $('#wpmseo_general').show();
255
+ $('#wpmseo_social').hide();
256
+
257
+ // Call js after meta seo tab ready
258
+ if (typeof tmpData['title'] !== 'undefined') {
259
+ $('#metaseo_wpmseo_title').val(tmpData['title']);
260
+ }
261
+ if (typeof tmpData['desc'] !== 'undefined') {
262
+ $('#metaseo_wpmseo_desc').val(tmpData['desc']);
263
+ }
264
+ if (typeof tmpData['keyword'] !== 'undefined') {
265
+ $('#metaseo_wpmseo_specific_keywords').val(tmpData['keyword']);
266
+ }
267
+ if (typeof tmpData['fbTitle'] !== 'undefined') {
268
+ $('#metaseo_wpmseo_opengraph-title').val(tmpData['fbTitle']);
269
+ }
270
+ if (typeof tmpData['fbDesc'] !== 'undefined') {
271
+ $('#metaseo_wpmseo_opengraph-desc').val(tmpData['fbDesc']);
272
+ }
273
+ if (typeof tmpData['fbImg'] !== 'undefined') {
274
+ $('#metaseo_wpmseo_opengraph-image').val(tmpData['fbImg']);
275
+ }
276
+ if (typeof tmpData['twTitle'] !== 'undefined') {
277
+ $('#metaseo_wpmseo_twitter-title').val(tmpData['twTitle']);
278
+ }
279
+ if (typeof tmpData['twDesc'] !== 'undefined') {
280
+ $('#metaseo_wpmseo_twitter-desc').val(tmpData['twDesc']);
281
+ }
282
+ if (typeof tmpData['twImg'] !== 'undefined') {
283
+ $('#metaseo_wpmseo_twitter-image').val(tmpData['twImg']);
284
+ }
285
+ if (typeof tmpData['sEKeyword'] !== 'undefined') {
286
+ $('#metaseo_wpmseo_keywords').val(tmpData['sEKeyword']);
287
+ }
288
+ if (typeof tmpData['canonicalUrl'] !== 'undefined') {
289
+ $('#metaseo_wpmseo_metaseo_canonical').val(tmpData['canonicalUrl']);
290
+ }
291
+
292
+ initMetaboxEvent();
293
+ })
294
+ .on('click', '#elementor-panel-elements-navigation .elementor-panel-navigation-tab:not(#wpms-onelementor-tab)', function (e) {
295
+ $('#wpms-onelementor-tab').removeClass('elementor-active');
296
+ $(this).addClass('elementor-active');
297
+
298
+ $('#elementor-panel-elements-search-area').show();
299
+ $('#elementor-panel-elements-wrapper').show();
300
+ $('#wpms-metabox-on-elementor').hide();
301
+ })
302
+
303
+ // Active SEO page
304
+ .on('click', '#elementor-wpms-general', (e) => {
305
+ $('#elementor-wpms-social').removeClass('active');
306
+ $('#elementor-wpms-general').addClass('active');
307
+ $('#wpmseo_social').hide();
308
+ $('#wpmseo_general').show();
309
+ })
310
+ .on('click', '#elementor-wpms-social', (e) => {
311
+ $('#elementor-wpms-general').removeClass('active');
312
+ $('#elementor-wpms-social').addClass('active');
313
+ $('#wpmseo_general').hide();
314
+ $('#wpmseo_social').show();
315
+ })
316
+
317
+ // when change follow of post/page in metabox view
318
+ .on('change', '.metaseo_metabox_follow', function () {
319
+ const page_id = $(this).data('post_id');
320
+ const follow = $(this).val();
321
+ metaseo_update_pagefollow(page_id, follow);
322
+ })
323
+ .on('change', '.metaseo_metabox_index', function () {
324
+ const page_id = $(this).data('post_id');
325
+ const index = $(this).val();
326
+ metaseo_update_pageindex(page_id, index);
327
+ });
328
+
329
+ function msClean(str) {
330
+ if (str === '' || typeof (str) === 'undefined') {
331
+ return '';
332
+ }
333
+
334
+ try {
335
+ str = str.replace(/<\/?[^>]+>/gi, '');
336
+ str = str.replace(/\[(.+?)](.+?\[\/\\1])?/g, '');
337
+ str = $('<div/>').html(str).text();
338
+ } catch (e) {
339
+ }
340
+
341
+ return str;
342
+ }
343
+
344
+ function msReplaceVariables(str, callback) {
345
+ if (typeof str === 'undefined') {
346
+ return;
347
+ }
348
+ let titleReplace = document.title;
349
+ titleReplace = titleReplace.replace("Elementor |", "");
350
+ titleReplace = titleReplace.trim();
351
+ if (titleReplace.length) {
352
+ str = str.replace(/%title%/g, titleReplace.replace(/(<([^>]+)>)/ig, ''));
353
+ }
354
+
355
+ // These are added in the head for performance reasons.
356
+ str = str.replace(/%id%/g, wpmseoMetaboxL10n.id);
357
+ str = str.replace(/%date%/g, wpmseoMetaboxL10n.date);
358
+ str = str.replace(/%sitedesc%/g, wpmseoMetaboxL10n.sitedesc);
359
+ str = str.replace(/%sitename%/g, wpmseoMetaboxL10n.sitename);
360
+ str = str.replace(/%sep%/g, wpmseoMetaboxL10n.sep);
361
+ str = str.replace(/%page%/g, wpmseoMetaboxL10n.page);
362
+ str = str.replace(/%currenttime%/g, wpmseoMetaboxL10n.currenttime);
363
+ str = str.replace(/%currentdate%/g, wpmseoMetaboxL10n.currentdate);
364
+ str = str.replace(/%currentday%/g, wpmseoMetaboxL10n.currentday);
365
+ str = str.replace(/%currentmonth%/g, wpmseoMetaboxL10n.currentmonth);
366
+ str = str.replace(/%currentyear%/g, wpmseoMetaboxL10n.currentyear);
367
+
368
+ // excerpt
369
+ var excerpt = '';
370
+ if ($('#excerpt').length) {
371
+ excerpt = msClean($('#excerpt').val().replace(/(<([^>]+)>)/ig, ''));
372
+ str = str.replace(/%excerpt_only%/g, excerpt);
373
+ }
374
+ if ('' === excerpt && $('#content').length) {
375
+ excerpt = $('#content').val().replace(/(<([^>]+)>)/ig, '').substring(0, wpmseoMetaboxL10n.wpmseo_meta_desc_length - 1);
376
+ }
377
+ str = str.replace(/%excerpt%/g, excerpt);
378
+
379
+ // parent page
380
+ if ($('#parent_id').length && $('#parent_id option:selected').text() !== wpmseoMetaboxL10n.no_parent_text) {
381
+ str = str.replace(/%parent_title%/g, $('#parent_id option:selected').text());
382
+ }
383
+
384
+ // remove double separators
385
+ var esc_sep = msEscapeFocusKw(wpmseoMetaboxL10n.sep);
386
+ var pattern = new RegExp(esc_sep + ' ' + esc_sep, 'g');
387
+ str = str.replace(pattern, wpmseoMetaboxL10n.sep);
388
+
389
+ if (str.indexOf('%') !== -1 && str.match(/%[a-z0-9_-]+%/i) !== null) {
390
+ var regex = /%[a-z0-9_-]+%/gi;
391
+ var matches = str.match(regex);
392
+ for (var i = 0; i < matches.length; i++) {
393
+ if (typeof (replacedVars[matches[i]]) === 'undefined') {
394
+ str = str.replace(matches[i], replacedVars[matches[i]]);
395
+ } else {
396
+ var replaceableVar = matches[i];
397
+
398
+ // create the cache already, so we don't do the request twice.
399
+ replacedVars[replaceableVar] = '';
400
+ msAjaxReplaceVariables(replaceableVar, callback);
401
+ }
402
+ }
403
+ }
404
+ callback(str);
405
+ }
406
+
407
+ function msAjaxReplaceVariables(replaceableVar, callback) {
408
+ $.post(ajaxurl, {
409
+ action: 'wpmseo_replace_vars',
410
+ string: replaceableVar,
411
+ post_id: $('#post_ID').val(),
412
+ _wpnonce: wpmseoMetaboxL10n.wpmseo_replace_vars_nonce
413
+ }, function (data) {
414
+ if (data) {
415
+ replacedVars[replaceableVar] = data;
416
+ }
417
+
418
+ msReplaceVariables(replaceableVar, callback);
419
+ });
420
+ }
421
+
422
+ /*
423
+ * Change meta title in meta box
424
+ */
425
+ function msUpdateTitle(force) {
426
+ var title = '';
427
+ var titleElm = $('#' + wpmseoMetaboxL10n.field_prefix + 'title');
428
+ if (!titleElm.length) {
429
+ return;
430
+ }
431
+ var titleLengthError = $('#' + wpmseoMetaboxL10n.field_prefix + 'title-length-warning');
432
+ var divHtml = $('<div />');
433
+
434
+ if (titleElm.val()) {
435
+ title = titleElm.val().replace(/(<([^>]+)>)/ig, '');
436
+ } else if (wpmseoMetaboxL10n.metatitle_tab === '1') {
437
+ title = wpmseoMetaboxL10n.wpmseo_title_template;
438
+ title = divHtml.html(title).text();
439
+ }
440
+
441
+ if (title === '') {
442
+ var len = wpmseoMetaboxL10n.wpmseo_meta_title_length - $('#metaseo_snippet_title').val().length;
443
+ metaseo_status_length(len, '#' + wpmseoMetaboxL10n.field_prefix + 'title-length');
444
+
445
+ titleLengthError.hide();
446
+ return;
447
+ }
448
+
449
+ title = msClean(title);
450
+ title = divHtml.text(title).html();
451
+ if (force) {
452
+ titleElm.val(title);
453
+ }
454
+ msReplaceVariables(title, function (title) {
455
+ title = msSanitizeTitle(title);
456
+ // do the placeholder
457
+ var placeholder_title = divHtml.html(title).text();
458
+ if (typeof placeholder_title !== 'undefined' && placeholder_title !== 'undefined') {
459
+ $('#metaseo_snippet_title').val(placeholder_title);
460
+ }
461
+
462
+ var len = wpmseoMetaboxL10n.wpmseo_meta_title_length - $('#metaseo_snippet_title').val().length;
463
+ if ($('#metaseo_snippet_title').val() === '') {
464
+ var mtitle_template = wpmseoMetaboxL10n.wpmseo_title_template;
465
+ if ($(wpmsdivtitle).length) {
466
+ mtitle_template = mtitle_template.replace(/%title%/g, $(wpmsdivtitle).val().replace(/(<([^>]+)>)/ig, ''));
467
+ }
468
+ len = wpmseoMetaboxL10n.wpmseo_meta_title_length - mtitle_template.length;
469
+ }
470
+
471
+ metaseo_status_length(len, '#' + wpmseoMetaboxL10n.field_prefix + 'title-length');
472
+ });
473
+ }
474
+
475
+ /*
476
+ * Change meta keywords in meta box
477
+ */
478
+ function msUpdateKeywords() {
479
+ var keywordsElm = $('#' + wpmseoMetaboxL10n.field_prefix + 'keywords');
480
+ if (typeof keywordsElm.val() !== 'undefined' && keywordsElm.val() !== '') {
481
+ var len = wpmseoMetaboxL10n.wpmseo_meta_keywords_length - keywordsElm.val().length;
482
+ metaseo_status_length(len, '#' + wpmseoMetaboxL10n.field_prefix + 'keywords-length');
483
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'keywords-length').html(len);
484
+ } else {
485
+ $('#' + wpmseoMetaboxL10n.field_prefix + 'keywords-length').addClass('length-true').removeClass('length-wrong').html('<span class="good">' + wpmseoMetaboxL10n.wpmseo_meta_keywords_length + '</span>');
486
+ }
487
+ }
488
+
489
+ /*
490
+ * Clean title
491
+ */
492
+ function msSanitizeTitle(title) {
493
+ title = msClean(title);
494
+ return title;
495
+ }
496
+
497
+ /*
498
+ * Change meta description in meta box
499
+ */
500
+ function msUpdateDesc() {
501
+ var desc = (msClean($('#' + wpmseoMetaboxL10n.field_prefix + 'desc').val())).trim();
502
+ var divHtml = $('<div />');
503
+ var snippet = $('#wpmseosnippet');
504
+
505
+ if (desc === '' && wpmseoMetaboxL10n.wpmseo_desc_template !== '') {
506
+ desc = wpmseoMetaboxL10n.wpmseo_desc_template;
507
+ }
508
+
509
+ if (desc !== '') {
510
+ msReplaceVariables(desc, function (desc) {
511
+ desc = divHtml.text(desc).html();
512
+ desc = msClean(desc);
513
+
514
+ var len = wpmseoMetaboxL10n.wpmseo_meta_desc_length - desc.length;
515
+ metaseo_status_length(len, '#' + wpmseoMetaboxL10n.field_prefix + 'desc-length');
516
+ desc = msSanitizeDesc(desc);
517
+
518
+ // Clear the autogen description.
519
+ snippet.find('.desc span.autogen').html('');
520
+ // Set our new one.
521
+ });
522
+ } else {
523
+ var len = wpmseoMetaboxL10n.wpmseo_meta_desc_length;
524
+ metaseo_status_length(len, '#' + wpmseoMetaboxL10n.field_prefix + 'desc-length');
525
+ }
526
+ }
527
+
528
+ /*
529
+ * Sanitize description
530
+ */
531
+ function msSanitizeDesc(desc) {
532
+ desc = msTrimDesc(desc);
533
+ return desc;
534
+ }
535
+
536
+ function msTrimDesc(desc) {
537
+ if (desc.length > wpmseoMetaboxL10n.wpmseo_meta_desc_length) {
538
+ var space;
539
+ if (desc.length > wpmseoMetaboxL10n.wpmseo_meta_desc_length) {
540
+ space = desc.lastIndexOf(' ', (wpmseoMetaboxL10n.wpmseo_meta_desc_length - 3));
541
+ } else {
542
+ space = wpmseoMetaboxL10n.wpmseo_meta_desc_length;
543
+ }
544
+ desc = desc.substring(0, space).concat(' ...');
545
+ }
546
+ return desc;
547
+ }
548
+
549
+ /*
550
+ * Update Url
551
+ */
552
+ function msUpdateURL() {
553
+ var url;
554
+ if ($('#editable-post-name-full').length) {
555
+ var name = $('#editable-post-name-full').text();
556
+ url = wpmseoMetaboxL10n.wpmseo_permalink_template.replace('%postname%', name).replace('http://', '');
557
+ }
558
+
559
+ $('#wpmseosnippet').find('.url').html(url);
560
+ }
561
+
562
+ function msUpdateSnippet() {
563
+ if (typeof wpmseoMetaboxL10n.show_keywords !== "undefined" && parseInt(wpmseoMetaboxL10n.show_keywords) === 1) {
564
+ msUpdateKeywords();
565
+ }
566
+ msUpdateURL();
567
+ msUpdateTitle();
568
+ msUpdateDesc();
569
+ }
570
+
571
+ function msEscapeFocusKw(str) {
572
+ return str.replace(/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
573
+ }
574
+
575
+ function metaseo_status_length(len, id, number) {
576
+ var num = 46;
577
+ var check = 0;
578
+ var mclass = '';
579
+ if (id === '#metaseo_wpmseo_title-length') {
580
+ num = 50;
581
+ check = wpmseoMetaboxL10n.wpmseo_meta_title_length - len;
582
+ mclass = 'word-74B6FC';
583
+ } else if (id === '#metaseo_wpmseo_desc-length') {
584
+ num = 120;
585
+ check = wpmseoMetaboxL10n.wpmseo_meta_desc_length - len;
586
+ mclass = 'word-74B6FC';
587
+ } else if (id === '#metaseo_wpmseo_keywords-length') {
588
+ num = 120;
589
+ check = len;
590
+ }
591
+
592
+ if (len < 0) {
593
+ $(id).addClass('length-wrong').removeClass('length-true length-warn ' + mclass);
594
+ len = '<span class="wrong">' + len + '</span>';
595
+ } else if (check >= 0 && check <= num) {
596
+ $(id).addClass('length-warn ' + mclass).removeClass('length-true length-wrong');
597
+ len = '<span class="length-warn ' + mclass + '">' + len + '</span>';
598
+ } else {
599
+ $(id).addClass('length-true').removeClass('length-wrong length-warn ' + mclass);
600
+ len = '<span class="good">' + len + '</span>';
601
+ }
602
+
603
+ $(id).html(len);
604
+ }
605
+
606
+ function metaseo_update_pagefollow(page_id, follow) {
607
+ $.ajax({
608
+ url: ajaxurl,
609
+ method: 'POST',
610
+ dataType: 'json',
611
+ data: {
612
+ 'action': 'wpms',
613
+ 'task': 'update_pagefollow',
614
+ 'page_id': page_id,
615
+ 'follow': follow,
616
+ 'wpms_nonce': wpmseoMetaboxL10n.wpms_nonce
617
+ }
618
+ });
619
+ }
620
+
621
+ function metaseo_update_pageindex(page_id, index) {
622
+ $.ajax({
623
+ url: ajaxurl,
624
+ method: 'POST',
625
+ dataType: 'json',
626
+ data: {
627
+ 'action': 'wpms',
628
+ 'task': 'update_pageindex',
629
+ 'page_id': page_id,
630
+ 'index': index,
631
+ 'wpms_nonce': wpmseoMetaboxL10n.wpms_nonce
632
+ }
633
+ });
634
+ }
635
+ });
assets/js/elementor/wpms-media.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 'use strict';
2
+ var wpmseo_target_id;
3
+ jQuery(document).on('click', '#wpms-onelementor-tab', function (e) {
4
+ var wpmseo_uploader;
5
+ jQuery('.wpmseo_image_upload_button').on('click', function (e) {
6
+ wpmseo_target_id = jQuery(this).attr('id').replace(/_button$/, '');
7
+ e.preventDefault();
8
+ if (wpmseo_uploader) {
9
+ wpmseo_uploader.open();
10
+ return;
11
+ }
12
+ wpmseo_uploader = wp.media.frames.file_frame = wp.media({
13
+ title: wpmseoMediaL10n.choose_image,
14
+ button: {text: wpmseoMediaL10n.choose_image},
15
+ multiple: false
16
+ });
17
+
18
+ wpmseo_uploader.on('select', function () {
19
+ var attachment = wpmseo_uploader.state().get('selection').first().toJSON();
20
+ jQuery('#' + wpmseo_target_id).val(attachment.url);
21
+ wpmseo_uploader.close();
22
+ });
23
+
24
+ wpmseo_uploader.open();
25
+ });
26
+ });
assets/js/elementor/wpms-seokeyword-metabox.js ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var elmContent = '';
2
+ var elmTitle = '';
3
+ (function (wpData, $) {
4
+ const {select, subscribe} = wpData;
5
+
6
+ class wpmsSpecificKeywords {
7
+ constructor() {
8
+ this.title = null;
9
+ this.content = null;
10
+ this.tagsElement = $('#metaseo_wpmseo_specific_keywords');
11
+ this.metaTitleElement = $('#metaseo_wpmseo_title');
12
+ this.metaDescElement = $('#metaseo_wpmseo_desc');
13
+ this.listTags = [];
14
+ this.resultAnalytics = null;
15
+ }
16
+
17
+ init = () => {
18
+ // Get editor title
19
+ if (typeof elmTitle !== 'undefined') {
20
+ this.title = elmTitle;
21
+ }
22
+ // Get editor content
23
+ if (typeof elmContent !== 'undefined') {
24
+ this.content = elmContent;
25
+ }
26
+
27
+ this.bindEvents();
28
+ this.tagsElement.on('itemAdded itemRemoved', this.bindEvents);
29
+ this.metaTitleElement.on('keyup', this.bindEvents);
30
+ this.metaDescElement.on('keyup', this.bindEvents);
31
+ }
32
+
33
+ bindEvents = () => {
34
+ this.listTags = this.tagsElement.tagsinput('items');
35
+ if (typeof this.listTags !== 'undefined' && typeof this.listTags.itemsArray !== 'undefined' && this.listTags.itemsArray !== '') {
36
+ this.listTags = this.listTags.itemsArray;
37
+ }
38
+
39
+ this.analytics();
40
+ }
41
+
42
+ analytics = () => {
43
+ this.resultAnalytics = {
44
+ keyInTitle: this.collectKeywordsInTitle(),
45
+ keyInContent: this.collectKeywordsInContent(),
46
+ keyInContentHeading: this.collectKeywordsInHeading(),
47
+ keyInMetaTitle: this.collectKeywordsInMetaTitle(),
48
+ keyInMetaDescription: this.collectKeywordsInMetaDesc()
49
+ }
50
+
51
+ if (this.resultAnalytics !== null) {
52
+ let discovered = false;
53
+ Object.entries(this.resultAnalytics).forEach(entry => {
54
+ const [key, value] = entry;
55
+ if (value) discovered = true;
56
+ this.changeAnalyticsInfo(key, value);
57
+ });
58
+
59
+ this.editAnalyticsInfo(discovered);
60
+ }
61
+ }
62
+
63
+ editAnalyticsInfo = (discovered) => {
64
+ const seo_keywords = $("input#metaseo_wpmseo_specific_keywords").val();
65
+ if (seo_keywords === '') {
66
+ $('div.metaseo_analysis[data-title="seokeyword"]').hide();
67
+ $('.seokeyword-information').hide();
68
+ $('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(0);
69
+ this.reDrawInactive(7);
70
+ return false;
71
+ } else {
72
+ $('div.metaseo_analysis[data-title="seokeyword"]').show();
73
+ $('.seokeyword-information').show();
74
+ }
75
+
76
+ if (!discovered) {
77
+ $('div.metaseo_analysis[data-title="seokeyword"]').find('i').removeClass('icons-mboxdone').addClass('icons-mboxwarning').html('error_outline');
78
+ $('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(0);
79
+ } else {
80
+ $('div.metaseo_analysis[data-title="seokeyword"]').find('i').removeClass('icons-mboxwarning').addClass('icons-mboxdone').html('done');
81
+ $('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(1);
82
+ }
83
+
84
+ this.reDrawInactive(8);
85
+ }
86
+
87
+ reDrawInactive = (totalItems) => {
88
+ const analyticItems = $('.panel-left .wpms_analysis_hidden');
89
+ let mcheck = 0;
90
+
91
+ for (let i = 0; i < analyticItems.length; i++) {
92
+ if ($(analyticItems[i]).val() == 1) {
93
+ mcheck++;
94
+ }
95
+ }
96
+
97
+ const circliful = Math.ceil((mcheck * 100) / totalItems);
98
+
99
+ $('#wpmetaseo_seo_keywords_result').val(circliful);
100
+ $('.metaseo-progress-bar').circleProgress('value', circliful / 100).on('circle-animation-progress', function (event, progress) {
101
+ $(this).find('strong').html(circliful + '<i>%</i>');
102
+ });
103
+ }
104
+
105
+ // change material icon
106
+ changeAnalyticsInfo = (key, value) => {
107
+ if (value) {
108
+ $('div.metaseo_analysis[data-title="' + key.toLowerCase() + '"]').find('i').removeClass('icons-mboxwarning').addClass('icons-mboxdone').html('done');
109
+ $('input.wpms_analysis_hidden[name="wpms[' + key.toLowerCase() + ']"]').val(1);
110
+ } else {
111
+ $('div.metaseo_analysis[data-title="' + key.toLowerCase() + '"]').find('i').removeClass('icons-mboxdone').addClass('icons-mboxwarning').html('error_outline');
112
+ $('input.wpms_analysis_hidden[name="wpms[' + key.toLowerCase() + ']"]').val(0);
113
+ }
114
+ }
115
+
116
+ collectKeywordsInTitle = () => {
117
+ let title = {text: this.title,};
118
+ let isContain = false;
119
+ //alert(this.listTags);
120
+ if (this.listTags.length && title.text.length) {
121
+ this.listTags.forEach(function (item) {
122
+ if (title.text.toLowerCase().includes(item.toLowerCase().trim())) {
123
+ isContain = true;
124
+ return isContain;
125
+ }
126
+ });
127
+ }
128
+
129
+ return isContain;
130
+ }
131
+
132
+ collectKeywordsInContent = () => {
133
+ let content = {text: this.content};
134
+ let isContain = false;
135
+ if (this.listTags.length && content.text.length) {
136
+ this.listTags.forEach(function (item, index) {
137
+ if (content.text.toLowerCase().includes(item.toLowerCase().trim())) {
138
+ isContain = true;
139
+ return isContain;
140
+ }
141
+ });
142
+ }
143
+
144
+ return isContain;
145
+ }
146
+
147
+ collectKeywordsInHeading = () => {
148
+ let content = {text: this.content};
149
+ let isContain = false;
150
+ if (this.listTags.length && content.text.length) {
151
+ this.listTags.forEach(function (item, index) {
152
+ const regex = RegExp("<h[2-6][^>]*>.*" + item.toLowerCase().trim() + ".*</h[2-6]>", "gi");
153
+ if (content.text.toLowerCase().match(regex) != null) {
154
+ isContain = true;
155
+ return isContain;
156
+ }
157
+ });
158
+ }
159
+
160
+ return isContain;
161
+ }
162
+
163
+ collectKeywordsInMetaTitle = () => {
164
+ let metaTitle = {text: this.replaceVariables(this.metaTitleElement.val())};
165
+ let isContain = false;
166
+ if (this.listTags.length && metaTitle.text.length) {
167
+ this.listTags.forEach(function (item, index) {
168
+ if (metaTitle.text.toLowerCase().includes(item.toLowerCase().trim())) {
169
+ isContain = true;
170
+ return isContain;
171
+ }
172
+ });
173
+ }
174
+
175
+ return isContain;
176
+ }
177
+
178
+ collectKeywordsInMetaDesc = () => {
179
+ let metaDesc = {text: this.replaceVariables(this.metaDescElement.val())};
180
+ let isContain = false;
181
+ if (this.listTags.length && metaDesc.text.length) {
182
+ this.listTags.forEach(function (item, index) {
183
+ if (metaDesc.text.toLowerCase().includes(item.toLowerCase().trim())) {
184
+ isContain = true;
185
+ return isContain;
186
+ }
187
+ });
188
+ }
189
+
190
+ return isContain;
191
+ }
192
+
193
+ replaceVariables = (str) => {
194
+ if (typeof str === 'undefined') {
195
+ return;
196
+ }
197
+
198
+ if (this.title) {
199
+ str = str.replace(/%title%/g, this.title.replace(/(<([^>]+)>)/ig, ''));
200
+ }
201
+
202
+ // These are added in the head for performance reasons.
203
+ str = str.replace(/%id%/g, wpmseoMetaboxL10n.id);
204
+ str = str.replace(/%date%/g, wpmseoMetaboxL10n.date);
205
+ str = str.replace(/%sitedesc%/g, wpmseoMetaboxL10n.sitedesc);
206
+ str = str.replace(/%sitename%/g, wpmseoMetaboxL10n.sitename);
207
+ str = str.replace(/%sep%/g, wpmseoMetaboxL10n.sep);
208
+ str = str.replace(/%page%/g, wpmseoMetaboxL10n.page);
209
+ str = str.replace(/%currenttime%/g, wpmseoMetaboxL10n.currenttime);
210
+ str = str.replace(/%currentdate%/g, wpmseoMetaboxL10n.currentdate);
211
+ str = str.replace(/%currentday%/g, wpmseoMetaboxL10n.currentday);
212
+ str = str.replace(/%currentmonth%/g, wpmseoMetaboxL10n.currentmonth);
213
+ str = str.replace(/%currentyear%/g, wpmseoMetaboxL10n.currentyear);
214
+
215
+ // excerpt
216
+ let excerpt = '';
217
+ if (jQuery('#excerpt').length) {
218
+ excerpt = msClean(jQuery('#excerpt').val().replace(/(<([^>]+)>)/ig, ''));
219
+ str = str.replace(/%excerpt_only%/g, excerpt);
220
+ }
221
+
222
+ if ('' === excerpt && jQuery('#content').length) {
223
+ excerpt = jQuery('#content').val().replace(/(<([^>]+)>)/ig, '').substring(0, wpmseoMetaboxL10n.wpmseo_meta_desc_length - 1);
224
+ }
225
+ str = str.replace(/%excerpt%/g, excerpt);
226
+
227
+ // parent page
228
+ if (jQuery('#parent_id').length && jQuery('#parent_id option:selected').text() !== wpmseoMetaboxL10n.no_parent_text) {
229
+ str = str.replace(/%parent_title%/g, jQuery('#parent_id option:selected').text());
230
+ }
231
+
232
+ // remove double separators
233
+ const esc_sep = wpmseoMetaboxL10n.sep.replace(/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
234
+ const pattern = new RegExp(esc_sep + ' ' + esc_sep, 'g');
235
+ str = str.replace(pattern, wpmseoMetaboxL10n.sep);
236
+
237
+ return str;
238
+ }
239
+ }
240
+
241
+ $(document).ready(function () {
242
+ $(document).on('click', '#wpms-onelementor-tab', (e) => {
243
+ if (typeof document.title !== 'undefined') {
244
+ elmTitle = document.title;
245
+ }
246
+ elmTitle = elmTitle.replace('Elementor |', '').trim();
247
+
248
+ // get content html from elementor frontend
249
+ elmContent = elementor.$previewElementorEl.html();
250
+
251
+ $(document).ajaxComplete(function (event, request, settings) {
252
+ if (typeof settings.data !== "undefined" && settings.data.includes('action=wpms&task=reload_analysis')) {
253
+ new wpmsSpecificKeywords().init();
254
+ }
255
+ });
256
+ });
257
+ });
258
+ })(wp.data, jQuery);
assets/js/metaseo_admin.js CHANGED
@@ -1082,6 +1082,9 @@ jQuery(document).ready(function ($) {
1082
  $('[name="post_type_filter"], .wpms_duplicate_meta, .wpms_lang_list, .wpms_post_visibility').on('change', function () {
1083
  $('#wp-seo-meta-form').submit()
1084
  });
 
 
 
1085
 
1086
  $('#home_text_default').on('change', function () {
1087
  if ($(this).is(':checked')) {
@@ -1339,7 +1342,7 @@ jQuery(document).ready(function ($) {
1339
 
1340
  $(".wpms-blocks-active").attr('disabled', 'disabled');
1341
 
1342
- $('.custom-bulk-metaseo-metadesc, .custom-bulk-metaseo-metatitle').on('mouseover', function () {
1343
  $(this).addClass('wpms-mouseover-frame');
1344
  }).on('mouseout', function () {
1345
  $(this).removeClass('wpms-mouseover-frame');
1082
  $('[name="post_type_filter"], .wpms_duplicate_meta, .wpms_lang_list, .wpms_post_visibility').on('change', function () {
1083
  $('#wp-seo-meta-form').submit()
1084
  });
1085
+ $('[name="taxonomy_filter"], .wpms_duplicate_cat_meta').on('change', function () {
1086
+ $('#wp-seo-meta-form').submit()
1087
+ });
1088
 
1089
  $('#home_text_default').on('change', function () {
1090
  if ($(this).is(':checked')) {
1342
 
1343
  $(".wpms-blocks-active").attr('disabled', 'disabled');
1344
 
1345
+ $('.custom-bulk-metaseo-metadesc, .custom-bulk-metaseo-metatitle, .wpms-category-title-input, .wpms-category-desc-textarea').on('mouseover', function () {
1346
  $(this).addClass('wpms-mouseover-frame');
1347
  }).on('mouseout', function () {
1348
  $(this).removeClass('wpms-mouseover-frame');
assets/js/wp-metaseo-metabox.js CHANGED
@@ -143,7 +143,6 @@ function msUpdateTitle(force) {
143
  // do the placeholder
144
  var placeholder_title = divHtml.html(title).text();
145
  jQuery('#metaseo_snippet_title').val(placeholder_title);
146
-
147
  var len = wpmseoMetaboxL10n.wpmseo_meta_title_length - jQuery('#metaseo_snippet_title').val().length;
148
  if (jQuery('#metaseo_snippet_title').val() === '') {
149
  var mtitle_template = wpmseoMetaboxL10n.wpmseo_title_template;
@@ -337,7 +336,10 @@ jQuery(document).ready(function ($) {
337
  msUpdateKeywords();
338
  });
339
 
340
- $('body').on('keyup', wpmsdivtitle, function(event){
 
 
 
341
  msUpdateTitle();
342
  msUpdateDesc();
343
  });
@@ -625,18 +627,7 @@ jQuery(document).ready(function ($) {
625
  500
626
  );
627
 
628
- tippy('.metaseo_help', {
629
- animation: 'scale',
630
- duration: 0,
631
- arrow: false,
632
- placement: 'top',
633
- theme: 'metaseo-tippy tippy-rounded',
634
- onShow(instance) {
635
- instance.popper.hidden = instance.reference.dataset.tippy ? false : true;
636
- instance.setContent(instance.reference.dataset.tippy);
637
- }
638
- });
639
- tippy('.metaseo_tool', {
640
  animation: 'scale',
641
  duration: 0,
642
  arrow: false,
143
  // do the placeholder
144
  var placeholder_title = divHtml.html(title).text();
145
  jQuery('#metaseo_snippet_title').val(placeholder_title);
 
146
  var len = wpmseoMetaboxL10n.wpmseo_meta_title_length - jQuery('#metaseo_snippet_title').val().length;
147
  if (jQuery('#metaseo_snippet_title').val() === '') {
148
  var mtitle_template = wpmseoMetaboxL10n.wpmseo_title_template;
336
  msUpdateKeywords();
337
  });
338
 
339
+ $('body').on('keyup', wpmsdivtitle, function(event) {
340
+ if (jQuery('#metaseo_wpmseo_title').data('firstcreatepost')) {
341
+ jQuery('#metaseo_wpmseo_title').val(jQuery(wpmsdivtitle).val().replace(/(<([^>]+)>)/ig, ''));
342
+ }
343
  msUpdateTitle();
344
  msUpdateDesc();
345
  });
627
  500
628
  );
629
 
630
+ tippy('.metaseo_help, .metaseo_tool', {
 
 
 
 
 
 
 
 
 
 
 
631
  animation: 'scale',
632
  duration: 0,
633
  arrow: false,
assets/js/wpms-category-meta.js ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+ // Catch event
3
+ $('.wpms-cat-meta-title').on('change', function (e) {
4
+ wpmsUpdateCatMetaTitle(this.id);
5
+ });
6
+ $('.wpms-cat-meta-desc').on('change', function (e) {
7
+ wpmsUpdateCatMetaDesc(this.id);
8
+ });
9
+ $('.wpms-cat-meta-title').on('keyup', function (e) {
10
+ wpmsUpdateTitleLen(this.id);
11
+ });
12
+ // Title counter
13
+ $('.wpms-cat-meta-title').each(function () {
14
+ wpmsUpdateTitleLen(this.id);
15
+ });
16
+ $('.wpms-cat-meta-title').on('keyup', function (e) {
17
+ wpmsUpdateTitleLen(this.id);
18
+ });
19
+ // Description counter
20
+ $('.wpms-cat-meta-desc').each(function () {
21
+ wpmsUpdateDescLen(this.id);
22
+ });
23
+ $('.wpms-cat-meta-desc').on('keyup', function (e) {
24
+ wpmsUpdateDescLen(this.id);
25
+ });
26
+
27
+ function wpmsUpdateCatMetaTitle(elementID) {
28
+ const termID = elementID.replace('wpms-cat-meta-title-', '');
29
+ const metaTitle = metaseo_clean($('#' + elementID).val()).trim();
30
+ const dataType = 'wpms-cat-meta-title';
31
+ updateCategoryContent(termID, dataType, metaTitle);
32
+ }
33
+ function wpmsUpdateCatMetaDesc(elementID) {
34
+ const termID = elementID.replace('wpms-cat-meta-desc-', '');
35
+ const metaDesc = metaseo_clean($('#' + elementID).val()).trim();
36
+ const dataType = 'wpms-cat-meta-desc';
37
+ updateCategoryContent(termID, dataType, metaDesc);
38
+ }
39
+
40
+ function wpmsUpdateTitleLen(elementID) {
41
+ var title = (metaseo_clean($('#' + elementID).val())).trim();
42
+ const termID = elementID.replace('wpms-cat-meta-title-', '');
43
+ const counterID = 'wpms-cat-title-len' + termID;
44
+ $('#' + counterID).text(title_max_len - title.length);
45
+ if (title.length >= title_max_len) {
46
+ $('#' + counterID).removeClass('word-74B6FC').addClass('word-exceed');//#FEFB04
47
+ } else if (title.length <= 50) {
48
+ $('#' + counterID).removeClass('word-exceed').addClass('word-74B6FC');//#74B6FC
49
+ } else {
50
+ $('#' + counterID).removeClass('word-exceed word-74B6FC');
51
+ }
52
+ }
53
+
54
+ function wpmsUpdateDescLen(elementID) {
55
+ var desc = metaseo_clean($('#' + elementID).val()).trim();
56
+ const termID = elementID.replace('wpms-cat-meta-desc-', '');
57
+ const counterID = 'wpms-cat-desc-len' + termID;
58
+ $('#' + counterID).text(desc_max_len - desc.length);
59
+ if (desc.length >= desc_max_len) {
60
+ $('#' + counterID).removeClass('word-74B6FC').addClass('word-exceed');//#FEFB04
61
+ } else if (desc.length <= 120) {
62
+ $('#' + counterID).removeClass('word-exceed').addClass('word-74B6FC');//#74B6FC
63
+ } else {
64
+ $('#' + counterID).removeClass('word-exceed word-74B6FC');
65
+ }
66
+ }
67
+
68
+ // update category meta content, the main function to save data
69
+ function updateCategoryContent(termID, dataType, data) {
70
+ const postData = {
71
+ 'action': 'wpms',
72
+ 'task': 'updateCategoryContent',
73
+ 'termID': termID,
74
+ 'dataType': dataType,
75
+ 'data': data,
76
+ 'wpms_nonce': wpms_localize.wpms_nonce
77
+ }
78
+ // call ajax
79
+ jQuery.ajax({
80
+ url: wpms_localize.ajax_url,
81
+ type: 'post',
82
+ data: postData,
83
+ dataType: 'json',
84
+ beforeSend: function () {
85
+ $('#wpms-cat-imgloader-' + termID).show();
86
+ },
87
+ success: function (response) {
88
+ $('#wpms-cat-imgloader-' + termID).hide();
89
+ if (response && response.updated) {
90
+ $('#wpms-cat-return-msg-' + termID).text(response.msg);
91
+ $('#wpms-cat-return-msg-' + termID).css('visibility', 'visible');
92
+ setTimeout(() => {
93
+ $('#wpms-cat-return-msg-' + termID).css('visibility', 'hidden');
94
+ }, 1500);
95
+ } else {
96
+ alert(response.msg);
97
+ }
98
+ },
99
+ });
100
+ }
101
+
102
+ // Bulk copy action
103
+ $('.btn_do_cat_copy').on('click', function(e) {
104
+ const $this = $(this);
105
+ var sl_bulk = $('.mbulk_copy:checked').val();
106
+ if (typeof sl_bulk === "undefined" || $('.wpms-bulk-action:checked').length === 0) { // no select
107
+ return;
108
+ }
109
+ var msCatSelected = [];
110
+ var action = $this.data('action');
111
+ if (typeof action !== 'undefined' && action === 'bulk_cat_copy') {
112
+ if (sl_bulk === 'only-selection') {
113
+ $(".wpms_cat_cb").each(function () {
114
+ if ($(this).is(':checked')) {
115
+ msCatSelected.push($(this).val()); // push term id into array
116
+ }
117
+ });
118
+ }
119
+ $('.wpms-bulk-action:checked').each(function (i, v) {
120
+ let action_name = $(v).val();
121
+ wpmsAjaxDoCopy(action_name, sl_bulk, msCatSelected);
122
+ });
123
+ }
124
+ });
125
+
126
+ function wpmsAjaxDoCopy(action_name, sl_bulk, msCatSelected) {
127
+ const postData = {
128
+ 'action': 'wpms',
129
+ 'task': 'wpmsBulkCatCopy',
130
+ 'catData': {
131
+ 'action_name': action_name,
132
+ 'sl_bulk': sl_bulk,
133
+ 'msCatSelected': msCatSelected
134
+ },
135
+ 'wpms_nonce': wpms_localize.wpms_nonce
136
+ }
137
+
138
+ // send ajax
139
+ $.ajax({
140
+ url: wpms_localize.ajax_url,
141
+ type: 'post',
142
+ data: postData,
143
+ dataType: 'json',
144
+ beforeSend: function () {
145
+ $('.wpms-spinner-cat-copy').css('visibility', 'visible');
146
+ },
147
+ success: function (response) {
148
+ if (response.updated) {
149
+ $('.wpms-spinner-cat-copy').css('visibility', 'hidden');
150
+ $('.bulk-msg').fadeIn(100).delay(1000);
151
+ } else {
152
+ alert('Something went wrong');
153
+ }
154
+ }
155
+ });
156
+ }
157
+ });
assets/js/wpms-seokeyword-metabox.js CHANGED
@@ -127,7 +127,7 @@
127
  let title = {text: this.title,};
128
  let isContain = false;
129
  this.listTags.forEach(function (item, index) {
130
- if (title.text.toLowerCase().includes(item.toLowerCase())) {
131
  isContain = true;
132
  return isContain;
133
  }
@@ -140,7 +140,7 @@
140
  let content = {text: this.content};
141
  let isContain = false;
142
  this.listTags.forEach(function (item, index) {
143
- if (content.text.toLowerCase().includes(item.toLowerCase())) {
144
  isContain = true;
145
  return isContain;
146
  }
@@ -153,7 +153,7 @@
153
  let content = {text: this.content};
154
  let isContain = false;
155
  this.listTags.forEach(function (item, index) {
156
- const regex = RegExp("<h[2-6][^>]*>.*" + item.toLowerCase() + ".*</h[2-6]>", "gi");
157
  if (content.text.toLowerCase().match(regex) != null) {
158
  isContain = true;
159
  return isContain;
@@ -167,7 +167,7 @@
167
  let metaTitle = {text: this.replaceVariables(this.metaTitleElement.val())};
168
  let isContain = false;
169
  this.listTags.forEach(function (item, index) {
170
- if (metaTitle.text.toLowerCase().includes(item.toLowerCase())) {
171
  isContain = true;
172
  return isContain;
173
  }
@@ -180,7 +180,7 @@
180
  let metaDesc = {text: this.replaceVariables(this.metaDescElement.val())};
181
  let isContain = false;
182
  this.listTags.forEach(function (item, index) {
183
- if (metaDesc.text.toLowerCase().includes(item.toLowerCase())) {
184
  isContain = true;
185
  return isContain;
186
  }
127
  let title = {text: this.title,};
128
  let isContain = false;
129
  this.listTags.forEach(function (item, index) {
130
+ if (title.text.toLowerCase().includes(item.toLowerCase().trim())) {
131
  isContain = true;
132
  return isContain;
133
  }
140
  let content = {text: this.content};
141
  let isContain = false;
142
  this.listTags.forEach(function (item, index) {
143
+ if (content.text.toLowerCase().includes(item.toLowerCase().trim())) {
144
  isContain = true;
145
  return isContain;
146
  }
153
  let content = {text: this.content};
154
  let isContain = false;
155
  this.listTags.forEach(function (item, index) {
156
+ const regex = RegExp("<h[2-6][^>]*>.*" + item.toLowerCase().trim() + ".*</h[2-6]>", "gi");
157
  if (content.text.toLowerCase().match(regex) != null) {
158
  isContain = true;
159
  return isContain;
167
  let metaTitle = {text: this.replaceVariables(this.metaTitleElement.val())};
168
  let isContain = false;
169
  this.listTags.forEach(function (item, index) {
170
+ if (metaTitle.text.toLowerCase().includes(item.toLowerCase().trim())) {
171
  isContain = true;
172
  return isContain;
173
  }
180
  let metaDesc = {text: this.replaceVariables(this.metaDescElement.val())};
181
  let isContain = false;
182
  this.listTags.forEach(function (item, index) {
183
+ if (metaDesc.text.toLowerCase().includes(item.toLowerCase().trim())) {
184
  isContain = true;
185
  return isContain;
186
  }
assets/js/wpms-seokeyword-metabox.min.js DELETED
@@ -1 +0,0 @@
1
- !function(t){var e={};function n(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)n.d(i,s,function(e){return t[e]}.bind(null,s));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e){t.exports=function(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t},t.exports.default=t.exports,t.exports.__esModule=!0},function(t,e,n){"use strict";n.r(e);var i=n(0),s=n.n(i);!function(t,e){const{select:n,subscribe:i}=t;class o{constructor(){s()(this,"init",()=>{this.bindEvents(),this.tagsElement.on("itemAdded itemRemoved",this.bindEvents),this.metaTitleElement.on("keyup",this.bindEvents),this.metaDescElement.on("keyup",this.bindEvents)}),s()(this,"bindEvents",()=>{void 0!==wp.blocks&&null!==n("core/editor")?(this.title=n("core/editor").getEditedPostAttribute("title"),this.content=n("core/editor").getEditedPostAttribute("content")):(this.title=e("#title").val(),"undefined"!=typeof tinyMCE&&null!==tinyMCE.get("content")?this.content=tinyMCE.editors.content.getContent():this.content=e("#content").val()),this.listTags=this.tagsElement.tagsinput("items"),this.analytics()}),s()(this,"editPost",t=>{void 0!==t&&(this.title=t.title,this.content=t.content),this.listTags=this.tagsElement.tagsinput("items"),this.analytics()}),s()(this,"analytics",()=>{if(this.resultAnalytics={keyInTitle:this.collectKeywordsInTitle(),keyInContent:this.collectKeywordsInContent(),keyInContentHeading:this.collectKeywordsInHeading(),keyInMetaTitle:this.collectKeywordsInMetaTitle(),keyInMetaDescription:this.collectKeywordsInMetaDesc()},null!==this.resultAnalytics){let t=!1;Object.entries(this.resultAnalytics).forEach(e=>{const[n,i]=e;i&&(t=!0),this.changeAnalyticsInfo(n,i)}),this.editAnalyticsInfo(t)}}),s()(this,"editAnalyticsInfo",t=>{if(""===e("input#metaseo_wpmseo_specific_keywords").val())return e('div.metaseo_analysis[data-title="seokeyword"]').hide(),e(".seokeyword-information").hide(),e('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(0),this.reDrawInactive(7),!1;e('div.metaseo_analysis[data-title="seokeyword"]').show(),e(".seokeyword-information").show(),t?(e('div.metaseo_analysis[data-title="seokeyword"]').find("i").removeClass("icons-mboxwarning").addClass("icons-mboxdone").html("done"),e('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(1)):(e('div.metaseo_analysis[data-title="seokeyword"]').find("i").removeClass("icons-mboxdone").addClass("icons-mboxwarning").html("error_outline"),e('input.wpms_analysis_hidden[name="wpms[seokeyword]"]').val(0)),this.reDrawInactive(8)}),s()(this,"reDrawInactive",t=>{const n=e(".panel-left .wpms_analysis_hidden");let i=0;for(let t=0;t<n.length;t++)1==e(n[t]).val()&&i++;const s=Math.ceil(100*i/t);e("#wpmetaseo_seo_keywords_result").val(s),e(".metaseo-progress-bar").circleProgress("value",s/100).on("circle-animation-progress",(function(t,n){e(this).find("strong").html(s+"<i>%</i>")}))}),s()(this,"changeAnalyticsInfo",(t,n)=>{n?(e('div.metaseo_analysis[data-title="'+t.toLowerCase()+'"]').find("i").removeClass("icons-mboxwarning").addClass("icons-mboxdone").html("done"),e('input.wpms_analysis_hidden[name="wpms['+t.toLowerCase()+']"]').val(1)):(e('div.metaseo_analysis[data-title="'+t.toLowerCase()+'"]').find("i").removeClass("icons-mboxdone").addClass("icons-mboxwarning").html("error_outline"),e('input.wpms_analysis_hidden[name="wpms['+t.toLowerCase()+']"]').val(0))}),s()(this,"collectKeywordsInTitle",()=>{let t={text:this.title},e=!1;return this.listTags.forEach((function(n,i){if(t.text.toLowerCase().includes(n.toLowerCase()))return e=!0,e})),e}),s()(this,"collectKeywordsInContent",()=>{let t={text:this.content},e=!1;return this.listTags.forEach((function(n,i){if(t.text.toLowerCase().includes(n.toLowerCase()))return e=!0,e})),e}),s()(this,"collectKeywordsInHeading",()=>{let t={text:this.content},e=!1;return this.listTags.forEach((function(n,i){const s=RegExp("<h[2-6][^>]*>.*"+n.toLowerCase()+".*</h[2-6]>","gi");if(null!=t.text.toLowerCase().match(s))return e=!0,e})),e}),s()(this,"collectKeywordsInMetaTitle",()=>{let t={text:this.replaceVariables(this.metaTitleElement.val())},e=!1;return this.listTags.forEach((function(n,i){if(t.text.toLowerCase().includes(n.toLowerCase()))return e=!0,e})),e}),s()(this,"collectKeywordsInMetaDesc",()=>{let t={text:this.replaceVariables(this.metaDescElement.val())},e=!1;return this.listTags.forEach((function(n,i){if(t.text.toLowerCase().includes(n.toLowerCase()))return e=!0,e})),e}),s()(this,"replaceVariables",t=>{if(void 0===t)return;this.title&&(t=t.replace(/%title%/g,this.title.replace(/(<([^>]+)>)/gi,""))),t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/%id%/g,wpmseoMetaboxL10n.id)).replace(/%date%/g,wpmseoMetaboxL10n.date)).replace(/%sitedesc%/g,wpmseoMetaboxL10n.sitedesc)).replace(/%sitename%/g,wpmseoMetaboxL10n.sitename)).replace(/%sep%/g,wpmseoMetaboxL10n.sep)).replace(/%page%/g,wpmseoMetaboxL10n.page)).replace(/%currenttime%/g,wpmseoMetaboxL10n.currenttime)).replace(/%currentdate%/g,wpmseoMetaboxL10n.currentdate)).replace(/%currentday%/g,wpmseoMetaboxL10n.currentday)).replace(/%currentmonth%/g,wpmseoMetaboxL10n.currentmonth)).replace(/%currentyear%/g,wpmseoMetaboxL10n.currentyear);let e="";jQuery("#excerpt").length&&(e=msClean(jQuery("#excerpt").val().replace(/(<([^>]+)>)/gi,"")),t=t.replace(/%excerpt_only%/g,e)),""===e&&jQuery("#content").length&&(e=jQuery("#content").val().replace(/(<([^>]+)>)/gi,"").substring(0,wpmseoMetaboxL10n.wpmseo_meta_desc_length-1)),t=t.replace(/%excerpt%/g,e),jQuery("#parent_id").length&&jQuery("#parent_id option:selected").text()!==wpmseoMetaboxL10n.no_parent_text&&(t=t.replace(/%parent_title%/g,jQuery("#parent_id option:selected").text()));const n=wpmseoMetaboxL10n.sep.replace(/[\-\[\]\/\{}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),i=new RegExp(n+" "+n,"g");return t.replace(i,wpmseoMetaboxL10n.sep)}),this.title=null,this.content=null,this.tagsElement=e("#metaseo_wpmseo_specific_keywords"),this.metaTitleElement=e("#metaseo_wpmseo_title"),this.metaDescElement=e("#metaseo_wpmseo_desc"),this.listTags=[],this.resultAnalytics=null}}class a{constructor(){s()(this,"init",()=>{i(()=>{const t=null!==n("core/editor")?n("core/editor").getEditedPostAttribute("title"):void 0;void 0!==t&&null===this.data.title&&(this.data.title=t),void 0!==t&&t!==this.data.title&&(this.data.title=t,this.changeTitle());const e=null!==n("core/editor")?n("core/editor").getEditedPostAttribute("content"):void 0;void 0!==e&&null===this.data.content&&(this.data.content=e),void 0!==e&&e!==this.data.content&&(this.data.content=e,this.changeContent())})}),s()(this,"changeTitle",()=>{(new o).editPost(this.data)}),s()(this,"changeContent",()=>{(new o).editPost(this.data)}),this.data={title:null,content:null}}}class l{constructor(){s()(this,"init",()=>{e("#title").on("keyup",this.changeTitle),"undefined"!=typeof tinyMCE&&null!==tinyMCE.get("content")?tinyMCE.get("content").on("keyup",this.changeContent):e("#content").on("keyup",this.changeContent)}),s()(this,"getData",()=>{this.data.title=e("#title").val(),"undefined"!=typeof tinyMCE&&null!==tinyMCE.get("content")?this.data.content=tinyMCE.editors.content.getContent():this.data.content=e("#content").val()}),s()(this,"changeTitle",()=>{this.getData(),(new o).editPost(this.data)}),s()(this,"changeContent",()=>{this.getData(),(new o).editPost(this.data)}),this.data={title:null,content:null}}}e(document).ajaxComplete((function(t,e,i){void 0!==i.data&&i.data.includes("action=wpms&task=reload_analysis")&&(void 0!==wp.blocks&&null!==n("core/editor")?(new a).init():(new l).init(),(new o).init())}))}(wp.data,jQuery)}]);
 
inc/class.metaseo-admin.php CHANGED
@@ -134,6 +134,9 @@ class MetaSeoAdmin
134
  add_action('post_updated', array('MetaSeoImageListTable', 'updatePost'), 10, 3);
135
  add_action('delete_post', array('MetaSeoImageListTable', 'deletePost'));
136
 
 
 
 
137
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
138
  add_action('product_cat_add_form_fields', array($this, 'categoryField'));
139
  add_action('product_cat_edit_form_fields', array($this, 'editCategoryFields'), 10);
@@ -1251,7 +1254,6 @@ class MetaSeoAdmin
1251
  '<div>' . html_entity_decode(stripcslashes($_POST['datas']['content']), ENT_COMPAT, 'UTF-8') . '</div>',
1252
  $_POST['datas']['post_id']
1253
  );
1254
-
1255
  $content = $this->injectAcfField($content, $_POST['datas']['post_id']);
1256
 
1257
  $content = $this->injectWooCommerce($content, $_POST['datas']['post_id']);
@@ -1494,16 +1496,12 @@ class MetaSeoAdmin
1494
  $check++;
1495
  } else {
1496
  $mpageurl = '';
1497
- if ($_POST['datas']['editor'] === 'gutenberg') {
1498
- if (isset($_POST['datas']['mpageurl'])) {
1499
- $infos = pathinfo($_POST['datas']['mpageurl']);
1500
- $mpageurl = $infos['filename'];
1501
- }
1502
- } else {
1503
- $mpageurl = $_POST['datas']['mpageurl'];
1504
  }
1505
 
1506
- if (!empty($mpageurl) && !empty($mtitle) && $mpageurl === sanitize_title($mtitle)) {
1507
  $output .= $this->createFieldAnalysis(
1508
  'pageurl',
1509
  $tooltip_page['page_url'],
@@ -2377,7 +2375,7 @@ class MetaSeoAdmin
2377
  }
2378
 
2379
  /**
2380
- * Show meta box in single post
2381
  *
2382
  * @return void
2383
  */
@@ -2466,6 +2464,7 @@ class MetaSeoAdmin
2466
  'wp-meta-seo_page_metaseo_broken_link',
2467
  'wp-meta-seo_page_metaseo_settings',
2468
  'wp-meta-seo_page_metaseo_content_meta',
 
2469
  'wp-meta-seo_page_metaseo_image_meta',
2470
  'wp-meta-seo_page_metaseo_link_meta'
2471
  );
@@ -2473,6 +2472,7 @@ class MetaSeoAdmin
2473
  $lists_pages = array(
2474
  'toplevel_page_metaseo_dashboard',
2475
  'wp-meta-seo_page_metaseo_content_meta',
 
2476
  'wp-meta-seo_page_metaseo_google_sitemap',
2477
  'wp-meta-seo_page_metaseo_image_meta',
2478
  'wp-meta-seo_page_metaseo_link_meta',
@@ -2597,6 +2597,7 @@ class MetaSeoAdmin
2597
  array(),
2598
  WPMSEO_VERSION
2599
  );
 
2600
  wp_enqueue_style('style', plugins_url('assets/css/style.css', dirname(__FILE__)), array(), WPMSEO_VERSION);
2601
  }
2602
 
@@ -2739,6 +2740,25 @@ class MetaSeoAdmin
2739
  true
2740
  );
2741
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2742
  wp_register_style(
2743
  'wpms-tippy-style',
2744
  plugins_url('assets/tippy/tippy.css', dirname(__FILE__)),
@@ -2976,6 +2996,7 @@ class MetaSeoAdmin
2976
  // Add intro text on each wpms topic
2977
  $tippy_pages = array(
2978
  'wp-meta-seo_page_metaseo_content_meta',
 
2979
  'wp-meta-seo_page_metaseo_image_meta',
2980
  'wp-meta-seo_page_metaseo_google_sitemap',
2981
  'wp-meta-seo_page_metaseo_link_meta',
@@ -3619,6 +3640,15 @@ class MetaSeoAdmin
3619
  array($this, 'loadPage'),
3620
  null
3621
  ),
 
 
 
 
 
 
 
 
 
3622
  array(
3623
  'metaseo_dashboard',
3624
  '',
@@ -4348,6 +4378,9 @@ class MetaSeoAdmin
4348
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/content-meta.php');
4349
  break;
4350
 
 
 
 
4351
 
4352
  case 'metaseo_image_meta':
4353
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/image-meta.php');
@@ -4774,6 +4807,10 @@ class MetaSeoAdmin
4774
  case 'reload_analysis':
4775
  $this->reloadAnalysis();
4776
  break;
 
 
 
 
4777
  case 'validate_analysis':
4778
  $this->validateAnalysis();
4779
  break;
@@ -4867,6 +4904,15 @@ class MetaSeoAdmin
4867
  case 'update_seokeyword_bulk_edit':
4868
  $this->updateSeokeywordBulkEdit();
4869
  break;
 
 
 
 
 
 
 
 
 
4870
  }
4871
  }
4872
  }
134
  add_action('post_updated', array('MetaSeoImageListTable', 'updatePost'), 10, 3);
135
  add_action('delete_post', array('MetaSeoImageListTable', 'deletePost'));
136
 
137
+ // Category meta hook
138
+ add_action('admin_head', array('WPMSCategoryMetaTable', 'customStyles'));
139
+
140
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
141
  add_action('product_cat_add_form_fields', array($this, 'categoryField'));
142
  add_action('product_cat_edit_form_fields', array($this, 'editCategoryFields'), 10);
1254
  '<div>' . html_entity_decode(stripcslashes($_POST['datas']['content']), ENT_COMPAT, 'UTF-8') . '</div>',
1255
  $_POST['datas']['post_id']
1256
  );
 
1257
  $content = $this->injectAcfField($content, $_POST['datas']['post_id']);
1258
 
1259
  $content = $this->injectWooCommerce($content, $_POST['datas']['post_id']);
1496
  $check++;
1497
  } else {
1498
  $mpageurl = '';
1499
+ if (isset($_POST['datas']['mpageurl'])) {
1500
+ $infos = pathinfo($_POST['datas']['mpageurl']);
1501
+ $mpageurl = $infos['filename'];
 
 
 
 
1502
  }
1503
 
1504
+ if (!empty($mpageurl) && !empty($mtitle) && strpos($mtitle, $mpageurl)) {
1505
  $output .= $this->createFieldAnalysis(
1506
  'pageurl',
1507
  $tooltip_page['page_url'],
2375
  }
2376
 
2377
  /**
2378
+ * Show meta box in single post, on elementor plugin
2379
  *
2380
  * @return void
2381
  */
2464
  'wp-meta-seo_page_metaseo_broken_link',
2465
  'wp-meta-seo_page_metaseo_settings',
2466
  'wp-meta-seo_page_metaseo_content_meta',
2467
+ 'wp-meta-seo_page_metaseo_category_meta',
2468
  'wp-meta-seo_page_metaseo_image_meta',
2469
  'wp-meta-seo_page_metaseo_link_meta'
2470
  );
2472
  $lists_pages = array(
2473
  'toplevel_page_metaseo_dashboard',
2474
  'wp-meta-seo_page_metaseo_content_meta',
2475
+ 'wp-meta-seo_page_metaseo_category_meta',
2476
  'wp-meta-seo_page_metaseo_google_sitemap',
2477
  'wp-meta-seo_page_metaseo_image_meta',
2478
  'wp-meta-seo_page_metaseo_link_meta',
2597
  array(),
2598
  WPMSEO_VERSION
2599
  );
2600
+
2601
  wp_enqueue_style('style', plugins_url('assets/css/style.css', dirname(__FILE__)), array(), WPMSEO_VERSION);
2602
  }
2603
 
2740
  true
2741
  );
2742
 
2743
+ // Enqueue for category meta page
2744
+ if ($current_screen->base === 'wp-meta-seo_page_metaseo_category_meta') {
2745
+ wp_enqueue_style(
2746
+ 'wpmsCategoryMeta',
2747
+ plugins_url('assets/css/metaseo-category-meta-bulk.css', dirname(__FILE__)),
2748
+ array(),
2749
+ WPMSEO_VERSION
2750
+ );
2751
+
2752
+ wp_enqueue_script(
2753
+ 'wpmsCategoryMeta',
2754
+ plugins_url('assets/js/wpms-category-meta.js', dirname(__FILE__)),
2755
+ array('jquery'),
2756
+ WPMSEO_VERSION,
2757
+ true
2758
+ );
2759
+ wp_enqueue_script('wpms-category-field');
2760
+ }
2761
+
2762
  wp_register_style(
2763
  'wpms-tippy-style',
2764
  plugins_url('assets/tippy/tippy.css', dirname(__FILE__)),
2996
  // Add intro text on each wpms topic
2997
  $tippy_pages = array(
2998
  'wp-meta-seo_page_metaseo_content_meta',
2999
+ 'wp-meta-seo_page_metaseo_category_meta',
3000
  'wp-meta-seo_page_metaseo_image_meta',
3001
  'wp-meta-seo_page_metaseo_google_sitemap',
3002
  'wp-meta-seo_page_metaseo_link_meta',
3640
  array($this, 'loadPage'),
3641
  null
3642
  ),
3643
+ array(
3644
+ 'metaseo_dashboard',
3645
+ '',
3646
+ esc_html__('Category meta', 'wp-meta-seo'),
3647
+ $manage_options_cap,
3648
+ 'metaseo_category_meta',
3649
+ array($this, 'loadPage'),
3650
+ null
3651
+ ),
3652
  array(
3653
  'metaseo_dashboard',
3654
  '',
4378
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/content-meta.php');
4379
  break;
4380
 
4381
+ case 'metaseo_category_meta':
4382
+ require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/category-meta.php');
4383
+ break;
4384
 
4385
  case 'metaseo_image_meta':
4386
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/pages/image-meta.php');
4807
  case 'reload_analysis':
4808
  $this->reloadAnalysis();
4809
  break;
4810
+ case 'wpmsElementorSavePost':
4811
+ require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-metabox.php');
4812
+ WPMSEOMetabox::savePostByElementor();
4813
+ break;
4814
  case 'validate_analysis':
4815
  $this->validateAnalysis();
4816
  break;
4904
  case 'update_seokeyword_bulk_edit':
4905
  $this->updateSeokeywordBulkEdit();
4906
  break;
4907
+ case 'updateCategoryContent':
4908
+ WPMSCategoryMetaTable::updateCategoryContent();
4909
+ break;
4910
+ case 'wpmsDeleteCat':
4911
+ WPMSCategoryMetaTable::wpmsDeleteCat();
4912
+ break;
4913
+ case 'wpmsBulkCatCopy':
4914
+ WPMSCategoryMetaTable::wpmsBulkCatCopy();
4915
+ break;
4916
  }
4917
  }
4918
  }
inc/class.metaseo-category-meta-table.php ADDED
@@ -0,0 +1,804 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* Prohibit direct script loading */
3
+ defined('ABSPATH') || die('No direct script access allowed!');
4
+ if (!class_exists('WP_List_Table')) {
5
+ require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
6
+ }
7
+
8
+ /**
9
+ * Class Meta seo category meta table
10
+ *
11
+ * Base class for displaying a list of category/product_cat in an ajaxified HTML table.
12
+ */
13
+ class WPMSCategoryMetaTable extends WP_List_Table
14
+ {
15
+ /**
16
+ * Post/product taxonomy
17
+ *
18
+ * @var array
19
+ */
20
+ public $taxonomy_cat;
21
+
22
+ /**
23
+ * MetaSeoContentListTable constructor.
24
+ */
25
+ public function __construct()
26
+ {
27
+ parent::__construct(array(
28
+ 'singular' => 'metaseo_category',
29
+ 'plural' => 'metaseo_categories',
30
+ 'ajax' => true
31
+ ));
32
+ }
33
+
34
+ /**
35
+ * Custom style for meta content table
36
+ *
37
+ * @return void
38
+ */
39
+ public static function customStyles()
40
+ {
41
+ echo '<style type="text/css">';
42
+ echo '.metaseo_categories .column-col_cat_title {width:30% !important;}';
43
+ echo '</style>';
44
+ }
45
+
46
+ /**
47
+ * Generate the table navigation above or below the table
48
+ *
49
+ * @param string $which Position of table nav
50
+ *
51
+ * @return void
52
+ */
53
+ protected function display_tablenav($which) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
54
+ {
55
+ ?>
56
+ <div class="<?php echo esc_attr('tablenav ' . $which); ?>">
57
+
58
+ <input type="hidden" name="page" value="metaseo_content_meta"/>
59
+ <?php // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
60
+ ?>
61
+ <?php if (!empty($_REQUEST['cat_status'])) : ?>
62
+ <input type="hidden" name="post_status" value="<?php echo esc_attr($_REQUEST['cat_status']); ?>"/>
63
+ <?php endif ?>
64
+ <?php // phpcs:enable
65
+ if ($which === 'top') {
66
+ $this->extra_tablenav($which); ?>
67
+ <div style="float:right;margin-left:8px;">
68
+ <label>
69
+ <input type="number" required
70
+ value="<?php echo esc_attr($this->_pagination_args['per_page']) ?>"
71
+ maxlength="3" name="wpms_cat_per_page" class="metaseo_imgs_per_page screen-per-page"
72
+ max="999" min="1" step="1">
73
+ <button type="submit" name="wpms_btn_perpage"
74
+ class="button_perpage ju-button orange-button waves-effect waves-light"
75
+ id="button_perpage"><?php esc_html_e('Apply', 'wp-meta-seo') ?></button>
76
+ </label>
77
+ </div>
78
+ <?php } else { ?>
79
+ <?php $this->pagination('top'); ?>
80
+ <?php } ?>
81
+ <br class="clear"/>
82
+ </div>
83
+
84
+ <?php
85
+ }
86
+
87
+ /**
88
+ * Display the pagination.
89
+ *
90
+ * @param string $which Possition
91
+ *
92
+ * @return void
93
+ */
94
+ protected function pagination($which)
95
+ {
96
+ if (empty($this->_pagination_args)) {
97
+ return;
98
+ }
99
+
100
+ $total_items = (int) $this->_pagination_args['total_items'];
101
+ $total_pages = (int) $this->_pagination_args['total_pages'];
102
+ $infinite_scroll = false;
103
+ if (isset($this->_pagination_args['infinite_scroll'])) {
104
+ $infinite_scroll = $this->_pagination_args['infinite_scroll'];
105
+ }
106
+
107
+ if ('top' === $which && $total_pages > 1) {
108
+ $this->screen->render_screen_reader_content('heading_pagination');
109
+ }
110
+
111
+ $output = '<span class="displaying-num">' . sprintf(_n('%s item', '%s items', $total_items, 'wp-meta-seo'), number_format_i18n($total_items)) . '</span>';
112
+
113
+ $current = (int) $this->get_pagenum();
114
+ $removable_query_args = wp_removable_query_args();
115
+
116
+ $current_url = set_url_scheme('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
117
+
118
+ $current_url = remove_query_arg($removable_query_args, $current_url);
119
+
120
+ $page_links = array();
121
+
122
+ $total_pages_before = '<span class="paging-input">';
123
+ $total_pages_after = '</span></span>';
124
+
125
+ $disable_first = false;
126
+ $disable_last = false;
127
+ $disable_prev = false;
128
+ $disable_next = false;
129
+
130
+ if ($current === 1) {
131
+ $disable_first = true;
132
+ $disable_prev = true;
133
+ }
134
+ if ($current === 2) {
135
+ $disable_first = true;
136
+ }
137
+
138
+ if ($current === $total_pages) {
139
+ $disable_last = true;
140
+ $disable_next = true;
141
+ }
142
+ if ($current === $total_pages - 1) {
143
+ $disable_last = true;
144
+ }
145
+
146
+ if ($disable_first) {
147
+ $page_links[] = '<a class="wpms-number-page first-page disable"><i class="material-icons">first_page</i></a>';
148
+ } else {
149
+ $page_links[] = sprintf(
150
+ "<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><i class='material-icons'>%s</i></a>",
151
+ esc_url(remove_query_arg('paged', $current_url)),
152
+ __('First page', 'wp-meta-seo'),
153
+ 'first_page'
154
+ );
155
+ }
156
+
157
+ if ($disable_prev) {
158
+ $page_links[] = '<a class="wpms-number-page prev-page disable"><i class="material-icons">keyboard_backspace</i></a>';
159
+ } else {
160
+ $page_links[] = sprintf(
161
+ "<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><i class='material-icons'>%s</i></a>",
162
+ esc_url(add_query_arg('paged', max(1, $current - 1), $current_url)),
163
+ __('Previous page', 'wp-meta-seo'),
164
+ 'keyboard_backspace'
165
+ );
166
+ }
167
+
168
+ $begin = $current - 2;
169
+ $end = $current + 2;
170
+ if ($begin < 1) {
171
+ $begin = 1;
172
+ $end = $begin + 4;
173
+ }
174
+ if ($end > $total_pages) {
175
+ $end = $total_pages;
176
+ $begin = $end - 4;
177
+ }
178
+ if ($begin < 1) {
179
+ $begin = 1;
180
+ }
181
+
182
+ $custom_html = '';
183
+ for ($i = $begin; $i <= $end; $i ++) {
184
+ if ($i === $current) {
185
+ $custom_html .= '<a class="wpms-number-page active" href="' . esc_url(add_query_arg('paged', $i, $current_url)) . '"><span class="screen-reader-text">' . esc_html($i) . '</span><span aria-hidden="true">' . esc_html($i) . '</span></a>';
186
+ } else {
187
+ $custom_html .= '<a class="wpms-number-page" href="' . esc_url(add_query_arg('paged', $i, $current_url)) . '"><span class="screen-reader-text">' . esc_html($i) . '</span><span aria-hidden="true">' . esc_html($i) . '</span></a>';
188
+ }
189
+ }
190
+ $page_links[] = $total_pages_before . $custom_html . $total_pages_after;
191
+
192
+ if ($disable_next) {
193
+ $page_links[] = '<a class="wpms-number-page disable next-page"><i class="material-icons">trending_flat</i></a>';
194
+ } else {
195
+ $page_links[] = sprintf(
196
+ "<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><i class='material-icons'>%s</i></a>",
197
+ esc_url(add_query_arg('paged', min($total_pages, $current + 1), $current_url)),
198
+ __('Next page', 'wp-meta-seo'),
199
+ 'trending_flat'
200
+ );
201
+ }
202
+
203
+ if ($disable_last) {
204
+ $page_links[] = '<a class="wpms-number-page last-page disable"><i class="material-icons">last_page</i></a>';
205
+ } else {
206
+ $page_links[] = sprintf(
207
+ "<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><i class='material-icons'>%s</i></a>",
208
+ esc_url(add_query_arg('paged', $total_pages, $current_url)),
209
+ __('Last page', 'wp-meta-seo'),
210
+ 'last_page'
211
+ );
212
+ }
213
+
214
+ $pagination_links_class = 'pagination-links';
215
+ if (!empty($infinite_scroll)) {
216
+ $pagination_links_class .= ' hide-if-js';
217
+ }
218
+ $output .= '<span class="' . esc_html($pagination_links_class) . '">' . join('', $page_links) . '</span>';
219
+
220
+ if ($total_pages) {
221
+ $page_class = $total_pages < 2 ? ' one-page' : '';
222
+ } else {
223
+ $page_class = ' no-pages';
224
+ }
225
+ $this->_pagination = '<div class="tablenav-pages' . esc_html($page_class) . '">' . $output . '</div>';
226
+
227
+ // phpcs:ignore WordPress.Security.EscapeOutput -- Content already escaped
228
+ echo $this->_pagination;
229
+ }
230
+
231
+ /**
232
+ * Displays the search box.
233
+ *
234
+ * @param string $text The 'submit' button label.
235
+ * @param string $input_id ID attribute value for the search input field.
236
+ *
237
+ * @return void
238
+ */
239
+ public function searchBox($text, $input_id)
240
+ {
241
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
242
+ if (empty($_REQUEST['s']) && !$this->has_items()) {
243
+ return;
244
+ }
245
+ $input_id = $input_id . '-search-input';
246
+
247
+ if (!empty($_REQUEST['orderby'])) {
248
+ echo '<input type="hidden" name="orderby" value="' . esc_attr($_REQUEST['orderby']) . '" />';
249
+ }
250
+ if (!empty($_REQUEST['order'])) {
251
+ echo '<input type="hidden" name="order" value="' . esc_attr($_REQUEST['order']) . '" />';
252
+ }
253
+ // phpcs:enable
254
+ ?>
255
+ <p class="search-box">
256
+ <label class="screen-reader-text" for="<?php echo esc_attr($input_id); ?>"><?php echo esc_html($text); ?>
257
+ :</label>
258
+ <input type="text" id="<?php echo esc_attr($input_id); ?>" class="wpms-search-input" name="s"
259
+ value="<?php _admin_search_query(); ?>"
260
+ placeholder="<?php esc_html_e('Search content', 'wp-meta-seo') ?>"/>
261
+ <button type="submit" id="search-submit"><span class="dashicons dashicons-search"></span></button>
262
+ </p>
263
+ <?php
264
+ }
265
+
266
+ /**
267
+ * Extra controls to be displayed between bulk actions and pagination
268
+ *
269
+ * @param string $which Possition of table nav
270
+ *
271
+ * @return void
272
+ */
273
+ protected function extra_tablenav($which) // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
274
+ {
275
+ echo '<div class="alignleft actions">';
276
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
277
+ $selected = !empty($_REQUEST['taxonomy_filter']) ? $_REQUEST['taxonomy_filter'] : - 1;
278
+
279
+ $options = '<option value="-1">Show All Categories</option>';
280
+
281
+ foreach ($this->taxonomy_cat as $taxonomy) {
282
+ $taxonomy_object = get_taxonomy($taxonomy);
283
+ $options .= sprintf(
284
+ '<option value="%2$s" %3$s>%1$s</option>',
285
+ esc_html($taxonomy_object->labels->name),
286
+ esc_attr($taxonomy),
287
+ selected($selected, $taxonomy, false)
288
+ );
289
+ }
290
+
291
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
292
+ $selected_duplicate = !empty($_REQUEST['wpms_duplicate_cat_meta']) ? $_REQUEST['wpms_duplicate_cat_meta'] : 'none';
293
+ $options_dups = array(
294
+ 'none' => esc_html__('All category meta information', 'wp-meta-seo'),
295
+ 'duplicate_cat_title' => esc_html__('Duplicated category meta titles', 'wp-meta-seo'),
296
+ 'duplicate_cat_desc' => esc_html__('Duplicated category meta descriptions', 'wp-meta-seo')
297
+ );
298
+ $sl_duplicate = '<select name="wpms_duplicate_cat_meta" class="wpms_duplicate_meta">';
299
+ foreach ($options_dups as $key => $label) {
300
+ if ($selected_duplicate === $key) {
301
+ $sl_duplicate .= '<option selected value="' . esc_attr($key) . '">' . esc_html($label) . '</option>';
302
+ } else {
303
+ $sl_duplicate .= '<option value="' . esc_attr($key) . '">' . esc_html($label) . '</option>';
304
+ }
305
+ }
306
+ $sl_duplicate .= '</select>';
307
+ // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
308
+ echo sprintf('<select name="taxonomy_filter" class="metaseo-filter">%1$s</select>', $options);
309
+ // phpcs:disable WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
310
+ echo $sl_duplicate;
311
+ // phpcs:enable
312
+ if (is_plugin_active(WPMSEO_ADDON_FILENAME)
313
+ && (is_plugin_active('sitepress-multilingual-cms/sitepress.php')
314
+ || is_plugin_active('polylang/polylang.php'))) {
315
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
316
+ $lang = !empty($_REQUEST['wpms_lang_list']) ? $_REQUEST['wpms_lang_list'] : '0';
317
+ $sl_lang = apply_filters('wpms_get_languagesList', '', $lang);
318
+ // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method MetaSeoAddonAdmin::listLanguageSelect
319
+ echo $sl_lang;
320
+ }
321
+
322
+ echo '<a href="#TB_inline?width=600&height=550&inlineId=cat-meta-bulk-actions" title="' . esc_html__('Bulk Actions', 'wp-meta-seo') . '"
323
+ class="ju-button orange-button wpms-middle thickbox">' . esc_html__('Meta Bulk Actions', 'wp-meta-seo') . '</a>';
324
+ echo '</div>';
325
+ }
326
+
327
+ /**
328
+ * Get a list of columns. The format is:
329
+ * 'internal-name' => 'Title'
330
+ *
331
+ * @return array
332
+ */
333
+ public function get_columns() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
334
+ {
335
+ $preview = esc_html__(" This is a rendering of what this post might look
336
+ like in Google's search results.", 'wp-meta-seo');
337
+ $info = sprintf('<a class="info-content"><img src=' . WPMETASEO_PLUGIN_URL . 'assets/images/info.png>'
338
+ . '<p class="tooltip-metacontent">'
339
+ . $preview
340
+ . '</p></a>');
341
+
342
+ $columns = array(
343
+ 'cb' => '<input id="cb-select-all-1" type="checkbox" style="margin:0">',
344
+ 'col_cat_title' => esc_html__('Title', 'wp-meta-seo'),
345
+ 'col_cat_snippet' => sprintf(esc_html__('Snippet Preview %s', 'wp-meta-seo'), $info)
346
+ );
347
+
348
+ return $columns;
349
+ }
350
+
351
+ /**
352
+ * Get a list of sortable columns. The format is:
353
+ * 'internal-name' => 'orderby'
354
+ * or
355
+ * 'internal-name' => array( 'orderby', true )
356
+ *
357
+ * The second format will make the initial sorting order be descending
358
+ *
359
+ * @return array
360
+ */
361
+ protected function get_sortable_columns() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
362
+ {
363
+ $sortable = array(
364
+ 'col_cat_title' => array('term_name', true)
365
+ );
366
+
367
+ return $sortable;
368
+ }
369
+
370
+ /**
371
+ * Get taxonomy for category (category/product_cat)
372
+ *
373
+ * @return array
374
+ */
375
+ public static function getTaxonomyCat()
376
+ {
377
+ $taxonomy = array();
378
+ if (taxonomy_exists('category')) {
379
+ $taxonomy[] = 'category';
380
+ }
381
+ // Check if Woocommerce product categories exits
382
+ if (taxonomy_exists('product_cat')) {
383
+ $taxonomy[] = 'product_cat';
384
+ }
385
+ return $taxonomy;
386
+ }
387
+
388
+ /**
389
+ * Prepares the list of items for displaying.
390
+ *
391
+ * @return void
392
+ */
393
+ public function prepare_items() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
394
+ {
395
+ global $wpdb;
396
+ $this->taxonomy_cat = $this->getTaxonomyCat();
397
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
398
+ $taxonomy_cat = isset($_REQUEST['taxonomy_filter']) ? $_REQUEST['taxonomy_filter'] : '';
399
+ if ($taxonomy_cat === '-1') {
400
+ $taxonomy_cat = ''; // show all categories (category and product_cat)
401
+ }
402
+
403
+ if (!empty($taxonomy_cat) && !in_array($taxonomy_cat, $this->taxonomy_cat)) {
404
+ $taxonomy_cat = 'category'; // default
405
+ } elseif (empty($taxonomy_cat)) { // all category will filter
406
+ $taxonomy_cat = implode("', '", $this->taxonomy_cat);
407
+ }
408
+
409
+ $where = array();
410
+ $where[] = 'taxonomy IN (\'' . $taxonomy_cat . '\')';
411
+
412
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
413
+ $keyword = !empty($_GET['s']) ? $_GET['s'] : '';
414
+ $keyword = filter_var($keyword, FILTER_SANITIZE_STRING);
415
+ if (isset($keyword) && $keyword !== '') {
416
+ $where[] = $wpdb->prepare('(term_name LIKE %s OR meta_title LIKE %s OR meta_desc LIKE %s)', array(
417
+ '%' . $keyword . '%',
418
+ '%' . $keyword . '%',
419
+ '%' . $keyword . '%'
420
+ ));
421
+ }
422
+
423
+ //Order By block
424
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
425
+ $orderby = !empty($_GET['orderby']) ? ($_GET['orderby']) : 'term_name';
426
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
427
+ $order = !empty($_GET['order']) ? ($_GET['order']) : 'asc';
428
+
429
+ $sortable = $this->get_sortable_columns();
430
+ $orderby_array = array($orderby, true);
431
+ if (in_array($orderby_array, $sortable)) {
432
+ $orderStr = $orderby;
433
+ } else {
434
+ $orderStr = 'term_name';
435
+ }
436
+
437
+ if ($order === 'asc') {
438
+ $orderStr .= ' ASC';
439
+ } else {
440
+ $orderStr .= ' DESC';
441
+ }
442
+
443
+ if (!empty($orderby) & !empty($order)) {
444
+ $orderStr = ' ORDER BY ' . esc_sql($orderStr) . ' ';
445
+ }
446
+
447
+ // phpcs:disable WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
448
+ if (isset($_GET['wpms_duplicate_cat_meta']) && $_GET['wpms_duplicate_cat_meta'] !== 'none') {
449
+ if ($_GET['wpms_duplicate_cat_meta'] === 'duplicate_cat_title') {
450
+ $where[] = 'meta_title IN (SELECT DISTINCT meta_value FROM ' . $wpdb->termmeta . ' WHERE meta_key="wpms_category_metatitle" AND meta_value != "" GROUP BY meta_value HAVING COUNT(*) >= 2)';
451
+ } elseif ($_GET['wpms_duplicate_cat_meta'] === 'duplicate_cat_desc') {
452
+ $where[] = 'meta_desc IN (SELECT DISTINCT meta_value FROM ' . $wpdb->termmeta . ' WHERE meta_key="wpms_category_metadesc" AND meta_value != "" GROUP BY meta_value HAVING COUNT(*) >= 2)';
453
+ }
454
+ }
455
+
456
+ $metaQuery = 'SELECT t.term_id, t.name term_name, t.slug term_slug, tmt.meta_value meta_title, tmd.meta_value meta_desc FROM ' . $wpdb->terms . ' t LEFT JOIN '
457
+ . '(SELECT * FROM ' . $wpdb->termmeta . ' WHERE meta_key = "wpms_category_metatitle") tmt ON t.term_id = tmt.term_id'
458
+ . ' LEFT JOIN (SELECT * FROM ' . $wpdb->termmeta . ' WHERE meta_key = "wpms_category_metadesc") tmd ON t.term_id = tmd.term_id';
459
+
460
+ $query = 'SELECT COUNT(A.term_id) FROM ' . $wpdb->term_taxonomy. ' A INNER JOIN '
461
+ . '(' . $metaQuery .') BC ON A.term_id = BC.term_id';
462
+ $query .= ' WHERE ' . implode(' AND ', $where);
463
+
464
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Variable has been prepare
465
+ $total_items = $wpdb->get_var($query);
466
+
467
+ $query = 'SELECT A.term_id, term_name, term_slug, meta_title, meta_desc, taxonomy, description, parent FROM ' . $wpdb->term_taxonomy. ' A INNER JOIN '
468
+ . '(' . $metaQuery .') BC ON A.term_id = BC.term_id';
469
+
470
+ $query .= ' WHERE ' . implode(' AND ', $where) . $orderStr;
471
+
472
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
473
+ if (!empty($_REQUEST['wpms_cat_per_page'])) {
474
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
475
+ $_per_page = intval($_REQUEST['wpms_cat_per_page']);
476
+ } else {
477
+ $_per_page = 0;
478
+ }
479
+
480
+ $per_page = get_user_option('wpms_cat_per_page');
481
+ if ($per_page !== false) {
482
+ if ($_per_page && $_per_page !== $per_page) {
483
+ $per_page = $_per_page;
484
+ update_user_option(get_current_user_id(), 'wpms_cat_per_page', $per_page);
485
+ }
486
+ } else {
487
+ if ($_per_page > 0) {
488
+ $per_page = $_per_page;
489
+ } else {
490
+ $per_page = 10;
491
+ }
492
+ add_user_meta(get_current_user_id(), 'wpms_cat_per_page', $per_page);
493
+ }
494
+
495
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
496
+ $paged = !empty($_GET['paged']) ? $_GET['paged'] : '';
497
+ if (empty($paged) || !is_numeric($paged) || $paged <= 0) {
498
+ $paged = 1;
499
+ }
500
+
501
+ $total_pages = ceil($total_items / $per_page);
502
+
503
+ if (!empty($paged) && !empty($per_page)) {
504
+ $offset = ($paged - 1) * $per_page;
505
+ $query .= $wpdb->prepare(' LIMIT %d, %d', array($offset, $per_page));
506
+ }
507
+
508
+ $this->set_pagination_args(array(
509
+ 'total_items' => $total_items,
510
+ 'total_pages' => $total_pages,
511
+ 'per_page' => $per_page
512
+ ));
513
+
514
+ $columns = $this->get_columns();
515
+ $hidden = array();
516
+ $sortable = $this->get_sortable_columns();
517
+ $this->_column_headers = array($columns, $hidden, $sortable);
518
+
519
+ // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Variable has been prepare
520
+ $this->items = $wpdb->get_results($query);
521
+ }
522
+
523
+ /**
524
+ * Generate the table rows
525
+ *
526
+ * @return void
527
+ */
528
+ public function display_rows() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps -- extends from WP_List_Table class
529
+ {
530
+ $records = $this->items;
531
+ $i = 0;
532
+ $alternate = '';
533
+ $url = preg_replace('/(http|https):\/\/([w]*[.])?/', '', network_site_url('/'));
534
+ $settings = get_option('_metaseo_settings');
535
+ if (!$settings || !isset($settings['metaseo_metatitle_tab'])) {
536
+ $settings['metaseo_metatitle_tab'] = 1;
537
+ }
538
+ list($columns, $hidden) = $this->get_column_info();
539
+
540
+ if (!empty($records)) {
541
+ foreach ($records as $rec) {
542
+ foreach ($columns as $column_name => $column_display_name) {
543
+ $class = sprintf('class="%1$s column-%1$s"', esc_attr($column_name));
544
+ $style = '';
545
+
546
+ if (in_array($column_name, $hidden)) {
547
+ $style = ' style="display:none;"';
548
+ }
549
+
550
+ $attributes = $class . $style;
551
+ switch ($column_name) {
552
+ case 'cb':
553
+ echo '<td scope="row" class="check-column">';
554
+ echo '<input id="' . esc_attr('cb-select-' . $rec->term_id) . '"
555
+ class="wpms_cat_cb" type="checkbox" value="' . esc_attr($rec->term_id) . '">';
556
+ echo '</td>';
557
+ break;
558
+
559
+ case 'col_cat_title':
560
+ $cat_name = stripslashes($rec->term_name);
561
+ if ($cat_name === '') {
562
+ $cat_name = esc_html__('(no category)', 'wp-meta-seo');
563
+ }
564
+
565
+ echo sprintf(
566
+ '<td id="col_cat_name-' . esc_attr($rec->term_id) . '" %2$s><div class="wpms-category-title">'
567
+ . '<strong id="' . esc_attr('post-title-' . $rec->term_id) . '" class="post-title">%1$s</strong>',
568
+ esc_html($cat_name),
569
+ $attributes // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
570
+ );
571
+
572
+ $taxonomy_object = get_taxonomy($rec->taxonomy);
573
+ $can_edit_cat = current_user_can($taxonomy_object->cap->edit_terms, $rec->term_id);
574
+ $can_del_cat = current_user_can($taxonomy_object->cap->delete_terms, $rec->term_id);
575
+ $actions = array();
576
+ // Edit category
577
+ if ($can_edit_cat) {
578
+ $actions['edit'] = '<a href="' . esc_url(get_edit_term_link($rec->term_id)) . '"
579
+ title="' . esc_attr__('Edit this category', 'wp-meta-seo') . '"
580
+ >' . esc_html__('Edit', 'wp-meta-seo') . '</a>';
581
+ }
582
+ // Preview category
583
+ $actions['view'] = '<a target="_blank" href="' . esc_url(get_category_link($rec->term_id)) . '"
584
+ title="' . esc_attr__('Preview this category', 'wp-meta-seo') . '"
585
+ >' . esc_html__('View', 'wp-meta-seo') . '</a>';
586
+
587
+ // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
588
+ echo $this->row_actions($actions);
589
+ break;
590
+ case 'col_cat_snippet':
591
+ echo '<td id="col_meta_seo-' . esc_attr($rec->term_id) . '"><div class="col-metaseo-wrapper">';
592
+ echo '<span class="snippet_metalink" style="padding-left: 10px;" id="' . esc_attr('snippet_metalink_' . $rec->term_id) . '">
593
+ ' . esc_url(get_category_link($rec->term_id)) . '</span>';
594
+ // <!-- Engine title -->
595
+ echo '<div class="custom-bulk-content-b wpms-category-title">';
596
+ echo '<input type="text" placeholder="Put your meta description here. Click here to edit..." class="large-text wpms_category_metatitle wpms-category-title-input wpms-cat-meta-title intro-topic-tooltip" rows="1"'
597
+ . ' id="wpms-cat-meta-title-'. esc_attr($rec->term_id) . '" name="wpms_meta_title['. esc_attr($rec->term_id) . ']" autocomplete="off"'
598
+ . ' value="'. esc_html($rec->meta_title) . '" data-tippy="This is your category meta title that should be displayed in Google Search results for this page">';
599
+ // title counter
600
+ echo sprintf(
601
+ '<div class="title-len wpms-cat-title-len" style="bottom: 32px" id="%1$s"></div>',
602
+ esc_attr('wpms-cat-title-len' . $rec->term_id)
603
+ );
604
+ echo '</div>';
605
+ // <!-- /Engine title -->
606
+ // <!-- Engine description -->
607
+ echo '<div class="custom-bulk-content-b wpms-category-desc">';
608
+ echo '<textarea placeholder="Put your meta description here. Click here to edit..." class="large-text wpms_category_metadesc wpms-category-desc-textarea wpms-cat-meta-desc intro-topic-tooltip"'
609
+ . ' id="wpms-cat-meta-desc-'. esc_attr($rec->term_id) . '" name="wpms_meta_desc['. esc_attr($rec->term_id) . ']" autocomplete="off" data-tippy="This is your category meta description that should be displayed in Google Search results for this page">'. esc_textarea($rec->meta_desc) . '</textarea>';
610
+ // description counter
611
+ echo sprintf(
612
+ '<div class="desc-len wpms-cat-desc-len" style="bottom: 45px" id="%1$s"></div>',
613
+ esc_attr('wpms-cat-desc-len' . $rec->term_id)
614
+ );
615
+ echo '</div>'; // <!-- /Engine description -->
616
+ // loader and success message
617
+ echo '<img id="wpms-cat-imgloader-'. esc_attr($rec->term_id) . '" class="' . esc_attr('wpms_cat_loader' . $rec->term_id . ' wpms_content_loader') . '"
618
+ src=' . esc_url(WPMETASEO_PLUGIN_URL) . 'assets/images/update_loading.gif>';
619
+ echo '<span id="wpms-cat-return-msg-'. esc_attr($rec->term_id) . '"
620
+ style="display: inline-block; visibility: hidden"
621
+ class="saved-info metaseo-msg-success">test wpms msg</span>';
622
+ echo '</div></td>'; // <!-- /Wrapper -->
623
+ break;
624
+ }
625
+ }
626
+
627
+ echo '</tr>';
628
+ }
629
+ }
630
+ }
631
+
632
+ /**
633
+ * Retrieves a modified URL query string.
634
+ *
635
+ * @return void
636
+ */
637
+ public function processAction()
638
+ {
639
+ $current_url = set_url_scheme('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
640
+ $redirect = false;
641
+ // phpcs:disable WordPress.Security.NonceVerification.Missing -- No action, nonce is not required
642
+ if (isset($_POST['taxonomy_filter'])) {
643
+ $current_url = add_query_arg(array('taxonomy_filter' => $_POST['taxonomy_filter']), $current_url);
644
+ $redirect = true;
645
+ }
646
+
647
+ if (isset($_POST['wpms_duplicate_cat_meta'])) {
648
+ $current_url = add_query_arg(array('wpms_duplicate_cat_meta' => $_POST['wpms_duplicate_cat_meta']), $current_url);
649
+ $redirect = true;
650
+ }
651
+
652
+ if (isset($_POST['wpms_lang_list'])) {
653
+ $current_url = add_query_arg(array('wpms_lang_list' => $_POST['wpms_lang_list']), $current_url);
654
+ $redirect = true;
655
+ }
656
+
657
+ if (!empty($_POST['paged'])) {
658
+ $current_url = add_query_arg(array('paged' => intval($_POST['paged'])), $current_url);
659
+ $redirect = true;
660
+ }
661
+
662
+ if (!empty($_POST['wpms_cat_per_page'])) {
663
+ $current_url = add_query_arg(
664
+ array(
665
+ 'wpms_cat_per_page' => intval($_POST['wpms_cat_per_page'])
666
+ ),
667
+ $current_url
668
+ );
669
+ $redirect = true;
670
+ }
671
+
672
+ if (isset($_POST['s'])) {
673
+ $current_url = add_query_arg(array('s' => urlencode($_POST['s'])), $current_url);
674
+ $redirect = true;
675
+ }
676
+ // phpcs:enable
677
+ if ($redirect) {
678
+ wp_redirect($current_url);
679
+ ob_end_flush();
680
+ exit();
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Update categories content field
686
+ *
687
+ * @return void
688
+ */
689
+ public function updateCategoryContent()
690
+ {
691
+ if (empty($_POST['wpms_nonce'])
692
+ || !wp_verify_nonce($_POST['wpms_nonce'], 'wpms_nonce')) {
693
+ die();
694
+ }
695
+ if (!isset($_POST['termID']) || !isset($_POST['dataType']) || !isset($_POST['data'])
696
+ || empty($_POST['termID']) || empty($_POST['dataType'])) {
697
+ die('-1');
698
+ }
699
+ $termID = filter_var($_POST['termID'], FILTER_SANITIZE_STRING);
700
+ $dataType = filter_var($_POST['dataType'], FILTER_SANITIZE_STRING);
701
+ $data = filter_var($_POST['data'], FILTER_SANITIZE_STRING);
702
+ $response = array('updated'=> false, 'msg' => 'Some things went wrong');
703
+ if (!current_user_can('manage_options')) {
704
+ $response['msg'] = 'Permission denied';
705
+ wp_send_json($response);
706
+ }
707
+ if (!empty($termID) && !empty($dataType) && isset($data)) {
708
+ switch ($dataType) {
709
+ case 'wpms-cat-meta-title':
710
+ update_term_meta($termID, 'wpms_category_metatitle', $data);
711
+ $response['updated'] = true;
712
+ $response['msg'] = 'Meta seo title was saved';
713
+ break;
714
+ case 'wpms-cat-meta-desc':
715
+ update_term_meta($termID, 'wpms_category_metadesc', $data);
716
+ $response['updated'] = true;
717
+ $response['msg'] = 'Meta seo description was saved';
718
+ break;
719
+ }
720
+ }
721
+ echo json_encode($response);
722
+ wp_die();
723
+ }
724
+
725
+ /**
726
+ * Delete cat category
727
+ *
728
+ * @return void
729
+ */
730
+ public function wpmsDeleteCat()
731
+ {
732
+ if (empty($_POST['wpms_nonce'])
733
+ || !wp_verify_nonce($_POST['wpms_nonce'], 'wpms_nonce')) {
734
+ die();
735
+ }
736
+ if (!isset($_POST['catData'])) {
737
+ die('Category data not found');
738
+ }
739
+ $catData = $_POST['catData'];
740
+ $term_id = (int)($catData['term_id']);
741
+ $taxonomy = filter_var($catData['taxonomy'], FILTER_SANITIZE_STRING);
742
+ $response = array('status' => false, 'msg' => 'Something went wrong');
743
+ if ($term_id && $taxonomy) {
744
+ if (wp_delete_term($term_id, $taxonomy)) {
745
+ $response['status'] = true;
746
+ $response['msg'] = 'Delete category successfully';
747
+ }
748
+ }
749
+ wp_send_json($response);
750
+ wp_die();
751
+ }
752
+
753
+ /**
754
+ * Bulk copy category meta title/description
755
+ *
756
+ * @return void
757
+ */
758
+ public function wpmsBulkCatCopy()
759
+ {
760
+ if (empty($_POST['wpms_nonce'])
761
+ || !wp_verify_nonce($_POST['wpms_nonce'], 'wpms_nonce')) {
762
+ die();
763
+ }
764
+ if (!isset($_POST['catData'])) {
765
+ die('Category data not found');
766
+ }
767
+ $catData = $_POST['catData'];
768
+ $taxonomy = array('category', 'product_cat');
769
+ if (isset($catData['sl_bulk']) && $catData['sl_bulk'] === 'all') {
770
+ $msArgs = array(
771
+ 'taxonomy' => $taxonomy,
772
+ 'hide_empty' => false,
773
+ );
774
+ } elseif (isset($catData['sl_bulk']) && $catData['sl_bulk'] === 'only-selection' && isset($catData['msCatSelected'])) {
775
+ $msArgs = array(
776
+ 'taxonomy' => $taxonomy,
777
+ 'hide_empty' => false,
778
+ 'include' => (array)$catData['msCatSelected']
779
+ );
780
+ }
781
+ $msTermQuery = new WP_Term_Query($msArgs);
782
+ $msTerms = $msTermQuery->get_terms();
783
+ if (!isset($catData['action_name'])) {
784
+ return;
785
+ }
786
+ $action = $catData['action_name'];
787
+ if ($action === 'cat-name-to-title') {
788
+ $meta_key = 'wpms_category_metatitle';
789
+ } else {
790
+ $meta_key = 'wpms_category_metadesc';
791
+ }
792
+ $response = array('updated' => false);
793
+ if (!empty($msTerms)) {
794
+ foreach ($msTerms as $term) {
795
+ $meta_value = $term->name;
796
+ $meta_value = sanitize_text_field($meta_value);
797
+ update_term_meta($term->term_id, $meta_key, $meta_value);
798
+ $response['updated'] = true;
799
+ }
800
+ }
801
+ wp_send_json($response);
802
+ wp_die();
803
+ }
804
+ }
inc/class.metaseo-metabox.php CHANGED
@@ -39,10 +39,12 @@ class WPMSEOMetabox extends WPMSEOMeta
39
  add_action('edit_attachment', array($this, 'savePostData'));
40
  add_action('add_attachment', array($this, 'savePostData'));
41
  add_action('admin_init', array($this, 'translateMetaBoxes'));
 
 
42
  }
43
 
44
  /**
45
- * Save post
46
  *
47
  * @param integer $post_id Post id
48
  *
@@ -50,7 +52,6 @@ class WPMSEOMetabox extends WPMSEOMeta
50
  */
51
  public function savePostData($post_id)
52
  {
53
-
54
  // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification -- Nonce used in next lines
55
  if (isset($_POST['metaseo_wpmseo_title'])) {
56
  if (empty($_POST['_wpnonce'])
@@ -62,7 +63,6 @@ class WPMSEOMetabox extends WPMSEOMeta
62
  if ($post_id === null) {
63
  return false;
64
  }
65
-
66
  if (wp_is_post_revision($post_id)) {
67
  $post_id = wp_is_post_revision($post_id);
68
  }
@@ -72,7 +72,6 @@ class WPMSEOMetabox extends WPMSEOMeta
72
  if (!is_object($post)) {
73
  return false;
74
  }
75
-
76
  do_action('wpmseo_save_compare_data', $post);
77
 
78
  $meta_boxes = apply_filters('wpmseo_save_metaboxes', array());
@@ -85,7 +84,6 @@ class WPMSEOMetabox extends WPMSEOMeta
85
  $this->getMetaFieldDefs('advanced'),
86
  $this->getMetaFieldDefs('social')
87
  );
88
-
89
  foreach ($meta_boxes as $key => $meta_box) {
90
  if ($key === 'facebook' || $key === 'twitter') {
91
  foreach ($meta_box as $k => $social) {
@@ -110,7 +108,6 @@ class WPMSEOMetabox extends WPMSEOMeta
110
  $data = $_POST[self::$form_prefix . $key];
111
  }
112
  }
113
-
114
  if ('metaseo_canonical' === $meta_box['type']) {
115
  // Convert data of canonical
116
  $data = MetaSeoAdmin::convertCanonicalUrlToSave($data);
@@ -130,6 +127,44 @@ class WPMSEOMetabox extends WPMSEOMeta
130
  return true;
131
  }
132
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  /**
134
  * Translate text strings for use in the meta box
135
  *
@@ -138,7 +173,7 @@ class WPMSEOMetabox extends WPMSEOMeta
138
  public static function translateMetaBoxes()
139
  {
140
  self::$meta_fields['general']['snippetpreview']['title'] = esc_html__('Results preview', 'wp-meta-seo');
141
- self::$meta_fields['general']['snippetpreview']['help'] = sprintf(
142
  esc_attr__('This is a preview of what your content will looks like
143
  in search engine results: title, description and URL', 'wp-meta-seo'),
144
  '<a target="_blank" href="https://www.joomunited.com/wordpress-products/wpms">',
@@ -146,47 +181,47 @@ class WPMSEOMetabox extends WPMSEOMeta
146
  );
147
 
148
  self::$meta_fields['general']['specific_keywords']['title'] = esc_html__('Page SEO keywords', 'wp-meta-seo');
149
- self::$meta_fields['general']['specific_keywords']['help'] = esc_attr__('Add the keywords related to your page, the SEO checker will verify if at least one of the SEO keywords are found in your content', 'wp-meta-seo');
150
 
151
  $settings = get_option('_metaseo_settings');
152
- if (isset($settings['metaseo_showkeywords']) && (int) $settings['metaseo_showkeywords'] === 1) {
153
  self::$meta_fields['general']['keywords']['title'] = esc_html__('Search engine keywords', 'wp-meta-seo');
154
  self::$meta_fields['general']['keywords']['description'] = '<span id="metaseo_wpmseo_keywords-length" class="length-box-meta"></span>';
155
- self::$meta_fields['general']['keywords']['help'] = esc_attr__('This is the keywords of your content that may be
156
  displayed in search engine results (meta keywords).', 'wp-meta-seo');
157
  } else {
158
  unset(self::$meta_fields['general']['keywords']);
159
  }
160
 
161
- if (isset($settings['metaseo_canonical']) && (int) $settings['metaseo_canonical'] === 1) {
162
  self::$meta_fields['general']['metaseo_canonical']['title'] = esc_html__('Canonical URL', 'wp-meta-seo');
163
  self::$meta_fields['general']['metaseo_canonical']['description'] = '';
164
- self::$meta_fields['general']['metaseo_canonical']['help'] = esc_attr__('Put the canonical URL which this page should point to. By default, it\'s the permalink', 'wp-meta-seo');
165
  } else {
166
  unset(self::$meta_fields['general']['metaseo_canonical']);
167
  }
168
 
169
- self::$meta_fields['social']['facebook']['opengraph-title']['title'] = esc_html__('Facebook Title', 'wp-meta-seo');
170
  self::$meta_fields['social']['facebook']['opengraph-title']['description'] = esc_html__('Custom title to display when
171
  sharing this content on facebook, content title override', 'wp-meta-seo');
172
 
173
- self::$meta_fields['social']['facebook']['opengraph-desc']['title'] = esc_html__('Facebook Description', 'wp-meta-seo');
174
  self::$meta_fields['social']['facebook']['opengraph-desc']['description'] = esc_html__('Custom description to display when sharing
175
  this content on facebook, content description override', 'wp-meta-seo');
176
 
177
- self::$meta_fields['social']['facebook']['opengraph-image']['title'] = esc_html__('Facebook Image', 'wp-meta-seo');
178
  self::$meta_fields['social']['facebook']['opengraph-image']['description'] = esc_html__('Custom image to display when sharing
179
  this content on facebook, content description override, recommended size is 1200px x 630px', 'wp-meta-seo');
180
 
181
- self::$meta_fields['social']['twitter']['twitter-title']['title'] = esc_html__('Twitter Title', 'wp-meta-seo');
182
  self::$meta_fields['social']['twitter']['twitter-title']['description'] = esc_html__('Custom title to display when sharing this
183
  content on twitter, content title override', 'wp-meta-seo');
184
 
185
- self::$meta_fields['social']['twitter']['twitter-desc']['title'] = esc_html__('Twitter Description', 'wp-meta-seo');
186
  self::$meta_fields['social']['twitter']['twitter-desc']['description'] = esc_html__('Custom description to display when sharing
187
  this content on twitter, content description override', 'wp-meta-seo');
188
 
189
- self::$meta_fields['social']['twitter']['twitter-image']['title'] = esc_html__('Twitter Image', 'wp-meta-seo');
190
  self::$meta_fields['social']['twitter']['twitter-image']['description'] = esc_html__('Custom image to display when sharing
191
  this content on facebook, content description override, recommended min size 440px X 220px', 'wp-meta-seo');
192
 
@@ -206,13 +241,13 @@ class WPMSEOMetabox extends WPMSEOMeta
206
  'post.php',
207
  'edit.php',
208
  ), true)
209
- && apply_filters('wpmseo_always_register_metaboxes_on_admin', false) === false)
210
  ) {
211
  return;
212
  }
213
 
214
  if ($pagenow !== 'edit.php') {
215
- if (0 !== (int) get_queried_object_id()) {
216
  // Enqueue files needed for upload functionality.
217
  wp_enqueue_media(
218
  array(
@@ -266,28 +301,13 @@ class WPMSEOMetabox extends WPMSEOMeta
266
  '2.2.1',
267
  true
268
  );
269
- wp_enqueue_script(
270
- 'wpms-tippy',
271
- plugins_url('assets/tippy/tippy.js', WPMSEO_FILE),
272
- array('jquery'),
273
- '2.2.1',
274
- true
275
- );
276
  wp_enqueue_script(
277
- 'm-wp-seo-metabox',
278
- plugins_url('assets/js/wp-metaseo-metabox.js', WPMSEO_FILE),
279
- array('jquery', 'jquery-ui-core'),
280
- WPMSEO_VERSION,
281
- true
282
- );
283
- wp_enqueue_script(
284
- 'mwpseo-admin-media',
285
- plugins_url('assets/js/wp-metaseo-admin-media.js', WPMSEO_FILE),
286
- array('jquery', 'jquery-ui-core'),
287
- WPMSEO_VERSION,
288
  true
289
  );
290
-
291
  wp_enqueue_script(
292
  'metaseo-circle-progress',
293
  plugins_url('assets/js/circle-progress.js', WPMSEO_FILE),
@@ -295,41 +315,62 @@ class WPMSEOMetabox extends WPMSEOMeta
295
  WPMSEO_VERSION,
296
  true
297
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
 
299
  wp_enqueue_script(
300
- 'metaseo-cliffpyles',
301
- plugins_url('assets/js/cliffpyles.js', WPMSEO_FILE),
302
- array('jquery', 'metaseo-circle-progress'),
303
  WPMSEO_VERSION,
304
  true
305
  );
306
-
307
- wp_enqueue_style(
308
- 'm-bootstrap-tagsinput',
309
- plugins_url('assets/css/bootstrap/bootstrap.tagsinput.css', WPMSEO_FILE),
310
- array(),
311
- WPMSEO_VERSION
312
- );
313
-
314
- wp_enqueue_script(
315
- 'metaseo-bootstrap-tagsinput',
316
- plugins_url('assets/js/bootstrap/bootstrap-tagsinput.min.js', WPMSEO_FILE),
317
- array('jquery'),
318
- WPMSEO_VERSION,
319
- true
320
- );
321
-
322
- wp_enqueue_script(
323
- 'wpms-seokeyword-metabox',
324
- plugins_url('assets/js/wpms-seokeyword-metabox.min.js', WPMSEO_FILE),
325
- array('wp-data', 'jquery')
326
- );
327
 
328
  wp_localize_script('m-wp-seo-metabox', 'wpmseoMetaboxL10n', $this->localizeScript());
329
  wp_localize_script('wpms-seokeyword-metabox', 'wpmseoMetaboxL10n', $this->localizeScript());
 
 
330
  $localize = $this->localizeSettingsScript();
331
  wp_localize_script('mwpseo-admin-media', 'wpmseoMediaL10n', $localize);
 
332
  wp_localize_script('metaseo-cliffpyles', 'wpmscliffpyles', $localize);
 
333
  }
334
  }
335
 
@@ -350,17 +391,17 @@ class WPMSEOMetabox extends WPMSEOMeta
350
  }
351
 
352
  $this->settings = array(
353
- 'metaseo_title_home' => '',
354
- 'metaseo_desc_home' => '',
355
- 'metaseo_showfacebook' => '',
356
- 'metaseo_showtwitter' => '',
357
- 'metaseo_twitter_card' => 'summary',
358
- 'metaseo_showkeywords' => 0,
359
  'metaseo_showtmetablock' => 1,
360
- 'metaseo_showsocial' => 1,
361
- 'metaseo_seovalidate' => 0
362
  );
363
- $settings = get_option('_metaseo_settings');
364
 
365
  if (is_array($settings)) {
366
  $this->settings = array_merge($this->settings, $settings);
@@ -370,7 +411,8 @@ class WPMSEOMetabox extends WPMSEOMeta
370
  'choose_image' => esc_html__('Use Image', 'wp-meta-seo'),
371
  'use_validate' => $this->settings['metaseo_seovalidate'],
372
  'post_title' => $post_title,
373
- 'post_content' => $post_content
 
374
  );
375
  }
376
 
@@ -386,12 +428,12 @@ class WPMSEOMetabox extends WPMSEOMeta
386
  if ((!is_object($post) || !isset($post->post_type))) {
387
  return array();
388
  }
389
- $settings = get_option('_metaseo_settings');
390
  self::$meta_length_reason = apply_filters('wpmseo_desc_length_reason', self::$meta_length_reason, $post);
391
- self::$meta_length = apply_filters('wpmseo_desc_length', self::$meta_length, $post);
392
- $title_template = '%title%';
393
 
394
- $desc_template = '';
395
  $sample_permalink = get_sample_permalink($post->ID);
396
  $sample_permalink = str_replace('%page', '%post', $sample_permalink[0]);
397
 
@@ -400,18 +442,18 @@ class WPMSEOMetabox extends WPMSEOMeta
400
  $settings['metaseo_metatitle_tab'] = 1;
401
  }
402
  $vars_to_cache = array(
403
- 'date' => wpmsRetrieveDate($post),
404
- 'id' => !(empty($post->ID)) ? $post->ID : null,
405
- 'sitename' => trim(strip_tags(get_bloginfo('name'))),
406
- 'sitedesc' => trim(strip_tags(get_bloginfo('description'))),
407
- 'sep' => '-',
408
- 'page' => '',
409
- 'currenttime' => date_i18n(get_option('time_format')),
410
- 'currentdate' => date_i18n(get_option('date_format')),
411
- 'currentday' => date_i18n('j'),
412
  'currentmonth' => date_i18n('F'),
413
- 'currentyear' => date_i18n('Y'),
414
- 'metatitle_tab'=> (!empty($settings['metaseo_metatitle_tab']) ? '1' : '0')
415
  );
416
 
417
  foreach ($vars_to_cache as $var => $value) {
@@ -420,7 +462,7 @@ class WPMSEOMetabox extends WPMSEOMeta
420
 
421
  $check_connected = false;
422
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
423
- // get domain
424
  $option = get_option(WPMS_GSC, array('profile' => ''));
425
  if (!empty($option['profile'])) {
426
  $check_connected = true;
@@ -428,27 +470,28 @@ class WPMSEOMetabox extends WPMSEOMeta
428
  }
429
 
430
  $cached_replacement_vars['sitename'] = get_option('blogname');
431
- $plugin_active = json_encode(get_option('active_plugins'));
432
- $array_keyword = array(
433
- 'plugin_active' => $plugin_active,
434
- 'field_prefix' => self::$form_prefix,
435
- 'choose_image' => esc_html__('Use Image', 'wp-meta-seo'),
436
- 'wpmseo_meta_desc_length' => self::$meta_length,
437
- 'wpmseo_meta_title_length' => self::$meta_title_length,
438
- 'wpmseo_meta_keywords_length' => self::$meta_keywords_length,
439
- 'wpmseo_title_template' => $title_template,
440
- 'wpmseo_desc_template' => $desc_template,
441
- 'wpmseo_permalink_template' => $sample_permalink,
442
  'wpmseo_keyword_suggest_nonce' => wp_create_nonce('wpmseo-get-suggest'),
443
- 'wpmseo_replace_vars_nonce' => wp_create_nonce('wpmseo-replace-vars'),
444
- 'no_parent_text' => esc_html__('(no parent)', 'wp-meta-seo'),
445
- 'show_keywords' => 0,
446
- 'image_loader' => esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/ajax-loader1.gif'),
447
- 'keyword_filter_return' => esc_html__('No search queries are currently indexed in the search console... Try typing custom keywords.', 'wp-meta-seo'),
448
- 'keyword_console_connected' => ($check_connected) ? 1 : 0
 
449
  );
450
- $settings = get_option('_metaseo_settings');
451
- if (isset($settings['metaseo_showkeywords']) && (int) $settings['metaseo_showkeywords'] === 1) {
452
  $array_keyword['show_keywords'] = 1;
453
  }
454
 
@@ -473,6 +516,143 @@ class WPMSEOMetabox extends WPMSEOMeta
473
  }
474
  }
475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
476
  /**
477
  * Output the meta box
478
  *
@@ -480,80 +660,89 @@ class WPMSEOMetabox extends WPMSEOMeta
480
  */
481
  public function metaBox()
482
  {
 
 
 
 
 
 
 
 
 
 
 
 
483
  $this->metaseoEnqueue();
484
- $post = $this->getMetaboxPost();
485
  $default_settings = array(
486
- 'metaseo_title_home' => '',
487
- 'metaseo_desc_home' => '',
488
- 'metaseo_showfacebook' => '',
489
- 'metaseo_showtwitter' => '',
490
- 'metaseo_twitter_card' => 'summary',
491
  'metaseo_showtmetablock' => 1,
492
- 'metaseo_showsocial' => 1
493
  );
494
- $settings = get_option('_metaseo_settings');
495
  if (is_array($settings)) {
496
  $default_settings = array_merge($default_settings, $settings);
497
  }
498
  $check_connected = false;
499
- $service = false;
500
- ?>
501
- <div class="wpmseo-metabox-tabs-div">
502
  <ul class="wpmseo-metabox-tabs tabs ju-tabs wpmstabs" id="wpmseo-metabox-tabs">
503
  <li class="tab wpmstab col">
504
- <a class="wpmseo_tablink"
505
- href="#wpmseo_general"><?php esc_html_e('SEO Page optimization', 'wp-meta-seo'); ?></a>
506
- </li>
507
- <?php
508
- if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
509
- $service = $this->serverWebmaster();
510
- if (!empty($service)) {
511
- // get domain
512
- $option = get_option(WPMS_GSC, array('profile' => ''));
513
- if (!empty($option['profile'])) {
514
- $check_connected = true;
515
- }
516
- }
517
- if ($check_connected) {
518
- echo '<li class="tab wpmstab col">';
519
- echo '<a class="wpmseo_tablink" href="#wpmseo_gsc_keywords">';
520
- esc_html_e('Search console keywords', 'wp-meta-seo');
521
- echo '</a>';
522
- echo '</li>';
523
  }
524
  }
525
- ?>
526
-
527
- <?php if ((isset($default_settings['metaseo_showsocial'])
528
- && (int) $default_settings['metaseo_showsocial'] === 1)) : ?>
529
- <li class="tab wpmstab col">
530
- <a class="wpmseo_tablink"
531
- href="#wpmseo_social"><?php esc_html_e('Social for search engine', 'wp-meta-seo') ?></a>
532
- </li>
533
- <?php endif; ?>
534
- <?php do_action('wpmseo_tab_header'); ?>
535
- </ul>
536
- <?php
 
 
 
 
 
 
537
  $content = '';
538
  if (is_object($post) && isset($post->post_type)) {
539
  foreach ($this->getMetaFieldDefs('general', $post->post_type) as $key => $meta_field) {
540
  $content .= $this->doMetaBox($meta_field, $key);
541
  if ($key === 'title') {
542
  $snippet_more = '%date%, %id%, %sitename%, %sitedesc%, %page%, %currenttime%, %currentdate%, %currentday%, %currentmonth%, %currentyear%';
543
- $content .= '<p class="description" style="margin: 0 0 10px 32px;">'.sprintf(esc_html__('Title and description variables: %s', 'wp-meta-seo'), '%title%, <span onclick="jQuery(this).text(\''.$snippet_more.'\').removeClass(\'snippet-more\')" class="snippet-more">more...</span>').'</p>';
544
  }
545
  }
546
  unset($key, $meta_field);
547
  }
548
- $this->doTab('wpmseo_general', $content);
549
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
550
  if ($check_connected) {
551
  // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method MetaSeoAddonAdmin::gscKeywords
552
- echo apply_filters('wpmsaddon_google_search_keywords', '', $post->post_content, $service);
553
  }
554
  }
555
 
556
 
 
557
  $content = '';
558
 
559
  $social = $this->getMetaFieldDefs('social');
@@ -561,20 +750,20 @@ class WPMSEOMetabox extends WPMSEOMeta
561
  $content .= '<div class="metabox-social-block">';
562
  if ($k === 'facebook') {
563
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook.png';
564
- $srcset2x = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook@2x.png';
565
- $srcset3x = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook@3x.png';
566
- $img = '<img src="'.esc_url($image_src).'"
567
- srcset="'.esc_url($srcset2x).' 2x,'.esc_url($srcset3x).' 3x"
568
  class="social-img">';
569
- $content .= '<h2 class="wpms-top-h2" style="padding: 0 20px">' . $img . '<span>' . esc_html__('Facebook', 'wp-meta-seo') .'</span></h2>';
570
  } elseif ($k === 'twitter') {
571
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter.png';
572
- $srcset2x = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter@2x.png';
573
- $srcset3x = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter@3x.png';
574
- $img = '<img src="'.esc_url($image_src).'"
575
- srcset="'.esc_url($srcset2x).' 2x,'.esc_url($srcset3x).' 3x"
576
  class="social-img">';
577
- $content .= '<h2 class="wpms-top-h2" style="padding: 0 20px">' . $img . '<span>' . esc_html__('Twitter', 'wp-meta-seo') .'</span></h2>';
578
  }
579
 
580
  foreach ($fields as $key => $field) {
@@ -583,13 +772,14 @@ class WPMSEOMetabox extends WPMSEOMeta
583
  $content .= '</div>';
584
  }
585
 
586
- if ((isset($default_settings['metaseo_showsocial']) && (int) $default_settings['metaseo_showsocial'] === 1)) {
587
- $this->doTab('wpmseo_social', $content);
588
  }
589
 
590
  do_action('wpmseo_tab_content');
591
 
592
- echo '</div>';
 
593
  }
594
 
595
  /**
@@ -610,19 +800,19 @@ class WPMSEOMetabox extends WPMSEOMeta
610
 
611
  $conn = get_option('wpms_gsc_connect');
612
  if (!empty($conn['googleClientId']) && !empty($conn['googleClientSecret'])) {
613
- $client_id = $conn['googleClientId'];
614
  $client_secret = $conn['googleClientSecret'];
615
  } else {
616
- $client_id = WPMSEO_ADDON_CLIENT_ID;
617
  $client_secret = WPMSEO_ADDON_CLIENT_SECRET;
618
  }
619
 
620
  $gsc = array(
621
  'application_name' => 'WP Meta SEO',
622
- 'client_id' => $client_id,
623
- 'client_secret' => $client_secret,
624
- 'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
625
- 'scopes' => array('https://www.googleapis.com/auth/webmasters'),
626
  );
627
 
628
  $this->client = new Wpms_Api_Google_Client($gsc, 'wpms-gsc', 'https://www.googleapis.com/webmasters/v3/');
@@ -645,19 +835,19 @@ class WPMSEOMetabox extends WPMSEOMeta
645
  $seokeywords_result = get_post_meta($post->ID, 'wp_metaseo_seoscore', true);
646
  $output = '';
647
  $circliful = 0;
648
- $output .= '<div class="wpms_width_100">';
649
- $output .= '<div class="metaseo_left" style="margin-top: 25px;">
650
  <div class="metaseo-progress-bar" data-post_id="' . esc_attr($post->ID) . '"><strong></strong></div>
651
  <input type="hidden" id="progressController" value="' . esc_attr($circliful) . '" />
652
  <input type="hidden" id="metaseo_alanysis_ok" value="' . esc_attr($this->perc_score) . '" />
653
  </div>';
654
 
655
- $output .= '<div class="metaseo_right" style="margin-top: 10px;">';
656
- $output .= '<div class="panel-left" style="width: 50%; float: left"></div>';
657
- $output .= '<div class="panel-right seokeyword-information" style="width: 50%; float: left"></div>';
658
  $output .= '<div style="clear: both"></div>';
659
  $output .= '</div>';
660
- $output .= '<input type="hidden" id="wpmetaseo_seo_keywords_result" name="wpmetaseo_seo_keywords_result" value="'.(!empty($seokeywords_result) ? $seokeywords_result : 0).'" />';
661
  $output .= '</div>';
662
  return $output;
663
  }
@@ -673,10 +863,10 @@ class WPMSEOMetabox extends WPMSEOMeta
673
  public function doMetaBox($meta_field_def, $key = '')
674
  {
675
  wp_enqueue_style('metaseo-google-icon');
676
- $content = '';
677
  $esc_form_key = esc_attr(self::$form_prefix . $key);
678
- $post = $this->getMetaboxPost();
679
- $meta_value = self::getValue($key, $post->ID);
680
 
681
  $class = '';
682
  if (isset($meta_field_def['class']) && $meta_field_def['class'] !== '') {
@@ -696,7 +886,7 @@ class WPMSEOMetabox extends WPMSEOMeta
696
  $content .= '<input type="text" id="' . esc_attr($esc_form_key) . '" name="' . esc_attr($esc_form_key) . '" value="' . esc_attr($meta_value) . '" data-role="tagsinput" />';
697
  break;
698
  case 'metaseo_canonical':
699
- $placeholder = ' placeholder="'.esc_html__('Put canonical URL in field', 'wp-meta-seo') . '"';
700
  $ac = '';
701
  if (isset($meta_field_def['autocomplete']) && $meta_field_def['autocomplete'] === false) {
702
  $ac = 'autocomplete="off" ';
@@ -738,7 +928,7 @@ class WPMSEOMetabox extends WPMSEOMeta
738
  class="' . esc_attr('metaseo' . $class) . '">';
739
  foreach ($meta_field_def['options'] as $val => $option) {
740
  $selected = selected($meta_value, $val, false);
741
- $content .= '<option ' . $selected . '
742
  value="' . esc_attr($val) . '">' . esc_html($option) . '</option>';
743
  }
744
  unset($val, $option, $selected);
@@ -750,7 +940,7 @@ class WPMSEOMetabox extends WPMSEOMeta
750
  $content .= '<input id="' . esc_attr($esc_form_key) . '" type="text" size="36" class="' . esc_attr($class) . '"
751
  name="' . esc_attr($esc_form_key) . '" value="' . esc_attr($meta_value) . '" />';
752
  $content .= '<button id="' . esc_attr($esc_form_key) . '_button" class="wpmseo_image_upload_button ju-button orange-button wpms-small-btn"
753
- type="button">'.esc_html__('Upload Image', 'wp-meta-seo').'</button>';
754
  break;
755
  }
756
 
@@ -781,7 +971,7 @@ class WPMSEOMetabox extends WPMSEOMeta
781
  $help = '';
782
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/question/question.png';
783
  if (isset($meta_field_def['help']) && $meta_field_def['help'] !== '') {
784
- $help = '<img src="'.esc_url($image_src).'" class="meta-question metaseo_help" id="' . esc_attr($key . 'help') . '" data-tippy="' . esc_attr($meta_field_def['help']) . '">';
785
  }
786
 
787
  if (isset($meta_field_def['description'])) {
@@ -790,9 +980,9 @@ class WPMSEOMetabox extends WPMSEOMeta
790
  }
791
  }
792
 
793
- $html = '<div class="'. esc_html($meta_field_def['classrow'] . ' wpms_left optimization-row-box') .'">';
794
- $html .= '<label class="ju-setting-label wpms_width_100 wpms_left p-l-0">'. $label . $help .'</label>';
795
- $html .= '<label class="wpms_width_100 label-input wpms_left p-t-20 snippet-preview">'. $content .'</label>';
796
  if (isset($meta_field_def['description'])) {
797
  if (!strpos($meta_field_def['class'], 'has-length') !== false) {
798
  $html .= '<p class="description">' . $meta_field_def['description'] . '</p>';
@@ -813,8 +1003,8 @@ class WPMSEOMetabox extends WPMSEOMeta
813
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
814
  if (isset($_GET['post'])) {
815
  //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
816
- $post_id = (int) $_GET['post'];
817
- $post = get_post($post_id);
818
  } else {
819
  $post = $GLOBALS['post'];
820
  }
@@ -829,8 +1019,8 @@ class WPMSEOMetabox extends WPMSEOMeta
829
  */
830
  public function snippet()
831
  {
832
- $post = $this->getMetaboxPost();
833
- $title = self::getValue('title', $post->ID);
834
  $description = self::getValue('desc', $post->ID);
835
 
836
  $snippet_preview = new WPMSEOSnippetPreview($post, $title, $description);
@@ -844,80 +1034,77 @@ class WPMSEOMetabox extends WPMSEOMeta
844
  * @param string $id Tab id
845
  * @param string $content Tab content
846
  *
847
- * @return void
848
  */
849
  public function doTab($id, $content)
850
  {
 
851
  global $post;
852
- ?>
853
 
854
- <div class="<?php echo esc_attr('wpmseotab ' . $id) ?>" id="<?php echo esc_attr($id) ?>">
855
  <div class="meta-box-top">
856
- <h1 class="wpms-top-h2" style="float: left">
857
- <?php
858
- if ($id === 'wpmseo_general') {
859
- esc_html_e('SEO Page Optimization', 'wp-meta-seo');
860
- } elseif ($id === 'wpmseo_social') {
861
- esc_html_e('Social Sharing Apparence', 'wp-meta-seo');
862
- }
863
- ?>
864
- </h1>
865
- <?php if ($id === 'wpmseo_general') : ?>
866
- <p class="reload_analysis" style="margin: 20px 0">
867
  <span class="spinner" style="float: left;"></span>
 
868
  <button type="button" name="reload_analysis" id="reload_analysis" class="ju-button orange-button waves-effect waves-light"
869
- ><?php esc_html_e('Reload analysis', 'wp-meta-seo'); ?></button>
870
- </p>
871
- <?php endif; ?>
872
- </div>
873
- <?php
874
- // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method doMetaBox
875
- echo $content;
876
- ?>
877
- <?php
878
- if ($id === 'wpmseo_general') {
879
- // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method pageAnalysis
880
- echo $this->pageAnalysis($post);
881
- $settings = get_option('_metaseo_settings');
882
- if (!empty($settings['metaseo_follow'])) {
883
- $page_follow = get_post_meta($post->ID, '_metaseo_metafollow', true);
884
- $slf = '<select class="metaseo_metabox_follow wpms-large-input" data-post_id="' . esc_attr($post->ID) . '">';
885
- if ($page_follow === 'nofollow') {
886
- $slf .= '<option value="follow">' . esc_html__('Follow', 'wp-meta-seo') . '</option>';
887
- $slf .= '<option selected value="nofollow">' . esc_html__('Nofollow', 'wp-meta-seo') . '</option>';
888
- } else {
889
- $slf .= '<option selected value="follow">' . esc_html__('Follow', 'wp-meta-seo') . '</option>';
890
- $slf .= '<option value="nofollow">' . esc_html__('Nofollow', 'wp-meta-seo') . '</option>';
891
- }
892
- $slf .= '</select>';
893
- echo '<p class="wpms_width_100 wpms_left optimization-row-box p_index_folder"><span class="wpmslabel"><label>' . esc_html__('Follow', 'wp-meta-seo') . '
894
  </label><i class="material-icons alignright metaseo_help" id="deschelp"
895
  data-tippy="' . esc_attr__('Nofollow provides a way for webmasters to tell search engines:
896
  don\'t follow this link. So it may influence the link target’s ranking', 'wp-meta-seo') . '"
897
  style="color:#32373C" data-hasqtip="2">chat_bubble</i></span>' . $slf . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
898
- }
899
 
900
- if (!empty($settings['metaseo_index'])) {
901
- $page_index = get_post_meta($post->ID, '_metaseo_metaindex', true);
902
- $sli = '<select class="metaseo_metabox_index wpms-large-input" data-post_id="' . esc_attr($post->ID) . '">';
903
- if ($page_index === 'noindex') {
904
- $sli .= '<option value="index">' . esc_html__('Index', 'wp-meta-seo') . '</option>';
905
- $sli .= '<option selected value="noindex">' . esc_html__('Noindex', 'wp-meta-seo') . '</option>';
906
- } else {
907
- $sli .= '<option selected value="index">' . esc_html__('Index', 'wp-meta-seo') . '</option>';
908
- $sli .= '<option value="noindex">' . esc_html__('Noindex', 'wp-meta-seo') . '</option>';
909
- }
910
 
911
- $sli .= '</select>';
912
- echo '<p class="wpms_width_100 wpms_left optimization-row-box p_index_folder"><span class="wpmslabel"><label>' . esc_html__('Index', 'wp-meta-seo') . '
913
  </label><i class="material-icons alignright metaseo_help" id="deschelp"
914
  data-tippy="' . esc_attr__('Allow search engines robots to index this content,
915
  as default your content is indexed', 'wp-meta-seo') . '"
916
  style="color:#32373C" data-hasqtip="2">chat_bubble</i></span>' . $sli . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
917
- }
918
  }
919
- ?>
920
- </div>
921
- <?php
922
  }
923
  }
39
  add_action('edit_attachment', array($this, 'savePostData'));
40
  add_action('add_attachment', array($this, 'savePostData'));
41
  add_action('admin_init', array($this, 'translateMetaBoxes'));
42
+ // Add Metabox on elementor
43
+ $this->loadPageSeoOnElementor();
44
  }
45
 
46
  /**
47
+ * Save post by default
48
  *
49
  * @param integer $post_id Post id
50
  *
52
  */
53
  public function savePostData($post_id)
54
  {
 
55
  // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification -- Nonce used in next lines
56
  if (isset($_POST['metaseo_wpmseo_title'])) {
57
  if (empty($_POST['_wpnonce'])
63
  if ($post_id === null) {
64
  return false;
65
  }
 
66
  if (wp_is_post_revision($post_id)) {
67
  $post_id = wp_is_post_revision($post_id);
68
  }
72
  if (!is_object($post)) {
73
  return false;
74
  }
 
75
  do_action('wpmseo_save_compare_data', $post);
76
 
77
  $meta_boxes = apply_filters('wpmseo_save_metaboxes', array());
84
  $this->getMetaFieldDefs('advanced'),
85
  $this->getMetaFieldDefs('social')
86
  );
 
87
  foreach ($meta_boxes as $key => $meta_box) {
88
  if ($key === 'facebook' || $key === 'twitter') {
89
  foreach ($meta_box as $k => $social) {
108
  $data = $_POST[self::$form_prefix . $key];
109
  }
110
  }
 
111
  if ('metaseo_canonical' === $meta_box['type']) {
112
  // Convert data of canonical
113
  $data = MetaSeoAdmin::convertCanonicalUrlToSave($data);
127
  return true;
128
  }
129
 
130
+ /**
131
+ * Save post data wpms meta box on elementor
132
+ *
133
+ * @return boolean
134
+ */
135
+ public function savePostByElementor()
136
+ {
137
+ if (empty($_POST['wpms_nonce'])
138
+ || !wp_verify_nonce($_POST['wpms_nonce'], 'wpms_nonce')) {
139
+ return false;
140
+ }
141
+
142
+ if (!current_user_can('edit_posts')) {
143
+ return false;
144
+ }
145
+ $post_id = (isset($_POST['elementorPostID'])) ? $_POST['elementorPostID'] : '';
146
+ if (!empty($post_id)) {
147
+ $data = $_POST['datas'];
148
+ $meta_prefix = '_metaseo_meta';
149
+ if (isset($data) && is_array($data)) {
150
+ foreach ($data as $key => $value) {
151
+ if ($key === 'wp_metaseo_seoscore') {
152
+ update_post_meta($post_id, 'wp_metaseo_seoscore', $value);
153
+ } else {
154
+ if ($key === 'metaseo_canonical') {
155
+ // Convert data of canonical
156
+ $value = MetaSeoAdmin::convertCanonicalUrlToSave($value);
157
+ }
158
+ update_post_meta($post_id, $meta_prefix . $key, $value);
159
+ }
160
+ }
161
+ return true;
162
+ }
163
+ }
164
+
165
+ return false;
166
+ }
167
+
168
  /**
169
  * Translate text strings for use in the meta box
170
  *
173
  public static function translateMetaBoxes()
174
  {
175
  self::$meta_fields['general']['snippetpreview']['title'] = esc_html__('Results preview', 'wp-meta-seo');
176
+ self::$meta_fields['general']['snippetpreview']['help'] = sprintf(
177
  esc_attr__('This is a preview of what your content will looks like
178
  in search engine results: title, description and URL', 'wp-meta-seo'),
179
  '<a target="_blank" href="https://www.joomunited.com/wordpress-products/wpms">',
181
  );
182
 
183
  self::$meta_fields['general']['specific_keywords']['title'] = esc_html__('Page SEO keywords', 'wp-meta-seo');
184
+ self::$meta_fields['general']['specific_keywords']['help'] = esc_attr__('Add the keywords related to your page, the SEO checker will verify if at least one of the SEO keywords are found in your content', 'wp-meta-seo');
185
 
186
  $settings = get_option('_metaseo_settings');
187
+ if (isset($settings['metaseo_showkeywords']) && (int)$settings['metaseo_showkeywords'] === 1) {
188
  self::$meta_fields['general']['keywords']['title'] = esc_html__('Search engine keywords', 'wp-meta-seo');
189
  self::$meta_fields['general']['keywords']['description'] = '<span id="metaseo_wpmseo_keywords-length" class="length-box-meta"></span>';
190
+ self::$meta_fields['general']['keywords']['help'] = esc_attr__('This is the keywords of your content that may be
191
  displayed in search engine results (meta keywords).', 'wp-meta-seo');
192
  } else {
193
  unset(self::$meta_fields['general']['keywords']);
194
  }
195
 
196
+ if (isset($settings['metaseo_canonical']) && (int)$settings['metaseo_canonical'] === 1) {
197
  self::$meta_fields['general']['metaseo_canonical']['title'] = esc_html__('Canonical URL', 'wp-meta-seo');
198
  self::$meta_fields['general']['metaseo_canonical']['description'] = '';
199
+ self::$meta_fields['general']['metaseo_canonical']['help'] = esc_attr__('Put the canonical URL which this page should point to. By default, it\'s the permalink', 'wp-meta-seo');
200
  } else {
201
  unset(self::$meta_fields['general']['metaseo_canonical']);
202
  }
203
 
204
+ self::$meta_fields['social']['facebook']['opengraph-title']['title'] = esc_html__('Facebook Title', 'wp-meta-seo');
205
  self::$meta_fields['social']['facebook']['opengraph-title']['description'] = esc_html__('Custom title to display when
206
  sharing this content on facebook, content title override', 'wp-meta-seo');
207
 
208
+ self::$meta_fields['social']['facebook']['opengraph-desc']['title'] = esc_html__('Facebook Description', 'wp-meta-seo');
209
  self::$meta_fields['social']['facebook']['opengraph-desc']['description'] = esc_html__('Custom description to display when sharing
210
  this content on facebook, content description override', 'wp-meta-seo');
211
 
212
+ self::$meta_fields['social']['facebook']['opengraph-image']['title'] = esc_html__('Facebook Image', 'wp-meta-seo');
213
  self::$meta_fields['social']['facebook']['opengraph-image']['description'] = esc_html__('Custom image to display when sharing
214
  this content on facebook, content description override, recommended size is 1200px x 630px', 'wp-meta-seo');
215
 
216
+ self::$meta_fields['social']['twitter']['twitter-title']['title'] = esc_html__('Twitter Title', 'wp-meta-seo');
217
  self::$meta_fields['social']['twitter']['twitter-title']['description'] = esc_html__('Custom title to display when sharing this
218
  content on twitter, content title override', 'wp-meta-seo');
219
 
220
+ self::$meta_fields['social']['twitter']['twitter-desc']['title'] = esc_html__('Twitter Description', 'wp-meta-seo');
221
  self::$meta_fields['social']['twitter']['twitter-desc']['description'] = esc_html__('Custom description to display when sharing
222
  this content on twitter, content description override', 'wp-meta-seo');
223
 
224
+ self::$meta_fields['social']['twitter']['twitter-image']['title'] = esc_html__('Twitter Image', 'wp-meta-seo');
225
  self::$meta_fields['social']['twitter']['twitter-image']['description'] = esc_html__('Custom image to display when sharing
226
  this content on facebook, content description override, recommended min size 440px X 220px', 'wp-meta-seo');
227
 
241
  'post.php',
242
  'edit.php',
243
  ), true)
244
+ && apply_filters('wpmseo_always_register_metaboxes_on_admin', false) === false)
245
  ) {
246
  return;
247
  }
248
 
249
  if ($pagenow !== 'edit.php') {
250
+ if (0 !== (int)get_queried_object_id()) {
251
  // Enqueue files needed for upload functionality.
252
  wp_enqueue_media(
253
  array(
301
  '2.2.1',
302
  true
303
  );
 
 
 
 
 
 
 
304
  wp_enqueue_script(
305
+ 'wpms-tippy',
306
+ plugins_url('assets/tippy/tippy.js', WPMSEO_FILE),
307
+ array('jquery'),
308
+ '2.2.1',
 
 
 
 
 
 
 
309
  true
310
  );
 
311
  wp_enqueue_script(
312
  'metaseo-circle-progress',
313
  plugins_url('assets/js/circle-progress.js', WPMSEO_FILE),
315
  WPMSEO_VERSION,
316
  true
317
  );
318
+ //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, no need verification
319
+ if (!(isset($_GET['action']) && $_GET['action'] === 'elementor')) {
320
+ wp_enqueue_script(
321
+ 'm-wp-seo-metabox',
322
+ plugins_url('assets/js/wp-metaseo-metabox.js', WPMSEO_FILE),
323
+ array('jquery', 'jquery-ui-core'),
324
+ WPMSEO_VERSION,
325
+ true
326
+ );
327
+ wp_enqueue_script(
328
+ 'metaseo-cliffpyles',
329
+ plugins_url('assets/js/cliffpyles.js', WPMSEO_FILE),
330
+ array('jquery', 'metaseo-circle-progress'),
331
+ WPMSEO_VERSION,
332
+ true
333
+ );
334
+ wp_enqueue_script(
335
+ 'wpms-seokeyword-metabox',
336
+ plugins_url('assets/js/wpms-seokeyword-metabox.js', WPMSEO_FILE),
337
+ array('wp-data', 'jquery')
338
+ );
339
+ wp_enqueue_script(
340
+ 'mwpseo-admin-media',
341
+ plugins_url('assets/js/wp-metaseo-admin-media.js', WPMSEO_FILE),
342
+ array('jquery', 'jquery-ui-core'),
343
+ WPMSEO_VERSION,
344
+ true
345
+ );
346
+ }
347
+ wp_enqueue_style(
348
+ 'm-bootstrap-tagsinput',
349
+ plugins_url('assets/css/bootstrap/bootstrap.tagsinput.css', WPMSEO_FILE),
350
+ array(),
351
+ WPMSEO_VERSION
352
+ );
353
 
354
  wp_enqueue_script(
355
+ 'metaseo-bootstrap-tagsinput',
356
+ plugins_url('assets/js/bootstrap/bootstrap-tagsinput.min.js', WPMSEO_FILE),
357
+ array('jquery'),
358
  WPMSEO_VERSION,
359
  true
360
  );
361
+ // snackbar module
362
+ wp_enqueue_style('wpms-snackbar-style');
363
+ wp_enqueue_script('wpms-snackbar-script');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  wp_localize_script('m-wp-seo-metabox', 'wpmseoMetaboxL10n', $this->localizeScript());
366
  wp_localize_script('wpms-seokeyword-metabox', 'wpmseoMetaboxL10n', $this->localizeScript());
367
+ wp_localize_script('wpmsMetaboxOnElementor', 'wpmseoMetaboxL10n', $this->localizeScript());
368
+ wp_localize_script('wpms-seokeyword-metabox-elementor', 'wpmseoMetaboxL10n', $this->localizeScript());
369
  $localize = $this->localizeSettingsScript();
370
  wp_localize_script('mwpseo-admin-media', 'wpmseoMediaL10n', $localize);
371
+ wp_localize_script('wpms-elementor-media', 'wpmseoMediaL10n', $localize);
372
  wp_localize_script('metaseo-cliffpyles', 'wpmscliffpyles', $localize);
373
+ wp_localize_script('wpms-cliffpyles-elementor', 'wpmscliffpyles', $localize);
374
  }
375
  }
376
 
391
  }
392
 
393
  $this->settings = array(
394
+ 'metaseo_title_home' => '',
395
+ 'metaseo_desc_home' => '',
396
+ 'metaseo_showfacebook' => '',
397
+ 'metaseo_showtwitter' => '',
398
+ 'metaseo_twitter_card' => 'summary',
399
+ 'metaseo_showkeywords' => 0,
400
  'metaseo_showtmetablock' => 1,
401
+ 'metaseo_showsocial' => 1,
402
+ 'metaseo_seovalidate' => 0
403
  );
404
+ $settings = get_option('_metaseo_settings');
405
 
406
  if (is_array($settings)) {
407
  $this->settings = array_merge($this->settings, $settings);
411
  'choose_image' => esc_html__('Use Image', 'wp-meta-seo'),
412
  'use_validate' => $this->settings['metaseo_seovalidate'],
413
  'post_title' => $post_title,
414
+ 'post_content' => $post_content,
415
+ 'wpms_nonce' => wp_create_nonce('wpms_nonce')
416
  );
417
  }
418
 
428
  if ((!is_object($post) || !isset($post->post_type))) {
429
  return array();
430
  }
431
+ $settings = get_option('_metaseo_settings');
432
  self::$meta_length_reason = apply_filters('wpmseo_desc_length_reason', self::$meta_length_reason, $post);
433
+ self::$meta_length = apply_filters('wpmseo_desc_length', self::$meta_length, $post);
434
+ $title_template = '%title%';
435
 
436
+ $desc_template = '';
437
  $sample_permalink = get_sample_permalink($post->ID);
438
  $sample_permalink = str_replace('%page', '%post', $sample_permalink[0]);
439
 
442
  $settings['metaseo_metatitle_tab'] = 1;
443
  }
444
  $vars_to_cache = array(
445
+ 'date' => wpmsRetrieveDate($post),
446
+ 'id' => !(empty($post->ID)) ? $post->ID : null,
447
+ 'sitename' => trim(strip_tags(get_bloginfo('name'))),
448
+ 'sitedesc' => trim(strip_tags(get_bloginfo('description'))),
449
+ 'sep' => '-',
450
+ 'page' => '',
451
+ 'currenttime' => date_i18n(get_option('time_format')),
452
+ 'currentdate' => date_i18n(get_option('date_format')),
453
+ 'currentday' => date_i18n('j'),
454
  'currentmonth' => date_i18n('F'),
455
+ 'currentyear' => date_i18n('Y'),
456
+ 'metatitle_tab' => (!empty($settings['metaseo_metatitle_tab']) ? '1' : '0')
457
  );
458
 
459
  foreach ($vars_to_cache as $var => $value) {
462
 
463
  $check_connected = false;
464
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
465
+ // get domain
466
  $option = get_option(WPMS_GSC, array('profile' => ''));
467
  if (!empty($option['profile'])) {
468
  $check_connected = true;
470
  }
471
 
472
  $cached_replacement_vars['sitename'] = get_option('blogname');
473
+ $plugin_active = json_encode(get_option('active_plugins'));
474
+ $array_keyword = array(
475
+ 'plugin_active' => $plugin_active,
476
+ 'field_prefix' => self::$form_prefix,
477
+ 'choose_image' => esc_html__('Use Image', 'wp-meta-seo'),
478
+ 'wpmseo_meta_desc_length' => self::$meta_length,
479
+ 'wpmseo_meta_title_length' => self::$meta_title_length,
480
+ 'wpmseo_meta_keywords_length' => self::$meta_keywords_length,
481
+ 'wpmseo_title_template' => $title_template,
482
+ 'wpmseo_desc_template' => $desc_template,
483
+ 'wpmseo_permalink_template' => $sample_permalink,
484
  'wpmseo_keyword_suggest_nonce' => wp_create_nonce('wpmseo-get-suggest'),
485
+ 'wpmseo_replace_vars_nonce' => wp_create_nonce('wpmseo-replace-vars'),
486
+ 'no_parent_text' => esc_html__('(no parent)', 'wp-meta-seo'),
487
+ 'show_keywords' => 0,
488
+ 'image_loader' => esc_url(WPMETASEO_PLUGIN_URL . '/assets/images/ajax-loader1.gif'),
489
+ 'keyword_filter_return' => esc_html__('No search queries are currently indexed in the search console... Try typing custom keywords.', 'wp-meta-seo'),
490
+ 'keyword_console_connected' => ($check_connected) ? 1 : 0,
491
+ 'wpms_nonce' => wp_create_nonce('wpms_nonce')
492
  );
493
+ $settings = get_option('_metaseo_settings');
494
+ if (isset($settings['metaseo_showkeywords']) && (int)$settings['metaseo_showkeywords'] === 1) {
495
  $array_keyword['show_keywords'] = 1;
496
  }
497
 
516
  }
517
  }
518
 
519
+ /**
520
+ * Check if Elementor plugin is active then load Meta-box SEO on Elementor
521
+ *
522
+ * @return void
523
+ */
524
+ private function loadPageSeoOnElementor()
525
+ {
526
+ // Elementor
527
+ if ($this->canAddMetaboxOnElementor()) {
528
+ // Enqueue WPMS style and script on Elementor
529
+ add_action('elementor/editor/before_enqueue_scripts', array($this, 'wpmsElementorAssets'));
530
+
531
+ // Add Meta Seo tab
532
+ add_action('elementor/editor/footer', array($this, 'start_insert_meta_box'), 0);
533
+ add_action('elementor/editor/footer', array($this, 'end_insert_meta_box'), 999);
534
+ }
535
+ }
536
+
537
+ /**
538
+ * Check can add Meta box
539
+ *
540
+ * @return boolean
541
+ */
542
+ private function canAddMetaboxOnElementor()
543
+ {
544
+ if (is_plugin_active('elementor/elementor.php')) {
545
+ return true;
546
+ }
547
+ return false;
548
+ }
549
+
550
+ /**
551
+ * Start insert Meta boxes on Elementor
552
+ *
553
+ * @return void
554
+ */
555
+ public function start_insert_meta_box()
556
+ {
557
+ ob_start();
558
+ }
559
+
560
+ /**
561
+ * End insert Meta boxes on Elementor
562
+ *
563
+ * @return void
564
+ */
565
+ public function end_insert_meta_box()
566
+ {
567
+ $output = \ob_get_clean();
568
+ $search = '/(<div class="elementor-component-tab elementor-panel-navigation-tab" data-tab="global">.*<\/div>)/m';
569
+
570
+ // Add Meta SEO tab
571
+ $wpmsElementorHTML = '${1}<div id="wpms-onelementor-tab" class="elementor-panel-navigation-tab wpms-onelementor-tab"
572
+ >' . esc_html__('Meta SEO', 'wp-meta-seo') . '</div>';
573
+
574
+ // Add content meta box
575
+ $wpmsElementorHTML .= '</div><div style="display: none" id="wpms-metabox-on-elementor">';
576
+ $wpmsElementorHTML .= $this->wpmsMetaboxContent() . '</div><div>';
577
+
578
+ // Append Meta box
579
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- my html
580
+ echo \preg_replace(
581
+ $search,
582
+ $wpmsElementorHTML, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- data had been escape
583
+ $output // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- ob get clean
584
+ );
585
+ }
586
+
587
+ /**
588
+ * Enqueue script and style for WPMS Meta box on Elementor
589
+ *
590
+ * @return void
591
+ */
592
+ public function wpmsElementorAssets()
593
+ {
594
+ wp_enqueue_style(
595
+ 'wpmsStyleOnElementor',
596
+ WPMETASEO_PLUGIN_URL . 'assets/css/elementor/wpms-elementor.css',
597
+ array(),
598
+ WPMSEO_VERSION
599
+ );
600
+ wp_enqueue_script('jquery');
601
+
602
+ // Main js
603
+ wp_enqueue_script(
604
+ 'wpmsScriptOnElementor',
605
+ WPMETASEO_PLUGIN_URL . 'assets/js/elementor/wpms-elementor.js',
606
+ 'jquery',
607
+ WPMSEO_VERSION
608
+ );
609
+ wp_enqueue_script(
610
+ 'wpms-cliffpyles-elementor',
611
+ WPMETASEO_PLUGIN_URL . 'assets/js/elementor/cliffpyles.js',
612
+ array('jquery', 'metaseo-circle-progress'),
613
+ WPMSEO_VERSION,
614
+ true
615
+ );
616
+ wp_enqueue_script(
617
+ 'wpms-seokeyword-metabox-elementor',
618
+ WPMETASEO_PLUGIN_URL . 'assets/js/elementor/wpms-seokeyword-metabox.js',
619
+ array('wp-data', 'jquery'),
620
+ WPMSEO_VERSION,
621
+ true
622
+ );
623
+ wp_enqueue_style(
624
+ 'wpms-mytippy-style',
625
+ plugins_url('assets/tippy/my-tippy.css', dirname(__FILE__)),
626
+ array(),
627
+ WPMSEO_VERSION
628
+ );
629
+ wp_enqueue_style(
630
+ 'metaseo-google-icon-elementor',
631
+ '//fonts.googleapis.com/icon?family=Material+Icons'
632
+ );
633
+ wp_enqueue_script(
634
+ 'wpms-elementor-media',
635
+ plugins_url('assets/js/elementor/wpms-media.js', WPMSEO_FILE),
636
+ array('jquery', 'jquery-ui-core'),
637
+ WPMSEO_VERSION,
638
+ true
639
+ );
640
+ // snackbar module
641
+ wp_enqueue_script(
642
+ 'wpms-snackbar-script-elementor',
643
+ plugins_url('assets/js/snackbar.js', dirname(__FILE__)),
644
+ array('jquery'),
645
+ WPMSEO_VERSION,
646
+ true
647
+ );
648
+ wp_enqueue_style(
649
+ 'wpms-snackbar-style-elementor',
650
+ plugins_url('assets/css/snackbar.css', dirname(__FILE__)),
651
+ array(),
652
+ WPMSEO_VERSION
653
+ );
654
+ }
655
+
656
  /**
657
  * Output the meta box
658
  *
660
  */
661
  public function metaBox()
662
  {
663
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- data had been escape
664
+ echo $this->wpmsMetaboxContent();
665
+ }
666
+
667
+ /**
668
+ * Generate WPMS Meta box html content
669
+ *
670
+ * @return string|mixed
671
+ */
672
+ public function wpmsMetaboxContent()
673
+ {
674
+ $wpmsMetaboxContent = '';
675
  $this->metaseoEnqueue();
676
+ $post = $this->getMetaboxPost();
677
  $default_settings = array(
678
+ 'metaseo_title_home' => '',
679
+ 'metaseo_desc_home' => '',
680
+ 'metaseo_showfacebook' => '',
681
+ 'metaseo_showtwitter' => '',
682
+ 'metaseo_twitter_card' => 'summary',
683
  'metaseo_showtmetablock' => 1,
684
+ 'metaseo_showsocial' => 1
685
  );
686
+ $settings = get_option('_metaseo_settings');
687
  if (is_array($settings)) {
688
  $default_settings = array_merge($default_settings, $settings);
689
  }
690
  $check_connected = false;
691
+ $service = false;
692
+ $wpmsMetaboxContent .= '<div class="wpmseo-metabox-tabs-div">
 
693
  <ul class="wpmseo-metabox-tabs tabs ju-tabs wpmstabs" id="wpmseo-metabox-tabs">
694
  <li class="tab wpmstab col">
695
+ <a id="elementor-wpms-general" class="wpmseo_tablink"
696
+ href="#wpmseo_general">' . esc_html__('SEO Page optimization', 'wp-meta-seo') . '</a></li>';
697
+
698
+ if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
699
+ $service = $this->serverWebmaster();
700
+ if (!empty($service)) {
701
+ // get domain
702
+ $option = get_option(WPMS_GSC, array('profile' => ''));
703
+ if (!empty($option['profile'])) {
704
+ $check_connected = true;
 
 
 
 
 
 
 
 
 
705
  }
706
  }
707
+ if ($check_connected) {
708
+ $wpmsMetaboxContent .= '<li class="tab wpmstab col">';
709
+ $wpmsMetaboxContent .= '<a class="wpmseo_tablink" href="#wpmseo_gsc_keywords">';
710
+ $wpmsMetaboxContent .= esc_html__('Search console keywords', 'wp-meta-seo');
711
+ $wpmsMetaboxContent .= '</a>';
712
+ $wpmsMetaboxContent .= '</li>';
713
+ }
714
+ }
715
+ if ((isset($default_settings['metaseo_showsocial'])
716
+ && (int)$default_settings['metaseo_showsocial'] === 1)) :
717
+ $wpmsMetaboxContent .= '<li class="tab wpmstab col">
718
+ <a id="elementor-wpms-social" class="wpmseo_tablink"
719
+ href="#wpmseo_social">' . esc_html__('Social for search engine', 'wp-meta-seo') . '</a></li>';
720
+ endif;
721
+ do_action('wpmseo_tab_header');
722
+ $wpmsMetaboxContent .= '</ul>';
723
+
724
+ // content in general tab
725
  $content = '';
726
  if (is_object($post) && isset($post->post_type)) {
727
  foreach ($this->getMetaFieldDefs('general', $post->post_type) as $key => $meta_field) {
728
  $content .= $this->doMetaBox($meta_field, $key);
729
  if ($key === 'title') {
730
  $snippet_more = '%date%, %id%, %sitename%, %sitedesc%, %page%, %currenttime%, %currentdate%, %currentday%, %currentmonth%, %currentyear%';
731
+ $content .= '<p class="description" style="margin: 0 0 10px 32px;">' . sprintf(esc_html__('Title and description variables: %s', 'wp-meta-seo'), '%title%, <span onclick="jQuery(this).text(\'' . $snippet_more . '\').removeClass(\'snippet-more\')" class="snippet-more">more...</span>') . '</p>';
732
  }
733
  }
734
  unset($key, $meta_field);
735
  }
736
+ $wpmsMetaboxContent .= $this->doTab('wpmseo_general', $content);
737
  if (is_plugin_active(WPMSEO_ADDON_FILENAME)) {
738
  if ($check_connected) {
739
  // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method MetaSeoAddonAdmin::gscKeywords
740
+ $wpmsMetaboxContent .= apply_filters('wpmsaddon_google_search_keywords', '', $post->post_content, $service);
741
  }
742
  }
743
 
744
 
745
+ // Content in social tab
746
  $content = '';
747
 
748
  $social = $this->getMetaFieldDefs('social');
750
  $content .= '<div class="metabox-social-block">';
751
  if ($k === 'facebook') {
752
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook.png';
753
+ $srcset2x = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook@2x.png';
754
+ $srcset3x = WPMETASEO_PLUGIN_URL . 'assets/images/facebook/facebook@3x.png';
755
+ $img = '<img src="' . esc_url($image_src) . '"
756
+ srcset="' . esc_url($srcset2x) . ' 2x,' . esc_url($srcset3x) . ' 3x"
757
  class="social-img">';
758
+ $content .= '<h2 class="wpms-top-h2" style="padding: 0 20px">' . $img . '<span>' . esc_html__('Facebook', 'wp-meta-seo') . '</span></h2>';
759
  } elseif ($k === 'twitter') {
760
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter.png';
761
+ $srcset2x = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter@2x.png';
762
+ $srcset3x = WPMETASEO_PLUGIN_URL . 'assets/images/twitter/twitter@3x.png';
763
+ $img = '<img src="' . esc_url($image_src) . '"
764
+ srcset="' . esc_url($srcset2x) . ' 2x,' . esc_url($srcset3x) . ' 3x"
765
  class="social-img">';
766
+ $content .= '<h2 class="wpms-top-h2" style="padding: 0 20px">' . $img . '<span>' . esc_html__('Twitter', 'wp-meta-seo') . '</span></h2>';
767
  }
768
 
769
  foreach ($fields as $key => $field) {
772
  $content .= '</div>';
773
  }
774
 
775
+ if ((isset($default_settings['metaseo_showsocial']) && (int)$default_settings['metaseo_showsocial'] === 1)) {
776
+ $wpmsMetaboxContent .= $this->doTab('wpmseo_social', $content);
777
  }
778
 
779
  do_action('wpmseo_tab_content');
780
 
781
+ $wpmsMetaboxContent .= '</div>';
782
+ return $wpmsMetaboxContent;
783
  }
784
 
785
  /**
800
 
801
  $conn = get_option('wpms_gsc_connect');
802
  if (!empty($conn['googleClientId']) && !empty($conn['googleClientSecret'])) {
803
+ $client_id = $conn['googleClientId'];
804
  $client_secret = $conn['googleClientSecret'];
805
  } else {
806
+ $client_id = WPMSEO_ADDON_CLIENT_ID;
807
  $client_secret = WPMSEO_ADDON_CLIENT_SECRET;
808
  }
809
 
810
  $gsc = array(
811
  'application_name' => 'WP Meta SEO',
812
+ 'client_id' => $client_id,
813
+ 'client_secret' => $client_secret,
814
+ 'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
815
+ 'scopes' => array('https://www.googleapis.com/auth/webmasters'),
816
  );
817
 
818
  $this->client = new Wpms_Api_Google_Client($gsc, 'wpms-gsc', 'https://www.googleapis.com/webmasters/v3/');
835
  $seokeywords_result = get_post_meta($post->ID, 'wp_metaseo_seoscore', true);
836
  $output = '';
837
  $circliful = 0;
838
+ $output .= '<div class="wpms_width_100">';
839
+ $output .= '<div class="metaseo_left mpns-clear-float" style="margin-top: 25px;">
840
  <div class="metaseo-progress-bar" data-post_id="' . esc_attr($post->ID) . '"><strong></strong></div>
841
  <input type="hidden" id="progressController" value="' . esc_attr($circliful) . '" />
842
  <input type="hidden" id="metaseo_alanysis_ok" value="' . esc_attr($this->perc_score) . '" />
843
  </div>';
844
 
845
+ $output .= '<div class="metaseo_right wpms-full-width" style="margin-top: 10px;">';
846
+ $output .= '<div class="panel-left wpms-full-width" style="width: 50%; float: left"></div>';
847
+ $output .= '<div class="panel-right seokeyword-information wpms-full-width" style="width: 50%; float: left"></div>';
848
  $output .= '<div style="clear: both"></div>';
849
  $output .= '</div>';
850
+ $output .= '<input type="hidden" id="wpmetaseo_seo_keywords_result" name="wpmetaseo_seo_keywords_result" value="' . (!empty($seokeywords_result) ? $seokeywords_result : 0) . '" />';
851
  $output .= '</div>';
852
  return $output;
853
  }
863
  public function doMetaBox($meta_field_def, $key = '')
864
  {
865
  wp_enqueue_style('metaseo-google-icon');
866
+ $content = '';
867
  $esc_form_key = esc_attr(self::$form_prefix . $key);
868
+ $post = $this->getMetaboxPost();
869
+ $meta_value = self::getValue($key, $post->ID);
870
 
871
  $class = '';
872
  if (isset($meta_field_def['class']) && $meta_field_def['class'] !== '') {
886
  $content .= '<input type="text" id="' . esc_attr($esc_form_key) . '" name="' . esc_attr($esc_form_key) . '" value="' . esc_attr($meta_value) . '" data-role="tagsinput" />';
887
  break;
888
  case 'metaseo_canonical':
889
+ $placeholder = ' placeholder="' . esc_html__('Put canonical URL in field', 'wp-meta-seo') . '"';
890
  $ac = '';
891
  if (isset($meta_field_def['autocomplete']) && $meta_field_def['autocomplete'] === false) {
892
  $ac = 'autocomplete="off" ';
928
  class="' . esc_attr('metaseo' . $class) . '">';
929
  foreach ($meta_field_def['options'] as $val => $option) {
930
  $selected = selected($meta_value, $val, false);
931
+ $content .= '<option ' . $selected . '
932
  value="' . esc_attr($val) . '">' . esc_html($option) . '</option>';
933
  }
934
  unset($val, $option, $selected);
940
  $content .= '<input id="' . esc_attr($esc_form_key) . '" type="text" size="36" class="' . esc_attr($class) . '"
941
  name="' . esc_attr($esc_form_key) . '" value="' . esc_attr($meta_value) . '" />';
942
  $content .= '<button id="' . esc_attr($esc_form_key) . '_button" class="wpmseo_image_upload_button ju-button orange-button wpms-small-btn"
943
+ type="button">' . esc_html__('Upload Image', 'wp-meta-seo') . '</button>';
944
  break;
945
  }
946
 
971
  $help = '';
972
  $image_src = WPMETASEO_PLUGIN_URL . 'assets/images/question/question.png';
973
  if (isset($meta_field_def['help']) && $meta_field_def['help'] !== '') {
974
+ $help = '<img src="' . esc_url($image_src) . '" class="meta-question metaseo_help" id="' . esc_attr($key . 'help') . '" data-tippy="' . esc_attr($meta_field_def['help']) . '">';
975
  }
976
 
977
  if (isset($meta_field_def['description'])) {
980
  }
981
  }
982
 
983
+ $html = '<div class="' . esc_html($meta_field_def['classrow'] . ' wpms_left optimization-row-box') . '">';
984
+ $html .= '<label class="ju-setting-label wpms_width_100 wpms_left p-l-0">' . $label . $help . '</label>';
985
+ $html .= '<label class="wpms_width_100 label-input wpms_left p-t-20 snippet-preview">' . $content . '</label>';
986
  if (isset($meta_field_def['description'])) {
987
  if (!strpos($meta_field_def['class'], 'has-length') !== false) {
988
  $html .= '<p class="description">' . $meta_field_def['description'] . '</p>';
1003
  // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
1004
  if (isset($_GET['post'])) {
1005
  //phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
1006
+ $post_id = (int)$_GET['post'];
1007
+ $post = get_post($post_id);
1008
  } else {
1009
  $post = $GLOBALS['post'];
1010
  }
1019
  */
1020
  public function snippet()
1021
  {
1022
+ $post = $this->getMetaboxPost();
1023
+ $title = self::getValue('title', $post->ID);
1024
  $description = self::getValue('desc', $post->ID);
1025
 
1026
  $snippet_preview = new WPMSEOSnippetPreview($post, $title, $description);
1034
  * @param string $id Tab id
1035
  * @param string $content Tab content
1036
  *
1037
+ * @return string|mixed
1038
  */
1039
  public function doTab($id, $content)
1040
  {
1041
+ $contentTab = '';
1042
  global $post;
 
1043
 
1044
+ $contentTab .= '<div class="' . esc_attr('wpmseotab ' . $id) . '" id="' . esc_attr($id) . '">
1045
  <div class="meta-box-top">
1046
+ <h1 class="wpms-top-h2" style="float: left">';
1047
+ if ($id === 'wpmseo_general') {
1048
+ $contentTab .= esc_html__('SEO Page Optimization', 'wp-meta-seo');
1049
+ } elseif ($id === 'wpmseo_social') {
1050
+ $contentTab .= esc_html__('Social Sharing Apparence', 'wp-meta-seo');
1051
+ }
1052
+ $contentTab .= '</h1>';
1053
+
1054
+ if ($id === 'wpmseo_general') :
1055
+ $contentTab .= '<p class="reload_analysis" style="margin: 20px 0">
 
1056
  <span class="spinner" style="float: left;"></span>
1057
+ <img id="wpms-elementor-spinner-gif" src="' . WPMETASEO_PLUGIN_URL . 'assets/images/spinner.gif" style="display: none;float: left;margin: 3px;">
1058
  <button type="button" name="reload_analysis" id="reload_analysis" class="ju-button orange-button waves-effect waves-light"
1059
+ >' . esc_html__('Reload analysis', 'wp-meta-seo') . '</button></p>';
1060
+ endif;
1061
+ $contentTab .= '</div>';
1062
+
1063
+ $contentTab .= $content;
1064
+
1065
+ if ($id === 'wpmseo_general') {
1066
+ // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in the method pageAnalysis
1067
+ $contentTab .= $this->pageAnalysis($post);
1068
+ $settings = get_option('_metaseo_settings');
1069
+ if (!empty($settings['metaseo_follow'])) {
1070
+ $page_follow = get_post_meta($post->ID, '_metaseo_metafollow', true);
1071
+ $slf = '<select class="metaseo_metabox_follow wpms-large-input" data-post_id="' . esc_attr($post->ID) . '">';
1072
+ if ($page_follow === 'nofollow') {
1073
+ $slf .= '<option value="follow">' . esc_html__('Follow', 'wp-meta-seo') . '</option>';
1074
+ $slf .= '<option selected value="nofollow">' . esc_html__('Nofollow', 'wp-meta-seo') . '</option>';
1075
+ } else {
1076
+ $slf .= '<option selected value="follow">' . esc_html__('Follow', 'wp-meta-seo') . '</option>';
1077
+ $slf .= '<option value="nofollow">' . esc_html__('Nofollow', 'wp-meta-seo') . '</option>';
1078
+ }
1079
+ $slf .= '</select>';
1080
+
1081
+ $contentTab .= '<p class="wpms_width_100 wpms_left optimization-row-box p_index_folder"><span class="wpmslabel"><label>' . esc_html__('Follow', 'wp-meta-seo') . '
 
 
1082
  </label><i class="material-icons alignright metaseo_help" id="deschelp"
1083
  data-tippy="' . esc_attr__('Nofollow provides a way for webmasters to tell search engines:
1084
  don\'t follow this link. So it may influence the link target’s ranking', 'wp-meta-seo') . '"
1085
  style="color:#32373C" data-hasqtip="2">chat_bubble</i></span>' . $slf . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
1086
+ }
1087
 
1088
+ if (!empty($settings['metaseo_index'])) {
1089
+ $page_index = get_post_meta($post->ID, '_metaseo_metaindex', true);
1090
+ $sli = '<select class="metaseo_metabox_index wpms-large-input" data-post_id="' . esc_attr($post->ID) . '">';
1091
+ if ($page_index === 'noindex') {
1092
+ $sli .= '<option value="index">' . esc_html__('Index', 'wp-meta-seo') . '</option>';
1093
+ $sli .= '<option selected value="noindex">' . esc_html__('Noindex', 'wp-meta-seo') . '</option>';
1094
+ } else {
1095
+ $sli .= '<option selected value="index">' . esc_html__('Index', 'wp-meta-seo') . '</option>';
1096
+ $sli .= '<option value="noindex">' . esc_html__('Noindex', 'wp-meta-seo') . '</option>';
1097
+ }
1098
 
1099
+ $sli .= '</select>';
1100
+ $contentTab .= '<p class="wpms_width_100 wpms_left optimization-row-box p_index_folder"><span class="wpmslabel"><label>' . esc_html__('Index', 'wp-meta-seo') . '
1101
  </label><i class="material-icons alignright metaseo_help" id="deschelp"
1102
  data-tippy="' . esc_attr__('Allow search engines robots to index this content,
1103
  as default your content is indexed', 'wp-meta-seo') . '"
1104
  style="color:#32373C" data-hasqtip="2">chat_bubble</i></span>' . $sli . '</p>'; // phpcs:ignore WordPress.Security.EscapeOutput -- Content escaped in previous line (same function)
 
1105
  }
1106
+ }
1107
+ $contentTab .= '</div>';
1108
+ return $contentTab;
1109
  }
1110
  }
inc/class.metaseo-snippet-preview.php CHANGED
@@ -166,16 +166,26 @@ class WPMSEOSnippetPreview
166
  if (!$settings || !isset($settings['metaseo_metatitle_tab'])) {
167
  $settings['metaseo_metatitle_tab'] = 1;
168
  }
169
- $title_snippet = (!empty($settings['metaseo_metatitle_tab']) ? '%title%' : '');
170
  $url = esc_url($this->url);
171
  $url = str_replace('http://', '', $url);
 
 
 
 
 
 
 
 
 
 
172
  // phpcs:disable WordPress.Security.EscapeOutput -- Content escaped before line 167
173
  $content = '<div id="wpmseosnippet">
174
  <a class="url m-t-10" style="width: 100%; padding-left: 12px; margin-bottom:5px">' . $url . '</a>
175
  <div class="metabox-snippet-title">
176
  <div class="container-snippet">
177
  <span class="text">'.esc_html($this->title).'</span>
178
- <input type="hidden" class="title input has-length metaseo_tool" id="metaseo_wpmseo_title" name="metaseo_wpmseo_title" value="' . esc_html(!empty($this->title) ? $this->title : $title_snippet) . '" />
179
  <input class="title input has-length metaseo_tool" placeholder="'.esc_html__('Put your meta title here. Click here to edit...', 'wp-meta-seo').'" data-tippy="'.esc_html__('This is your meta title that should be displayed in Google Search results for this page', 'wp-meta-seo').'" id="metaseo_snippet_title" value="" />
180
  </div>
181
  <span id="metaseo_wpmseo_title-length" class="length-box-meta"></span>
166
  if (!$settings || !isset($settings['metaseo_metatitle_tab'])) {
167
  $settings['metaseo_metatitle_tab'] = 1;
168
  }
169
+ //$title_snippet = (!empty($settings['metaseo_metatitle_tab']) ? '%title%' : '');
170
  $url = esc_url($this->url);
171
  $url = str_replace('http://', '', $url);
172
+ // convert %title% snippet back to default page title
173
+ $firstCreatePost = 0;
174
+ if (empty($this->post->post_title)) {
175
+ $firstCreatePost = 1;
176
+ }
177
+ if ($this->title === '%title%' || empty($this->title)) {
178
+ $this->title = $this->post->post_title;
179
+ // update meta title
180
+ update_post_meta($this->post->ID, '_metaseo_metatitle', $this->title);
181
+ }
182
  // phpcs:disable WordPress.Security.EscapeOutput -- Content escaped before line 167
183
  $content = '<div id="wpmseosnippet">
184
  <a class="url m-t-10" style="width: 100%; padding-left: 12px; margin-bottom:5px">' . $url . '</a>
185
  <div class="metabox-snippet-title">
186
  <div class="container-snippet">
187
  <span class="text">'.esc_html($this->title).'</span>
188
+ <input type="hidden" data-firstcreatepost="'. esc_attr($firstCreatePost) .'" class="title input has-length metaseo_tool" id="metaseo_wpmseo_title" name="metaseo_wpmseo_title" value="' . esc_html($this->title). '" />
189
  <input class="title input has-length metaseo_tool" placeholder="'.esc_html__('Put your meta title here. Click here to edit...', 'wp-meta-seo').'" data-tippy="'.esc_html__('This is your meta title that should be displayed in Google Search results for this page', 'wp-meta-seo').'" id="metaseo_snippet_title" value="" />
190
  </div>
191
  <span id="metaseo_wpmseo_title-length" class="length-box-meta"></span>
inc/pages/category-meta.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* Prohibit direct script loading */
3
+ defined('ABSPATH') || die('No direct script access allowed!');
4
+ if (!class_exists('WPMSCategoryMetaTable')) {
5
+ require_once(WPMETASEO_PLUGIN_DIR . '/inc/class.metaseo-category-meta-table.php');
6
+ }
7
+
8
+ add_thickbox();
9
+ $wpmsCategoryMeta = new WPMSCategoryMetaTable();
10
+ $wpmsCategoryMeta->processAction();
11
+ $wpmsCategoryMeta->prepare_items();
12
+
13
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- No action, nonce is not required
14
+ if (!empty($_REQUEST['_wp_http_referer'])) {
15
+ wp_redirect(remove_query_arg(array('_wp_http_referer', '_wpnonce'), stripslashes($_SERVER['REQUEST_URI'])));
16
+ exit;
17
+ }
18
+ ?>
19
+
20
+ <div class="wrap seo_extended_table_page">
21
+ <div id="icon-edit-pages" class="icon32 icon32-posts-page"></div>
22
+
23
+ <form id="wp-seo-meta-form" class="wpms-form-table" action="" method="post">
24
+ <div id="cat-meta-bulk-actions" style="display:none;">
25
+ <div class="m-tb-20">
26
+ <h3 class="wpms-top-h3"><?php esc_html_e('Apply bulk action to', 'wp-meta-seo') ?></h3>
27
+ <p>
28
+ <label class="wpms-text-action">
29
+ <input type="checkbox" class="mbulk_copy wpms-checkbox" value="all">
30
+ <?php esc_html_e('All Categories', 'wp-meta-seo') ?>
31
+ </label>
32
+ </p>
33
+ <p>
34
+ <label class="wpms-text-action">
35
+ <input type="checkbox" class="mbulk_copy wpms-checkbox" value="only-selection" checked="checked">
36
+ <?php esc_html_e('Only Category selection', 'wp-meta-seo') ?>
37
+ </label>
38
+ </p>
39
+ </div>
40
+ <div class="m-tb-20">
41
+ <h3 class="wpms-top-h3"><?php esc_html_e('Action', 'wp-meta-seo') ?></h3>
42
+ <p>
43
+ <label class="wpms-text-action">
44
+ <input type="checkbox" class="wpms-bulk-action wpms-checkbox wpms-bulk-action-metatitle" value="cat-name-to-title">
45
+ <?php esc_html_e('Copy Title as Meta Title', 'wp-meta-seo') ?>
46
+ </label>
47
+ </p>
48
+ <p>
49
+ <label class="wpms-text-action">
50
+ <input type="checkbox" class="wpms-bulk-action wpms-checkbox wpms-bulk-action-metadesc" value="cat-name-to-desc">
51
+ <?php esc_html_e('Copy Title as Meta Description', 'wp-meta-seo') ?>
52
+ </label>
53
+ </p>
54
+ </div>
55
+ <button type="button" name="do_copy" data-action="bulk_cat_copy"
56
+ class="ju-button orange-button btn_do_cat_copy post_do_copy wpms-small-btn wpms_left"><?php esc_html_e('Apply now', 'wp-meta-seo') ?></button>
57
+ <span class="spinner wpms-spinner wpms-spinner-cat-copy wpms_left"></span>
58
+ <label class="bulk-msg"><?php esc_html_e('Done! You may ', 'wp-meta-seo') ?><a href="<?php echo esc_url(admin_url('admin.php?page=metaseo_category_meta')) ?>"><?php esc_html_e('close the window and refresh the page...', 'wp-meta-seo') ?></a></label>
59
+ </div>
60
+ <?php
61
+ echo '<h1 class="wpms-top-h1">' . esc_html__('Category Meta', 'wp-meta-seo') . '
62
+ <i class="material-icons intro-topic-tooltip" data-tippy="'.esc_html__('Edit all your post/product categories meta information here and apply bulk edition on them', 'wp-meta-seo').'">help_outline</i>
63
+ </h1>';
64
+ $wpmsCategoryMeta->searchBox(esc_html__('Search Categories', 'wp-meta-seo'), 'wpms_cat_content');
65
+ $wpmsCategoryMeta->display();
66
+ ?>
67
+ </form>
68
+
69
+ </div>
jufeedback/assets/js/jureview.js CHANGED
@@ -2,7 +2,6 @@ jQuery(document).ready(function($){
2
  if (typeof ajaxurl === "undefined") {
3
  ajaxurl = ju_review.ajaxurl;
4
  }
5
-
6
  $('.jureview-hide-review').on('click', function(e){
7
  var slug = ($(e.target).parents('.jureview-notice').attr('data-slug'));
8
  hide_review(slug);
@@ -27,8 +26,10 @@ jQuery(document).ready(function($){
27
  action: 'jureview_ajax_hide_review_' + slug,
28
  ajaxnonce: ju_review.token
29
  },
30
- success: function () {
31
- $('.jureview-notice[data-slug="' + slug + '"]').hide('fade');
 
 
32
  }
33
  });
34
  }
2
  if (typeof ajaxurl === "undefined") {
3
  ajaxurl = ju_review.ajaxurl;
4
  }
 
5
  $('.jureview-hide-review').on('click', function(e){
6
  var slug = ($(e.target).parents('.jureview-notice').attr('data-slug'));
7
  hide_review(slug);
26
  action: 'jureview_ajax_hide_review_' + slug,
27
  ajaxnonce: ju_review.token
28
  },
29
+ success: function (response) {
30
+ if (typeof response !== 'undefined' && typeof response.status !== 'undefined' && response.status) {
31
+ $('.jureview-notice[data-slug="' + slug + '"]').hide('fade');
32
+ }
33
  }
34
  });
35
  }
jufeedback/assets/js/jureview.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(e){function a(a){e.ajax({url:ajaxurl,dataType:"json",method:"POST",data:{action:"jureview_ajax_hide_review_"+a,ajaxnonce:ju_review.token},success:function(){e('.jureview-notice[data-slug="'+a+'"]').hide("fade")}})}"undefined"==typeof ajaxurl&&(ajaxurl=ju_review.ajaxurl),e(".jureview-hide-review").click(function(t){a(e(t.target).parents(".jureview-notice").attr("data-slug"))}),e(".jureview-already-review").on("click",function(t){t.preventDefault();var r=e(t.target).parents(".jureview-notice").attr("data-slug"),i=e(this).attr("href");window.open(i),a(r)})});
1
+ !function(e){var t={};function r(n){if(t[n])return t[n].exports;var u=t[n]={i:n,l:!1,exports:{}};return e[n].call(u.exports,u,u.exports,r),u.l=!0,u.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var u in e)r.d(n,u,function(t){return e[t]}.bind(null,u));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){jQuery(document).ready((function(e){function t(t){e.ajax({url:ajaxurl,dataType:"json",method:"POST",data:{action:"jureview_ajax_hide_review_"+t,ajaxnonce:ju_review.token},success:function(r){void 0!==r&&void 0!==r.status&&r.status&&e('.jureview-notice[data-slug="'+t+'"]').hide("fade")}})}"undefined"==typeof ajaxurl&&(ajaxurl=ju_review.ajaxurl),e(".jureview-hide-review").on("click",(function(r){t(e(r.target).parents(".jureview-notice").attr("data-slug"))})),e(".jureview-already-review").on("click",(function(r){r.preventDefault();var n=e(r.target).parents(".jureview-notice").attr("data-slug"),u=e(this).attr("href");window.open(u),t(n)}))}))}]);
jufeedback/jufeedback.php CHANGED
@@ -550,6 +550,7 @@ class Jufeedback
550
  {
551
  check_ajax_referer('ju-review', 'ajaxnonce');
552
  update_option(self::$plugin_prefix . '_jureview_installation_time', 'unnecessary');
 
553
  wp_die();
554
  }
555
 
550
  {
551
  check_ajax_referer('ju-review', 'ajaxnonce');
552
  update_option(self::$plugin_prefix . '_jureview_installation_time', 'unnecessary');
553
+ wp_send_json(array('status' => true));
554
  wp_die();
555
  }
556
 
languages/wp-meta-seo-en_US.mo CHANGED
Binary file
readme.txt CHANGED
@@ -3,7 +3,7 @@ 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.7
5
  Tested up to: 5.8.0
6
- Stable tag: 4.3.7
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -258,6 +258,10 @@ Yes WP Meta SEO is compatible with Gutenberg editor since 3.7 version.
258
 
259
  == Changelog ==
260
 
 
 
 
 
261
  = 4.3.7 =
262
  * Fix : The header title issue on some themes
263
 
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.7
5
  Tested up to: 5.8.0
6
+ Stable tag: 4.4.0
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
258
 
259
  == Changelog ==
260
 
261
+ = 4.4.0 =
262
+ * Add : Meta SEO meta box on Elementor
263
+ * Add : Bulk editor for post/product categories
264
+
265
  = 4.3.7 =
266
  * Fix : The header title issue on some themes
267
 
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.3.7
8
  * Text Domain: wp-meta-seo
9
  * Domain Path: /languages
10
  * Author: JoomUnited
@@ -133,7 +133,7 @@ if (!defined('WPMSEO_VERSION')) {
133
  /**
134
  * Plugin version
135
  */
136
- define('WPMSEO_VERSION', '4.3.7');
137
  }
138
 
139
  if (!defined('WPMS_CLIENTID')) {
@@ -395,6 +395,7 @@ if (isset($settings['metaseo_removecatprefix']) && $settings['metaseo_removecatp
395
 
396
  if (is_admin()) {
397
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-content-list-table.php');
 
398
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-image-list-table.php');
399
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-dashboard.php');
400
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-broken-link-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.4.0
8
  * Text Domain: wp-meta-seo
9
  * Domain Path: /languages
10
  * Author: JoomUnited
133
  /**
134
  * Plugin version
135
  */
136
+ define('WPMSEO_VERSION', '4.4.0');
137
  }
138
 
139
  if (!defined('WPMS_CLIENTID')) {
395
 
396
  if (is_admin()) {
397
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-content-list-table.php');
398
+ require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-category-meta-table.php');
399
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-image-list-table.php');
400
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-dashboard.php');
401
  require_once(WPMETASEO_PLUGIN_DIR . 'inc/class.metaseo-broken-link-table.php');