The SEO Framework - Version 2.6.6

Version Description

  • Semantic Structures =

Release date:

  • June 14th 2016

Summarized

  • Page builders are great for if you want to style your website, and when you want to do it fast.
  • So from this update the Divi Builder, Visual Composer, Beaver Builder, and the Page Builder by SiteOrigin are now fully supported.
  • Various bugs have also been fixed, to improve your experience. One particular bugfix is related to Polylang; this bugfix should improve performance and reduce other bugs from happening as well.
  • The Automated and Manual description output has been improved in several ways as well.
  • For developers, a class has been removed. All functions within have been moved to more suitable classes. This change will reduce server resource usage and increase overall performance.

SEO Tip of the Update - Know your Keywords:

  • To know how your website is found, sign up for Google Search Console. Over a couple of days (or weeks), elegant data has been accumulated about your website.
  • When you go to the Search Analytics within the Search Console, you'll see a list of queries people have used to find your website.
  • The queries can be used as keywords, they are excellent starting points for new post titles and subjects. Go ahead, use them!

For developers - About the class removal:

  • Because the plugin makes use of a "Facade pattern", all functions within the plugin are available at all times.
  • In trade for increased resource usage this does make the plugin very compatible, faster, and easier to work with.
  • This plugin serves one single responsibility: Outputting SEO data, and determining the reason why. Therefore, although it looks like a "God object", it's not.
  • Please keep in mind that all functions from any class are available through the "Facade object". Because of this, the class removal shouldn't cause issues for developers.
  • You can call this "Facade object" through a single cached function (rather than a global variable), this cached function is the_seo_framework().
  • If you wish to extend this plugin, feel free to ask me for any details or suggestions at the Support forums.

Detailed Log:

There's something to be said about all these details.

Download this release

Release Info

Developer Cybr
Plugin Icon 128x128 The SEO Framework
Version 2.6.6
Comparing to
See all releases

Version 2.6.6

Files changed (47) hide show
  1. autodescription.php +159 -0
  2. inc/classes/admininit.class.php +468 -0
  3. inc/classes/adminpages.class.php +889 -0
  4. inc/classes/compat.class.php +100 -0
  5. inc/classes/core.class.php +568 -0
  6. inc/classes/debug.class.php +890 -0
  7. inc/classes/detect.class.php +1129 -0
  8. inc/classes/doingitright.class.php +1656 -0
  9. inc/classes/feed.class.php +142 -0
  10. inc/classes/generate-description.class.php +812 -0
  11. inc/classes/generate-image.class.php +363 -0
  12. inc/classes/generate-ldjson.class.php +933 -0
  13. inc/classes/generate-title.class.php +1394 -0
  14. inc/classes/generate-url.class.php +1343 -0
  15. inc/classes/generate.class.php +313 -0
  16. inc/classes/init.class.php +404 -0
  17. inc/classes/inpost.class.php +664 -0
  18. inc/classes/metaboxes.class.php +2424 -0
  19. inc/classes/postdata.class.php +421 -0
  20. inc/classes/query.class.php +1107 -0
  21. inc/classes/render.class.php +1122 -0
  22. inc/classes/sanitize.class.php +978 -0
  23. inc/classes/search.class.php +124 -0
  24. inc/classes/sitemaps.class.php +980 -0
  25. inc/classes/siteoptions.class.php +1090 -0
  26. inc/classes/termdata.class.php +417 -0
  27. inc/classes/transients.class.php +660 -0
  28. inc/deprecated/deprecated.class.php +729 -0
  29. inc/deprecated/deprecated.php +29 -0
  30. inc/functions/benchmark.php +369 -0
  31. inc/functions/compat.php +359 -0
  32. inc/functions/optionsapi.php +229 -0
  33. index.php +2 -0
  34. language/autodescription.pot +1718 -0
  35. lib/css/autodescription-rtl.css +589 -0
  36. lib/css/autodescription-rtl.min.css +1 -0
  37. lib/css/autodescription.css +593 -0
  38. lib/css/autodescription.min.css +1 -0
  39. lib/js/autodescription.js +1276 -0
  40. lib/js/autodescription.min.js +24 -0
  41. license.txt +552 -0
  42. load.class.php +256 -0
  43. patch/2.6.6.patch +3633 -0
  44. patch/index.php +10 -0
  45. readme.txt +753 -0
  46. seotips/index.php +2 -0
  47. seotips/seotips.txt +125 -0
