All in One SEO Pack - Version 2.11

Version Description

Download this release

Release Info

Developer hallsofmontezuma
Plugin Icon 128x128 All in One SEO Pack
Version 2.11
Comparing to
See all releases

Code changes from version 2.10.1 to 2.11

aioseop_class.php CHANGED
@@ -3704,6 +3704,7 @@ class All_in_One_SEO_Pack extends All_in_One_SEO_Pack_Module {
3704
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_styles_all' ) );
3705
  add_action( 'admin_init', 'aioseop_addmycolumns', 1 );
3706
  add_action( 'admin_init', 'aioseop_handle_ignore_notice' );
 
3707
  if ( AIOSEOPPRO ) {
3708
  if ( current_user_can( 'update_plugins' ) ) {
3709
  add_action( 'admin_notices', array( $aioseop_update_checker, 'key_warning' ) );
@@ -4860,7 +4861,6 @@ EOF;
4860
  }
4861
 
4862
  function admin_menu() {
4863
- $this->check_recently_activated_modules( $_POST );
4864
  $file = plugin_basename( __FILE__ );
4865
  $menu_name = __( 'All in One SEO', 'all-in-one-seo-pack' );
4866
 
@@ -5029,32 +5029,6 @@ EOF;
5029
  }
5030
  }
5031
 
5032
- /**
5033
- * Checks which module(s) have been (de)activated just now and fires a corresponding action.
5034
- *
5035
- * @param array $post Duplicate of $_POST.
5036
- */
5037
- private function check_recently_activated_modules( $post ) {
5038
- global $aioseop_options;
5039
- $modules = array();
5040
- if ( array_key_exists( 'modules', $aioseop_options ) && array_key_exists( 'aiosp_feature_manager_options', $aioseop_options['modules'] ) ) {
5041
- $modules = array_keys( $aioseop_options['modules']['aiosp_feature_manager_options'] );
5042
- }
5043
-
5044
- if ( $modules ) {
5045
- foreach ( $modules as $module ) {
5046
- $name = str_replace( 'aiosp_feature_manager_enable_', '', $module );
5047
- if ( empty( $aioseop_options['modules']['aiosp_feature_manager_options'][ $module ] ) && ! empty( $post[ $module ] ) ) {
5048
- // this module was activated.
5049
- do_action( $this->prefix . 'activate_' . $name );
5050
- } else if ( ! empty( $aioseop_options['modules']['aiosp_feature_manager_options'][ $module ] ) && ! isset( $post[ $module ] ) ) {
5051
- // this module was deactivated. This action should be registered NOT in the specific module but elsewhere because that module is not going to be loaded.
5052
- do_action( $this->prefix . 'deactivate_' . $name );
5053
- }
5054
- }
5055
- }
5056
- }
5057
-
5058
  /**
5059
  * @param $menu_order
5060
  *
@@ -5261,4 +5235,41 @@ EOF;
5261
  <?php
5262
  }
5263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5264
  }
3704
  add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_styles_all' ) );
3705
  add_action( 'admin_init', 'aioseop_addmycolumns', 1 );
3706
  add_action( 'admin_init', 'aioseop_handle_ignore_notice' );
3707
+ add_action( 'shutdown', array( $this, 'check_recently_activated_modules' ), 99 );
3708
  if ( AIOSEOPPRO ) {
3709
  if ( current_user_can( 'update_plugins' ) ) {
3710
  add_action( 'admin_notices', array( $aioseop_update_checker, 'key_warning' ) );
4861
  }
4862
 
4863
  function admin_menu() {
 
4864
  $file = plugin_basename( __FILE__ );
4865
  $menu_name = __( 'All in One SEO', 'all-in-one-seo-pack' );
4866
 
5029
  }
5030
  }
5031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5032
  /**
5033
  * @param $menu_order
5034
  *
5235
  <?php
5236
  }
5237
 
5238
+ /**
5239
+ * Checks which module(s) have been (de)activated just now and fires a corresponding action.
5240
+ */
5241
+ function check_recently_activated_modules() {
5242
+ global $aioseop_options;
5243
+ $options = get_option( 'aioseop_options' );
5244
+ $modules_before = array();
5245
+ $modules_now = array();
5246
+ if ( array_key_exists( 'modules', $aioseop_options ) && array_key_exists( 'aiosp_feature_manager_options', $aioseop_options['modules'] ) ) {
5247
+ foreach( $aioseop_options['modules']['aiosp_feature_manager_options'] as $module => $state ) {
5248
+ if ( ! empty( $state ) ) {
5249
+ $modules_before[] = $module;
5250
+ }
5251
+ }
5252
+ }
5253
+ if ( array_key_exists( 'modules', $options ) && array_key_exists( 'aiosp_feature_manager_options', $options['modules'] ) ) {
5254
+ foreach( $options['modules']['aiosp_feature_manager_options'] as $module => $state ) {
5255
+ if ( ! empty( $state ) ) {
5256
+ $modules_now[] = $module;
5257
+ }
5258
+ }
5259
+ }
5260
+
5261
+ $action = 'deactivate';
5262
+ $diff = array_diff( $modules_before, $modules_now );
5263
+ if ( count( $modules_now ) > count( $modules_before ) ) {
5264
+ $action = 'activate';
5265
+ $diff = array_diff( $modules_now, $modules_before );
5266
+ }
5267
+
5268
+ if ( $diff ) {
5269
+ foreach ( $diff as $module ) {
5270
+ $name = str_replace( 'aiosp_feature_manager_enable_', '', $module );
5271
+ do_action( $this->prefix . $action . '_' . $name );
5272
+ }
5273
+ }
5274
+ }
5275
  }
all_in_one_seo_pack.php CHANGED
@@ -4,7 +4,7 @@
4
  Plugin Name: All In One SEO Pack
5
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
6
  Description: Out-of-the-box SEO for your WordPress blog. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.
7
- Version: 2.10.1
8
  Author: Michael Torbert
9
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
10
  Text Domain: all-in-one-seo-pack
@@ -12,7 +12,7 @@ Domain Path: /i18n/
12
  */
13
 
14
  /*
15
- Copyright (C) 2007-2018 Michael Torbert, https://semperfiwebdesign.com
16
 
17
  This program is free software; you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License as published by
@@ -32,14 +32,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
32
  * The original WordPress SEO plugin.
33
  *
34
  * @package All-in-One-SEO-Pack
35
- * @version 2.10.1
36
  */
37
 
38
  if ( ! defined( 'AIOSEOPPRO' ) ) {
39
  define( 'AIOSEOPPRO', false );
40
  }
41
  if ( ! defined( 'AIOSEOP_VERSION' ) ) {
42
- define( 'AIOSEOP_VERSION', '2.10.1' );
43
  }
44
  global $aioseop_plugin_name;
45
  $aioseop_plugin_name = 'All in One SEO Pack';
4
  Plugin Name: All In One SEO Pack
5
  Plugin URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
6
  Description: Out-of-the-box SEO for your WordPress blog. Features like XML Sitemaps, SEO for custom post types, SEO for blogs or business sites, SEO for ecommerce sites, and much more. More than 50 million downloads since 2007.
7
+ Version: 2.11
8
  Author: Michael Torbert
9
  Author URI: https://semperplugins.com/all-in-one-seo-pack-pro-version/
10
  Text Domain: all-in-one-seo-pack
12
  */
13
 
14
  /*
15
+ Copyright (C) 2007-2019 Michael Torbert, https://semperfiwebdesign.com
16
 
17
  This program is free software; you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License as published by
32
  * The original WordPress SEO plugin.
33
  *
34
  * @package All-in-One-SEO-Pack
35
+ * @version 2.11
36
  */
37
 
38
  if ( ! defined( 'AIOSEOPPRO' ) ) {
39
  define( 'AIOSEOPPRO', false );
40
  }
41
  if ( ! defined( 'AIOSEOP_VERSION' ) ) {
42
+ define( 'AIOSEOP_VERSION', '2.11' );
43
  }
44
  global $aioseop_plugin_name;
45
  $aioseop_plugin_name = 'All in One SEO Pack';
css/modules/aioseop_module.css CHANGED
@@ -118,9 +118,7 @@ div.aioseop_tip_icon:before {
118
  .aioseop_meta_box_help,
119
  .aioseop_meta_box_help:active {
120
  float: right;
121
- padding-left: 0;
122
- width: 16px;
123
- margin-right: 32px;
124
  text-decoration: none;
125
  height: 15px;
126
  padding-top: 1px;
118
  .aioseop_meta_box_help,
119
  .aioseop_meta_box_help:active {
120
  float: right;
121
+ text-align: right;
 
 
122
  text-decoration: none;
123
  height: 15px;
124
  padding-top: 1px;
inc/aiosp_common.php CHANGED
@@ -14,6 +14,13 @@
14
  class aiosp_common {
15
  // @codingStandardsIgnoreEnd
16
 
 
 
 
 
 
 
 
17
  /**
18
  * aiosp_common constructor.
19
  *
@@ -174,12 +181,278 @@ class aiosp_common {
174
  * Renders the value XML safe.
175
  */
176
  public static function make_xml_safe( $tag, $value ) {
177
- if ( in_array( $tag, array( 'guid', 'link', 'loc', 'image:loc' ) ) ) {
 
 
 
 
 
 
178
  $value = esc_url( $value );
179
- } else if( ! is_array( $value ) ) {
180
- $value = htmlspecialchars( $value, ENT_QUOTES );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
182
- return $value;
183
  }
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }
14
  class aiosp_common {
15
  // @codingStandardsIgnoreEnd
16
 
17
+ /**
18
+ * @var null|array
19
+ *
20
+ * @since 2.9.2
21
+ */
22
+ public static $attachment_url_postids = null;
23
+
24
  /**
25
  * aiosp_common constructor.
26
  *
181
  * Renders the value XML safe.
182
  */
183
  public static function make_xml_safe( $tag, $value ) {
184
+ // some tags contain an array of values.
185
+ if ( is_array( $value ) ) {
186
+ return $value;
187
+ }
188
+
189
+ // sanitize the other tags.
190
+ if ( in_array( $tag, array( 'guid', 'link', 'loc', 'image:loc' ), true ) ) {
191
  $value = esc_url( $value );
192
+ } else {
193
+ // some tags contain sanitized to some extent but they do not encode < and >.
194
+ if ( ! in_array( $tag, array( 'image:title' ), true ) ) {
195
+ // use the WP core functions if they exist.
196
+ if ( function_exists( 'convert_chars' ) && function_exists( 'wptexturize' ) ) {
197
+ $value = convert_chars( wptexturize( $value ) );
198
+ } else {
199
+ $value = htmlspecialchars( $value, ENT_QUOTES );
200
+ }
201
+ }
202
+ }
203
+ return esc_html( $value );
204
+ }
205
+
206
+ /**
207
+ * Attachment URL to Post ID
208
+ *
209
+ * Returns the (original) post/attachment ID from the URL param given. The function checks if URL is
210
+ * within, chacks for original attachment URLs, and then custom attachment URLs. The main intent for this function
211
+ * is to avoid having to query if possible (if cache was set prior), and if not, there is only 1 query per instance
212
+ * rather than multiple queries per instance.
213
+ * NOTE: Attempting to paginate the query actually caused the memory to peak higher.
214
+ * NOTE: The weakest point in this function is multiple calls to Result_2's SQL query for custom attachment URLs.
215
+ *
216
+ * This is intended to work much the same way as WP's `attachment_url_to_postid()`.
217
+ *
218
+ * @link https://developer.wordpress.org/reference/functions/attachment_url_to_postid/
219
+ *
220
+ * @see aiosp_common::set_transient_url_postids()
221
+ * @see get_transient()
222
+ * @link https://developer.wordpress.org/reference/functions/get_transient/
223
+ * @see wpdb::get_results()
224
+ * @link https://developer.wordpress.org/reference/classes/wpdb/get_results/
225
+ * @see wp_list_pluck()
226
+ * @link https://developer.wordpress.org/reference/functions/wp_list_pluck/
227
+ * @see wp_upload_dir()
228
+ * @link https://developer.wordpress.org/reference/functions/wp_upload_dir/
229
+ *
230
+ * @since 2.9.2
231
+ *
232
+ * @param string $url Full image URL.
233
+ * @return int
234
+ */
235
+ public static function attachment_url_to_postid( $url ) {
236
+ global $wpdb;
237
+ static $results_1;
238
+ static $results_2;
239
+
240
+ $id = 0;
241
+ $url_md5 = md5( $url );
242
+
243
+ // Gets the URL => PostIDs array.
244
+ // If static variable is still empty, load transient data.
245
+ if ( is_null( self::$attachment_url_postids ) ) {
246
+ if ( is_multisite() ) {
247
+ self::$attachment_url_postids = get_site_transient( 'aioseop_multisite_attachment_url_postids' );
248
+ } else {
249
+ self::$attachment_url_postids = get_transient( 'aioseop_attachment_url_postids' );
250
+ }
251
+
252
+ // If no transient data, set as (default) empty array.
253
+ if ( false === self::$attachment_url_postids ) {
254
+ self::$attachment_url_postids = array();
255
+ }
256
+ }
257
+
258
+ // Search for URL and get ID.
259
+ if ( isset( self::$attachment_url_postids[ $url_md5 ] ) ) {
260
+ // If static is already loaded and has URL, then return the URL's Post ID.
261
+ $id = intval( self::$attachment_url_postids[ $url_md5 ] );
262
+ } else {
263
+ // Check to make sure Image URL is not outside the website.
264
+ $uploads_dir = wp_upload_dir();
265
+ if ( false !== strpos( $url, $uploads_dir['baseurl'] . '/' ) ) {
266
+ // Results_1 query looks for URLs with the original guid that is uncropped and unedited.
267
+ if ( is_null( $results_1 ) ) {
268
+ $results_1 = aiosp_common::attachment_url_to_postid_query_1();
269
+ }
270
+
271
+ if ( isset( $results_1[ $url_md5 ] ) ) {
272
+ $id = intval( $results_1[ $url_md5 ] );
273
+ }
274
+
275
+ // TODO Add setting to enable; this is TOO MEMORY INTENSE which could result in 1 or more crashes,
276
+ // TODO however some may still need custom image URLs.
277
+ // TODO NOTE: Transient data does prevent continual crashes.
278
+ // else {
279
+ // // Results_2 query looks for the URL that is cropped and edited. This searches JSON strings
280
+ // // and returns the original attachment ID (there is no custom attachment IDs).
281
+ //
282
+ // if ( is_null( $results_2 ) ) {
283
+ // $results_2 = aiosp_common::attachment_url_to_postid_query_2();
284
+ // }
285
+ //
286
+ // if ( isset( $results_2[ $url_md5 ] ) ) {
287
+ // $id = intval( $results_2[ $url_md5 ] );
288
+ // }
289
+ // }
290
+ }
291
+
292
+ self::$attachment_url_postids[ $url_md5 ] = $id;
293
+
294
+ /**
295
+ * Sets the transient data at the last hook instead at every call.
296
+ *
297
+ * @see aiosp_common::set_transient_url_postids()
298
+ */
299
+ add_action( 'shutdown', array( 'aiosp_common', 'set_transient_url_postids' ) );
300
+ }
301
+
302
+ return $id;
303
+ }
304
+
305
+ /**
306
+ * Sets the transient data at the last hook instead at every call.
307
+ *
308
+ * @see set_transient()
309
+ * @link https://developer.wordpress.org/reference/functions/set_transient/
310
+ *
311
+ * @since 2.9.2
312
+ */
313
+ public static function set_transient_url_postids() {
314
+ if ( is_multisite() ) {
315
+ set_site_transient( 'aioseop_multisite_attachment_url_postids', self::$attachment_url_postids, 24 * HOUR_IN_SECONDS );
316
+ } else {
317
+ set_transient( 'aioseop_attachment_url_postids', self::$attachment_url_postids, 24 * HOUR_IN_SECONDS );
318
  }
319
+
320
  }
321
 
322
+ /**
323
+ * Attachment URL to Post ID - Query 1
324
+ *
325
+ * This is intended to work solely with `aiosp_common::attachment_url_to_post_id()`. Calling this multiple times
326
+ * is memory intense.
327
+ *
328
+ * @see wpdb::get_results()
329
+ * @link https://developer.wordpress.org/reference/classes/wpdb/get_results/
330
+ *
331
+ * @return array
332
+ */
333
+ public static function attachment_url_to_postid_query_1() {
334
+ global $wpdb;
335
+
336
+ $results_1 = $wpdb->get_results(
337
+ "SELECT ID, MD5(guid) AS guid FROM $wpdb->posts WHERE post_type='attachment' AND post_status='inherit' AND post_mime_type LIKE 'image/%';",
338
+ ARRAY_A
339
+ );
340
+
341
+ if ( $results_1 ) {
342
+ $results_1 = array_combine(
343
+ wp_list_pluck( $results_1, 'guid' ),
344
+ wp_list_pluck( $results_1, 'ID' )
345
+ );
346
+ } else {
347
+ $results_1 = array();
348
+ }
349
+
350
+ return $results_1;
351
+ }
352
+
353
+ /**
354
+ * Attachment URL to Post ID - Query 2
355
+ *
356
+ * Unused/Conceptual function. This is intended to work solely with `aiosp_common::attachment_url_to_post_id()`.
357
+ * Calling this multiple times is memory intense. It's intended to query for custom images, and data for those types
358
+ * of images only exists in the postmeta database table
359
+ *
360
+ * @todo Investigate unserialize() memory consumption/leak.
361
+ * @link https://www.evonide.com/breaking-phps-garbage-collection-and-unserialize/
362
+ *
363
+ * @see aiosp_common::attachment_url_to_postid()
364
+ * @see unserialize()
365
+ * @link http://php.net/manual/en/function.unserialize.php
366
+ * @see wpdb::get_results()
367
+ * @link https://developer.wordpress.org/reference/classes/wpdb/get_results/
368
+ * @see wp_upload_dir()
369
+ * @link https://developer.wordpress.org/reference/functions/wp_upload_dir/
370
+ *
371
+ * @return array
372
+ */
373
+ public static function attachment_url_to_postid_query_2() {
374
+ global $wpdb;
375
+
376
+ $tmp_arr = array();
377
+ $results_2 = $wpdb->get_results(
378
+ "SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE `meta_key` = '_wp_attachment_metadata' AND `meta_value` != '" . serialize( array() ) . "';",
379
+ ARRAY_A
380
+ );
381
+ if ( $results_2 ) {
382
+ for ( $i = 0; $i < count( $results_2 ); $i++ ) {
383
+ // TODO Investigate potentual memory leak(s); currently with unserialize.
384
+ $meta_value = maybe_unserialize( $results_2[ $i ]['meta_value'] );
385
+
386
+ // TODO Needs Discussion: Should this be added? To handle errors better instead of suspecting aioseop is at fault and lessen support threads.
387
+ /**
388
+ * This currently handles "warning" notices with unserialize which normally can't be handled with a try/catch.
389
+ * However, this notice should be identified and corrected; which is seperate from the plugin, but
390
+ * can also triggered by the plugin.
391
+ *
392
+ * @see aiosp_common::error_handle_images()
393
+ * @see set_error_handler()
394
+ * @link http://php.net/manual/en/function.set-error-handler.php
395
+ * @see restore_error_handler()
396
+ * @link http://php.net/manual/en/function.restore-error-handler.php
397
+ */
398
+ /*
399
+ set_error_handler( 'aiosp_common::error_handle_images' );
400
+ try {
401
+ $meta_value = unserialize( $results_2[ $i ]['meta_value'] );
402
+ } catch ( Exception $e ) {
403
+ unset( $meta_value );
404
+ restore_error_handler();
405
+ continue;
406
+ }
407
+ restore_error_handler();
408
+ */
409
+
410
+ // Images and Videos use different variable structures.
411
+ if ( false === $meta_value || ! isset( $meta_value['file'] ) && ! isset( $meta_value['sizes'] ) ) {
412
+ continue;
413
+ }
414
+
415
+ // Set the URL => PostIDs.
416
+ $uploads_dir = wp_upload_dir();
417
+ $custom_img_base_url = $uploads_dir['baseurl'] . '/' . str_replace( wp_basename( $meta_value['file'] ), '', $meta_value['file'] );
418
+ foreach ( $meta_value['sizes'] as $image_size_arr ) {
419
+ $tmp_arr[ md5( ( $custom_img_base_url . $image_size_arr['file'] ) ) ] = $results_2[ $i ]['post_id'];
420
+ }
421
+
422
+ unset( $meta_value );
423
+ }
424
+ }
425
+
426
+ $results_2 = $tmp_arr;
427
+ unset( $tmp_arr );
428
+
429
+ return $results_2;
430
+ }
431
+
432
+ /**
433
+ * Error Hand Images
434
+ *
435
+ * Unused/Conceptual function potentually used in `aiosp_common::attachment_url_to_post_id_query_2()`.
436
+ * This is to handle errors where a normal try/catch wouldn't have the exception needed to catch.
437
+ *
438
+ * @see aiosp_common::attachment_url_to_post_id_query_2()
439
+ *
440
+ * @param $errno
441
+ * @param $errstr
442
+ * @param $errfile
443
+ * @param $errline
444
+ * @return bool
445
+ * @throws ErrorException
446
+ */
447
+ public static function error_handle_images( $errno, $errstr, $errfile, $errline ) {
448
+ // Possibly handle known issues differently.
449
+ // Handles unserialize() warning notice.
450
+ if ( 8 === $errno || strpos( $errstr , 'unserialize():' ) ) {
451
+ throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );
452
+ } else {
453
+ throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );
454
+ }
455
+
456
+ return false;
457
+ }
458
  }
modules/aioseop_opengraph.php CHANGED
@@ -1,1755 +1,1884 @@
1
- <?php
2
- /**
3
- * The Opengraph class.
4
- *
5
- * @package All-in-One-SEO-Pack
6
- * @version 2.3.16
7
- */
8
- if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
9
- class All_in_One_SEO_Pack_Opengraph extends All_in_One_SEO_Pack_Module {
10
- var $fb_object_types;
11
- var $type;
12
-
13
- /**
14
- * Module constructor.
15
- *
16
- * @since 2.3.14 Added display filter.
17
- * @since 2.3.16 #1066 Force init on constructor.
18
- */
19
- function __construct() {
20
- add_action( 'admin_enqueue_scripts', array( $this, 'og_admin_enqueue_scripts' ) );
21
-
22
- $this->name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin
23
- $this->prefix = 'aiosp_opengraph_'; // option prefix
24
- $this->file = __FILE__; // the current file
25
- $this->fb_object_types = array(
26
- 'Activities' => array(
27
- 'activity' => __( 'Activity', 'all-in-one-seo-pack' ),
28
- 'sport' => __( 'Sport', 'all-in-one-seo-pack' ),
29
- ),
30
- 'Businesses' => array(
31
- 'bar' => __( 'Bar', 'all-in-one-seo-pack' ),
32
- 'company' => __( 'Company', 'all-in-one-seo-pack' ),
33
- 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ),
34
- 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ),
35
- 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ),
36
- ),
37
- 'Groups' => array(
38
- 'cause' => __( 'Cause', 'all-in-one-seo-pack' ),
39
- 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ),
40
- 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ),
41
- ),
42
- 'Organizations' => array(
43
- 'band' => __( 'Band', 'all-in-one-seo-pack' ),
44
- 'government' => __( 'Government', 'all-in-one-seo-pack' ),
45
- 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ),
46
- 'school' => __( 'School', 'all-in-one-seo-pack' ),
47
- 'university' => __( 'University', 'all-in-one-seo-pack' ),
48
- ),
49
- 'People' => array(
50
- 'actor' => __( 'Actor', 'all-in-one-seo-pack' ),
51
- 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ),
52
- 'author' => __( 'Author', 'all-in-one-seo-pack' ),
53
- 'director' => __( 'Director', 'all-in-one-seo-pack' ),
54
- 'musician' => __( 'Musician', 'all-in-one-seo-pack' ),
55
- 'politician' => __( 'Politician', 'all-in-one-seo-pack' ),
56
- 'profile' => __( 'Profile', 'all-in-one-seo-pack' ),
57
- 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ),
58
- ),
59
- 'Places' => array(
60
- 'city' => __( 'City', 'all-in-one-seo-pack' ),
61
- 'country' => __( 'Country', 'all-in-one-seo-pack' ),
62
- 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ),
63
- 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ),
64
- ),
65
- 'Products and Entertainment' => array(
66
- 'album' => __( 'Album', 'all-in-one-seo-pack' ),
67
- 'book' => __( 'Book', 'all-in-one-seo-pack' ),
68
- 'drink' => __( 'Drink', 'all-in-one-seo-pack' ),
69
- 'food' => __( 'Food', 'all-in-one-seo-pack' ),
70
- 'game' => __( 'Game', 'all-in-one-seo-pack' ),
71
- 'movie' => __( 'Movie', 'all-in-one-seo-pack' ),
72
- 'product' => __( 'Product', 'all-in-one-seo-pack' ),
73
- 'song' => __( 'Song', 'all-in-one-seo-pack' ),
74
- 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ),
75
- 'episode' => __( 'Episode', 'all-in-one-seo-pack' ),
76
- ),
77
- 'Websites' => array(
78
- 'article' => __( 'Article', 'all-in-one-seo-pack' ),
79
- 'blog' => __( 'Blog', 'all-in-one-seo-pack' ),
80
- 'website' => __( 'Website', 'all-in-one-seo-pack' ),
81
- ),
82
- );
83
- parent::__construct();
84
-
85
- $this->help_text = array(
86
- 'setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ),
87
- 'key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ),
88
- 'appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ),
89
- 'title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ),
90
- 'description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ),
91
- 'sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ),
92
- 'hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ),
93
- 'description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ),
94
- 'homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ),
95
- 'generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ),
96
- 'defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ),
97
- 'fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ),
98
- 'dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ),
99
- 'dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ),
100
- 'dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ),
101
- 'meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ),
102
- 'image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ),
103
- 'customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ),
104
- 'imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
105
- 'imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
106
- 'video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ),
107
- 'videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
108
- 'videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
109
- 'defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ),
110
- 'setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ),
111
- 'twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ),
112
- 'twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ),
113
- 'twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ),
114
- 'customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ),
115
- 'gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ),
116
- 'gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ),
117
- 'gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ),
118
- 'gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ),
119
- 'types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ),
120
- 'title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ),
121
- 'desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ),
122
- 'category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ),
123
- 'facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ),
124
- 'section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ),
125
- 'tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ),
126
- 'facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ),
127
- 'facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ),
128
- 'person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ),
129
- 'profile_links' => __( "Add URLs for your website's social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.", 'all-in-one-seo-pack' ),
130
- 'social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ),
131
- );
132
-
133
- $this->help_anchors = array(
134
- 'title_shortcodes' => '#run-shortcodes-in-title',
135
- 'description_shortcodes' => '#run-shortcodes-in-description',
136
- 'generate_descriptions' => '#auto-generate-og-descriptions',
137
- 'setmeta' => '#use-aioseo-title-and-description',
138
- 'sitename' => '#site-name',
139
- 'hometitle' => '#home-title-and-description',
140
- 'description' => '#home-title-and-description',
141
- 'homeimage' => '#home-image',
142
- 'defimg' => '#select-og-image-source',
143
- 'fallback' => '#use-default-if-no-image-found',
144
- 'dimg' => '#default-og-image',
145
- 'dimgwidth' => '#default-image-width',
146
- 'dimgheight' => '#default-image-height',
147
- 'meta_key' => '#use-custom-field-for-image',
148
- 'profile_links' => '#social-profile-links',
149
- 'person_or_org' => '#social-profile-links',
150
- 'social_name' => '#social-profile-links',
151
- 'key' => '#facebook-admin-id',
152
- 'appid' => '#facebook-app-id',
153
- 'gen_tags' => '#automatically-generate-article-tags',
154
- 'gen_keywords' => '#use-keywords-in-article-tags',
155
- 'gen_categories' => '#use-categories-in-article-tags',
156
- 'gen_post_tags' => '#use-post-tags-in-article-tags',
157
- 'facebook_publisher' => '#show-facebook-publisher-on-articles',
158
- 'facebook_author' => '#show-facebook-author-on-articles',
159
- 'types' => '#enable-facebook-meta-for',
160
- 'defcard' => '#default-twitter-card',
161
- 'twitter_site' => '#twitter-site',
162
- 'twitter_creator' => '#show-twitter-author',
163
- 'twitter_domain' => '#twitter-domain',
164
- 'scan_header' => '#scan-social-meta',
165
- 'title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title',
166
- 'desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description',
167
- 'image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image',
168
- 'customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image',
169
- 'imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height',
170
- 'imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height',
171
- 'video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video',
172
- 'videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height',
173
- 'videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height',
174
- 'category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type',
175
- 'facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug',
176
- 'section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section',
177
- 'tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags',
178
- 'setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type',
179
- 'customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image',
180
- );
181
-
182
- if ( is_admin() ) {
183
- add_action( 'admin_init', array( $this, 'admin_init' ), 5 );
184
- } else {
185
- add_action( 'wp', array( $this, 'type_setup' ) );
186
- }
187
-
188
- if ( ! is_admin() || defined( 'DOING_AJAX' ) ) {
189
- $this->do_opengraph();
190
- }
191
- // Set variables after WordPress load.
192
- add_action( 'init', array( &$this, 'init' ), 999999 );
193
- add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags
194
- // Force refresh of Facebook cache.
195
- add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 );
196
- add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 );
197
- add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 );
198
- // Adds special filters
199
- add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) );
200
- // Call to init to generate menus
201
- $this->init();
202
- }
203
-
204
- /**
205
- * Hook called after WordPress has been loaded.
206
- *
207
- * @since 2.4.14
208
- */
209
- public function init() {
210
- $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' );
211
- // Create default options
212
- $this->default_options = array(
213
- 'scan_header' => array(
214
- 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ),
215
- 'type' => 'custom',
216
- 'save' => true,
217
- ),
218
- 'setmeta' => array(
219
- 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ),
220
- 'type' => 'checkbox',
221
- ),
222
- 'key' => array(
223
- 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ),
224
- 'default' => '',
225
- 'type' => 'text',
226
- ),
227
- 'appid' => array(
228
- 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ),
229
- 'default' => '',
230
- 'type' => 'text',
231
- ),
232
- 'title_shortcodes' => array(
233
- 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ),
234
- ),
235
- 'description_shortcodes' => array(
236
- 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ),
237
- ),
238
- 'sitename' => array(
239
- 'name' => __( 'Site Name', 'all-in-one-seo-pack' ),
240
- 'default' => get_bloginfo( 'name' ),
241
- 'type' => 'text',
242
- ),
243
- 'hometitle' => array(
244
- 'name' => __( 'Home Title', 'all-in-one-seo-pack' ),
245
- 'default' => '',
246
- 'type' => 'textarea',
247
- 'condshow' => array(
248
- 'aiosp_opengraph_setmeta' => array(
249
- 'lhs' => 'aiosp_opengraph_setmeta',
250
- 'op' => '!=',
251
- 'rhs' => 'on',
252
- ),
253
- ),
254
- ),
255
- 'description' => array(
256
- 'name' => __( 'Home Description', 'all-in-one-seo-pack' ),
257
- 'default' => '',
258
- 'type' => 'textarea',
259
- 'condshow' => array(
260
- 'aiosp_opengraph_setmeta' => array(
261
- 'lhs' => 'aiosp_opengraph_setmeta',
262
- 'op' => '!=',
263
- 'rhs' => 'on',
264
- ),
265
- ),
266
- ),
267
- 'homeimage' => array(
268
- 'name' => __( 'Home Image', 'all-in-one-seo-pack' ),
269
- 'type' => 'image',
270
- ),
271
- 'generate_descriptions' => array(
272
- 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ),
273
- 'default' => 0,
274
- ),
275
- 'defimg' => array(
276
- 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ),
277
- 'type' => 'select',
278
- 'initial_options' => array(
279
- '' => __( 'Default Image' ),
280
- 'featured' => __( 'Featured Image' ),
281
- 'attach' => __( 'First Attached Image' ),
282
- 'content' => __( 'First Image In Content' ),
283
- 'custom' => __( 'Image From Custom Field' ),
284
- 'author' => __( 'Post Author Image' ),
285
- 'auto' => __( 'First Available Image' ),
286
- ),
287
- ),
288
- 'fallback' => array(
289
- 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ),
290
- 'type' => 'checkbox',
291
- ),
292
- 'dimg' => array(
293
- 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ),
294
- 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png',
295
- 'type' => 'image',
296
- ),
297
- 'dimgwidth' => array(
298
- 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ),
299
- 'type' => 'text',
300
- 'default' => '',
301
- ),
302
- 'dimgheight' => array(
303
- 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ),
304
- 'type' => 'text',
305
- 'default' => '',
306
- ),
307
- 'meta_key' => array(
308
- 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ),
309
- 'type' => 'text',
310
- 'default' => '',
311
- ),
312
- 'image' => array(
313
- 'name' => __( 'Image', 'all-in-one-seo-pack' ),
314
- 'type' => 'radio',
315
- 'initial_options' => array(
316
- 0 => '<img style="width:50px;height:auto;display:inline-block;vertical-align:bottom;" src="' . AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png' . '">',
317
- ),
318
- ),
319
- 'customimg' => array(
320
- 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ),
321
- 'type' => 'image',
322
- ),
323
- 'imagewidth' => array(
324
- 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ),
325
- 'type' => 'text',
326
- 'default' => '',
327
- ),
328
- 'imageheight' => array(
329
- 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ),
330
- 'type' => 'text',
331
- 'default' => '',
332
- ),
333
- 'video' => array(
334
- 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ),
335
- 'type' => 'text',
336
- ),
337
- 'videowidth' => array(
338
- 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ),
339
- 'type' => 'text',
340
- 'default' => '',
341
- 'condshow' => array(
342
- 'aioseop_opengraph_settings_video' => array(
343
- 'lhs' => 'aioseop_opengraph_settings_video',
344
- 'op' => '!=',
345
- 'rhs' => '',
346
- ),
347
- ),
348
- ),
349
- 'videoheight' => array(
350
- 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ),
351
- 'type' => 'text',
352
- 'default' => '',
353
- 'condshow' => array(
354
- 'aioseop_opengraph_settings_video' => array(
355
- 'lhs' => 'aioseop_opengraph_settings_video',
356
- 'op' => '!=',
357
- 'rhs' => '',
358
- ),
359
- ),
360
- ),
361
- 'defcard' => array(
362
- 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ),
363
- 'type' => 'select',
364
- 'default' => 'summary',
365
- 'initial_options' => array(
366
- 'summary' => __( 'Summary', 'all-in-one-seo-pack' ),
367
- 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ),
368
-
369
- /*
370
- REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE
371
- 'photo' => __( 'Photo', 'all-in-one-seo-pack' )
372
- */
373
- ),
374
- ),
375
- 'setcard' => array(
376
- 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ),
377
- 'type' => 'select',
378
- 'initial_options' => array(
379
- 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ),
380
- 'summary' => __( 'Summary', 'all-in-one-seo-pack' ),
381
-
382
- /*
383
- REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE
384
- 'photo' => __( 'Photo', 'all-in-one-seo-pack' )
385
- */
386
- ),
387
- ),
388
- 'twitter_site' => array(
389
- 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ),
390
- 'type' => 'text',
391
- 'default' => '',
392
- ),
393
- 'twitter_creator' => array(
394
- 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ),
395
- ),
396
- 'twitter_domain' => array(
397
- 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ),
398
- 'type' => 'text',
399
- 'default' => '',
400
- ),
401
- 'customimg_twitter' => array(
402
- 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ),
403
- 'type' => 'image',
404
- ),
405
- 'gen_tags' => array(
406
- 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ),
407
- ),
408
- 'gen_keywords' => array(
409
- 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ),
410
- 'default' => 'on',
411
- 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
412
- ),
413
- 'gen_categories' => array(
414
- 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ),
415
- 'default' => 'on',
416
- 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
417
- ),
418
- 'gen_post_tags' => array(
419
- 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ),
420
- 'default' => 'on',
421
- 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
422
- ),
423
- 'types' => array(
424
- 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ),
425
- 'type' => 'multicheckbox',
426
- 'default' => array( 'post' => 'post', 'page' => 'page' ),
427
- 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ),
428
- ),
429
- 'title' => array(
430
- 'name' => __( 'Title', 'all-in-one-seo-pack' ),
431
- 'default' => '',
432
- 'type' => 'text',
433
- 'size' => 95,
434
- 'count' => 1,
435
- 'count_desc' => $count_desc,
436
- ),
437
- 'desc' => array(
438
- 'name' => __( 'Description', 'all-in-one-seo-pack' ),
439
- 'default' => '',
440
- 'type' => 'textarea',
441
- 'cols' => 250,
442
- 'rows' => 4,
443
- 'count' => 1,
444
- 'count_desc' => $count_desc,
445
- ),
446
- 'category' => array(
447
- 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ),
448
- 'type' => 'select',
449
- 'style' => '',
450
- 'default' => '',
451
- 'initial_options' => $this->fb_object_types,
452
- ),
453
- 'facebook_debug' => array(
454
- 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ),
455
- 'type' => 'html',
456
- 'save' => false,
457
- 'default' => '<a
458
- name="aioseop_opengraph_settings_facebook_debug"
459
- id="aioseop_opengraph_settings_facebook_debug"
460
- class="button-primary"
461
- href=""
462
- target="_blank">' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '</a>',
463
- ),
464
- 'section' => array(
465
- 'name' => __( 'Article Section', 'all-in-one-seo-pack' ),
466
- 'type' => 'text',
467
- 'default' => '',
468
- 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ),
469
- ),
470
- 'tag' => array(
471
- 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ),
472
- 'type' => 'text',
473
- 'default' => '',
474
- 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ),
475
- ),
476
- 'facebook_publisher' => array(
477
- 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ),
478
- 'type' => 'text',
479
- 'default' => '',
480
- ),
481
- 'facebook_author' => array(
482
- 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ),
483
- ),
484
- 'profile_links' => array(
485
- 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ),
486
- 'type' => 'textarea',
487
- 'cols' => 60,
488
- 'rows' => 5,
489
- ),
490
- 'person_or_org' => array(
491
- 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ),
492
- 'type' => 'radio',
493
- 'initial_options' => array(
494
- 'person' => __( 'Person', 'all-in-one-seo-pack' ),
495
- 'org' => __( 'Organization', 'all-in-one-seo-pack' ),
496
- ),
497
- ),
498
- 'social_name' => array(
499
- 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ),
500
- 'type' => 'text',
501
- 'default' => '',
502
- ),
503
- );
504
- // load initial options / set defaults
505
- $this->update_options();
506
- $display = array();
507
- if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) {
508
- $display = $this->options['aiosp_opengraph_types'];
509
- }
510
- $this->locations = array(
511
- 'opengraph' => array(
512
- 'name' => $this->name,
513
- 'prefix' => 'aiosp_',
514
- 'type' => 'settings',
515
- 'options' => array(
516
- 'scan_header',
517
- 'setmeta',
518
- 'key',
519
- 'appid',
520
- 'sitename',
521
- 'title_shortcodes',
522
- 'description_shortcodes',
523
- 'hometitle',
524
- 'description',
525
- 'homeimage',
526
- 'generate_descriptions',
527
- 'defimg',
528
- 'fallback',
529
- 'dimg',
530
- 'dimgwidth',
531
- 'dimgheight',
532
- 'meta_key',
533
- 'defcard',
534
- 'profile_links',
535
- 'person_or_org',
536
- 'social_name',
537
- 'twitter_site',
538
- 'twitter_creator',
539
- 'twitter_domain',
540
- 'gen_tags',
541
- 'gen_keywords',
542
- 'gen_categories',
543
- 'gen_post_tags',
544
- 'types',
545
- 'facebook_publisher',
546
- 'facebook_author',
547
- ),
548
- ),
549
- 'settings' => array(
550
- 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ),
551
- 'type' => 'metabox',
552
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/',
553
- 'options' => array(
554
- 'title',
555
- 'desc',
556
- 'image',
557
- 'customimg',
558
- 'imagewidth',
559
- 'imageheight',
560
- 'video',
561
- 'videowidth',
562
- 'videoheight',
563
- 'category',
564
- 'facebook_debug',
565
- 'section',
566
- 'tag',
567
- 'setcard',
568
- 'customimg_twitter',
569
- ),
570
- 'display' => apply_filters( 'aioseop_opengraph_display', $display ),
571
- 'prefix' => 'aioseop_opengraph_',
572
- ),
573
- );
574
- $this->layout = array(
575
- 'home' => array(
576
- 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ),
577
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description',
578
- 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ),
579
- ),
580
- 'image' => array(
581
- 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ),
582
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source',
583
- 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ),
584
- ),
585
- 'links' => array(
586
- 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ),
587
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links',
588
- 'options' => array( 'profile_links', 'person_or_org', 'social_name' ),
589
- ),
590
- 'facebook' => array(
591
- 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ),
592
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings',
593
- 'options' => array(
594
- 'key',
595
- 'appid',
596
- 'types',
597
- 'gen_tags',
598
- 'gen_keywords',
599
- 'gen_categories',
600
- 'gen_post_tags',
601
- 'facebook_publisher',
602
- 'facebook_author',
603
- ),
604
- ),
605
- 'twitter' => array(
606
- 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ),
607
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card',
608
- 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ),
609
- ),
610
- 'default' => array(
611
- 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ),
612
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/',
613
- 'options' => array(), // this is set below, to the remaining options -- pdb
614
- ),
615
- 'scan_meta' => array(
616
- 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ),
617
- 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta',
618
- 'options' => array( 'scan_header' ),
619
- ),
620
- );
621
- $other_options = array();
622
- foreach ( $this->layout as $k => $v ) {
623
- $other_options = array_merge( $other_options, $v['options'] );
624
- }
625
-
626
- $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options );
627
- }
628
-
629
- /**
630
- * Forces FaceBook OpenGraph to refresh its cache when a post is changed to
631
- *
632
- * @param $new_status
633
- * @param $old_status
634
- * @param $post
635
- *
636
- * @todo this and force_fb_refresh_update can probably have the remote POST extracted out.
637
- *
638
- * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update
639
- * @since 2.3.11
640
- */
641
- function force_fb_refresh_transition( $new_status, $old_status, $post ) {
642
- if ( 'publish' !== $new_status ) {
643
- return;
644
- }
645
- if ( 'future' !== $old_status ) {
646
- return;
647
- }
648
-
649
- $current_post_type = get_post_type();
650
-
651
- // Only ping Facebook if Social SEO is enabled on this post type.
652
- if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) {
653
- $post_url = aioseop_get_permalink( $post->ID );
654
- $endpoint = sprintf(
655
- 'https://graph.facebook.com/?%s', http_build_query(
656
- array(
657
- 'id' => $post_url,
658
- 'scrape' => true,
659
- )
660
- )
661
- );
662
- wp_remote_post( $endpoint, array( 'blocking' => false ) );
663
- }
664
- }
665
-
666
- /**
667
- * Forces FaceBook OpenGraph refresh on update.
668
- *
669
- * @param $post_id
670
- * @param $post_after
671
- *
672
- * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update
673
- * @since 2.3.11
674
- */
675
- function force_fb_refresh_update( $post_id, $post_after ) {
676
-
677
- $current_post_type = get_post_type();
678
-
679
- // Only ping Facebook if Social SEO is enabled on this post type.
680
- if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) {
681
- $post_url = aioseop_get_permalink( $post_id );
682
- $endpoint = sprintf(
683
- 'https://graph.facebook.com/?%s', http_build_query(
684
- array(
685
- 'id' => $post_url,
686
- 'scrape' => true,
687
- )
688
- )
689
- );
690
- wp_remote_post( $endpoint, array( 'blocking' => false ) );
691
- }
692
- }
693
-
694
- function settings_page_init() {
695
- add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 );
696
- }
697
-
698
- function filter_options( $options, $location ) {
699
- if ( $location == 'settings' ) {
700
- $prefix = $this->get_prefix( $location ) . $location . '_';
701
- list( $legacy, $images ) = $this->get_all_images( $options );
702
- if ( isset( $options ) && isset( $options["{$prefix}image"] ) ) {
703
- $thumbnail = $options["{$prefix}image"];
704
- if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) {
705
- if ( $thumbnail == 'post' ) {
706
- $thumbnail = $images['post1'];
707
- } elseif ( ! empty( $legacy[ $thumbnail ] ) ) {
708
- $thumbnail = $legacy[ $thumbnail ];
709
- }
710
- }
711
- $options["{$prefix}image"] = $thumbnail;
712
- }
713
- if ( empty( $options[ $prefix . 'image' ] ) ) {
714
- $img = array_keys( $images );
715
- if ( ! empty( $img ) && ! empty( $img[1] ) ) {
716
- $options[ $prefix . 'image' ] = $img[1];
717
- }
718
- }
719
- }
720
-
721
- return $options;
722
- }
723
-
724
- /**
725
- * Applies filter to module settings.
726
- *
727
- * @since 2.3.11
728
- * @since 2.4.14 Added filter for description and title placeholders.
729
- * @since 2.3.15 do_shortcode on description.
730
- *
731
- * @see [plugin]\admin\aioseop_module_class.php > display_options()
732
- */
733
- function filter_settings( $settings, $location, $current ) {
734
- global $aiosp, $post;
735
- if ( $location == 'opengraph' || $location == 'settings' ) {
736
- $prefix = $this->get_prefix( $location ) . $location . '_';
737
- if ( $location == 'opengraph' ) {
738
- return $settings;
739
- }
740
- if ( $location == 'settings' ) {
741
- list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current );
742
- $opts = array( 'title', 'desc' );
743
- $current_post_type = get_post_type();
744
- if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) {
745
- $flat_type_list = array();
746
- foreach ( $this->fb_object_types as $k => $v ) {
747
- if ( is_array( $v ) ) {
748
- $flat_type_list = array_merge( $flat_type_list, $v );
749
- } else {
750
- $flat_type_list[ $k ] = $v;
751
- }
752
- }
753
- $settings[ $prefix . 'category' ]['initial_options'] = array_merge(
754
- array(
755
- $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - '
756
- . $flat_type_list[ $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ],
757
- ),
758
- $settings[ $prefix . 'category' ]['initial_options']
759
- );
760
- }
761
- if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) {
762
- $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard'];
763
- }
764
- $info = $aiosp->get_page_snippet_info();
765
- $title = $info['title'];
766
- $description = $info['description'];
767
-
768
- // Description options
769
- if ( is_object( $post ) ) {
770
- // Always show excerpt
771
- $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] )
772
- ? $aiosp->trim_excerpt_without_filters(
773
- $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ),
774
- 1000
775
- )
776
- : $aiosp->trim_excerpt_without_filters(
777
- $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ),
778
- 1000
779
- );
780
- }
781
-
782
- // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932.
783
- $screen = get_current_screen();
784
- $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id;
785
-
786
- // Add filters
787
- $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version );
788
- // Add placholders
789
- $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title );
790
- $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description );
791
- }
792
- if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) {
793
- foreach ( $opts as $opt ) {
794
- if ( isset( $settings[ $prefix . $opt ] ) ) {
795
- $settings[ $prefix . $opt ]['type'] = 'hidden';
796
- $settings[ $prefix . $opt ]['label'] = 'none';
797
- $settings[ $prefix . $opt ]['help_text'] = '';
798
- unset( $settings[ $prefix . $opt ]['count'] );
799
- }
800
- }
801
- }
802
- }
803
-
804
- return $settings;
805
- }
806
-
807
- /**
808
- * Applies filter to module options.
809
- * These will display in the "Social Settings" object tab.
810
- * filter:{prefix}override_options
811
- *
812
- * @since 2.3.11
813
- * @since 2.4.14 Overrides empty og:type values.
814
- *
815
- * @see [plugin]\admin\aioseop_module_class.php > display_options()
816
- *
817
- * @global array $aioseop_options Plugin options.
818
- *
819
- * @param array $options Current options.
820
- * @param string $location Location where filter is called.
821
- * @param array $settings Settings.
822
- *
823
- * @return array
824
- */
825
- function override_options( $options, $location, $settings ) {
826
- global $aioseop_options;
827
- // Prepare default and prefix
828
- $prefix = $this->get_prefix( $location ) . $location . '_';
829
- $opts = array();
830
-
831
- foreach ( $settings as $k => $v ) {
832
- if ( $v['save'] ) {
833
- $opts[ $k ] = $v['default'];
834
- }
835
- }
836
- foreach ( $options as $k => $v ) {
837
- switch ( $k ) {
838
- case $prefix . 'category':
839
- if ( empty( $v ) ) {
840
- // Get post type
841
- $type = isset( get_current_screen()->post_type )
842
- ? get_current_screen()->post_type
843
- : null;
844
- // Assign default from plugin options
845
- if ( ! empty( $type )
846
- && isset( $aioseop_options['modules'] )
847
- && isset( $aioseop_options['modules']['aiosp_opengraph_options'] )
848
- && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] )
849
- ) {
850
- $options[ $prefix . 'category' ] =
851
- $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ];
852
- }
853
- continue;
854
- }
855
- break;
856
- }
857
- if ( $v === null ) {
858
- unset( $options[ $k ] );
859
- }
860
- }
861
- $options = wp_parse_args( $options, $opts );
862
-
863
- return $options;
864
- }
865
-
866
- /**
867
- * Applies filter to metabox settings before they are saved.
868
- * Sets custom as default if a custom image is uploaded.
869
- * filter:{prefix}filter_metabox_options
870
- * filter:{prefix}filter_term_metabox_options
871
- *
872
- * @since 2.3.11
873
- * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found.
874
- *
875
- * @see [plugin]\admin\aioseop_module_class.php > save_post_data()
876
- * @see [this file] > save_tax_data()
877
- *
878
- * @param array $options List of current options.
879
- * @param string $location Location where filter is called.
880
- * @param int $id Either post_id or term_id.
881
- *
882
- * @return array
883
- */
884
- function filter_metabox_options( $options, $location, $post_id ) {
885
- if ( $location == 'settings' ) {
886
- $prefix = $this->get_prefix( $location ) . $location . '_';
887
- if ( isset( $options[ $prefix . 'customimg_checker' ] )
888
- && $options[ $prefix . 'customimg_checker' ]
889
- ) {
890
- $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ];
891
- }
892
- }
893
- return $options;
894
- }
895
-
896
- /** Custom settings **/
897
- function display_custom_options( $buf, $args ) {
898
- if ( $args['name'] == 'aiosp_opengraph_scan_header' ) {
899
- $buf .= '<div class="aioseop aioseop_options aiosp_opengraph_settings"><div class="aioseop_wrapper aioseop_custom_type" id="aiosp_opengraph_scan_header_wrapper"><div class="aioseop_input" id="aiosp_opengraph_scan_header" style="padding-left:20px;">';
900
- $args['options']['type'] = 'submit';
901
- $args['attr'] = " class='button-primary' ";
902
- $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' );
903
- $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' );
904
- $buf .= '<br /><br />' . $this->get_option_html( $args );
905
- $buf .= '</div></div></div>';
906
- }
907
-
908
- return $buf;
909
- }
910
-
911
- function add_attributes( $output ) {
912
- // avoid having duplicate meta tags
913
- $type = $this->type;
914
- if ( empty( $type ) ) {
915
- $type = 'website';
916
- }
917
-
918
- $schema_types = array(
919
- 'album' => 'MusicAlbum',
920
- 'article' => 'Article',
921
- 'bar' => 'BarOrPub',
922
- 'blog' => 'Blog',
923
- 'book' => 'Book',
924
- 'cafe' => 'CafeOrCoffeeShop',
925
- 'city' => 'City',
926
- 'country' => 'Country',
927
- 'episode' => 'Episode',
928
- 'food' => 'FoodEvent',
929
- 'game' => 'Game',
930
- 'hotel' => 'Hotel',
931
- 'landmark' => 'LandmarksOrHistoricalBuildings',
932
- 'movie' => 'Movie',
933
- 'product' => 'Product',
934
- 'profile' => 'ProfilePage',
935
- 'restaurant' => 'Restaurant',
936
- 'school' => 'School',
937
- 'sport' => 'SportsEvent',
938
- 'website' => 'WebSite',
939
- );
940
-
941
- if ( ! empty( $schema_types[ $type ] ) ) {
942
- $type = $schema_types[ $type ];
943
- } else {
944
- $type = 'WebSite';
945
- }
946
-
947
- $attributes = apply_filters(
948
- $this->prefix . 'attributes', array(
949
- 'prefix="og: http://ogp.me/ns#"',
950
- )
951
- );
952
-
953
- foreach ( $attributes as $attr ) {
954
- if ( strpos( $output, $attr ) === false ) {
955
- $output .= "\n\t$attr ";
956
- }
957
- }
958
-
959
- return $output;
960
- }
961
-
962
- /**
963
- * Add our social meta.
964
- *
965
- * @since 1.0.0
966
- * @since 2.3.11.5 Support for multiple fb_admins.
967
- * @since 2.3.13 Adds filter:aioseop_description on description.
968
- * @since 2.4.14 Fixes for aioseop-pro #67.
969
- * @since 2.3.15 Always do_shortcode on descriptions, removed for titles.
970
- *
971
- * @global object $post Current WP_Post object.
972
- * @global object $aiosp All in one seo plugin object.
973
- * @global array $aioseop_options All in one seo plugin options.
974
- * @global object $wp_query WP_Query global instance.
975
- */
976
- function add_meta() {
977
- global $post, $aiosp, $aioseop_options, $wp_query;
978
- $metabox = $this->get_current_options( array(), 'settings' );
979
- $key = $this->options['aiosp_opengraph_key'];
980
- $key = $this->options['aiosp_opengraph_key'];
981
- $dimg = $this->options['aiosp_opengraph_dimg'];
982
- $current_post_type = get_post_type();
983
- $title = $description = $image = $video = '';
984
- $type = $this->type;
985
- $sitename = $this->options['aiosp_opengraph_sitename'];
986
-
987
- $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : '';
988
-
989
- if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) {
990
- $first_page = false;
991
- if ( $aiosp->get_page_number() < 2 ) {
992
- $first_page = true;
993
- }
994
- } else {
995
- $first_page = true;
996
- }
997
- $url = $aiosp->aiosp_mrt_get_url( $wp_query );
998
- $url = apply_filters( 'aioseop_canonical_url', $url );
999
-
1000
- $setmeta = $this->options['aiosp_opengraph_setmeta'];
1001
- $social_links = '';
1002
- if ( is_front_page() ) {
1003
- $title = $this->options['aiosp_opengraph_hometitle'];
1004
- if ( $first_page ) {
1005
- $description = $this->options['aiosp_opengraph_description'];
1006
- if ( empty( $description ) ) {
1007
- $description = get_bloginfo( 'description' );
1008
- }
1009
- }
1010
- if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) {
1011
- $thumbnail = $this->options['aiosp_opengraph_homeimage'];
1012
- } else {
1013
- $thumbnail = $this->options['aiosp_opengraph_dimg'];
1014
- }
1015
-
1016
- /* If Use AIOSEO Title and Desc Selected */
1017
- if ( $setmeta ) {
1018
- $title = $aiosp->wp_title();
1019
- if ( $first_page ) {
1020
- $description = $aiosp->get_aioseop_description( $post );
1021
- }
1022
- }
1023
-
1024
- /* Add some defaults */
1025
- if ( empty( $title ) ) {
1026
- $title = get_bloginfo( 'name' );
1027
- }
1028
- if ( empty( $sitename ) ) {
1029
- $sitename = get_bloginfo( 'name' );
1030
- }
1031
-
1032
- if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) {
1033
-
1034
- if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) {
1035
- $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 );
1036
-
1037
- if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) {
1038
- $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 );
1039
- }
1040
- }
1041
- }
1042
-
1043
- if ( empty( $description ) && $first_page ) {
1044
- $description = get_bloginfo( 'description' );
1045
- }
1046
- if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) {
1047
- $social_links = $this->options['aiosp_opengraph_profile_links'];
1048
- if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) {
1049
- $social_name = $this->options['aiosp_opengraph_social_name'];
1050
- } else {
1051
- $social_name = '';
1052
- }
1053
- if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) {
1054
- $social_type = 'Person';
1055
- } else {
1056
- $social_type = 'Organization';
1057
- }
1058
- }
1059
- } elseif ( is_singular() && $this->option_isset( 'types' )
1060
- && is_array( $this->options['aiosp_opengraph_types'] )
1061
- && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] )
1062
- ) {
1063
-
1064
- if ( $type == 'article' ) {
1065
- if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) {
1066
- $section = $metabox['aioseop_opengraph_settings_section'];
1067
- }
1068
- if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) {
1069
- $tag = $metabox['aioseop_opengraph_settings_tag'];
1070
- }
1071
- if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) {
1072
- $publisher = $this->options['aiosp_opengraph_facebook_publisher'];
1073
- }
1074
- }
1075
-
1076
- if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1077
- $domain = $this->options['aiosp_opengraph_twitter_domain'];
1078
- }
1079
-
1080
- if ( $type == 'article' && ! empty( $post ) ) {
1081
- if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) {
1082
- $author = get_the_author_meta( 'facebook', $post->post_author );
1083
- }
1084
-
1085
- if ( isset( $post->post_date_gmt ) ) {
1086
- $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) );
1087
- }
1088
-
1089
- if ( isset( $post->post_modified_gmt ) ) {
1090
- $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) );
1091
- }
1092
- }
1093
-
1094
- $image = $metabox['aioseop_opengraph_settings_image'];
1095
- $video = $metabox['aioseop_opengraph_settings_video'];
1096
- $title = $metabox['aioseop_opengraph_settings_title'];
1097
- $description = $metabox['aioseop_opengraph_settings_desc'];
1098
-
1099
- /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */
1100
- global $aiosp;
1101
- if ( empty( $title ) ) {
1102
- $title = $aiosp->wp_title();
1103
- }
1104
- if ( empty( $description ) ) {
1105
- $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) );
1106
- }
1107
-
1108
- /* Add default title */
1109
- if ( empty( $title ) ) {
1110
- $title = get_the_title();
1111
- }
1112
-
1113
- // Add default description.
1114
- if ( empty( $description ) && ! post_password_required( $post ) ) {
1115
-
1116
- $description = $post->post_excerpt;
1117
-
1118
- if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) {
1119
- $description = $post->post_content;
1120
- }
1121
- }
1122
- if ( empty( $type ) ) {
1123
- $type = 'article';
1124
- }
1125
- } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) {
1126
- if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) {
1127
- $type = $this->options['aioseop_opengraph_settings_category'];
1128
- }
1129
- if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) {
1130
- $type = $metabox['aioseop_opengraph_settings_category'];
1131
- }
1132
- if ( $type == 'article' ) {
1133
- if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) {
1134
- $section = $metabox['aioseop_opengraph_settings_section'];
1135
- }
1136
- if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) {
1137
- $tag = $metabox['aioseop_opengraph_settings_tag'];
1138
- }
1139
- if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) {
1140
- $publisher = $this->options['aiosp_opengraph_facebook_publisher'];
1141
- }
1142
- }
1143
- if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1144
- $domain = $this->options['aiosp_opengraph_twitter_domain'];
1145
- }
1146
- if ( $type == 'article' && ! empty( $post ) ) {
1147
- if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) {
1148
- $author = get_the_author_meta( 'facebook', $post->post_author );
1149
- }
1150
-
1151
- if ( isset( $post->post_date_gmt ) ) {
1152
- $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) );
1153
- }
1154
- if ( isset( $post->post_modified_gmt ) ) {
1155
- $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) );
1156
- }
1157
- }
1158
- $image = $metabox['aioseop_opengraph_settings_image'];
1159
- $video = $metabox['aioseop_opengraph_settings_video'];
1160
- $title = $metabox['aioseop_opengraph_settings_title'];
1161
- $description = $metabox['aioseop_opengraph_settings_desc'];
1162
- /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */
1163
- global $aiosp;
1164
- if ( empty( $title ) ) {
1165
- $title = $aiosp->wp_title();
1166
- }
1167
- if ( empty( $description ) ) {
1168
- $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0;
1169
- $term_id = $term_id ? $term_id : get_queried_object()->term_id;
1170
- $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) );
1171
- }
1172
- // Add default title
1173
- if ( empty( $title ) ) {
1174
- $title = get_the_title();
1175
- }
1176
- // Add default description.
1177
- if ( empty( $description ) && ! post_password_required( $post ) ) {
1178
- $description = get_queried_object()->description;
1179
- }
1180
- if ( empty( $type ) ) {
1181
- $type = 'website';
1182
- }
1183
- } elseif ( is_home() && ! is_front_page() ) {
1184
- // This is the blog page but not the homepage.
1185
- global $aiosp;
1186
- $image = $metabox['aioseop_opengraph_settings_image'];
1187
- $video = $metabox['aioseop_opengraph_settings_video'];
1188
- $title = $metabox['aioseop_opengraph_settings_title'];
1189
- $description = $metabox['aioseop_opengraph_settings_desc'];
1190
-
1191
- if ( empty( $description ) ) {
1192
- // If there's not social description, fall back to the SEO description.
1193
- $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) );
1194
- }
1195
- if ( empty( $title ) ) {
1196
- $title = $aiosp->wp_title();
1197
- }
1198
- } else {
1199
- return;
1200
- }
1201
-
1202
- if ( $type === 'article' && ! empty( $post ) && is_singular() ) {
1203
- if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) {
1204
- if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) {
1205
- $keywords = $aiosp->get_main_keywords();
1206
- $keywords = $this->apply_cf_fields( $keywords );
1207
- $keywords = apply_filters( 'aioseop_keywords', $keywords );
1208
- if ( ! empty( $keywords ) && ! empty( $tag ) ) {
1209
- $tag .= ',' . $keywords;
1210
- } elseif ( empty( $tag ) ) {
1211
- $tag = $keywords;
1212
- }
1213
- }
1214
- $tag = $aiosp->keyword_string_to_list( $tag );
1215
- if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) {
1216
- $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) );
1217
- }
1218
- if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) {
1219
- $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) );
1220
- }
1221
- }
1222
- if ( ! empty( $tag ) ) {
1223
- $tag = $aiosp->clean_keyword_list( $tag );
1224
- }
1225
- }
1226
-
1227
- if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) {
1228
- $title = do_shortcode( $title );
1229
- }
1230
- if ( ! empty( $description ) ) {
1231
- $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) );
1232
- if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) {
1233
- $description = do_shortcode( $description );
1234
- }
1235
- $description = $aiosp->trim_excerpt_without_filters( $description, 1000 );
1236
- }
1237
-
1238
- $title = $this->apply_cf_fields( $title );
1239
- $description = $this->apply_cf_fields( $description );
1240
-
1241
- /* Data Validation */
1242
- $title = strip_tags( esc_attr( $title ) );
1243
- $sitename = strip_tags( esc_attr( $sitename ) );
1244
- $description = strip_tags( esc_attr( $description ) );
1245
-
1246
- if ( empty( $thumbnail ) && ! empty( $image ) ) {
1247
- $thumbnail = $image;
1248
- }
1249
-
1250
- // Add user supplied default image.
1251
- if ( empty( $thumbnail ) ) {
1252
- if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) {
1253
- $thumbnail = $this->options['aiosp_opengraph_dimg'];
1254
- } else {
1255
- $img_type = $this->options['aiosp_opengraph_defimg'];
1256
- if ( ! empty( $post ) ) {
1257
- // Customize the type of image per post/post_type.
1258
- $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type );
1259
- }
1260
- switch ( $img_type ) {
1261
- case 'featured':
1262
- $thumbnail = $this->get_the_image_by_post_thumbnail();
1263
- break;
1264
- case 'attach':
1265
- $thumbnail = $this->get_the_image_by_attachment();
1266
- break;
1267
- case 'content':
1268
- $thumbnail = $this->get_the_image_by_scan();
1269
- break;
1270
- case 'custom':
1271
- $meta_key = $this->options['aiosp_opengraph_meta_key'];
1272
- if ( ! empty( $meta_key ) && ! empty( $post ) ) {
1273
- $meta_key = explode( ',', $meta_key );
1274
- $thumbnail = $this->get_the_image_by_meta_key(
1275
- array(
1276
- 'post_id' => $post->ID,
1277
- 'meta_key' => $meta_key,
1278
- )
1279
- );
1280
- }
1281
- break;
1282
- case 'auto':
1283
- $thumbnail = $this->get_the_image();
1284
- break;
1285
- case 'author':
1286
- $thumbnail = $this->get_the_image_by_author();
1287
- break;
1288
- default:
1289
- $thumbnail = $this->options['aiosp_opengraph_dimg'];
1290
- }
1291
- }
1292
- }
1293
-
1294
- if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) {
1295
- $thumbnail = $this->options['aiosp_opengraph_dimg'];
1296
- if ( ! empty( $post ) ) {
1297
- // Customize the default image per post/post_type.
1298
- $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type );
1299
- }
1300
- }
1301
-
1302
- if ( ! empty( $thumbnail ) ) {
1303
- $thumbnail = esc_url( $thumbnail );
1304
- $thumbnail = set_url_scheme( $thumbnail );
1305
- }
1306
-
1307
- $width = $height = '';
1308
- if ( ! empty( $thumbnail ) ) {
1309
- if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) {
1310
- $width = $metabox['aioseop_opengraph_settings_imagewidth'];
1311
- }
1312
- if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) {
1313
- $height = $metabox['aioseop_opengraph_settings_imageheight'];
1314
- }
1315
- if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) {
1316
- $width = $this->options['aiosp_opengraph_dimgwidth'];
1317
- }
1318
- if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) {
1319
- $height = $this->options['aiosp_opengraph_dimgheight'];
1320
- }
1321
- }
1322
-
1323
- if ( ! empty( $video ) ) {
1324
- if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) {
1325
- $videowidth = $metabox['aioseop_opengraph_settings_videowidth'];
1326
- }
1327
- if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) {
1328
- $videoheight = $metabox['aioseop_opengraph_settings_videoheight'];
1329
- }
1330
- }
1331
-
1332
- $card = 'summary';
1333
- if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) {
1334
- $card = $this->options['aiosp_opengraph_defcard'];
1335
- }
1336
-
1337
- if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) {
1338
- $card = $metabox['aioseop_opengraph_settings_setcard'];
1339
- }
1340
-
1341
- // support for changing legacy twitter cardtype-photo to summary large image
1342
- if ( $card == 'photo' ) {
1343
- $card = 'summary_large_image';
1344
- }
1345
-
1346
- $site = $domain = $creator = '';
1347
-
1348
- if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) {
1349
- $site = $this->options['aiosp_opengraph_twitter_site'];
1350
- $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site );
1351
- }
1352
-
1353
- if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1354
- $domain = $this->options['aiosp_opengraph_twitter_domain'];
1355
- }
1356
-
1357
- if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) {
1358
- $creator = get_the_author_meta( 'twitter', $post->post_author );
1359
- $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator );
1360
- }
1361
-
1362
- if ( ! empty( $thumbnail ) ) {
1363
- $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set.
1364
- }
1365
-
1366
- if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) {
1367
- // Set Twitter image from custom.
1368
- $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] );
1369
- }
1370
-
1371
- // Apply last filters.
1372
- $description = apply_filters( 'aioseop_description', $description );
1373
-
1374
- $meta = array(
1375
- 'facebook' => array(
1376
- 'title' => 'og:title',
1377
- 'type' => 'og:type',
1378
- 'url' => 'og:url',
1379
- 'thumbnail' => 'og:image',
1380
- 'width' => 'og:image:width',
1381
- 'height' => 'og:image:height',
1382
- 'video' => 'og:video',
1383
- 'videowidth' => 'og:video:width',
1384
- 'videoheight' => 'og:video:height',
1385
- 'sitename' => 'og:site_name',
1386
- 'key' => 'fb:admins',
1387
- 'appid' => 'fb:app_id',
1388
- 'description' => 'og:description',
1389
- 'section' => 'article:section',
1390
- 'tag' => 'article:tag',
1391
- 'publisher' => 'article:publisher',
1392
- 'author' => 'article:author',
1393
- 'published_time' => 'article:published_time',
1394
- 'modified_time' => 'article:modified_time',
1395
- ),
1396
- 'twitter' => array(
1397
- 'card' => 'twitter:card',
1398
- 'site' => 'twitter:site',
1399
- 'creator' => 'twitter:creator',
1400
- 'domain' => 'twitter:domain',
1401
- 'title' => 'twitter:title',
1402
- 'description' => 'twitter:description',
1403
- 'twitter_thumbnail' => 'twitter:image',
1404
- ),
1405
- );
1406
-
1407
- // Only show if "use schema.org markup is checked".
1408
- if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) {
1409
- $meta['google+'] = array( 'thumbnail' => 'image' );
1410
- }
1411
-
1412
- $tags = array(
1413
- 'facebook' => array( 'name' => 'property', 'value' => 'content' ),
1414
- 'twitter' => array( 'name' => 'name', 'value' => 'content' ),
1415
- 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ),
1416
- );
1417
-
1418
- foreach ( $meta as $t => $data ) {
1419
- foreach ( $data as $k => $v ) {
1420
- if ( empty( $$k ) ) {
1421
- $$k = '';
1422
- }
1423
- $filtered_value = $$k;
1424
- $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k );
1425
- if ( ! empty( $filtered_value ) ) {
1426
- if ( ! is_array( $filtered_value ) ) {
1427
- $filtered_value = array( $filtered_value );
1428
- }
1429
-
1430
- /**
1431
- * This is to accomodate multiple fb:admins on separate lines.
1432
- * @TODO Eventually we'll want to put this in its own function so things like images work too.
1433
- */
1434
- if ( 'key' === $k ) {
1435
- $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array.
1436
- foreach ( $fbadmins as $fbadmin ) {
1437
- echo '<meta ' . $tags[ $t ]['name'] . '="' . $v . '" ' . $tags[ $t ]['value'] . '="' . $fbadmin . '" />' . "\n";
1438
- }
1439
- } else {
1440
- // For everything else.
1441
- foreach ( $filtered_value as $f ) {
1442
- // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES )
1443
- echo '<meta ' . $tags[ $t ]['name'] . '="' . $v . '" ' . $tags[ $t ]['value'] . '="' . esc_attr( $f ) . '" />' . "\n";
1444
- }
1445
- }
1446
- }
1447
- }
1448
- }
1449
- $social_link_schema = '';
1450
- if ( ! empty( $social_links ) ) {
1451
- $home_url = esc_url( get_home_url() );
1452
- $social_links = explode( "\n", $social_links );
1453
- foreach ( $social_links as $k => $v ) {
1454
- $v = trim( $v );
1455
- if ( empty( $v ) ) {
1456
- unset( $social_links[ $k ] );
1457
- } else {
1458
- $v = esc_url( $v );
1459
- $social_links[ $k ] = $v;
1460
- }
1461
- }
1462
- $social_links = join( '","', $social_links );
1463
- $social_link_schema = <<<END
1464
- <script type="application/ld+json">
1465
- { "@context" : "http://schema.org",
1466
- "@type" : "{$social_type}",
1467
- "name" : "{$social_name}",
1468
- "url" : "{$home_url}",
1469
- "sameAs" : ["{$social_links}"]
1470
- }
1471
- </script>
1472
-
1473
- END;
1474
- }
1475
- echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema );
1476
- }
1477
-
1478
- /**
1479
- * Do / adds opengraph properties to meta.
1480
- * @since 2.3.11
1481
- *
1482
- * @global array $aioseop_options AIOSEOP plugin options.
1483
- */
1484
- public function do_opengraph() {
1485
- global $aioseop_options;
1486
- if ( ! empty( $aioseop_options )
1487
- && ! empty( $aioseop_options['aiosp_schema_markup'] )
1488
- ) {
1489
- add_filter( 'language_attributes', array( &$this, 'add_attributes' ) );
1490
- }
1491
- if ( ! defined( 'DOING_AJAX' ) ) {
1492
- add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 );
1493
- // Add social meta to AMP plugin.
1494
- if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) {
1495
- add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 );
1496
- }
1497
- }
1498
- }
1499
-
1500
- /**
1501
- * Set up types.
1502
- *
1503
- * @since ?
1504
- * @since 2.3.15 Change to website for homepage and blog post index page, default to object.
1505
- */
1506
- function type_setup() {
1507
- $this->type = 'object'; // Default to type object if we don't have some other rule.
1508
-
1509
- if ( is_home() || is_front_page() ) {
1510
- $this->type = 'website'; // Home page and blog page should be website.
1511
- } elseif ( is_singular() && $this->option_isset( 'types' ) ) {
1512
- $metabox = $this->get_current_options( array(), 'settings' );
1513
- $current_post_type = get_post_type();
1514
- if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) {
1515
- $this->type = $metabox['aioseop_opengraph_settings_category'];
1516
- } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) {
1517
- $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ];
1518
- }
1519
- }
1520
- }
1521
-
1522
- /**
1523
- * Inits hooks and others for admin init.
1524
- * action:admin_init.
1525
- *
1526
- * @since 2.3.11
1527
- * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox.
1528
- */
1529
- function admin_init() {
1530
- add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 );
1531
- add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 );
1532
- add_filter( $this->get_prefix( 'settings' ) . 'default_options', array(
1533
- &$this,
1534
- 'filter_default_options',
1535
- ), 10, 2 );
1536
- add_filter(
1537
- $this->get_prefix( 'settings' ) . 'filter_metabox_options', array(
1538
- &$this,
1539
- 'filter_metabox_options',
1540
- ), 10, 3
1541
- );
1542
- add_filter(
1543
- $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array(
1544
- &$this,
1545
- 'filter_metabox_options',
1546
- ), 10, 3
1547
- );
1548
- $post_types = $this->get_post_type_titles();
1549
- $rempost = array(
1550
- 'revision' => 1,
1551
- 'nav_menu_item' => 1,
1552
- 'custom_css' => 1,
1553
- 'customize_changeset' => 1,
1554
- );
1555
- $post_types = array_diff_key( $post_types, $rempost );
1556
- $this->default_options['types']['initial_options'] = $post_types;
1557
- foreach ( $post_types as $slug => $name ) {
1558
- $field = $slug . '_fb_object_type';
1559
- $this->default_options[ $field ] = array(
1560
- 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "<br />($slug)",
1561
- 'type' => 'select',
1562
- 'style' => '',
1563
- 'initial_options' => $this->fb_object_types,
1564
- 'default' => 'article',
1565
- 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ),
1566
- );
1567
- $this->help_text[ $field ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' );
1568
- $this->help_anchors[ $field ] = '#content-object-types';
1569
- $this->locations['opengraph']['options'][] = $field;
1570
- $this->layout['facebook']['options'][] = $field;
1571
- }
1572
- $this->setting_options();
1573
- $this->add_help_text_links();
1574
-
1575
- }
1576
-
1577
- function get_all_images( $options = null, $p = null ) {
1578
- static $img = array();
1579
- if ( ! is_array( $options ) ) {
1580
- $options = array();
1581
- }
1582
- if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) {
1583
- $options['meta_key'] = $this->options['aiosp_opengraph_meta_key'];
1584
- }
1585
- if ( empty( $img ) ) {
1586
- $size = apply_filters( 'post_thumbnail_size', 'large' );
1587
- $default = $this->get_the_image_by_default();
1588
- if ( ! empty( $default ) ) {
1589
- $default = set_url_scheme( $default );
1590
- $img[ $default ] = 0;
1591
- }
1592
- $img = array_merge( $img, parent::get_all_images( $options, null ) );
1593
- }
1594
-
1595
- if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) {
1596
- $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg';
1597
- }
1598
-
1599
- if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) {
1600
- $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg';
1601
- $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter';
1602
- }
1603
-
1604
- if ( $author_img = $this->get_the_image_by_author( $p ) ) {
1605
- $image['author'] = $author_img;
1606
- }
1607
- $image = array_flip( $img );
1608
- $images = array();
1609
- if ( ! empty( $image ) ) {
1610
- foreach ( $image as $k => $v ) {
1611
- $images[ $v ] = '<img height=150 src="' . $v . '">';
1612
- }
1613
- }
1614
-
1615
- return array( $image, $images );
1616
- }
1617
-
1618
- function get_the_image_by_author( $options = null, $p = null ) {
1619
- if ( $p === null ) {
1620
- global $post;
1621
- } else {
1622
- $post = $p;
1623
- }
1624
- if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
1625
- $matches = array();
1626
- $get_avatar = get_avatar( $post->post_author, 300 );
1627
- if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) {
1628
- return $matches[1];
1629
- }
1630
- }
1631
-
1632
- return false;
1633
- }
1634
-
1635
- function get_the_image( $options = null, $p = null ) {
1636
- $meta_key = $this->options['aiosp_opengraph_meta_key'];
1637
-
1638
- return parent::get_the_image( array( 'meta_key' => $meta_key ), $p );
1639
- }
1640
-
1641
- function get_the_image_by_default( $args = array() ) {
1642
- return $this->options['aiosp_opengraph_dimg'];
1643
- }
1644
-
1645
- function settings_update() {
1646
-
1647
- }
1648
-
1649
- /**
1650
- * Admin Enqueue Scripts
1651
- *
1652
- * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen.
1653
- * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page.
1654
- *
1655
- * @since 2.9.2
1656
- *
1657
- * @see 'admin_enqueue_scripts' hook
1658
- * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
1659
- *
1660
- * @param string $hook_suffix
1661
- */
1662
- public function admin_enqueue_scripts( $hook_suffix ) {
1663
- wp_enqueue_script(
1664
- 'aioseop-opengraph-script',
1665
- AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js',
1666
- array(),
1667
- AIOSEOP_VERSION
1668
- );
1669
-
1670
- // Dev note: If certain JS files need to be restricted to select screens, then follow concept
1671
- // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix`
1672
- // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed.
1673
-
1674
- parent::admin_enqueue_scripts( $hook_suffix );
1675
- }
1676
-
1677
- /**
1678
- * Enqueue our file upload scripts and styles.
1679
- * @param $hook
1680
- */
1681
- function og_admin_enqueue_scripts( $hook ) {
1682
-
1683
- if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) {
1684
- // Only enqueue if we're on the social module settings page.
1685
- return;
1686
- }
1687
-
1688
- wp_enqueue_script( 'media-upload' );
1689
- wp_enqueue_script( 'thickbox' );
1690
- wp_enqueue_style( 'thickbox' );
1691
- wp_enqueue_media();
1692
- }
1693
-
1694
- function save_tax_data( $term_id, $tt_id, $taxonomy ) {
1695
- static $update = false;
1696
- if ( $update ) {
1697
- return;
1698
- }
1699
- if ( $this->locations !== null ) {
1700
- foreach ( $this->locations as $k => $v ) {
1701
- if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) {
1702
- $opts = $this->default_options( $k );
1703
- $options = array();
1704
- $update = false;
1705
- foreach ( $opts as $l => $o ) {
1706
- if ( isset( $_POST[ $l ] ) ) {
1707
- $options[ $l ] = stripslashes_deep( $_POST[ $l ] );
1708
- $options[ $l ] = esc_attr( $options[ $l ] );
1709
- $update = true;
1710
- }
1711
- }
1712
- if ( $update ) {
1713
- $prefix = $this->get_prefix( $k );
1714
- $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id );
1715
- update_term_meta( $term_id, '_' . $prefix . $k, $options );
1716
- }
1717
- }
1718
- }
1719
- }
1720
- }
1721
-
1722
- /**
1723
- * Returns the placeholder filtered and ready for DOM display.
1724
- * filter:aioseop_opengraph_placeholder
1725
- * @since 2.4.14
1726
- *
1727
- * @param mixed $placeholder Placeholder to be filtered.
1728
- * @param string $type Type of the value to be filtered.
1729
- *
1730
- * @return string
1731
- */
1732
- public function filter_placeholder( $placeholder, $type = 'text' ) {
1733
- return strip_tags( trim( $placeholder ) );
1734
- }
1735
-
1736
- /**
1737
- * Returns filtered default options.
1738
- * filter:{prefix}default_options
1739
- * @since 2.4.13
1740
- *
1741
- * @param array $options Default options.
1742
- * @param string $location Location.
1743
- *
1744
- * @return array
1745
- */
1746
- public function filter_default_options( $options, $location ) {
1747
- if ( $location === 'settings' ) {
1748
- $prefix = $this->get_prefix( $location ) . $location . '_';
1749
- // Add image checker as default
1750
- $options[ $prefix . 'customimg_checker' ] = 0;
1751
- }
1752
- return $options;
1753
- }
1754
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1755
  }