autodescription.php ADDED
@@ -0,0 +1,159 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: The SEO Framework
4
+ * Plugin URI: https://wordpress.org/plugins/autodescription/
5
+ * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
+ * Version: 2.6.6
7
+ * Author: Sybre Waaijer
8
+ * Author URI: https://cyberwire.nl/
9
+ * License: GPLv3
10
+ * Text Domain: autodescription
11
+ * Domain Path: /language
12
+ */
13
+
14
+ /**
15
+ * The SEO Framework plugin
16
+ * Copyright (C) 2015 - 2016 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
17
+ *
18
+ * This program is free software: you can redistribute it and/or modify
19
+ * it under the terms of the GNU General Public License version 3 as published
20
+ * by the Free Software Foundation.
21
+ *
22
+ * This program is distributed in the hope that it will be useful,
23
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ * GNU General Public License for more details.
26
+ *
27
+ * You should have received a copy of the GNU General Public License
28
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
+ */
30
+
31
+ //* Debug. Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
32
+ //add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
33
+ //if ( is_admin() ) {
34
+ // define( 'THE_SEO_FRAMEWORK_DEBUG', true );
35
+ // define( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN', true );
36
+ // define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
37
+ //}
38
+ //}},0);
39
+
40
+ /**
41
+ * CDN Cache buster. 3 to 4 point.
42
+ * Not many caching plugins use CDN in dashboard. What a shame. Firefox does cache.
43
+ * @since 1.0.0
44
+ */
45
+ define( 'THE_SEO_FRAMEWORK_VERSION', '2.6.6' );
46
+
47
+ /**
48
+ * Plugin options filter.
49
+ * @since 2.2.2
50
+ */
51
+ define( 'THE_SEO_FRAMEWORK_SITE_OPTIONS', (string) apply_filters( 'the_seo_framework_site_options', 'autodescription-site-settings' ) );
52
+
53
+ /**
54
+ * Plugin options filter.
55
+ * @since 2.2.2
56
+ */
57
+ define( 'THE_SEO_FRAMEWORK_NETWORK_OPTIONS', (string) apply_filters( 'the_seo_framework_network_settings', 'autodescription-network-settings' ) );
58
+
59
+ /**
60
+ * The plugin map url.
61
+ * Used for calling browser files.
62
+ * @since 2.2.2
63
+ */
64
+ define( 'THE_SEO_FRAMEWORK_DIR_URL', plugin_dir_url( __FILE__ ) );
65
+
66
+ /**
67
+ * The plugin map absolute path.
68
+ * Used for calling php files.
69
+ * @since 2.2.2
70
+ */
71
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH', plugin_dir_path( __FILE__ ) );
72
+
73
+ /**
74
+ * The plugin file relative to the plugins dir.
75
+ * @since 2.2.8
76
+ */
77
+ define( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
78
+
79
+ /**
80
+ * The plugin file, absolute unix path.
81
+ * @since 2.2.9
82
+ */
83
+ define( 'THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE', __FILE__ );
84
+
85
+ /**
86
+ * The plugin class map absolute path.
87
+ * @since 2.2.9
88
+ */
89
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_CLASS', THE_SEO_FRAMEWORK_DIR_PATH . '/inc/classes/' );
90
+
91
+ /**
92
+ * The plugin function map absolute path.
93
+ * @since 2.2.9
94
+ */
95
+ define( 'THE_SEO_FRAMEWORK_DIR_PATH_FUNCT', THE_SEO_FRAMEWORK_DIR_PATH . '/inc/functions/' );
96
+
97
+ add_action( 'plugins_loaded', 'the_seo_framework_locale_init', 10 );
98
+ /**
99
+ * Plugin locale 'autodescription'
100
+ * File located in plugin folder autodescription/language/
101
+ * @since 1.0.0
102
+ */
103
+ function the_seo_framework_locale_init() {
104
+ load_plugin_textdomain( 'autodescription', false, basename( dirname( __FILE__ ) ) . '/language/' );
105
+ }
106
+
107
+ /**
108
+ * Load plugin files.
109
+ * @since 1.0.0
110
+ * @uses THE_SEO_FRAMEWORK_DIR_PATH
111
+ */
112
+ require_once( THE_SEO_FRAMEWORK_DIR_PATH . '/load.class.php' );
113
+
114
+ //* Load deprecated functions.
115
+ //require_once( THE_SEO_FRAMEWORK_DIR_PATH . 'inc/deprecated/deprecated.php' );
116
+
117
+ /**
118
+ * FLush permalinks on activation/deactivation.
119
+ * Calls functions statically.
120
+ * @since 2.2.9
121
+ */
122
+ register_activation_hook( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE, 'the_seo_framework_flush_rewrite_rules_activation' );
123
+ register_deactivation_hook( THE_SEO_FRAMEWORK_PLUGIN_BASE_FILE, 'the_seo_framework_flush_rewrite_rules_deactivation' );
124
+
125
+ /**
126
+ * Add and Flush rewrite rules on plugin activation.
127
+ *
128
+ * @global object $wp_rewrite
129
+ *
130
+ * @since 2.6.6
131
+ * @access private
132
+ */
133
+ function the_seo_framework_flush_rewrite_rules_activation() {
134
+ global $wp_rewrite;
135
+
136
+ $the_seo_framework = the_seo_framework();
137
+ $the_seo_framework->rewrite_rule_sitemap( true );
138
+
139
+ $wp_rewrite->init();
140
+ $wp_rewrite->flush_rules( true );
141
+ }
142
+
143
+ /**
144
+ * Flush rewrite rules on plugin deactivation.
145
+ *
146
+ * @global object $wp_rewrite
147
+ *
148
+ * @since 2.6.6
149
+ * @access private
150
+ */
151
+ function the_seo_framework_flush_rewrite_rules_deactivation() {
152
+ global $wp_rewrite;
153
+
154
+ $wp_rewrite->init();
155
+
156
+ unset( $wp_rewrite->extra_rules_top['sitemap\.xml#x27;] );
157
+
158
+ $wp_rewrite->flush_rules( true );
159
+ }
inc/classes/admininit.class.php ADDED
@@ -0,0 +1,468 @@
1
+ <?php
2
+ /**
3
+ * The SEO Framework plugin
4
+ * Copyright (C) 2015 - 2016 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License version 3 as published
8
+ * by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ /**
20
+ * Class AutoDescription_Admin_Init
21
+ *
22
+ * Initializes the plugin for the wp-admin screens.
23
+ * Enqueues CSS and Javascript.
24
+ *
25
+ * @since 2.1.6
26
+ */
27
+ class AutoDescription_Admin_Init extends AutoDescription_Init {
28
+
29
+ /**
30
+ * Page Hook.
31
+ *
32
+ * @since 2.5.2.2
33
+ *
34
+ * @var String Holds Admin Page hook.
35
+ */
36
+ protected $page_hook;
37
+
38
+ /**
39
+ * JavaScript name identifier to be used with enqueuing.
40
+ *
41
+ * @since 2.5.2.2
42
+ *
43
+ * @var array JavaScript name identifier.
44
+ */
45
+ public $js_name;
46
+
47
+ /**
48
+ * CSS script name identifier to be used with enqueuing.
49
+ *
50
+ * @since 2.6.0
51
+ *
52
+ * @var array CSS name identifier.
53
+ */
54
+ public $css_name;
55
+
56
+ /**
57
+ * Constructor, load parent constructor
58
+ *
59
+ * Initalizes wp-admin functions
60
+ */
61
+ public function __construct() {
62
+ parent::__construct();
63
+
64
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ), 0, 1 );
65
+
66
+ $this->js_name = 'autodescription';
67
+ $this->css_name = 'autodescription';
68
+
69
+ //* Admin AJAX for counter options.
70
+ add_action( 'wp_ajax_the_seo_framework_update_counter', array( $this, 'the_counter_visualized' ) );
71
+
72
+ }
73
+
74
+ /**
75
+ * Enqueues scripts in the admin area on the supported screens.
76
+ *
77
+ * @since 2.3.3
78
+ *
79
+ * @param $hook the current page
80
+ */
81
+ public function enqueue_admin_scripts( $hook ) {
82
+
83
+ $enqueue_hooks = array(
84
+ 'edit.php',
85
+ 'post.php',
86
+ 'post-new.php',
87
+ 'edit-tags.php',
88
+ 'term.php',
89
+ );
90
+
91
+ /**
92
+ * Check hook first.
93
+ * @since 2.3.9
94
+ */
95
+ if ( isset( $hook ) && $hook && in_array( $hook, $enqueue_hooks ) ) {
96
+ /**
97
+ * @uses $this->post_type_supports_custom_seo()
98
+ * @since 2.3.9
99
+ */
100
+ if ( $this->post_type_supports_custom_seo() )
101
+ $this->init_admin_scripts();
102
+
103
+ }
104
+
105
+ }
106
+
107
+ /**
108
+ * Register and output Admin scripts.
109
+ *
110
+ * @since 2.6.0
111
+ */
112
+ public function init_admin_scripts() {
113
+
114
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_css' ), 1 );
115
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_javascript' ), 1 );
116
+
117
+ }
118
+
119
+ /**
120
+ * AutoDescription JavaScript helper file
121
+ *
122
+ * @since 2.0.2
123
+ *
124
+ * @usedby add_inpost_seo_box
125
+ * @usedby enqueue_javascript
126
+ *
127
+ * @param string|array|object $hook the current page
128
+ */
129
+ public function enqueue_admin_javascript( $hook ) {
130
+
131
+ /**
132
+ * Put hook and js name in class vars.
133
+ * @since 2.5.2.2
134
+ */
135
+ $this->page_hook = $this->page_hook ? $this->page_hook : $hook;
136
+
137
+ //* Register the script.
138
+ $this->register_admin_javascript();
139
+
140
+ wp_enqueue_script( $this->js_name );
141
+
142
+ /**
143
+ * Localize JavaScript.
144
+ * @since 2.5.2.2
145
+ */
146
+ add_action( 'admin_footer', array( $this, 'localize_admin_javascript' ) );
147
+
148
+ }
149
+
150
+ /**
151
+ * Registers Admin CSS.
152
+ *
153
+ * @since 2.6.0
154
+ * @staticvar bool $registered : Prevents Re-registering of the style.
155
+ *
156
+ * @access private
157
+ */
158
+ public function register_admin_javascript() {
159
+
160
+ static $registered = null;
161
+
162
+ if ( isset( $registered ) )
163
+ return;
164
+
165
+ $suffix = $this->script_debug ? '' : '.min';
166
+
167
+ wp_register_script( $this->js_name, THE_SEO_FRAMEWORK_DIR_URL . "lib/js/autodescription{$suffix}.js", array( 'jquery' ), THE_SEO_FRAMEWORK_VERSION, true );
168
+
169
+ $registered = true;
170
+
171
+ }
172
+
173
+ /**
174
+ * Localizes admin javascript.
175
+ *
176
+ * @since 2.5.2.2
177
+ */
178
+ public function localize_admin_javascript() {
179
+
180
+ static $localized = null;
181
+
182
+ if ( isset( $localized ) )
183
+ return;
184
+
185
+ $strings = $this->get_javascript_l10n();
186
+
187
+ wp_localize_script( $this->js_name, 'autodescriptionL10n', $strings );
188
+
189
+ $localized = true;
190
+
191
+ }
192
+
193
+ /**
194
+ * Generate Javascript Localization.
195
+ *
196
+ * @since 2.6.0
197
+ * @staticvar array $strings : The l10n strings.
198
+ *
199
+ * @return array $strings The l10n strings.
200
+ */
201
+ protected function get_javascript_l10n() {
202
+
203
+ static $strings = null;
204
+
205
+ if ( isset( $strings ) )
206
+ return $strings;
207
+
208
+ $blog_name = $this->get_blogname();
209
+ $description = $this->get_blogdescription();
210
+ $title = '';
211
+ $additions = '';
212
+
213
+ $tagline = (bool) $this->get_option( 'homepage_tagline' );
214
+ $home_tagline = $this->get_option( 'homepage_title_tagline' );
215
+ $title_location = $this->get_option( 'title_location' );
216
+ $title_add_additions = $this->add_title_additions();
217
+ $counter_type = $this->get_option( 'counter_type' );
218
+
219
+ //* Enunciate the lenghts of Titles and Descriptions.
220
+ $good = __( 'Good', 'autodescription' );
221
+ $okay = __( 'Okay', 'autodescription' );
222
+ $bad = __( 'Bad', 'autodescription' );
223
+ $unknown = __( 'Unknown', 'autodescription' );
224
+
225
+ $separator = $this->get_separator( 'title', true );
226
+
227
+ $rtl = (bool) is_rtl();
228
+ $ishome = false;
229
+
230
+ /**
231
+ * We're gaining UX in exchange for resource usage.
232
+ *
233
+ * Any way to cache this?
234
+ *
235
+ * @since 2.2.4
236
+ */
237
+ if ( isset( $this->page_hook ) && $this->page_hook ) {
238
+ // We're somewhere within default WordPress pages.
239
+ $post_id = $this->get_the_real_ID();
240
+
241
+ if ( $this->is_static_frontpage( $post_id ) ) {
242
+ $title = $blog_name;
243
+ $title_location = $this->get_option( 'home_title_location' );
244
+ $ishome = true;
245
+
246
+ if ( $tagline ) {
247
+ $additions = $home_tagline ? $home_tagline : $description;
248
+ } else {
249
+ $additions = '';
250
+ }
251
+ } else if ( $post_id ) {
252
+ //* We're on post.php
253
+ $generated_doctitle_args = array(
254
+ 'term_id' => $post_id,
255
+ 'notagline' => true,
256
+ 'get_custom_field' => false,
257
+ );
258
+
259
+ $title = $this->title( '', '', '', $generated_doctitle_args );
260
+
261
+ if ( $title_add_additions ) {
262
+ $additions = $blog_name;
263
+ $tagline = true;
264
+ } else {
265
+ $additions = '';
266
+ $tagline = false;
267
+ }
268
+ } else if ( $this->is_archive() ) {
269
+ //* Category or Tag.
270
+ global $current_screen;
271
+
272
+ if ( isset( $current_screen->taxonomy ) ) {
273
+
274
+ $term_id = $this->get_admin_term_id();
275
+
276
+ if ( $term_id ) {
277
+ $generated_doctitle_args = array(
278
+ 'term_id' => $term_id,
279
+ 'taxonomy' => $current_screen->taxonomy,
280
+ 'notagline' => true,
281
+ 'get_custom_field' => false
282
+ );
283
+
284
+ $title = $this->title( '', '', '', $generated_doctitle_args );
285
+ $additions = $title_add_additions ? $blog_name : '';
286
+ }
287
+ }
288
+
289
+ } else {
290
+ //* We're in a special place.
291
+ // Can't fetch title.
292
+ $title = '';
293
+ $additions = $title_add_additions ? $blog_name : '';
294
+ }
295
+
296
+ } else {
297
+ // We're on our SEO settings pages.
298
+ if ( $this->has_page_on_front() ) {
299
+ // Home is a page.
300
+ $inpost_title = $this->get_custom_field( '_genesis_title', get_option( 'page_on_front' ) );
301
+ } else {
302
+ // Home is a blog.
303
+ $inpost_title = '';
304
+ }
305
+ $title = $inpost_title ? $inpost_title : $blog_name;
306
+ $additions = $home_tagline ? $home_tagline : $description;
307
+ }
308
+
309
+ return $strings = array(
310
+ 'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.', 'autodescription' ),
311
+ 'confirmReset' => __( 'Are you sure you want to reset all SEO settings to their defaults?', 'autodescription' ),
312
+ 'siteTitle' => $title,
313
+ 'titleAdditions' => $additions,
314
+ 'blogDescription' => $description,
315
+ 'titleTagline' => $tagline,
316
+ 'titleSeparator' => $separator,
317
+ 'titleLocation' => $title_location,
318
+ 'isRTL' => $rtl,
319
+ 'isHome' => $ishome,
320
+ 'counterType' => $counter_type,
321
+ 'good' => $good,
322
+ 'okay' => $okay,
323
+ 'bad' => $bad,
324
+ 'unknown' => $unknown,
325
+ );
326
+ }
327
+
328
+ /**
329
+ * CSS for the AutoDescription Bar
330
+ *
331
+ * @since 2.1.9
332
+ *
333
+ * @param $hook the current page
334
+ *
335
+ * @todo get_network_option
336
+ * @priority low 3.0.0
337
+ */
338
+ public function enqueue_admin_css( $hook ) {
339
+
340
+ /**
341
+ * Put hook and js name in class vars.
342
+ * @since 2.5.2.2
343
+ */
344
+ $this->page_hook = $this->page_hook ? $this->page_hook : $hook;
345
+
346
+ //* Register the script.
347
+ $this->register_admin_css();
348
+
349
+ wp_enqueue_style( $this->css_name );
350
+
351
+ }
352
+
353
+ /**
354
+ * Registers Admin CSS.
355
+ *
356
+ * @since 2.6.0
357
+ * @staticvar bool $registered : Prevents Re-registering of the style.
358
+ *
359
+ * @access private
360
+ */
361
+ protected function register_admin_css() {
362
+
363
+ static $registered = null;
364
+
365
+ if ( isset( $registered ) )
366
+ return;
367
+
368
+ $rtl = '';
369
+
370
+ if ( is_rtl() )
371
+ $rtl = '-rtl';
372
+
373
+ $suffix = $this->script_debug ? '' : '.min';
374
+
375
+ wp_register_style( $this->css_name, THE_SEO_FRAMEWORK_DIR_URL . "lib/css/autodescription{$rtl}{$suffix}.css", array(), THE_SEO_FRAMEWORK_VERSION, 'all' );
376
+
377
+ $registered = true;
378
+
379
+ }
380
+
381
+ /**
382
+ * Checks the screen hook.
383
+ *
384
+ * @since 2.2.2
385
+ * @global string $page_hook the current page hook.
386
+ *
387
+ * @return bool true if screen match.
388
+ */
389
+ public function is_menu_page( $pagehook = '' ) {
390
+ global $page_hook;
391
+
392
+ if ( isset( $page_hook ) && $page_hook === $pagehook )
393
+ return true;
394
+
395
+ //* May be too early for $page_hook
396
+ if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] === $pagehook )
397
+ return true;
398
+
399
+ return false;
400
+ }
401
+
402
+ /**
403
+ * Redirect the user to an admin page, and add query args to the URL string
404
+ * for alerts, etc.
405
+ *
406
+ * @since 2.2.2
407
+ *
408
+ * @param string $page Menu slug.
409
+ * @param array $query_args Optional. Associative array of query string arguments
410
+ * (key => value). Default is an empty array.
411
+ *
412
+ * @credits StudioPress for some code.
413
+ *
414
+ * @return null Return early if first argument is false.
415
+ */
416
+ public function admin_redirect( $page, array $query_args = array() ) {
417
+
418
+ if ( empty( $page ) )
419
+ return;
420
+
421
+ $url = html_entity_decode( menu_page_url( $page, 0 ) );
422
+
423
+ foreach ( $query_args as $key => $value ) {
424
+ if ( empty( $key ) || empty( $value ) )
425
+ unset( $query_args[$key] );
426
+ }
427
+
428
+ $url = add_query_arg( $query_args, $url );
429
+
430
+ wp_redirect( esc_url_raw( $url ) );
431
+ exit;
432
+ }
433
+
434
+
435
+ /**
436
+ * Handles counter option update on AJAX request.
437
+ *
438
+ * @since 2.6.0
439
+ * @access private
440
+ */
441
+ public function the_counter_visualized() {
442
+
443
+ if ( $this->is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
444
+ //* If current user isn't allowed to edit posts, don't do anything.
445
+ if ( ! current_user_can( 'publish_posts' ) )
446
+ exit;
447
+
448
+ $options = $this->get_all_options();
449
+
450
+ /**
451
+ * Count up, reset to 0 if needed. We have 4 options: 0, 1, 2, 3
452
+ * We're not accepting any $_POST values. Keeping it clean.
453
+ * Yet we should for consistency. @TODO
454
+ * @priority high 2.6.2
455
+ */
456
+ $options['counter_type'] = $options['counter_type'] + 1;
457
+ if ( $options['counter_type'] > 3 )
458
+ $options['counter_type'] = 0;
459
+
460
+ update_option( $this->settings_field, $options );
461
+
462
+ //* Kill PHP.
463
+ exit;
464
+ }
465
+
466
+ }
467
+
468
+ }
inc/classes/adminpages.class.php ADDED
@@ -0,0 +1,889 @@
1
+ <?php
2
+ /**
3
+ * The SEO Framework plugin
4
+ * Copyright (C) 2015 - 2016 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License version 3 as published
8
+ * by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ /**
20
+ * Class AutoDescription_Siteoptions
21
+ *
22
+ * Renders admin pages content for AutoDescription.
23
+ *
24
+ * @since 2.2.2
25
+ */
26
+ class AutoDescription_Adminpages extends AutoDescription_Inpost {
27
+
28
+ /**
29
+ * Page Defaults.
30
+ *
31
+ * @since 2.2.2
32
+ *
33
+ * @var array Holds Page output defaults.
34
+ */
35
+ public $page_defaults = array();
36
+
37
+ /**
38
+ * Name of the page hook when the menu is registered.
39
+ *
40
+ * @since 2.2.2
41
+ *
42
+ * @var string Page hook
43
+ */
44
+ public $pagehook;
45
+
46
+ /**
47
+ * Name of the network page hook when the menu is registered.
48
+ *
49
+ * @since 2.2.2
50
+ *
51
+ * @var string Page hook
52
+ */
53
+ public $network_pagehook;
54
+
55
+ /**
56
+ * Load the options.
57
+ *
58
+ * @since 2.6.0
59
+ *
60
+ * @var bool Load options.
61
+ */
62
+ public $load_options;
63
+
64
+ /**
65
+ * Constructor, load parent constructor and set up variables.
66
+ */
67
+ public function __construct() {
68
+ parent::__construct();
69
+
70
+ /**
71
+ * Applies filters the_seo_framework_load_options : Boolean Allows the options page to be removed
72
+ * @since 2.2.2
73
+ */
74
+ $this->load_options = (bool) apply_filters( 'the_seo_framework_load_options', true );
75
+
76
+ if ( $this->load_options ) {
77
+ add_action( 'admin_init', array( $this, 'enqueue_page_defaults' ), 1 );
78
+
79
+ // Add menu links and register $this->pagehook
80
+ add_action( 'admin_menu', array( $this, 'add_menu_link' ) );
81
+
82
+ /**
83
+ * Add specific Multisite options
84
+ * @TODO
85
+ * @priority low 3.0.0
86
+ */
87
+ // if ( is_multisite() ) add_action( 'network_admin_menu', array( $this, 'add_network_menu_link' ) );
88
+
89
+ //* Load the page content
90
+ add_action( 'admin_init', array( $this, 'settings_init' ) );
91
+
92
+ // Set up notices
93
+ add_action( 'admin_notices', array( $this, 'notices' ) );
94
+
95
+ // Load nessecary assets
96
+ add_action( 'admin_init', array( $this, 'load_assets' ) );
97
+ }
98
+
99
+ }
100
+
101
+ /**
102
+ * Enqueue page defaults early.
103
+ *
104
+ * Applies filter 'the_seo_framework_admin_page_defaults' : Array
105
+ * This filter adds i18n support for buttons and notices.
106
+ *
107
+ * @since 2.3.1
108
+ */
109
+ public function enqueue_page_defaults() {
110
+
111
+ $this->page_defaults = (array) apply_filters(
112
+ 'the_seo_framework_admin_page_defaults',
113
+ array(
114
+ 'save_button_text' => __( 'Save Settings', 'autodescription' ),
115
+ 'reset_button_text' => __( 'Reset Settings', 'autodescription' ),
116
+ 'saved_notice_text' => __( 'Settings are saved.', 'autodescription' ),
117
+ 'reset_notice_text' => __( 'Settings are reset.', 'autodescription' ),
118
+ 'error_notice_text' => __( 'Error saving settings.', 'autodescription' ),
119
+ 'plugin_update_text' => __( 'New SEO Settings have been updated.', 'autodescription' ),
120
+ )
121
+ );
122
+
123
+ }
124
+
125
+ /**
126
+ * Adds menu links under "settings" in the wp-admin dashboard
127
+ *
128
+ * @since 2.2.2
129
+ *
130
+ * @return void
131
+ */
132
+ public function add_menu_link() {
133
+
134
+ $menu = array(
135
+ 'pagetitle' => __( 'SEO Settings', 'autodescription' ),
136
+ 'menutitle' => __( 'SEO', 'autodescription' ),
137
+ 'capability' => $this->settings_capability(),
138
+ 'menu_slug' => 'autodescription-settings',
139
+ 'callback' => array( $this, 'admin' ),
140
+ 'icon' => 'dashicons-search',
141
+ 'position' => '90.9001',
142
+ );
143
+
144
+ $this->pagehook = add_menu_page(
145
+ $menu['pagetitle'],
146
+ $menu['menutitle'],
147
+ $menu['capability'],
148
+ $menu['menu_slug'],
149
+ $menu['callback'],
150
+ $menu['icon'],
151
+ $menu['position']
152
+ );
153
+
154
+ //* Enqueue styles
155
+ add_action( 'admin_print_styles-' . $this->pagehook, array( $this, 'enqueue_admin_css' ), 11 );
156
+
157
+ //* Enqueue scripts
158
+ add_action( 'admin_print_scripts-' . $this->pagehook, array( $this, 'enqueue_admin_javascript' ), 11 );
159
+
160
+ }
161
+
162
+ /**
163
+ * Adds menu links under "settings" in the wp-admin dashboard
164
+ *
165
+ * Applies `autodescription_settings_capability` filters.
166
+ * This filter changes the minimum role for viewing and editing the plugin's settings.
167
+ *
168
+ * @since 2.2.2
169
+ * @return void
170
+ *
171
+ * @TODO Everything.
172
+ * @priority low 3.0.0
173
+ */
174
+ public function add_network_menu_link() {
175
+
176
+ $menu = array(
177
+ 'pagetitle' => __( 'Network SEO Settings', 'autodescription' ),
178
+ 'menutitle' => __( 'Network SEO', 'autodescription' ),
179
+
180
+ 'capability' => 'manage_network',
181
+
182
+ 'menu_slug' => 'autodescription-network-settings',
183
+ 'callback' => array( $this, 'network_admin' ),
184
+ 'icon' => 'dashicons-search',
185
+ 'position' => '99.9001',
186
+ );
187
+
188
+ $this->network_pagehook = add_menu_page(
189
+ $menu['pagetitle'],
190
+ $menu['menutitle'],
191
+ $menu['capability'],
192
+ $menu['menu_slug'],
193
+ $menu['callback'],
194
+ $menu['icon'],
195
+ $menu['position']
196
+ );
197
+
198
+ // Enqueue styles
199
+ add_action( 'admin_print_styles-' . $this->network_pagehook, array( $this, 'enqueue_admin_css' ), 11 );
200
+
201
+ // Enqueue scripts
202
+ add_action( 'admin_print_scripts-' . $this->network_pagehook, array( $this, 'enqueue_admin_javascript' ), 11 );
203
+
204
+ }
205
+
206
+ /**
207
+ * Initialize the settings page.
208
+ *
209
+ * @since 2.2.2
210
+ */
211
+ public function settings_init() {
212
+
213
+ add_action( $this->pagehook . '_settings_page_boxes', array( $this, 'do_metaboxes' ) );
214
+ add_action( 'load-' . $this->pagehook, array( $this, 'metaboxes' ) );
215
+
216
+ }
217
+
218
+ /**
219
+ * Echo out the do_metaboxes() and wrapping markup.
220
+ *
221
+ * @since 2.2.2
222
+ *
223
+ * @global array $wp_meta_boxes Holds all metaboxes data.
224
+ */
225
+ public function do_metaboxes() {
226
+ global $wp_meta_boxes;
227
+
228
+ ?>
229
+ <div class="metabox-holder columns-2">
230
+ <div class="postbox-container-1">
231
+ <?php
232
+ do_action( 'the_seo_framework_before_siteadmin_metaboxes', $this->pagehook );
233
+
234
+ do_meta_boxes( $this->pagehook, 'main', null );
235
+
236
+ if ( isset( $wp_meta_boxes[$this->pagehook]['main_extra'] ) )
237
+ do_meta_boxes( $this->pagehook, 'main_extra', null );
238
+
239
+ do_action( 'the_seo_framework_after_siteadmin_metaboxes', $this->pagehook );
240
+ ?>
241
+ </div>
242
+ <div class="postbox-container-2">
243
+ <?php
244
+ do_action( 'the_seo_framework_before_siteadmin_metaboxes_side', $this->pagehook );
245
+
246
+ /**
247
+ * @TODO fill this in
248
+ * @priority low 2.9.0
249
+ */
250
+
251
+ do_action( 'the_seo_framework_after_siteadmin_metaboxes_side', $this->pagehook );
252
+ ?>
253
+ </div>
254
+ </div>
255
+ <?php
256
+ }
257
+
258
+ /**
259
+ * Register meta boxes on the Site SEO Settings page.
260
+ *
261
+ * @since 2.2.2
262
+ *
263
+ * @see $this->title_metabox() Callback for Title Settings box.
264
+ * @see $this->description_metabox() Callback for Description Settings box.
265
+ * @see $this->robots_metabox() Callback for Robots Settings box.
266
+ * @see $this->homepage_metabox() Callback for Home Page Settings box.
267
+ * @see $this->social_metabox() Callback for Social Settings box.
268
+ * @see $this->knowledge_metabox() Callback for Knowledge Graph Settings box.
269
+ * @see $this->schema_metabox() Callback for Schema Settings box.
270
+ * @see $this->webmaster_metabox() Callback for Webmaster Settings box.
271
+ * @see $this->sitemaps_metabox() Callback for Sitemap Settings box.
272
+ * @see $this->feed_metabox() Callback for Feed Settings box.
273
+ */
274
+ public function metaboxes() {
275
+
276
+ /**
277
+ * Various metabox filters.
278
+ * Set any to false if you wish the meta box to be removed.
279
+ *
280
+ * @since 2.2.4
281
+ */
282
+ $title = (bool) apply_filters( 'the_seo_framework_title_metabox', true );
283
+ $description = (bool) apply_filters( 'the_seo_framework_description_metabox', true );
284
+ $robots = (bool) apply_filters( 'the_seo_framework_robots_metabox', true );
285
+ $home = (bool) apply_filters( 'the_seo_framework_home_metabox', true );
286
+ $social = (bool) apply_filters( 'the_seo_framework_social_metabox', true );
287
+ $knowledge = (bool) apply_filters( 'the_seo_framework_knowledge_metabox', true );
288
+ $schema = (bool) apply_filters( 'the_seo_framework_schema_metabox', true );
289
+ $webmaster = (bool) apply_filters( 'the_seo_framework_webmaster_metabox', true );
290
+ $sitemap = (bool) apply_filters( 'the_seo_framework_sitemap_metabox', true );
291
+ $feed = (bool) apply_filters( 'the_seo_framework_feed_metabox', true );
292
+
293
+ //* Title Meta Box
294
+ if ( $title )
295
+ add_meta_box(
296
+ 'autodescription-title-settings',
297
+ __( 'Title Settings', 'autodescription' ),
298
+ array( $this, 'title_metabox' ),
299
+ $this->pagehook,
300
+ 'main'
301
+ );
302
+
303
+ //* Description Meta Box
304
+ if ( $description )
305
+ add_meta_box(
306
+ 'autodescription-description-settings',
307
+ __( 'Description Meta Settings', 'autodescription' ),
308
+ array( $this, 'description_metabox' ),
309
+ $this->pagehook,
310
+ 'main'
311
+ );
312
+
313
+ //* Home Page Meta Box
314
+ if ( $home )
315
+ add_meta_box(
316
+ 'autodescription-homepage-settings',
317
+ __( 'Home Page Settings', 'autodescription' ),
318
+ array( $this, 'homepage_metabox' ),
319
+ $this->pagehook,
320
+ 'main'
321
+ );
322
+
323
+ //* Social Meta Box
324
+ if ( $social )
325
+ add_meta_box(
326
+ 'autodescription-social-settings',
327
+ __( 'Social Meta Settings', 'autodescription' ),
328
+ array( $this, 'social_metabox' ),
329
+ $this->pagehook,
330
+ 'main'
331
+ );
332
+
333
+ //* Knowledge Graph Meta Box
334
+ if ( $knowledge )
335
+ add_meta_box(
336
+ 'autodescription-knowledgegraph-settings',
337
+ __( 'Knowledge Graph Settings', 'autodescription' ),
338
+ array( $this, 'knowledge_metabox' ),
339
+ $this->pagehook,
340
+ 'main'
341
+ );
342
+
343
+ //* Title Meta Box
344
+ if ( $schema )
345
+ add_meta_box(
346
+ 'autodescription-schema-settings',
347
+ __( 'Schema Settings', 'autodescription' ),
348
+ array( $this, 'schema_metabox' ),
349
+ $this->pagehook,
350
+ 'main'
351
+ );
352
+
353
+ //* Robots Meta Box
354
+ if ( $robots )
355
+ add_meta_box(
356
+ 'autodescription-robots-settings',
357
+ __( 'Robots Meta Settings', 'autodescription' ),
358
+ array( $this, 'robots_metabox' ),
359
+ $this->pagehook,
360
+ 'main'
361
+ );
362
+
363
+ //* Webmaster Meta Box
364
+ if ( $webmaster )
365
+ add_meta_box(
366
+ 'autodescription-webmaster-settings',
367
+ __( 'Webmaster Meta Settings', 'autodescription' ),
368
+ array( $this, 'webmaster_metabox' ),
369
+ $this->pagehook,
370
+ 'main'
371
+ );
372
+
373
+ //* Sitemaps Meta Box
374
+ if ( $sitemap )
375
+ add_meta_box(
376
+ 'autodescription-sitemap-settings',
377
+ __( 'Sitemap Settings', 'autodescription' ),
378
+ array( $this, 'sitemaps_metabox' ),
379
+ $this->pagehook,
380
+ 'main'
381
+ );
382
+
383
+ //* Feed Meta Box
384
+ if ( $feed )
385
+ add_meta_box(
386
+ 'autodescription-feed-settings',
387
+ __( 'Feed Settings', 'autodescription' ),
388
+ array( $this, 'feed_metabox' ),
389
+ $this->pagehook,
390
+ 'main'
391
+ );
392
+
393
+ }
394
+
395
+ /**
396
+ * Use this as the settings admin callback to create an admin page with sortable metaboxes.
397
+ * Create a 'settings_boxes' method to add metaboxes.
398
+ *
399
+ * @since 2.2.2
400
+ */
401
+ public function admin() {
402
+
403
+ ?>
404
+ <div class="wrap autodescription-metaboxes">
405
+ <form method="post" action="options.php">
406
+
407
+ <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
408
+ <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
409
+ <?php settings_fields( $this->settings_field ); ?>
410
+
411
+ <div class="top-wrap">
412
+ <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
413
+ <p class="top-buttons">
414
+ <?php
415
+ submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
416
+ submit_button( $this->page_defaults['reset_button_text'], 'secondary autodescription-js-confirm-reset', $this->get_field_name( 'reset' ), false, array( 'id' => '' ) );
417
+ ?>
418
+ </p>
419
+ </div>
420
+
421
+ <?php do_action( "{$this->pagehook}_settings_page_boxes", $this->pagehook ); ?>
422
+
423
+ <div class="bottom-buttons">
424
+ <?php
425
+ submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
426
+ submit_button( $this->page_defaults['reset_button_text'], 'secondary autodescription-js-confirm-reset', $this->get_field_name( 'reset' ), false, array( 'id' => '' ) );
427
+ ?>
428
+ </div>
429
+ </form>
430
+ </div>
431
+ <?php // Add postbox listeners ?>
432
+ <script type="text/javascript">
433
+ //<![CDATA[
434
+ jQuery(document).ready( function ($) {
435
+ // close postboxes that should be closed
436
+ $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
437
+ // postboxes setup
438
+ postboxes.add_postbox_toggles('<?php echo $this->pagehook; ?>');
439
+ });
440
+ //]]>
441
+ </script>
442
+ <?php
443
+
444
+ }
445
+
446
+ /**
447
+ * Use this as the settings admin callback to create an admin page with sortable metaboxes.
448
+ * Create a 'settings_boxes' method to add metaboxes.
449
+ *
450
+ * @since 2.2.2
451
+ */
452
+ public function network_admin() {
453
+
454
+ ?>
455
+ <div class="wrap autodescription-metaboxes">
456
+ <form method="post" action="options.php">
457
+
458
+ <?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
459
+ <?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
460
+ <?php settings_fields( $this->network_settings_field ); ?>
461
+
462
+ <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
463
+ <p class="top-buttons">
464
+ <?php
465
+ submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
466
+ submit_button( $this->page_defaults['reset_button_text'], 'secondary autodescription-js-confirm-reset', $this->get_field_name( 'reset' ), false, array( 'id' => '' ) );
467
+ ?>
468
+ </p>
469
+
470
+ <?php do_action( "{$this->network_pagehook}_settings_page_boxes", $this->network_pagehook ); ?>
471
+
472
+ <div class="bottom-buttons">
473
+ <?php
474
+ submit_button( $this->page_defaults['save_button_text'], 'primary', 'submit', false, array( 'id' => '' ) );
475
+ submit_button( $this->page_defaults['reset_button_text'], 'secondary autodescription-js-confirm-reset', $this->get_field_name( 'reset' ), false, array( 'id' => '' ) );
476
+ ?>
477
+ </div>
478
+ </form>
479
+ </div>
480
+ <?php // Add postbox listeners ?>
481
+ <script type="text/javascript">
482
+ //<![CDATA[
483
+ jQuery(document).ready( function ($) {
484
+ // close postboxes that should be closed
485
+ $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
486
+ // postboxes setup
487
+ postboxes.add_postbox_toggles('<?php echo $this->network_pagehook; ?>');
488
+ });
489
+ //]]>
490
+ </script>
491
+ <?php
492
+
493
+ }
494
+
495
+ /**
496
+ * Display notices on the save or reset of settings.
497
+ *
498
+ * @since 2.2.2
499
+ *
500
+ * @return void
501
+ */
502
+ public function notices() {
503
+
504
+ if ( false === $this->is_seo_settings_page() )
505
+ return;
506
+
507
+ if ( isset( $_REQUEST['settings-updated'] ) && 'true' === $_REQUEST['settings-updated'] )
508
+ echo $this->generate_dismissible_notice( $this->page_defaults['saved_notice_text'], 'updated' );
509
+ elseif ( isset( $_REQUEST['reset'] ) && 'true' === $_REQUEST['reset'] )
510
+ echo $this->generate_dismissible_notice( $this->page_defaults['reset_notice_text'], 'warning' );
511
+ elseif ( isset( $_REQUEST['error'] ) && 'true' === $_REQUEST['error'] )
512
+ echo $this->generate_dismissible_notice( $this->page_defaults['error_notice_text'], 'error' );
513
+ elseif ( isset( $_REQUEST['seo-updated'] ) && 'true' === $_REQUEST['seo-updated'] )
514
+ echo $this->generate_dismissible_notice( $this->page_defaults['plugin_update_text'], 'updated' );
515
+
516
+ }
517
+
518
+ /**
519
+ * Helper function that constructs name attributes for use in form fields.
520
+ *
521
+ * Other page implementation classes may wish to construct and use a
522
+ * get_field_id() method, if the naming format needs to be different.
523
+ *
524
+ * @since 2.2.2
525
+ *
526
+ * @param string $name Field name base
527
+ * @return string Full field name
528
+ */
529
+ public function get_field_name( $name ) {
530
+ return sprintf( '%s[%s]', $this->settings_field, $name );
531
+ }
532
+
533
+ /**
534
+ * Echo constructed name attributes in form fields.
535
+ *
536
+ * @since 2.2.2
537
+ *
538
+ * @uses $this->get_field_name() Construct name attributes for use in form fields.
539
+ *
540
+ * @param string $name Field name base
541
+ */
542
+ public function field_name( $name ) {
543
+ echo $this->get_field_name( $name );
544
+ }
545
+
546
+ /**
547
+ * Helper function that constructs id attributes for use in form fields.
548
+ *
549
+ * @since 2.2.2
550
+ *
551
+ * @param string $id Field id base
552
+ * @return string Full field id
553
+ */
554
+ public function get_field_id( $id ) {
555
+ return sprintf( '%s[%s]', $this->settings_field, $id );
556
+ }
557
+
558
+ /**
559
+ * Echo constructed id attributes in form fields.
560
+ *
561
+ * @since 2.2.2
562
+ *
563
+ * @uses $this->get_field_id() Constructs id attributes for use in form fields.
564
+ *
565
+ * @param string $id Field id base
566
+ * @param boolean $echo echo or return
567
+ * @return string Full field id
568
+ */
569
+ public function field_id( $id, $echo = true ) {
570
+
571
+ if ( $echo ) {
572
+ echo $this->get_field_id( $id );
573
+ } else {
574
+ return $this->get_field_id( $id );
575
+ }
576
+ }
577
+
578
+ /**
579
+ * Helper function that returns a setting value from this form's settings
580
+ * field for use in form fields.
581
+ *
582
+ * Fetches blog option.
583
+ *
584
+ * @since 2.2.2
585
+ *
586
+ * @param string $key Field key
587
+ * @return string Field value
588
+ */
589
+ public function get_field_value( $key ) {
590
+ return $this->get_option( $key, $this->settings_field );
591
+ }
592
+
593
+ /**
594
+ * Helper function that returns a setting value from this form's settings
595
+ * field for use in form fields.
596
+ *
597
+ * Fetches network option.
598
+ *
599
+ * @since 2.2.2
600
+ *
601
+ * @param string $key Field key
602
+ * @return string Field value
603
+ */
604
+ public function get_field_value_network( $key ) {
605
+ return $this->get_site_option( $key, $this->settings_field );
606
+ }
607
+
608
+ /**
609
+ * Echo a setting value from this form's settings field for use in form fields.
610
+ *
611
+ * @uses $this->get_field_value() Constructs value attributes for use in form fields.
612
+ *
613
+ * @since 2.2.2
614
+ *
615
+ * @param string $key Field key
616
+ */
617
+ public function field_value( $key ) {
618
+ echo $this->get_field_value( $key );
619
+ }
620
+
621
+ /**
622
+ * Echo or return a chechbox fields wrapper.
623
+ *
624
+ * @since 2.6.0
625
+ *
626
+ * @param string $input The input to wrap.
627
+ * @param bool $echo Whether to echo or return.
628
+ *
629
+ * @return Wrapped $input.
630
+ */
631
+ public function wrap_fields( $input = '', $echo = false ) {
632
+
633
+ if ( is_array( $input ) )
634
+ $input = implode( "\r\n", $input );
635
+
636
+ if ( $echo )
637
+ echo '<div class="theseoframework-fields">' . "\r\n" . $input . "\r\n" . '</div>';
638
+ else
639
+ return '<div class="theseoframework-fields">' . "\r\n" . $input . "\r\n" . '</div>';
640
+ }
641
+
642
+ /**
643
+ * Return a chechbox wrapper.
644
+ *
645
+ * @since 2.6.0
646
+ *
647
+ * @param string $field_id The option ID. Must be within the Autodescription settings.
648
+ * @param string $label The checkbox description label
649
+ * @param string $description Addition description to place beneath the checkbox.
650
+ *
651
+ * @return HTML checkbox output.
652
+ */
653
+ public function make_checkbox( $field_id = '', $label = '', $description = '' ) {
654
+
655
+ $description = $description ? '<p class="description theseoframework-option-spacer">' . $description . '</p>' : '';
656
+
657
+ $output = '<span class="toblock">'
658
+ . '<label for="' . $this->get_field_id( $field_id ) . '">'
659
+ . '<input '
660
+ . 'type="checkbox" '
661
+ . 'name="' . $this->get_field_name( $field_id ) . '" '
662
+ . 'id="' . $this->get_field_id( $field_id ) . '" '
663
+ . $this->get_is_conditional_checked( $field_id ) . ' '
664
+ . 'value="1" '
665
+ . checked( $this->get_field_value( $field_id ), true, false ) .
666
+ ' />'
667
+ . $label
668
+ . '</label>'
669
+ . '</span>'
670
+ . $description
671
+ ;
672
+
673
+ return $output;
674
+ }
675
+
676
+ /**
677
+ * Return a wrapped question mark.
678
+ *
679
+ * @since 2.6.0
680
+ *
681
+ * @param string $description The descriptive on-hover title.
682
+ * @param string $link The non-escaped link.
683
+ * @param bool $echo Whether to echo or return.
684
+ *
685
+ * @return HTML checkbox output.
686
+ */
687
+ public function make_info( $description = '', $link = '', $echo = true ) {
688
+
689
+ if ( $link )
690
+ $output = '<a href="' . esc_url( $link ) . '" target="_blank" title="' . esc_attr( $description ) . '">[?]</a>';
691
+ else
692
+ $output = '<span title="' . esc_attr( $description ) . '">[?]</span>';
693
+
694
+ if ( $echo )
695
+ echo $output;
696
+ else
697
+ return $output;
698
+ }
699
+
700
+ /**
701
+ * Load script and stylesheet assets via metabox_scripts() methods.
702
+ *
703
+ * @since 2.2.2
704
+ */
705
+ public function load_assets() {
706
+ //* Hook scripts method
707
+ add_action( "load-{$this->pagehook}", array( $this, 'metabox_scripts' ) );
708
+ }
709
+
710
+ /**
711
+ * Include the necessary sortable metabox scripts.
712
+ *
713
+ * @since 2.2.2
714
+ */
715
+ public function metabox_scripts() {
716
+ wp_enqueue_script( 'common' );
717
+ wp_enqueue_script( 'wp-lists' );
718
+ wp_enqueue_script( 'postbox' );
719
+ }
720
+
721
+ /**
722
+ * Returns the HTML class wrap for default Checkbox options.
723
+ *
724
+ * This function does nothing special. But is merely a simple wrapper.
725
+ * Just like code_wrap.
726
+ *
727
+ * @param string $key required The option name which returns boolean.
728
+ * @param string $setting optional The settings field
729
+ * @param bool $wrap optional output class="" or just the class name.
730
+ * @param bool $echo optional echo or return the output.
731
+ *
732
+ * @since 2.2.5
733
+ */
734
+ public function is_default_checked( $key, $setting = '', $wrap = true, $echo = true ) {
735
+
736
+ $class = '';
737
+
738
+ $default = $this->get_default_settings( $key, $setting );
739
+
740
+ if ( 1 === $default )
741
+ $class = 'seoframework-default-selected';
742
+
743
+ if ( $echo ) {
744
+ if ( $wrap )
745
+ printf( 'class="%s"', $class );
746
+ else
747
+ echo $class;
748
+ } else {
749
+ if ( $wrap )
750
+ return sprintf( 'class="%s"', $class );
751
+
752
+ return $class;
753
+ }
754
+ }
755
+
756
+ /**
757
+ * Returns the HTML class wrap for warning Checkbox options.
758
+ *
759
+ * This function does nothing special. But is merely a simple wrapper.
760
+ * Just like code_wrap.
761
+ *
762
+ * @param string $key required The option name which returns boolean.
763
+ * @param string $setting optional The settings field
764
+ * @param bool $wrap optional output class="" or just the class name.
765
+ * @param bool $echo optional echo or return the output.
766
+ *
767
+ * @since 2.3.4
768
+ *
769
+ * @return string Empty on echo or The class with an optional wrapper.
770
+ */
771
+ public function is_warning_checked( $key, $setting = '', $wrap = true, $echo = true ) {
772
+
773
+ $class = '';
774
+
775
+ $warned = $this->get_warned_settings( $key, $setting );
776
+
777
+ if ( 1 === $warned )
778
+ $class = 'seoframework-warning-selected';
779
+
780
+ if ( $echo ) {
781
+ if ( $wrap ) {
782
+ printf( 'class="%s"', $class );
783
+ } else {
784
+ echo $class;
785
+ }
786
+ } else {
787
+ if ( $wrap )
788
+ return sprintf( 'class="%s"', $class );
789
+
790
+ return $class;
791
+ }
792
+ }
793
+
794
+ /**
795
+ * Helper function that constructs id attributes for use in form fields.
796
+ *
797
+ * @since 2.6.0
798
+ *
799
+ * @param string $key The option name which returns boolean.
800
+ */
801
+ public function get_is_conditional_checked( $key ) {
802
+ return $this->is_conditional_checked( $key, $this->settings_field, true, false );
803
+ }
804
+
805
+ /**
806
+ * Returns the HTML class wrap for warning/default Checkbox options.
807
+ *
808
+ * This function does nothing special. But is merely a simple wrapper.
809
+ * Just like code_wrap.
810
+ *
811
+ * @param string $key required The option name which returns boolean.
812
+ * @param string $setting optional The settings field
813
+ * @param bool $wrap optional output class="" or just the class name.
814
+ * @param bool $echo optional echo or return the output.
815
+ *
816
+ * @since 2.3.4
817
+ *
818
+ * @return string Empty on echo or The class with an optional wrapper.
819
+ */
820
+ public function is_conditional_checked( $key, $setting = '', $wrap = true, $echo = true ) {
821
+
822
+ $class = '';
823
+
824
+ $default = $this->is_default_checked( $key, $setting, false, false );
825
+ $warned = $this->is_warning_checked( $key, $setting, false, false );
826
+
827
+ if ( '' !== $default && '' !== $warned ) {
828
+ $class = $default . ' ' . $warned;
829
+ } else if ( '' !== $default ) {
830
+ $class = $default;
831
+ } else if ( '' !== $warned ) {
832
+ $class = $warned;
833
+ }
834
+
835
+ if ( $echo ) {
836
+ if ( $wrap ) {
837
+ printf( 'class="%s"', $class );
838
+ } else {
839
+ echo $class;
840
+ }
841
+ } else {
842
+ if ( $wrap ) {
843
+ return sprintf( 'class="%s"', $class );
844
+ } else {
845
+ return $class;
846
+ }
847
+ }
848
+ }
849
+
850
+ /**
851
+ * Returns the HTML class wrap for default radio options.
852
+ *
853
+ * @param string $key required The option name which returns boolean.
854
+ * @param string $value required The option value which returns boolean.
855
+ * @param string $setting optional The settings field
856
+ * @param bool $wrap optional output class="" or just the class name.
857
+ * @param bool $echo optional echo or return the output.
858
+ *
859
+ * @since 2.2.5
860
+ *
861
+ * @TODO use this
862
+ * @priority low 2.8.0+
863
+ *
864
+ * @return string|null the default selected class.
865
+ */
866
+ public function is_default_radio( $key, $value, $setting = '', $wrap = true, $echo = true ) {
867
+
868
+ $class = '';
869
+
870
+ $default = $this->get_default_settings( $key, $setting );
871
+
872
+ if ( $value === $default )
873
+ $class = 'seoframework-default-selected';
874
+
875
+ if ( $echo ) {
876
+ if ( $wrap ) {
877
+ echo sprintf( 'class="%s"', $class );
878
+ } else {
879
+ echo $class;
880
+ }
881
+ } else {
882
+ if ( $wrap )
883
+ return sprintf( 'class="%s"', $class );
884
+
885
+ return $class;
886
+ }
887
+ }
888
+
889
+ }
inc/classes/compat.class.php ADDED
@@ -0,0 +1,100 @@
1
+ <?php
2
+ /**
3
+ * The SEO Framework plugin
4
+ * Copyright (C) 2015 - 2016 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License version 3 as published
8
+ * by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ /**
20
+ * Class AutoDescription_Compat
21
+ *
22
+ * Adds theme/plugin compatibility.
23
+ *
24
+ * @since 2.6.0
25
+ */
26
+ class AutoDescription_Compat extends AutoDescription_Debug {
27
+
28
+ /**
29
+ * Constructor, load parent constructor
30
+ */
31
+ public function __construct() {
32
+ parent::__construct();
33
+
34
+ //* Genesis compat.
35
+ add_action( 'init', array( $this, 'genesis_compat' ) );
36
+ add_filter( 'genesis_detect_seo_plugins', array( $this, 'no_more_genesis_seo' ), 10 );
37
+
38
+ //* Headway compat.
39
+ add_filter( 'headway_seo_disabled', '__return_true' );
40
+
41
+ //* Jetpack compat.
42
+ add_action( 'init', array( $this, 'jetpack_compat' ) );
43
+
44
+ }
45
+
46
+ /**
47
+ * Adds Genesis SEO compatibility.
48
+ *
49
+ * @since 2.6.0
50
+ */
51
+ public function genesis_compat() {
52
+
53
+ //* Nothing to do on admin.
54
+ if ( $this->is_admin() )
55
+ return;
56
+
57
+ //* Reverse the removal of head attributes, this shouldn't affect SEO.
58
+ remove_filter( 'genesis_attr_head', 'genesis_attributes_empty_class' );
59
+ add_filter( 'genesis_attr_head', 'genesis_attributes_head' );
60
+
61
+ }
62
+
63
+ /**
64
+ * Removes the Genesis SEO meta boxes on the SEO Settings page
65
+ *
66
+ * @since 2.2.4
67
+ *
68
+ * @param array $plugins, overwritten as this filter will fire the
69
+ * detection, regardless of other SEO plugins.
70
+ * @return array Plugins to detect.
71
+ */
72
+ public function no_more_genesis_seo( $plugins ) {
73
+
74
+ $plugins = array(
75
+ 'classes' => array(
76
+ 'The_SEO_Framework_Load',
77
+ ),
78
+ 'functions' => array(),
79
+ 'constants' => array(),
80
+ );
81
+
82
+ return $plugins;
83
+ }
84
+
85
+ /**
86
+ * Adds compatibility with various JetPack modules.
87
+ *
88
+ * @since 2.6.0
89
+ */
90
+ public function jetpack_compat() {
91
+
92
+ if ( $this->use_og_tags() ) {
93
+ //* Disable Jetpack Publicize's Open Graph.
94
+ add_filter( 'jetpack_enable_open_graph', '__return_false', 99 );
95
+ }
96
+
97
+ }
98
+
99
+
100
+ }
inc/classes/core.class.php ADDED
@@ -0,0 +1,568 @@
1
+ <?php
2
+ /**
3
+ * The SEO Framework plugin
4
+ * Copyright (C) 2015 - 2016 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License version 3 as published
8
+ * by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ /**
20
+ * Class AutoDescription_Core
21
+ *
22
+ * Initializes the plugin & Holds plugin core functions.
23
+ *
24
+ * @since 2.6.0
25
+ */
26
+ class AutoDescription_Core {
27
+
28
+ /**
29
+ * Constructor. Loads actions and filters.
30
+ * Latest Class. Doesn't have parent.
31
+ */
32
+ public function __construct() {
33
+
34
+ add_action( 'current_screen', array( $this, 'post_type_support' ), 0 );
35
+
36
+ /**
37
+ * Add plugin links to the plugin activation page.
38
+ * @since 2.2.8
39
+ */
40
+ add_filter( 'plugin_action_links_' . THE_SEO_FRAMEWORK_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ), 10, 2 );
41
+
42
+ }
43
+
44
+ /**
45
+ * Proportionate dimensions based on Width and Height.
46
+ * AKA Aspect Ratio.
47
+ *
48
+ * @param int $i The dimension to resize.
49
+ * @param int $r1 The deminsion that determines the ratio.
50
+ * @param int $r2 The dimension to proportionate to.
51
+ *
52
+ * @since 2.6.0
53
+ *
54
+ * @return int The proportional dimension, rounded.
55
+ */
56
+ public function proportionate_dimensions( $i, $r1, $r2 ) {
57
+
58
+ //* Get aspect ratio.
59
+ $ar = $r1 / $r2;
60
+
61
+ $i = $i / $ar;
62
+ return round( $i );
63
+ }
64
+
65
+ /**
66
+ * Adds post type support
67
+ *
68
+ * Applies filters the_seo_framework_supported_post_types : The supported post types.
69
+ * @since 2.3.1
70
+ *
71
+ * @since 2.1.6
72
+ */
73
+ public function post_type_support() {
74
+
75
+ /**
76
+ * Added product post type.
77
+ *
78
+ * @since 2.3.1
79
+ */
80
+ $defaults = array(
81
+ 'post', 'page',
82
+ 'product',
83
+ 'forum', 'topic',
84
+ 'jetpack-testimonial', 'jetpack-portfolio',
85
+ );
86
+
87
+ $post_types = (array) apply_filters( 'the_seo_framework_supported_post_types', $defaults );
88
+
89
+ $types = wp_parse_args( $defaults, $post_types );
90
+
91
+ foreach ( $types as $type )
92
+ add_post_type_support( $type, array( 'autodescription-meta' ) );
93
+
94
+ }
95
+
96
+ /**
97
+ * Adds link from plugins page to SEO Settings page.
98
+ *
99
+ * @param array $links The current links.
100
+ *
101
+ * @since 2.2.8
102
+ */
103
+ public function plugin_action_links( $links = array() ) {
104
+
105
+ $framework_links = array();
106
+
107
+ if ( $this->load_options )
108
+ $framework_links['settings'] = '<a href="' . esc_url( admin_url( 'admin.php?page=' . $this->page_id ) ) . '">' . __( 'SEO Settings', 'autodescription' ) . '</a>';
109
+
110
+ $framework_links['home'] = '<a href="'. esc_url( 'https://theseoframework.com/' ) . '" target="_blank">' . _x( 'Plugin Home', 'As in: The Plugin Home Page', 'autodescription' ) . '</a>';
111
+
112
+ return array_merge( $framework_links, $links );
113
+ }
114
+
115
+ /**
116
+ * Returns the front page ID, if home is a page.
117
+ *
118
+ * @since 2.6.0
119
+ *
120
+ * @return int the ID.
121
+ */
122
+ public function get_the_front_page_ID() {
123
+
124
+ static $front_id = null;
125
+
126
+ if ( isset( $front_id ) )
127
+ return $front_id;
128
+
129
+ return $front_id = $this->has_page_on_front() ? (int) get_option( 'page_on_front' ) : 0;
130
+ }
131
+
132
+ /**
133
+ * Generate dismissible notice.
134
+ *
135
+ * @param $message The notice message.
136
+ * @param $type The notice type : 'updated', 'error', 'warning'
137
+ *
138
+ * @since 2.6.0
139
+ */
140
+ public function generate_dismissible_notice( $message = '', $type = 'updated' ) {
141
+
142
+ if ( empty( $message ) )
143
+ return '';
144
+
145
+ if ( 'warning' === $type )
146
+ $type = 'notice-warning';
147
+
148
+ $notice = '<div class="notice ' . $type . ' seo-notice"><p>';
149
+ $notice .= '<a class="hide-if-no-js autodescription-dismiss" title="' . __( 'Dismiss', 'AutoDescription' ) . '"></a>';
150
+ $notice .= '<strong>' . $message . '</strong>';
151
+ $notice .= '</p></div>';
152
+
153
+ return $notice;
154
+ }
155
+
156
+ /**
157
+ * Mark up content with code tags.
158
+ *
159
+ * Escapes all HTML, so `<` gets changed to `&lt;` and displays correctly.
160
+ *
161
+ * @since 2.0.0
162
+ *
163
+ * @param string $content Content to be wrapped in code tags.
164
+ *
165
+ * @return string Content wrapped in code tags.
166
+ */
167
+ public function code_wrap( $content ) {
168
+ return '<code>' . esc_html( $content ) . '</code>';
169
+ }
170
+
171
+ /**
172
+ * Mark up content with code tags.
173
+ *
174
+ * Escapes no HTML.
175
+ *
176
+ * @since 2.2.2
177
+ *
178
+ * @param string $content Content to be wrapped in code tags.
179
+ *
180
+ * @return string Content wrapped in code tags.
181
+ */
182
+ public function code_wrap_noesc( $content ) {
183
+ return '<code>' . $content . '</code>';
184
+ }
185
+
186
+ /**
187
+ * Return custom field post meta data.
188
+ *
189
+ * Return only the first value of custom field. Return false if field is
190
+ * blank or not set.
191
+ *
192
+ * @since 2.0.0
193
+ *
194
+ * @param string $field Custom field key.
195
+ * @param int $post_id The post ID
196
+ *
197
+ * @return string|boolean Return value or false on failure.
198
+ *
199
+ * @thanks StudioPress (http://www.studiopress.com/) for some code.
200
+ *
201
+ * @staticvar array $field_cache
202
+ * @since 2.2.5
203
+ */
204
+ public function get_custom_field( $field, $post_id = null ) {
205
+
206
+ //* No field has been provided.
207
+ if ( empty( $field ) )
208
+ return false;
209
+
210
+ //* Setup cache.
211
+ static $field_cache = array();
212
+
213
+ //* Check field cache.
214
+ if ( isset( $field_cache[$field][$post_id] ) )
215
+ //* Field has been cached.
216
+ return $field_cache[$field][$post_id];
217
+
218
+ if ( null === $post_id || empty( $post_id ) )
219
+ $post_id = $this->get_the_real_ID();
220
+
221
+ if ( null === $post_id || empty( $post_id ) )
222
+ return '';
223
+
224
+ $custom_field = get_post_meta( $post_id, $field, true );
225
+
226
+ //