1
+ <?php
2
+ /**
3
+ * The Opengraph class.
4
+ *
5
+ * @package All-in-One-SEO-Pack
6
+ * @version 2.3.16
7
+ */
8
+ if ( ! class_exists( 'All_in_One_SEO_Pack_Opengraph' ) ) {
9
+ class All_in_One_SEO_Pack_Opengraph extends All_in_One_SEO_Pack_Module {
10
+ var $fb_object_types;
11
+ var $type;
12
+
13
+ /**
14
+ * Module constructor.
15
+ *
16
+ * @since 2.3.14 Added display filter.
17
+ * @since 2.3.16 #1066 Force init on constructor.
18
+ */
19
+ function __construct() {
20
+ add_action( 'admin_enqueue_scripts', array( $this, 'og_admin_enqueue_scripts' ) );
21
+
22
+ $this->name = __( 'Social Meta', 'all-in-one-seo-pack' ); // Human-readable name of the plugin
23
+ $this->prefix = 'aiosp_opengraph_'; // option prefix
24
+ $this->file = __FILE__; // the current file
25
+ $this->fb_object_types = array(
26
+ 'Activities' => array(
27
+ 'activity' => __( 'Activity', 'all-in-one-seo-pack' ),
28
+ 'sport' => __( 'Sport', 'all-in-one-seo-pack' ),
29
+ ),
30
+ 'Businesses' => array(
31
+ 'bar' => __( 'Bar', 'all-in-one-seo-pack' ),
32
+ 'company' => __( 'Company', 'all-in-one-seo-pack' ),
33
+ 'cafe' => __( 'Cafe', 'all-in-one-seo-pack' ),
34
+ 'hotel' => __( 'Hotel', 'all-in-one-seo-pack' ),
35
+ 'restaurant' => __( 'Restaurant', 'all-in-one-seo-pack' ),
36
+ ),
37
+ 'Groups' => array(
38
+ 'cause' => __( 'Cause', 'all-in-one-seo-pack' ),
39
+ 'sports_league' => __( 'Sports League', 'all-in-one-seo-pack' ),
40
+ 'sports_team' => __( 'Sports Team', 'all-in-one-seo-pack' ),
41
+ ),
42
+ 'Organizations' => array(
43
+ 'band' => __( 'Band', 'all-in-one-seo-pack' ),
44
+ 'government' => __( 'Government', 'all-in-one-seo-pack' ),
45
+ 'non_profit' => __( 'Non Profit', 'all-in-one-seo-pack' ),
46
+ 'school' => __( 'School', 'all-in-one-seo-pack' ),
47
+ 'university' => __( 'University', 'all-in-one-seo-pack' ),
48
+ ),
49
+ 'People' => array(
50
+ 'actor' => __( 'Actor', 'all-in-one-seo-pack' ),
51
+ 'athlete' => __( 'Athlete', 'all-in-one-seo-pack' ),
52
+ 'author' => __( 'Author', 'all-in-one-seo-pack' ),
53
+ 'director' => __( 'Director', 'all-in-one-seo-pack' ),
54
+ 'musician' => __( 'Musician', 'all-in-one-seo-pack' ),
55
+ 'politician' => __( 'Politician', 'all-in-one-seo-pack' ),
56
+ 'profile' => __( 'Profile', 'all-in-one-seo-pack' ),
57
+ 'public_figure' => __( 'Public Figure', 'all-in-one-seo-pack' ),
58
+ ),
59
+ 'Places' => array(
60
+ 'city' => __( 'City', 'all-in-one-seo-pack' ),
61
+ 'country' => __( 'Country', 'all-in-one-seo-pack' ),
62
+ 'landmark' => __( 'Landmark', 'all-in-one-seo-pack' ),
63
+ 'state_province' => __( 'State Province', 'all-in-one-seo-pack' ),
64
+ ),
65
+ 'Products and Entertainment' => array(
66
+ 'album' => __( 'Album', 'all-in-one-seo-pack' ),
67
+ 'book' => __( 'Book', 'all-in-one-seo-pack' ),
68
+ 'drink' => __( 'Drink', 'all-in-one-seo-pack' ),
69
+ 'food' => __( 'Food', 'all-in-one-seo-pack' ),
70
+ 'game' => __( 'Game', 'all-in-one-seo-pack' ),
71
+ 'movie' => __( 'Movie', 'all-in-one-seo-pack' ),
72
+ 'product' => __( 'Product', 'all-in-one-seo-pack' ),
73
+ 'song' => __( 'Song', 'all-in-one-seo-pack' ),
74
+ 'tv_show' => __( 'TV Show', 'all-in-one-seo-pack' ),
75
+ 'episode' => __( 'Episode', 'all-in-one-seo-pack' ),
76
+ ),
77
+ 'Websites' => array(
78
+ 'article' => __( 'Article', 'all-in-one-seo-pack' ),
79
+ 'blog' => __( 'Blog', 'all-in-one-seo-pack' ),
80
+ 'website' => __( 'Website', 'all-in-one-seo-pack' ),
81
+ ),
82
+ );
83
+ parent::__construct();
84
+
85
+ $this->help_text = array(
86
+ 'setmeta' => __( 'Checking this box will use the Home Title and Home Description set in All in One SEO Pack, General Settings as the Open Graph title and description for your home page.', 'all-in-one-seo-pack' ),
87
+ 'key' => __( 'Enter your Facebook Admin ID here. You can enter multiple IDs separated by a comma. You can look up your Facebook ID using this tool http://findmyfbid.com/', 'all-in-one-seo-pack' ),
88
+ 'appid' => __( 'Enter your Facebook App ID here. Information about how to get your Facebook App ID can be found at https://developers.facebook.com/docs/apps/register', 'all-in-one-seo-pack' ),
89
+ 'title_shortcodes' => __( 'Run shortcodes that appear in social title meta tags.', 'all-in-one-seo-pack' ),
90
+ 'description_shortcodes' => __( 'Run shortcodes that appear in social description meta tags.', 'all-in-one-seo-pack' ),
91
+ 'sitename' => __( 'The Site Name is the name that is used to identify your website.', 'all-in-one-seo-pack' ),
92
+ 'hometitle' => __( 'The Home Title is the Open Graph title for your home page.', 'all-in-one-seo-pack' ),
93
+ 'description' => __( 'The Home Description is the Open Graph description for your home page.', 'all-in-one-seo-pack' ),
94
+ 'homeimage' => __( 'The Home Image is the Open Graph image for your home page.', 'all-in-one-seo-pack' ),
95
+ 'generate_descriptions' => __( 'This option will auto generate your Open Graph descriptions from your post content instead of your post excerpt. WooCommerce users should read the documentation regarding this setting.', 'all-in-one-seo-pack' ),
96
+ 'defimg' => __( 'This option lets you choose which image will be displayed by default for the Open Graph image. You may override this on individual posts.', 'all-in-one-seo-pack' ),
97
+ 'fallback' => __( 'This option lets you fall back to the default image if no image could be found above.', 'all-in-one-seo-pack' ),
98
+ 'dimg' => __( 'This option sets a default image that can be used for the Open Graph image. You can upload an image, select an image from your Media Library or paste the URL of an image here.', 'all-in-one-seo-pack' ),
99
+ 'dimgwidth' => __( 'This option lets you set a default width for your images, where unspecified.', 'all-in-one-seo-pack' ),
100
+ 'dimgheight' => __( 'This option lets you set a default height for your images, where unspecified.', 'all-in-one-seo-pack' ),
101
+ 'meta_key' => __( 'Enter the name of a custom field (or multiple field names separated by commas) to use that field to specify the Open Graph image on Pages or Posts.', 'all-in-one-seo-pack' ),
102
+ 'image' => __( 'This option lets you select the Open Graph image that will be used for this Page or Post, overriding the default settings.', 'all-in-one-seo-pack' ),
103
+ 'customimg' => __( 'This option lets you upload an image to use as the Open Graph image for this Page or Post.', 'all-in-one-seo-pack' ),
104
+ 'imagewidth' => __( 'Enter the width for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
105
+ 'imageheight' => __( 'Enter the height for your Open Graph image in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
106
+ 'video' => __( 'This option lets you specify a link to the Open Graph video used on this Page or Post.', 'all-in-one-seo-pack' ),
107
+ 'videowidth' => __( 'Enter the width for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
108
+ 'videoheight' => __( 'Enter the height for your Open Graph video in pixels (i.e. 600).', 'all-in-one-seo-pack' ),
109
+ 'defcard' => __( 'Select the default type of Twitter Card to display.', 'all-in-one-seo-pack' ),
110
+ 'setcard' => __( 'Select the Twitter Card type to use for this Page or Post, overriding the default setting.', 'all-in-one-seo-pack' ),
111
+ 'twitter_site' => __( 'Enter the Twitter username associated with your website here.', 'all-in-one-seo-pack' ),
112
+ 'twitter_creator' => __( 'Allows your authors to be identified by their Twitter usernames as content creators on the Twitter cards for their posts.', 'all-in-one-seo-pack' ),
113
+ 'twitter_domain' => __( 'Enter the name of your website here.', 'all-in-one-seo-pack' ),
114
+ 'customimg_twitter' => __( 'This option lets you upload an image to use as the Twitter image for this Page or Post.', 'all-in-one-seo-pack' ),
115
+ 'gen_tags' => __( 'Automatically generate article tags for Facebook type article when not provided.', 'all-in-one-seo-pack' ),
116
+ 'gen_keywords' => __( 'Use keywords in generated article tags.', 'all-in-one-seo-pack' ),
117
+ 'gen_categories' => __( 'Use categories in generated article tags.', 'all-in-one-seo-pack' ),
118
+ 'gen_post_tags' => __( 'Use post tags in generated article tags.', 'all-in-one-seo-pack' ),
119
+ 'types' => __( 'Select which Post Types you want to use All in One SEO Pack to set Open Graph meta values for.', 'all-in-one-seo-pack' ),
120
+ 'title' => __( 'This is the Open Graph title of this Page or Post.', 'all-in-one-seo-pack' ),
121
+ 'desc' => __( 'This is the Open Graph description of this Page or Post.', 'all-in-one-seo-pack' ),
122
+ 'category' => __( 'Select the Open Graph type that best describes the content of this Page or Post.', 'all-in-one-seo-pack' ),
123
+ 'facebook_debug' => __( 'Press this button to have Facebook re-fetch and debug this page.', 'all-in-one-seo-pack' ),
124
+ 'section' => __( 'This Open Graph meta allows you to add a general section name that best describes this content.', 'all-in-one-seo-pack' ),
125
+ 'tag' => __( 'This Open Graph meta allows you to add a list of keywords that best describe this content.', 'all-in-one-seo-pack' ),
126
+ 'facebook_publisher' => __( 'Link articles to the Facebook page associated with your website.', 'all-in-one-seo-pack' ),
127
+ 'facebook_author' => __( 'Allows your authors to be identified by their Facebook pages as content authors on the Opengraph meta for their articles.', 'all-in-one-seo-pack' ),
128
+ 'person_or_org' => __( 'Are the social profile links for your website for a person or an organization?', 'all-in-one-seo-pack' ),
129
+ 'profile_links' => __( "Add URLs for your website's social profiles here (Facebook, Twitter, Google+, Instagram, LinkedIn), one per line.", 'all-in-one-seo-pack' ),
130
+ 'social_name' => __( 'Add the name of the person or organization who owns these profiles.', 'all-in-one-seo-pack' ),
131
+ );
132
+
133
+ $this->help_anchors = array(
134
+ 'title_shortcodes' => '#run-shortcodes-in-title',
135
+ 'description_shortcodes' => '#run-shortcodes-in-description',
136
+ 'generate_descriptions' => '#auto-generate-og-descriptions',
137
+ 'setmeta' => '#use-aioseo-title-and-description',
138
+ 'sitename' => '#site-name',
139
+ 'hometitle' => '#home-title-and-description',
140
+ 'description' => '#home-title-and-description',
141
+ 'homeimage' => '#home-image',
142
+ 'defimg' => '#select-og-image-source',
143
+ 'fallback' => '#use-default-if-no-image-found',
144
+ 'dimg' => '#default-og-image',
145
+ 'dimgwidth' => '#default-image-width',
146
+ 'dimgheight' => '#default-image-height',
147
+ 'meta_key' => '#use-custom-field-for-image',
148
+ 'profile_links' => '#social-profile-links',
149
+ 'person_or_org' => '#social-profile-links',
150
+ 'social_name' => '#social-profile-links',
151
+ 'key' => '#facebook-admin-id',
152
+ 'appid' => '#facebook-app-id',
153
+ 'gen_tags' => '#automatically-generate-article-tags',
154
+ 'gen_keywords' => '#use-keywords-in-article-tags',
155
+ 'gen_categories' => '#use-categories-in-article-tags',
156
+ 'gen_post_tags' => '#use-post-tags-in-article-tags',
157
+ 'facebook_publisher' => '#show-facebook-publisher-on-articles',
158
+ 'facebook_author' => '#show-facebook-author-on-articles',
159
+ 'types' => '#enable-facebook-meta-for',
160
+ 'defcard' => '#default-twitter-card',
161
+ 'twitter_site' => '#twitter-site',
162
+ 'twitter_creator' => '#show-twitter-author',
163
+ 'twitter_domain' => '#twitter-domain',
164
+ 'scan_header' => '#scan-social-meta',
165
+ 'title' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#title',
166
+ 'desc' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#description',
167
+ 'image' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#image',
168
+ 'customimg' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-image',
169
+ 'imagewidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height',
170
+ 'imageheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-image-width-height',
171
+ 'video' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-video',
172
+ 'videowidth' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height',
173
+ 'videoheight' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#specify-video-width-height',
174
+ 'category' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-object-type',
175
+ 'facebook_debug' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#facebook-debug',
176
+ 'section' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-section',
177
+ 'tag' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#article-tags',
178
+ 'setcard' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#twitter-card-type',
179
+ 'customimg_twitter' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/#custom-twitter-image',
180
+ );
181
+
182
+ if ( is_admin() ) {
183
+ add_action( 'admin_init', array( $this, 'admin_init' ), 5 );
184
+ } else {
185
+ add_action( 'wp', array( $this, 'type_setup' ) );
186
+ }
187
+
188
+ if ( ! is_admin() || defined( 'DOING_AJAX' ) ) {
189
+ $this->do_opengraph();
190
+ }
191
+ // Set variables after WordPress load.
192
+ add_action( 'init', array( &$this, 'init' ), 999999 );
193
+ add_filter( 'jetpack_enable_open_graph', '__return_false' ); // Avoid having duplicate meta tags
194
+ // Force refresh of Facebook cache.
195
+ add_action( 'post_updated', array( &$this, 'force_fb_refresh_update' ), 10, 3 );
196
+ add_action( 'transition_post_status', array( &$this, 'force_fb_refresh_transition' ), 10, 3 );
197
+ add_action( 'edited_term', array( &$this, 'save_tax_data' ), 10, 3 );
198
+ // Adds special filters
199
+ add_filter( 'aioseop_opengraph_placeholder', array( &$this, 'filter_placeholder' ) );
200
+ add_action( 'aiosp_activate_opengraph', array( $this, 'activate_module' ) );
201
+ add_action( 'created_term', array( $this, 'created_term' ), 10, 3 );
202
+ // Call to init to generate menus
203
+ $this->init();
204
+ }
205
+
206
+ /**
207
+ * Sets the terms defaults after a new term is created.
208
+ *
209
+ * @param int $term_id Term ID.
210
+ * @param int $tt_id Term taxonomy ID.
211
+ * @param string $taxonomy Taxonomy slug.
212
+ */
213
+ function created_term( $term_id, $tt_id, $taxonomy_name ) {
214
+ $k = 'settings';
215
+ $prefix = $this->get_prefix( $k );
216
+ $tax = get_taxonomy( $taxonomy_name );
217
+ $this->set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, false, array( $term_id ) );
218
+ }
219
+
220
+ /**
221
+ * Sets the defaults for a taxonomy.
222
+ *
223
+ * @param string $prefix The prefix of this module.
224
+ * @param string $k The key against which the options will be determined/set.
225
+ * @param string $taxonomy_name The name of the taxonomy.
226
+ * @param Object $tax The taxonomy object.
227
+ * @param bool $bail_if_no_terms Bail if the taxonomy has no terms.
228
+ * @param array $terms The terms in the taxonomy.
229
+ */
230
+ private function set_object_type_for_taxonomy( $prefix, $k, $taxonomy_name, $tax, $bail_if_no_terms = false, $terms = null ) {
231
+ $object_type = null;
232
+ if ( ! $terms ) {
233
+ $terms = get_terms( $taxonomy_name, array(
234
+ 'meta_query' => array(
235
+ array(
236
+ 'key' => '_' . $prefix . $k,
237
+ 'compare' => 'NOT EXISTS',
238
+ )
239
+ ),
240
+ 'number' => PHP_INT_MAX,
241
+ 'fields' => 'ids',
242
+ 'hide_empty' => false,
243
+ ) );
244
+ }
245
+
246
+ if ( empty( $terms ) && $bail_if_no_terms ) {
247
+ return false;
248
+ }
249
+
250
+ if ( true === $tax->_builtin ) {
251
+ $object_type = 'article';
252
+ } else {
253
+ // custom taxonomy. Let's get a post against this to determine its post type.
254
+ $posts = get_posts( array(
255
+ 'numberposts' => 1,
256
+ 'post_type' => 'any',
257
+ 'tax_query' => array(
258
+ array(
259
+ 'taxonomy' => $taxonomy_name,
260
+ 'field' => 'term_id',
261
+ 'terms' => $terms
262
+ ),
263
+ ),
264
+ ) );
265
+ if ( $posts ) {
266
+ global $aioseop_options;
267
+ $post_type = $posts[0]->post_type;
268
+ if ( isset( $aioseop_options['modules'] ) && isset( $aioseop_options['modules'][ $this->prefix . 'options' ] ) ) {
269
+ $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ];
270
+
271
+ // now let's see what default object type is set for this post type.
272
+ $object_type_set = $og_options[ $this->prefix . $post_type . '_fb_object_type' ];
273
+ if ( ! empty( $object_type_set ) ) {
274
+ $object_type = $object_type_set;
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ if ( $object_type ) {
281
+ $opts[ $prefix . $k .'_category' ] = $object_type;
282
+ foreach ( $terms as $term_id ) {
283
+ update_term_meta( $term_id, '_' . $prefix . $k, $opts );
284
+ }
285
+ }
286
+
287
+ return true;
288
+ }
289
+
290
+ /**
291
+ * Called when this module is activated.
292
+ */
293
+ public function activate_module() {
294
+ if ( $this->locations !== null ) {
295
+ foreach ( $this->locations as $k => $v ) {
296
+ if ( ! isset( $v['type'] ) || 'metabox' !== $v['type'] ) {
297
+ continue;
298
+ }
299
+ $this->set_virgin_tax_terms( $k );
300
+ }
301
+ }
302
+ }
303
+ /**
304
+ * This iterates over all taxonomies that do not have a opengraph setting defined and sets the defaults.
305
+ *
306
+ * @param string $k The key against which the options will be determined/set.
307
+ */
308
+ private function set_virgin_tax_terms( $k ) {
309
+ $prefix = $this->get_prefix( $k );
310
+ $opts = $this->default_options( $k );
311
+ $taxonomies = get_taxonomies( array( 'public' => true ), 'object' );
312
+ if ( ! $taxonomies ) {
313
+ return;
314
+ }
315
+ foreach ( $taxonomies as $name => $tax ) {
316
+ $this->set_object_type_for_taxonomy( $prefix, $k, $name, $tax, true, null );
317
+
318
+
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Hook called after WordPress has been loaded.
324
+ *
325
+ * @since 2.4.14
326
+ */
327
+ public function init() {
328
+ $count_desc = __( ' characters. Open Graph allows up to a maximum of %1$s chars for the %2$s.', 'all-in-one-seo-pack' );
329
+ // Create default options
330
+ $this->default_options = array(
331
+ 'scan_header' => array(
332
+ 'name' => __( 'Scan Header', 'all-in-one-seo-pack' ),
333
+ 'type' => 'custom',
334
+ 'save' => true,
335
+ ),
336
+ 'setmeta' => array(
337
+ 'name' => __( 'Use AIOSEO Title and Description', 'all-in-one-seo-pack' ),
338
+ 'type' => 'checkbox',
339
+ ),
340
+ 'key' => array(
341
+ 'name' => __( 'Facebook Admin ID', 'all-in-one-seo-pack' ),
342
+ 'default' => '',
343
+ 'type' => 'text',
344
+ ),
345
+ 'appid' => array(
346
+ 'name' => __( 'Facebook App ID', 'all-in-one-seo-pack' ),
347
+ 'default' => '',
348
+ 'type' => 'text',
349
+ ),
350
+ 'title_shortcodes' => array(
351
+ 'name' => __( 'Run Shortcodes In Title', 'all-in-one-seo-pack' ),
352
+ ),
353
+ 'description_shortcodes' => array(
354
+ 'name' => __( 'Run Shortcodes In Description', 'all-in-one-seo-pack' ),
355
+ ),
356
+ 'sitename' => array(
357
+ 'name' => __( 'Site Name', 'all-in-one-seo-pack' ),
358
+ 'default' => get_bloginfo( 'name' ),
359
+ 'type' => 'text',
360
+ ),
361
+ 'hometitle' => array(
362
+ 'name' => __( 'Home Title', 'all-in-one-seo-pack' ),
363
+ 'default' => '',
364
+ 'type' => 'textarea',
365
+ 'condshow' => array(
366
+ 'aiosp_opengraph_setmeta' => array(
367
+ 'lhs' => 'aiosp_opengraph_setmeta',
368
+ 'op' => '!=',
369
+ 'rhs' => 'on',
370
+ ),
371
+ ),
372
+ ),
373
+ 'description' => array(
374
+ 'name' => __( 'Home Description', 'all-in-one-seo-pack' ),
375
+ 'default' => '',
376
+ 'type' => 'textarea',
377
+ 'condshow' => array(
378
+ 'aiosp_opengraph_setmeta' => array(
379
+ 'lhs' => 'aiosp_opengraph_setmeta',
380
+ 'op' => '!=',
381
+ 'rhs' => 'on',
382
+ ),
383
+ ),
384
+ ),
385
+ 'homeimage' => array(
386
+ 'name' => __( 'Home Image', 'all-in-one-seo-pack' ),
387
+ 'type' => 'image',
388
+ ),
389
+ 'generate_descriptions' => array(
390
+ 'name' => __( 'Use Content For Autogenerated OG Descriptions', 'all-in-one-seo-pack' ),
391
+ 'default' => 0,
392
+ ),
393
+ 'defimg' => array(
394
+ 'name' => __( 'Select OG:Image Source', 'all-in-one-seo-pack' ),
395
+ 'type' => 'select',
396
+ 'initial_options' => array(
397
+ '' => __( 'Default Image' ),
398
+ 'featured' => __( 'Featured Image' ),
399
+ 'attach' => __( 'First Attached Image' ),
400
+ 'content' => __( 'First Image In Content' ),
401
+ 'custom' => __( 'Image From Custom Field' ),
402
+ 'author' => __( 'Post Author Image' ),
403
+ 'auto' => __( 'First Available Image' ),
404
+ ),
405
+ ),
406
+ 'fallback' => array(
407
+ 'name' => __( 'Use Default If No Image Found', 'all-in-one-seo-pack' ),
408
+ 'type' => 'checkbox',
409
+ ),
410
+ 'dimg' => array(
411
+ 'name' => __( 'Default OG:Image', 'all-in-one-seo-pack' ),
412
+ 'default' => AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png',
413
+ 'type' => 'image',
414
+ ),
415
+ 'dimgwidth' => array(
416
+ 'name' => __( 'Default Image Width', 'all-in-one-seo-pack' ),
417
+ 'type' => 'text',
418
+ 'default' => '',
419
+ ),
420
+ 'dimgheight' => array(
421
+ 'name' => __( 'Default Image Height', 'all-in-one-seo-pack' ),
422
+ 'type' => 'text',
423
+ 'default' => '',
424
+ ),
425
+ 'meta_key' => array(
426
+ 'name' => __( 'Use Custom Field For Image', 'all-in-one-seo-pack' ),
427
+ 'type' => 'text',
428
+ 'default' => '',
429
+ ),
430
+ 'image' => array(
431
+ 'name' => __( 'Image', 'all-in-one-seo-pack' ),
432
+ 'type' => 'radio',
433
+ 'initial_options' => array(
434
+ 0 => '<img style="width:50px;height:auto;display:inline-block;vertical-align:bottom;" src="' . AIOSEOP_PLUGIN_IMAGES_URL . 'default-user-image.png' . '">',
435
+ ),
436
+ ),
437
+ 'customimg' => array(
438
+ 'name' => __( 'Custom Image', 'all-in-one-seo-pack' ),
439
+ 'type' => 'image',
440
+ ),
441
+ 'imagewidth' => array(
442
+ 'name' => __( 'Specify Image Width', 'all-in-one-seo-pack' ),
443
+ 'type' => 'text',
444
+ 'default' => '',
445
+ ),
446
+ 'imageheight' => array(
447
+ 'name' => __( 'Specify Image Height', 'all-in-one-seo-pack' ),
448
+ 'type' => 'text',
449
+ 'default' => '',
450
+ ),
451
+ 'video' => array(
452
+ 'name' => __( 'Custom Video', 'all-in-one-seo-pack' ),
453
+ 'type' => 'text',
454
+ ),
455
+ 'videowidth' => array(
456
+ 'name' => __( 'Specify Video Width', 'all-in-one-seo-pack' ),
457
+ 'type' => 'text',
458
+ 'default' => '',
459
+ 'condshow' => array(
460
+ 'aioseop_opengraph_settings_video' => array(
461
+ 'lhs' => 'aioseop_opengraph_settings_video',
462
+ 'op' => '!=',
463
+ 'rhs' => '',
464
+ ),
465
+ ),
466
+ ),
467
+ 'videoheight' => array(
468
+ 'name' => __( 'Specify Video Height', 'all-in-one-seo-pack' ),
469
+ 'type' => 'text',
470
+ 'default' => '',
471
+ 'condshow' => array(
472
+ 'aioseop_opengraph_settings_video' => array(
473
+ 'lhs' => 'aioseop_opengraph_settings_video',
474
+ 'op' => '!=',
475
+ 'rhs' => '',
476
+ ),
477
+ ),
478
+ ),
479
+ 'defcard' => array(
480
+ 'name' => __( 'Default Twitter Card', 'all-in-one-seo-pack' ),
481
+ 'type' => 'select',
482
+ 'default' => 'summary',
483
+ 'initial_options' => array(
484
+ 'summary' => __( 'Summary', 'all-in-one-seo-pack' ),
485
+ 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ),
486
+
487
+ /*
488
+ REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE
489
+ 'photo' => __( 'Photo', 'all-in-one-seo-pack' )
490
+ */
491
+ ),
492
+ ),
493
+ 'setcard' => array(
494
+ 'name' => __( 'Twitter Card Type', 'all-in-one-seo-pack' ),
495
+ 'type' => 'select',
496
+ 'initial_options' => array(
497
+ 'summary_large_image' => __( 'Summary Large Image', 'all-in-one-seo-pack' ),
498
+ 'summary' => __( 'Summary', 'all-in-one-seo-pack' ),
499
+
500
+ /*
501
+ REMOVING THIS TWITTER CARD TYPE FROM SOCIAL META MODULE
502
+ 'photo' => __( 'Photo', 'all-in-one-seo-pack' )
503
+ */
504
+ ),
505
+ ),
506
+ 'twitter_site' => array(
507
+ 'name' => __( 'Twitter Site', 'all-in-one-seo-pack' ),
508
+ 'type' => 'text',
509
+ 'default' => '',
510
+ ),
511
+ 'twitter_creator' => array(
512
+ 'name' => __( 'Show Twitter Author', 'all-in-one-seo-pack' ),
513
+ ),
514
+ 'twitter_domain' => array(
515
+ 'name' => __( 'Twitter Domain', 'all-in-one-seo-pack' ),
516
+ 'type' => 'text',
517
+ 'default' => '',
518
+ ),
519
+ 'customimg_twitter' => array(
520
+ 'name' => __( 'Custom Twitter Image', 'all-in-one-seo-pack' ),
521
+ 'type' => 'image',
522
+ ),
523
+ 'gen_tags' => array(
524
+ 'name' => __( 'Automatically Generate Article Tags', 'all-in-one-seo-pack' ),
525
+ ),
526
+ 'gen_keywords' => array(
527
+ 'name' => __( 'Use Keywords In Article Tags', 'all-in-one-seo-pack' ),
528
+ 'default' => 'on',
529
+ 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
530
+ ),
531
+ 'gen_categories' => array(
532
+ 'name' => __( 'Use Categories In Article Tags', 'all-in-one-seo-pack' ),
533
+ 'default' => 'on',
534
+ 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
535
+ ),
536
+ 'gen_post_tags' => array(
537
+ 'name' => __( 'Use Post Tags In Article Tags', 'all-in-one-seo-pack' ),
538
+ 'default' => 'on',
539
+ 'condshow' => array( 'aiosp_opengraph_gen_tags' => 'on' ),
540
+ ),
541
+ 'types' => array(
542
+ 'name' => __( 'Enable Facebook Meta for Post Types', 'all-in-one-seo-pack' ),
543
+ 'type' => 'multicheckbox',
544
+ 'default' => array( 'post' => 'post', 'page' => 'page' ),
545
+ 'initial_options' => $this->get_post_type_titles( array( '_builtin' => false ) ),
546
+ ),
547
+ 'title' => array(
548
+ 'name' => __( 'Title', 'all-in-one-seo-pack' ),
549
+ 'default' => '',
550
+ 'type' => 'text',
551
+ 'size' => 95,
552
+ 'count' => 1,
553
+ 'count_desc' => $count_desc,
554
+ ),
555
+ 'desc' => array(
556
+ 'name' => __( 'Description', 'all-in-one-seo-pack' ),
557
+ 'default' => '',
558
+ 'type' => 'textarea',
559
+ 'cols' => 250,
560
+ 'rows' => 4,
561
+ 'count' => 1,
562
+ 'count_desc' => $count_desc,
563
+ ),
564
+ 'category' => array(
565
+ 'name' => __( 'Facebook Object Type', 'all-in-one-seo-pack' ),
566
+ 'type' => 'select',
567
+ 'style' => '',
568
+ 'default' => '',
569
+ 'initial_options' => $this->fb_object_types,
570
+ ),
571
+ 'facebook_debug' => array(
572
+ 'name' => __( 'Facebook Debug', 'all-in-one-seo-pack' ),
573
+ 'type' => 'html',
574
+ 'save' => false,
575
+ 'default' => '<a
576
+ name="aioseop_opengraph_settings_facebook_debug"
577
+ id="aioseop_opengraph_settings_facebook_debug"
578
+ class="button-primary"
579
+ href=""
580
+ target="_blank">' . __( 'Debug This Post', 'all-in-one-seo-pack' ) . '</a>',
581
+ ),
582
+ 'section' => array(
583
+ 'name' => __( 'Article Section', 'all-in-one-seo-pack' ),
584
+ 'type' => 'text',
585
+ 'default' => '',
586
+ 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ),
587
+ ),
588
+ 'tag' => array(
589
+ 'name' => __( 'Article Tags', 'all-in-one-seo-pack' ),
590
+ 'type' => 'text',
591
+ 'default' => '',
592
+ 'condshow' => array( 'aioseop_opengraph_settings_category' => 'article' ),
593
+ ),
594
+ 'facebook_publisher' => array(
595
+ 'name' => __( 'Show Facebook Publisher on Articles', 'all-in-one-seo-pack' ),
596
+ 'type' => 'text',
597
+ 'default' => '',
598
+ ),
599
+ 'facebook_author' => array(
600
+ 'name' => __( 'Show Facebook Author on Articles', 'all-in-one-seo-pack' ),
601
+ ),
602
+ 'profile_links' => array(
603
+ 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ),
604
+ 'type' => 'textarea',
605
+ 'cols' => 60,
606
+ 'rows' => 5,
607
+ ),
608
+ 'person_or_org' => array(
609
+ 'name' => __( 'Person or Organization?', 'all-in-one-seo-pack' ),
610
+ 'type' => 'radio',
611
+ 'initial_options' => array(
612
+ 'person' => __( 'Person', 'all-in-one-seo-pack' ),
613
+ 'org' => __( 'Organization', 'all-in-one-seo-pack' ),
614
+ ),
615
+ ),
616
+ 'social_name' => array(
617
+ 'name' => __( 'Associated Name', 'all-in-one-seo-pack' ),
618
+ 'type' => 'text',
619
+ 'default' => '',
620
+ ),
621
+ );
622
+ // load initial options / set defaults
623
+ $this->update_options();
624
+ $display = array();
625
+ if ( isset( $this->options['aiosp_opengraph_types'] ) && ! empty( $this->options['aiosp_opengraph_types'] ) ) {
626
+ $display = $this->options['aiosp_opengraph_types'];
627
+ }
628
+ $this->locations = array(
629
+ 'opengraph' => array(
630
+ 'name' => $this->name,
631
+ 'prefix' => 'aiosp_',
632
+ 'type' => 'settings',
633
+ 'options' => array(
634
+ 'scan_header',
635
+ 'setmeta',
636
+ 'key',
637
+ 'appid',
638
+ 'sitename',
639
+ 'title_shortcodes',
640
+ 'description_shortcodes',
641
+ 'hometitle',
642
+ 'description',
643
+ 'homeimage',
644
+ 'generate_descriptions',
645
+ 'defimg',
646
+ 'fallback',
647
+ 'dimg',
648
+ 'dimgwidth',
649
+ 'dimgheight',
650
+ 'meta_key',
651
+ 'defcard',
652
+ 'profile_links',
653
+ 'person_or_org',
654
+ 'social_name',
655
+ 'twitter_site',
656
+ 'twitter_creator',
657
+ 'twitter_domain',
658
+ 'gen_tags',
659
+ 'gen_keywords',
660
+ 'gen_categories',
661
+ 'gen_post_tags',
662
+ 'types',
663
+ 'facebook_publisher',
664
+ 'facebook_author',
665
+ ),
666
+ ),
667
+ 'settings' => array(
668
+ 'name' => __( 'Social Settings', 'all-in-one-seo-pack' ),
669
+ 'type' => 'metabox',
670
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-settings-individual-pagepost-settings/',
671
+ 'options' => array(
672
+ 'title',
673
+ 'desc',
674
+ 'image',
675
+ 'customimg',
676
+ 'imagewidth',
677
+ 'imageheight',
678
+ 'video',
679
+ 'videowidth',
680
+ 'videoheight',
681
+ 'category',
682
+ 'facebook_debug',
683
+ 'section',
684
+ 'tag',
685
+ 'setcard',
686
+ 'customimg_twitter',
687
+ ),
688
+ 'display' => apply_filters( 'aioseop_opengraph_display', $display ),
689
+ 'prefix' => 'aioseop_opengraph_',
690
+ ),
691
+ );
692
+ $this->layout = array(
693
+ 'home' => array(
694
+ 'name' => __( 'Home Page Settings', 'all-in-one-seo-pack' ),
695
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#use-aioseo-title-and-description',
696
+ 'options' => array( 'setmeta', 'sitename', 'hometitle', 'description', 'homeimage' ),
697
+ ),
698
+ 'image' => array(
699
+ 'name' => __( 'Image Settings', 'all-in-one-seo-pack' ),
700
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#select-og-image-source',
701
+ 'options' => array( 'defimg', 'fallback', 'dimg', 'dimgwidth', 'dimgheight', 'meta_key' ),
702
+ ),
703
+ 'links' => array(
704
+ 'name' => __( 'Social Profile Links', 'all-in-one-seo-pack' ),
705
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#social-profile-links',
706
+ 'options' => array( 'profile_links', 'person_or_org', 'social_name' ),
707
+ ),
708
+ 'facebook' => array(
709
+ 'name' => __( 'Facebook Settings', 'all-in-one-seo-pack' ),
710
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#facebook-settings',
711
+ 'options' => array(
712
+ 'key',
713
+ 'appid',
714
+ 'types',
715
+ 'gen_tags',
716
+ 'gen_keywords',
717
+ 'gen_categories',
718
+ 'gen_post_tags',
719
+ 'facebook_publisher',
720
+ 'facebook_author',
721
+ ),
722
+ ),
723
+ 'twitter' => array(
724
+ 'name' => __( 'Twitter Settings', 'all-in-one-seo-pack' ),
725
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#default-twitter-card',
726
+ 'options' => array( 'defcard', 'setcard', 'twitter_site', 'twitter_creator', 'twitter_domain' ),
727
+ ),
728
+ 'default' => array(
729
+ 'name' => __( 'Advanced Settings', 'all-in-one-seo-pack' ),
730
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/',
731
+ 'options' => array(), // this is set below, to the remaining options -- pdb
732
+ ),
733
+ 'scan_meta' => array(
734
+ 'name' => __( 'Scan Social Meta', 'all-in-one-seo-pack' ),
735
+ 'help_link' => 'https://semperplugins.com/documentation/social-meta-module/#scan_meta',
736
+ 'options' => array( 'scan_header' ),
737
+ ),
738
+ );
739
+ $other_options = array();
740
+ foreach ( $this->layout as $k => $v ) {
741
+ $other_options = array_merge( $other_options, $v['options'] );
742
+ }
743
+
744
+ $this->layout['default']['options'] = array_diff( array_keys( $this->default_options ), $other_options );
745
+ }
746
+
747
+ /**
748
+ * Forces FaceBook OpenGraph to refresh its cache when a post is changed to
749
+ *
750
+ * @param $new_status
751
+ * @param $old_status
752
+ * @param $post
753
+ *
754
+ * @todo this and force_fb_refresh_update can probably have the remote POST extracted out.
755
+ *
756
+ * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update
757
+ * @since 2.3.11
758
+ */
759
+ function force_fb_refresh_transition( $new_status, $old_status, $post ) {
760
+ if ( 'publish' !== $new_status ) {
761
+ return;
762
+ }
763
+ if ( 'future' !== $old_status ) {
764
+ return;
765
+ }
766
+
767
+ $current_post_type = get_post_type();
768
+
769
+ // Only ping Facebook if Social SEO is enabled on this post type.
770
+ if ( $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) {
771
+ $post_url = aioseop_get_permalink( $post->ID );
772
+ $endpoint = sprintf(
773
+ 'https://graph.facebook.com/?%s', http_build_query(
774
+ array(
775
+ 'id' => $post_url,
776
+ 'scrape' => true,
777
+ )
778
+ )
779
+ );
780
+ wp_remote_post( $endpoint, array( 'blocking' => false ) );
781
+ }
782
+ }
783
+
784
+ /**
785
+ * Forces FaceBook OpenGraph refresh on update.
786
+ *
787
+ * @param $post_id
788
+ * @param $post_after
789
+ *
790
+ * @see https://developers.facebook.com/docs/sharing/opengraph/using-objects#update
791
+ * @since 2.3.11
792
+ */
793
+ function force_fb_refresh_update( $post_id, $post_after ) {
794
+
795
+ $current_post_type = get_post_type();
796
+
797
+ // Only ping Facebook if Social SEO is enabled on this post type.
798
+ if ( 'publish' === $post_after->post_status && $this->option_isset( 'types' ) && is_array( $this->options['aiosp_opengraph_types'] ) && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] ) ) {
799
+ $post_url = aioseop_get_permalink( $post_id );
800
+ $endpoint = sprintf(
801
+ 'https://graph.facebook.com/?%s', http_build_query(
802
+ array(
803
+ 'id' => $post_url,
804
+ 'scrape' => true,
805
+ )
806
+ )
807
+ );
808
+ wp_remote_post( $endpoint, array( 'blocking' => false ) );
809
+ }
810
+ }
811
+
812
+ function settings_page_init() {
813
+ add_filter( 'aiosp_output_option', array( $this, 'display_custom_options' ), 10, 2 );
814
+ }
815
+
816
+ function filter_options( $options, $location ) {
817
+ if ( $location == 'settings' ) {
818
+ $prefix = $this->get_prefix( $location ) . $location . '_';
819
+ list( $legacy, $images ) = $this->get_all_images( $options );
820
+ if ( isset( $options ) && isset( $options["{$prefix}image"] ) ) {
821
+ $thumbnail = $options["{$prefix}image"];
822
+ if ( ctype_digit( (string) $thumbnail ) || ( $thumbnail == 'post' ) ) {
823
+ if ( $thumbnail == 'post' ) {
824
+ $thumbnail = $images['post1'];
825
+ } elseif ( ! empty( $legacy[ $thumbnail ] ) ) {
826
+ $thumbnail = $legacy[ $thumbnail ];
827
+ }
828
+ }
829
+ $options["{$prefix}image"] = $thumbnail;
830
+ }
831
+ if ( empty( $options[ $prefix . 'image' ] ) ) {
832
+ $img = array_keys( $images );
833
+ if ( ! empty( $img ) && ! empty( $img[1] ) ) {
834
+ $options[ $prefix . 'image' ] = $img[1];
835
+ }
836
+ }
837
+ }
838
+
839
+ return $options;
840
+ }
841
+
842
+ /**
843
+ * Applies filter to module settings.
844
+ *
845
+ * @since 2.3.11
846
+ * @since 2.4.14 Added filter for description and title placeholders.
847
+ * @since 2.3.15 do_shortcode on description.
848
+ *
849
+ * @see [plugin]\admin\aioseop_module_class.php > display_options()
850
+ */
851
+ function filter_settings( $settings, $location, $current ) {
852
+ global $aiosp, $post;
853
+ if ( $location == 'opengraph' || $location == 'settings' ) {
854
+ $prefix = $this->get_prefix( $location ) . $location . '_';
855
+ if ( $location == 'opengraph' ) {
856
+ return $settings;
857
+ }
858
+ if ( $location == 'settings' ) {
859
+ list( $legacy, $settings[ $prefix . 'image' ]['initial_options'] ) = $this->get_all_images( $current );
860
+ $opts = array( 'title', 'desc' );
861
+ $current_post_type = get_post_type();
862
+ if ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) {
863
+ $flat_type_list = array();
864
+ foreach ( $this->fb_object_types as $k => $v ) {
865
+ if ( is_array( $v ) ) {
866
+ $flat_type_list = array_merge( $flat_type_list, $v );
867
+ } else {
868
+ $flat_type_list[ $k ] = $v;
869
+ }
870
+ }
871
+ $settings[ $prefix . 'category' ]['initial_options'] = array_merge(
872
+ array(
873
+ $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] => __( 'Default ', 'all-in-one-seo-pack' ) . ' - '
874
+ . $flat_type_list[ $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ],
875
+ ),
876
+ $settings[ $prefix . 'category' ]['initial_options']
877
+ );
878
+ }
879
+ if ( isset( $this->options['aiosp_opengraph_defcard'] ) ) {
880
+ $settings[ $prefix . 'setcard' ]['default'] = $this->options['aiosp_opengraph_defcard'];
881
+ }
882
+ $info = $aiosp->get_page_snippet_info();
883
+ $title = $info['title'];
884
+ $description = $info['description'];
885
+
886
+ // Description options
887
+ if ( is_object( $post ) ) {
888
+ // Always show excerpt
889
+ $description = empty( $this->options['aiosp_opengraph_generate_descriptions'] )
890
+ ? $aiosp->trim_excerpt_without_filters(
891
+ $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ),
892
+ 1000
893
+ )
894
+ : $aiosp->trim_excerpt_without_filters(
895
+ $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ),
896
+ 1000
897
+ );
898
+ }
899
+
900
+ // #1308 - we want to make sure we are ignoring php version only in the admin area while editing the post, so that it does not impact #932.
901
+ $screen = get_current_screen();
902
+ $ignore_php_version = is_admin() && isset( $screen->id ) && 'post' == $screen->id;
903
+
904
+ // Add filters
905
+ $description = apply_filters( 'aioseop_description', $description, false, $ignore_php_version );
906
+ // Add placholders
907
+ $settings[ "{$prefix}title" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $title );
908
+ $settings[ "{$prefix}desc" ]['placeholder'] = apply_filters( 'aioseop_opengraph_placeholder', $description );
909
+ }
910
+ if ( isset( $current[ $prefix . 'setmeta' ] ) && $current[ $prefix . 'setmeta' ] ) {
911
+ foreach ( $opts as $opt ) {
912
+ if ( isset( $settings[ $prefix . $opt ] ) ) {
913
+ $settings[ $prefix . $opt ]['type'] = 'hidden';
914
+ $settings[ $prefix . $opt ]['label'] = 'none';
915
+ $settings[ $prefix . $opt ]['help_text'] = '';
916
+ unset( $settings[ $prefix . $opt ]['count'] );
917
+ }
918
+ }
919
+ }
920
+ }
921
+
922
+ return $settings;
923
+ }
924
+
925
+ /**
926
+ * Applies filter to module options.
927
+ * These will display in the "Social Settings" object tab.
928
+ * filter:{prefix}override_options
929
+ *
930
+ * @since 2.3.11
931
+ * @since 2.4.14 Overrides empty og:type values.
932
+ *
933
+ * @see [plugin]\admin\aioseop_module_class.php > display_options()
934
+ *
935
+ * @global array $aioseop_options Plugin options.
936
+ *
937
+ * @param array $options Current options.
938
+ * @param string $location Location where filter is called.
939
+ * @param array $settings Settings.
940
+ *
941
+ * @return array
942
+ */
943
+ function override_options( $options, $location, $settings ) {
944
+ global $aioseop_options;
945
+ // Prepare default and prefix
946
+ $prefix = $this->get_prefix( $location ) . $location . '_';
947
+ $opts = array();
948
+
949
+ foreach ( $settings as $k => $v ) {
950
+ if ( $v['save'] ) {
951
+ $opts[ $k ] = $v['default'];
952
+ }
953
+ }
954
+ foreach ( $options as $k => $v ) {
955
+ switch ( $k ) {
956
+ case $prefix . 'category':
957
+ if ( empty( $v ) ) {
958
+ // Get post type
959
+ $type = isset( get_current_screen()->post_type )
960
+ ? get_current_screen()->post_type
961
+ : null;
962
+ // Assign default from plugin options
963
+ if ( ! empty( $type )
964
+ && isset( $aioseop_options['modules'] )
965
+ && isset( $aioseop_options['modules']['aiosp_opengraph_options'] )
966
+ && isset( $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ] )
967
+ ) {
968
+ $options[ $prefix . 'category' ] =
969
+ $aioseop_options['modules']['aiosp_opengraph_options'][ 'aiosp_opengraph_' . $type . '_fb_object_type' ];
970
+ }
971
+ continue;
972
+ }
973
+ break;
974
+ }
975
+ if ( $v === null ) {
976
+ unset( $options[ $k ] );
977
+ }
978
+ }
979
+ $options = wp_parse_args( $options, $opts );
980
+
981
+ return $options;
982
+ }
983
+
984
+ /**
985
+ * Applies filter to metabox settings before they are saved.
986
+ * Sets custom as default if a custom image is uploaded.
987
+ * filter:{prefix}filter_metabox_options
988
+ * filter:{prefix}filter_term_metabox_options
989
+ *
990
+ * @since 2.3.11
991
+ * @since 2.4.14 Fixes for aioseop-pro #67 and other bugs found.
992
+ *
993
+ * @see [plugin]\admin\aioseop_module_class.php > save_post_data()
994
+ * @see [this file] > save_tax_data()
995
+ *
996
+ * @param array $options List of current options.
997
+ * @param string $location Location where filter is called.
998
+ * @param int $id Either post_id or term_id.
999
+ *
1000
+ * @return array
1001
+ */
1002
+ function filter_metabox_options( $options, $location, $post_id ) {
1003
+ if ( $location == 'settings' ) {
1004
+ $prefix = $this->get_prefix( $location ) . $location . '_';
1005
+ if ( isset( $options[ $prefix . 'customimg_checker' ] )
1006
+ && $options[ $prefix . 'customimg_checker' ]
1007
+ ) {
1008
+ $options[ $prefix . 'image' ] = $options[ $prefix . 'customimg' ];
1009
+ }
1010
+ }
1011
+ return $options;
1012
+ }
1013
+
1014
+ /** Custom settings **/
1015
+ function display_custom_options( $buf, $args ) {
1016
+ if ( $args['name'] == 'aiosp_opengraph_scan_header' ) {
1017
+ $buf .= '<div class="aioseop aioseop_options aiosp_opengraph_settings"><div class="aioseop_wrapper aioseop_custom_type" id="aiosp_opengraph_scan_header_wrapper"><div class="aioseop_input" id="aiosp_opengraph_scan_header" style="padding-left:20px;">';
1018
+ $args['options']['type'] = 'submit';
1019
+ $args['attr'] = " class='button-primary' ";
1020
+ $args['value'] = $args['options']['default'] = __( 'Scan Now', 'all-in-one-seo-pack' );
1021
+ $buf .= __( 'Scan your site for duplicate social meta tags.', 'all-in-one-seo-pack' );
1022
+ $buf .= '<br /><br />' . $this->get_option_html( $args );
1023
+ $buf .= '</div></div></div>';
1024
+ }
1025
+
1026
+ return $buf;
1027
+ }
1028
+
1029
+ function add_attributes( $output ) {
1030
+ // avoid having duplicate meta tags
1031
+ $type = $this->type;
1032
+ if ( empty( $type ) ) {
1033
+ $type = 'website';
1034
+ }
1035
+ $schema_types = array(
1036
+ 'album' => 'MusicAlbum',
1037
+ 'article' => 'Article',
1038
+ 'bar' => 'BarOrPub',
1039
+ 'blog' => 'Blog',
1040
+ 'book' => 'Book',
1041
+ 'cafe' => 'CafeOrCoffeeShop',
1042
+ 'city' => 'City',
1043
+ 'country' => 'Country',
1044
+ 'episode' => 'Episode',
1045
+ 'food' => 'FoodEvent',
1046
+ 'game' => 'Game',
1047
+ 'hotel' => 'Hotel',
1048
+ 'landmark' => 'LandmarksOrHistoricalBuildings',
1049
+ 'movie' => 'Movie',
1050
+ 'product' => 'Product',
1051
+ 'profile' => 'ProfilePage',
1052
+ 'restaurant' => 'Restaurant',
1053
+ 'school' => 'School',
1054
+ 'sport' => 'SportsEvent',
1055
+ 'website' => 'WebSite',
1056
+ );
1057
+
1058
+ if ( ! empty( $schema_types[ $type ] ) ) {
1059
+ $type = $schema_types[ $type ];
1060
+ } else {
1061
+ $type = 'WebSite';
1062
+ }
1063
+
1064
+ $attributes = apply_filters(
1065
+ $this->prefix . 'attributes', array(
1066
+ 'prefix="og: http://ogp.me/ns#"',
1067
+ )
1068
+ );
1069
+
1070
+ foreach ( $attributes as $attr ) {
1071
+ if ( strpos( $output, $attr ) === false ) {
1072
+ $output .= "\n\t$attr ";
1073
+ }
1074
+ }
1075
+
1076
+ return $output;
1077
+ }
1078
+
1079
+ /**
1080
+ * Add our social meta.
1081
+ *
1082
+ * @since 1.0.0
1083
+ * @since 2.3.11.5 Support for multiple fb_admins.
1084
+ * @since 2.3.13 Adds filter:aioseop_description on description.
1085
+ * @since 2.4.14 Fixes for aioseop-pro #67.
1086
+ * @since 2.3.15 Always do_shortcode on descriptions, removed for titles.
1087
+ *
1088
+ * @global object $post Current WP_Post object.
1089
+ * @global object $aiosp All in one seo plugin object.
1090
+ * @global array $aioseop_options All in one seo plugin options.
1091
+ * @global object $wp_query WP_Query global instance.
1092
+ */
1093
+ function add_meta() {
1094
+ global $post, $aiosp, $aioseop_options, $wp_query;
1095
+ $metabox = $this->get_current_options( array(), 'settings' );
1096
+ $key = $this->options['aiosp_opengraph_key'];
1097
+ $key = $this->options['aiosp_opengraph_key'];
1098
+ $dimg = $this->options['aiosp_opengraph_dimg'];
1099
+ $current_post_type = get_post_type();
1100
+ $title = $description = $image = $video = '';
1101
+ $type = $this->type;
1102
+ $sitename = $this->options['aiosp_opengraph_sitename'];
1103
+
1104
+ $appid = isset( $this->options['aiosp_opengraph_appid'] ) ? $this->options['aiosp_opengraph_appid'] : '';
1105
+
1106
+ if ( ! empty( $aioseop_options['aiosp_hide_paginated_descriptions'] ) ) {
1107
+ $first_page = false;
1108
+ if ( $aiosp->get_page_number() < 2 ) {
1109
+ $first_page = true;
1110
+ }
1111
+ } else {
1112
+ $first_page = true;
1113
+ }
1114
+ $url = $aiosp->aiosp_mrt_get_url( $wp_query );
1115
+ $url = apply_filters( 'aioseop_canonical_url', $url );
1116
+
1117
+ $setmeta = $this->options['aiosp_opengraph_setmeta'];
1118
+ $social_links = '';
1119
+ if ( is_front_page() ) {
1120
+ $title = $this->options['aiosp_opengraph_hometitle'];
1121
+ if ( $first_page ) {
1122
+ $description = $this->options['aiosp_opengraph_description'];
1123
+ if ( empty( $description ) ) {
1124
+ $description = get_bloginfo( 'description' );
1125
+ }
1126
+ }
1127
+ if ( ! empty( $this->options['aiosp_opengraph_homeimage'] ) ) {
1128
+ $thumbnail = $this->options['aiosp_opengraph_homeimage'];
1129
+ } else {
1130
+ $thumbnail = $this->options['aiosp_opengraph_dimg'];
1131
+ }
1132
+
1133
+ /* If Use AIOSEO Title and Desc Selected */
1134
+ if ( $setmeta ) {
1135
+ $title = $aiosp->wp_title();
1136
+ if ( $first_page ) {
1137
+ $description = $aiosp->get_aioseop_description( $post );
1138
+ }
1139
+ }
1140
+
1141
+ /* Add some defaults */
1142
+ if ( empty( $title ) ) {
1143
+ $title = get_bloginfo( 'name' );
1144
+ }
1145
+ if ( empty( $sitename ) ) {
1146
+ $sitename = get_bloginfo( 'name' );
1147
+ }
1148
+
1149
+ if ( empty( $description ) && $first_page && ! empty( $post ) && ! post_password_required( $post ) ) {
1150
+
1151
+ if ( ! empty( $post->post_content ) || ! empty( $post->post_excerpt ) ) {
1152
+ $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_excerpt ) ), 1000 );
1153
+
1154
+ if ( ! empty( $this->options['aiosp_opengraph_generate_descriptions'] ) ) {
1155
+ $description = $aiosp->trim_excerpt_without_filters( $aiosp->internationalize( preg_replace( '/\s+/', ' ', $post->post_content ) ), 1000 );
1156
+ }
1157
+ }
1158
+ }
1159
+
1160
+ if ( empty( $description ) && $first_page ) {
1161
+ $description = get_bloginfo( 'description' );
1162
+ }
1163
+ if ( ! empty( $this->options['aiosp_opengraph_profile_links'] ) ) {
1164
+ $social_links = $this->options['aiosp_opengraph_profile_links'];
1165
+ if ( ! empty( $this->options['aiosp_opengraph_social_name'] ) ) {
1166
+ $social_name = $this->options['aiosp_opengraph_social_name'];
1167
+ } else {
1168
+ $social_name = '';
1169
+ }
1170
+ if ( $this->options['aiosp_opengraph_person_or_org'] == 'person' ) {
1171
+ $social_type = 'Person';
1172
+ } else {
1173
+ $social_type = 'Organization';
1174
+ }
1175
+ }
1176
+ } elseif ( is_singular() && $this->option_isset( 'types' )
1177
+ && is_array( $this->options['aiosp_opengraph_types'] )
1178
+ && in_array( $current_post_type, $this->options['aiosp_opengraph_types'] )
1179
+ ) {
1180
+
1181
+ if ( $type == 'article' ) {
1182
+ if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) {
1183
+ $section = $metabox['aioseop_opengraph_settings_section'];
1184
+ }
1185
+ if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) {
1186
+ $tag = $metabox['aioseop_opengraph_settings_tag'];
1187
+ }
1188
+ if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) {
1189
+ $publisher = $this->options['aiosp_opengraph_facebook_publisher'];
1190
+ }
1191
+ }
1192
+
1193
+ if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1194
+ $domain = $this->options['aiosp_opengraph_twitter_domain'];
1195
+ }
1196
+
1197
+ if ( $type == 'article' && ! empty( $post ) ) {
1198
+ if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) {
1199
+ $author = get_the_author_meta( 'facebook', $post->post_author );
1200
+ }
1201
+
1202
+ if ( isset( $post->post_date_gmt ) ) {
1203
+ $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) );
1204
+ }
1205
+
1206
+ if ( isset( $post->post_modified_gmt ) ) {
1207
+ $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) );
1208
+ }
1209
+ }
1210
+
1211
+ $image = $metabox['aioseop_opengraph_settings_image'];
1212
+ $video = $metabox['aioseop_opengraph_settings_video'];
1213
+ $title = $metabox['aioseop_opengraph_settings_title'];
1214
+ $description = $metabox['aioseop_opengraph_settings_desc'];
1215
+
1216
+ /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */
1217
+ global $aiosp;
1218
+ if ( empty( $title ) ) {
1219
+ $title = $aiosp->wp_title();
1220
+ }
1221
+ if ( empty( $description ) ) {
1222
+ $description = trim( strip_tags( get_post_meta( $post->ID, '_aioseop_description', true ) ) );
1223
+ }
1224
+
1225
+ /* Add default title */
1226
+ if ( empty( $title ) ) {
1227
+ $title = get_the_title();
1228
+ }
1229
+
1230
+ // Add default description.
1231
+ if ( empty( $description ) && ! post_password_required( $post ) ) {
1232
+
1233
+ $description = $post->post_excerpt;
1234
+
1235
+ if ( $this->options['aiosp_opengraph_generate_descriptions'] || empty( $description ) ) {
1236
+ $description = $post->post_content;
1237
+ }
1238
+ }
1239
+ if ( empty( $type ) ) {
1240
+ $type = 'article';
1241
+ }
1242
+ } elseif ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) {
1243
+ if ( isset( $this->options['aioseop_opengraph_settings_category'] ) ) {
1244
+ $type = $this->options['aioseop_opengraph_settings_category'];
1245
+ }
1246
+ if ( isset( $metabox['aioseop_opengraph_settings_category'] ) ) {
1247
+ $type = $metabox['aioseop_opengraph_settings_category'];
1248
+ }
1249
+ if ( $type == 'article' ) {
1250
+ if ( ! empty( $metabox['aioseop_opengraph_settings_section'] ) ) {
1251
+ $section = $metabox['aioseop_opengraph_settings_section'];
1252
+ }
1253
+ if ( ! empty( $metabox['aioseop_opengraph_settings_tag'] ) ) {
1254
+ $tag = $metabox['aioseop_opengraph_settings_tag'];
1255
+ }
1256
+ if ( ! empty( $this->options['aiosp_opengraph_facebook_publisher'] ) ) {
1257
+ $publisher = $this->options['aiosp_opengraph_facebook_publisher'];
1258
+ }
1259
+ }
1260
+ if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1261
+ $domain = $this->options['aiosp_opengraph_twitter_domain'];
1262
+ }
1263
+ if ( $type == 'article' && ! empty( $post ) ) {
1264
+ if ( isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_facebook_author'] ) ) {
1265
+ $author = get_the_author_meta( 'facebook', $post->post_author );
1266
+ }
1267
+
1268
+ if ( isset( $post->post_date_gmt ) ) {
1269
+ $published_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_date_gmt ) );
1270
+ }
1271
+ if ( isset( $post->post_modified_gmt ) ) {
1272
+ $modified_time = date( 'Y-m-d\TH:i:s\Z', mysql2date( 'U', $post->post_modified_gmt ) );
1273
+ }
1274
+ }
1275
+ $image = $metabox['aioseop_opengraph_settings_image'];
1276
+ $video = $metabox['aioseop_opengraph_settings_video'];
1277
+ $title = $metabox['aioseop_opengraph_settings_title'];
1278
+ $description = $metabox['aioseop_opengraph_settings_desc'];
1279
+ /* Add AIOSEO variables if Site Title and Desc from AIOSEOP not selected */
1280
+ global $aiosp;
1281
+ if ( empty( $title ) ) {
1282
+ $title = $aiosp->wp_title();
1283
+ }
1284
+ if ( empty( $description ) ) {
1285
+ $term_id = isset( $_GET['tag_ID'] ) ? (int) $_GET['tag_ID'] : 0;
1286
+ $term_id = $term_id ? $term_id : get_queried_object()->term_id;
1287
+ $description = trim( strip_tags( get_term_meta( $term_id, '_aioseop_description', true ) ) );
1288
+ }
1289
+ // Add default title
1290
+ if ( empty( $title ) ) {
1291
+ $title = get_the_title();
1292
+ }
1293
+ // Add default description.
1294
+ if ( empty( $description ) && ! post_password_required( $post ) ) {
1295
+ $description = get_queried_object()->description;
1296
+ }
1297
+ if ( empty( $type ) ) {
1298
+ # https://github.com/semperfiwebdesign/aioseop-pro/issues/321
1299
+ if ( AIOSEOPPRO && ( is_category() || is_tag() || is_tax() ) ) {
1300
+ $og_options = $aioseop_options['modules'][ $this->prefix . 'options' ];
1301
+ $current_post_type = get_post_type();
1302
+ // check if the post type's object type is set.
1303
+ if ( isset( $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) {
1304
+ $type = $og_options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ];
1305
+ } elseif ( in_array( $current_post_type, array( 'post', 'page' ) ) ) {
1306
+ $type = 'article';
1307
+ }
1308
+ } else {
1309
+ $type = 'website';
1310
+ }
1311
+ }
1312
+ } elseif ( is_home() && ! is_front_page() ) {
1313
+ // This is the blog page but not the homepage.
1314
+ global $aiosp;
1315
+ $image = $metabox['aioseop_opengraph_settings_image'];
1316
+ $video = $metabox['aioseop_opengraph_settings_video'];
1317
+ $title = $metabox['aioseop_opengraph_settings_title'];
1318
+ $description = $metabox['aioseop_opengraph_settings_desc'];
1319
+
1320
+ if ( empty( $description ) ) {
1321
+ // If there's not social description, fall back to the SEO description.
1322
+ $description = trim( strip_tags( get_post_meta( get_option( 'page_for_posts' ), '_aioseop_description', true ) ) );
1323
+ }
1324
+ if ( empty( $title ) ) {
1325
+ $title = $aiosp->wp_title();
1326
+ }
1327
+ } else {
1328
+ return;
1329
+ }
1330
+
1331
+ if ( $type === 'article' && ! empty( $post ) && is_singular() ) {
1332
+ if ( ! empty( $this->options['aiosp_opengraph_gen_tags'] ) ) {
1333
+ if ( ! empty( $this->options['aiosp_opengraph_gen_keywords'] ) ) {
1334
+ $keywords = $aiosp->get_main_keywords();
1335
+ $keywords = $this->apply_cf_fields( $keywords );
1336
+ $keywords = apply_filters( 'aioseop_keywords', $keywords );
1337
+ if ( ! empty( $keywords ) && ! empty( $tag ) ) {
1338
+ $tag .= ',' . $keywords;
1339
+ } elseif ( empty( $tag ) ) {
1340
+ $tag = $keywords;
1341
+ }
1342
+ }
1343
+ $tag = $aiosp->keyword_string_to_list( $tag );
1344
+ if ( ! empty( $this->options['aiosp_opengraph_gen_categories'] ) ) {
1345
+ $tag = array_merge( $tag, $aiosp->get_all_categories( $post->ID ) );
1346
+ }
1347
+ if ( ! empty( $this->options['aiosp_opengraph_gen_post_tags'] ) ) {
1348
+ $tag = array_merge( $tag, $aiosp->get_all_tags( $post->ID ) );
1349
+ }
1350
+ }
1351
+ if ( ! empty( $tag ) ) {
1352
+ $tag = $aiosp->clean_keyword_list( $tag );
1353
+ }
1354
+ }
1355
+
1356
+ if ( ! empty( $this->options['aiosp_opengraph_title_shortcodes'] ) ) {
1357
+ $title = do_shortcode( $title );
1358
+ }
1359
+ if ( ! empty( $description ) ) {
1360
+ $description = $aiosp->internationalize( preg_replace( '/\s+/', ' ', $description ) );
1361
+ if ( ! empty( $this->options['aiosp_opengraph_description_shortcodes'] ) ) {
1362
+ $description = do_shortcode( $description );
1363
+ }
1364
+ $description = $aiosp->trim_excerpt_without_filters( $description, 1000 );
1365
+ }
1366
+
1367
+ $title = $this->apply_cf_fields( $title );
1368
+ $description = $this->apply_cf_fields( $description );
1369
+
1370
+ /* Data Validation */
1371
+ $title = strip_tags( esc_attr( $title ) );
1372
+ $sitename = strip_tags( esc_attr( $sitename ) );
1373
+ $description = strip_tags( esc_attr( $description ) );
1374
+
1375
+ if ( empty( $thumbnail ) && ! empty( $image ) ) {
1376
+ $thumbnail = $image;
1377
+ }
1378
+
1379
+ // Add user supplied default image.
1380
+ if ( empty( $thumbnail ) ) {
1381
+ if ( empty( $this->options['aiosp_opengraph_defimg'] ) ) {
1382
+ $thumbnail = $this->options['aiosp_opengraph_dimg'];
1383
+ } else {
1384
+ $img_type = $this->options['aiosp_opengraph_defimg'];
1385
+ if ( ! empty( $post ) ) {
1386
+ // Customize the type of image per post/post_type.
1387
+ $img_type = apply_filters( $this->prefix . 'default_image_type', $img_type, $post, $type );
1388
+ }
1389
+ switch ( $img_type ) {
1390
+ case 'featured':
1391
+ $thumbnail = $this->get_the_image_by_post_thumbnail();
1392
+ break;
1393
+ case 'attach':
1394
+ $thumbnail = $this->get_the_image_by_attachment();
1395
+ break;
1396
+ case 'content':
1397
+ $thumbnail = $this->get_the_image_by_scan();
1398
+ break;
1399
+ case 'custom':
1400
+ $meta_key = $this->options['aiosp_opengraph_meta_key'];
1401
+ if ( ! empty( $meta_key ) && ! empty( $post ) ) {
1402
+ $meta_key = explode( ',', $meta_key );
1403
+ $thumbnail = $this->get_the_image_by_meta_key(
1404
+ array(
1405
+ 'post_id' => $post->ID,
1406
+ 'meta_key' => $meta_key,
1407
+ )
1408
+ );
1409
+ }
1410
+ break;
1411
+ case 'auto':
1412
+ $thumbnail = $this->get_the_image();
1413
+ break;
1414
+ case 'author':
1415
+ $thumbnail = $this->get_the_image_by_author();
1416
+ break;
1417
+ default:
1418
+ $thumbnail = $this->options['aiosp_opengraph_dimg'];
1419
+ }
1420
+ }
1421
+ }
1422
+
1423
+ if ( empty( $thumbnail ) && ! empty( $this->options['aiosp_opengraph_fallback'] ) ) {
1424
+ $thumbnail = $this->options['aiosp_opengraph_dimg'];
1425
+ if ( ! empty( $post ) ) {
1426
+ // Customize the default image per post/post_type.
1427
+ $thumbnail = apply_filters( $this->prefix . 'default_image', $thumbnail, $post, $type );
1428
+ }
1429
+ }
1430
+
1431
+ if ( ! empty( $thumbnail ) ) {
1432
+ $thumbnail = esc_url( $thumbnail );
1433
+ $thumbnail = set_url_scheme( $thumbnail );
1434
+ }
1435
+
1436
+ $width = $height = '';
1437
+ if ( ! empty( $thumbnail ) ) {
1438
+ if ( ! empty( $metabox['aioseop_opengraph_settings_imagewidth'] ) ) {
1439
+ $width = $metabox['aioseop_opengraph_settings_imagewidth'];
1440
+ }
1441
+ if ( ! empty( $metabox['aioseop_opengraph_settings_imageheight'] ) ) {
1442
+ $height = $metabox['aioseop_opengraph_settings_imageheight'];
1443
+ }
1444
+ if ( empty( $width ) && ! empty( $this->options['aiosp_opengraph_dimgwidth'] ) ) {
1445
+ $width = $this->options['aiosp_opengraph_dimgwidth'];
1446
+ }
1447
+ if ( empty( $height ) && ! empty( $this->options['aiosp_opengraph_dimgheight'] ) ) {
1448
+ $height = $this->options['aiosp_opengraph_dimgheight'];
1449
+ }
1450
+ }
1451
+
1452
+ if ( ! empty( $video ) ) {
1453
+ if ( ! empty( $metabox['aioseop_opengraph_settings_videowidth'] ) ) {
1454
+ $videowidth = $metabox['aioseop_opengraph_settings_videowidth'];
1455
+ }
1456
+ if ( ! empty( $metabox['aioseop_opengraph_settings_videoheight'] ) ) {
1457
+ $videoheight = $metabox['aioseop_opengraph_settings_videoheight'];
1458
+ }
1459
+ }
1460
+
1461
+ $card = 'summary';
1462
+ if ( ! empty( $this->options['aiosp_opengraph_defcard'] ) ) {
1463
+ $card = $this->options['aiosp_opengraph_defcard'];
1464
+ }
1465
+
1466
+ if ( ! empty( $metabox['aioseop_opengraph_settings_setcard'] ) ) {
1467
+ $card = $metabox['aioseop_opengraph_settings_setcard'];
1468
+ }
1469
+
1470
+ // support for changing legacy twitter cardtype-photo to summary large image
1471
+ if ( $card == 'photo' ) {
1472
+ $card = 'summary_large_image';
1473
+ }
1474
+
1475
+ $site = $domain = $creator = '';
1476
+
1477
+ if ( ! empty( $this->options['aiosp_opengraph_twitter_site'] ) ) {
1478
+ $site = $this->options['aiosp_opengraph_twitter_site'];
1479
+ $site = AIOSEOP_Opengraph_Public::prepare_twitter_username( $site );
1480
+ }
1481
+
1482
+ if ( ! empty( $this->options['aiosp_opengraph_twitter_domain'] ) ) {
1483
+ $domain = $this->options['aiosp_opengraph_twitter_domain'];
1484
+ }
1485
+
1486
+ if ( ! empty( $post ) && isset( $post->post_author ) && ! empty( $this->options['aiosp_opengraph_twitter_creator'] ) ) {
1487
+ $creator = get_the_author_meta( 'twitter', $post->post_author );
1488
+ $creator = AIOSEOP_Opengraph_Public::prepare_twitter_username( $creator );
1489
+ }
1490
+
1491
+ if ( ! empty( $thumbnail ) ) {
1492
+ $twitter_thumbnail = $thumbnail; // Default Twitter image if custom isn't set.
1493
+ }
1494
+
1495
+ if ( isset( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) && ! empty( $metabox['aioseop_opengraph_settings_customimg_twitter'] ) ) {
1496
+ // Set Twitter image from custom.
1497
+ $twitter_thumbnail = set_url_scheme( $metabox['aioseop_opengraph_settings_customimg_twitter'] );
1498
+ }
1499
+
1500
+ // Apply last filters.
1501
+ $description = apply_filters( 'aioseop_description', $description );
1502
+
1503
+ $meta = array(
1504
+ 'facebook' => array(
1505
+ 'title' => 'og:title',
1506
+ 'type' => 'og:type',
1507
+ 'url' => 'og:url',
1508
+ 'thumbnail' => 'og:image',
1509
+ 'width' => 'og:image:width',
1510
+ 'height' => 'og:image:height',
1511
+ 'video' => 'og:video',
1512
+ 'videowidth' => 'og:video:width',
1513
+ 'videoheight' => 'og:video:height',
1514
+ 'sitename' => 'og:site_name',
1515
+ 'key' => 'fb:admins',
1516
+ 'appid' => 'fb:app_id',
1517
+ 'description' => 'og:description',
1518
+ 'section' => 'article:section',
1519
+ 'tag' => 'article:tag',
1520
+ 'publisher' => 'article:publisher',
1521
+ 'author' => 'article:author',
1522
+ 'published_time' => 'article:published_time',
1523
+ 'modified_time' => 'article:modified_time',
1524
+ ),
1525
+ 'twitter' => array(
1526
+ 'card' => 'twitter:card',
1527
+ 'site' => 'twitter:site',
1528
+ 'creator' => 'twitter:creator',
1529
+ 'domain' => 'twitter:domain',
1530
+ 'title' => 'twitter:title',
1531
+ 'description' => 'twitter:description',
1532
+ 'twitter_thumbnail' => 'twitter:image',
1533
+ ),
1534
+ );
1535
+
1536
+ // Only show if "use schema.org markup is checked".
1537
+ if ( ! empty( $aioseop_options['aiosp_schema_markup'] ) ) {
1538
+ $meta['google+'] = array( 'thumbnail' => 'image' );
1539
+ }
1540
+
1541
+ $tags = array(
1542
+ 'facebook' => array( 'name' => 'property', 'value' => 'content' ),
1543
+ 'twitter' => array( 'name' => 'name', 'value' => 'content' ),
1544
+ 'google+' => array( 'name' => 'itemprop', 'value' => 'content' ),
1545
+ );
1546
+
1547
+ foreach ( $meta as $t => $data ) {
1548
+ foreach ( $data as $k => $v ) {
1549
+ if ( empty( $$k ) ) {
1550
+ $$k = '';
1551
+ }
1552
+ $filtered_value = $$k;
1553
+ $filtered_value = apply_filters( $this->prefix . 'meta', $filtered_value, $t, $k );
1554
+ if ( ! empty( $filtered_value ) ) {
1555
+ if ( ! is_array( $filtered_value ) ) {
1556
+ $filtered_value = array( $filtered_value );
1557
+ }
1558
+
1559
+ /**
1560
+ * This is to accomodate multiple fb:admins on separate lines.
1561
+ * @TODO Eventually we'll want to put this in its own function so things like images work too.
1562
+ */
1563
+ if ( 'key' === $k ) {
1564
+ $fbadmins = explode( ',', str_replace( ' ', '', $filtered_value[0] ) ); // Trim spaces then turn comma-separated values into an array.
1565
+ foreach ( $fbadmins as $fbadmin ) {
1566
+ echo '<meta ' . $tags[ $t ]['name'] . '="' . $v . '" ' . $tags[ $t ]['value'] . '="' . $fbadmin . '" />' . "\n";
1567
+ }
1568
+ } else {
1569
+ // For everything else.
1570
+ foreach ( $filtered_value as $f ) {
1571
+ // #1363: use esc_attr( $f ) instead of htmlspecialchars_decode( $f, ENT_QUOTES )
1572
+ echo '<meta ' . $tags[ $t ]['name'] . '="' . $v . '" ' . $tags[ $t ]['value'] . '="' . esc_attr( $f ) . '" />' . "\n";
1573
+ }
1574
+ }
1575
+ }
1576
+ }
1577
+ }
1578
+ $social_link_schema = '';
1579
+ if ( ! empty( $social_links ) ) {
1580
+ $home_url = esc_url( get_home_url() );
1581
+ $social_links = explode( "\n", $social_links );
1582
+ foreach ( $social_links as $k => $v ) {
1583
+ $v = trim( $v );
1584
+ if ( empty( $v ) ) {
1585
+ unset( $social_links[ $k ] );
1586
+ } else {
1587
+ $v = esc_url( $v );
1588
+ $social_links[ $k ] = $v;
1589
+ }
1590
+ }
1591
+ $social_links = join( '","', $social_links );
1592
+ $social_link_schema = <<<END
1593
+ <script type="application/ld+json">
1594
+ { "@context" : "http://schema.org",
1595
+ "@type" : "{$social_type}",
1596
+ "name" : "{$social_name}",
1597
+ "url" : "{$home_url}",
1598
+ "sameAs" : ["{$social_links}"]
1599
+ }
1600
+ </script>
1601
+
1602
+ END;
1603
+ }
1604
+ echo apply_filters( 'aiosp_opengraph_social_link_schema', $social_link_schema );
1605
+ }
1606
+
1607
+ /**
1608
+ * Do / adds opengraph properties to meta.
1609
+ * @since 2.3.11
1610
+ *
1611
+ * @global array $aioseop_options AIOSEOP plugin options.
1612
+ */
1613
+ public function do_opengraph() {
1614
+ global $aioseop_options;
1615
+ if ( ! empty( $aioseop_options )
1616
+ && ! empty( $aioseop_options['aiosp_schema_markup'] )
1617
+ ) {
1618
+ add_filter( 'language_attributes', array( &$this, 'add_attributes' ) );
1619
+ }
1620
+ if ( ! defined( 'DOING_AJAX' ) ) {
1621
+ add_action( 'aioseop_modules_wp_head', array( &$this, 'add_meta' ), 5 );
1622
+ // Add social meta to AMP plugin.
1623
+ if ( apply_filters( 'aioseop_enable_amp_social_meta', true ) === true ) {
1624
+ add_action( 'amp_post_template_head', array( &$this, 'add_meta' ), 12 );
1625
+ }
1626
+ }
1627
+ }
1628
+
1629
+ /**
1630
+ * Set up types.
1631
+ *
1632
+ * @since ?
1633
+ * @since 2.3.15 Change to website for homepage and blog post index page, default to object.
1634
+ */
1635
+ function type_setup() {
1636
+ $this->type = 'object'; // Default to type object if we don't have some other rule.
1637
+
1638
+ if ( is_home() || is_front_page() ) {
1639
+ $this->type = 'website'; // Home page and blog page should be website.
1640
+ } elseif ( is_singular() && $this->option_isset( 'types' ) ) {
1641
+ $metabox = $this->get_current_options( array(), 'settings' );
1642
+ $current_post_type = get_post_type();
1643
+ if ( ! empty( $metabox['aioseop_opengraph_settings_category'] ) ) {
1644
+ $this->type = $metabox['aioseop_opengraph_settings_category'];
1645
+ } elseif ( isset( $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ] ) ) {
1646
+ $this->type = $this->options[ "aiosp_opengraph_{$current_post_type}_fb_object_type" ];
1647
+ }
1648
+ }
1649
+ }
1650
+
1651
+ /**
1652
+ * Inits hooks and others for admin init.
1653
+ * action:admin_init.
1654
+ *
1655
+ * @since 2.3.11
1656
+ * @since 2.4.14 Refactored function name, and new filter added for defaults and missing term metabox.
1657
+ */
1658
+ function admin_init() {
1659
+ add_filter( $this->prefix . 'display_settings', array( &$this, 'filter_settings' ), 10, 3 );
1660
+ add_filter( $this->prefix . 'override_options', array( &$this, 'override_options' ), 10, 3 );
1661
+ add_filter( $this->get_prefix( 'settings' ) . 'default_options', array(
1662
+ &$this,
1663
+ 'filter_default_options',
1664
+ ), 10, 2 );
1665
+ add_filter(
1666
+ $this->get_prefix( 'settings' ) . 'filter_metabox_options', array(
1667
+ &$this,
1668
+ 'filter_metabox_options',
1669
+ ), 10, 3
1670
+ );
1671
+ add_filter(
1672
+ $this->get_prefix( 'settings' ) . 'filter_term_metabox_options', array(
1673
+ &$this,
1674
+ 'filter_metabox_options',
1675
+ ), 10, 3
1676
+ );
1677
+ $post_types = $this->get_post_type_titles();
1678
+ $rempost = array(
1679
+ 'revision' => 1,
1680
+ 'nav_menu_item' => 1,
1681
+ 'custom_css' => 1,
1682
+ 'customize_changeset' => 1,
1683
+ );
1684
+ $post_types = array_diff_key( $post_types, $rempost );
1685
+ $this->default_options['types']['initial_options'] = $post_types;
1686
+ foreach ( $post_types as $slug => $name ) {
1687
+ $field = $slug . '_fb_object_type';
1688
+ $this->default_options[ $field ] = array(
1689
+ 'name' => "$name " . __( 'Object Type', 'all-in-one-seo-pack' ) . "<br />($slug)",
1690
+ 'type' => 'select',
1691
+ 'style' => '',
1692
+ 'initial_options' => $this->fb_object_types,
1693
+ 'default' => 'article',
1694
+ 'condshow' => array( 'aiosp_opengraph_types\[\]' => $slug ),
1695
+ );
1696
+ $this->help_text[ $field ] = __( 'Choose a default value that best describes the content of your post type.', 'all-in-one-seo-pack' );
1697
+ $this->help_anchors[ $field ] = '#content-object-types';
1698
+ $this->locations['opengraph']['options'][] = $field;
1699
+ $this->layout['facebook']['options'][] = $field;
1700
+ }
1701
+ $this->setting_options();
1702
+ $this->add_help_text_links();
1703
+
1704
+ }
1705
+
1706
+ function get_all_images( $options = null, $p = null ) {
1707
+ static $img = array();
1708
+ if ( ! is_array( $options ) ) {
1709
+ $options = array();
1710
+ }
1711
+ if ( ! empty( $this->options['aiosp_opengraph_meta_key'] ) ) {
1712
+ $options['meta_key'] = $this->options['aiosp_opengraph_meta_key'];
1713
+ }
1714
+ if ( empty( $img ) ) {
1715
+ $size = apply_filters( 'post_thumbnail_size', 'large' );
1716
+ $default = $this->get_the_image_by_default();
1717
+ if ( ! empty( $default ) ) {
1718
+ $default = set_url_scheme( $default );
1719
+ $img[ $default ] = 0;
1720
+ }
1721
+ $img = array_merge( $img, parent::get_all_images( $options, null ) );
1722
+ }
1723
+
1724
+ if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) {
1725
+ $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg';
1726
+ }
1727
+
1728
+ if ( ! empty( $options ) && ! empty( $options['aioseop_opengraph_settings_customimg'] ) ) {
1729
+ $img[ $options['aioseop_opengraph_settings_customimg'] ] = 'customimg';
1730
+ $img[ $options['aioseop_opengraph_settings_customimg_twitter'] ] = 'customimg_twitter';
1731
+ }
1732
+
1733
+ if ( $author_img = $this->get_the_image_by_author( $p ) ) {
1734
+ $image['author'] = $author_img;
1735
+ }
1736
+ $image = array_flip( $img );
1737
+ $images = array();
1738
+ if ( ! empty( $image ) ) {
1739
+ foreach ( $image as $k => $v ) {
1740
+ $images[ $v ] = '<img height=150 src="' . $v . '">';
1741
+ }
1742
+ }
1743
+
1744
+ return array( $image, $images );
1745
+ }
1746
+
1747
+ function get_the_image_by_author( $options = null, $p = null ) {
1748
+ if ( $p === null ) {
1749
+ global $post;
1750
+ } else {
1751
+ $post = $p;
1752
+ }
1753
+ if ( ! empty( $post ) && ! empty( $post->post_author ) ) {
1754
+ $matches = array();
1755
+ $get_avatar = get_avatar( $post->post_author, 300 );
1756
+ if ( preg_match( "/src='(.*?)'/i", $get_avatar, $matches ) ) {
1757
+ return $matches[1];
1758
+ }
1759
+ }
1760
+
1761
+ return false;
1762
+ }
1763
+
1764
+ function get_the_image( $options = null, $p = null ) {
1765
+ $meta_key = $this->options['aiosp_opengraph_meta_key'];
1766
+
1767
+ return parent::get_the_image( array( 'meta_key' => $meta_key ), $p );
1768
+ }
1769
+
1770
+ function get_the_image_by_default( $args = array() ) {
1771
+ return $this->options['aiosp_opengraph_dimg'];
1772
+ }
1773
+
1774
+ function settings_update() {
1775
+
1776
+ }
1777
+
1778
+ /**
1779
+ * Admin Enqueue Scripts
1780
+ *
1781
+ * Add hook in \All_in_One_SEO_Pack_Module::enqueue_metabox_scripts - Bails adding hook if not on target valid screen.
1782
+ * Add hook in \All_in_One_SEO_Pack_Module::add_page_hooks - Function itself is hooked based on the screen_id/page.
1783
+ *
1784
+ * @since 2.9.2
1785
+ *
1786
+ * @see 'admin_enqueue_scripts' hook
1787
+ * @link https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
1788
+ *
1789
+ * @param string $hook_suffix
1790
+ */
1791
+ public function admin_enqueue_scripts( $hook_suffix ) {
1792
+ wp_enqueue_script(
1793
+ 'aioseop-opengraph-script',
1794
+ AIOSEOP_PLUGIN_URL . 'js/modules/aioseop_opengraph.js',
1795
+ array(),
1796
+ AIOSEOP_VERSION
1797
+ );
1798
+
1799
+ // Dev note: If certain JS files need to be restricted to select screens, then follow concept
1800
+ // used in `All_in_One_SEO_Pack::admin_enqueue_scripts()` (v2.9.1); which uses the `$hook_suffix`
1801
+ // and a switch-case. This also helps prevent unnessecarily processing localized data when it isn't needed.
1802
+
1803
+ parent::admin_enqueue_scripts( $hook_suffix );
1804
+ }
1805
+
1806
+ /**
1807
+ * Enqueue our file upload scripts and styles.
1808
+ * @param $hook
1809
+ */
1810
+ function og_admin_enqueue_scripts( $hook ) {
1811
+
1812
+ if ( 'all-in-one-seo_page_aiosp_opengraph' != $hook && 'term.php' != $hook ) {
1813
+ // Only enqueue if we're on the social module settings page.
1814
+ return;
1815
+ }
1816
+
1817
+ wp_enqueue_script( 'media-upload' );
1818
+ wp_enqueue_script( 'thickbox' );
1819
+ wp_enqueue_style( 'thickbox' );
1820
+ wp_enqueue_media();
1821
+ }
1822
+
1823
+ function save_tax_data( $term_id, $tt_id, $taxonomy ) {
1824
+ static $update = false;
1825
+ if ( $update ) {
1826
+ return;
1827
+ }
1828
+ if ( $this->locations !== null ) {
1829
+ foreach ( $this->locations as $k => $v ) {
1830
+ if ( isset( $v['type'] ) && ( $v['type'] === 'metabox' ) ) {
1831
+ $opts = $this->default_options( $k );
1832
+ $options = array();
1833
+ $update = false;
1834
+ foreach ( $opts as $l => $o ) {
1835
+ if ( isset( $_POST[ $l ] ) ) {
1836
+ $options[ $l ] = stripslashes_deep( $_POST[ $l ] );
1837
+ $options[ $l ] = esc_attr( $options[ $l ] );
1838
+ $update = true;
1839
+ }
1840
+ }
1841
+ if ( $update ) {
1842
+ $prefix = $this->get_prefix( $k );
1843
+ $options = apply_filters( $prefix . 'filter_term_metabox_options', $options, $k, $term_id );
1844
+ update_term_meta( $term_id, '_' . $prefix . $k, $options );
1845
+ }
1846
+ }
1847
+ }
1848
+ }
1849
+ }
1850
+
1851
+ /**
1852
+ * Returns the placeholder filtered and ready for DOM display.
1853
+ * filter:aioseop_opengraph_placeholder
1854
+ * @since 2.4.14
1855
+ *
1856
+ * @param mixed $placeholder Placeholder to be filtered.
1857
+ * @param string $type Type of the value to be filtered.
1858
+ *
1859
+ * @return string
1860
+ */
1861
+ public function filter_placeholder( $placeholder, $type = 'text' ) {
1862
+ return strip_tags( trim( $placeholder ) );
1863
+ }
1864
+
1865
+ /**
1866
+ * Returns filtered default options.
1867
+ * filter:{prefix}default_options
1868
+ * @since 2.4.13
1869
+ *
1870
+ * @param array $options Default options.
1871
+ * @param string $location Location.
1872
+ *
1873
+ * @return array
1874
+ */
1875
+ public function filter_default_options( $options, $location ) {
1876
+ if ( $location === 'settings' ) {
1877
+ $prefix = $this->get_prefix( $location ) . $location . '_';
1878
+ // Add image checker as default
1879
+ $options[ $prefix . 'customimg_checker' ] = 0;
1880
+ }
1881
+ return $options;
1882
+ }
1883
+ }
1884
  }
modules/aioseop_sitemap.php CHANGED
@@ -141,6 +141,18 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
141
  'gif',
142
  );
143
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * All_in_One_SEO_Pack_Sitemap constructor.
146
  */
@@ -825,7 +837,7 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
825
  *
826
  * @return string
827
  */
828
- private function get_filename() {
829
  $filename = 'sitemap';
830
  if ( ! empty( $this->options[ "{$this->prefix}filename" ] ) ) {
831
  $filename = $this->options[ "{$this->prefix}filename" ];
@@ -3338,10 +3350,13 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3338
  /**
3339
  * Return the images from the post.
3340
  *
3341
- * @param WP_Post|int $post the post object.
 
3342
  *
3343
  * @since 2.4
 
3344
  *
 
3345
  * @return array
3346
  */
3347
  private function get_images_from_post( $post ) {
@@ -3349,7 +3364,10 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3349
  return array();
3350
  }
3351
 
3352
- $images = array();
 
 
 
3353
 
3354
  if ( is_numeric( $post ) ) {
3355
  if ( 0 === $post ) {
@@ -3365,14 +3383,29 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3365
  }
3366
  $attributes = wp_get_attachment_image_src( $post->ID );
3367
  if ( $attributes ) {
3368
- $images[] = array(
3369
  'image:loc' => $this->clean_url( $attributes[0] ),
3370
  'image:caption' => wp_get_attachment_caption( $post->ID ),
3371
  'image:title' => get_the_title( $post->ID ),
3372
  );
3373
  }
3374
 
3375
- return $images;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3376
  }
3377
 
3378
  /**
@@ -3396,72 +3429,119 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3396
  }
3397
 
3398
  if ( isset( $post_thumbnails[ $post->ID ] ) ) {
3399
- $attachment_url = wp_get_attachment_image_url( $post_thumbnails[ $post->ID ], 'post-thumbnail' );
3400
- if ( $attachment_url ) {
3401
- $images[] = $attachment_url;
3402
- }
3403
  }
3404
 
3405
- $content = $post->post_content;
3406
 
3407
- $this->get_gallery_images( $post, $images );
3408
 
 
 
3409
  $content .= $this->get_content_from_galleries( $content );
3410
- $this->parse_content_for_images( $content, $images );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3411
 
3412
- if ( $images ) {
3413
- $tmp = $images;
3414
- if ( 1 < count( $images ) ) {
3415
- // Filter out duplicates.
3416
- $tmp = array_unique( $images );
 
 
 
 
 
 
 
 
 
3417
  }
 
3418
 
3419
- // remove any invalid/empty images.
3420
- $tmp = array_filter( $images, array( $this, 'is_image_valid' ) );
 
 
3421
 
3422
- $images = array();
3423
- foreach ( $tmp as $image ) {
3424
- $image_attributes = $this->get_image_attributes( $image );
 
 
 
 
 
3425
 
3426
- $images[] = array_merge(
3427
- array(
3428
- 'image:loc' => $this->clean_url( $image ),
3429
- ),
3430
- $image_attributes
 
 
 
 
 
 
 
 
 
3431
  );
3432
  }
3433
  }
3434
 
3435
- return $images;
 
 
 
 
 
 
 
 
 
 
 
 
 
3436
  }
3437
 
3438
  /**
3439
- * Fetch image attributes such as title and caption given the image URL.
3440
  *
3441
- * @param string $url The image URL.
3442
- * @return array
3443
  */
3444
- private function get_image_attributes( $url ) {
3445
- global $wpdb;
3446
- $attributes = array();
3447
-
3448
- $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $url ) );
3449
- if ( $attachment && is_array( $attachment ) && is_numeric( $attachment[0] ) ) {
3450
- $attributes = array(
3451
- 'image:caption' => wp_get_attachment_caption( $attachment[0] ),
3452
- 'image:title' => get_the_title( $attachment[0] ),
3453
- );
3454
  }
3455
- return $attributes;
3456
  }
3457
 
3458
  /**
3459
  * Fetch images from WP, Jetpack and WooCommerce galleries.
3460
  *
 
 
 
3461
  * @param WP_Post $post The post.
3462
  * @param array $images the array of images.
3463
- *
3464
- * @since 2.4.2
3465
  */
3466
  private function get_gallery_images( $post, &$images ) {
3467
  if ( false === apply_filters( 'aioseo_include_images_in_wp_gallery', true ) ) {
@@ -3471,6 +3551,13 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3471
  // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes.
3472
  if ( has_shortcode( $post->post_content, 'gallery' ) ) {
3473
  // Get the jetpack gallery images.
 
 
 
 
 
 
 
3474
  if ( class_exists( 'Jetpack_PostImages' ) ) {
3475
  $jetpack = Jetpack_PostImages::get_images( $post->ID );
3476
  if ( $jetpack ) {
@@ -3479,30 +3566,67 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3479
  }
3480
  }
3481
  }
 
3482
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3483
  // Get the default WP gallery images.
3484
  $galleries = get_post_galleries( $post, false );
3485
- if ( $galleries ) {
3486
  foreach ( $galleries as $gallery ) {
3487
- $images = array_merge( $images, $gallery['src'] );
 
 
 
 
 
 
 
 
 
 
 
 
3488
  }
3489
  }
3490
  }
3491
 
3492
  // Check WooCommerce product gallery.
3493
  if ( class_exists( 'WooCommerce' ) ) {
3494
- $woo_images = get_post_meta( $post->ID, '_product_image_gallery', true );
3495
  if ( ! empty( $woo_images ) ) {
3496
- $woo_images = array_filter( explode( ',', $woo_images ) );
3497
- if ( is_array( $woo_images ) ) {
3498
- foreach ( $woo_images as $id ) {
3499
- $images[] = wp_get_attachment_url( $id );
 
 
3500
  }
3501
  }
3502
  }
3503
  }
3504
 
3505
- $images = array_unique( $images );
3506
  }
3507
 
3508
  /**
@@ -3608,10 +3732,11 @@ if ( ! class_exists( 'All_in_One_SEO_Pack_Sitemap' ) ) {
3608
  *
3609
  * @since 2.4.1
3610
  * @since 2.4.3 Compatibility with Pre v4.7 wp_parse_url().
 
3611
  *
3612
  * @return bool
3613
  */
3614
- public function is_image_valid( $image ) {
3615
  global $wp_version;
3616
 
3617
  // Bail if empty image.
141
  'gif',
142
  );
143
 
144
+ /**
145
+ * Image IDs => URLs
146
+ *
147
+ * @since 2.11
148
+ *
149
+ * @var null|array $image_ids_urls {
150
+ * @type string $base_url The URL for the original sized image.
151
+ * @type string ${$id} Contains the URLs associated to the IDs.
152
+ * }
153
+ */
154
+ private $image_ids_urls = null;
155
+
156
  /**
157
  * All_in_One_SEO_Pack_Sitemap constructor.
158
  */
837
  *
838
  * @return string
839
  */
840
+ protected function get_filename() {
841
  $filename = 'sitemap';
842
  if ( ! empty( $this->options[ "{$this->prefix}filename" ] ) ) {
843
  $filename = $this->options[ "{$this->prefix}filename" ];
3350
  /**
3351
  * Return the images from the post.
3352
  *
3353
+ * @todo Add ~`get_attachment_postid_to_url()` function.
3354
+ * @todo Benchmark `wp_get_attachment_image_src()` & `wp_get_attachment_url()`.
3355
  *
3356
  * @since 2.4
3357
+ * @since 2.11 Optimization #2008 - Reduce the need to convert url to id.
3358
  *
3359
+ * @param WP_Post|int $post the post object.
3360
  * @return array
3361
  */
3362
  private function get_images_from_post( $post ) {
3364
  return array();
3365
  }
3366
 
3367
+ $rtn_image_attributes = array();
3368
+ $post_image_ids = array();
3369
+ $post_image_urls = array();
3370
+ $transient_update = false;
3371
 
3372
  if ( is_numeric( $post ) ) {
3373
  if ( 0 === $post ) {
3383
  }
3384
  $attributes = wp_get_attachment_image_src( $post->ID );
3385
  if ( $attributes ) {
3386
+ $rtn_image_attributes[] = array(
3387
  'image:loc' => $this->clean_url( $attributes[0] ),
3388
  'image:caption' => wp_get_attachment_caption( $post->ID ),
3389
  'image:title' => get_the_title( $post->ID ),
3390
  );
3391
  }
3392
 
3393
+ return $rtn_image_attributes;
3394
+ }
3395
+
3396
+ // Set Image IDs w/ URLs.
3397
+ if ( is_null( $this->image_ids_urls ) ) {
3398
+ // Get Transient/Cache data.
3399
+ if ( is_multisite() ) {
3400
+ $this->image_ids_urls = get_site_transient( 'aioseop_multisite_attachment_ids_urls' );
3401
+ } else {
3402
+ $this->image_ids_urls = get_transient( 'aioseop_attachment_ids_urls' );
3403
+ }
3404
+
3405
+ // Set default if no data exists.
3406
+ if ( false === $this->image_ids_urls ) {
3407
+ $this->image_ids_urls = array();
3408
+ }
3409
  }
3410
 
3411
  /**
3429
  }
3430
 
3431
  if ( isset( $post_thumbnails[ $post->ID ] ) ) {
3432
+ $post_image_ids[] = intval( $post_thumbnails[ $post->ID ] );
 
 
 
3433
  }
3434
 
3435
+ $post_image_ids = array_merge( $post_image_ids, $this->get_gallery_image_ids( $post ) );
3436
 
3437
+ $this->get_gallery_images( $post, $post_image_urls );
3438
 
3439
+ // Get image URLs from content.
3440
+ $content = $post->post_content;
3441
  $content .= $this->get_content_from_galleries( $content );
3442
+ $this->parse_content_for_images( $content, $post_image_urls );
3443
+
3444
+ if ( ! empty( $post_image_urls ) ) {
3445
+ // Remove any invalid/empty images.
3446
+ $post_image_urls = array_filter( $post_image_urls, array( $this, 'is_image_url_valid' ) );
3447
+
3448
+ // If possible, get ID from URL, and store the post's attachment ID => URL value.
3449
+ // This is to base the attachment query on the ID instead of the URL; which is less SQL intense.
3450
+ foreach ( $post_image_urls as $k1_index => &$v1_image_url ) {
3451
+ $v1_image_url = aiosp_common::absolutize_url( $v1_image_url );
3452
+ $attachment_id = aiosp_common::attachment_url_to_postid( $v1_image_url );
3453
+
3454
+ if ( $attachment_id ) {
3455
+ if ( ! isset( $this->image_ids_urls[ $attachment_id ] ) ) {
3456
+ // Use transient/cache data.
3457
+ $this->image_ids_urls[ $attachment_id ] = array( $v1_image_url );
3458
 
3459
+ $transient_update = true;
3460
+ } else {
3461
+ // If transient/cache data is already set, and URL is not already stored.
3462
+ if ( ! in_array( $v1_image_url, $this->image_ids_urls[ $attachment_id ], true ) ) {
3463
+ $this->image_ids_urls[ $attachment_id ][] = $v1_image_url;
3464
+
3465
+ $transient_update = true;
3466
+ }
3467
+ }
3468
+
3469
+ // Store and use ID instead.
3470
+ array_push( $post_image_ids, $attachment_id );
3471
+ unset( $post_image_urls[ $k1_index ] );
3472
+ }
3473
  }
3474
+ }
3475
 
3476
+ // Site's Images.
3477
+ if ( $post_image_ids ) {
3478
+ // Filter out duplicates.
3479
+ $post_image_ids = array_unique( $post_image_ids );
3480
 
3481
+ foreach ( $post_image_ids as $v1_image_id ) {
3482
+ // Set base URL to display later in this instance, or later (transient/cache) instances.
3483
+ // Converting ID from URL can also be heavy on memory & time.
3484
+ if ( ! isset( $this->image_ids_urls[ $v1_image_id ] ) ) {
3485
+ // Sets any remaining post image IDs that weren't converted from URL.
3486
+ $this->image_ids_urls[ $v1_image_id ] = array(
3487
+ 'base_url' => $this->clean_url( wp_get_attachment_url( $v1_image_id ) ),
3488
+ );
3489
 
3490
+ $transient_update = true;
3491
+ } else {
3492
+ if ( empty( $this->image_ids_urls[ $v1_image_id ]['base_url'] ) ) {
3493
+ $this->image_ids_urls[ $v1_image_id ]['base_url'] = $this->clean_url( wp_get_attachment_url( $v1_image_id ) );
3494
+
3495
+ $transient_update = true;
3496
+ }
3497
+ }
3498
+
3499
+ // Set return variable for image data/attributes.
3500
+ $rtn_image_attributes[] = array(
3501
+ 'image:loc' => $this->image_ids_urls[ $v1_image_id ]['base_url'],
3502
+ 'image:caption' => wp_get_attachment_caption( $v1_image_id ),
3503
+ 'image:title' => get_the_title( $v1_image_id ),
3504
  );
3505
  }
3506
  }
3507
 
3508
+ // External/Custom images remaining.
3509
+ if ( ! empty( $post_image_urls ) ) {
3510
+ foreach ( $post_image_urls as $v1_image_url ) {
3511
+ $rtn_image_attributes[] = array(
3512
+ 'image:loc' => $v1_image_url,
3513
+ );
3514
+ }
3515
+ }
3516
+
3517
+ if ( $transient_update ) {
3518
+ add_action( 'shutdown', array( $this, 'set_transient_attachment_ids_urls' ) );
3519
+ }
3520
+
3521
+ return $rtn_image_attributes;
3522
  }
3523
 
3524
  /**
3525
+ * Set Transient for Image IDs => URLs
3526
  *
3527
+ * @since 2.11
 
3528
  */
3529
+ public function set_transient_attachment_ids_urls() {
3530
+ if ( is_multisite() ) {
3531
+ set_site_transient( 'aioseop_multisite_attachment_ids_urls', $this->image_ids_urls, DAY_IN_SECONDS );
3532
+ } else {
3533
+ set_transient( 'aioseop_attachment_ids_urls', $this->image_ids_urls, DAY_IN_SECONDS );
 
 
 
 
 
3534
  }
 
3535
  }
3536
 
3537
  /**
3538
  * Fetch images from WP, Jetpack and WooCommerce galleries.
3539
  *
3540
+ * @since 2.4.2
3541
+ * @since 2.11 Optimization #2008 - Reduce the need to convert url to id.
3542
+ *
3543
  * @param WP_Post $post The post.
3544
  * @param array $images the array of images.
 
 
3545
  */
3546
  private function get_gallery_images( $post, &$images ) {
3547
  if ( false === apply_filters( 'aioseo_include_images_in_wp_gallery', true ) ) {
3551
  // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes.
3552
  if ( has_shortcode( $post->post_content, 'gallery' ) ) {
3553
  // Get the jetpack gallery images.
3554
+ // TODO Investigate other alternatives to retrieve ID instead. Specifically Jetpack data.
3555
+ /*
3556
+ * Is this even necessary? Jetpack uses many of the WP functions, some of which may already be in use.
3557
+ * This is also limited to 1 source, and doesn't check other sources once a value is obtained.
3558
+ *
3559
+ * @link https://hayashikejinan.com/wp-content/uploads/jetpack_api/classes/Jetpack_PostImages.html
3560
+ */
3561
  if ( class_exists( 'Jetpack_PostImages' ) ) {
3562
  $jetpack = Jetpack_PostImages::get_images( $post->ID );
3563
  if ( $jetpack ) {
3566
  }
3567
  }
3568
  }
3569
+ }
3570
 
3571
+ $images = array_unique( $images );
3572
+ }
3573
+
3574
+ /**
3575
+ * Get Gallery Image IDs
3576
+ *
3577
+ * @uses get_post_galleries()
3578
+ * @link https://developer.wordpress.org/reference/functions/get_post_galleries/
3579
+ *
3580
+ * @since 2.11
3581
+ *
3582
+ * @param WP_Post $post
3583
+ * @return array
3584
+ */
3585
+ private function get_gallery_image_ids( $post ) {
3586
+ $rtn_image_ids = array();
3587
+ if ( false === apply_filters( 'aioseo_include_images_in_wp_gallery', true ) ) {
3588
+ return $rtn_image_ids;
3589
+ }
3590
+
3591
+ // Check images galleries in the content. DO NOT run the_content filter here as it might cause issues with other shortcodes.
3592
+ if ( has_shortcode( $post->post_content, 'gallery' ) ) {
3593
  // Get the default WP gallery images.
3594
  $galleries = get_post_galleries( $post, false );
3595
+ if ( ! empty( $galleries ) ) {
3596
  foreach ( $galleries as $gallery ) {
3597
+ $gallery_ids = explode( ',', $gallery['ids'] );
3598
+
3599
+ if ( ! empty( $gallery_ids ) ) {
3600
+ foreach ( $gallery_ids as $image_id ) {
3601
+ // Skip if invalid id.
3602
+ if ( ! is_numeric( $image_id ) ) {
3603
+ continue;
3604
+ }
3605
+ $image_id = intval( $image_id );
3606
+
3607
+ array_push( $rtn_image_ids, $image_id );
3608
+ }
3609
+ }
3610
  }
3611
  }
3612
  }
3613
 
3614
  // Check WooCommerce product gallery.
3615
  if ( class_exists( 'WooCommerce' ) ) {
3616
+ $wc_image_ids = get_post_meta( $post->ID, '_product_image_gallery', true );
3617
  if ( ! empty( $woo_images ) ) {
3618
+ $wc_image_ids = array_filter( explode( ',', $wc_image_ids ) );
3619
+ foreach ( $wc_image_ids as $image_id ) {
3620
+ if ( is_numeric( $image_id ) ) {
3621
+ $image_id = intval( $image_id );
3622
+
3623
+ array_push( $rtn_image_ids, $image_id );
3624
  }
3625
  }
3626
  }
3627
  }
3628
 
3629
+ return array_unique( $rtn_image_ids );
3630
  }
3631
 
3632
  /**
3732
  *
3733
  * @since 2.4.1
3734
  * @since 2.4.3 Compatibility with Pre v4.7 wp_parse_url().
3735
+ * @since 2.11 Sitemap Optimization #2008 - Changed to a more appropriate name.
3736
  *
3737
  * @return bool
3738
  */
3739
+ public function is_image_url_valid( $image ) {
3740
  global $wp_version;
3741
 
3742
  // Bail if empty image.
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mrtor
4
  Tags: seo, all in one seo, google, twitter, page, image seo, social, search engine optimization, sitemap, WordPress SEO, meta, meta description, xml sitemap, google sitemap, sitemaps, robots meta, yahoo, bing, news sitemaps, multisite, canonical, nofollow, noindex, keywords, description, webmaster tools, google webmaster tools, google analytics
5
  Requires at least: 4.4
6
  Tested up to: 5.0
7
- Stable tag: 2.10.1
8
- License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  The original WordPress SEO plugin, downloaded over 50,000,000 times since 2007.
4
  Tags: seo, all in one seo, google, twitter, page, image seo, social, search engine optimization, sitemap, WordPress SEO, meta, meta description, xml sitemap, google sitemap, sitemaps, robots meta, yahoo, bing, news sitemaps, multisite, canonical, nofollow, noindex, keywords, description, webmaster tools, google webmaster tools, google analytics
5
  Requires at least: 4.4
6
  Tested up to: 5.0
7
+ Stable tag: 2.11
8
+ License: GPLv2 or11er
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
  The original WordPress SEO plugin, downloaded over 50,000,000 times since 2007.