Content Aware Sidebars – Unlimited Widget Areas - Version 3.15.2

Version Description

  • [new] performance improvements
  • [new] publishpress authors compatibility
  • [new] wordpress 5.7 support
  • [fixed] toolbar menu now supports theme areas registered without titles
  • [fixed] toolbar menu now displays nested custom sidebars properly
  • [updated] ui improvements for screen readers
  • [updated] wp-content-aware-engine library
  • [updated] freemius sdk

Pro Plan:

  • [fixed] url condition compatible with wordpress installed in subdirectories
  • [fixed] acf condition supports more field types
Download this release

Release Info

Developer intoxstudio
Plugin Icon 128x128 Content Aware Sidebars – Unlimited Widget Areas
Version 3.15.2
Comparing to
See all releases

Code changes from version 3.15.1 to 3.15.2

Files changed (69) hide show
  1. admin/admin_bar.php +14 -2
  2. admin/db-updates.php +75 -40
  3. admin/quick_select.php +0 -1
  4. admin/sidebar-edit.php +1 -3
  5. admin/sidebar-list-table.php +1 -2
  6. admin/sidebar-overview.php +3 -5
  7. app.php +9 -4
  8. content-aware-sidebars.php +1 -1
  9. freemius.php +1 -0
  10. lib/freemius/assets/css/admin/common.css +1 -1
  11. lib/freemius/assets/css/admin/connect.css +1 -1
  12. lib/freemius/includes/class-freemius.php +79 -41
  13. lib/freemius/includes/class-fs-logger.php +2 -2
  14. lib/freemius/includes/entities/class-fs-site.php +17 -0
  15. lib/freemius/includes/entities/class-fs-user.php +0 -17
  16. lib/freemius/languages/freemius-cs_CZ.mo +0 -0
  17. lib/freemius/languages/freemius-da_DK.mo +0 -0
  18. lib/freemius/languages/freemius-en.mo +0 -0
  19. lib/freemius/languages/freemius-es_ES.mo +0 -0
  20. lib/freemius/languages/freemius-fr_FR.mo +0 -0
  21. lib/freemius/languages/freemius-he_IL.mo +0 -0
  22. lib/freemius/languages/freemius-hu_HU.mo +0 -0
  23. lib/freemius/languages/freemius-it_IT.mo +0 -0
  24. lib/freemius/languages/freemius-ja.mo +0 -0
  25. lib/freemius/languages/freemius-nl_NL.mo +0 -0
  26. lib/freemius/languages/freemius-ru_RU.mo +0 -0
  27. lib/freemius/languages/freemius-ta.mo +0 -0
  28. lib/freemius/languages/freemius-zh_CN.mo +0 -0
  29. lib/freemius/start.php +3 -3
  30. lib/freemius/templates/account.php +5 -3
  31. lib/freemius/templates/connect.php +49 -37
  32. lib/freemius/templates/forms/license-activation.php +3 -1
  33. lib/wp-content-aware-engine/assets/css/index.php +2 -2
  34. lib/wp-content-aware-engine/assets/index.php +2 -2
  35. lib/wp-content-aware-engine/assets/js/condition_groups.min.js +7 -7
  36. lib/wp-content-aware-engine/assets/js/index.php +2 -2
  37. lib/wp-content-aware-engine/bootstrap.php +3 -3
  38. lib/wp-content-aware-engine/core.php +1253 -1252
  39. lib/wp-content-aware-engine/index.php +1 -1
  40. lib/wp-content-aware-engine/meta.php +238 -238
  41. lib/wp-content-aware-engine/module/author.php +113 -113
  42. lib/wp-content-aware-engine/module/base.php +16 -16
  43. lib/wp-content-aware-engine/module/bbpress.php +111 -111
  44. lib/wp-content-aware-engine/module/bp_member.php +173 -173
  45. lib/wp-content-aware-engine/module/date.php +80 -80
  46. lib/wp-content-aware-engine/module/page_template.php +100 -100
  47. lib/wp-content-aware-engine/module/pods.php +124 -124
  48. lib/wp-content-aware-engine/module/polylang.php +118 -118
  49. lib/wp-content-aware-engine/module/post_type.php +550 -548
  50. lib/wp-content-aware-engine/module/qtranslate.php +111 -111
  51. lib/wp-content-aware-engine/module/static.php +106 -106
  52. lib/wp-content-aware-engine/module/taxonomy.php +59 -60
  53. lib/wp-content-aware-engine/module/translatepress.php +88 -88
  54. lib/wp-content-aware-engine/module/transposh.php +104 -104
  55. lib/wp-content-aware-engine/module/wpml.php +91 -91
  56. lib/wp-content-aware-engine/objectmanager.php +145 -145
  57. lib/wp-content-aware-engine/typemanager.php +107 -107
  58. lib/wp-content-aware-engine/view.php +124 -124
  59. lib/wp-content-aware-engine/view/index.php +2 -2
  60. lib/wp-content-aware-engine/view/meta_box.php +35 -35
  61. readme.txt +18 -2
  62. sidebar.php +8 -0
  63. view/meta_box_advanced.php +5 -4
  64. view/meta_box_design.php +15 -30
  65. view/meta_box_html.php +7 -5
  66. view/meta_box_status.php +4 -5
  67. view/meta_box_submit.php +1 -1
  68. view/meta_box_support.php +2 -2
  69. view/notice_review.php +2 -5
admin/admin_bar.php CHANGED
@@ -150,9 +150,12 @@ class CAS_Admin_Bar
150
 
151
  $args = [];
152
  foreach ($this->theme_sidebars as $index => $has_widgets) {
 
 
 
153
  $args[] = [
154
  'id' => $index,
155
- 'title' => $wp_registered_sidebars[$index]['name'] . ($has_widgets ? '' : ' ('.__('Hidden').')'),
156
  ];
157
  }
158
  $this->add_nodes($admin_bar, $args, self::NODE_THEME_AREAS);
@@ -167,7 +170,7 @@ class CAS_Admin_Bar
167
 
168
  $args = [];
169
  foreach ($this->custom_sidebars as $id => $has_widgets) {
170
- $sidebar = CAS_App::instance()->_manager->sidebars[$id];
171
  $args[] = [
172
  'id' => $sidebar->ID,
173
  'title' => $sidebar->post_title,
@@ -244,5 +247,14 @@ class CAS_Admin_Bar
244
  } else {
245
  $this->custom_sidebars[$index] = $has_widgets;
246
  }
 
 
 
 
 
 
 
 
 
247
  }
248
  }
150
 
151
  $args = [];
152
  foreach ($this->theme_sidebars as $index => $has_widgets) {
153
+ $sidebar_name = isset($wp_registered_sidebars[$index]['name'])
154
+ ? $wp_registered_sidebars[$index]['name']
155
+ : $index;
156
  $args[] = [
157
  'id' => $index,
158
+ 'title' => $sidebar_name . ($has_widgets ? '' : ' ('.__('Hidden').')'),
159
  ];
160
  }
161
  $this->add_nodes($admin_bar, $args, self::NODE_THEME_AREAS);
170
 
171
  $args = [];
172
  foreach ($this->custom_sidebars as $id => $has_widgets) {
173
+ $sidebar = CAS_App::instance()->manager()->sidebars[$id];
174
  $args[] = [
175
  'id' => $sidebar->ID,
176
  'title' => $sidebar->post_title,
247
  } else {
248
  $this->custom_sidebars[$index] = $has_widgets;
249
  }
250
+ $this->detect_sidebar_target($has_widgets, $index);
251
+ }
252
+
253
+ private function detect_sidebar_target($has_widgets, $index)
254
+ {
255
+ $host_map = CAS_App::instance()->manager()->get_replacement_map();
256
+ if (isset($host_map[$index])) {
257
+ $this->detect_sidebar($has_widgets, $host_map[$index]);
258
+ }
259
  }
260
  }
admin/db-updates.php CHANGED
@@ -17,52 +17,87 @@ $cas_db_updater->register_version_update('3.4', 'cas_update_to_34');
17
  $cas_db_updater->register_version_update('3.5.1', 'cas_update_to_351');
18
  $cas_db_updater->register_version_update('3.8', 'cas_update_to_38');
19
  $cas_db_updater->register_version_update('3.15', 'cas_update_to_315');
 
20
 
21
- /**
22
- * Enable legacy date module and
23
- * negated conditions if in use
24
- *
25
- * @since 3.15
26
- *
27
- * @return bool
28
- */
29
- function cas_update_to_315()
30
- {
31
- global $wpdb;
32
-
33
- $types = WPCACore::types()->get_all();
34
-
35
- $options = [
36
- 'legacy.date_module' => [],
37
- 'legacy.negated_conditions' => []
38
- ];
39
 
40
- $options['legacy.date_module'] = array_flip((array)$wpdb->get_col("
41
- SELECT p.post_type FROM $wpdb->posts p
42
- INNER JOIN $wpdb->posts c on p.ID = c.post_parent
43
- INNER JOIN $wpdb->postmeta m on c.ID = m.post_id
44
- WHERE c.post_type = 'condition_group' AND m.meta_key = '_ca_date'
45
- "));
46
-
47
- $options['legacy.negated_conditions'] = array_flip((array)$wpdb->get_col("
48
- SELECT p.post_type FROM $wpdb->posts p
49
- INNER JOIN $wpdb->posts c on p.ID = c.post_parent
50
- WHERE c.post_type = 'condition_group' AND c.post_status = 'negated'
51
- "));
52
-
53
- foreach ($types as $type => $val) {
54
- foreach ($options as $option => $post_types) {
55
- if (isset($post_types[$type])) {
56
- WPCACore::save_option($type, $option, true);
57
- } elseif (WPCACore::get_option($type, $option, false)) {
58
- WPCACore::save_option($type, $option, false);
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  }
61
  }
62
-
63
- return true;
64
  }
65
 
 
 
 
66
 
67
  /**
68
  * Update to version 3.8
17
  $cas_db_updater->register_version_update('3.5.1', 'cas_update_to_351');
18
  $cas_db_updater->register_version_update('3.8', 'cas_update_to_38');
19
  $cas_db_updater->register_version_update('3.15', 'cas_update_to_315');
20
+ $cas_db_updater->register_version_update('3.15.2', 'cas_update_to_3152');
21
 
22
+ /**
23
+ * Add -1 to condition groups with select terms
24
+ *
25
+ * @since 3.15.2
26
+ *
27
+ * @return bool
28
+ */
29
+ function cas_update_to_3152()
30
+ {
31
+ $taxonomies = array_map(function ($value) {
32
+ return "'" . esc_sql($value) . "'";
33
+ }, get_taxonomies(['public' => true]));
 
 
 
 
 
 
34
 
35
+ if (empty($taxonomies)) {
36
+ return true;
37
+ }
38
+
39
+ global $wpdb;
40
+
41
+ $condition_group_ids = array_unique((array)$wpdb->get_col("
42
+ SELECT p.ID FROM $wpdb->posts p
43
+ INNER JOIN $wpdb->term_relationships r ON r.object_id = p.ID
44
+ INNER JOIN $wpdb->term_taxonomy t ON t.term_taxonomy_id = r.term_taxonomy_id
45
+ WHERE p.post_type = 'condition_group'
46
+ AND t.taxonomy IN (".implode(',', $taxonomies).')
47
+ '));
48
+
49
+ foreach ($condition_group_ids as $id) {
50
+ add_post_meta($id, '_ca_taxonomy', '-1');
51
+ }
52
+
53
+ return true;
54
+ }
55
+
56
+ /**
57
+ * Enable legacy date module and
58
+ * negated conditions if in use
59
+ *
60
+ * @since 3.15
61
+ *
62
+ * @return bool
63
+ */
64
+ function cas_update_to_315()
65
+ {
66
+ global $wpdb;
67
+
68
+ $types = WPCACore::types()->get_all();
69
+
70
+ $options = [
71
+ 'legacy.date_module' => [],
72
+ 'legacy.negated_conditions' => []
73
+ ];
74
+
75
+ $options['legacy.date_module'] = array_flip((array)$wpdb->get_col("
76
+ SELECT p.post_type FROM $wpdb->posts p
77
+ INNER JOIN $wpdb->posts c on p.ID = c.post_parent
78
+ INNER JOIN $wpdb->postmeta m on c.ID = m.post_id
79
+ WHERE c.post_type = 'condition_group' AND m.meta_key = '_ca_date'
80
+ "));
81
+
82
+ $options['legacy.negated_conditions'] = array_flip((array)$wpdb->get_col("
83
+ SELECT p.post_type FROM $wpdb->posts p
84
+ INNER JOIN $wpdb->posts c on p.ID = c.post_parent
85
+ WHERE c.post_type = 'condition_group' AND c.post_status = 'negated'
86
+ "));
87
+
88
+ foreach ($types as $type => $val) {
89
+ foreach ($options as $option => $post_types) {
90
+ if (isset($post_types[$type])) {
91
+ WPCACore::save_option($type, $option, true);
92
+ } elseif (WPCACore::get_option($type, $option, false)) {
93
+ WPCACore::save_option($type, $option, false);
94
  }
95
  }
 
 
96
  }
97
 
98
+ return true;
99
+ }
100
+
101
 
102
  /**
103
  * Update to version 3.8
admin/quick_select.php CHANGED
@@ -193,7 +193,6 @@ class CAS_Quick_Select
193
 
194
  if ($condition_group_id) {
195
  add_post_meta($condition_group_id, $meta_key, $post_id);
196
- //add_post_meta($condition_group_id, $meta_key.'_direct', 1);
197
  }
198
  }
199
  }
193
 
194
  if ($condition_group_id) {
195
  add_post_meta($condition_group_id, $meta_key, $post_id);
 
196
  }
197
  }
198
  }
admin/sidebar-edit.php CHANGED
@@ -694,8 +694,6 @@ final class CAS_Sidebar_Edit extends CAS_Admin
694
  CAS_App::instance()->manager()->populate_metadata();
695
  $path = plugin_dir_path(dirname(__FILE__)).'view/';
696
 
697
- $cas_fs = cas_fs();
698
-
699
  $boxes = [];
700
  $boxes[] = [
701
  'id' => 'submitdiv',
@@ -945,7 +943,7 @@ final class CAS_Sidebar_Edit extends CAS_Admin
945
  $this->enqueue_style('flatpickr', 'flatpickr.dark.min', [], '3.0.6');
946
  wp_enqueue_style('wp-color-picker');
947
 
948
- $metadata = CAS_App::instance()->_manager->metadata();
949
  $visibility = [];
950
  $target = [];
951
  foreach ($metadata->get('visibility')->get_input_list() as $category_key => $category) {
694
  CAS_App::instance()->manager()->populate_metadata();
695
  $path = plugin_dir_path(dirname(__FILE__)).'view/';
696
 
 
 
697
  $boxes = [];
698
  $boxes[] = [
699
  'id' => 'submitdiv',
943
  $this->enqueue_style('flatpickr', 'flatpickr.dark.min', [], '3.0.6');
944
  wp_enqueue_style('wp-color-picker');
945
 
946
+ $metadata = CAS_App::instance()->manager()->metadata();
947
  $visibility = [];
948
  $target = [];
949
  foreach ($metadata->get('visibility')->get_input_list() as $category_key => $category) {
admin/sidebar-list-table.php CHANGED
@@ -335,12 +335,11 @@ class CAS_Sidebar_List_Table extends WP_List_Table
335
  */
336
  public function get_sortable_columns()
337
  {
338
- $columns = [
339
  'title' => ['title', true],
340
  'status' => 'post_status',
341
  'handler' => 'meta_handle'
342
  ];
343
- return $columns;
344
  }
345
 
346
  /**
335
  */
336
  public function get_sortable_columns()
337
  {
338
+ return [
339
  'title' => ['title', true],
340
  'status' => 'post_status',
341
  'handler' => 'meta_handle'
342
  ];
 
343
  }
344
 
345
  /**
admin/sidebar-overview.php CHANGED
@@ -39,7 +39,7 @@ final class CAS_Sidebar_Overview extends CAS_Admin
39
  {
40
  global $_wp_last_object_menu;
41
 
42
- $post_type_object = get_post_type_object(CAS_App::TYPE_SIDEBAR);
43
 
44
  $notification_label = $this->notification_count ? sprintf(' <span class="awaiting-mod">%d</span>', $this->notification_count) : '';
45
 
@@ -143,7 +143,6 @@ final class CAS_Sidebar_Overview extends CAS_Admin
143
  */
144
  public function process_actions()
145
  {
146
- $post_type = CAS_App::TYPE_SIDEBAR;
147
  $doaction = $this->table->current_action();
148
 
149
  if ($doaction) {
@@ -248,8 +247,6 @@ final class CAS_Sidebar_Overview extends CAS_Admin
248
  break;
249
  case 'delete':
250
  foreach ($post_ids as $post_id) {
251
- $post_del = get_post($post_id);
252
-
253
  if (!current_user_can('delete_post', $post_id)) {
254
  wp_die(__('You are not allowed to delete this item.'));
255
  }
@@ -261,6 +258,8 @@ final class CAS_Sidebar_Overview extends CAS_Admin
261
  }
262
  $sendback = add_query_arg('deleted', $handled, $sendback);
263
  break;
 
 
264
  }
265
 
266
  $sendback = remove_query_arg(['action', 'action2', 'post_status', 'post', 'bulk_edit'], $sendback);
@@ -292,7 +291,6 @@ final class CAS_Sidebar_Overview extends CAS_Admin
292
 
293
  public function bulk_messages()
294
  {
295
- $manage_widgets = sprintf(' <a href="%1$s">%2$s</a>', 'widgets.php', __('Manage widgets', 'content-aware-sidebars'));
296
  $bulk_messages = [
297
  'updated' => _n_noop('%s sidebar updated.', '%s sidebars updated.', 'content-aware-sidebars'),
298
  'locked' => _n_noop('%s sidebar not updated, somebody is editing it.', '%s sidebars not updated, somebody is editing them.', 'content-aware-sidebars'),
39
  {
40
  global $_wp_last_object_menu;
41
 
42
+ $post_type_object = $this->get_sidebar_type();
43
 
44
  $notification_label = $this->notification_count ? sprintf(' <span class="awaiting-mod">%d</span>', $this->notification_count) : '';
45
 
143
  */
144
  public function process_actions()
145
  {
 
146
  $doaction = $this->table->current_action();
147
 
148
  if ($doaction) {
247
  break;
248
  case 'delete':
249
  foreach ($post_ids as $post_id) {
 
 
250
  if (!current_user_can('delete_post', $post_id)) {
251
  wp_die(__('You are not allowed to delete this item.'));
252
  }
258
  }
259
  $sendback = add_query_arg('deleted', $handled, $sendback);
260
  break;
261
+ default:
262
+ break;
263
  }
264
 
265
  $sendback = remove_query_arg(['action', 'action2', 'post_status', 'post', 'bulk_edit'], $sendback);
291
 
292
  public function bulk_messages()
293
  {
 
294
  $bulk_messages = [
295
  'updated' => _n_noop('%s sidebar updated.', '%s sidebars updated.', 'content-aware-sidebars'),
296
  'locked' => _n_noop('%s sidebar not updated, somebody is editing it.', '%s sidebars not updated, somebody is editing them.', 'content-aware-sidebars'),
app.php CHANGED
@@ -11,7 +11,7 @@ defined('ABSPATH') || exit;
11
  final class CAS_App
12
  {
13
  const PLUGIN_VERSION_KEY = 'cas_db_version';
14
- const PLUGIN_VERSION = '3.15.1';
15
 
16
  /**
17
  * Prefix for sidebar id
@@ -45,6 +45,9 @@ final class CAS_App
45
  */
46
  const META_PREFIX = '_ca_';
47
 
 
 
 
48
  private $manager;
49
 
50
  /**
@@ -53,7 +56,6 @@ final class CAS_App
53
  private $db_updater;
54
 
55
  /**
56
- * Class singleton
57
  * @var CAS_App
58
  */
59
  private static $_instance;
@@ -73,7 +75,7 @@ final class CAS_App
73
 
74
  public function __construct()
75
  {
76
- $this->_manager = new CAS_Sidebar_Manager();
77
 
78
  $this->db_updater = new WP_DB_Updater(self::PLUGIN_VERSION_KEY, self::PLUGIN_VERSION, true);
79
 
@@ -99,9 +101,12 @@ final class CAS_App
99
  return $this->db_updater;
100
  }
101
 
 
 
 
102
  public function manager()
103
  {
104
- return $this->_manager;
105
  }
106
 
107
  /**
11
  final class CAS_App
12
  {
13
  const PLUGIN_VERSION_KEY = 'cas_db_version';
14
+ const PLUGIN_VERSION = '3.15.2';
15
 
16
  /**
17
  * Prefix for sidebar id
45
  */
46
  const META_PREFIX = '_ca_';
47
 
48
+ /**
49
+ * @var CAS_Sidebar_Manager
50
+ */
51
  private $manager;
52
 
53
  /**
56
  private $db_updater;
57
 
58
  /**
 
59
  * @var CAS_App
60
  */
61
  private static $_instance;
75
 
76
  public function __construct()
77
  {
78
+ $this->manager = new CAS_Sidebar_Manager();
79
 
80
  $this->db_updater = new WP_DB_Updater(self::PLUGIN_VERSION_KEY, self::PLUGIN_VERSION, true);
81
 
101
  return $this->db_updater;
102
  }
103
 
104
+ /**
105
+ * @return CAS_Sidebar_Manager
106
+ */
107
  public function manager()
108
  {
109
+ return $this->manager;
110
  }
111
 
112
  /**
content-aware-sidebars.php CHANGED
@@ -9,7 +9,7 @@
9
  Plugin Name: Content Aware Sidebars
10
  Plugin URI: https://dev.institute/wordpress-sidebars/
11
  Description: Unlimited custom sidebars and widget areas for any post, page, category etc.
12
- Version: 3.15.1
13
  Author: Joachim Jensen - DEV Institute
14
  Author URI: https://dev.institute
15
  Requires at least: 4.9
9
  Plugin Name: Content Aware Sidebars
10
  Plugin URI: https://dev.institute/wordpress-sidebars/
11
  Description: Unlimited custom sidebars and widget areas for any post, page, category etc.
12
+ Version: 3.15.2
13
  Author: Joachim Jensen - DEV Institute
14
  Author URI: https://dev.institute
15
  Requires at least: 4.9
freemius.php CHANGED
@@ -79,6 +79,7 @@ $cas_fs->add_filter(
79
  );
80
  $cas_fs->add_filter( 'show_affiliate_program_notice', '__return_false' );
81
  $cas_fs->add_filter( 'plugin_icon', 'cas_fs_get_plugin_icon' );
 
82
  function cas_fs_upgrade()
83
  {
84
  global $cas_fs ;
79
  );
80
  $cas_fs->add_filter( 'show_affiliate_program_notice', '__return_false' );
81
  $cas_fs->add_filter( 'plugin_icon', 'cas_fs_get_plugin_icon' );
82
+ $cas_fs->add_filter( 'permission_extensions_default', '__return_true' );
83
  function cas_fs_upgrade()
84
  {
85
  global $cas_fs ;
lib/freemius/assets/css/admin/common.css CHANGED
@@ -1,2 +1,2 @@
1
  .fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:white;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3)}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{position:relative;top:0;margin-top:10px;text-align:center}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{position:relative;display:inline-block;color:#ccc;text-shadow:0 1px 1px rgba(255,255,255,0.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);background:#ececec;box-shadow:0 0 4px rgba(0,0,0,0.1),inset 0 1px 3px 0 rgba(0,0,0,0.1);cursor:pointer}.fs-switch span{display:inline-block;width:35px;text-transform:uppercase}.fs-switch .fs-toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.3);border-radius:4px;background:#fff;background-color:#fff;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ececec), color-stop(1, #fff));background-image:-webkit-linear-gradient(top, #ececec, #fff);background-image:-moz-linear-gradient(top, #ececec, #fff);background-image:-ms-linear-gradient(top, #ececec, #fff);background-image:-o-linear-gradient(top, #ececec, #fff);background-image:linear-gradient(top, bottom, #ececec, #fff);box-shadow:inset 0 1px 0 0 rgba(255,255,255,0.5);z-index:999;-moz-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-o-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-ms-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-webkit-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1)}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{top:8px;padding:4px 25px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round .fs-toggle{top:0;width:24px;height:24px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{top:0;width:18px;height:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}.fs-switch-feedback{margin-left:10px}.fs-switch-feedback.success{color:#71ae00}.rtl .fs-switch-feedback{margin-left:0;margin-right:10px}#fs_frame{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media (max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}
2
- .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 500px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
1
  .fs-badge{position:absolute;top:10px;right:0;background:#71ae00;color:white;text-transform:uppercase;padding:5px 10px;-moz-border-radius:3px 0 0 3px;-webkit-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;font-weight:bold;border-right:0;-moz-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);-webkit-box-shadow:0 2px 1px -1px rgba(0,0,0,0.3);box-shadow:0 2px 1px -1px rgba(0,0,0,0.3)}.theme-browser .theme .fs-premium-theme-badge-container{position:absolute;right:0;top:0}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge{position:relative;top:0;margin-top:10px;text-align:center}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-premium-theme-badge{font-size:1.1em}.theme-browser .theme .fs-premium-theme-badge-container .fs-badge.fs-beta-theme-badge{background:#00a0d2}.fs-switch{position:relative;display:inline-block;color:#ccc;text-shadow:0 1px 1px rgba(255,255,255,0.8);height:18px;padding:6px 6px 5px 6px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);background:#ececec;box-shadow:0 0 4px rgba(0,0,0,0.1),inset 0 1px 3px 0 rgba(0,0,0,0.1);cursor:pointer}.fs-switch span{display:inline-block;width:35px;text-transform:uppercase}.fs-switch .fs-toggle{position:absolute;top:1px;width:37px;height:25px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.3);border-radius:4px;background:#fff;background-color:#fff;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ececec), color-stop(1, #fff));background-image:-webkit-linear-gradient(top, #ececec, #fff);background-image:-moz-linear-gradient(top, #ececec, #fff);background-image:-ms-linear-gradient(top, #ececec, #fff);background-image:-o-linear-gradient(top, #ececec, #fff);background-image:linear-gradient(top, bottom, #ececec, #fff);box-shadow:inset 0 1px 0 0 rgba(255,255,255,0.5);z-index:999;-moz-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-o-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-ms-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);-webkit-transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1);transition:0.4s cubic-bezier(0.54, 1.6, 0.5, 1)}.fs-switch.fs-off .fs-toggle{left:2%}.fs-switch.fs-on .fs-toggle{left:54%}.fs-switch.fs-round{top:8px;padding:4px 25px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round .fs-toggle{top:0;width:24px;height:24px;-moz-border-radius:24px;-webkit-border-radius:24px;border-radius:24px}.fs-switch.fs-round.fs-off .fs-toggle{left:-1px}.fs-switch.fs-round.fs-on{background:#0085ba}.fs-switch.fs-round.fs-on .fs-toggle{left:25px}.fs-switch.fs-small.fs-round{padding:1px 19px}.fs-switch.fs-small.fs-round .fs-toggle{top:0;width:18px;height:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px}.fs-switch.fs-small.fs-round.fs-on .fs-toggle{left:19px}.fs-switch-feedback{margin-left:10px}.fs-switch-feedback.success{color:#71ae00}.rtl .fs-switch-feedback{margin-left:0;margin-right:10px}#fs_frame{line-height:0;font-size:0}.fs-full-size-wrapper{margin:40px 0 -65px -20px}@media (max-width: 600px){.fs-full-size-wrapper{margin:0 0 -65px -10px}}
2
+ .fs-notice{position:relative}.fs-notice.fs-has-title{margin-bottom:30px !important}.fs-notice.success{color:green}.fs-notice.promotion{border-color:#00a0d2 !important;background-color:#f2fcff !important}.fs-notice .fs-notice-body{margin:.5em 0;padding:2px}.fs-notice .fs-close{cursor:pointer;color:#aaa;float:right}.fs-notice .fs-close:hover{color:#666}.fs-notice .fs-close>*{margin-top:7px;display:inline-block}.fs-notice label.fs-plugin-title{background:rgba(0,0,0,0.3);color:#fff;padding:2px 10px;position:absolute;top:100%;bottom:auto;right:auto;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;left:10px;font-size:12px;font-weight:bold;cursor:auto}div.fs-notice.updated,div.fs-notice.success,div.fs-notice.promotion{display:block !important}.rtl .fs-notice .fs-close{float:left}.fs-secure-notice{position:fixed;top:32px;left:160px;right:0;background:#ebfdeb;padding:10px 20px;color:green;z-index:9999;-moz-box-shadow:0 2px 2px rgba(6,113,6,0.3);-webkit-box-shadow:0 2px 2px rgba(6,113,6,0.3);box-shadow:0 2px 2px rgba(6,113,6,0.3);opacity:0.95;filter:alpha(opacity=95)}.fs-secure-notice:hover{opacity:1;filter:alpha(opacity=100)}.fs-secure-notice a.fs-security-proof{color:green;text-decoration:none}@media screen and (max-width: 960px){.fs-secure-notice{left:36px}}@media screen and (max-width: 600px){.fs-secure-notice{display:none}}@media screen and (max-width: 1250px){#fs_promo_tab{display:none}}@media screen and (max-width: 782px){.fs-secure-notice{left:0;top:46px;text-align:center}}span.fs-submenu-item.fs-sub:before{content:'\21B3';padding:0 5px}.rtl span.fs-submenu-item.fs-sub:before{content:'\21B2'}.fs-submenu-item.pricing.upgrade-mode{color:greenyellow}.fs-submenu-item.pricing.trial-mode{color:#83e2ff}#adminmenu .update-plugins.fs-trial{background-color:#00b9eb}.fs-ajax-spinner{border:0;width:20px;height:20px;margin-right:5px;vertical-align:sub;display:inline-block;background:url("/wp-admin/images/wpspin_light-2x.gif");background-size:contain;margin-bottom:-2px}.wrap.fs-section h2{text-align:left}.plugins p.fs-upgrade-notice{border:0;background-color:#d54e21;padding:10px;color:#f9f9f9;margin-top:10px}
lib/freemius/assets/css/admin/connect.css CHANGED
@@ -1 +1 @@
1
- #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{margin-right:15px;float:right;height:26px;vertical-align:middle;line-height:37px;font-weight:bold;border-bottom:1px dashed;text-decoration:none}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions .fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li .fs-switch{float:right}#fs_connect .fs-permissions ul li .fs-permission-description{margin-left:55px}#fs_connect .fs-permissions ul li .fs-permission-description span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:#C2EEFF;text-decoration:underline}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out;position:absolute;background:rgba(0,0,0,0.8);color:#fff;font-family:'arial', serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:0;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);line-height:1.3em;font-weight:bold;text-align:left}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right}.fs-tooltip-trigger .fs-tooltip::after{content:' ';display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,0.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}#fs_marketing_optin{display:none;margin-top:10px;border:1px solid #ccc;padding:10px;line-height:1.5em}#fs_marketing_optin .fs-message{display:block;margin-bottom:5px;font-size:1.05em;font-weight:600}#fs_marketing_optin.error{border:1px solid #d3135a;background:#fee}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{margin-top:5px;display:block}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li .fs-switch{float:left}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,0.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:white;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:52px;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms{background:rgba(140,140,140,0.64)}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}
1
+ #fs_connect{width:480px;-moz-box-shadow:0px 1px 2px rgba(0,0,0,0.3);-webkit-box-shadow:0px 1px 2px rgba(0,0,0,0.3);box-shadow:0px 1px 2px rgba(0,0,0,0.3);margin:20px 0}@media screen and (max-width: 479px){#fs_connect{-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;width:auto;margin:0 0 0 -10px}}#fs_connect .fs-content{background:#fff;padding:15px 20px}#fs_connect .fs-content .fs-error{background:snow;color:#d3135a;border:1px solid #d3135a;-moz-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);text-align:center;padding:5px;margin-bottom:10px}#fs_connect .fs-content p{margin:0;padding:0;font-size:1.2em}#fs_connect .fs-license-key-container{position:relative;width:280px;margin:10px auto 0 auto}#fs_connect .fs-license-key-container input{width:100%}#fs_connect .fs-license-key-container .dashicons{position:absolute;top:5px;right:5px}#fs_connect.require-license-key .fs-sites-list-container td{cursor:pointer}#fs_connect #delegate_to_site_admins{margin-right:15px;float:right;height:26px;vertical-align:middle;line-height:37px;font-weight:bold;border-bottom:1px dashed;text-decoration:none}#fs_connect #delegate_to_site_admins.rtl{margin-left:15px;margin-right:0}#fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}#fs_connect .fs-actions .button{padding:0 10px 1px;line-height:35px;height:37px;font-size:16px;margin-bottom:0}#fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}#fs_connect .fs-actions .button.button-primary{padding-right:15px;padding-left:15px}#fs_connect .fs-actions .button.button-primary:after{content:' \279C'}#fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}#fs_connect .fs-actions .button.button-secondary{float:right}#fs_connect.fs-anonymous-disabled .fs-actions .button.button-primary{width:100%}#fs_connect .fs-permissions{padding:10px 20px;background:#FEFEFE;-moz-transition:background 0.5s ease;-o-transition:background 0.5s ease;-ms-transition:background 0.5s ease;-webkit-transition:background 0.5s ease;transition:background 0.5s ease}#fs_connect .fs-permissions .fs-license-sync-disclaimer{text-align:center;margin-top:0}#fs_connect .fs-permissions>.fs-trigger{font-size:0.9em;text-decoration:none;text-align:center;display:block}#fs_connect .fs-permissions ul{height:0;overflow:hidden;margin:0}#fs_connect .fs-permissions ul li{margin-bottom:12px}#fs_connect .fs-permissions ul li:last-child{margin-bottom:0}#fs_connect .fs-permissions ul li>i.dashicons{float:left;font-size:40px;width:40px;height:40px}#fs_connect .fs-permissions ul li .fs-switch{float:right}#fs_connect .fs-permissions ul li .fs-permission-description{margin-left:55px}#fs_connect .fs-permissions ul li .fs-permission-description span{font-weight:bold;text-transform:uppercase;color:#23282d}#fs_connect .fs-permissions ul li .fs-permission-description p{margin:2px 0 0 0}#fs_connect .fs-permissions.fs-open{background:#fff}#fs_connect .fs-permissions.fs-open ul{overflow:initial;height:auto;margin:20px 20px 10px 20px}@media screen and (max-width: 479px){#fs_connect .fs-permissions{background:#fff}#fs_connect .fs-permissions .fs-trigger{display:none}#fs_connect .fs-permissions ul{height:auto;margin:20px}}#fs_connect .fs-freemium-licensing{padding:8px;background:#777;color:#fff}#fs_connect .fs-freemium-licensing p{text-align:center;display:block;margin:0;padding:0}#fs_connect .fs-freemium-licensing a{color:#C2EEFF;text-decoration:underline}#fs_connect .fs-visual{padding:12px;line-height:0;background:#fafafa;height:80px;position:relative}#fs_connect .fs-visual .fs-site-icon{position:absolute;left:20px;top:10px}#fs_connect .fs-visual .fs-connect-logo{position:absolute;right:20px;top:10px}#fs_connect .fs-visual .fs-plugin-icon{position:absolute;top:10px;left:50%;margin-left:-40px}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-site-icon,#fs_connect .fs-visual img,#fs_connect .fs-visual object{width:80px;height:80px}#fs_connect .fs-visual .dashicons-wordpress{font-size:64px;background:#01749a;color:#fff;width:64px;height:64px;padding:8px}#fs_connect .fs-visual .dashicons-plus{position:absolute;top:50%;font-size:30px;margin-top:-10px;color:#bbb}#fs_connect .fs-visual .dashicons-plus.fs-first{left:28%}#fs_connect .fs-visual .dashicons-plus.fs-second{left:65%}#fs_connect .fs-visual .fs-plugin-icon,#fs_connect .fs-visual .fs-connect-logo,#fs_connect .fs-visual .fs-site-icon{border:1px solid #ccc;padding:1px;background:#fff}#fs_connect .fs-terms{text-align:center;font-size:0.85em;padding:5px;background:rgba(0,0,0,0.05)}#fs_connect .fs-terms,#fs_connect .fs-terms a{color:#999}#fs_connect .fs-terms a{text-decoration:none}.fs-multisite-options-container{margin-top:10px;border:1px solid #ccc;padding:5px}.fs-multisite-options-container a{text-decoration:none}.fs-multisite-options-container a:focus{box-shadow:none}.fs-multisite-options-container a.selected{font-weight:bold}.fs-multisite-options-container.fs-apply-on-all-sites{border:0 none;padding:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options{border-spacing:0}.fs-multisite-options-container.fs-apply-on-all-sites .fs-all-sites-options td:not(:first-child){display:none}.fs-multisite-options-container .fs-sites-list-container{display:none;overflow:auto}.fs-multisite-options-container .fs-sites-list-container table td{border-top:1px solid #ccc;padding:4px 2px}.fs-tooltip-trigger{position:relative}.fs-tooltip-trigger:not(a){cursor:help}.fs-tooltip-trigger .fs-tooltip{opacity:0;visibility:hidden;-moz-transition:opacity 0.3s ease-in-out;-o-transition:opacity 0.3s ease-in-out;-ms-transition:opacity 0.3s ease-in-out;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out;position:absolute;background:rgba(0,0,0,0.8);color:#fff !important;font-family:'arial', serif;font-size:12px;padding:10px;z-index:999999;bottom:100%;margin-bottom:5px;left:-17px;right:0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;-moz-box-shadow:1px 1px 1px rgba(0,0,0,0.2);-webkit-box-shadow:1px 1px 1px rgba(0,0,0,0.2);box-shadow:1px 1px 1px rgba(0,0,0,0.2);line-height:1.3em;font-weight:bold;text-align:left;text-transform:none !important}.rtl .fs-tooltip-trigger .fs-tooltip{text-align:right;left:auto;right:-17px}.fs-tooltip-trigger .fs-tooltip::after{content:' ';display:block;width:0;height:0;border-style:solid;border-width:5px 5px 0 5px;border-color:rgba(0,0,0,0.8) transparent transparent transparent;position:absolute;top:100%;left:21px}.rtl .fs-tooltip-trigger .fs-tooltip::after{right:21px;left:auto}.fs-tooltip-trigger:hover .fs-tooltip{visibility:visible;opacity:1}#fs_marketing_optin{display:none;margin-top:10px;border:1px solid #ccc;padding:10px;line-height:1.5em}#fs_marketing_optin .fs-message{display:block;margin-bottom:5px;font-size:1.05em;font-weight:600}#fs_marketing_optin.error{border:1px solid #d3135a;background:#fee}#fs_marketing_optin.error .fs-message{color:#d3135a}#fs_marketing_optin .fs-input-container{margin-top:5px}#fs_marketing_optin .fs-input-container label{margin-top:5px;display:block}#fs_marketing_optin .fs-input-container label input{float:left;margin:1px 0 0 0}#fs_marketing_optin .fs-input-container label:first-child{display:block;margin-bottom:2px}#fs_marketing_optin .fs-input-label{display:block;margin-left:20px}#fs_marketing_optin .fs-input-label .underlined{text-decoration:underline}.rtl #fs_marketing_optin .fs-input-container label input{float:right}.rtl #fs_marketing_optin .fs-input-label{margin-left:0;margin-right:20px}.rtl #fs_connect .fs-actions{padding:10px 20px;background:#C0C7CA}.rtl #fs_connect .fs-actions .button .dashicons{font-size:37px;margin-left:-8px;margin-right:12px}.rtl #fs_connect .fs-actions .button.button-primary:after{content:' \000bb'}.rtl #fs_connect .fs-actions .button.button-primary.fs-loading:after{content:''}.rtl #fs_connect .fs-actions .button.button-secondary{float:left}.rtl #fs_connect .fs-permissions ul li .fs-permission-description{margin-right:55px;margin-left:0}.rtl #fs_connect .fs-permissions ul li .fs-switch{float:left}.rtl #fs_connect .fs-permissions ul li i.dashicons{float:right}.rtl #fs_connect .fs-visual .fs-site-icon{right:20px;left:auto}.rtl #fs_connect .fs-visual .fs-connect-logo{right:auto;left:20px}#fs_theme_connect_wrapper{position:fixed;top:0;height:100%;width:100%;z-index:99990;background:rgba(0,0,0,0.75);text-align:center;overflow-y:auto}#fs_theme_connect_wrapper:before{content:"";display:inline-block;vertical-align:middle;height:100%}#fs_theme_connect_wrapper>button.close{color:white;cursor:pointer;height:40px;width:40px;position:absolute;right:0;border:0;background-color:transparent;top:32px}#fs_theme_connect_wrapper #fs_connect{top:0;text-align:left;display:inline-block;vertical-align:middle;margin-top:52px;margin-bottom:20px}#fs_theme_connect_wrapper #fs_connect .fs-terms{background:rgba(140,140,140,0.64)}#fs_theme_connect_wrapper #fs_connect .fs-terms,#fs_theme_connect_wrapper #fs_connect .fs-terms a{color:#c5c5c5}.wp-pointer-content #fs_connect{margin:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.fs-opt-in-pointer .wp-pointer-content{padding:0}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow{border-bottom-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-top .wp-pointer-arrow-inner{border-bottom-color:#fafafa}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow{border-top-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-bottom .wp-pointer-arrow-inner{border-top-color:#fafafa}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow{border-right-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-left .wp-pointer-arrow-inner{border-right-color:#fafafa}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow{border-left-color:#dfdfdf}.fs-opt-in-pointer.wp-pointer-right .wp-pointer-arrow-inner{border-left-color:#fafafa}#license_issues_link{display:block;text-align:center;font-size:0.9em;margin-top:10px}
lib/freemius/includes/class-freemius.php CHANGED
@@ -384,6 +384,13 @@
384
  * @var boolean|null
385
  */
386
  private $_use_external_pricing = null;
 
 
 
 
 
 
 
387
 
388
  #endregion
389
 
@@ -5484,7 +5491,7 @@
5484
  function is_extensions_tracking_allowed() {
5485
  return ( true === $this->apply_filters(
5486
  'is_extensions_tracking_allowed',
5487
- $this->_storage->get( 'is_extensions_tracking_allowed', true )
5488
  ) );
5489
  }
5490
 
@@ -5528,10 +5535,12 @@
5528
  * @author Leo Fajardo (@leorw)
5529
  * @since 2.3.2
5530
  *
5531
- * @param bool $is_enabled
5532
  */
5533
- private function update_extensions_tracking_flag( $is_enabled ) {
5534
- $this->_storage->store( 'is_extensions_tracking_allowed', $is_enabled );
 
 
5535
  }
5536
 
5537
  /**
@@ -6860,8 +6869,6 @@
6860
  */
6861
  function _sync_cron_method( array $blog_ids, $current_blog_id = null ) {
6862
  if ( $this->is_registered() ) {
6863
- $this->sync_user_beta_mode();
6864
-
6865
  if ( $this->has_paid_plan() ) {
6866
  // Initiate background plan sync.
6867
  $this->_sync_license( true, false, $current_blog_id );
@@ -7234,7 +7241,8 @@
7234
  }
7235
 
7236
  if ( $this->is_plugin_new_install() || $this->is_only_premium() ) {
7237
- if ( ! $this->_anonymous_mode ) {
 
7238
  // Show notice for new plugin installations.
7239
  $this->_admin_notices->add(
7240
  sprintf(
@@ -7285,6 +7293,10 @@
7285
  * @return bool
7286
  */
7287
  private function should_add_sticky_optin_notice() {
 
 
 
 
7288
  if ( fs_is_network_admin() ) {
7289
  if ( ! $this->_is_network_active ) {
7290
  return false;
@@ -13238,26 +13250,25 @@
13238
  self::shoot_ajax_failure();
13239
  }
13240
 
13241
- $user = $this->get_api_user_scope()->call(
13242
  '',
13243
  'put',
13244
  array(
13245
- 'plugin_id' => $this->get_id(),
13246
  'is_beta' => ( 'true' == $is_beta ),
13247
  'fields' => 'is_beta'
13248
  )
13249
  );
13250
 
13251
- if ( ! $this->is_api_result_entity( $user ) ) {
13252
  self::shoot_ajax_failure(
13253
- FS_Api::is_api_error_object( $user ) ?
13254
- $user->error->message :
13255
  fs_text_inline( "An unknown error has occurred while trying to set the user's beta mode.", 'unknown-error-occurred', $this->get_slug() )
13256
  );
13257
  }
13258
 
13259
- $this->_user->is_beta = $user->is_beta;
13260
- $this->_store_user();
13261
 
13262
  self::shoot_ajax_response( array( 'success' => true ) );
13263
  }
@@ -13292,7 +13303,7 @@
13292
  fs_request_get( 'blog_id', null ),
13293
  fs_request_get( 'module_id', null, 'post' ),
13294
  fs_request_get( 'user_id', null ),
13295
- fs_request_get_bool( 'is_extensions_tracking_allowed', true )
13296
  );
13297
 
13298
  if (
@@ -13482,7 +13493,31 @@
13482
  * @return string
13483
  */
13484
  function get_pricing_js_path() {
13485
- return $this->apply_filters( 'freemius_pricing_js_path', WP_FS__DIR_INCLUDES . '/freemius-pricing/freemius-pricing.js' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13486
  }
13487
 
13488
  /**
@@ -13527,7 +13562,7 @@
13527
  $blog_id = null,
13528
  $plugin_id = null,
13529
  $license_owner_id = null,
13530
- $is_extensions_tracking_allowed = true
13531
  ) {
13532
  $this->_logger->entrance();
13533
 
@@ -16448,19 +16483,6 @@
16448
  );
16449
  }
16450
 
16451
- /**
16452
- * @author Leo Fajardo (@leorw)
16453
- * @since 2.3.0
16454
- */
16455
- private function sync_user_beta_mode() {
16456
- $user = $this->get_api_user_scope()->get( '/?plugin_id=' . $this->get_id() . '&fields=is_beta' );
16457
-
16458
- if ( $this->is_api_result_entity( $user ) ) {
16459
- $this->_user->is_beta = $user->is_beta;
16460
- $this->_store_user();
16461
- }
16462
- }
16463
-
16464
  /**
16465
  * @author Vova Feldman (@svovaf)
16466
  * @since 1.1.7.4
@@ -17148,9 +17170,7 @@
17148
  $this->disable_opt_in_notice_and_lock_user();
17149
  }
17150
 
17151
- if ( ! is_null( $is_extensions_tracking_allowed ) ) {
17152
- $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
17153
- }
17154
 
17155
  return $this->setup_account(
17156
  $this->_user,
@@ -17195,9 +17215,7 @@
17195
  $this->disable_opt_in_notice_and_lock_user();
17196
  }
17197
 
17198
- if ( ! is_null( $is_extensions_tracking_allowed ) ) {
17199
- $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
17200
- }
17201
 
17202
  $sites = array();
17203
  foreach ( $site_ids as $site_id ) {
@@ -17240,9 +17258,7 @@
17240
  $this->disable_opt_in_notice_and_lock_user();
17241
  }
17242
 
17243
- if ( ! is_null( $is_extensions_tracking_allowed ) ) {
17244
- $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
17245
- }
17246
 
17247
  $install_ids = array();
17248
 
@@ -17353,7 +17369,7 @@
17353
  */
17354
  $license_key = fs_request_get( 'license_secret_key' );
17355
 
17356
- $this->update_extensions_tracking_flag( fs_request_get_bool( 'is_extensions_tracking_allowed', true ) );
17357
 
17358
  $this->install_with_current_user( $license_key );
17359
  }
@@ -20605,6 +20621,20 @@
20605
  }
20606
  }
20607
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20608
  if ( $this->is_addon() || $this->has_addons() ) {
20609
  /**
20610
  * Purge the valid user licenses cache so that when the "Account" or the "Add-Ons" page is loaded,
@@ -21298,7 +21328,7 @@
21298
 
21299
  if ( $this->has_secret_key() ) {
21300
  $endpoint = add_query_arg( 'type', 'all', $endpoint );
21301
- } else if ( $this->is_registered() && $this->_user->is_beta() ) {
21302
  $endpoint = add_query_arg( 'type', 'beta', $endpoint );
21303
  }
21304
 
@@ -23396,6 +23426,14 @@
23396
  return;
23397
  }
23398
 
 
 
 
 
 
 
 
 
23399
  if ( fs_is_network_admin() ) {
23400
  if ( ! $this->_is_network_active ) {
23401
  // Don't add tracking links when browsing the network WP Admin and the plugin is not network active.
384
  * @var boolean|null
385
  */
386
  private $_use_external_pricing = null;
387
+ /**
388
+ * @author Leo Fajardo (@leorw)
389
+ * @since 2.4.2
390
+ *
391
+ * @var string|null
392
+ */
393
+ private $_pricing_js_path = null;
394
 
395
  #endregion
396
 
5491
  function is_extensions_tracking_allowed() {
5492
  return ( true === $this->apply_filters(
5493
  'is_extensions_tracking_allowed',
5494
+ $this->_storage->get( 'is_extensions_tracking_allowed', null )
5495
  ) );
5496
  }
5497
 
5535
  * @author Leo Fajardo (@leorw)
5536
  * @since 2.3.2
5537
  *
5538
+ * @param bool|null $is_enabled
5539
  */
5540
+ function update_extensions_tracking_flag( $is_enabled ) {
5541
+ if ( is_bool( $is_enabled ) ) {
5542
+ $this->_storage->store( 'is_extensions_tracking_allowed', $is_enabled );
5543
+ }
5544
  }
5545
 
5546
  /**
6869
  */
6870
  function _sync_cron_method( array $blog_ids, $current_blog_id = null ) {
6871
  if ( $this->is_registered() ) {
 
 
6872
  if ( $this->has_paid_plan() ) {
6873
  // Initiate background plan sync.
6874
  $this->_sync_license( true, false, $current_blog_id );
7241
  }
7242
 
7243
  if ( $this->is_plugin_new_install() || $this->is_only_premium() ) {
7244
+ if ( ! $this->_anonymous_mode &&
7245
+ ( ! $this->is_addon() || ! $this->_parent->is_anonymous() ) ) {
7246
  // Show notice for new plugin installations.
7247
  $this->_admin_notices->add(
7248
  sprintf(
7293
  * @return bool
7294
  */
7295
  private function should_add_sticky_optin_notice() {
7296
+ if ( $this->is_addon() && $this->_parent->is_anonymous() ) {
7297
+ return false;
7298
+ }
7299
+
7300
  if ( fs_is_network_admin() ) {
7301
  if ( ! $this->_is_network_active ) {
7302
  return false;
13250
  self::shoot_ajax_failure();
13251
  }
13252
 
13253
+ $site = $this->get_api_site_scope()->call(
13254
  '',
13255
  'put',
13256
  array(
 
13257
  'is_beta' => ( 'true' == $is_beta ),
13258
  'fields' => 'is_beta'
13259
  )
13260
  );
13261
 
13262
+ if ( ! $this->is_api_result_entity( $site ) ) {
13263
  self::shoot_ajax_failure(
13264
+ FS_Api::is_api_error_object( $site ) ?
13265
+ $site->error->message :
13266
  fs_text_inline( "An unknown error has occurred while trying to set the user's beta mode.", 'unknown-error-occurred', $this->get_slug() )
13267
  );
13268
  }
13269
 
13270
+ $this->_site->is_beta = $site->is_beta;
13271
+ $this->_store_site();
13272
 
13273
  self::shoot_ajax_response( array( 'success' => true ) );
13274
  }
13303
  fs_request_get( 'blog_id', null ),
13304
  fs_request_get( 'module_id', null, 'post' ),
13305
  fs_request_get( 'user_id', null ),
13306
+ fs_request_get_bool( 'is_extensions_tracking_allowed', null )
13307
  );
13308
 
13309
  if (
13493
  * @return string
13494
  */
13495
  function get_pricing_js_path() {
13496
+ if ( ! isset( $this->_pricing_js_path ) ) {
13497
+ $pricing_js_path = $this->apply_filters( 'freemius_pricing_js_path', '' );
13498
+
13499
+ if ( empty( $pricing_js_path ) ) {
13500
+ global $fs_active_plugins;
13501
+
13502
+ foreach ( $fs_active_plugins->plugins as $sdk_path => $data ) {
13503
+ if ( $data->plugin_path == $this->get_plugin_basename() ) {
13504
+ $plugin_or_theme_root_dir = ( $this->is_plugin() ? WP_PLUGIN_DIR : get_theme_root( get_stylesheet() ) );
13505
+
13506
+ $pricing_js_path = $plugin_or_theme_root_dir
13507
+ . '/'
13508
+ // The basename will be `plugins`, `themes`, or the basename of a custom plugins or themes directory.
13509
+ . str_replace( '../' . basename( $plugin_or_theme_root_dir ) . '/', '', $sdk_path )
13510
+ . '/includes/freemius-pricing/freemius-pricing.js';
13511
+
13512
+ break;
13513
+ }
13514
+ }
13515
+ }
13516
+
13517
+ $this->_pricing_js_path = $pricing_js_path;
13518
+ }
13519
+
13520
+ return $this->_pricing_js_path;
13521
  }
13522
 
13523
  /**
13562
  $blog_id = null,
13563
  $plugin_id = null,
13564
  $license_owner_id = null,
13565
+ $is_extensions_tracking_allowed = null
13566
  ) {
13567
  $this->_logger->entrance();
13568
 
16483
  );
16484
  }
16485
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16486
  /**
16487
  * @author Vova Feldman (@svovaf)
16488
  * @since 1.1.7.4
17170
  $this->disable_opt_in_notice_and_lock_user();
17171
  }
17172
 
17173
+ $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
 
 
17174
 
17175
  return $this->setup_account(
17176
  $this->_user,
17215
  $this->disable_opt_in_notice_and_lock_user();
17216
  }
17217
 
17218
+ $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
 
 
17219
 
17220
  $sites = array();
17221
  foreach ( $site_ids as $site_id ) {
17258
  $this->disable_opt_in_notice_and_lock_user();
17259
  }
17260
 
17261
+ $this->update_extensions_tracking_flag( $is_extensions_tracking_allowed );
 
 
17262
 
17263
  $install_ids = array();
17264
 
17369
  */
17370
  $license_key = fs_request_get( 'license_secret_key' );
17371
 
17372
+ $this->update_extensions_tracking_flag( fs_request_get_bool( 'is_extensions_tracking_allowed', null ) );
17373
 
17374
  $this->install_with_current_user( $license_key );
17375
  }
20621
  }
20622
  }
20623
 
20624
+ if ( ! $this->is_addon() &&
20625
+ $this->_site->is_beta() !== $site->is_beta
20626
+ ) {
20627
+ // Beta flag updated.
20628
+ $this->_site = $site;
20629
+
20630
+ $this->_store_site(
20631
+ true,
20632
+ $is_site_level_sync ?
20633
+ null :
20634
+ $this->get_network_install_blog_id()
20635
+ );
20636
+ }
20637
+
20638
  if ( $this->is_addon() || $this->has_addons() ) {
20639
  /**
20640
  * Purge the valid user licenses cache so that when the "Account" or the "Add-Ons" page is loaded,
21328
 
21329
  if ( $this->has_secret_key() ) {
21330
  $endpoint = add_query_arg( 'type', 'all', $endpoint );
21331
+ } else if ( is_object( $this->_site ) && $this->_site->is_beta() ) {
21332
  $endpoint = add_query_arg( 'type', 'beta', $endpoint );
21333
  }
21334
 
23426
  return;
23427
  }
23428
 
23429
+ if (
23430
+ $this->is_addon() &&
23431
+ ! $this->is_only_premium() &&
23432
+ $this->_parent->is_anonymous()
23433
+ ) {
23434
+ return;
23435
+ }
23436
+
23437
  if ( fs_is_network_admin() ) {
23438
  if ( ! $this->_is_network_active ) {
23439
  // Don't add tracking links when browsing the network WP Admin and the plugin is not network active.
lib/freemius/includes/class-fs-logger.php CHANGED
@@ -142,7 +142,7 @@
142
  return $this->_file_start;
143
  }
144
 
145
- private function _log( &$message, $type = 'log', $wrapper ) {
146
  if ( ! $this->is_on() ) {
147
  return;
148
  }
@@ -688,4 +688,4 @@ KEY `type` (`type` ASC))" );
688
  }
689
 
690
  #endregion
691
- }
142
  return $this->_file_start;
143
  }
144
 
145
+ private function _log( &$message, $type, $wrapper = false ) {
146
  if ( ! $this->is_on() ) {
147
  return;
148
  }
688
  }
689
 
690
  #endregion
691
+ }
lib/freemius/includes/entities/class-fs-site.php CHANGED
@@ -102,6 +102,14 @@
102
  * @var bool
103
  */
104
  public $is_uninstalled = false;
 
 
 
 
 
 
 
 
105
 
106
  /**
107
  * @param stdClass|bool $site
@@ -233,4 +241,13 @@
233
  function is_tracking_prohibited() {
234
  return ! $this->is_tracking_allowed();
235
  }
 
 
 
 
 
 
 
 
 
236
  }
102
  * @var bool
103
  */
104
  public $is_uninstalled = false;
105
+ /**
106
+ * @author Edgar Melkonyan
107
+ *
108
+ * @since 2.4.2
109
+ *
110
+ * @var bool
111
+ */
112
+ public $is_beta;
113
 
114
  /**
115
  * @param stdClass|bool $site
241
  function is_tracking_prohibited() {
242
  return ! $this->is_tracking_allowed();
243
  }
244
+
245
+ /**
246
+ * @author Edgar Melkonyan
247
+ *
248
+ * @return bool
249
+ */
250
+ function is_beta() {
251
+ return ( isset( $this->is_beta ) && true === $this->is_beta );
252
+ }
253
  }
lib/freemius/includes/entities/class-fs-user.php CHANGED
@@ -31,13 +31,6 @@
31
  */
32
  public $is_verified;
33
  /**
34
- * @author Leo Fajardo (@leorw)
35
- * @since 2.3.0
36
- *
37
- * @var bool
38
- */
39
- public $is_beta;
40
- /**
41
  * @var string|null
42
  */
43
  public $customer_id;
@@ -63,16 +56,6 @@
63
  return ( isset( $this->is_verified ) && true === $this->is_verified );
64
  }
65
 
66
- /**
67
- * @author Leo Fajardo (@leorw)
68
- * @since 2.3.0
69
- *
70
- * @return bool
71
- */
72
- function is_beta() {
73
- return ( isset( $this->is_beta ) && true === $this->is_beta );
74
- }
75
-
76
  static function get_type() {
77
  return 'user';
78
  }
31
  */
32
  public $is_verified;
33
  /**
 
 
 
 
 
 
 
34
  * @var string|null
35
  */
36
  public $customer_id;
56
  return ( isset( $this->is_verified ) && true === $this->is_verified );
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
59
  static function get_type() {
60
  return 'user';
61
  }
lib/freemius/languages/freemius-cs_CZ.mo CHANGED
Binary file
lib/freemius/languages/freemius-da_DK.mo CHANGED
Binary file
lib/freemius/languages/freemius-en.mo CHANGED
Binary file
lib/freemius/languages/freemius-es_ES.mo CHANGED
Binary file
lib/freemius/languages/freemius-fr_FR.mo CHANGED
Binary file
lib/freemius/languages/freemius-he_IL.mo CHANGED
Binary file
lib/freemius/languages/freemius-hu_HU.mo CHANGED
Binary file
lib/freemius/languages/freemius-it_IT.mo CHANGED
Binary file
lib/freemius/languages/freemius-ja.mo CHANGED
Binary file
lib/freemius/languages/freemius-nl_NL.mo CHANGED
Binary file
lib/freemius/languages/freemius-ru_RU.mo CHANGED
Binary file
lib/freemius/languages/freemius-ta.mo CHANGED
Binary file
lib/freemius/languages/freemius-zh_CN.mo CHANGED
Binary file
lib/freemius/start.php CHANGED
@@ -15,7 +15,7 @@
15
  *
16
  * @var string
17
  */
18
- $this_sdk_version = '2.4.1';
19
 
20
  #region SDK Selection Logic --------------------------------------------------------------------
21
 
@@ -512,7 +512,7 @@
512
  }
513
 
514
  /**
515
- * @param array <string,string> $module Plugin or Theme details.
516
  *
517
  * @return Freemius
518
  * @throws Freemius_Exception
@@ -527,4 +527,4 @@
527
  function fs_dump_log() {
528
  FS_Logger::dump();
529
  }
530
- }
15
  *
16
  * @var string
17
  */
18
+ $this_sdk_version = '2.4.2';
19
 
20
  #region SDK Selection Logic --------------------------------------------------------------------
21
 
512
  }
513
 
514
  /**
515
+ * @param array <string,string|bool|array> $module Plugin or Theme details.
516
  *
517
  * @return Freemius
518
  * @throws Freemius_Exception
527
  function fs_dump_log() {
528
  FS_Logger::dump();
529
  }
530
+ }
lib/freemius/templates/account.php CHANGED
@@ -21,7 +21,9 @@
21
  /**
22
  * @var FS_Plugin_Tag $update
23
  */
24
- $update = $fs->get_update( false, false, WP_FS__TIME_24_HOURS_IN_SEC / 24 );
 
 
25
 
26
  if ( is_object($update) ) {
27
  /**
@@ -433,11 +435,11 @@
433
  'value' => $fs->get_plugin_version()
434
  );
435
 
436
- if ( $is_premium && ! $is_whitelabeled ) {
437
  $profile[] = array(
438
  'id' => 'beta_program',
439
  'title' => '',
440
- 'value' => $user->is_beta
441
  );
442
  }
443
 
21
  /**
22
  * @var FS_Plugin_Tag $update
23
  */
24
+ $update = $fs->has_release_on_freemius() ?
25
+ $fs->get_update( false, false, WP_FS__TIME_24_HOURS_IN_SEC / 24 ) :
26
+ null;
27
 
28
  if ( is_object($update) ) {
29
  /**
435
  'value' => $fs->get_plugin_version()
436
  );
437
 
438
+ if ( ! fs_is_network_admin() && $is_premium && ! $is_whitelabeled ) {
439
  $profile[] = array(
440
  'id' => 'beta_program',
441
  'title' => '',
442
+ 'value' => $site->is_beta
443
  );
444
  }
445
 
lib/freemius/templates/connect.php CHANGED
@@ -181,12 +181,7 @@
181
 
182
  $message = $fs->apply_filters(
183
  'connect-message_on-premium',
184
- ($is_network_upgrade_mode ?
185
- '' :
186
- /* translators: %s: name (e.g. Hey John,) */
187
- $hey_x_text . '<br>'
188
- ) .
189
- sprintf( fs_text_inline( 'Thanks for purchasing %s! To get started, please enter your license key:', 'thanks-for-purchasing', $slug ), '<b>' . $fs->get_plugin_name() . '</b>' ),
190
  $first_name,
191
  $fs->get_plugin_name()
192
  );
@@ -347,6 +342,9 @@
347
  } ?>><?php echo esc_html( $button_label ) ?></button>
348
  </form>
349
  <?php endif ?>
 
 
 
350
  </div><?php
351
 
352
  // Set core permission list items.
@@ -367,26 +365,30 @@
367
  );
368
  }
369
 
370
- $permissions['site'] = array(
371
- 'icon-class' => 'dashicons dashicons-admin-settings',
372
- 'label' => $fs->get_text_inline( 'Your Site Overview', 'permissions-site' ),
373
- 'desc' => $fs->get_text_inline( 'Site URL, WP version, PHP info', 'permissions-site_desc' ),
374
- 'priority' => 10,
375
- );
376
-
377
- $permissions['notices'] = array(
378
- 'icon-class' => 'dashicons dashicons-testimonial',
379
- 'label' => $fs->get_text_inline( 'Admin Notices', 'permissions-admin-notices' ),
380
- 'desc' => $fs->get_text_inline( 'Updates, announcements, marketing, no spam', 'permissions-newsletter_desc' ),
381
- 'priority' => 13,
382
- );
 
 
 
383
 
384
- $permissions['events'] = array(
385
- 'icon-class' => 'dashicons dashicons-admin-' . ( $fs->is_plugin() ? 'plugins' : 'appearance' ),
386
- 'label' => sprintf( $fs->get_text_inline( 'Current %s Events', 'permissions-events' ), ucfirst( $fs->get_module_type() ) ),
387
- 'desc' => $fs->get_text_inline( 'Activation, deactivation and uninstall', 'permissions-events_desc' ),
388
- 'priority' => 20,
389
- );
 
390
 
391
  // Add newsletter permissions if enabled.
392
  if ( $is_gdpr_required || $fs->is_permission_requested( 'newsletter' ) ) {
@@ -398,14 +400,15 @@
398
  );
399
  }
400
 
401
- $permissions['extensions'] = array(
402
  'icon-class' => 'dashicons dashicons-menu',
403
- 'label' => $fs->get_text_inline( 'Plugins & Themes', 'permissions-extensions' ),
 
404
  'desc' => $fs->get_text_inline( 'Title, slug, version, and is active', 'permissions-extensions_desc' ),
405
  'priority' => 25,
406
  'optional' => true,
407
- 'default' => $fs->apply_filters( 'permission_extensions_default', true )
408
- );
409
 
410
  // Allow filtering of the permissions list.
411
  $permissions = $fs->apply_filters( 'permission_list', $permissions );
@@ -417,13 +420,15 @@
417
  <div class="fs-permissions">
418
  <?php if ( $require_license_key ) : ?>
419
  <p class="fs-license-sync-disclaimer"><?php
420
- echo sprintf(
421
- fs_esc_html_inline( 'The %1$s will be periodically sending data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ),
422
  $fs->get_module_label( true ),
423
- $freemius_link
 
424
  ) ?></p>
425
- <?php endif ?>
426
  <a class="fs-trigger" href="#" tabindex="1"><?php fs_esc_html_echo_inline( 'What permissions are being granted?', 'what-permissions', $slug ) ?></a>
 
427
  <ul><?php
428
  foreach ( $permissions as $id => $permission ) : ?>
429
  <li id="fs-permission-<?php echo esc_attr( $id ); ?>"
@@ -436,7 +441,7 @@
436
  <?php endif ?>
437
 
438
  <div class="fs-permission-description">
439
- <span><?php echo esc_html( $permission['label'] ); ?></span>
440
 
441
  <p><?php echo esc_html( $permission['desc'] ); ?></p>
442
  </div>
@@ -702,9 +707,16 @@
702
  var ajaxOptin = ( requireLicenseKey || isNetworkActive );
703
 
704
  $form.on('submit', function () {
705
- var isExtensionsTrackingAllowed = $( '#fs-permission-extensions .fs-switch' ).hasClass( 'fs-on' );
706
-
707
- $( 'input[name=is_extensions_tracking_allowed]' ).val( isExtensionsTrackingAllowed ? 1 : 0 );
 
 
 
 
 
 
 
708
 
709
  /**
710
  * @author Vova Feldman (@svovaf)
181
 
182
  $message = $fs->apply_filters(
183
  'connect-message_on-premium',
184
+ sprintf( fs_text_inline( 'Welcome to %s! To get started, please enter your license key:', 'thanks-for-purchasing', $slug ), '<b>' . $fs->get_plugin_name() . '</b>' ),
 
 
 
 
 
185
  $first_name,
186
  $fs->get_plugin_name()
187
  );
342
  } ?>><?php echo esc_html( $button_label ) ?></button>
343
  </form>
344
  <?php endif ?>
345
+ <?php if ( $require_license_key ) : ?>
346
+ <a id="license_issues_link" href="<?php echo $fs->apply_filters( 'known_license_issues_url', 'https://freemius.com/help/documentation/wordpress-sdk/license-activation-issues/' ) ?>" target="_blank"><?php fs_esc_html_echo_inline( 'License issues?', 'license-issues', $slug ) ?></a>
347
+ <?php endif ?>
348
  </div><?php
349
 
350
  // Set core permission list items.
365
  );
366
  }
367
 
368
+ $permissions['site'] = array(
369
+ 'icon-class' => 'dashicons dashicons-admin-settings',
370
+ 'tooltip' => ( $require_license_key ? sprintf( $fs->get_text_inline( 'So you can manage and control your license remotely from the User Dashboard.', 'permissions-site_tooltip' ), $fs->get_module_type() ) : '' ),
371
+ 'label' => $fs->get_text_inline( 'Your Site Overview', 'permissions-site' ),
372
+ 'desc' => $fs->get_text_inline( 'Site URL, WP version, PHP info', 'permissions-site_desc' ),
373
+ 'priority' => 10,
374
+ );
375
+
376
+ if ( ! $require_license_key ) {
377
+ $permissions['notices'] = array(
378
+ 'icon-class' => 'dashicons dashicons-testimonial',
379
+ 'label' => $fs->get_text_inline( 'Admin Notices', 'permissions-admin-notices' ),
380
+ 'desc' => $fs->get_text_inline( 'Updates, announcements, marketing, no spam', 'permissions-newsletter_desc' ),
381
+ 'priority' => 13,
382
+ );
383
+ }
384
 
385
+ $permissions['events'] = array(
386
+ 'icon-class' => 'dashicons dashicons-admin-' . ( $fs->is_plugin() ? 'plugins' : 'appearance' ),
387
+ 'tooltip' => ( $require_license_key ? sprintf( $fs->get_text_inline( 'So you can reuse the license when the %s is no longer active.', 'permissions-events_tooltip' ), $fs->get_module_type() ) : '' ),
388
+ 'label' => sprintf( $fs->get_text_inline( 'Current %s Status', 'permissions-events' ), ucfirst( $fs->get_module_type() ) ),
389
+ 'desc' => $fs->get_text_inline( 'Active, deactivated, or uninstalled', 'permissions-events_desc' ),
390
+ 'priority' => 20,
391
+ );
392
 
393
  // Add newsletter permissions if enabled.
394
  if ( $is_gdpr_required || $fs->is_permission_requested( 'newsletter' ) ) {
400
  );
401
  }
402
 
403
+ $permissions['extensions'] = array(
404
  'icon-class' => 'dashicons dashicons-menu',
405
+ 'label' => $fs->get_text_inline( 'Plugins & Themes', 'permissions-extensions' ) . ( $require_license_key ? ' (' . $fs->get_text_inline( 'optional' ) . ')' : '' ),
406
+ 'tooltip' => $fs->get_text_inline( 'To help us troubleshoot any potential issues that may arise from other plugin or theme conflicts.', 'permissions-events_tooltip' ),
407
  'desc' => $fs->get_text_inline( 'Title, slug, version, and is active', 'permissions-extensions_desc' ),
408
  'priority' => 25,
409
  'optional' => true,
410
+ 'default' => $fs->apply_filters( 'permission_extensions_default', ! $require_license_key )
411
+ );
412
 
413
  // Allow filtering of the permissions list.
414
  $permissions = $fs->apply_filters( 'permission_list', $permissions );
420
  <div class="fs-permissions">
421
  <?php if ( $require_license_key ) : ?>
422
  <p class="fs-license-sync-disclaimer"><?php
423
+ echo sprintf(
424
+ fs_esc_html_inline( 'The %1$s will periodically send %2$s to %3$s for security & feature updates delivery, and license management.', 'license-sync-disclaimer', $slug ),
425
  $fs->get_module_label( true ),
426
+ sprintf('<a class="fs-trigger" href="#" tabindex="1">%s</a>', fs_esc_html_inline('diagnostic data', 'send-data')),
427
+ '<a class="fs-tooltip-trigger' . (is_rtl() ? ' rtl' : '') . '" href="' . $freemius_site_url . '" target="_blank" rel="noopener" tabindex="1">freemius.com <i class="dashicons dashicons-editor-help" style="text-decoration: none;"><span class="fs-tooltip" style="width: 170px">' . $fs->get_text_inline( 'Freemius is our licensing and software updates engine', 'permissions-extensions_desc' ) . '</span></i></a>'
428
  ) ?></p>
429
+ <?php else : ?>
430
  <a class="fs-trigger" href="#" tabindex="1"><?php fs_esc_html_echo_inline( 'What permissions are being granted?', 'what-permissions', $slug ) ?></a>
431
+ <?php endif ?>
432
  <ul><?php
433
  foreach ( $permissions as $id => $permission ) : ?>
434
  <li id="fs-permission-<?php echo esc_attr( $id ); ?>"
441
  <?php endif ?>
442
 
443
  <div class="fs-permission-description">
444
+ <span<?php if ( ! empty($permission['tooltip']) ) : ?> class="fs-tooltip-trigger"<?php endif ?>><?php echo esc_html( $permission['label'] ); ?><?php if ( ! empty($permission['tooltip']) ) : ?><i class="dashicons dashicons-editor-help"><span class="fs-tooltip" style="width: 200px"><?php echo $permission['tooltip'] ?></span></i><?php endif ?></span>
445
 
446
  <p><?php echo esc_html( $permission['desc'] ); ?></p>
447
  </div>
707
  var ajaxOptin = ( requireLicenseKey || isNetworkActive );
708
 
709
  $form.on('submit', function () {
710
+ var $extensionsPermission = $('#fs-permission-extensions .fs-switch'),
711
+ isExtensionsTrackingAllowed = ($extensionsPermission.length > 0) ?
712
+ $extensionsPermission.hasClass('fs-on') :
713
+ null;
714
+
715
+ if (null === isExtensionsTrackingAllowed) {
716
+ $('input[name=is_extensions_tracking_allowed]').remove();
717
+ } else {
718
+ $('input[name=is_extensions_tracking_allowed]').val(isExtensionsTrackingAllowed ? 1 : 0);
719
+ }
720
 
721
  /**
722
  * @author Vova Feldman (@svovaf)
lib/freemius/templates/forms/license-activation.php CHANGED
@@ -115,13 +115,15 @@ HTML;
115
  * @var FS_Plugin_License $license
116
  */
117
  foreach ( $available_licenses as $license ) {
 
 
118
  $label = sprintf(
119
  "%s-Site %s License - %s",
120
  ( 1 == $license->quota ?
121
  'Single' :
122
  ( $license->is_unlimited() ? 'Unlimited' : $license->quota )
123
  ),
124
- $fs->_get_plan_by_id( $license->plan_id )->title,
125
  $license->get_html_escaped_masked_secret_key()
126
  );
127
 
115
  * @var FS_Plugin_License $license
116
  */
117
  foreach ( $available_licenses as $license ) {
118
+ $plan = $fs->_get_plan_by_id( $license->plan_id );
119
+
120
  $label = sprintf(
121
  "%s-Site %s License - %s",
122
  ( 1 == $license->quota ?
123
  'Single' :
124
  ( $license->is_unlimited() ? 'Unlimited' : $license->quota )
125
  ),
126
+ ( is_object( $plan ) ? $plan->title : '' ),
127
  $license->get_html_escaped_masked_secret_key()
128
  );
129
 
lib/wp-content-aware-engine/assets/css/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- /**/
1
+ <?php
2
+ /**/
lib/wp-content-aware-engine/assets/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- /**/
1
+ <?php
2
+ /**/
lib/wp-content-aware-engine/assets/js/condition_groups.min.js CHANGED
@@ -1,7 +1,7 @@
1
- /*!
2
- * @package WP Content Aware Engine
3
- * @author Joachim Jensen <joachim@dev.institute>
4
- * @license GPLv3
5
- * @copyright 2020 by Joachim Jensen
6
- */
7
- var CAE=CAE||{};!function($,CAE){"use strict";CAE.settings={views:{}},CAE.Models={},CAE.Models.Alert=Backbone.Model.extend({defaults:{text:"",success:!0},sync:function(){return!1},url:"",reset:function(){this.set(this.defaults)}}),CAE.Models.Condition=Backbone.Model.extend({unsaved:{prompt:WPCA.unsaved,unloadWindowPrompt:!0},defaults:{module:null,label:"",placeholder:"",values:[],default_value:null},initialize:function(){this.startTracking(),this.on("destroy",this.stopTracking,this)},sync:function(){return!1},url:""}),CAE.Models.Group=Backbone.Model.extend({unsaved:{prompt:WPCA.unsaved,unloadWindowPrompt:!0},defaults:function(){var e=WPCA.meta_default;return e.id=null,e.status="wpca_or",e.exposure=1,e},initialize:function(){this.startTracking(),this.on("destroy",this.stopTracking,this),this.conditions||(this.conditions=new CAE.Models.ConditionCollection)},parse:function(e){var t=[];if(_.has(e,"conditions")){for(var n in e.conditions)if(e.conditions.hasOwnProperty(n)){var i=[],o=e.conditions[n];for(var s in o.data)o.data.hasOwnProperty(s)&&i.push({text:"object"==typeof o.data[s]?o.data[s].text:o.data[s],id:s});delete o.data,o.module=n,o.values=i,t.push(o)}delete e.conditions}return this.conditions=new CAE.Models.ConditionCollection(t),e},sync:function(){return!1},url:""}),CAE.Models.GroupCollection=Backbone.Collection.extend({model:CAE.Models.Group,parse:function(e){return e}}),CAE.Models.ConditionCollection=Backbone.Collection.extend({model:CAE.Models.Condition}),CAE.Views={},CAE.Views.Alert=Backbone.Epoxy.View.extend({bindings:"data-vm",tagName:"div",className:"wpca-alert",template:"<div data-vm=\"classes:{'wpca-success':success,'wpca-error':not(success)},text:text\"></div>",timer:4e3,success:function(e){this.model.set({text:e,success:!0})},failure:function(e){this.model.set({text:e,success:!1})},dismiss:function(){var e=this;this.$el.fadeOut("slow",function(){e.model.reset()})},initialize:function(){this.listenTo(this.model,"change:text",this.show),this.$el.appendTo("body").hide().html(this.template)},show:function(){if(""!==this.model.get("text")){this.$el.fadeIn("slow");var e=this;setTimeout(function(){e.dismiss()},this.timer)}}}),CAE.Views.Condition=Backbone.Epoxy.View.extend({bindings:"data-vm",model:CAE.Models.Condition,tagName:"div",className:"cas-condition",templateName:"#wpca-template-condition",events:{"click .js-wpca-condition-remove":"removeModel"},initialize:function(){this.listenTo(this.model,"destroy",this.remove);var e=$(this.templateName);e.length?(this.template=e.html(),this.$el.append(this.template),this.createSuggestInput()):this.model.destroy()},removeModel:function(e){var t=this;this.$el.slideUp(300,function(){t.model.destroy()})},createSuggestInput:function(){var n=this.$el.find(".js-wpca-suggest");if(n.length){var i=this.model,e=this.model.get("values"),t=$("<div></div>").html(i.get("placeholder")).text();n.select2({cachedResults:{},quietMillis:400,searchTimer:null,type:i.get("module"),theme:"wpca",dir:WPCA.text_direction,placeholder:t,minimumInputLength:0,closeOnSelect:!0,width:"100%",language:{noResults:function(){return WPCA.noResults},searching:function(){return WPCA.searching+"..."},loadingMore:function(){return WPCA.loadingMore+"..."}},nextSearchTerm:function(e,t){return t},templateResult:function(e){return e.level?$('<span class="wpca-level-'+e.level+'">'+e.text+"</span>"):e.text},data:e,dataAdapter:l.wpcaDataAdapter,ajax:{}}).on("select2:selecting",function(e){n.data("forceOpen",!0)}).on("select2:closing",function(e){n.data("forceOpen")&&(e.preventDefault(),n.data("forceOpen",!1))}),e.length&&n.val(_.map(e,function(e){return e.id})).trigger("change"),n.on("change",function(e){var t=n.select2("data");i.set("values",t)})}}}),CAE.Views.Group=Backbone.Epoxy.View.extend({bindings:"data-vm",model:CAE.Models.Group,tagName:"li",className:"cas-group-single",template:$("#wpca-template-group").html(),itemView:function(e){if(CAE.Views[e.model.get("module")])var t=new(CAE.Views[e.model.get("module")])(e);else t=new CAE.Views.Condition(e);return t},events:{"click .js-wpca-save-group":"saveGroup","click .js-wpca-options":"showOptions"},computeds:{statusNegated:{deps:["status"],get:function(e){return"negated"==e},set:function(e){var t=e?"negated":"wpca_or";this.setBinding("status",t)}},statusExcept:{deps:["status"],get:function(e){return"wpca_except"==e},set:function(e){var t=e?"wpca_except":"wpca_or";this.setBinding("status",t)}},statusLabel:function(){switch(this.getBinding("status")){case"wpca_except":return WPCA.condition_except;case"negated":return WPCA.condition_not;default:return WPCA.condition_or}}},bindingFilters:{int:{get:function(e){return e?1:0},set:function(e){return e?1:0}},binary:{get:function(e){return e?1:0},set:function(e){return e?1:0}},hasModule:function(e){for(var t={},n=1;n<arguments.length;n++)t[arguments[n]]=!0;return e.filter(function(e){return t.hasOwnProperty(e.get("module"))}).length==arguments.length-1},hasAnyModule:function(e){for(var t={},n=1;n<arguments.length;n++)t[arguments[n]]=!0;return!!e.find(function(e){return t.hasOwnProperty(e.get("module"))})}},initialize:function(){this.collection=this.model.conditions,this.$el.hide().html(this.template).fadeIn(300),this.listenTo(this.model,"destroy",this.remove),this.listenTo(this.model,"unsavedChanges",this.saveChanges),this.listenTo(this.model.conditions,"unsavedChanges",this.saveChanges),this.listenTo(this.model.conditions,"add remove",this.saveAddRemove);var i=this,o=$(".js-wpca-add-and",this.$el);o.select2({theme:"wpca",placeholder:"+ "+WPCA.newCondition,minimumInputLength:0,closeOnSelect:!0,allowClear:!1,width:"resolve",matcher:l.wpcaModuleMatcher,nextSearchTerm:function(e,t){return t},data:WPCA.conditions}).on("select2:select",function(e){var t=e.params.data;if(!i.model.conditions.findWhere({module:t.id})){var n=new CAE.Models.Condition({module:t.id,label:t.text,placeholder:t.placeholder,default_value:t.default_value});i.model.conditions.add(n)}o.val(null).trigger("change")})},showOptions:function(e){$(e.delegateTarget).find(".cas-group-options").slideToggle(200),$(e.currentTarget).toggleClass("active")},saveChanges:function(e,t){e&&i.start(this)},saveAddRemove:function(e,t,n){t.length?n.add?""!==e.get("default_value")&&i.start(this):this.model.get("id")&&i.start(this):(i.clear(this),this.model.get("id")?this.saveGroup():this.removeModel())},removeModel:function(){var e=this;this.$el.slideUp(400,function(){e.model.destroy()})},saveGroup:function(e){var i=this.$el.find(".spinner"),o=this.$el.find(".js-wpca-save-group"),t=this,n=_.clone(this.model.attributes);n.action="wpca/add-rule",n.token=l.nonce,n.current_id=l.sidebarID,n.post_type=WPCA.post_type,n.conditions={},this.model.conditions.each(function(e){e.get("values").length?n.conditions[e.get("module")]=e.get("values").map(function(e){return e.id}):""!==e.get("default_value")&&(n.conditions[e.get("module")]=[e.get("default_value")])}),o.attr("disabled",!0),i.addClass("is-active"),$.ajax({url:ajaxurl,data:n,dataType:"JSON",type:"POST",success:function(e){l.alert.success(e.message),e.removed?t.removeModel():e.new_post_id&&t.model.set("id",e.new_post_id,{silent:!0}),e.removed||(o.hide(),i.removeClass("is-active"),t.model.restartTracking(),t.model.conditions.each(function(e){e.restartTracking()}))},error:function(e,t,n){o.attr("disabled",!1).show(),i.removeClass("is-active"),l.alert.failure(e.responseJSON.data)}})},slideRemove:function(){this.$el.slideUp(400,function(){this.remove()})}}),CAE.Views.GroupCollection=Backbone.Epoxy.View.extend({bindings:"data-vm",el:"#cas-groups",collection:CAE.Models.GroupCollection,events:{"click .js-wpca-add-quick":"addGroupQuick","click .js-wpca-save":"saveAll"},conditionsById:{},initialize:function(){var o=this;this.conditionsById=_.chain(WPCA.conditions).pluck(["children"]).flatten().indexBy("id").value();var s=$(".js-wpca-add-or",this.$el);s.select2({theme:"wpca",placeholder:"+ "+WPCA.newGroup,minimumInputLength:0,closeOnSelect:!0,allowClear:!1,width:"auto",matcher:l.wpcaModuleMatcher,nextSearchTerm:function(e,t){return t},data:WPCA.conditions}).on("select2:select",function(e){var t=e.params.data,n=new CAE.Models.Group,i=new CAE.Models.Condition({module:t.id,label:t.text,placeholder:t.placeholder,default_value:t.default_value});o.collection.add(n),n.conditions.add(i),s.val(null).trigger("change")})},itemView:function(e){return new CAE.Views.Group(e)},addGroupQuick:function(e){e.preventDefault();var t=$(e.currentTarget).data("config"),n=new CAE.Models.Group;for(var i in n.set(t.options),this.collection.add(n),t.modules)if(this.conditionsById.hasOwnProperty(t.modules[i])){var o=this.conditionsById[t.modules[i]],s=new CAE.Models.Condition({module:o.id,label:o.text,placeholder:o.placeholder,default_value:o.default_value});n.conditions.add(s)}}}),$.fn.select2.amd.require(["select2/selection/search"],function(e){e.prototype.searchRemoveChoice=function(e,t){this.trigger("unselect",{data:t}),this.$search.val(""),this.handleSearch()}},null,!0),$.fn.select2.amd.require(["select2/results"],function(e){e.prototype.ensureHighlightVisible=function(){this.$results.resize()}},null,!0),$.fn.select2.amd.define("select2/wpca/conditionData",["select2/data/array","select2/utils"],function(e,t){function n(e,t){n.__super__.constructor.call(this,e,t)}return t.Extend(n,e),n.prototype.query=function(n,i){n.term=n.term||"";var o=this.options.options,s=o.cachedResults[n.term],a=n.page||1;if(s&&s.page>=a){if(!(1<a))return void i({results:s.items,pagination:{more:s.more}});a=s.page}clearTimeout(o.searchTimer),o.searchTimer=setTimeout(function(){$.ajax({url:ajaxurl,data:{search:n.term,paged:a,limit:20,action:"wpca/module/"+o.type,sidebar_id:l.sidebarID,nonce:l.nonce},dataType:"JSON",type:"POST",success:function(e){var t=!(e.length<20);o.cachedResults[n.term]={page:a,more:t,items:s?o.cachedResults[n.term].items.concat(e):e},i({results:e,pagination:{more:t}})}})},o.quietMillis)},n}),$.fn.select2.amd.define("select2/wpca/moduleMatcher",["select2/diacritics"],function(t){function l(e){return e.replace(/[^\u0000-\u007E]/g,function(e){return t[e]||e})}return function e(t,n){if(null==t.term||""===t.term.trim())return n;var i=l(n.text).toUpperCase(),o=l(t.term).toUpperCase();if(-1<i.indexOf(o))return n;if(n.children&&0<n.children.length){for(var s=$.extend(!0,{},n),a=n.children.length-1;0<=a;a--)null==e(t,n.children[a])&&s.children.splice(a,1);return 0<s.children.length?s:e(t,s)}return null}});var i={treshold:2e3,timerQueue:{},start:function(e){this.clear(e);var t=this;this.timerQueue[e.cid]=window.setTimeout(function(){t.set(e)},this.treshold)},set:function(e){e.saveGroup()},clear:function(e){e&&this.timerQueue[e.cid]&&window.clearInterval(this.timerQueue[e.cid])}},l={nonce:$("#_ca_nonce").val(),sidebarID:$("#post_ID").val(),alert:null,wpcaDataAdapter:$.fn.select2.amd.require("select2/wpca/conditionData"),wpcaModuleMatcher:$.fn.select2.amd.require("select2/wpca/moduleMatcher"),init:function(){this.alert=new CAE.Views.Alert({model:new CAE.Models.Alert}),CAE.conditionGroups=new CAE.Views.GroupCollection({collection:new CAE.Models.GroupCollection(WPCA.groups,{parse:!0})})}};$(function(){l.init()})}(jQuery,CAE);
1
+ /*!
2
+ * @package WP Content Aware Engine
3
+ * @author Joachim Jensen <joachim@dev.institute>
4
+ * @license GPLv3
5
+ * @copyright 2020 by Joachim Jensen
6
+ */
7
+ var CAE=CAE||{};!function($,CAE){"use strict";CAE.settings={views:{}},CAE.Models={},CAE.Models.Alert=Backbone.Model.extend({defaults:{text:"",success:!0},sync:function(){return!1},url:"",reset:function(){this.set(this.defaults)}}),CAE.Models.Condition=Backbone.Model.extend({unsaved:{prompt:WPCA.unsaved,unloadWindowPrompt:!0},defaults:{module:null,label:"",placeholder:"",values:[],default_value:null},initialize:function(){this.startTracking(),this.on("destroy",this.stopTracking,this)},sync:function(){return!1},url:""}),CAE.Models.Group=Backbone.Model.extend({unsaved:{prompt:WPCA.unsaved,unloadWindowPrompt:!0},defaults:function(){var e=WPCA.meta_default;return e.id=null,e.status="wpca_or",e.exposure=1,e},initialize:function(){this.startTracking(),this.on("destroy",this.stopTracking,this),this.conditions||(this.conditions=new CAE.Models.ConditionCollection)},parse:function(e){var t=[];if(_.has(e,"conditions")){for(var n in e.conditions)if(e.conditions.hasOwnProperty(n)){var i=[],o=e.conditions[n];for(var s in o.data)o.data.hasOwnProperty(s)&&i.push({text:"object"==typeof o.data[s]?o.data[s].text:o.data[s],id:s});delete o.data,o.module=n,o.values=i,t.push(o)}delete e.conditions}return this.conditions=new CAE.Models.ConditionCollection(t),e},sync:function(){return!1},url:""}),CAE.Models.GroupCollection=Backbone.Collection.extend({model:CAE.Models.Group,parse:function(e){return e}}),CAE.Models.ConditionCollection=Backbone.Collection.extend({model:CAE.Models.Condition}),CAE.Views={},CAE.Views.Alert=Backbone.Epoxy.View.extend({bindings:"data-vm",tagName:"div",className:"wpca-alert",template:"<div data-vm=\"classes:{'wpca-success':success,'wpca-error':not(success)},text:text\"></div>",timer:4e3,success:function(e){this.model.set({text:e,success:!0})},failure:function(e){this.model.set({text:e,success:!1})},dismiss:function(){var e=this;this.$el.fadeOut("slow",function(){e.model.reset()})},initialize:function(){this.listenTo(this.model,"change:text",this.show),this.$el.appendTo("body").hide().html(this.template)},show:function(){if(""!==this.model.get("text")){this.$el.fadeIn("slow");var e=this;setTimeout(function(){e.dismiss()},this.timer)}}}),CAE.Views.Condition=Backbone.Epoxy.View.extend({bindings:"data-vm",model:CAE.Models.Condition,tagName:"div",className:"cas-condition",templateName:"#wpca-template-condition",events:{"click .js-wpca-condition-remove":"removeModel"},initialize:function(){this.listenTo(this.model,"destroy",this.remove);var e=$(this.templateName);e.length?(this.template=e.html(),this.$el.append(this.template),this.createSuggestInput()):this.model.destroy()},removeModel:function(e){var t=this;this.$el.slideUp(300,function(){t.model.destroy()})},createSuggestInput:function(){var n=this.$el.find(".js-wpca-suggest");if(n.length){var i=this.model,e=this.model.get("values"),t=$("<div></div>").html(i.get("placeholder")).text();n.select2({cachedResults:{},quietMillis:400,searchTimer:null,type:i.get("module"),theme:"wpca",dir:WPCA.text_direction,placeholder:t,minimumInputLength:0,closeOnSelect:!0,width:"100%",language:{noResults:function(){return WPCA.noResults},searching:function(){return WPCA.searching+"..."},loadingMore:function(){return WPCA.loadingMore+"..."}},nextSearchTerm:function(e,t){return t},templateResult:function(e){return e.level?$('<span class="wpca-level-'+e.level+'">'+e.text+"</span>"):e.text},data:e,dataAdapter:l.wpcaDataAdapter,ajax:{}}).on("select2:selecting",function(e){n.data("forceOpen",!0)}).on("select2:closing",function(e){n.data("forceOpen")&&(e.preventDefault(),n.data("forceOpen",!1))}),e.length&&n.val(_.map(e,function(e){return e.id})).trigger("change"),n.on("change",function(e){var t=n.select2("data");i.set("values",t)})}}}),CAE.Views.Group=Backbone.Epoxy.View.extend({bindings:"data-vm",model:CAE.Models.Group,tagName:"li",className:"cas-group-single",template:$("#wpca-template-group").html(),itemView:function(e){return CAE.Views[e.model.get("module")]?new(CAE.Views[e.model.get("module")])(e):new CAE.Views.Condition(e)},events:{"click .js-wpca-save-group":"saveGroup","click .js-wpca-options":"showOptions"},computeds:{statusNegated:{deps:["status"],get:function(e){return"negated"==e},set:function(e){var t=e?"negated":"wpca_or";this.setBinding("status",t)}},statusExcept:{deps:["status"],get:function(e){return"wpca_except"==e},set:function(e){var t=e?"wpca_except":"wpca_or";this.setBinding("status",t)}},statusLabel:function(){switch(this.getBinding("status")){case"wpca_except":return WPCA.condition_except;case"negated":return WPCA.condition_not;default:return WPCA.condition_or}}},bindingFilters:{int:{get:function(e){return e?1:0},set:function(e){return e?1:0}},binary:{get:function(e){return e?1:0},set:function(e){return e?1:0}},hasModule:function(e){for(var t={},n=1;n<arguments.length;n++)t[arguments[n]]=!0;return e.filter(function(e){return t.hasOwnProperty(e.get("module"))}).length==arguments.length-1},hasAnyModule:function(e){for(var t={},n=1;n<arguments.length;n++)t[arguments[n]]=!0;return!!e.find(function(e){return t.hasOwnProperty(e.get("module"))})}},initialize:function(){this.collection=this.model.conditions,this.$el.hide().html(this.template).fadeIn(300),this.listenTo(this.model,"destroy",this.remove),this.listenTo(this.model,"unsavedChanges",this.saveChanges),this.listenTo(this.model.conditions,"unsavedChanges",this.saveChanges),this.listenTo(this.model.conditions,"add remove",this.saveAddRemove);var i=this,o=$(".js-wpca-add-and",this.$el);o.select2({theme:"wpca",placeholder:"+ "+WPCA.newCondition,minimumInputLength:0,closeOnSelect:!0,allowClear:!1,width:"resolve",matcher:l.wpcaModuleMatcher,nextSearchTerm:function(e,t){return t},data:WPCA.conditions}).on("select2:select",function(e){var t=e.params.data;if(!i.model.conditions.findWhere({module:t.id})){var n=new CAE.Models.Condition({module:t.id,label:t.text,placeholder:t.placeholder,default_value:t.default_value});i.model.conditions.add(n)}o.val(null).trigger("change")})},showOptions:function(e){$(e.delegateTarget).find(".cas-group-options").slideToggle(200),$(e.currentTarget).toggleClass("active")},saveChanges:function(e,t){e&&i.start(this)},saveAddRemove:function(e,t,n){t.length?n.add?""!==e.get("default_value")&&i.start(this):this.model.get("id")&&i.start(this):(i.clear(this),this.model.get("id")?this.saveGroup():this.removeModel())},removeModel:function(){var e=this;this.$el.slideUp(400,function(){e.model.destroy()})},saveGroup:function(e){var i=this.$el.find(".spinner"),o=this.$el.find(".js-wpca-save-group"),t=this,n=_.clone(this.model.attributes);n.action="wpca/add-rule",n.token=l.nonce,n.current_id=l.sidebarID,n.post_type=WPCA.post_type,n.conditions={},this.model.conditions.each(function(e){e.get("values").length?n.conditions[e.get("module")]=e.get("values").map(function(e){return e.id}):""!==e.get("default_value")&&(n.conditions[e.get("module")]=[e.get("default_value")])}),o.attr("disabled",!0),i.addClass("is-active"),$.ajax({url:ajaxurl,data:n,dataType:"JSON",type:"POST",success:function(e){l.alert.success(e.message),e.removed?t.removeModel():e.new_post_id&&t.model.set("id",e.new_post_id,{silent:!0}),e.removed||(o.hide(),i.removeClass("is-active"),t.model.restartTracking(),t.model.conditions.each(function(e){e.restartTracking()}))},error:function(e,t,n){o.attr("disabled",!1).show(),i.removeClass("is-active"),l.alert.failure(e.responseJSON.data)}})},slideRemove:function(){this.$el.slideUp(400,function(){this.remove()})}}),CAE.Views.GroupCollection=Backbone.Epoxy.View.extend({bindings:"data-vm",el:"#cas-groups",collection:CAE.Models.GroupCollection,events:{"click .js-wpca-add-quick":"addGroupQuick","click .js-wpca-save":"saveAll"},conditionsById:{},initialize:function(){var o=this;this.conditionsById=_.chain(WPCA.conditions).pluck(["children"]).flatten().indexBy("id").value();var s=$(".js-wpca-add-or",this.$el);s.select2({theme:"wpca",placeholder:"+ "+WPCA.newGroup,minimumInputLength:0,closeOnSelect:!0,allowClear:!1,width:"auto",matcher:l.wpcaModuleMatcher,nextSearchTerm:function(e,t){return t},data:WPCA.conditions}).on("select2:select",function(e){var t=e.params.data,n=new CAE.Models.Group,i=new CAE.Models.Condition({module:t.id,label:t.text,placeholder:t.placeholder,default_value:t.default_value});o.collection.add(n),n.conditions.add(i),s.val(null).trigger("change")})},itemView:function(e){return new CAE.Views.Group(e)},addGroupQuick:function(e){e.preventDefault();var t=$(e.currentTarget).data("config"),n=new CAE.Models.Group;for(var i in n.set(t.options),this.collection.add(n),t.modules)if(this.conditionsById.hasOwnProperty(t.modules[i])){var o=this.conditionsById[t.modules[i]],s=new CAE.Models.Condition({module:o.id,label:o.text,placeholder:o.placeholder,default_value:o.default_value});n.conditions.add(s)}}}),$.fn.select2.amd.require(["select2/selection/search"],function(e){e.prototype.searchRemoveChoice=function(e,t){this.trigger("unselect",{data:t}),this.$search.val(""),this.handleSearch()}},null,!0),$.fn.select2.amd.require(["select2/results"],function(e){e.prototype.ensureHighlightVisible=function(){this.$results.resize()}},null,!0),$.fn.select2.amd.define("select2/wpca/conditionData",["select2/data/array","select2/utils"],function(e,t){function n(e,t){n.__super__.constructor.call(this,e,t)}return t.Extend(n,e),n.prototype.query=function(n,i){n.term=n.term||"";var o=this.options.options,s=o.cachedResults[n.term],a=n.page||1;if(s&&s.page>=a){if(!(1<a))return void i({results:s.items,pagination:{more:s.more}});a=s.page}clearTimeout(o.searchTimer),o.searchTimer=setTimeout(function(){$.ajax({url:ajaxurl,data:{search:n.term,paged:a,limit:20,action:"wpca/module/"+o.type,sidebar_id:l.sidebarID,nonce:l.nonce},dataType:"JSON",type:"POST",success:function(e){var t=20<=e.length;o.cachedResults[n.term]={page:a,more:t,items:s?o.cachedResults[n.term].items.concat(e):e},i({results:e,pagination:{more:t}})}})},o.quietMillis)},n}),$.fn.select2.amd.define("select2/wpca/moduleMatcher",["select2/diacritics"],function(t){function l(e){return e.replace(/[^\u0000-\u007E]/g,function(e){return t[e]||e})}return function e(t,n){if(null==t.term||""===t.term.trim())return n;var i=l(n.text).toUpperCase(),o=l(t.term).toUpperCase();if(-1<i.indexOf(o))return n;if(n.children&&0<n.children.length){for(var s=$.extend(!0,{},n),a=n.children.length-1;0<=a;a--)null==e(t,n.children[a])&&s.children.splice(a,1);return 0<s.children.length?s:e(t,s)}return null}});var i={treshold:2e3,timerQueue:{},start:function(e){this.clear(e);var t=this;this.timerQueue[e.cid]=window.setTimeout(function(){t.set(e)},this.treshold)},set:function(e){e.saveGroup()},clear:function(e){e&&this.timerQueue[e.cid]&&window.clearInterval(this.timerQueue[e.cid])}},l={nonce:$("#_ca_nonce").val(),sidebarID:$("#post_ID").val(),alert:null,wpcaDataAdapter:$.fn.select2.amd.require("select2/wpca/conditionData"),wpcaModuleMatcher:$.fn.select2.amd.require("select2/wpca/moduleMatcher"),init:function(){this.alert=new CAE.Views.Alert({model:new CAE.Models.Alert}),CAE.conditionGroups=new CAE.Views.GroupCollection({collection:new CAE.Models.GroupCollection(WPCA.groups,{parse:!0})})}};$(function(){l.init()})}(jQuery,CAE);
lib/wp-content-aware-engine/assets/js/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- /**/
1
+ <?php
2
+ /**/
lib/wp-content-aware-engine/bootstrap.php CHANGED
@@ -12,7 +12,7 @@ defined('ABSPATH') || exit;
12
  * Version of this WPCA
13
  * @var string
14
  */
15
- $this_wpca_version = '9.2a';
16
 
17
  /**
18
  * Class to make sure the latest
@@ -28,7 +28,7 @@ if (!class_exists('WPCALoader')) {
28
  * Absolute paths and versions
29
  * @var array
30
  */
31
- private static $_paths = array();
32
 
33
  public function __construct()
34
  {
@@ -87,6 +87,6 @@ if (!class_exists('WPCALoader')) {
87
  }
88
  }
89
  //Hook as early as possible after plugins are loaded
90
- add_action('plugins_loaded', array('WPCALoader','load'), -999999);
91
  }
92
  WPCALoader::add(plugin_dir_path(__FILE__), $this_wpca_version);
12
  * Version of this WPCA
13
  * @var string
14
  */
15
+ $this_wpca_version = '9.3a';
16
 
17
  /**
18
  * Class to make sure the latest
28
  * Absolute paths and versions
29
  * @var array
30
  */
31
+ private static $_paths = [];
32
 
33
  public function __construct()
34
  {
87
  }
88
  }
89
  //Hook as early as possible after plugins are loaded
90
+ add_action('plugins_loaded', ['WPCALoader','load'], -999999);
91
  }
92
  WPCALoader::add(plugin_dir_path(__FILE__), $this_wpca_version);
lib/wp-content-aware-engine/core.php CHANGED
@@ -1,234 +1,234 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- if (!class_exists('WPCACore')) {
12
- $domain = explode('/', plugin_basename(__FILE__));
13
- define('WPCA_DOMAIN', $domain[0]);
14
- define('WPCA_PATH', plugin_dir_path(__FILE__));
15
-
16
- /**
17
- * Core for WordPress Content Aware Engine
18
- */
19
- final class WPCACore
20
- {
21
-
22
- /**
23
- * Using class prefix instead of namespace
24
- * for PHP5.2 compatibility
25
- */
26
- const CLASS_PREFIX = 'WPCA';
27
-
28
- /**
29
- * Prefix for data (keys) stored in database
30
- */
31
- const PREFIX = '_ca_';
32
-
33
- /**
34
- * Post Type for condition groups
35
- */
36
- const TYPE_CONDITION_GROUP = 'condition_group';
37
-
38
- /**
39
- * Post Statuses for condition groups
40
- */
41
- /**
42
- * @deprecated
43
- */
44
- const STATUS_NEGATED = 'negated';
45
- /**
46
- * @deprecated
47
- */
48
- const STATUS_PUBLISHED = 'publish';
49
- const STATUS_OR = 'wpca_or';
50
- const STATUS_EXCEPT = 'wpca_except';
51
-
52
- /**
53
- * Exposures for condition groups
54
- */
55
- const EXP_SINGULAR = 0;
56
- const EXP_SINGULAR_ARCHIVE = 1;
57
- const EXP_ARCHIVE = 2;
58
-
59
- /**
60
- * @deprecated 7.0
61
- */
62
- const CAPABILITY = 'edit_theme_options';
63
-
64
- /**
65
- * Name for generated nonces
66
- */
67
- const NONCE = '_ca_nonce';
68
-
69
- const OPTION_CONDITION_TYPE_CACHE = '_ca_condition_type_cache';
70
- const OPTION_POST_TYPE_OPTIONS = '_ca_post_type_options';
71
-
72
- /**
73
- * Post Types that use the engine
74
- * @var WPCAPostTypeManager
75
- */
76
- private static $type_manager;
77
-
78
- /**
79
- * Conditions retrieved from database
80
- * @var array
81
- */
82
- private static $condition_cache = array();
83
-
84
- /**
85
- * Objects retrieved from database
86
- * @var array
87
- */
88
- private static $post_cache = array();
89
-
90
- private static $wp_query_original = array();
91
-
92
- private static $filtered_modules = array();
93
-
94
- /**
95
- * Constructor
96
- */
97
- public static function init()
98
- {
99
- spl_autoload_register(array(__CLASS__,'_autoload_class_files'));
100
-
101
- if (is_admin()) {
102
- add_action(
103
- 'admin_enqueue_scripts',
104
- array(__CLASS__,'add_group_script_styles'),
105
- 9
106
- );
107
- add_action(
108
- 'delete_post',
109
- array(__CLASS__,'sync_group_deletion')
110
- );
111
- add_action(
112
- 'trashed_post',
113
- array(__CLASS__,'sync_group_trashed')
114
- );
115
- add_action(
116
- 'untrashed_post',
117
- array(__CLASS__,'sync_group_untrashed')
118
- );
119
- add_action(
120
- 'add_meta_boxes',
121
- array(__CLASS__,'add_group_meta_box'),
122
- 10,
123
- 2
124
- );
125
- add_action(
126
- 'wpca/modules/save-data',
127
- array(__CLASS__,'save_condition_options'),
128
- 10,
129
- 3
130
- );
131
-
132
- add_action(
133
- 'wp_ajax_wpca/add-rule',
134
- array(__CLASS__,'ajax_update_group')
135
- );
136
- }
137
-
138
- add_action(
139
- 'init',
140
- array(__CLASS__,'add_group_post_type'),
141
- 99
142
- );
143
-
144
- add_action(
145
- 'init',
146
- array(__CLASS__,'schedule_cache_condition_types'),
147
- 99
148
- );
149
-
150
- add_action(
151
- 'wpca/cache_condition_types',
152
- array(__CLASS__,'cache_condition_types'),
153
- 999
154
- );
155
- }
156
-
157
- /**
158
- * Get post type manager
159
- *
160
- * @deprecated 4.0
161
- * @since 1.0
162
- * @return WPCAPostTypeManager
163
- */
164
- public static function post_types()
165
- {
166
- return self::types();
167
- }
168
-
169
- /**
170
- * Get type manager
171
- *
172
- * @since 4.0
173
- * @return WPCAPostTypeManager
174
- */
175
- public static function types()
176
- {
177
- if (!isset(self::$type_manager)) {
178
- self::$type_manager = new WPCATypeManager();
179
- }
180
- return self::$type_manager;
181
- }
182
-
183
- /**
184
- * @since 8.0
185
- *
186
- * @return void
187
- */
188
- public static function schedule_cache_condition_types()
189
- {
190
- if (wp_next_scheduled('wpca/cache_condition_types') !== false) {
191
- return;
192
- }
193
-
194
- wp_schedule_event(get_gmt_from_date('today 02:00:00', 'U'), 'daily', 'wpca/cache_condition_types');
195
- }
196
-
197
- /**
198
- * Cache condition types currently in use
199
- *
200
- * @since 8.0
201
- *
202
- * @return void
203
- */
204
- public static function cache_condition_types()
205
- {
206
- $all_modules = array();
207
- $modules_by_type = array();
208
- $ignored_modules = array('taxonomy' => 1);
209
- $cache = array();
210
-
211
- $types = self::types();
212
- foreach ($types as $type => $modules) {
213
- $modules_by_type[$type] = array();
214
- $cache[$type] = array();
215
- foreach ($modules as $module) {
216
- if (isset($ignored_modules[$module->get_id()])) {
217
- continue;
218
- }
219
-
220
- $modules_by_type[$type][$module->get_data_key()] = $module->get_id();
221
- $all_modules[$module->get_data_key()] = $module->get_data_key();
222
- }
223
- }
224
-
225
- if (!$all_modules) {
226
- update_option(self::OPTION_CONDITION_TYPE_CACHE, array());
227
- return;
228
- }
229
-
230
- global $wpdb;
231
-
232
  $query = '
233
  SELECT p.post_type, m.meta_key
234
  FROM '.$wpdb->posts.' p
@@ -237,1030 +237,1031 @@ INNER JOIN '.$wpdb->postmeta.' m ON m.post_id = c.ID
237
  WHERE p.post_type IN ('.self::sql_prepare_in(array_keys($modules_by_type)).')
238
  AND m.meta_key IN ('.self::sql_prepare_in($all_modules).')
239
  GROUP BY p.post_type, m.meta_key
240
- ';
241
-
242
- $results = (array) $wpdb->get_results($query);
243
-
244
- foreach ($results as $result) {
245
- if (isset($modules_by_type[$result->post_type][$result->meta_key])) {
246
- $cache[$result->post_type][] = $modules_by_type[$result->post_type][$result->meta_key];
247
- }
248
- }
249
-
250
- update_option(self::OPTION_CONDITION_TYPE_CACHE, $cache);
251
- }
252
-
253
- /**
254
- * Register group post type
255
- *
256
- * @since 1.0
257
- * @return void
258
- */
259
- public static function add_group_post_type()
260
- {
261
- //This is just a safety placeholder,
262
- //authorization will be done with parent object's cap
263
- $capability = 'edit_theme_options';
264
- $capabilities = array(
265
- 'edit_post' => $capability,
266
- 'read_post' => $capability,
267
- 'delete_post' => $capability,
268
- 'edit_posts' => $capability,
269
- 'delete_posts' => $capability,
270
- 'edit_others_posts' => $capability,
271
- 'publish_posts' => $capability,
272
- 'read_private_posts' => $capability
273
- );
274
-
275
- register_post_type(self::TYPE_CONDITION_GROUP, array(
276
- 'labels' => array(
277
- 'name' => __('Condition Groups', WPCA_DOMAIN),
278
- 'singular_name' => __('Condition Group', WPCA_DOMAIN),
279
- ),
280
- 'capabilities' => $capabilities,
281
- 'public' => false,
282
- 'hierarchical' => false,
283
- 'exclude_from_search' => true,
284
- 'publicly_queryable' => false,
285
- 'show_ui' => false,
286
- 'show_in_menu' => false,
287
- 'show_in_nav_menus' => false,
288
- 'show_in_admin_bar' => false,
289
- 'has_archive' => false,
290
- 'rewrite' => false,
291
- 'query_var' => false,
292
- 'supports' => array('author'),
293
- 'can_export' => false,
294
- 'delete_with_user' => false
295
- ));
296
-
297
- register_post_status(self::STATUS_NEGATED, array(
298
- 'label' => _x('Negated', 'condition status', WPCA_DOMAIN),
299
- 'public' => false,
300
- 'exclude_from_search' => true,
301
- 'show_in_admin_all_list' => false,
302
- 'show_in_admin_status_list' => false,
303
- ));
304
- register_post_status(self::STATUS_EXCEPT, array(
305
- 'label' => _x('Exception', 'condition status', WPCA_DOMAIN),
306
- 'public' => false,
307
- 'exclude_from_search' => true,
308
- 'show_in_admin_all_list' => false,
309
- 'show_in_admin_status_list' => false,
310
- ));
311
- register_post_status(self::STATUS_OR, array(
312
- 'label' => _x('Or', 'condition status', WPCA_DOMAIN),
313
- 'public' => false,
314
- 'exclude_from_search' => true,
315
- 'show_in_admin_all_list' => false,
316
- 'show_in_admin_status_list' => false,
317
- ));
318
- }
319
-
320
- /**
321
- * Get group IDs by their parent ID
322
- *
323
- * @since 1.0
324
- * @param int $parent_id
325
- * @return array
326
- */
327
- private static function get_group_ids_by_parent($parent_id)
328
- {
329
- if (!self::types()->has(get_post_type($parent_id))) {
330
- return array();
331
- }
332
-
333
- global $wpdb;
334
- return (array)$wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = '%d'", $parent_id));
335
- }
336
-
337
- /**
338
- * Delete groups from database when their parent is deleted
339
- *
340
- * @since 1.0
341
- * @param int $post_id
342
- * @return void
343
- */
344
- public static function sync_group_deletion($post_id)
345
- {
346
- $groups = self::get_group_ids_by_parent($post_id);
347
- if ($groups) {
348
- foreach ($groups as $group_id) {
349
- //Takes care of metadata and terms too
350
- wp_delete_post($group_id, true);
351
- }
352
- }
353
- }
354
-
355
- /**
356
- * Trash groups when their parent is trashed
357
- *
358
- * @since 1.0
359
- * @param int $post_id
360
- * @return void
361
- */
362
- public static function sync_group_trashed($post_id)
363
- {
364
- $groups = self::get_group_ids_by_parent($post_id);
365
- if ($groups) {
366
- foreach ($groups as $group_id) {
367
- wp_trash_post($group_id);
368
- }
369
- }
370
- }
371
-
372
- /**
373
- * Untrash groups when their parent is untrashed
374
- *
375
- * @since 1.0
376
- * @param int $post_id
377
- * @return void
378
- */
379
- public static function sync_group_untrashed($post_id)
380
- {
381
- $groups = self::get_group_ids_by_parent($post_id);
382
- if ($groups) {
383
- foreach ($groups as $group_id) {
384
- wp_untrash_post($group_id);
385
- }
386
- }
387
- }
388
-
389
- /**
390
- * @param string $post_type
391
- * @return array
392
- */
393
- public static function get_conditional_modules($post_type)
394
- {
395
- if (!isset(self::$filtered_modules[$post_type])) {
396
- return array();
397
- }
398
- return self::$filtered_modules[$post_type];
399
- }
400
-
401
- /**
402
- * Get filtered condition groups
403
- *
404
- * @since 2.0
405
- * @return array
406
- */
407
- public static function get_conditions($post_type)
408
- {
409
- global $wpdb, $wp_query, $post;
410
-
411
- if ((!$wp_query->query && !$post) || is_admin()) {
412
- return array();
413
- }
414
-
415
- // Return cache if present
416
- if (isset(self::$condition_cache[$post_type])) {
417
- return self::$condition_cache[$post_type];
418
- }
419
-
420
- $excluded = array();
421
- $where = array();
422
- $join = array();
423
-
424
- $cache = array(
425
- $post_type
426
- );
427
-
428
- $modules = self::types()->get($post_type)->get_all();
429
- $modules = self::filter_condition_type_cache($post_type, $modules);
430
-
431
- //avoid combining as long as negated conditions are being deprecated
432
- // foreach (self::types() as $other_type => $other_modules) {
433
- // if ($other_type == $post_type) {
434
- // continue;
435
- // }
436
- // if (self::filter_condition_type_cache($other_type, $other_modules->get_all()) === $modules) {
437
- // $cache[] = $other_type;
438
- // }
439
- // }
440
-
441
- self::fix_wp_query();
442
-
443
- foreach ($modules as $module) {
444
- $id = $module->get_id();
445
- $name = $module->get_query_name();
446
- if (apply_filters("wpca/module/$id/in-context", $module->in_context())) {
447
- $join[$id] = apply_filters("wpca/module/$id/db-join", $module->db_join());
448
- $data = $module->get_context_data();
449
- if (is_array($data)) {
450
- $data = "($name.meta_value IS NULL OR $name.meta_value IN ('".implode("','", $data) ."'))";
451
- }
452
- $where[$id] = apply_filters("wpca/module/$id/db-where", $data);
453
- self::$filtered_modules[$post_type][] = $module;
454
- } else {
455
- $excluded[] = $module;
456
- }
457
- }
458
-
459
- $use_negated_conditions = self::get_option($post_type, 'legacy.negated_conditions', false);
460
-
461
- // Check if there are any conditions for current content
462
- $groups_in_context = array();
463
- if (!empty($where)) {
464
- $post_status = array(
465
- self::STATUS_PUBLISHED,
466
- self::STATUS_OR,
467
- self::STATUS_EXCEPT
468
- );
469
-
470
- if ($use_negated_conditions) {
471
- $post_status[] = self::STATUS_NEGATED;
472
- }
473
-
474
- if (defined('CAS_SQL_CHUNK_SIZE') && CAS_SQL_CHUNK_SIZE > 0) {
475
- $chunk_size = CAS_SQL_CHUNK_SIZE;
476
- } else {
477
- //Syntax changed in MySQL 5.5 and MariaDB 10.0 (reports as version 5.5)
478
- $wpdb->query('SET'.(version_compare($wpdb->db_version(), '5.5', '>=') ? ' SESSION' : ' OPTION').' SQL_BIG_SELECTS = 1');
479
- $chunk_size = count($join);
480
- }
481
-
482
- $joins = array_chunk($join, $chunk_size);
483
- $joins_max = count($joins) - 1;
484
- $wheres = array_chunk($where, $chunk_size);
485
- $group_ids = array();
486
- $groups_in_context = array();
487
-
488
- $where2 = array();
489
- $where2[] = "p.post_type = '".self::TYPE_CONDITION_GROUP."'";
490
- $where2[] = "p.post_status IN ('".implode("','", $post_status)."')";
491
- //exposure
492
- $where2[] = 'p.menu_order '.(is_archive() || is_home() ? '>=' : '<=').' 1';
493
-
494
- foreach ($joins as $i => $join) {
495
- if ($i == $joins_max) {
496
- $groups_in_context = $wpdb->get_results(
497
- 'SELECT p.ID, p.post_parent, p.post_status '.
498
- "FROM $wpdb->posts p ".
 
499
  implode(' ', $join).'
500
  WHERE
501
  '.implode(' AND ', $wheres[$i]).'
502
- AND '.implode(' AND ', $where2).
503
- (!empty($group_ids) ? ' AND p.id IN ('.implode(',', $group_ids).')' : ''),
504
- OBJECT_K
505
- );
506
- break;
507
- }
508
-
509
- $group_ids = array_merge($group_ids, $wpdb->get_col(
510
- 'SELECT p.ID '.
511
- "FROM $wpdb->posts p ".
512
  implode(' ', $join).'
513
  WHERE
514
  '.implode(' AND ', $wheres[$i]).'
515
- AND '.implode(' AND ', $where2)
516
- ));
517
- }
518
- }
519
-
520
- $groups_negated = array();
521
- if ($use_negated_conditions) {
522
- $groups_negated = $wpdb->get_results($wpdb->prepare(
523
- 'SELECT p.ID, p.post_parent '.
524
- "FROM $wpdb->posts p ".
525
- "WHERE p.post_type = '%s' ".
526
- "AND p.post_status = '%s' ",
527
- self::TYPE_CONDITION_GROUP,
528
- self::STATUS_NEGATED
529
- ), OBJECT_K);
530
- }
531
-
532
- if (!empty($groups_in_context) || !empty($groups_negated)) {
533
- //Force update of meta cache to prevent lazy loading
534
- update_meta_cache('post', array_keys($groups_in_context + $groups_negated));
535
- }
536
-
537
- //condition group => type
538
- $valid = array();
539
- foreach ($groups_in_context as $group) {
540
- $valid[$group->ID] = $group->post_parent;
541
- }
542
-
543
- //Exclude types that have unrelated content in same group
544
- foreach ($excluded as $module) {
545
- $valid = $module->filter_excluded_context($valid);
546
- }
547
-
548
- //exclude exceptions
549
- $excepted = array();
550
- foreach ($valid as $group_id => $parent_id) {
551
- //sanity
552
- if (!isset($groups_in_context[$group_id])) {
553
- continue;
554
- }
555
-
556
- if ($groups_in_context[$group_id]->post_status == self::STATUS_EXCEPT) {
557
- $excepted[$parent_id] = 1;
558
- }
559
- }
560
-
561
- foreach ($valid as $group_id => $parent_id) {
562
- if (isset($excepted[$parent_id])) {
563
- unset($valid[$group_id]);
564
- }
565
- }
566
-
567
- if ($use_negated_conditions) {
568
- //Filter negated groups
569
- //type => group
570
- $handled_already = array_flip($valid);
571
- foreach ($groups_negated as $group) {
572
- if (isset($valid[$group->ID])) {
573
- unset($valid[$group->ID]);
574
- } else {
575
- $valid[$group->ID] = $group->post_parent;
576
- }
577
- if (isset($handled_already[$group->post_parent])) {
578
- unset($valid[$group->ID]);
579
- }
580
- $handled_already[$group->post_parent] = 1;
581
- }
582
- }
583
-
584
- self::restore_wp_query();
585
-
586
- foreach ($cache as $cache_type) {
587
- self::$condition_cache[$cache_type] = $valid;
588
- }
589
-
590
- return self::$condition_cache[$post_type];
591
- }
592
-
593
- /**
594
- * Get filtered posts from a post type
595
- *
596
- * @since 1.0
597
- * @global type $wpdb
598
- * @global WP_Query $wp_query
599
- * @global WP_Post $post
600
- * @return array
601
- */
602
- public static function get_posts($post_type)
603
- {
604
- global $wp_query, $post;
605
-
606
- // Return cache if present
607
- if (isset(self::$post_cache[$post_type])) {
608
- return self::$post_cache[$post_type];
609
- }
610
-
611
- if (!self::types()->has($post_type) || (!$wp_query->query && !$post) || is_admin()) {
612
- return false;
613
- }
614
-
615
- $valid = self::get_conditions($post_type);
616
-
617
- self::$post_cache[$post_type] = array();
618
-
619
- $results = array();
620
-
621
- if (!empty($valid)) {
622
- $data = new WP_Query(array(
623
- 'post__in' => array_values($valid),
624
- 'post_type' => $post_type,
625
- 'post_status' => 'publish',
626
- 'posts_per_page' => -1,
627
- 'ignore_sticky_posts' => true,
628
- 'update_post_term_cache' => false,
629
- 'update_post_meta_cache' => true,
630
- 'suppress_filters' => true,
631
- 'no_found_rows' => true,
632
- 'orderby' => 'none'
633
- ));
634
-
635
- $results = array_merge($results, $data->posts);
636
- }
637
-
638
- //legacy sorting
639
- uasort($results, function (WP_Post $post_a, WP_Post $post_b) {
640
- //asc
641
- if ($post_a->menu_order != $post_b->menu_order) {
642
- return $post_a->menu_order < $post_b->menu_order ? -1 : 1;
643
- }
644
-
645
- $post_a_handle = get_post_meta($post_a->ID, '_ca_handle', true);
646
- $post_b_handle = get_post_meta($post_b->ID, '_ca_handle', true);
647
-
648
- //desc
649
- if ($post_a_handle != $post_b_handle) {
650
- return $post_a_handle > $post_b_handle ? -1 : 1;
651
- }
652
-
653
- //desc
654
- if ($post_a->post_date != $post_b->post_date) {
655
- return $post_a->post_date > $post_b->post_date ? -1 : 1;
656
- }
657
-
658
- return 0;
659
- });
660
-
661
- $results = array_reduce($results, function ($carry, $post) {
662
- $carry[$post->ID] = (object)array(
663
- 'ID' => $post->ID,
664
- 'post_type' => $post->post_type,
665
- 'handle' => get_post_meta($post->ID, '_ca_handle', true),
666
- 'menu_order' => $post->menu_order,
667
- 'post_date' => $post->post_date
668
- );
669
- return $carry;
670
- }, array());
671
-
672
- self::$post_cache[$post_type] = apply_filters("wpca/posts/{$post_type}", $results);
673
-
674
- return self::$post_cache[$post_type];
675
- }
676
-
677
- /**
678
- * Add meta box to manage condition groups
679
- *
680
- * @since 1.0
681
- * @param string $post_type
682
- * @param WP_Post $post
683
- */
684
- public static function add_group_meta_box($post_type, $post)
685
- {
686
- if (is_null($post)) {
687
- return;
688
- }
689
- self::render_group_meta_box($post, $post_type, 'normal', 'default');
690
- }
691
-
692
- public static function render_group_meta_box($post, $screen, $context = 'normal', $priority = 'default')
693
- {
694
- if (is_null($post) || !self::types()->has($post->post_type)) {
695
- return;
696
- }
697
-
698
- $post_type_obj = get_post_type_object($post->post_type);
699
-
700
- if (!current_user_can($post_type_obj->cap->edit_post, $post->ID)) {
701
- return;
702
- }
703
-
704
- $template = WPCAView::make('condition_options', array(
705
- 'post_type' => $post->post_type
706
- ));
707
- add_action('wpca/group/settings', array($template,'render'), -1, 2);
708
-
709
- $template = WPCAView::make('group_template', array(
710
- 'post_type' => $post->post_type
711
- ));
712
- add_action('admin_footer', array($template,'render'));
713
-
714
- $template = WPCAView::make('condition_template');
715
- add_action('admin_footer', array($template,'render'));
716
-
717
- $view = WPCAView::make('meta_box', array(
718
- 'post_type' => $post->post_type,
719
- 'nonce' => wp_nonce_field(self::PREFIX.$post->ID, self::NONCE, true, false),
720
- ));
721
-
722
- $title = isset($post_type_obj->labels->ca_title) ? $post_type_obj->labels->ca_title : __('Conditional Logic', WPCA_DOMAIN);
723
-
724
- add_meta_box(
725
- 'cas-rules',
726
- $title,
727
- array($view,'render'),
728
- $screen,
729
- $context,
730
- $priority
731
- );
732
- }
733
-
734
- /**
735
- * Insert new condition group for a post type
736
- * Uses current post per default
737
- *
738
- * @since 1.0
739
- * @param WP_Post|int $post
740
- * @return int
741
- */
742
- public static function add_condition_group($post_id = null)
743
- {
744
- $post = get_post($post_id);
745
-
746
- //Make sure to go from auto-draft to draft
747
- if ($post->post_status == 'auto-draft') {
748
- wp_update_post(array(
749
- 'ID' => $post->ID,
750
- 'post_title' => '',
751
- 'post_status' => 'draft'
752
- ));
753
- }
754
-
755
- return wp_insert_post(array(
756
- 'post_status' => self::STATUS_OR,
757
- 'menu_order' => self::EXP_SINGULAR_ARCHIVE,
758
- 'post_type' => self::TYPE_CONDITION_GROUP,
759
- 'post_author' => $post->post_author,
760
- 'post_parent' => $post->ID,
761
- ));
762
- }
763
-
764
- /**
765
- * Get condition groups for a post type
766
- * Uses current post per default
767
- *
768
- * @since 1.0
769
- * @param WP_Post|int $post_id
770
- * @return array
771
- */
772
- private static function get_condition_groups($post_id = null)
773
- {
774
- $post = get_post($post_id);
775
- $groups = array();
776
-
777
- if ($post) {
778
- $groups = get_posts(array(
779
- 'posts_per_page' => -1,
780
- 'post_type' => self::TYPE_CONDITION_GROUP,
781
- 'post_parent' => $post->ID,
782
- 'post_status' => array(self::STATUS_PUBLISHED,self::STATUS_NEGATED,self::STATUS_EXCEPT, self::STATUS_OR),
783
- 'order' => 'ASC',
784
- 'orderby' => 'post_status'
785
- ));
786
- }
787
- return $groups;
788
- }
789
-
790
- /**
791
- * AJAX callback to update a condition group
792
- *
793
- * @since 1.0
794
- * @return void
795
- */
796
- public static function ajax_update_group()
797
- {
798
- if (!isset($_POST['current_id']) ||
799
- !check_ajax_referer(self::PREFIX.$_POST['current_id'], 'token', false)) {
800
- wp_send_json_error(__('Unauthorized request', WPCA_DOMAIN), 403);
801
- }
802
-
803
- $parent_id = (int)$_POST['current_id'];
804
- $parent_type = get_post_type_object($_POST['post_type']);
805
-
806
- if (! current_user_can($parent_type->cap->edit_post, $parent_id)) {
807
- wp_send_json_error(__('Unauthorized request', WPCA_DOMAIN), 403);
808
- }
809
-
810
- $response = array(
811
- 'message' => __('Conditions updated', WPCA_DOMAIN)
812
- );
813
-
814
- //Make sure some rules are sent
815
- if (!isset($_POST['conditions'])) {
816
- //Otherwise we delete group
817
- if ($_POST['id'] && wp_delete_post(intval($_POST['id']), true) === false) {
818
- wp_send_json_error(__('Could not delete conditions', WPCA_DOMAIN), 500);
819
- }
820
-
821
- $response['removed'] = true;
822
- wp_send_json($response);
823
- }
824
-
825
- //If ID was not sent at this point, it is a new group
826
- if (!$_POST['id']) {
827
- $post_id = self::add_condition_group($parent_id);
828
- $response['new_post_id'] = $post_id;
829
- } else {
830
- $post_id = (int)$_POST['id'];
831
- }
832
-
833
- wp_update_post(array(
834
- 'ID' => $post_id,
835
- 'post_status' => self::sanitize_status($_POST['status']),
836
- 'menu_order' => (int)$_POST['exposure']
837
- ));
838
-
839
- //Prune condition type cache, will rebuild within 24h
840
- update_option(self::OPTION_CONDITION_TYPE_CACHE, array());
841
-
842
- foreach (self::types()->get($parent_type->name)->get_all() as $module) {
843
- //send $_POST here
844
- $module->save_data($post_id);
845
- }
846
-
847
- do_action('wpca/modules/save-data', $post_id, $parent_type->name);
848
-
849
- wp_send_json($response);
850
- }
851
-
852
- /**
853
- * @param string $status
854
- *
855
- * @return string
856
- */
857
- private static function sanitize_status($status)
858
- {
859
- switch ($status) {
860
- case self::STATUS_NEGATED:
861
- return self::STATUS_NEGATED;
862
- case self::STATUS_EXCEPT:
863
- return self::STATUS_EXCEPT;
864
- case self::STATUS_OR:
865
- case self::STATUS_PUBLISHED:
866
- default:
867
- return self::STATUS_OR;
868
- }
869
- }
870
-
871
- /**
872
- * Save registered meta for condition group
873
- *
874
- * @since 3.2
875
- * @param int $group_id
876
- * @return void
877
- */
878
- public static function save_condition_options($group_id, $post_type)
879
- {
880
- $meta_keys = self::get_condition_meta_keys($post_type);
881
- foreach ($meta_keys as $key => $default_value) {
882
- $value = isset($_POST[$key]) ? $_POST[$key] : false;
883
- if ($value) {
884
- update_post_meta($group_id, $key, $value);
885
- } elseif (get_post_meta($group_id, $key, true)) {
886
- delete_post_meta($group_id, $key);
887
- }
888
- }
889
- }
890
-
891
- public static function add_group_script_styles($hook)
892
- {
893
- $current_screen = get_current_screen();
894
-
895
- wp_register_style(
896
- self::PREFIX.'condition-groups',
897
- plugins_url('/assets/css/condition_groups.css', __FILE__),
898
- array(),
899
- WPCA_VERSION
900
- );
901
-
902
- if (self::types()->has($current_screen->post_type) && $current_screen->base == 'post') {
903
- self::enqueue_scripts_styles($current_screen->post_type);
904
- }
905
- }
906
-
907
- /**
908
- * Get condition option defaults
909
- *
910
- * @since 3.2
911
- * @param string $post_type
912
- * @return array
913
- */
914
- public static function get_condition_meta_keys($post_type)
915
- {
916
- $group_meta = array(
917
- '_ca_autoselect' => 0
918
- );
919
- return apply_filters('wpca/condition/meta', $group_meta, $post_type);
920
- }
921
-
922
- /**
923
- * Register and enqueue scripts and styles
924
- * for post edit screen
925
- *
926
- * @since 1.0
927
- * @param string $hook
928
- * @return void
929
- */
930
- public static function enqueue_scripts_styles($post_type = '')
931
- {
932
- $post_type = empty($post_type) ? get_post_type() : $post_type;
933
-
934
- $group_meta = self::get_condition_meta_keys($post_type);
935
-
936
- $groups = self::get_condition_groups();
937
- $data = array();
938
- $i = 0;
939
- foreach ($groups as $group) {
940
- $data[$i] = array(
941
- 'id' => $group->ID,
942
- 'status' => $group->post_status,
943
- 'exposure' => $group->menu_order,
944
- 'conditions' => array()
945
- );
946
-
947
- foreach (self::types()->get($post_type)->get_all() as $module) {
948
- $data[$i]['conditions'] = $module->get_group_data($data[$i]['conditions'], $group->ID);
949
- }
950
-
951
- foreach ($group_meta as $meta_key => $default_value) {
952
- $value = get_post_meta($group->ID, $meta_key, true);
953
- if ($value === false) {
954
- $value = $default_value;
955
- }
956
- $data[$i][$meta_key] = $value;
957
- }
958
- $i++;
959
- }
960
-
961
- $conditions = array(
962
- 'general' => array(
963
- 'text' => __('General'),
964
- 'children' => array()
965
- ),
966
- 'post_type' => array(
967
- 'text' => __('Post Types'),
968
- 'children' => array()
969
- ),
970
- 'taxonomy' => array(
971
- 'text' => __('Taxonomies'),
972
- 'children' => array()
973
- ),
974
- 'plugins' => array(
975
- 'text' => __('Plugins'),
976
- 'children' => array()
977
- )
978
- );
979
-
980
- foreach (self::types()->get($post_type)->get_all() as $module) {
981
- $category = $module->get_category();
982
- if (!isset($conditions[$category])) {
983
- $category = 'general';
984
- }
985
-
986
- //array_values used for backwards compatibility
987
- $conditions[$category]['children'] = array_values($module->list_module($conditions[$category]['children']));
988
- }
989
-
990
- foreach ($conditions as $key => $condition) {
991
- if (empty($condition['children'])) {
992
- unset($conditions[$key]);
993
- }
994
- }
995
-
996
- //Make sure to use packaged version
997
- if (wp_script_is('select2', 'registered')) {
998
- wp_deregister_script('select2');
999
- wp_deregister_style('select2');
1000
- }
1001
-
1002
- $plugins_url = plugins_url('', __FILE__);
1003
-
1004
- //Add to head to take priority
1005
- //if being added under other name
1006
- wp_register_script(
1007
- 'select2',
1008
- $plugins_url . '/assets/js/select2.min.js',
1009
- array('jquery'),
1010
- '4.0.3',
1011
- false
1012
- );
1013
-
1014
- wp_register_script(
1015
- 'backbone.trackit',
1016
- $plugins_url . '/assets/js/backbone.trackit.min.js',
1017
- array('backbone'),
1018
- '0.1.0',
1019
- true
1020
- );
1021
-
1022
- wp_register_script(
1023
- 'backbone.epoxy',
1024
- $plugins_url . '/assets/js/backbone.epoxy.min.js',
1025
- array('backbone'),
1026
- '1.3.3',
1027
- true
1028
- );
1029
-
1030
- wp_register_script(
1031
- self::PREFIX.'condition-groups',
1032
- $plugins_url . '/assets/js/condition_groups.min.js',
1033
- array('jquery','select2','backbone.trackit','backbone.epoxy'),
1034
- WPCA_VERSION,
1035
- true
1036
- );
1037
-
1038
- wp_enqueue_script(self::PREFIX.'condition-groups');
1039
- wp_localize_script(self::PREFIX.'condition-groups', 'WPCA', array(
1040
- 'searching' => __('Searching', WPCA_DOMAIN),
1041
- 'noResults' => __('No results found.', WPCA_DOMAIN),
1042
- 'loadingMore' => __('Loading more results', WPCA_DOMAIN),
1043
- 'unsaved' => __('Conditions have unsaved changes. Do you want to continue and discard these changes?', WPCA_DOMAIN),
1044
- 'newGroup' => __('New condition group', WPCA_DOMAIN),
1045
- 'newCondition' => __('Meet ALL of these conditions', WPCA_DOMAIN),
1046
- 'conditions' => array_values($conditions),
1047
- 'groups' => $data,
1048
- 'meta_default' => $group_meta,
1049
- 'post_type' => $post_type,
1050
- 'text_direction' => is_rtl() ? 'rtl' : 'ltr',
1051
- 'condition_not' => __('Not', WPCA_DOMAIN),
1052
- 'condition_or' => __('Or', WPCA_DOMAIN),
1053
- 'condition_except' => __('Except', WPCA_DOMAIN)
1054
- ));
1055
- wp_enqueue_style(self::PREFIX.'condition-groups');
1056
-
1057
- //@todo remove when ultimate member includes fix
1058
- wp_dequeue_style('um_styles');
1059
-
1060
- //@todo remove when events calendar pro plugin includes fix
1061
- wp_dequeue_script('tribe-select2');
1062
- }
1063
-
1064
- /**
1065
- * Modify wp_query for plugin compatibility
1066
- *
1067
- * @since 5.0
1068
- * @return void
1069
- */
1070
- private static function fix_wp_query()
1071
- {
1072
- $query = array();
1073
-
1074
- //When themes don't declare WooCommerce support,
1075
- //conditionals are not working properly for Shop
1076
- if (defined('WOOCOMMERCE_VERSION') && function_exists('is_shop') && is_shop() && !is_post_type_archive('product')) {
1077
- $query = array(
1078
- 'is_archive' => true,
1079
- 'is_post_type_archive' => true,
1080
- 'is_page' => false,
1081
- 'is_singular' => false,
1082
- 'query_vars' => array(
1083
- 'post_type' => 'product'
1084
- )
1085
- );
1086
- }
1087
-
1088
- self::set_wp_query($query);
1089
- }
1090
-
1091
- /**
1092
- * Restore original wp_query
1093
- *
1094
- * @since 5.0
1095
- * @return void
1096
- */
1097
- private static function restore_wp_query()
1098
- {
1099
- self::set_wp_query(self::$wp_query_original);
1100
- self::$wp_query_original = array();
1101
- }
1102
-
1103
- /**
1104
- * Set properties in wp_query and save original value
1105
- *
1106
- * @since 5.0
1107
- * @param array $query
1108
- */
1109
- private static function set_wp_query($query)
1110
- {
1111
- global $wp_query;
1112
- foreach ($query as $key => $val) {
1113
- $is_array = is_array($val);
1114
-
1115
- if (!isset(self::$wp_query_original[$key])) {
1116
- self::$wp_query_original[$key] = $is_array ? array() : $wp_query->$key;
1117
- }
1118
-
1119
- if ($is_array) {
1120
- foreach ($val as $k1 => $v1) {
1121
- if (!isset(self::$wp_query_original[$key][$k1])) {
1122
- self::$wp_query_original[$key][$k1] = $wp_query->{$key}[$k1];
1123
- }
1124
- $wp_query->{$key}[$k1] = $v1;
1125
- }
1126
- } else {
1127
- $wp_query->$key = $val;
1128
- }
1129
- }
1130
- }
1131
-
1132
- /**
1133
- * Autoload class files
1134
- *
1135
- * @since 1.0
1136
- * @param string $class
1137
- * @return void
1138
- */
1139
- private static function _autoload_class_files($class)
1140
- {
1141
- if (strpos($class, self::CLASS_PREFIX) === 0) {
1142
- $class = str_replace(self::CLASS_PREFIX, '', $class);
1143
- $class = self::str_replace_first('_', '/', $class);
1144
- $class = strtolower($class);
1145
- $file = WPCA_PATH . $class . '.php';
1146
- if (file_exists($file)) {
1147
- include($file);
1148
- }
1149
- }
1150
- }
1151
-
1152
- /**
1153
- * Helper function to replace first
1154
- * occurence of substring
1155
- *
1156
- * @since 1.0
1157
- * @param string $search
1158
- * @param string $replace
1159
- * @param string $subject
1160
- * @return string
1161
- */
1162
- private static function str_replace_first($search, $replace, $subject)
1163
- {
1164
- $pos = strpos($subject, $search);
1165
- if ($pos !== false) {
1166
- $subject = substr_replace($subject, $replace, $pos, strlen($search));
1167
- }
1168
- return $subject;
1169
- }
1170
-
1171
- /**
1172
- * @since 8.0
1173
- * @param array $input
1174
- *
1175
- * @return string
1176
- */
1177
- private static function sql_prepare_in($input)
1178
- {
1179
- $output = array_map(function ($value) {
1180
- return "'" . esc_sql($value) . "'";
1181
- }, $input);
1182
- return implode(',', $output);
1183
- }
1184
-
1185
- /**
1186
- * @since 8.0
1187
- * @param string $type
1188
- * @param array $modules
1189
- *
1190
- * @return array
1191
- */
1192
- private static function filter_condition_type_cache($type, $modules)
1193
- {
1194
- $included_conditions = get_option(self::OPTION_CONDITION_TYPE_CACHE, array());
1195
-
1196
- if (!$included_conditions || !isset($included_conditions[$type])) {
1197
- return $modules;
1198
- }
1199
-
1200
- $ignored_modules = array('taxonomy' => 1);
1201
- $included_conditions_lookup = array_flip($included_conditions[$type]);
1202
- $filtered_modules = array();
1203
-
1204
- foreach ($modules as $module) {
1205
- if (isset($ignored_modules[$module->get_id()]) || isset($included_conditions_lookup[$module->get_id()])) {
1206
- $filtered_modules[] = $module;
1207
- }
1208
- }
1209
-
1210
- return $filtered_modules;
1211
- }
1212
-
1213
- /**
1214
- * @param string $post_type
1215
- * @param string $name
1216
- * @param mixed|null $default_value
1217
- *
1218
- * @return mixed|null
1219
- */
1220
- public static function get_option($post_type, $name, $default_value = null)
1221
- {
1222
- if (!self::types()->has($post_type)) {
1223
- return $default_value;
1224
- }
1225
-
1226
- $value = get_option(self::OPTION_POST_TYPE_OPTIONS, array());
1227
- $levels = explode('.', $post_type.'.'.$name);
1228
-
1229
- foreach ($levels as $option_level) {
1230
- if (!is_array($value) || !isset($value[$option_level])) {
1231
- return $default_value;
1232
- }
1233
- $value = $value[$option_level];
1234
- }
1235
- return $value;
1236
- }
1237
-
1238
- /**
1239
- * @param string $post_type
1240
- * @param string $name
1241
- * @param mixed $value
1242
- *
1243
- * @return bool
1244
- */
1245
- public static function save_option($post_type, $name, $value)
1246
- {
1247
- if (!self::types()->has($post_type)) {
1248
- return false;
1249
- }
1250
-
1251
- $options = get_option(self::OPTION_POST_TYPE_OPTIONS, array());
1252
- $keys = explode('.', $post_type.'.'.$name);
1253
- $array = &$options;
1254
-
1255
- foreach ($keys as $key) {
1256
- if (!isset($array[$key]) || !is_array($array[$key])) {
1257
- $array[$key] = array();
1258
- }
1259
- $array = &$array[$key];
1260
- }
1261
- $array = $value;
1262
-
1263
- return update_option(self::OPTION_POST_TYPE_OPTIONS, $options);
1264
- }
1265
- }
1266
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ if (!class_exists('WPCACore')) {
12
+ $domain = explode('/', plugin_basename(__FILE__));
13
+ define('WPCA_DOMAIN', $domain[0]);
14
+ define('WPCA_PATH', plugin_dir_path(__FILE__));
15
+
16
+ /**
17
+ * Core for WordPress Content Aware Engine
18
+ */
19
+ final class WPCACore
20
+ {
21
+
22
+ /**
23
+ * Using class prefix instead of namespace
24
+ * for PHP5.2 compatibility
25
+ */
26
+ const CLASS_PREFIX = 'WPCA';
27
+
28
+ /**
29
+ * Prefix for data (keys) stored in database
30
+ */
31
+ const PREFIX = '_ca_';
32
+
33
+ /**
34
+ * Post Type for condition groups
35
+ */
36
+ const TYPE_CONDITION_GROUP = 'condition_group';
37
+
38
+ /**
39
+ * Post Statuses for condition groups
40
+ */
41
+ /**
42
+ * @deprecated
43
+ */
44
+ const STATUS_NEGATED = 'negated';
45
+ /**
46
+ * @deprecated
47
+ */
48
+ const STATUS_PUBLISHED = 'publish';
49
+ const STATUS_OR = 'wpca_or';
50
+ const STATUS_EXCEPT = 'wpca_except';
51
+
52
+ /**
53
+ * Exposures for condition groups
54
+ */
55
+ const EXP_SINGULAR = 0;
56
+ const EXP_SINGULAR_ARCHIVE = 1;
57
+ const EXP_ARCHIVE = 2;
58
+
59
+ /**
60
+ * @deprecated 7.0
61
+ */
62
+ const CAPABILITY = 'edit_theme_options';
63
+
64
+ /**
65
+ * Name for generated nonces
66
+ */
67
+ const NONCE = '_ca_nonce';
68
+
69
+ const OPTION_CONDITION_TYPE_CACHE = '_ca_condition_type_cache';
70
+ const OPTION_POST_TYPE_OPTIONS = '_ca_post_type_options';
71
+
72
+ /**
73
+ * Post Types that use the engine
74
+ * @var WPCAPostTypeManager
75
+ */
76
+ private static $type_manager;
77
+
78
+ /**
79
+ * Conditions retrieved from database
80
+ * @var array
81
+ */
82
+ private static $condition_cache = [];
83
+
84
+ /**
85
+ * Objects retrieved from database
86
+ * @var array
87
+ */
88
+ private static $post_cache = [];
89
+
90
+ private static $wp_query_original = [];
91
+
92
+ private static $filtered_modules = [];
93
+
94
+ /**
95
+ * Constructor
96
+ */
97
+ public static function init()
98
+ {
99
+ spl_autoload_register([__CLASS__,'_autoload_class_files']);
100
+
101
+ if (is_admin()) {
102
+ add_action(
103
+ 'admin_enqueue_scripts',
104
+ [__CLASS__,'add_group_script_styles'],
105
+ 9
106
+ );
107
+ add_action(
108
+ 'delete_post',
109
+ [__CLASS__,'sync_group_deletion']
110
+ );
111
+ add_action(
112
+ 'trashed_post',
113
+ [__CLASS__,'sync_group_trashed']
114
+ );
115
+ add_action(
116
+ 'untrashed_post',
117
+ [__CLASS__,'sync_group_untrashed']
118
+ );
119
+ add_action(
120
+ 'add_meta_boxes',
121
+ [__CLASS__,'add_group_meta_box'],
122
+ 10,
123
+ 2
124
+ );
125
+ add_action(
126
+ 'wpca/modules/save-data',
127
+ [__CLASS__,'save_condition_options'],
128
+ 10,
129
+ 3
130
+ );
131
+
132
+ add_action(
133
+ 'wp_ajax_wpca/add-rule',
134
+ [__CLASS__,'ajax_update_group']
135
+ );
136
+ }
137
+
138
+ add_action(
139
+ 'init',
140
+ [__CLASS__,'add_group_post_type'],
141
+ 99
142
+ );
143
+
144
+ add_action(
145
+ 'init',
146
+ [__CLASS__,'schedule_cache_condition_types'],
147
+ 99
148
+ );
149
+
150
+ add_action(
151
+ 'wpca/cache_condition_types',
152
+ [__CLASS__,'cache_condition_types'],
153
+ 999
154
+ );
155
+ }
156
+
157
+ /**
158
+ * Get post type manager
159
+ *
160
+ * @deprecated 4.0
161
+ * @since 1.0
162
+ * @return WPCAPostTypeManager
163
+ */
164
+ public static function post_types()
165
+ {
166
+ return self::types();
167
+ }
168
+
169
+ /**
170
+ * Get type manager
171
+ *
172
+ * @since 4.0
173
+ * @return WPCAPostTypeManager
174
+ */
175
+ public static function types()
176
+ {
177
+ if (!isset(self::$type_manager)) {
178
+ self::$type_manager = new WPCATypeManager();
179
+ }
180
+ return self::$type_manager;
181
+ }
182
+
183
+ /**
184
+ * @since 8.0
185
+ *
186
+ * @return void
187
+ */
188
+ public static function schedule_cache_condition_types()
189
+ {
190
+ if (wp_next_scheduled('wpca/cache_condition_types') !== false) {
191
+ return;
192
+ }
193
+
194
+ wp_schedule_event(get_gmt_from_date('today 02:00:00', 'U'), 'daily', 'wpca/cache_condition_types');
195
+ }
196
+
197
+ /**
198
+ * Cache condition types currently in use
199
+ *
200
+ * @since 8.0
201
+ *
202
+ * @return void
203
+ */
204
+ public static function cache_condition_types()
205
+ {
206
+ $all_modules = [];
207
+ $modules_by_type = [];
208
+ $ignored_modules = ['taxonomy' => 1];
209
+ $cache = [];
210
+
211
+ $types = self::types();
212
+ foreach ($types as $type => $modules) {
213
+ $modules_by_type[$type] = [];
214
+ $cache[$type] = [];
215
+ foreach ($modules as $module) {
216
+ if (isset($ignored_modules[$module->get_id()])) {
217
+ continue;
218
+ }
219
+
220
+ $modules_by_type[$type][$module->get_data_key()] = $module->get_id();
221
+ $all_modules[$module->get_data_key()] = $module->get_data_key();
222
+ }
223
+ }
224
+
225
+ if (!$all_modules) {
226
+ update_option(self::OPTION_CONDITION_TYPE_CACHE, []);
227
+ return;
228
+ }
229
+
230
+ global $wpdb;
231
+
232
  $query = '
233
  SELECT p.post_type, m.meta_key
234
  FROM '.$wpdb->posts.' p
237
  WHERE p.post_type IN ('.self::sql_prepare_in(array_keys($modules_by_type)).')
238
  AND m.meta_key IN ('.self::sql_prepare_in($all_modules).')
239
  GROUP BY p.post_type, m.meta_key
240
+ ';
241
+
242
+ $results = (array) $wpdb->get_results($query);
243
+
244
+ foreach ($results as $result) {
245
+ if (isset($modules_by_type[$result->post_type][$result->meta_key])) {
246
+ $cache[$result->post_type][] = $modules_by_type[$result->post_type][$result->meta_key];
247
+ }
248
+ }
249
+
250
+ update_option(self::OPTION_CONDITION_TYPE_CACHE, $cache);
251
+ }
252
+
253
+ /**
254
+ * Register group post type
255
+ *
256
+ * @since 1.0
257
+ * @return void
258
+ */
259
+ public static function add_group_post_type()
260
+ {
261
+ //This is just a safety placeholder,
262
+ //authorization will be done with parent object's cap
263
+ $capability = 'edit_theme_options';
264
+ $capabilities = [
265
+ 'edit_post' => $capability,
266
+ 'read_post' => $capability,
267
+ 'delete_post' => $capability,
268
+ 'edit_posts' => $capability,
269
+ 'delete_posts' => $capability,
270
+ 'edit_others_posts' => $capability,
271
+ 'publish_posts' => $capability,
272
+ 'read_private_posts' => $capability
273
+ ];
274
+
275
+ register_post_type(self::TYPE_CONDITION_GROUP, [
276
+ 'labels' => [
277
+ 'name' => __('Condition Groups', WPCA_DOMAIN),
278
+ 'singular_name' => __('Condition Group', WPCA_DOMAIN),
279
+ ],
280
+ 'capabilities' => $capabilities,
281
+ 'public' => false,
282
+ 'hierarchical' => false,
283
+ 'exclude_from_search' => true,
284
+ 'publicly_queryable' => false,
285
+ 'show_ui' => false,
286
+ 'show_in_menu' => false,
287
+ 'show_in_nav_menus' => false,
288
+ 'show_in_admin_bar' => false,
289
+ 'show_in_rest' => false,
290
+ 'has_archive' => false,
291
+ 'rewrite' => false,
292
+ 'query_var' => false,
293
+ 'supports' => ['title'],
294
+ 'can_export' => false,
295
+ 'delete_with_user' => false
296
+ ]);
297
+
298
+ register_post_status(self::STATUS_NEGATED, [
299
+ 'label' => _x('Negated', 'condition status', WPCA_DOMAIN),
300
+ 'public' => false,
301
+ 'exclude_from_search' => true,
302
+ 'show_in_admin_all_list' => false,
303
+ 'show_in_admin_status_list' => false,
304
+ ]);
305
+ register_post_status(self::STATUS_EXCEPT, [
306
+ 'label' => _x('Exception', 'condition status', WPCA_DOMAIN),
307
+ 'public' => false,
308
+ 'exclude_from_search' => true,
309
+ 'show_in_admin_all_list' => false,
310
+ 'show_in_admin_status_list' => false,
311
+ ]);
312
+ register_post_status(self::STATUS_OR, [
313
+ 'label' => _x('Or', 'condition status', WPCA_DOMAIN),
314
+ 'public' => false,
315
+ 'exclude_from_search' => true,
316
+ 'show_in_admin_all_list' => false,
317
+ 'show_in_admin_status_list' => false,
318
+ ]);
319
+ }
320
+
321
+ /**
322
+ * Get group IDs by their parent ID
323
+ *
324
+ * @since 1.0
325
+ * @param int $parent_id
326
+ * @return array
327
+ */
328
+ private static function get_group_ids_by_parent($parent_id)
329
+ {
330
+ if (!self::types()->has(get_post_type($parent_id))) {
331
+ return [];
332
+ }
333
+
334
+ global $wpdb;
335
+ return (array)$wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_parent = '%d'", $parent_id));
336
+ }
337
+
338
+ /**
339
+ * Delete groups from database when their parent is deleted
340
+ *
341
+ * @since 1.0
342
+ * @param int $post_id
343
+ * @return void
344
+ */
345
+ public static function sync_group_deletion($post_id)
346
+ {
347
+ $groups = self::get_group_ids_by_parent($post_id);
348
+ if ($groups) {
349
+ foreach ($groups as $group_id) {
350
+ //Takes care of metadata and terms too
351
+ wp_delete_post($group_id, true);
352
+ }
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Trash groups when their parent is trashed
358
+ *
359
+ * @since 1.0
360
+ * @param int $post_id
361
+ * @return void
362
+ */
363
+ public static function sync_group_trashed($post_id)
364
+ {
365
+ $groups = self::get_group_ids_by_parent($post_id);
366
+ if ($groups) {
367
+ foreach ($groups as $group_id) {
368
+ wp_trash_post($group_id);
369
+ }
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Untrash groups when their parent is untrashed
375
+ *
376
+ * @since 1.0
377
+ * @param int $post_id
378
+ * @return void
379
+ */
380
+ public static function sync_group_untrashed($post_id)
381
+ {
382
+ $groups = self::get_group_ids_by_parent($post_id);
383
+ if ($groups) {
384
+ foreach ($groups as $group_id) {
385
+ wp_untrash_post($group_id);
386
+ }
387
+ }
388
+ }
389
+
390
+ /**
391
+ * @param string $post_type
392
+ * @return array
393
+ */
394
+ public static function get_conditional_modules($post_type)
395
+ {
396
+ if (!isset(self::$filtered_modules[$post_type])) {
397
+ return [];
398
+ }
399
+ return self::$filtered_modules[$post_type];
400
+ }
401
+
402
+ /**
403
+ * Get filtered condition groups
404
+ *
405
+ * @since 2.0
406
+ * @return array
407
+ */
408
+ public static function get_conditions($post_type)
409
+ {
410
+ global $wpdb, $wp_query, $post;
411
+
412
+ if ((!$wp_query->query && !$post) || is_admin()) {
413
+ return [];
414
+ }
415
+
416
+ // Return cache if present
417
+ if (isset(self::$condition_cache[$post_type])) {
418
+ return self::$condition_cache[$post_type];
419
+ }
420
+
421
+ $excluded = [];
422
+ $where = [];
423
+ $join = [];
424
+
425
+ $cache = [
426
+ $post_type
427
+ ];
428
+
429
+ $modules = self::types()->get($post_type)->get_all();
430
+ $modules = self::filter_condition_type_cache($post_type, $modules);
431
+
432
+ //avoid combining as long as negated conditions are being deprecated
433
+ // foreach (self::types() as $other_type => $other_modules) {
434
+ // if ($other_type == $post_type) {
435
+ // continue;
436
+ // }
437
+ // if (self::filter_condition_type_cache($other_type, $other_modules->get_all()) === $modules) {
438
+ // $cache[] = $other_type;
439
+ // }
440
+ // }
441
+
442
+ self::fix_wp_query();
443
+
444
+ foreach ($modules as $module) {
445
+ $id = $module->get_id();
446
+ $name = $module->get_query_name();
447
+ if (apply_filters("wpca/module/$id/in-context", $module->in_context())) {
448
+ $join[$id] = apply_filters("wpca/module/$id/db-join", $module->db_join());
449
+ $data = $module->get_context_data();
450
+ if (is_array($data)) {
451
+ $data = "($name.meta_value IS NULL OR $name.meta_value IN ('".implode("','", $data) ."'))";
452
+ }
453
+ $where[$id] = apply_filters("wpca/module/$id/db-where", $data);
454
+ self::$filtered_modules[$post_type][] = $module;
455
+ } else {
456
+ $excluded[] = $module;
457
+ }
458
+ }
459
+
460
+ $use_negated_conditions = self::get_option($post_type, 'legacy.negated_conditions', false);
461
+
462
+ // Check if there are any conditions for current content
463
+ $groups_in_context = [];
464
+ if (!empty($where)) {
465
+ $post_status = [
466
+ self::STATUS_PUBLISHED,
467
+ self::STATUS_OR,
468
+ self::STATUS_EXCEPT
469
+ ];
470
+
471
+ if ($use_negated_conditions) {
472
+ $post_status[] = self::STATUS_NEGATED;
473
+ }
474
+
475
+ if (defined('CAS_SQL_CHUNK_SIZE') && CAS_SQL_CHUNK_SIZE > 0) {
476
+ $chunk_size = CAS_SQL_CHUNK_SIZE;
477
+ } else {
478
+ //Syntax changed in MySQL 5.5 and MariaDB 10.0 (reports as version 5.5)
479
+ $wpdb->query('SET'.(version_compare($wpdb->db_version(), '5.5', '>=') ? ' SESSION' : ' OPTION').' SQL_BIG_SELECTS = 1');
480
+ $chunk_size = count($join);
481
+ }
482
+
483
+ $joins = array_chunk($join, $chunk_size);
484
+ $joins_max = count($joins) - 1;
485
+ $wheres = array_chunk($where, $chunk_size);
486
+ $group_ids = [];
487
+ $groups_in_context = [];
488
+
489
+ $where2 = [];
490
+ $where2[] = "p.post_type = '".self::TYPE_CONDITION_GROUP."'";
491
+ $where2[] = "p.post_status IN ('".implode("','", $post_status)."')";
492
+ //exposure
493
+ $where2[] = 'p.menu_order '.(is_archive() || is_home() ? '>=' : '<=').' 1';
494
+
495
+ foreach ($joins as $i => $join) {
496
+ if ($i == $joins_max) {
497
+ $groups_in_context = $wpdb->get_results(
498
+ 'SELECT p.ID, p.post_parent, p.post_status '.
499
+ "FROM $wpdb->posts p ".
500
  implode(' ', $join).'
501
  WHERE
502
  '.implode(' AND ', $wheres[$i]).'
503
+ AND '.implode(' AND ', $where2).
504
+ (!empty($group_ids) ? ' AND p.id IN ('.implode(',', $group_ids).')' : ''),
505
+ OBJECT_K
506
+ );
507
+ break;
508
+ }
509
+
510
+ $group_ids = array_merge($group_ids, $wpdb->get_col(
511
+ 'SELECT p.ID '.
512
+ "FROM $wpdb->posts p ".
513
  implode(' ', $join).'
514
  WHERE
515
  '.implode(' AND ', $wheres[$i]).'
516
+ AND '.implode(' AND ', $where2)
517
+ ));
518
+ }
519
+ }
520
+
521
+ $groups_negated = [];
522
+ if ($use_negated_conditions) {
523
+ $groups_negated = $wpdb->get_results($wpdb->prepare(
524
+ 'SELECT p.ID, p.post_parent '.
525
+ "FROM $wpdb->posts p ".
526
+ "WHERE p.post_type = '%s' ".
527
+ "AND p.post_status = '%s' ",
528
+ self::TYPE_CONDITION_GROUP,
529
+ self::STATUS_NEGATED
530
+ ), OBJECT_K);
531
+ }
532
+
533
+ if (!empty($groups_in_context) || !empty($groups_negated)) {
534
+ //Force update of meta cache to prevent lazy loading
535
+ update_meta_cache('post', array_keys($groups_in_context + $groups_negated));
536
+ }
537
+
538
+ //condition group => type
539
+ $valid = [];
540
+ foreach ($groups_in_context as $group) {
541
+ $valid[$group->ID] = $group->post_parent;
542
+ }
543
+
544
+ //Exclude types that have unrelated content in same group
545
+ foreach ($excluded as $module) {
546
+ $valid = $module->filter_excluded_context($valid);
547
+ }
548
+
549
+ //exclude exceptions
550
+ $excepted = [];
551
+ foreach ($valid as $group_id => $parent_id) {
552
+ //sanity
553
+ if (!isset($groups_in_context[$group_id])) {
554
+ continue;
555
+ }
556
+
557
+ if ($groups_in_context[$group_id]->post_status == self::STATUS_EXCEPT) {
558
+ $excepted[$parent_id] = 1;
559
+ }
560
+ }
561
+
562
+ foreach ($valid as $group_id => $parent_id) {
563
+ if (isset($excepted[$parent_id])) {
564
+ unset($valid[$group_id]);
565
+ }
566
+ }
567
+
568
+ if ($use_negated_conditions) {
569
+ //Filter negated groups
570
+ //type => group
571
+ $handled_already = array_flip($valid);
572
+ foreach ($groups_negated as $group) {
573
+ if (isset($valid[$group->ID])) {
574
+ unset($valid[$group->ID]);
575
+ } else {
576
+ $valid[$group->ID] = $group->post_parent;
577
+ }
578
+ if (isset($handled_already[$group->post_parent])) {
579
+ unset($valid[$group->ID]);
580
+ }
581
+ $handled_already[$group->post_parent] = 1;
582
+ }
583
+ }
584
+
585
+ self::restore_wp_query();
586
+
587
+ foreach ($cache as $cache_type) {
588
+ self::$condition_cache[$cache_type] = $valid;
589
+ }
590
+
591
+ return self::$condition_cache[$post_type];
592
+ }
593
+
594
+ /**
595
+ * Get filtered posts from a post type
596
+ *
597
+ * @since 1.0
598
+ * @global type $wpdb
599
+ * @global WP_Query $wp_query
600
+ * @global WP_Post $post
601
+ * @return array
602
+ */
603
+ public static function get_posts($post_type)
604
+ {
605
+ global $wp_query, $post;
606
+
607
+ // Return cache if present
608
+ if (isset(self::$post_cache[$post_type])) {
609
+ return self::$post_cache[$post_type];
610
+ }
611
+
612
+ if (!self::types()->has($post_type) || (!$wp_query->query && !$post) || is_admin()) {
613
+ return false;
614
+ }
615
+
616
+ $valid = self::get_conditions($post_type);
617
+
618
+ self::$post_cache[$post_type] = [];
619
+
620
+ $results = [];
621
+
622
+ if (!empty($valid)) {
623
+ $data = new WP_Query([
624
+ 'post__in' => array_values($valid),
625
+ 'post_type' => $post_type,
626
+ 'post_status' => 'publish',
627
+ 'posts_per_page' => -1,
628
+ 'ignore_sticky_posts' => true,
629
+ 'update_post_term_cache' => false,
630
+ 'update_post_meta_cache' => true,
631
+ 'suppress_filters' => true,
632
+ 'no_found_rows' => true,
633
+ 'orderby' => 'none'
634
+ ]);
635
+
636
+ $results = array_merge($results, $data->posts);
637
+ }
638
+
639
+ //legacy sorting
640
+ uasort($results, function (WP_Post $post_a, WP_Post $post_b) {
641
+ //asc
642
+ if ($post_a->menu_order != $post_b->menu_order) {
643
+ return $post_a->menu_order < $post_b->menu_order ? -1 : 1;
644
+ }
645
+
646
+ $post_a_handle = get_post_meta($post_a->ID, '_ca_handle', true);
647
+ $post_b_handle = get_post_meta($post_b->ID, '_ca_handle', true);
648
+
649
+ //desc
650
+ if ($post_a_handle != $post_b_handle) {
651
+ return $post_a_handle > $post_b_handle ? -1 : 1;
652
+ }
653
+
654
+ //desc
655
+ if ($post_a->post_date != $post_b->post_date) {
656
+ return $post_a->post_date > $post_b->post_date ? -1 : 1;
657
+ }
658
+
659
+ return 0;
660
+ });
661
+
662
+ $results = array_reduce($results, function ($carry, $post) {
663
+ $carry[$post->ID] = (object)[
664
+ 'ID' => $post->ID,
665
+ 'post_type' => $post->post_type,
666
+ 'handle' => get_post_meta($post->ID, '_ca_handle', true),
667
+ 'menu_order' => $post->menu_order,
668
+ 'post_date' => $post->post_date
669
+ ];
670
+ return $carry;
671
+ }, []);
672
+
673
+ self::$post_cache[$post_type] = apply_filters("wpca/posts/{$post_type}", $results);
674
+
675
+ return self::$post_cache[$post_type];
676
+ }
677
+
678
+ /**
679
+ * Add meta box to manage condition groups
680
+ *
681
+ * @since 1.0
682
+ * @param string $post_type
683
+ * @param WP_Post $post
684
+ */
685
+ public static function add_group_meta_box($post_type, $post)
686
+ {
687
+ if (is_null($post)) {
688
+ return;
689
+ }
690
+ self::render_group_meta_box($post, $post_type, 'normal', 'default');
691
+ }
692
+
693
+ public static function render_group_meta_box($post, $screen, $context = 'normal', $priority = 'default')
694
+ {
695
+ if (is_null($post) || !self::types()->has($post->post_type)) {
696
+ return;
697
+ }
698
+
699
+ $post_type_obj = get_post_type_object($post->post_type);
700
+
701
+ if (!current_user_can($post_type_obj->cap->edit_post, $post->ID)) {
702
+ return;
703
+ }
704
+
705
+ $template = WPCAView::make('condition_options', [
706
+ 'post_type' => $post->post_type
707
+ ]);
708
+ add_action('wpca/group/settings', [$template,'render'], -1, 2);
709
+
710
+ $template = WPCAView::make('group_template', [
711
+ 'post_type' => $post->post_type
712
+ ]);
713
+ add_action('admin_footer', [$template,'render']);
714
+
715
+ $template = WPCAView::make('condition_template');
716
+ add_action('admin_footer', [$template,'render']);
717
+
718
+ $view = WPCAView::make('meta_box', [
719
+ 'post_type' => $post->post_type,
720
+ 'nonce' => wp_nonce_field(self::PREFIX.$post->ID, self::NONCE, true, false),
721
+ ]);
722
+
723
+ $title = isset($post_type_obj->labels->ca_title) ? $post_type_obj->labels->ca_title : __('Conditional Logic', WPCA_DOMAIN);
724
+
725
+ add_meta_box(
726
+ 'cas-rules',
727
+ $title,
728
+ [$view,'render'],
729
+ $screen,
730
+ $context,
731
+ $priority
732
+ );
733
+ }
734
+
735
+ /**
736
+ * Insert new condition group for a post type
737
+ * Uses current post per default
738
+ *
739
+ * @since 1.0
740
+ * @param WP_Post|int $post
741
+ * @return int
742
+ */
743
+ public static function add_condition_group($post_id = null)
744
+ {
745
+ $post = get_post($post_id);
746
+
747
+ //Make sure to go from auto-draft to draft
748
+ if ($post->post_status == 'auto-draft') {
749
+ wp_update_post([
750
+ 'ID' => $post->ID,
751
+ 'post_title' => '',
752
+ 'post_status' => 'draft'
753
+ ]);
754
+ }
755
+
756
+ return wp_insert_post([
757
+ 'post_status' => self::STATUS_OR,
758
+ 'menu_order' => self::EXP_SINGULAR_ARCHIVE,
759
+ 'post_type' => self::TYPE_CONDITION_GROUP,
760
+ 'post_author' => $post->post_author,
761
+ 'post_parent' => $post->ID,
762
+ ]);
763
+ }
764
+
765
+ /**
766
+ * Get condition groups for a post type
767
+ * Uses current post per default
768
+ *
769
+ * @since 1.0
770
+ * @param WP_Post|int $post_id
771
+ * @return array
772
+ */
773
+ private static function get_condition_groups($post_id = null)
774
+ {
775
+ $post = get_post($post_id);
776
+ $groups = [];
777
+
778
+ if ($post) {
779
+ $groups = get_posts([
780
+ 'posts_per_page' => -1,
781
+ 'post_type' => self::TYPE_CONDITION_GROUP,
782
+ 'post_parent' => $post->ID,
783
+ 'post_status' => [self::STATUS_PUBLISHED,self::STATUS_NEGATED,self::STATUS_EXCEPT, self::STATUS_OR],
784
+ 'order' => 'ASC',
785
+ 'orderby' => 'post_status'
786
+ ]);
787
+ }
788
+ return $groups;
789
+ }
790
+
791
+ /**
792
+ * AJAX callback to update a condition group
793
+ *
794
+ * @since 1.0
795
+ * @return void
796
+ */
797
+ public static function ajax_update_group()
798
+ {
799
+ if (!isset($_POST['current_id']) ||
800
+ !check_ajax_referer(self::PREFIX.$_POST['current_id'], 'token', false)) {
801
+ wp_send_json_error(__('Unauthorized request', WPCA_DOMAIN), 403);
802
+ }
803
+
804
+ $parent_id = (int)$_POST['current_id'];
805
+ $parent_type = get_post_type_object($_POST['post_type']);
806
+
807
+ if (! current_user_can($parent_type->cap->edit_post, $parent_id)) {
808
+ wp_send_json_error(__('Unauthorized request', WPCA_DOMAIN), 403);
809
+ }
810
+
811
+ $response = [
812
+ 'message' => __('Conditions updated', WPCA_DOMAIN)
813
+ ];
814
+
815
+ //Make sure some rules are sent
816
+ if (!isset($_POST['conditions'])) {
817
+ //Otherwise we delete group
818
+ if ($_POST['id'] && wp_delete_post(intval($_POST['id']), true) === false) {
819
+ wp_send_json_error(__('Could not delete conditions', WPCA_DOMAIN), 500);
820
+ }
821
+
822
+ $response['removed'] = true;
823
+ wp_send_json($response);
824
+ }
825
+
826
+ //If ID was not sent at this point, it is a new group
827
+ if (!$_POST['id']) {
828
+ $post_id = self::add_condition_group($parent_id);
829
+ $response['new_post_id'] = $post_id;
830
+ } else {
831
+ $post_id = (int)$_POST['id'];
832
+ }
833
+
834
+ wp_update_post([
835
+ 'ID' => $post_id,
836
+ 'post_status' => self::sanitize_status($_POST['status']),
837
+ 'menu_order' => (int)$_POST['exposure']
838
+ ]);
839
+
840
+ //Prune condition type cache, will rebuild within 24h
841
+ update_option(self::OPTION_CONDITION_TYPE_CACHE, []);
842
+
843
+ foreach (self::types()->get($parent_type->name)->get_all() as $module) {
844
+ //send $_POST here
845
+ $module->save_data($post_id);
846
+ }
847
+
848
+ do_action('wpca/modules/save-data', $post_id, $parent_type->name);
849
+
850
+ wp_send_json($response);
851
+ }
852
+
853
+ /**
854
+ * @param string $status
855
+ *
856
+ * @return string
857
+ */
858
+ private static function sanitize_status($status)
859
+ {
860
+ switch ($status) {
861
+ case self::STATUS_NEGATED:
862
+ return self::STATUS_NEGATED;
863
+ case self::STATUS_EXCEPT:
864
+ return self::STATUS_EXCEPT;
865
+ case self::STATUS_OR:
866
+ case self::STATUS_PUBLISHED:
867
+ default:
868
+ return self::STATUS_OR;
869
+ }
870
+ }
871
+
872
+ /**
873
+ * Save registered meta for condition group
874
+ *
875
+ * @since 3.2
876
+ * @param int $group_id
877
+ * @return void
878
+ */
879
+ public static function save_condition_options($group_id, $post_type)
880
+ {
881
+ $meta_keys = self::get_condition_meta_keys($post_type);
882
+ foreach ($meta_keys as $key => $default_value) {
883
+ $value = isset($_POST[$key]) ? $_POST[$key] : false;
884
+ if ($value) {
885
+ update_post_meta($group_id, $key, $value);
886
+ } elseif (get_post_meta($group_id, $key, true)) {
887
+ delete_post_meta($group_id, $key);
888
+ }
889
+ }
890
+ }
891
+
892
+ public static function add_group_script_styles($hook)
893
+ {
894
+ $current_screen = get_current_screen();
895
+
896
+ wp_register_style(
897
+ self::PREFIX.'condition-groups',
898
+ plugins_url('/assets/css/condition_groups.css', __FILE__),
899
+ [],
900
+ WPCA_VERSION
901
+ );
902
+
903
+ if (self::types()->has($current_screen->post_type) && $current_screen->base == 'post') {
904
+ self::enqueue_scripts_styles($current_screen->post_type);
905
+ }
906
+ }
907
+
908
+ /**
909
+ * Get condition option defaults
910
+ *
911
+ * @since 3.2
912
+ * @param string $post_type
913
+ * @return array
914
+ */
915
+ public static function get_condition_meta_keys($post_type)
916
+ {
917
+ $group_meta = [
918
+ '_ca_autoselect' => 0
919
+ ];
920
+ return apply_filters('wpca/condition/meta', $group_meta, $post_type);
921
+ }
922
+
923
+ /**
924
+ * Register and enqueue scripts and styles
925
+ * for post edit screen
926
+ *
927
+ * @since 1.0
928
+ * @param string $hook
929
+ * @return void
930
+ */
931
+ public static function enqueue_scripts_styles($post_type = '')
932
+ {
933
+ $post_type = empty($post_type) ? get_post_type() : $post_type;
934
+
935
+ $group_meta = self::get_condition_meta_keys($post_type);
936
+
937
+ $groups = self::get_condition_groups();
938
+ $data = [];
939
+ $i = 0;
940
+ foreach ($groups as $group) {
941
+ $data[$i] = [
942
+ 'id' => $group->ID,
943
+ 'status' => $group->post_status,
944
+ 'exposure' => $group->menu_order,
945
+ 'conditions' => []
946
+ ];
947
+
948
+ foreach (self::types()->get($post_type)->get_all() as $module) {
949
+ $data[$i]['conditions'] = $module->get_group_data($data[$i]['conditions'], $group->ID);
950
+ }
951
+
952
+ foreach ($group_meta as $meta_key => $default_value) {
953
+ $value = get_post_meta($group->ID, $meta_key, true);
954
+ if ($value === false) {
955
+ $value = $default_value;
956
+ }
957
+ $data[$i][$meta_key] = $value;
958
+ }
959
+ $i++;
960
+ }
961
+
962
+ $conditions = [
963
+ 'general' => [
964
+ 'text' => __('General'),
965
+ 'children' => []
966
+ ],
967
+ 'post_type' => [
968
+ 'text' => __('Post Types'),
969
+ 'children' => []
970
+ ],
971
+ 'taxonomy' => [
972
+ 'text' => __('Taxonomies'),
973
+ 'children' => []
974
+ ],
975
+ 'plugins' => [
976
+ 'text' => __('Plugins'),
977
+ 'children' => []
978
+ ]
979
+ ];
980
+
981
+ foreach (self::types()->get($post_type)->get_all() as $module) {
982
+ $category = $module->get_category();
983
+ if (!isset($conditions[$category])) {
984
+ $category = 'general';
985
+ }
986
+
987
+ //array_values used for backwards compatibility
988
+ $conditions[$category]['children'] = array_values($module->list_module($conditions[$category]['children']));
989
+ }
990
+
991
+ foreach ($conditions as $key => $condition) {
992
+ if (empty($condition['children'])) {
993
+ unset($conditions[$key]);
994
+ }
995
+ }
996
+
997
+ //Make sure to use packaged version
998
+ if (wp_script_is('select2', 'registered')) {
999
+ wp_deregister_script('select2');
1000
+ wp_deregister_style('select2');
1001
+ }
1002
+
1003
+ $plugins_url = plugins_url('', __FILE__);
1004
+
1005
+ //Add to head to take priority
1006
+ //if being added under other name
1007
+ wp_register_script(
1008
+ 'select2',
1009
+ $plugins_url . '/assets/js/select2.min.js',
1010
+ ['jquery'],
1011
+ '4.0.3',
1012
+ false
1013
+ );
1014
+
1015
+ wp_register_script(
1016
+ 'backbone.trackit',
1017
+ $plugins_url . '/assets/js/backbone.trackit.min.js',
1018
+ ['backbone'],
1019
+ '0.1.0',
1020
+ true
1021
+ );
1022
+
1023
+ wp_register_script(
1024
+ 'backbone.epoxy',
1025
+ $plugins_url . '/assets/js/backbone.epoxy.min.js',
1026
+ ['backbone'],
1027
+ '1.3.3',
1028
+ true
1029
+ );
1030
+
1031
+ wp_register_script(
1032
+ self::PREFIX.'condition-groups',
1033
+ $plugins_url . '/assets/js/condition_groups.min.js',
1034
+ ['jquery','select2','backbone.trackit','backbone.epoxy'],
1035
+ WPCA_VERSION,
1036
+ true
1037
+ );
1038
+
1039
+ wp_enqueue_script(self::PREFIX.'condition-groups');
1040
+ wp_localize_script(self::PREFIX.'condition-groups', 'WPCA', [
1041
+ 'searching' => __('Searching', WPCA_DOMAIN),
1042
+ 'noResults' => __('No results found.', WPCA_DOMAIN),
1043
+ 'loadingMore' => __('Loading more results', WPCA_DOMAIN),
1044
+ 'unsaved' => __('Conditions have unsaved changes. Do you want to continue and discard these changes?', WPCA_DOMAIN),
1045
+ 'newGroup' => __('New condition group', WPCA_DOMAIN),
1046
+ 'newCondition' => __('Meet ALL of these conditions', WPCA_DOMAIN),
1047
+ 'conditions' => array_values($conditions),
1048
+ 'groups' => $data,
1049
+ 'meta_default' => $group_meta,
1050
+ 'post_type' => $post_type,
1051
+ 'text_direction' => is_rtl() ? 'rtl' : 'ltr',
1052
+ 'condition_not' => __('Not', WPCA_DOMAIN),
1053
+ 'condition_or' => __('Or', WPCA_DOMAIN),
1054
+ 'condition_except' => __('Except', WPCA_DOMAIN)
1055
+ ]);
1056
+ wp_enqueue_style(self::PREFIX.'condition-groups');
1057
+
1058
+ //@todo remove when ultimate member includes fix
1059
+ wp_dequeue_style('um_styles');
1060
+
1061
+ //@todo remove when events calendar pro plugin includes fix
1062
+ wp_dequeue_script('tribe-select2');
1063
+ }
1064
+
1065
+ /**
1066
+ * Modify wp_query for plugin compatibility
1067
+ *
1068
+ * @since 5.0
1069
+ * @return void
1070
+ */
1071
+ private static function fix_wp_query()
1072
+ {
1073
+ $query = [];
1074
+
1075
+ //When themes don't declare WooCommerce support,
1076
+ //conditionals are not working properly for Shop
1077
+ if (defined('WOOCOMMERCE_VERSION') && function_exists('is_shop') && is_shop() && !is_post_type_archive('product')) {
1078
+ $query = [
1079
+ 'is_archive' => true,
1080
+ 'is_post_type_archive' => true,
1081
+ 'is_page' => false,
1082
+ 'is_singular' => false,
1083
+ 'query_vars' => [
1084
+ 'post_type' => 'product'
1085
+ ]
1086
+ ];
1087
+ }
1088
+
1089
+ self::set_wp_query($query);
1090
+ }
1091
+
1092
+ /**
1093
+ * Restore original wp_query
1094
+ *
1095
+ * @since 5.0
1096
+ * @return void
1097
+ */
1098
+ private static function restore_wp_query()
1099
+ {
1100
+ self::set_wp_query(self::$wp_query_original);
1101
+ self::$wp_query_original = [];
1102
+ }
1103
+
1104
+ /**
1105
+ * Set properties in wp_query and save original value
1106
+ *
1107
+ * @since 5.0
1108
+ * @param array $query
1109
+ */
1110
+ private static function set_wp_query($query)
1111
+ {
1112
+ global $wp_query;
1113
+ foreach ($query as $key => $val) {
1114
+ $is_array = is_array($val);
1115
+
1116
+ if (!isset(self::$wp_query_original[$key])) {
1117
+ self::$wp_query_original[$key] = $is_array ? [] : $wp_query->$key;
1118
+ }
1119
+
1120
+ if ($is_array) {
1121
+ foreach ($val as $k1 => $v1) {
1122
+ if (!isset(self::$wp_query_original[$key][$k1])) {
1123
+ self::$wp_query_original[$key][$k1] = $wp_query->{$key}[$k1];
1124
+ }
1125
+ $wp_query->{$key}[$k1] = $v1;
1126
+ }
1127
+ } else {
1128
+ $wp_query->$key = $val;
1129
+ }
1130
+ }
1131
+ }
1132
+
1133
+ /**
1134
+ * Autoload class files
1135
+ *
1136
+ * @since 1.0
1137
+ * @param string $class
1138
+ * @return void
1139
+ */
1140
+ private static function _autoload_class_files($class)
1141
+ {
1142
+ if (strpos($class, self::CLASS_PREFIX) === 0) {
1143
+ $class = str_replace(self::CLASS_PREFIX, '', $class);
1144
+ $class = self::str_replace_first('_', '/', $class);
1145
+ $class = strtolower($class);
1146
+ $file = WPCA_PATH . $class . '.php';
1147
+ if (file_exists($file)) {
1148
+ include($file);
1149
+ }
1150
+ }
1151
+ }
1152
+
1153
+ /**
1154
+ * Helper function to replace first
1155
+ * occurence of substring
1156
+ *
1157
+ * @since 1.0
1158
+ * @param string $search
1159
+ * @param string $replace
1160
+ * @param string $subject
1161
+ * @return string
1162
+ */
1163
+ private static function str_replace_first($search, $replace, $subject)
1164
+ {
1165
+ $pos = strpos($subject, $search);
1166
+ if ($pos !== false) {
1167
+ $subject = substr_replace($subject, $replace, $pos, strlen($search));
1168
+ }
1169
+ return $subject;
1170
+ }
1171
+
1172
+ /**
1173
+ * @since 8.0
1174
+ * @param array $input
1175
+ *
1176
+ * @return string
1177
+ */
1178
+ private static function sql_prepare_in($input)
1179
+ {
1180
+ $output = array_map(function ($value) {
1181
+ return "'" . esc_sql($value) . "'";
1182
+ }, $input);
1183
+ return implode(',', $output);
1184
+ }
1185
+
1186
+ /**
1187
+ * @since 8.0
1188
+ * @param string $type
1189
+ * @param array $modules
1190
+ *
1191
+ * @return array
1192
+ */
1193
+ private static function filter_condition_type_cache($type, $modules)
1194
+ {
1195
+ $included_conditions = get_option(self::OPTION_CONDITION_TYPE_CACHE, []);
1196
+
1197
+ if (!$included_conditions || !isset($included_conditions[$type])) {
1198
+ return $modules;
1199
+ }
1200
+
1201
+ $ignored_modules = ['taxonomy' => 1];
1202
+ $included_conditions_lookup = array_flip($included_conditions[$type]);
1203
+ $filtered_modules = [];
1204
+
1205
+ foreach ($modules as $module) {
1206
+ if (isset($ignored_modules[$module->get_id()]) || isset($included_conditions_lookup[$module->get_id()])) {
1207
+ $filtered_modules[] = $module;
1208
+ }
1209
+ }
1210
+
1211
+ return $filtered_modules;
1212
+ }
1213
+
1214
+ /**
1215
+ * @param string $post_type
1216
+ * @param string $name
1217
+ * @param mixed|null $default_value
1218
+ *
1219
+ * @return mixed|null
1220
+ */
1221
+ public static function get_option($post_type, $name, $default_value = null)
1222
+ {
1223
+ if (!self::types()->has($post_type)) {
1224
+ return $default_value;
1225
+ }
1226
+
1227
+ $value = get_option(self::OPTION_POST_TYPE_OPTIONS, []);
1228
+ $levels = explode('.', $post_type.'.'.$name);
1229
+
1230
+ foreach ($levels as $option_level) {
1231
+ if (!is_array($value) || !isset($value[$option_level])) {
1232
+ return $default_value;
1233
+ }
1234
+ $value = $value[$option_level];
1235
+ }
1236
+ return $value;
1237
+ }
1238
+
1239
+ /**
1240
+ * @param string $post_type
1241
+ * @param string $name
1242
+ * @param mixed $value
1243
+ *
1244
+ * @return bool
1245
+ */
1246
+ public static function save_option($post_type, $name, $value)
1247
+ {
1248
+ if (!self::types()->has($post_type)) {
1249
+ return false;
1250
+ }
1251
+
1252
+ $options = get_option(self::OPTION_POST_TYPE_OPTIONS, []);
1253
+ $keys = explode('.', $post_type.'.'.$name);
1254
+ $array = &$options;
1255
+
1256
+ foreach ($keys as $key) {
1257
+ if (!isset($array[$key]) || !is_array($array[$key])) {
1258
+ $array[$key] = [];
1259
+ }
1260
+ $array = &$array[$key];
1261
+ }
1262
+ $array = $value;
1263
+
1264
+ return update_option(self::OPTION_POST_TYPE_OPTIONS, $options);
1265
+ }
1266
+ }
1267
+ }
lib/wp-content-aware-engine/index.php CHANGED
@@ -1,2 +1,2 @@
1
  <?php
2
- /**/
1
  <?php
2
+ /**/
lib/wp-content-aware-engine/meta.php CHANGED
@@ -1,238 +1,238 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- if (!class_exists('WPCAMeta')) {
12
- /**
13
- * Post Meta
14
- */
15
- class WPCAMeta
16
- {
17
-
18
- /**
19
- * Id
20
- * @var string
21
- */
22
- private $id;
23
-
24
- /**
25
- * Title
26
- * @var string
27
- */
28
- private $title;
29
-
30
- /**
31
- * Description
32
- * @var string
33
- */
34
- private $description;
35
-
36
- /**
37
- * Default value
38
- * @var mixed
39
- */
40
- private $default_value;
41
-
42
- /**
43
- * Input type
44
- * @var string
45
- */
46
- private $input_type;
47
-
48
- /**
49
- * Input list
50
- * @var string
51
- */
52
- private $input_list;
53
-
54
- /**
55
- * Callback to sanitize data before save
56
- * @var func
57
- */
58
- private $sanitizer;
59
-
60
- /**
61
- * Constructor
62
- *
63
- * @since 1.0
64
- */
65
- public function __construct(
66
- $id,
67
- $title,
68
- $default_value = '',
69
- $input_type = 'text',
70
- $input_list = array(),
71
- $description = '',
72
- $sanitizer = ''
73
- ) {
74
- $this->id = $id;
75
- $this->title = $title;
76
- $this->default_value = $default_value;
77
- $this->input_type = $input_type;
78
- $this->input_list = $input_list;
79
- $this->description = $description;
80
- $this->sanitizer = $sanitizer;
81
- }
82
-
83
- /**
84
- * Get meta id
85
- *
86
- * @since 1.0
87
- * @return string
88
- */
89
- public function get_id()
90
- {
91
- return $this->id;
92
- }
93
- /**
94
- * Get meta title
95
- *
96
- * @since 1.0
97
- * @return string
98
- */
99
- public function get_title()
100
- {
101
- return $this->title;
102
- }
103
-
104
- /**
105
- * Get meta input type
106
- *
107
- * @since 1.0
108
- * @return string
109
- */
110
- public function get_input_type()
111
- {
112
- return $this->input_type;
113
- }
114
-
115
- /**
116
- * Get meta input list
117
- *
118
- * @since 1.0
119
- * @return array
120
- */
121
- public function get_input_list()
122
- {
123
- return $this->input_list;
124
- }
125
-
126
- /**
127
- * Set meta input list
128
- *
129
- * @since 1.0
130
- * @param array $input_list
131
- */
132
- public function set_input_list($input_list)
133
- {
134
- $this->input_list = $input_list;
135
- }
136
-
137
- /**
138
- * Get this meta data for a post
139
- *
140
- * @since 1.0
141
- * @param int $post_id
142
- * @param boolean $default_fallback
143
- * @param boolean $single
144
- * @return mixed
145
- */
146
- public function get_data($post_id, $default_fallback = false, $single = true)
147
- {
148
- $data = get_post_meta($post_id, WPCACore::PREFIX . $this->id, $single);
149
- if ($data == '' && $default_fallback) {
150
- $data = $this->default_value;
151
- }
152
- return $data;
153
- }
154
-
155
- /**
156
- * Update this meta data for a post
157
- *
158
- * @since 1.0
159
- * @param int $post_id
160
- * @param string $value
161
- * @return void
162
- */
163
- public function update($post_id, $value)
164
- {
165
- if ($this->input_type != 'multi') {
166
- update_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
167
- } else {
168
- add_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
169
- }
170
- }
171
-
172
- /**
173
- * Delete this meta data for a post
174
- *
175
- * @since 1.0
176
- * @param int $post_id
177
- * @param string $value
178
- * @return void
179
- */
180
- public function delete($post_id, $value = '')
181
- {
182
- delete_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
183
- }
184
-
185
- /**
186
- * Save data based on POST
187
- *
188
- * @since 4.2
189
- * @param int $post_id
190
- * @param string $value
191
- * @return void
192
- */
193
- public function save($post_id)
194
- {
195
- $value = isset($_POST[$this->id]) ? $_POST[$this->id] : '';
196
- if ($this->sanitizer && is_callable($this->sanitizer)) {
197
- $value = call_user_func($this->sanitizer, $value);
198
- }
199
- if ($this->input_type != 'multi') {
200
- //value can be 0 and valid
201
- if ($value != '') {
202
- $this->update($post_id, $value);
203
- } elseif ($this->get_data($post_id, false, true) != '') {
204
- $this->delete($post_id);
205
- }
206
- } else {
207
- $old = array_flip($this->get_data($post_id, false, false));
208
- if (is_array($value)) {
209
- foreach ($value as $meta) {
210
- if (isset($old[$meta])) {
211
- unset($old[$meta]);
212
- } else {
213
- $this->update($post_id, $meta);
214
- }
215
- }
216
- }
217
-
218
- foreach ($old as $meta => $v) {
219
- $this->delete($post_id, $meta);
220
- }
221
- }
222
- }
223
-
224
- /**
225
- * Get this meta data for a post
226
- * represented by entry in input list
227
- *
228
- * @since 1.0
229
- * @param int $post_id
230
- * @return mixed
231
- */
232
- public function get_list_data($post_id, $default_fallback = true)
233
- {
234
- $data = $this->get_data($post_id, $default_fallback);
235
- return isset($this->input_list[$data]) ? $this->input_list[$data] : null;
236
- }
237
- }
238
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ if (!class_exists('WPCAMeta')) {
12
+ /**
13
+ * Post Meta
14
+ */
15
+ class WPCAMeta
16
+ {
17
+
18
+ /**
19
+ * Id
20
+ * @var string
21
+ */
22
+ private $id;
23
+
24
+ /**
25
+ * Title
26
+ * @var string
27
+ */
28
+ private $title;
29
+
30
+ /**
31
+ * Description
32
+ * @var string
33
+ */
34
+ private $description;
35
+
36
+ /**
37
+ * Default value
38
+ * @var mixed
39
+ */
40
+ private $default_value;
41
+
42
+ /**
43
+ * Input type
44
+ * @var string
45
+ */
46
+ private $input_type;
47
+
48
+ /**
49
+ * Input list
50
+ * @var string
51
+ */
52
+ private $input_list;
53
+
54
+ /**
55
+ * Callback to sanitize data before save
56
+ * @var func
57
+ */
58
+ private $sanitizer;
59
+
60
+ /**
61
+ * Constructor
62
+ *
63
+ * @since 1.0
64
+ */
65
+ public function __construct(
66
+ $id,
67
+ $title,
68
+ $default_value = '',
69
+ $input_type = 'text',
70
+ $input_list = [],
71
+ $description = '',
72
+ $sanitizer = ''
73
+ ) {
74
+ $this->id = $id;
75
+ $this->title = $title;
76
+ $this->default_value = $default_value;
77
+ $this->input_type = $input_type;
78
+ $this->input_list = $input_list;
79
+ $this->description = $description;
80
+ $this->sanitizer = $sanitizer;
81
+ }
82
+
83
+ /**
84
+ * Get meta id
85
+ *
86
+ * @since 1.0
87
+ * @return string
88
+ */
89
+ public function get_id()
90
+ {
91
+ return $this->id;
92
+ }
93
+ /**
94
+ * Get meta title
95
+ *
96
+ * @since 1.0
97
+ * @return string
98
+ */
99
+ public function get_title()
100
+ {
101
+ return $this->title;
102
+ }
103
+
104
+ /**
105
+ * Get meta input type
106
+ *
107
+ * @since 1.0
108
+ * @return string
109
+ */
110
+ public function get_input_type()
111
+ {
112
+ return $this->input_type;
113
+ }
114
+
115
+ /**
116
+ * Get meta input list
117
+ *
118
+ * @since 1.0
119
+ * @return array
120
+ */
121
+ public function get_input_list()
122
+ {
123
+ return $this->input_list;
124
+ }
125
+
126
+ /**
127
+ * Set meta input list
128
+ *
129
+ * @since 1.0
130
+ * @param array $input_list
131
+ */
132
+ public function set_input_list($input_list)
133
+ {
134
+ $this->input_list = $input_list;
135
+ }
136
+
137
+ /**
138
+ * Get this meta data for a post
139
+ *
140
+ * @since 1.0
141
+ * @param int $post_id
142
+ * @param boolean $default_fallback
143
+ * @param boolean $single
144
+ * @return mixed
145
+ */
146
+ public function get_data($post_id, $default_fallback = false, $single = true)
147
+ {
148
+ $data = get_post_meta($post_id, WPCACore::PREFIX . $this->id, $single);
149
+ if ($data == '' && $default_fallback) {
150
+ $data = $this->default_value;
151
+ }
152
+ return $data;
153
+ }
154
+
155
+ /**
156
+ * Update this meta data for a post
157
+ *
158
+ * @since 1.0
159
+ * @param int $post_id
160
+ * @param string $value
161
+ * @return void
162
+ */
163
+ public function update($post_id, $value)
164
+ {
165
+ if ($this->input_type != 'multi') {
166
+ update_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
167
+ } else {
168
+ add_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Delete this meta data for a post
174
+ *
175
+ * @since 1.0
176
+ * @param int $post_id
177
+ * @param string $value
178
+ * @return void
179
+ */
180
+ public function delete($post_id, $value = '')
181
+ {
182
+ delete_post_meta($post_id, WPCACore::PREFIX . $this->id, $value);
183
+ }
184
+
185
+ /**
186
+ * Save data based on POST
187
+ *
188
+ * @since 4.2
189
+ * @param int $post_id
190
+ * @param string $value
191
+ * @return void
192
+ */
193
+ public function save($post_id)
194
+ {
195
+ $value = isset($_POST[$this->id]) ? $_POST[$this->id] : '';
196
+ if ($this->sanitizer && is_callable($this->sanitizer)) {
197
+ $value = call_user_func($this->sanitizer, $value);
198
+ }
199
+ if ($this->input_type != 'multi') {
200
+ //value can be 0 and valid
201
+ if ($value != '') {
202
+ $this->update($post_id, $value);
203
+ } elseif ($this->get_data($post_id, false, true) != '') {
204
+ $this->delete($post_id);
205
+ }
206
+ } else {
207
+ $old = array_flip($this->get_data($post_id, false, false));
208
+ if (is_array($value)) {
209
+ foreach ($value as $meta) {
210
+ if (isset($old[$meta])) {
211
+ unset($old[$meta]);
212
+ } else {
213
+ $this->update($post_id, $meta);
214
+ }
215
+ }
216
+ }
217
+
218
+ foreach ($old as $meta => $v) {
219
+ $this->delete($post_id, $meta);
220
+ }
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Get this meta data for a post
226
+ * represented by entry in input list
227
+ *
228
+ * @since 1.0
229
+ * @param int $post_id
230
+ * @return mixed
231
+ */
232
+ public function get_list_data($post_id, $default_fallback = true)
233
+ {
234
+ $data = $this->get_data($post_id, $default_fallback);
235
+ return isset($this->input_list[$data]) ? $this->input_list[$data] : null;
236
+ }
237
+ }
238
+ }
lib/wp-content-aware-engine/module/author.php CHANGED
@@ -1,113 +1,113 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Author Module
14
- *
15
- * Detects if current content is:
16
- * a) post type written by any or specific author
17
- * b) any or specific author archive
18
- *
19
- */
20
- class WPCAModule_author extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * Constructor
25
- */
26
- public function __construct()
27
- {
28
- parent::__construct('author', __('Authors', WPCA_DOMAIN));
29
- $this->placeholder = __('All Authors', WPCA_DOMAIN);
30
- $this->default_value = $this->id;
31
- $this->query_name = 'ca';
32
- }
33
-
34
- /**
35
- * Determine if content is relevant
36
- *
37
- * @since 1.0
38
- * @return boolean
39
- */
40
- public function in_context()
41
- {
42
- return (is_singular() && !is_front_page()) || is_author();
43
- }
44
-
45
- /**
46
- * Get data from context
47
- *
48
- * @global WP_Post $post
49
- * @since 1.0
50
- * @return array
51
- */
52
- public function get_context_data()
53
- {
54
- global $post;
55
- return array(
56
- $this->id,
57
- (string)(is_singular() ? $post->post_author : get_query_var('author'))
58
- );
59
- }
60
-
61
- /**
62
- * @param array $args
63
- *
64
- * @return array
65
- */
66
- protected function parse_query_args($args)
67
- {
68
- $new_args = array(
69
- 'number' => $args['limit'],
70
- 'offset' => ($args['paged'] - 1) * $args['limit'],
71
- 'search' => $args['search'],
72
- 'fields' => array('ID','display_name'),
73
- 'orderby' => 'display_name',
74
- 'order' => 'ASC',
75
- 'include' => $args['include'],
76
- 'count_total' => false,
77
- );
78
- if ($new_args['search']) {
79
- if (false !== strpos($new_args['search'], '@')) {
80
- $new_args['search_columns'] = array( 'user_email' );
81
- } elseif (is_numeric($new_args['search'])) {
82
- $new_args['search_columns'] = array( 'user_login', 'ID' );
83
- } else {
84
- $new_args['search_columns'] = array( 'user_nicename', 'user_login', 'display_name' );
85
- }
86
- $new_args['search'] = '*'.$new_args['search'].'*';
87
- }
88
- return $new_args;
89
- }
90
-
91
- /**
92
- * Get authors
93
- *
94
- * @since 1.0
95
- * @param array $args
96
- * @return array
97
- */
98
- protected function _get_content($args = array())
99
- {
100
- $user_query = new WP_User_Query($args);
101
- $author_list = array();
102
-
103
- if ($user_query->results) {
104
- foreach ($user_query->get_results() as $user) {
105
- $author_list[] = array(
106
- 'id' => $user->ID,
107
- 'text' => $user->display_name
108
- );
109
- }
110
- }
111
- return $author_list;
112
- }
113
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Author Module
14
+ *
15
+ * Detects if current content is:
16
+ * a) post type written by any or specific author
17
+ * b) any or specific author archive
18
+ *
19
+ */
20
+ class WPCAModule_author extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct()
27
+ {
28
+ parent::__construct('author', __('Authors', WPCA_DOMAIN));
29
+ $this->placeholder = __('All Authors', WPCA_DOMAIN);
30
+ $this->default_value = $this->id;
31
+ $this->query_name = 'ca';
32
+ }
33
+
34
+ /**
35
+ * Determine if content is relevant
36
+ *
37
+ * @since 1.0
38
+ * @return boolean
39
+ */
40
+ public function in_context()
41
+ {
42
+ return (is_singular() && !is_front_page()) || is_author();
43
+ }
44
+
45
+ /**
46
+ * Get data from context
47
+ *
48
+ * @global WP_Post $post
49
+ * @since 1.0
50
+ * @return array
51
+ */
52
+ public function get_context_data()
53
+ {
54
+ global $post;
55
+ return [
56
+ $this->id,
57
+ (string)(is_singular() ? $post->post_author : get_query_var('author'))
58
+ ];
59
+ }
60
+
61
+ /**
62
+ * @param array $args
63
+ *
64
+ * @return array
65
+ */
66
+ protected function parse_query_args($args)
67
+ {
68
+ $new_args = [
69
+ 'number' => $args['limit'],
70
+ 'offset' => ($args['paged'] - 1) * $args['limit'],
71
+ 'search' => $args['search'],
72
+ 'fields' => ['ID','display_name'],
73
+ 'orderby' => 'display_name',
74
+ 'order' => 'ASC',
75
+ 'include' => $args['include'],
76
+ 'count_total' => false,
77
+ ];
78
+ if ($new_args['search']) {
79
+ if (false !== strpos($new_args['search'], '@')) {
80
+ $new_args['search_columns'] = [ 'user_email' ];
81
+ } elseif (is_numeric($new_args['search'])) {
82
+ $new_args['search_columns'] = [ 'user_login', 'ID' ];
83
+ } else {
84
+ $new_args['search_columns'] = [ 'user_nicename', 'user_login', 'display_name' ];
85
+ }
86
+ $new_args['search'] = '*'.$new_args['search'].'*';
87
+ }
88
+ return $new_args;
89
+ }
90
+
91
+ /**
92
+ * Get authors
93
+ *
94
+ * @since 1.0
95
+ * @param array $args
96
+ * @return array
97
+ */
98
+ protected function _get_content($args = [])
99
+ {
100
+ $user_query = new WP_User_Query($args);
101
+ $author_list = [];
102
+
103
+ if ($user_query->results) {
104
+ foreach ($user_query->get_results() as $user) {
105
+ $author_list[] = [
106
+ 'id' => $user->ID,
107
+ 'text' => $user->display_name
108
+ ];
109
+ }
110
+ }
111
+ return $author_list;
112
+ }
113
+ }
lib/wp-content-aware-engine/module/base.php CHANGED
@@ -80,7 +80,7 @@ abstract class WPCAModule_Base
80
  if (is_admin()) {
81
  add_action(
82
  'wp_ajax_wpca/module/'.$this->id,
83
- array($this,'ajax_print_content')
84
  );
85
  }
86
  }
@@ -103,12 +103,12 @@ abstract class WPCAModule_Base
103
  */
104
  public function list_module($list)
105
  {
106
- $list[] = array(
107
  'id' => $this->id,
108
  'text' => $this->name,
109
  'placeholder' => $this->placeholder,
110
  'default_value' => $this->default_value,
111
- );
112
  return $list;
113
  }
114
 
@@ -222,12 +222,12 @@ abstract class WPCAModule_Base
222
  {
223
  $data = get_post_custom_values($this->get_data_key(), $post_id);
224
  if ($data) {
225
- $group_data[$this->id] = array(
226
  'label' => $this->name,
227
  'placeholder' => $this->placeholder,
228
- 'data' => $this->get_content(array('include' => $data)),
229
  'default_value' => $this->default_value
230
- );
231
  }
232
  return $group_data;
233
  }
@@ -239,7 +239,7 @@ abstract class WPCAModule_Base
239
  * @param array $args
240
  * @return array
241
  */
242
- abstract protected function _get_content($args = array());
243
 
244
  /**
245
  * Determine if current content is relevant
@@ -292,12 +292,12 @@ abstract class WPCAModule_Base
292
  */
293
  protected function get_content($args)
294
  {
295
- $args = array_merge(array(
296
- 'include' => array(),
297
  'paged' => 1,
298
  'search' => false,
299
  'limit' => -1,
300
- ), $args);
301
  return $this->_get_content($this->parse_query_args($args));
302
  }
303
 
@@ -318,23 +318,23 @@ abstract class WPCAModule_Base
318
  wp_die();
319
  }
320
 
321
- $response = $this->get_content(array(
322
  'paged' => $_POST['paged'],
323
  'search' => isset($_POST['search']) ? $_POST['search'] : false,
324
  'limit' => isset($_POST['limit']) ? $_POST['limit'] : 20,
325
  'item_object' => $_POST['action']
326
- ));
327
 
328
  //ECMAScript has no standard to guarantee
329
  //prop order in an object, send array instead
330
  //todo: fix in each module
331
- $fix_response = array();
332
  foreach ($response as $id => $title) {
333
  if (!is_array($title)) {
334
- $fix_response[] = array(
335
  'id' => $id,
336
  'text' => $title
337
- );
338
  } else {
339
  $fix_response[] = $title;
340
  }
@@ -353,7 +353,7 @@ abstract class WPCAModule_Base
353
  if (is_admin()) {
354
  remove_action(
355
  'wp_ajax_wpca/module/'.$this->id,
356
- array($this,'ajax_print_content')
357
  );
358
  }
359
  }
80
  if (is_admin()) {
81
  add_action(
82
  'wp_ajax_wpca/module/'.$this->id,
83
+ [$this,'ajax_print_content']
84
  );
85
  }
86
  }
103
  */
104
  public function list_module($list)
105
  {
106
+ $list[] = [
107
  'id' => $this->id,
108
  'text' => $this->name,
109
  'placeholder' => $this->placeholder,
110
  'default_value' => $this->default_value,
111
+ ];
112
  return $list;
113
  }
114
 
222
  {
223
  $data = get_post_custom_values($this->get_data_key(), $post_id);
224
  if ($data) {
225
+ $group_data[$this->id] = [
226
  'label' => $this->name,
227
  'placeholder' => $this->placeholder,
228
+ 'data' => $this->get_content(['include' => $data]),
229
  'default_value' => $this->default_value
230
+ ];
231
  }
232
  return $group_data;
233
  }
239
  * @param array $args
240
  * @return array
241
  */
242
+ abstract protected function _get_content($args = []);
243
 
244
  /**
245
  * Determine if current content is relevant
292
  */
293
  protected function get_content($args)
294
  {
295
+ $args = array_merge([
296
+ 'include' => [],
297
  'paged' => 1,
298
  'search' => false,
299
  'limit' => -1,
300
+ ], $args);
301
  return $this->_get_content($this->parse_query_args($args));
302
  }
303
 
318
  wp_die();
319
  }
320
 
321
+ $response = $this->get_content([
322
  'paged' => $_POST['paged'],
323
  'search' => isset($_POST['search']) ? $_POST['search'] : false,
324
  'limit' => isset($_POST['limit']) ? $_POST['limit'] : 20,
325
  'item_object' => $_POST['action']
326
+ ]);
327
 
328
  //ECMAScript has no standard to guarantee
329
  //prop order in an object, send array instead
330
  //todo: fix in each module
331
+ $fix_response = [];
332
  foreach ($response as $id => $title) {
333
  if (!is_array($title)) {
334
+ $fix_response[] = [
335
  'id' => $id,
336
  'text' => $title
337
+ ];
338
  } else {
339
  $fix_response[] = $title;
340
  }
353
  if (is_admin()) {
354
  remove_action(
355
  'wp_ajax_wpca/module/'.$this->id,
356
+ [$this,'ajax_print_content']
357
  );
358
  }
359
  }
lib/wp-content-aware-engine/module/bbpress.php CHANGED
@@ -1,111 +1,111 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * bbPress Module
14
- * Requires bbPress 2.5+
15
- *
16
- * Detects if current content is:
17
- * a) any or specific bbpress user profile
18
- *
19
- */
20
- class WPCAModule_bbpress extends WPCAModule_author
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct();
34
- $this->id = 'bb_profile';
35
- $this->name = __('bbPress User Profiles', WPCA_DOMAIN);
36
- $this->placeholder = __('All Profiles', WPCA_DOMAIN);
37
- $this->default_value = $this->id;
38
-
39
- $this->query_name = 'cbb';
40
- }
41
-
42
- /**
43
- * Initiate module
44
- *
45
- * @since 2.0
46
- * @return void
47
- */
48
- public function initiate()
49
- {
50
- parent::initiate();
51
- add_filter(
52
- 'wpca/module/post_type/db-where',
53
- array($this,'add_forum_dependency')
54
- );
55
- }
56
-
57
- /**
58
- * @return bool
59
- */
60
- public function can_enable()
61
- {
62
- return function_exists('bbp_get_version')
63
- && function_exists('bbp_is_single_user')
64
- && function_exists('bbp_get_displayed_user_id')
65
- && function_exists('bbp_get_forum_id');
66
- }
67
-
68
- /**
69
- * @since 1.0
70
- * @return boolean
71
- */
72
- public function in_context()
73
- {
74
- return bbp_is_single_user();
75
- }
76
-
77
- /**
78
- * Get data from context
79
- *
80
- * @since 1.0
81
- * @return array
82
- */
83
- public function get_context_data()
84
- {
85
- $data = array($this->id);
86
- $data[] = bbp_get_displayed_user_id();
87
- return $data;
88
- }
89
-
90
- /**
91
- * Sidebars to be displayed with forums will also
92
- * be dislpayed with respective topics and replies
93
- *
94
- * @since 1.0
95
- * @param string $where
96
- * @return string
97
- */
98
- public function add_forum_dependency($where)
99
- {
100
- if (is_singular(array('topic','reply'))) {
101
- $data = array(
102
- get_post_type(),
103
- get_the_ID(),
104
- 'forum'
105
- );
106
- $data[] = bbp_get_forum_id();
107
- $where = "(cp.meta_value IS NULL OR cp.meta_value IN('".implode("','", $data)."'))";
108
- }
109
- return $where;
110
- }
111
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * bbPress Module
14
+ * Requires bbPress 2.5+
15
+ *
16
+ * Detects if current content is:
17
+ * a) any or specific bbpress user profile
18
+ *
19
+ */
20
+ class WPCAModule_bbpress extends WPCAModule_author
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct();
34
+ $this->id = 'bb_profile';
35
+ $this->name = __('bbPress User Profiles', WPCA_DOMAIN);
36
+ $this->placeholder = __('All Profiles', WPCA_DOMAIN);
37
+ $this->default_value = $this->id;
38
+
39
+ $this->query_name = 'cbb';
40
+ }
41
+
42
+ /**
43
+ * Initiate module
44
+ *
45
+ * @since 2.0
46
+ * @return void
47
+ */
48
+ public function initiate()
49
+ {
50
+ parent::initiate();
51
+ add_filter(
52
+ 'wpca/module/post_type/db-where',
53
+ [$this,'add_forum_dependency']
54
+ );
55
+ }
56
+
57
+ /**
58
+ * @return bool
59
+ */
60
+ public function can_enable()
61
+ {
62
+ return function_exists('bbp_get_version')
63
+ && function_exists('bbp_is_single_user')
64
+ && function_exists('bbp_get_displayed_user_id')
65
+ && function_exists('bbp_get_forum_id');
66
+ }
67
+
68
+ /**
69
+ * @since 1.0
70
+ * @return boolean
71
+ */
72
+ public function in_context()
73
+ {
74
+ return bbp_is_single_user();
75
+ }
76
+
77
+ /**
78
+ * Get data from context
79
+ *
80
+ * @since 1.0
81
+ * @return array
82
+ */
83
+ public function get_context_data()
84
+ {
85
+ $data = [$this->id];
86
+ $data[] = bbp_get_displayed_user_id();
87
+ return $data;
88
+ }
89
+
90
+ /**
91
+ * Sidebars to be displayed with forums will also
92
+ * be dislpayed with respective topics and replies
93
+ *
94
+ * @since 1.0
95
+ * @param string $where
96
+ * @return string
97
+ */
98
+ public function add_forum_dependency($where)
99
+ {
100
+ if (is_singular(['topic','reply'])) {
101
+ $data = [
102
+ get_post_type(),
103
+ get_the_ID(),
104
+ 'forum'
105
+ ];
106
+ $data[] = bbp_get_forum_id();
107
+ $where = "(cp.meta_value IS NULL OR cp.meta_value IN('".implode("','", $data)."'))";
108
+ }
109
+ return $where;
110
+ }
111
+ }
lib/wp-content-aware-engine/module/bp_member.php CHANGED
@@ -1,173 +1,173 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * BuddyPress Member Page Module
14
- * Requires BuddyPress 2.6+
15
- *
16
- * Detects if current content is:
17
- * a) a specific buddypress member page
18
- *
19
- */
20
- class WPCAModule_bp_member extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Cached search string
30
- * @var string
31
- */
32
- protected $search_string;
33
-
34
- /**
35
- * Constructor
36
- */
37
- public function __construct()
38
- {
39
- parent::__construct('bp_member', __('BuddyPress Profiles', WPCA_DOMAIN));
40
- $this->default_value = 0;
41
- $this->placeholder = __('All Sections', WPCA_DOMAIN);
42
-
43
- $this->query_name = 'cbp';
44
- }
45
-
46
- /**
47
- * @return bool
48
- */
49
- public function can_enable()
50
- {
51
- return defined('BP_VERSION');
52
- }
53
-
54
- /**
55
- * Initiate module
56
- *
57
- * @since 2.0
58
- * @return void
59
- */
60
- public function initiate()
61
- {
62
- parent::initiate();
63
- add_filter(
64
- 'wpca/module/static/in-context',
65
- array($this,'static_is_content')
66
- );
67
- }
68
-
69
- /**
70
- * Get content for sidebar editor
71
- *
72
- * @global object $bp
73
- * @since 1.0
74
- * @param array $args
75
- * @return array
76
- */
77
- protected function _get_content($args = array())
78
- {
79
- global $bp;
80
-
81
- if (isset($args['paged']) && $args['paged'] > 1) {
82
- return array();
83
- }
84
-
85
- $content = array();
86
- $is_search = isset($args['search']) && $args['search'];
87
-
88
- if (isset($bp->members->nav)) {
89
- foreach ($bp->members->nav->get_item_nav() as $item) {
90
- $content[$item->slug] = array(
91
- 'id' => $item->slug,
92
- 'text' => strip_tags($item->name)
93
- );
94
- if ($item->children) {
95
- $level = $is_search ? 0 : 1;
96
- foreach ($item->children as $child_item) {
97
- $content[$item->slug.'-'.$child_item->slug] = array(
98
- 'text' => strip_tags($child_item->name),
99
- 'id' => $item->slug.'-'.$child_item->slug,
100
- 'level' => $level
101
- );
102
- }
103
- }
104
- }
105
- }
106
-
107
- if (!empty($args['include'])) {
108
- $content = array_intersect_key($content, array_flip($args['include']));
109
- } elseif ($is_search) {
110
- $this->search_string = $args['search'];
111
- $content = array_filter($content, array($this,'_filter_search'));
112
- }
113
-
114
- return $content;
115
- }
116
-
117
- /**
118
- * Filter content based on search
119
- *
120
- * @since 2.0
121
- * @param string $value
122
- * @return boolean
123
- */
124
- protected function _filter_search($value)
125
- {
126
- return mb_stripos($value['text'], $this->search_string) !== false;
127
- }
128
-
129
- /**
130
- * @global object $bp
131
- * @since 1.0
132
- * @return boolean
133
- */
134
- public function in_context()
135
- {
136
- global $bp;
137
- return isset($bp->displayed_user->domain) && $bp->displayed_user->domain;
138
- }
139
-
140
- /**
141
- * Get data from context
142
- *
143
- * @global object $bp
144
- * @since 1.0
145
- * @return array
146
- */
147
- public function get_context_data()
148
- {
149
- global $bp;
150
- $data = array($this->default_value);
151
- if (isset($bp->current_component)) {
152
- $data[] = $bp->current_component;
153
- if (isset($bp->current_action)) {
154
- $data[] = $bp->current_component.'-'.$bp->current_action;
155
- }
156
- }
157
- return $data;
158
- }
159
-
160
- /**
161
- * Avoid collision with content of static module
162
- * Somehow buddypress pages pass is_404()
163
- *
164
- * @since 1.0
165
- * @param boolean $content
166
- * @return boolean
167
- */
168
- public function static_is_content($content)
169
- {
170
- //TODO: test if deprecated
171
- return $content && !$this->in_context();
172
- }
173
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * BuddyPress Member Page Module
14
+ * Requires BuddyPress 2.6+
15
+ *
16
+ * Detects if current content is:
17
+ * a) a specific buddypress member page
18
+ *
19
+ */
20
+ class WPCAModule_bp_member extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Cached search string
30
+ * @var string
31
+ */
32
+ protected $search_string;
33
+
34
+ /**
35
+ * Constructor
36
+ */
37
+ public function __construct()
38
+ {
39
+ parent::__construct('bp_member', __('BuddyPress Profiles', WPCA_DOMAIN));
40
+ $this->default_value = 0;
41
+ $this->placeholder = __('All Sections', WPCA_DOMAIN);
42
+
43
+ $this->query_name = 'cbp';
44
+ }
45
+
46
+ /**
47
+ * @return bool
48
+ */
49
+ public function can_enable()
50
+ {
51
+ return defined('BP_VERSION');
52
+ }
53
+
54
+ /**
55
+ * Initiate module
56
+ *
57
+ * @since 2.0
58
+ * @return void
59
+ */
60
+ public function initiate()
61
+ {
62
+ parent::initiate();
63
+ add_filter(
64
+ 'wpca/module/static/in-context',
65
+ [$this,'static_is_content']
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Get content for sidebar editor
71
+ *
72
+ * @global object $bp
73
+ * @since 1.0
74
+ * @param array $args
75
+ * @return array
76
+ */
77
+ protected function _get_content($args = [])
78
+ {
79
+ global $bp;
80
+
81
+ if (isset($args['paged']) && $args['paged'] > 1) {
82
+ return [];
83
+ }
84
+
85
+ $content = [];
86
+ $is_search = isset($args['search']) && $args['search'];
87
+
88
+ if (isset($bp->members->nav)) {
89
+ foreach ($bp->members->nav->get_item_nav() as $item) {
90
+ $content[$item->slug] = [
91
+ 'id' => $item->slug,
92
+ 'text' => strip_tags($item->name)
93
+ ];
94
+ if ($item->children) {
95
+ $level = $is_search ? 0 : 1;
96
+ foreach ($item->children as $child_item) {
97
+ $content[$item->slug.'-'.$child_item->slug] = [
98
+ 'text' => strip_tags($child_item->name),
99
+ 'id' => $item->slug.'-'.$child_item->slug,
100
+ 'level' => $level
101
+ ];
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ if (!empty($args['include'])) {
108
+ $content = array_intersect_key($content, array_flip($args['include']));
109
+ } elseif ($is_search) {
110
+ $this->search_string = $args['search'];
111
+ $content = array_filter($content, [$this,'_filter_search']);
112
+ }
113
+
114
+ return $content;
115
+ }
116
+
117
+ /**
118
+ * Filter content based on search
119
+ *
120
+ * @since 2.0
121
+ * @param string $value
122
+ * @return boolean
123
+ */
124
+ protected function _filter_search($value)
125
+ {
126
+ return mb_stripos($value['text'], $this->search_string) !== false;
127
+ }
128
+
129
+ /**
130
+ * @global object $bp
131
+ * @since 1.0
132
+ * @return boolean
133
+ */
134
+ public function in_context()
135
+ {
136
+ global $bp;
137
+ return isset($bp->displayed_user->domain) && $bp->displayed_user->domain;
138
+ }
139
+
140
+ /**
141
+ * Get data from context
142
+ *
143
+ * @global object $bp
144
+ * @since 1.0
145
+ * @return array
146
+ */
147
+ public function get_context_data()
148
+ {
149
+ global $bp;
150
+ $data = [$this->default_value];
151
+ if (isset($bp->current_component)) {
152
+ $data[] = $bp->current_component;
153
+ if (isset($bp->current_action)) {
154
+ $data[] = $bp->current_component.'-'.$bp->current_action;
155
+ }
156
+ }
157
+ return $data;
158
+ }
159
+
160
+ /**
161
+ * Avoid collision with content of static module
162
+ * Somehow buddypress pages pass is_404()
163
+ *
164
+ * @since 1.0
165
+ * @param boolean $content
166
+ * @return boolean
167
+ */
168
+ public function static_is_content($content)
169
+ {
170
+ //TODO: test if deprecated
171
+ return $content && !$this->in_context();
172
+ }
173
+ }
lib/wp-content-aware-engine/module/date.php CHANGED
@@ -1,80 +1,80 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- * Date Module
13
- *
14
- * @deprecated 9.1
15
- */
16
- class WPCAModule_date extends WPCAModule_Base
17
- {
18
-
19
- /**
20
- * Constructor
21
- */
22
- public function __construct()
23
- {
24
- parent::__construct(
25
- 'date',
26
- __('Dates', WPCA_DOMAIN)
27
- );
28
- $this->placeholder = __('Date Archives', WPCA_DOMAIN);
29
- $this->default_value = '0000-00-00';
30
- if (get_class() === 'WPCAModule_date') {
31
- $this->name .= ' (Legacy)';
32
- }
33
- //$this->query_name = 'cd';
34
- }
35
-
36
- /**
37
- * Determine if content is relevant
38
- *
39
- * @since 1.0
40
- * @return boolean
41
- */
42
- public function in_context()
43
- {
44
- return is_date();
45
- }
46
-
47
- /**
48
- * Get data from context
49
- *
50
- * @global object $wpdb
51
- * @since 1.0
52
- * @return array
53
- */
54
- public function get_context_data()
55
- {
56
- global $wpdb;
57
-
58
- $name = $this->get_query_name();
59
-
60
- return $wpdb->prepare(
61
- "($name.meta_value IS NULL OR '%s' = $name.meta_value)",
62
- '0000-00-00'
63
- );
64
- }
65
-
66
- /**
67
- * Get content
68
- *
69
- * @since 1.0
70
- * @return array
71
- */
72
- protected function _get_content($args = array())
73
- {
74
- $data = array();
75
- if ($args['include']) {
76
- $data = array_intersect_key($data, array_flip($args['include']));
77
- }
78
- return $data;
79
- }
80
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ * Date Module
13
+ *
14
+ * @deprecated 9.1
15
+ */
16
+ class WPCAModule_date extends WPCAModule_Base
17
+ {
18
+
19
+ /**
20
+ * Constructor
21
+ */
22
+ public function __construct()
23
+ {
24
+ parent::__construct(
25
+ 'date',
26
+ __('Dates', WPCA_DOMAIN)
27
+ );
28
+ $this->placeholder = __('Date Archives', WPCA_DOMAIN);
29
+ $this->default_value = '0000-00-00';
30
+ if (get_class() === 'WPCAModule_date') {
31
+ $this->name .= ' (Legacy)';
32
+ }
33
+ //$this->query_name = 'cd';
34
+ }
35
+
36
+ /**
37
+ * Determine if content is relevant
38
+ *
39
+ * @since 1.0
40
+ * @return boolean
41
+ */
42
+ public function in_context()
43
+ {
44
+ return is_date();
45
+ }
46
+
47
+ /**
48
+ * Get data from context
49
+ *
50
+ * @global object $wpdb
51
+ * @since 1.0
52
+ * @return array
53
+ */
54
+ public function get_context_data()
55
+ {
56
+ global $wpdb;
57
+
58
+ $name = $this->get_query_name();
59
+
60
+ return $wpdb->prepare(
61
+ "($name.meta_value IS NULL OR '%s' = $name.meta_value)",
62
+ '0000-00-00'
63
+ );
64
+ }
65
+
66
+ /**
67
+ * Get content
68
+ *
69
+ * @since 1.0
70
+ * @return array
71
+ */
72
+ protected function _get_content($args = [])
73
+ {
74
+ $data = [];
75
+ if ($args['include']) {
76
+ $data = array_intersect_key($data, array_flip($args['include']));
77
+ }
78
+ return $data;
79
+ }
80
+ }
lib/wp-content-aware-engine/module/page_template.php CHANGED
@@ -1,100 +1,100 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Page Template Module
14
- *
15
- * Detects if current content has:
16
- * a) any or specific page template
17
- *
18
- *
19
- */
20
- class WPCAModule_page_template extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * Cached search string
25
- * @var string
26
- */
27
- protected $search_string;
28
-
29
- /**
30
- * Constructor
31
- */
32
- public function __construct()
33
- {
34
- parent::__construct('page_template', __('Page Templates', WPCA_DOMAIN));
35
- $this->placeholder = __('All Templates', WPCA_DOMAIN);
36
- $this->default_value = $this->id;
37
-
38
- $this->query_name = 'cpt';
39
- }
40
-
41
- /**
42
- * Determine if content is relevant
43
- *
44
- * @since 1.0
45
- * @return boolean
46
- */
47
- public function in_context()
48
- {
49
- if (is_singular() && !('page' == get_option('show_on_front') && get_option('page_on_front') == get_the_ID())) {
50
- $template = get_post_meta(get_the_ID(), '_wp_page_template', true);
51
- return ($template && $template != 'default');
52
- }
53
- return false;
54
- }
55
-
56
- /**
57
- * Get data from context
58
- *
59
- * @since 1.0
60
- * @return array
61
- */
62
- public function get_context_data()
63
- {
64
- return array(
65
- $this->id,
66
- get_post_meta(get_the_ID(), '_wp_page_template', true)
67
- );
68
- }
69
-
70
- /**
71
- * Get page templates
72
- *
73
- * @since 1.0
74
- * @param array $args
75
- * @return array
76
- */
77
- protected function _get_content($args = array())
78
- {
79
- $templates = array_flip(get_page_templates());
80
- if ($args['include']) {
81
- $templates = array_intersect_key($templates, array_flip($args['include']));
82
- } elseif ($args['search']) {
83
- $this->search_string = $args['search'];
84
- $templates = array_filter($templates, array($this,'_filter_search'));
85
- }
86
- return $templates;
87
- }
88
-
89
- /**
90
- * Filter content based on search
91
- *
92
- * @since 2.0
93
- * @param string $value
94
- * @return boolean
95
- */
96
- protected function _filter_search($value)
97
- {
98
- return mb_stripos($value, $this->search_string) !== false;
99
- }
100
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Page Template Module
14
+ *
15
+ * Detects if current content has:
16
+ * a) any or specific page template
17
+ *
18
+ *
19
+ */
20
+ class WPCAModule_page_template extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * Cached search string
25
+ * @var string
26
+ */
27
+ protected $search_string;
28
+
29
+ /**
30
+ * Constructor
31
+ */
32
+ public function __construct()
33
+ {
34
+ parent::__construct('page_template', __('Page Templates', WPCA_DOMAIN));
35
+ $this->placeholder = __('All Templates', WPCA_DOMAIN);
36
+ $this->default_value = $this->id;
37
+
38
+ $this->query_name = 'cpt';
39
+ }
40
+
41
+ /**
42
+ * Determine if content is relevant
43
+ *
44
+ * @since 1.0
45
+ * @return boolean
46
+ */
47
+ public function in_context()
48
+ {
49
+ if (is_singular() && !('page' == get_option('show_on_front') && get_option('page_on_front') == get_the_ID())) {
50
+ $template = get_post_meta(get_the_ID(), '_wp_page_template', true);
51
+ return ($template && $template != 'default');
52
+ }
53
+ return false;
54
+ }
55
+
56
+ /**
57
+ * Get data from context
58
+ *
59
+ * @since 1.0
60
+ * @return array
61
+ */
62
+ public function get_context_data()
63
+ {
64
+ return [
65
+ $this->id,
66
+ get_post_meta(get_the_ID(), '_wp_page_template', true)
67
+ ];
68
+ }
69
+
70
+ /**
71
+ * Get page templates
72
+ *
73
+ * @since 1.0
74
+ * @param array $args
75
+ * @return array
76
+ */
77
+ protected function _get_content($args = [])
78
+ {
79
+ $templates = array_flip(get_page_templates());
80
+ if ($args['include']) {
81
+ $templates = array_intersect_key($templates, array_flip($args['include']));
82
+ } elseif ($args['search']) {
83
+ $this->search_string = $args['search'];
84
+ $templates = array_filter($templates, [$this,'_filter_search']);
85
+ }
86
+ return $templates;
87
+ }
88
+
89
+ /**
90
+ * Filter content based on search
91
+ *
92
+ * @since 2.0
93
+ * @param string $value
94
+ * @return boolean
95
+ */
96
+ protected function _filter_search($value)
97
+ {
98
+ return mb_stripos($value, $this->search_string) !== false;
99
+ }
100
+ }
lib/wp-content-aware-engine/module/pods.php CHANGED
@@ -1,124 +1,124 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Pods Module
14
- * Requires version 2.6+
15
- *
16
- * Detects if current content is:
17
- * a) any or specific Pods Page
18
- *
19
- */
20
- class WPCAModule_pods extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct('pods', __('Pods Pages', WPCA_DOMAIN));
34
- $this->placeholder = __('All Pods Pages', WPCA_DOMAIN);
35
- $this->default_value = $this->id;
36
-
37
- $this->query_name = 'cpo';
38
- }
39
-
40
- /**
41
- * @return bool
42
- */
43
- public function can_enable()
44
- {
45
- return defined('PODS_DIR')
46
- && function_exists('pod_page_exists')
47
- && function_exists('is_pod_page')
48
- && function_exists('pods_api');
49
- }
50
-
51
- /**
52
- * @since 2.0
53
- * @return boolean
54
- */
55
- public function in_context()
56
- {
57
- return is_pod_page();
58
- }
59
-
60
- /**
61
- * Get data from context
62
- *
63
- * @since 2.0
64
- * @return array
65
- */
66
- public function get_context_data()
67
- {
68
- $data = array(
69
- $this->id
70
- );
71
- $pod_page = pod_page_exists();
72
- $data[] = $pod_page['id'];
73
- return $data;
74
- }
75
-
76
- /**
77
- * @param array $args
78
- *
79
- * @return array
80
- */
81
- protected function parse_query_args($args)
82
- {
83
- return array(
84
- 'ids' => $args['include'] ? $args['include'] : false,
85
- 'where' => '',
86
- 'limit' => $args['limit'],
87
- 'search' => $args['search']
88
- );
89
- }
90
-
91
- /**
92
- * Get Pod Pages
93
- *
94
- * @since 2.0
95
- * @param array $args
96
- * @return array
97
- */
98
- protected function _get_content($args = array())
99
- {
100
- $pods = array();
101
- $results = pods_api()->load_pages($this->parse_query_args($args));
102
- foreach ($results as $result) {
103
- $pods[$result['id']] = $result['name'];
104
- }
105
- if ($args['search']) {
106
- $this->search_string = $args['search'];
107
- $pods = array_filter($pods, array($this,'_filter_search'));
108
- }
109
-
110
- return $pods;
111
- }
112
-
113
- /**
114
- * Filter content based on search
115
- *
116
- * @since 2.0
117
- * @param string $value
118
- * @return boolean
119
- */
120
- protected function _filter_search($value)
121
- {
122
- return mb_stripos($value, $this->search_string) !== false;
123
- }
124
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Pods Module
14
+ * Requires version 2.6+
15
+ *
16
+ * Detects if current content is:
17
+ * a) any or specific Pods Page
18
+ *
19
+ */
20
+ class WPCAModule_pods extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct('pods', __('Pods Pages', WPCA_DOMAIN));
34
+ $this->placeholder = __('All Pods Pages', WPCA_DOMAIN);
35
+ $this->default_value = $this->id;
36
+
37
+ $this->query_name = 'cpo';
38
+ }
39
+
40
+ /**
41
+ * @return bool
42
+ */
43
+ public function can_enable()
44
+ {
45
+ return defined('PODS_DIR')
46
+ && function_exists('pod_page_exists')
47
+ && function_exists('is_pod_page')
48
+ && function_exists('pods_api');
49
+ }
50
+
51
+ /**
52
+ * @since 2.0
53
+ * @return boolean
54
+ */
55
+ public function in_context()
56
+ {
57
+ return is_pod_page();
58
+ }
59
+
60
+ /**
61
+ * Get data from context
62
+ *
63
+ * @since 2.0
64
+ * @return array
65
+ */
66
+ public function get_context_data()
67
+ {
68
+ $data = [
69
+ $this->id
70
+ ];
71
+ $pod_page = pod_page_exists();
72
+ $data[] = $pod_page['id'];
73
+ return $data;
74
+ }
75
+
76
+ /**
77
+ * @param array $args
78
+ *
79
+ * @return array
80
+ */
81
+ protected function parse_query_args($args)
82
+ {
83
+ return [
84
+ 'ids' => $args['include'] ? $args['include'] : false,
85
+ 'where' => '',
86
+ 'limit' => $args['limit'],
87
+ 'search' => $args['search']
88
+ ];
89
+ }
90
+
91
+ /**
92
+ * Get Pod Pages
93
+ *
94
+ * @since 2.0
95
+ * @param array $args
96
+ * @return array
97
+ */
98
+ protected function _get_content($args = [])
99
+ {
100
+ $pods = [];
101
+ $results = pods_api()->load_pages($this->parse_query_args($args));
102
+ foreach ($results as $result) {
103
+ $pods[$result['id']] = $result['name'];
104
+ }
105
+ if ($args['search']) {
106
+ $this->search_string = $args['search'];
107
+ $pods = array_filter($pods, [$this,'_filter_search']);
108
+ }
109
+
110
+ return $pods;
111
+ }
112
+
113
+ /**
114
+ * Filter content based on search
115
+ *
116
+ * @since 2.0
117
+ * @param string $value
118
+ * @return boolean
119
+ */
120
+ protected function _filter_search($value)
121
+ {
122
+ return mb_stripos($value, $this->search_string) !== false;
123
+ }
124
+ }
lib/wp-content-aware-engine/module/polylang.php CHANGED
@@ -1,118 +1,118 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Polylang Module
14
- * Requires version 1.7+
15
- *
16
- * Detects if current content is:
17
- * a) in specific language
18
- *
19
- */
20
- class WPCAModule_polylang extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
-
35
- $this->query_name = 'cl';
36
- }
37
-
38
- public function initiate()
39
- {
40
- parent::initiate();
41
- add_filter(
42
- 'pll_get_post_types',
43
- array($this,'remove_sidebar_multilingual')
44
- );
45
- }
46
-
47
- /**
48
- * @return bool
49
- */
50
- public function can_enable()
51
- {
52
- return defined('POLYLANG_VERSION')
53
- && function_exists('pll_current_language');
54
- }
55
-
56
- /**
57
- * @since 1.0
58
- * @return boolean
59
- */
60
- public function in_context()
61
- {
62
- return true;
63
- }
64
-
65
- /**
66
- * Get data from context
67
- *
68
- * @since 1.0
69
- * @return array
70
- */
71
- public function get_context_data()
72
- {
73
- $data = array($this->id);
74
- $data[] = pll_current_language();
75
- return $data;
76
- }
77
-
78
- /**
79
- * Get languages
80
- *
81
- * @global object $polylang
82
- * @since 1.0
83
- * @param array $args
84
- * @return array
85
- */
86
- protected function _get_content($args = array())
87
- {
88
- global $polylang;
89
-
90
- $langs = array();
91
-
92
- if (isset($polylang->model) && method_exists($polylang->model, 'get_languages_list')) {
93
- foreach ($polylang->model->get_languages_list(array('fields' => false)) as $lng) {
94
- $langs[$lng->slug] = $lng->name;
95
- }
96
- }
97
-
98
- if ($args['include']) {
99
- $langs = array_intersect_key($langs, array_flip($args['include']));
100
- }
101
- return $langs;
102
- }
103
-
104
- /**
105
- * Remove sidebars from multilingual list
106
- *
107
- * @since 1.0
108
- * @param array $post_types
109
- * @return array
110
- */
111
- public function remove_sidebar_multilingual($post_types)
112
- {
113
- foreach (WPCACore::types() as $post_type => $module) {
114
- unset($post_types[$post_type]);
115
- }
116
- return $post_types;
117
- }
118
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Polylang Module
14
+ * Requires version 1.7+
15
+ *
16
+ * Detects if current content is:
17
+ * a) in specific language
18
+ *
19
+ */
20
+ class WPCAModule_polylang extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
+
35
+ $this->query_name = 'cl';
36
+ }
37
+
38
+ public function initiate()
39
+ {
40
+ parent::initiate();
41
+ add_filter(
42
+ 'pll_get_post_types',
43
+ [$this,'remove_sidebar_multilingual']
44
+ );
45
+ }
46
+
47
+ /**
48
+ * @return bool
49
+ */
50
+ public function can_enable()
51
+ {
52
+ return defined('POLYLANG_VERSION')
53
+ && function_exists('pll_current_language');
54
+ }
55
+
56
+ /**
57
+ * @since 1.0
58
+ * @return boolean
59
+ */
60
+ public function in_context()
61
+ {
62
+ return true;
63
+ }
64
+
65
+ /**
66
+ * Get data from context
67
+ *
68
+ * @since 1.0
69
+ * @return array
70
+ */
71
+ public function get_context_data()
72
+ {
73
+ $data = [$this->id];
74
+ $data[] = pll_current_language();
75
+ return $data;
76
+ }
77
+
78
+ /**
79
+ * Get languages
80
+ *
81
+ * @global object $polylang
82
+ * @since 1.0
83
+ * @param array $args
84
+ * @return array
85
+ */
86
+ protected function _get_content($args = [])
87
+ {
88
+ global $polylang;
89
+
90
+ $langs = [];
91
+
92
+ if (isset($polylang->model) && method_exists($polylang->model, 'get_languages_list')) {
93
+ foreach ($polylang->model->get_languages_list(['fields' => false]) as $lng) {
94
+ $langs[$lng->slug] = $lng->name;
95
+ }
96
+ }
97
+
98
+ if ($args['include']) {
99
+ $langs = array_intersect_key($langs, array_flip($args['include']));
100
+ }
101
+ return $langs;
102
+ }
103
+
104
+ /**
105
+ * Remove sidebars from multilingual list
106
+ *
107
+ * @since 1.0
108
+ * @param array $post_types
109
+ * @return array
110
+ */
111
+ public function remove_sidebar_multilingual($post_types)
112
+ {
113
+ foreach (WPCACore::types() as $post_type => $module) {
114
+ unset($post_types[$post_type]);
115
+ }
116
+ return $post_types;
117
+ }
118
+ }
lib/wp-content-aware-engine/module/post_type.php CHANGED
@@ -1,123 +1,123 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
-
12
- /**
13
- *
14
- * Post Type Module
15
- *
16
- * Detects if current content is:
17
- * a) specific post type or specific post
18
- * b) specific post type archive or home
19
- *
20
- */
21
- class WPCAModule_post_type extends WPCAModule_Base
22
- {
23
-
24
- /**
25
- * @var string
26
- */
27
- protected $category = 'post_type';
28
-
29
- /**
30
- * Registered public post types
31
- *
32
- * @var array
33
- */
34
- private $_post_types;
35
-
36
- /**
37
- * Conditions to inherit from post ancestors
38
- * @var array
39
- */
40
- private $_post_ancestor_conditions;
41
-
42
- /**
43
- * Constructor
44
- */
45
- public function __construct()
46
- {
47
- parent::__construct('post_type', __('Post Types', WPCA_DOMAIN));
48
-
49
- $this->query_name = 'cp';
50
- }
51
-
52
- /**
53
- * Initiate module
54
- *
55
- * @since 2.0
56
- * @return void
57
- */
58
- public function initiate()
59
- {
60
- parent::initiate();
61
-
62
- add_action(
63
- 'transition_post_status',
64
- array($this,'post_ancestry_check'),
65
- 10,
66
- 3
67
- );
68
-
69
- if (is_admin()) {
70
- foreach ($this->post_types() as $post_type) {
71
- add_action(
72
- 'wp_ajax_wpca/module/'.$this->id.'-'.$post_type,
73
- array($this,'ajax_print_content')
74
- );
75
- }
76
- }
77
- }
78
-
79
- /**
80
- * Get content for sidebar editor
81
- *
82
- * @since 1.0
83
- * @param array $args
84
- * @return array
85
- */
86
- protected function _get_content($args = array())
87
- {
88
- $walk_tree = false;
89
- $start = ($args['paged'] - 1) * $args['posts_per_page'];
90
- $end = $start + $args['posts_per_page'];
91
-
92
- //WordPress searches in title and content by default
93
- //We want to search in title and slug
94
- if (!empty($args['search'])) {
95
- $exclude_query = '';
96
- if (!empty($args['post__not_in'])) {
97
- $exclude_query = ' AND ID NOT IN ('.implode(',', $args['post__not_in']).')';
98
- }
99
-
100
- $columns = array(
101
- array('post_title', 'LIKE', '%'.$args['search'].'%'),
102
- array('post_name', 'LIKE', '%'.$args['search'].'%'),
103
- );
104
-
105
- if (is_numeric($args['search'])) {
106
- $columns[] = array('ID', '=', $args['search']);
107
- }
108
-
109
- $where = array();
110
- $values = array();
111
- foreach ($columns as $column_value) {
112
- list($column, $operator, $value) = $column_value;
113
- $prepared_value = is_numeric($value) ? '%d' : '%s';
114
- $where[] = "{$column} {$operator} '{$prepared_value}'";
115
- $values[] = $value;
116
- }
117
-
118
- //Using unprepared (safe) exclude because WP is not good at parsing arrays
119
- global $wpdb;
120
- $posts = $wpdb->get_results($wpdb->prepare(
121
  "
122
  SELECT ID, post_title, post_type, post_parent, post_status, post_password
123
  FROM {$wpdb->posts}
@@ -127,431 +127,433 @@ class WPCAModule_post_type extends WPCAModule_Base
127
  $exclude_query
128
  ORDER BY post_title ASC
129
  LIMIT %d,%d
130
- ",
131
- array_merge($values, array(
132
- $args['post_type'],
133
- $start,
134
- $args['posts_per_page']
135
- ))
136
- ));
137
- } else {
138
- if (is_post_type_hierarchical($args['post_type']) && !isset($args['post__in'])) {
139
- $args['posts_per_page'] = -1;
140
- $args['paged'] = 0;
141
- $args['orderby'] = 'menu_order title';
142
-
143
- $walk_tree = true;
144
- }
145
- $query = new WP_Query($args);
146
- $posts = $query->posts;
147
- }
148
-
149
- $retval = array();
150
-
151
- if ($walk_tree) {
152
- $pages_sorted = array();
153
- foreach ($posts as $post) {
154
- $pages_sorted[$post->post_parent][] = $post;
155
- }
156
- $i = 0;
157
- $this->_walk_tree($pages_sorted, $pages_sorted[0], $i, $start, $end, 0, $retval);
158
- } else {
159
- foreach ($posts as $post) {
160
- $retval[$post->ID] = $this->post_title($post);
161
- }
162
- }
163
-
164
- return $retval;
165
- }
166
-
167
- /**
168
- * Get hierarchical content with level param
169
- *
170
- * @since 3.7.2
171
- * @param array $all_pages
172
- * @param array $pages
173
- * @param int $i
174
- * @param int $start
175
- * @param int $end
176
- * @param int $level
177
- * @param array &$retval
178
- * @return void
179
- */
180
- protected function _walk_tree($all_pages, $pages, &$i, $start, $end, $level, &$retval)
181
- {
182
- foreach ($pages as $page) {
183
- if ($i >= $end) {
184
- break;
185
- }
186
-
187
- if ($i >= $start) {
188
- $retval[] = array(
189
- 'id' => $page->ID,
190
- 'text' => $this->post_title($page),
191
- 'level' => $level
192
- );
193
- }
194
-
195
- $i++;
196
-
197
- if (isset($all_pages[$page->ID])) {
198
- $this->_walk_tree($all_pages, $all_pages[$page->ID], $i, $start, $end, $level + 1, $retval);
199
- }
200
- }
201
- }
202
-
203
- /**
204
- * Get registered public post types
205
- *
206
- * @since 4.0
207
- * @return array
208
- */
209
- public function post_types()
210
- {
211
- if (!$this->_post_types) {
212
- // List public post types
213
- foreach (get_post_types(array('public' => true), 'names') as $post_type) {
214
- $this->_post_types[$post_type] = $post_type;
215
- }
216
- }
217
- return $this->_post_types;
218
- }
219
-
220
- /**
221
- * Get data for condition group
222
- *
223
- * @since 2.0
224
- * @param array $group_data
225
- * @param int $post_id
226
- * @return array
227
- */
228
- public function get_group_data($group_data, $post_id)
229
- {
230
- $ids = get_post_custom_values(WPCACore::PREFIX . $this->id, $post_id);
231
- if ($ids) {
232
- $lookup = array_flip((array)$ids);
233
- foreach ($this->post_types() as $post_type) {
234
- $post_type_obj = get_post_type_object($post_type);
235
- $data = $this->get_content(array(
236
- 'include' => $ids,
237
- 'post_type' => $post_type
238
- ));
239
-
240
- if ($data || isset($lookup[$post_type])) {
241
- $placeholder = $post_type_obj->labels->all_items;
242
- switch ($post_type) {
243
- case 'post':
244
- $placeholder .= ' / '.__('Blog Page', WPCA_DOMAIN);
245
- break;
246
- case 'product':
247
- $placeholder .= ' / '.__('Shop Page', WPCA_DOMAIN);
248
- break;
249
- default:
250
- if ($post_type_obj->has_archive) {
251
- $placeholder .= ' / '.sprintf(__('%s Archives', WPCA_DOMAIN), $post_type_obj->labels->singular_name);
252
- }
253
- break;
254
- }
255
-
256
- $group_data[$this->id.'-'.$post_type] = array(
257
- 'label' => $post_type_obj->label,
258
- 'placeholder' => $placeholder,
259
- 'default_value' => $post_type
260
- );
261
-
262
- if ($data) {
263
- $group_data[$this->id.'-'.$post_type]['data'] = $data;
264
- }
265
- }
266
- }
267
- }
268
- return $group_data;
269
- }
270
-
271
- /**
272
- * Determine if content is relevant
273
- *
274
- * @since 1.0
275
- * @return boolean
276
- */
277
- public function in_context()
278
- {
279
- return ((is_singular() || is_home()) && !is_front_page()) || is_post_type_archive();
280
- }
281
-
282
- /**
283
- * Get data from context
284
- *
285
- * @since 1.0
286
- * @return array
287
- */
288
- public function get_context_data()
289
- {
290
- if (is_singular()) {
291
- return array(
292
- get_post_type(),
293
- get_queried_object_id()
294
- );
295
- }
296
-
297
- // Home has post as default post type
298
- $post_type = get_query_var('post_type');
299
- if (is_array($post_type)) {
300
- $post_type = reset($post_type);
301
- } elseif (!$post_type) {
302
- $post_type = 'post';
303
- }
304
-
305
- return array(
306
- $post_type
307
- );
308
- }
309
-
310
- /**
311
- * @param array $args
312
- *
313
- * @return array
314
- */
315
- protected function parse_query_args($args)
316
- {
317
- if (isset($args['item_object'])) {
318
- preg_match('/post_type-(.+)$/i', $args['item_object'], $matches);
319
- $post_type_name = isset($matches[1]) ? $matches[1] : '___';
320
- } else {
321
- $post_type_name = isset($args['post_type']) ? $args['post_type'] : 'category';
322
- }
323
-
324
- $exclude = array();
325
- if ($post_type_name == 'page' && 'page' == get_option('show_on_front')) {
326
- $exclude[] = intval(get_option('page_on_front'));
327
- $exclude[] = intval(get_option('page_for_posts'));
328
- }
329
-
330
- $post_status = array('publish','private','future','draft');
331
- if ($post_type_name == 'attachment') {
332
- $post_status = array('inherit');
333
- }
334
-
335
- $new_args = array(
336
- 'post__not_in' => $exclude,
337
- 'post_type' => $post_type_name,
338
- 'post_status' => $post_status,
339
- 'orderby' => 'title',
340
- 'order' => 'ASC',
341
- 'paged' => $args['paged'],
342
- 'posts_per_page' => $args['limit'],
343
- 'search' => $args['search'],
344
- 'ignore_sticky_posts' => true,
345
- 'update_post_term_cache' => false,
346
- 'suppress_filters' => true,
347
- 'no_found_rows' => true,
348
- );
349
-
350
- //future proof in case this is considered a bug https://core.trac.wordpress.org/ticket/28099
351
- if (!empty($args['include'])) {
352
- $new_args['post__in'] = $args['include'];
353
- }
354
-
355
- return $new_args;
356
- }
357
-
358
- /**
359
- * @since 2.0
360
- * @param array $list
361
- *
362
- * @return array
363
- */
364
- public function list_module($list)
365
- {
366
- foreach ($this->post_types() as $post_type) {
367
- $post_type_obj = get_post_type_object($post_type);
368
-
369
- $name = $post_type_obj->label;
370
- $placeholder = $post_type_obj->labels->all_items;
371
-
372
- switch ($post_type) {
373
- case 'post':
374
- $name .= ' / '.__('Blog', WPCA_DOMAIN);
375
- $placeholder .= ' / '.__('Blog Page', WPCA_DOMAIN);
376
- break;
377
- case 'product':
378
- $name .= ' / '.__('Shop', WPCA_DOMAIN);
379
- $placeholder .= ' / '.__('Shop Page', WPCA_DOMAIN);
380
- break;
381
- default:
382
- if ($post_type_obj->has_archive) {
383
- $placeholder .= ' / '.sprintf(__('%s Archives', WPCA_DOMAIN), $post_type_obj->labels->singular_name);
384
- }
385
- break;
386
- }
387
-
388
- $list[] = array(
389
- 'id' => $this->id.'-'.$post_type,
390
- 'text' => $name,
391
- 'placeholder' => $placeholder,
392
- 'default_value' => $post_type
393
- );
394
- }
395
- return $list;
396
- }
397
-
398
- /**
399
- * Get post title and state
400
- *
401
- * @since 3.7
402
- * @param WP_Post $post
403
- * @return string
404
- */
405
- public function post_title($post)
406
- {
407
- $post_states = array();
408
-
409
- if (!empty($post->post_password)) {
410
- $post_states['protected'] = __('Password protected');
411
- }
412
-
413
- if (is_sticky($post->ID)) {
414
- $post_states['sticky'] = __('Sticky');
415
- }
416
-
417
- switch ($post->post_status) {
418
- case 'private':
419
- $post_states['private'] = __('Private');
420
- break;
421
- case 'draft':
422
- $post_states['draft'] = __('Draft');
423
- break;
424
- case 'pending':
425
- /* translators: post state */
426
- $post_states['pending'] = _x('Pending', 'post state');
427
- break;
428
- case 'scheduled':
429
- $post_states['scheduled'] = __('Scheduled');
430
- break;
431
- }
432
-
433
- $post_title = $post->post_title ? $post->post_title : __('(no title)');
434
- $post_states = apply_filters('display_post_states', $post_states, $post);
435
-
436
- return $post_title . ' ' . ($post_states ? ' ('.implode(', ', $post_states).')' : '');
437
- }
438
-
439
- /**
440
- * Save data on POST
441
- *
442
- * @since 1.0
443
- * @param int $post_id
444
- * @return void
445
- */
446
- public function save_data($post_id)
447
- {
448
- $meta_key = WPCACore::PREFIX . $this->id;
449
- $old = array_flip(get_post_meta($post_id, $meta_key, false));
450
- $new = array();
451
-
452
- foreach ($this->post_types() as $post_type) {
453
- $id = $this->id.'-'.$post_type;
454
- if (isset($_POST['conditions'][$id])) {
455
- $new = array_merge($new, $_POST['conditions'][$id]);
456
- }
457
- }
458
-
459
- if ($new) {
460
- //$new = array_unique($new);
461
- // Skip existing data or insert new data
462
- foreach ($new as $new_single) {
463
- if (isset($old[$new_single])) {
464
- unset($old[$new_single]);
465
- } else {
466
- add_post_meta($post_id, $meta_key, $new_single);
467
- }
468
- }
469
- // Remove existing data that have not been skipped
470
- foreach ($old as $old_key => $old_value) {
471
- delete_post_meta($post_id, $meta_key, $old_key);
472
- }
473
- } elseif (!empty($old)) {
474
- // Remove any old values when $new is empty
475
- delete_post_meta($post_id, $meta_key);
476
- }
477
- }
478
-
479
- /**
480
- * Check if post ancestors have sidebar conditions
481
- *
482
- * @since 1.0
483
- * @param string $new_status
484
- * @param string $old_status
485
- * @param WP_Post $post
486
- * @return void
487
- */
488
- public function post_ancestry_check($new_status, $old_status, $post)
489
- {
490
- if (!WPCACore::types()->has($post->post_type) && $post->post_type != WPCACore::TYPE_CONDITION_GROUP && $post->post_parent) {
491
- $status = array(
492
- 'publish' => 1,
493
- 'private' => 1,
494
- 'future' => 1
495
- );
496
-
497
- // Only new posts are relevant
498
- if (!isset($status[$old_status]) && isset($status[$new_status])) {
499
- $post_type = get_post_type_object($post->post_type);
500
- if ($post_type->hierarchical && $post_type->public) {
501
-
502
-
503
- // Get sidebars with post ancestor wanting to auto-select post
504
- $query = new WP_Query(array(
505
- 'post_type' => WPCACore::TYPE_CONDITION_GROUP,
506
- 'post_status' => array(WPCACore::STATUS_OR,WPCACore::STATUS_EXCEPT,WPCACore::STATUS_PUBLISHED),
507
- 'meta_query' => array(
508
- 'relation' => 'AND',
509
- array(
510
- 'key' => WPCACore::PREFIX . 'autoselect',
511
- 'value' => 1,
512
- 'compare' => '='
513
- ),
514
- array(
515
- 'key' => WPCACore::PREFIX . $this->id,
516
- 'value' => get_post_ancestors($post),
517
- 'type' => 'numeric',
518
- 'compare' => 'IN'
519
- )
520
- )
521
- ));
522
-
523
- if ($query && $query->found_posts) {
524
-
525
- //Add conditions after Quick Select
526
- //otherwise they will be removed there
527
- $this->_post_ancestor_conditions = $query->posts;
528
- add_action(
529
- 'save_post_'.$post->post_type,
530
- array($this,'post_ancestry_add'),
531
- 99,
532
- 2
533
- );
534
- do_action('wpca/modules/auto-select/'.$this->category, $query->posts, $post);
535
- }
536
- }
537
- }
538
- }
539
- }
540
-
541
- /**
542
- * Add sidebar conditions from post ancestors
543
- *
544
- * @since 3.1.1
545
- * @param int $post_id
546
- * @param WP_Post $post
547
- * @return void
548
- */
549
- public function post_ancestry_add($post_id, $post)
550
- {
551
- if ($this->_post_ancestor_conditions) {
552
- foreach ($this->_post_ancestor_conditions as $condition) {
553
- add_post_meta($condition->ID, WPCACore::PREFIX.$this->id, $post_id);
554
- }
555
- }
556
- }
557
- }
 
 
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+
12
+ /**
13
+ *
14
+ * Post Type Module
15
+ *
16
+ * Detects if current content is:
17
+ * a) specific post type or specific post
18
+ * b) specific post type archive or home
19
+ *
20
+ */
21
+ class WPCAModule_post_type extends WPCAModule_Base
22
+ {
23
+
24
+ /**
25
+ * @var string
26
+ */
27
+ protected $category = 'post_type';
28
+
29
+ /**
30
+ * Registered public post types
31
+ *
32
+ * @var array
33
+ */
34
+ private $_post_types;
35
+
36
+ /**
37
+ * Conditions to inherit from post ancestors
38
+ * @var array
39
+ */
40
+ private $_post_ancestor_conditions;
41
+
42
+ /**
43
+ * Constructor
44
+ */
45
+ public function __construct()
46
+ {
47
+ parent::__construct('post_type', __('Post Types', WPCA_DOMAIN));
48
+
49
+ $this->query_name = 'cp';
50
+ }
51
+
52
+ /**
53
+ * Initiate module
54
+ *
55
+ * @since 2.0
56
+ * @return void
57
+ */
58
+ public function initiate()
59
+ {
60
+ parent::initiate();
61
+
62
+ add_action(
63
+ 'transition_post_status',
64
+ [$this,'post_ancestry_check'],
65
+ 10,
66
+ 3
67
+ );
68
+
69
+ if (is_admin()) {
70
+ foreach ($this->post_types() as $post_type) {
71
+ add_action(
72
+ 'wp_ajax_wpca/module/'.$this->id.'-'.$post_type,
73
+ [$this,'ajax_print_content']
74
+ );
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Get content for sidebar editor
81
+ *
82
+ * @since 1.0
83
+ * @param array $args
84
+ * @return array
85
+ */
86
+ protected function _get_content($args = [])
87
+ {
88
+ $walk_tree = false;
89
+ $start = ($args['paged'] - 1) * $args['posts_per_page'];
90
+ $end = $start + $args['posts_per_page'];
91
+
92
+ //WordPress searches in title and content by default
93
+ //We want to search in title and slug
94
+ if (!empty($args['search'])) {
95
+ $exclude_query = '';
96
+ if (!empty($args['post__not_in'])) {
97
+ $exclude_query = ' AND ID NOT IN ('.implode(',', $args['post__not_in']).')';
98
+ }
99
+
100
+ $columns = [
101
+ ['post_title', 'LIKE', '%'.$args['search'].'%'],
102
+ ['post_name', 'LIKE', '%'.$args['search'].'%'],
103
+ ];
104
+
105
+ if (is_numeric($args['search'])) {
106
+ $columns[] = ['ID', '=', $args['search']];
107
+ }
108
+
109
+ $where = [];
110
+ $values = [];
111
+ foreach ($columns as $column_value) {
112
+ list($column, $operator, $value) = $column_value;
113
+ $prepared_value = is_numeric($value) ? '%d' : '%s';
114
+ $where[] = "{$column} {$operator} '{$prepared_value}'";
115
+ $values[] = $value;
116
+ }
117
+
118
+ //Using unprepared (safe) exclude because WP is not good at parsing arrays
119
+ global $wpdb;
120
+ $posts = $wpdb->get_results($wpdb->prepare(
121
  "
122
  SELECT ID, post_title, post_type, post_parent, post_status, post_password
123
  FROM {$wpdb->posts}
127
  $exclude_query
128
  ORDER BY post_title ASC
129
  LIMIT %d,%d
130
+ ",
131
+ array_merge($values, [
132
+ $args['post_type'],
133
+ $start,
134
+ $args['posts_per_page']
135
+ ])
136
+ ));
137
+ } else {
138
+ if (is_post_type_hierarchical($args['post_type']) && !isset($args['post__in'])) {
139
+ $args['posts_per_page'] = -1;
140
+ $args['paged'] = 0;
141
+ $args['orderby'] = 'menu_order title';
142
+
143
+ $walk_tree = true;
144
+ }
145
+ $query = new WP_Query($args);
146
+ $posts = $query->posts;
147
+ }
148
+
149
+ $retval = [];
150
+
151
+ if ($walk_tree) {
152
+ $pages_sorted = [];
153
+ foreach ($posts as $post) {
154
+ $pages_sorted[$post->post_parent][] = $post;
155
+ }
156
+ $i = 0;
157
+ $this->_walk_tree($pages_sorted, $pages_sorted[0], $i, $start, $end, 0, $retval);
158
+ } else {
159
+ foreach ($posts as $post) {
160
+ $retval[$post->ID] = $this->post_title($post);
161
+ }
162
+ }
163
+
164
+ return $retval;
165
+ }
166
+
167
+ /**
168
+ * Get hierarchical content with level param
169
+ *
170
+ * @since 3.7.2
171
+ * @param array $all_pages
172
+ * @param array $pages
173
+ * @param int $i
174
+ * @param int $start
175
+ * @param int $end
176
+ * @param int $level
177
+ * @param array &$retval
178
+ * @return void
179
+ */
180
+ protected function _walk_tree($all_pages, $pages, &$i, $start, $end, $level, &$retval)
181
+ {
182
+ foreach ($pages as $page) {
183
+ if ($i >= $end) {
184
+ break;
185
+ }
186
+
187
+ if ($i >= $start) {
188
+ $retval[] = [
189
+ 'id' => $page->ID,
190
+ 'text' => $this->post_title($page),
191
+ 'level' => $level
192
+ ];
193
+ }
194
+
195
+ $i++;
196
+
197
+ if (isset($all_pages[$page->ID])) {
198
+ $this->_walk_tree($all_pages, $all_pages[$page->ID], $i, $start, $end, $level + 1, $retval);
199
+ }
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Get registered public post types
205
+ *
206
+ * @since 4.0
207
+ * @return array
208
+ */
209
+ public function post_types()
210
+ {
211
+ if (!$this->_post_types) {
212
+ // List public post types
213
+ foreach (get_post_types(['public' => true], 'names') as $post_type) {
214
+ $this->_post_types[$post_type] = $post_type;
215
+ }
216
+ }
217
+ return $this->_post_types;
218
+ }
219
+
220
+ /**
221
+ * Get data for condition group
222
+ *
223
+ * @since 2.0
224
+ * @param array $group_data
225
+ * @param int $post_id
226
+ * @return array
227
+ */
228
+ public function get_group_data($group_data, $post_id)
229
+ {
230
+ $ids = get_post_custom_values(WPCACore::PREFIX . $this->id, $post_id);
231
+ if ($ids) {
232
+ $lookup = array_flip((array)$ids);
233
+ foreach ($this->post_types() as $post_type) {
234
+ $post_type_obj = get_post_type_object($post_type);
235
+ $data = $this->get_content([
236
+ 'include' => $ids,
237
+ 'post_type' => $post_type
238
+ ]);
239
+
240
+ if ($data || isset($lookup[$post_type])) {
241
+ $placeholder = $post_type_obj->labels->all_items;
242
+ switch ($post_type) {
243
+ case 'post':
244
+ $placeholder .= ' / '.__('Blog Page', WPCA_DOMAIN);
245
+ break;
246
+ case 'product':
247
+ $placeholder .= ' / '.__('Shop Page', WPCA_DOMAIN);
248
+ break;
249
+ default:
250
+ if ($post_type_obj->has_archive) {
251
+ $placeholder .= ' / '.sprintf(__('%s Archives', WPCA_DOMAIN), $post_type_obj->labels->singular_name);
252
+ }
253
+ break;
254
+ }
255
+
256
+ $group_data[$this->id.'-'.$post_type] = [
257
+ 'label' => $post_type_obj->label,
258
+ 'placeholder' => $placeholder,
259
+ 'default_value' => $post_type
260
+ ];
261
+
262
+ if ($data) {
263
+ $group_data[$this->id.'-'.$post_type]['data'] = $data;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ return $group_data;
269
+ }
270
+
271
+ /**
272
+ * Determine if content is relevant
273
+ *
274
+ * @since 1.0
275
+ * @return boolean
276
+ */
277
+ public function in_context()
278
+ {
279
+ return ((is_singular() || is_home()) && !is_front_page()) || is_post_type_archive();
280
+ }
281
+
282
+ /**
283
+ * Get data from context
284
+ *
285
+ * @since 1.0
286
+ * @return array
287
+ */
288
+ public function get_context_data()
289
+ {
290
+ if (is_singular()) {
291
+ return [
292
+ get_post_type(),
293
+ get_queried_object_id()
294
+ ];
295
+ }
296
+
297
+ // Home has post as default post type
298
+ $post_type = get_query_var('post_type');
299
+ if (is_array($post_type)) {
300
+ $post_type = reset($post_type);
301
+ } elseif (!$post_type) {
302
+ $post_type = 'post';
303
+ }
304
+
305
+ return [
306
+ $post_type
307
+ ];
308
+ }
309
+
310
+ /**
311
+ * @param array $args
312
+ *
313
+ * @return array
314
+ */
315
+ protected function parse_query_args($args)
316
+ {
317
+ if (isset($args['item_object'])) {
318
+ preg_match('/post_type-(.+)$/i', $args['item_object'], $matches);
319
+ $post_type_name = isset($matches[1]) ? $matches[1] : '___';
320
+ } else {
321
+ $post_type_name = isset($args['post_type']) ? $args['post_type'] : 'category';
322
+ }
323
+
324
+ $exclude = [];
325
+ if ($post_type_name == 'page' && 'page' == get_option('show_on_front')) {
326
+ $exclude[] = intval(get_option('page_on_front'));
327
+ $exclude[] = intval(get_option('page_for_posts'));
328
+ }
329
+
330
+ $post_status = ['publish','private','future','draft'];
331
+ if ($post_type_name == 'attachment') {
332
+ $post_status = ['inherit'];
333
+ }
334
+
335
+ $new_args = [
336
+ 'post__not_in' => $exclude,
337
+ 'post_type' => $post_type_name,
338
+ 'post_status' => $post_status,
339
+ 'orderby' => 'title',
340
+ 'order' => 'ASC',
341
+ 'paged' => $args['paged'],
342
+ 'posts_per_page' => $args['limit'],
343
+ 'search' => $args['search'],
344
+ 'ignore_sticky_posts' => true,
345
+ 'update_post_term_cache' => false,
346
+ 'suppress_filters' => true,
347
+ 'no_found_rows' => true,
348
+ ];
349
+
350
+ //future proof in case this is considered a bug https://core.trac.wordpress.org/ticket/28099
351
+ if (!empty($args['include'])) {
352
+ $new_args['post__in'] = $args['include'];
353
+ }
354
+
355
+ return $new_args;
356
+ }
357
+
358
+ /**
359
+ * @since 2.0
360
+ * @param array $list
361
+ *
362
+ * @return array
363
+ */
364
+ public function list_module($list)
365
+ {
366
+ foreach ($this->post_types() as $post_type) {
367
+ $post_type_obj = get_post_type_object($post_type);
368
+
369
+ $name = $post_type_obj->label;
370
+ $placeholder = $post_type_obj->labels->all_items;
371
+
372
+ switch ($post_type) {
373
+ case 'post':
374
+ $name .= ' / '.__('Blog', WPCA_DOMAIN);
375
+ $placeholder .= ' / '.__('Blog Page', WPCA_DOMAIN);
376
+ break;
377
+ case 'product':
378
+ $name .= ' / '.__('Shop', WPCA_DOMAIN);
379
+ $placeholder .= ' / '.__('Shop Page', WPCA_DOMAIN);
380
+ break;
381
+ default:
382
+ if ($post_type_obj->has_archive) {
383
+ $placeholder .= ' / '.sprintf(__('%s Archives', WPCA_DOMAIN), $post_type_obj->labels->singular_name);
384
+ }
385
+ break;
386
+ }
387
+
388
+ $list[] = [
389
+ 'id' => $this->id.'-'.$post_type,
390
+ 'text' => $name,
391
+ 'placeholder' => $placeholder,
392
+ 'default_value' => $post_type
393
+ ];
394
+ }
395
+ return $list;
396
+ }
397
+
398
+ /**
399
+ * Get post title and state
400
+ *
401
+ * @since 3.7
402
+ * @param WP_Post $post
403
+ * @return string
404
+ */
405
+ public function post_title($post)
406
+ {
407
+ $post_states = [];
408
+
409
+ if (!empty($post->post_password)) {
410
+ $post_states['protected'] = __('Password protected');
411
+ }
412
+
413
+ if (is_sticky($post->ID)) {
414
+ $post_states['sticky'] = __('Sticky');
415
+ }
416
+
417
+ switch ($post->post_status) {
418
+ case 'private':
419
+ $post_states['private'] = __('Private');
420
+ break;
421
+ case 'draft':
422
+ $post_states['draft'] = __('Draft');
423
+ break;
424
+ case 'pending':
425
+ /* translators: post state */
426
+ $post_states['pending'] = _x('Pending', 'post state');
427
+ break;
428
+ case 'scheduled':
429
+ $post_states['scheduled'] = __('Scheduled');
430
+ break;
431
+ default:
432
+ break;
433
+ }
434
+
435
+ $post_title = $post->post_title ? $post->post_title : __('(no title)');
436
+ $post_states = apply_filters('display_post_states', $post_states, $post);
437
+
438
+ return $post_title . ' ' . ($post_states ? ' ('.implode(', ', $post_states).')' : '');
439
+ }
440
+
441
+ /**
442
+ * Save data on POST
443
+ *
444
+ * @since 1.0
445
+ * @param int $post_id
446
+ * @return void
447
+ */
448
+ public function save_data($post_id)
449
+ {
450
+ $meta_key = WPCACore::PREFIX . $this->id;
451
+ $old = array_flip(get_post_meta($post_id, $meta_key, false));
452
+ $new = [];
453
+
454
+ foreach ($this->post_types() as $post_type) {
455
+ $id = $this->id.'-'.$post_type;
456
+ if (isset($_POST['conditions'][$id])) {
457
+ $new = array_merge($new, $_POST['conditions'][$id]);
458
+ }
459
+ }
460
+
461
+ if ($new) {
462
+ //$new = array_unique($new);
463
+ // Skip existing data or insert new data
464
+ foreach ($new as $new_single) {
465
+ if (isset($old[$new_single])) {
466
+ unset($old[$new_single]);
467
+ } else {
468
+ add_post_meta($post_id, $meta_key, $new_single);
469
+ }
470
+ }
471
+ // Remove existing data that have not been skipped
472
+ foreach ($old as $old_key => $old_value) {
473
+ delete_post_meta($post_id, $meta_key, $old_key);
474
+ }
475
+ } elseif (!empty($old)) {
476
+ // Remove any old values when $new is empty
477
+ delete_post_meta($post_id, $meta_key);
478
+ }
479
+ }
480
+
481
+ /**
482
+ * Check if post ancestors have sidebar conditions
483
+ *
484
+ * @since 1.0
485
+ * @param string $new_status
486
+ * @param string $old_status
487
+ * @param WP_Post $post
488
+ * @return void
489
+ */
490
+ public function post_ancestry_check($new_status, $old_status, $post)
491
+ {
492
+ if (!WPCACore::types()->has($post->post_type) && $post->post_type != WPCACore::TYPE_CONDITION_GROUP && $post->post_parent) {
493
+ $status = [
494
+ 'publish' => 1,
495
+ 'private' => 1,
496
+ 'future' => 1
497
+ ];
498
+
499
+ // Only new posts are relevant
500
+ if (!isset($status[$old_status]) && isset($status[$new_status])) {
501
+ $post_type = get_post_type_object($post->post_type);
502
+ if ($post_type->hierarchical && $post_type->public) {
503
+
504
+
505
+ // Get sidebars with post ancestor wanting to auto-select post
506
+ $query = new WP_Query([
507
+ 'post_type' => WPCACore::TYPE_CONDITION_GROUP,
508
+ 'post_status' => [WPCACore::STATUS_OR,WPCACore::STATUS_EXCEPT,WPCACore::STATUS_PUBLISHED],
509
+ 'meta_query' => [
510
+ 'relation' => 'AND',
511
+ [
512
+ 'key' => WPCACore::PREFIX . 'autoselect',
513
+ 'value' => 1,
514
+ 'compare' => '='
515
+ ],
516
+ [
517
+ 'key' => WPCACore::PREFIX . $this->id,
518
+ 'value' => get_post_ancestors($post),
519
+ 'type' => 'numeric',
520
+ 'compare' => 'IN'
521
+ ]
522
+ ]
523
+ ]);
524
+
525
+ if ($query && $query->found_posts) {
526
+
527
+ //Add conditions after Quick Select
528
+ //otherwise they will be removed there
529
+ $this->_post_ancestor_conditions = $query->posts;
530
+ add_action(
531
+ 'save_post_'.$post->post_type,
532
+ [$this,'post_ancestry_add'],
533
+ 99,
534
+ 2
535
+ );
536
+ do_action('wpca/modules/auto-select/'.$this->category, $query->posts, $post);
537
+ }
538
+ }
539
+ }
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Add sidebar conditions from post ancestors
545
+ *
546
+ * @since 3.1.1
547
+ * @param int $post_id
548
+ * @param WP_Post $post
549
+ * @return void
550
+ */
551
+ public function post_ancestry_add($post_id, $post)
552
+ {
553
+ if ($this->_post_ancestor_conditions) {
554
+ foreach ($this->_post_ancestor_conditions as $condition) {
555
+ add_post_meta($condition->ID, WPCACore::PREFIX.$this->id, $post_id);
556
+ }
557
+ }
558
+ }
559
+ }
lib/wp-content-aware-engine/module/qtranslate.php CHANGED
@@ -1,111 +1,111 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * qTranslate X Module
14
- * Requires version v3.4.6.4+
15
- *
16
- * Detects if current content is:
17
- * a) in specific language
18
- *
19
- */
20
- class WPCAModule_qtranslate extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
-
35
- $this->query_name = 'cl';
36
- }
37
-
38
- public function initiate()
39
- {
40
- parent::initiate();
41
- if (is_admin()) {
42
- global $q_config;
43
- //Disable multilanguage
44
- if (is_array($q_config['post_type_excluded'])) {
45
- foreach (WPCACore::types() as $name => $modules) {
46
- $q_config['post_type_excluded'][] = $name;
47
- }
48
- $q_config['post_type_excluded'][] = WPCACore::TYPE_CONDITION_GROUP;
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * @return bool
55
- */
56
- public function can_enable()
57
- {
58
- return defined('QTX_VERSION')
59
- && function_exists('qtranxf_getLanguage');
60
- }
61
-
62
- /**
63
- * @since 1.0
64
- * @return boolean
65
- */
66
- public function in_context()
67
- {
68
- return true;
69
- }
70
-
71
- /**
72
- * Get data from context
73
- *
74
- * @since 1.0
75
- * @return array
76
- */
77
- public function get_context_data()
78
- {
79
- $data = array($this->id);
80
- $data[] = qtranxf_getLanguage();
81
- return $data;
82
- }
83
-
84
- /**
85
- * Get content for sidebar edit screen
86
- *
87
- * @global array $q_config
88
- * @since 1.0
89
- * @param array $args
90
- * @return array
91
- */
92
- protected function _get_content($args = array())
93
- {
94
- global $q_config;
95
-
96
- $langs = array();
97
-
98
- if (isset($q_config['language_name'])) {
99
- foreach ((array)get_option('qtranslate_enabled_languages') as $lng) {
100
- if (isset($q_config['language_name'][$lng])) {
101
- $langs[$lng] = $q_config['language_name'][$lng];
102
- }
103
- }
104
- }
105
-
106
- if ($args['include']) {
107
- $langs = array_intersect_key($langs, array_flip($args['include']));
108
- }
109
- return $langs;
110
- }
111
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * qTranslate X Module
14
+ * Requires version v3.4.6.4+
15
+ *
16
+ * Detects if current content is:
17
+ * a) in specific language
18
+ *
19
+ */
20
+ class WPCAModule_qtranslate extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
+
35
+ $this->query_name = 'cl';
36
+ }
37
+
38
+ public function initiate()
39
+ {
40
+ parent::initiate();
41
+ if (is_admin()) {
42
+ global $q_config;
43
+ //Disable multilanguage
44
+ if (is_array($q_config['post_type_excluded'])) {
45
+ foreach (WPCACore::types() as $name => $modules) {
46
+ $q_config['post_type_excluded'][] = $name;
47
+ }
48
+ $q_config['post_type_excluded'][] = WPCACore::TYPE_CONDITION_GROUP;
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @return bool
55
+ */
56
+ public function can_enable()
57
+ {
58
+ return defined('QTX_VERSION')
59
+ && function_exists('qtranxf_getLanguage');
60
+ }
61
+
62
+ /**
63
+ * @since 1.0
64
+ * @return boolean
65
+ */
66
+ public function in_context()
67
+ {
68
+ return true;
69
+ }
70
+
71
+ /**
72
+ * Get data from context
73
+ *
74
+ * @since 1.0
75
+ * @return array
76
+ */
77
+ public function get_context_data()
78
+ {
79
+ $data = [$this->id];
80
+ $data[] = qtranxf_getLanguage();
81
+ return $data;
82
+ }
83
+
84
+ /**
85
+ * Get content for sidebar edit screen
86
+ *
87
+ * @global array $q_config
88
+ * @since 1.0
89
+ * @param array $args
90
+ * @return array
91
+ */
92
+ protected function _get_content($args = [])
93
+ {
94
+ global $q_config;
95
+
96
+ $langs = [];
97
+
98
+ if (isset($q_config['language_name'])) {
99
+ foreach ((array)get_option('qtranslate_enabled_languages') as $lng) {
100
+ if (isset($q_config['language_name'][$lng])) {
101
+ $langs[$lng] = $q_config['language_name'][$lng];
102
+ }
103
+ }
104
+ }
105
+
106
+ if ($args['include']) {
107
+ $langs = array_intersect_key($langs, array_flip($args['include']));
108
+ }
109
+ return $langs;
110
+ }
111
+ }
lib/wp-content-aware-engine/module/static.php CHANGED
@@ -1,106 +1,106 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Static Pages Module
14
- *
15
- * Detects if current content is:
16
- * a) front page
17
- * b) search results
18
- * c) 404 page
19
- *
20
- */
21
- class WPCAModule_static extends WPCAModule_Base
22
- {
23
-
24
- /**
25
- * Cached search string
26
- * @var string
27
- */
28
- protected $search_string;
29
-
30
- /**
31
- * Constructor
32
- */
33
- public function __construct()
34
- {
35
- parent::__construct('static', __('Special Pages', WPCA_DOMAIN));
36
-
37
- $this->query_name = 'cs';
38
- }
39
-
40
- /**
41
- * Get static content
42
- *
43
- * @since 1.0
44
- * @param array $args
45
- * @return array
46
- */
47
- protected function _get_content($args = array())
48
- {
49
- $static = array(
50
- 'front-page' => __('Front Page', WPCA_DOMAIN),
51
- 'search' => __('Search Results', WPCA_DOMAIN),
52
- '404' => __('404 Page', WPCA_DOMAIN)
53
- );
54
-
55
- if ($args['include']) {
56
- $static = array_intersect_key($static, array_flip($args['include']));
57
- } elseif ($args['search']) {
58
- $this->search_string = $args['search'];
59
- $static = array_filter($static, array($this,'_filter_search'));
60
- }
61
- return $static;
62
- }
63
-
64
- /**
65
- * Filter content based on search
66
- *
67
- * @since 2.0
68
- * @param string $value
69
- * @return boolean
70
- */
71
- protected function _filter_search($value)
72
- {
73
- return mb_stripos($value, $this->search_string) !== false;
74
- }
75
-
76
- /**
77
- * Determine if content is relevant
78
- *
79
- * @since 1.0
80
- * @return boolean
81
- */
82
- public function in_context()
83
- {
84
- return is_front_page() || is_search() || is_404();
85
- }
86
-
87
- /**
88
- * Get data from context
89
- *
90
- * @since 1.0
91
- * @return array
92
- */
93
- public function get_context_data()
94
- {
95
- if (is_front_page()) {
96
- $val = 'front-page';
97
- } elseif (is_search()) {
98
- $val = 'search';
99
- } else {
100
- $val = '404';
101
- }
102
- return array(
103
- $val
104
- );
105
- }
106
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Static Pages Module
14
+ *
15
+ * Detects if current content is:
16
+ * a) front page
17
+ * b) search results
18
+ * c) 404 page
19
+ *
20
+ */
21
+ class WPCAModule_static extends WPCAModule_Base
22
+ {
23
+
24
+ /**
25
+ * Cached search string
26
+ * @var string
27
+ */
28
+ protected $search_string;
29
+
30
+ /**
31
+ * Constructor
32
+ */
33
+ public function __construct()
34
+ {
35
+ parent::__construct('static', __('Special Pages', WPCA_DOMAIN));
36
+
37
+ $this->query_name = 'cs';
38
+ }
39
+
40
+ /**
41
+ * Get static content
42
+ *
43
+ * @since 1.0
44
+ * @param array $args
45
+ * @return array
46
+ */
47
+ protected function _get_content($args = [])
48
+ {
49
+ $static = [
50
+ 'front-page' => __('Front Page', WPCA_DOMAIN),
51
+ 'search' => __('Search Results', WPCA_DOMAIN),
52
+ '404' => __('404 Page', WPCA_DOMAIN)
53
+ ];
54
+
55
+ if ($args['include']) {
56
+ $static = array_intersect_key($static, array_flip($args['include']));
57
+ } elseif ($args['search']) {
58
+ $this->search_string = $args['search'];
59
+ $static = array_filter($static, [$this,'_filter_search']);
60
+ }
61
+ return $static;
62
+ }
63
+
64
+ /**
65
+ * Filter content based on search
66
+ *
67
+ * @since 2.0
68
+ * @param string $value
69
+ * @return boolean
70
+ */
71
+ protected function _filter_search($value)
72
+ {
73
+ return mb_stripos($value, $this->search_string) !== false;
74
+ }
75
+
76
+ /**
77
+ * Determine if content is relevant
78
+ *
79
+ * @since 1.0
80
+ * @return boolean
81
+ */
82
+ public function in_context()
83
+ {
84
+ return is_front_page() || is_search() || is_404();
85
+ }
86
+
87
+ /**
88
+ * Get data from context
89
+ *
90
+ * @since 1.0
91
+ * @return array
92
+ */
93
+ public function get_context_data()
94
+ {
95
+ if (is_front_page()) {
96
+ $val = 'front-page';
97
+ } elseif (is_search()) {
98
+ $val = 'search';
99
+ } else {
100
+ $val = '404';
101
+ }
102
+ return [
103
+ $val
104
+ ];
105
+ }
106
+ }
lib/wp-content-aware-engine/module/taxonomy.php CHANGED
@@ -19,6 +19,12 @@ defined('ABSPATH') || exit;
19
  */
20
  class WPCAModule_taxonomy extends WPCAModule_Base
21
  {
 
 
 
 
 
 
22
 
23
  /**
24
  * @var string
@@ -30,7 +36,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
30
  *
31
  * @var array
32
  */
33
- private $taxonomy_objects = array();
34
 
35
  /**
36
  * Terms of a given singular
@@ -60,7 +66,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
60
  parent::initiate();
61
  add_action(
62
  'created_term',
63
- array($this,'term_ancestry_check'),
64
  10,
65
  3
66
  );
@@ -69,7 +75,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
69
  foreach ($this->_get_taxonomies() as $taxonomy) {
70
  add_action(
71
  'wp_ajax_wpca/module/'.$this->id.'-'.$taxonomy->name,
72
- array($this,'ajax_print_content')
73
  );
74
  }
75
  }
@@ -85,8 +91,8 @@ class WPCAModule_taxonomy extends WPCAModule_Base
85
  {
86
  if (is_singular()) {
87
  $tax = $this->_get_taxonomies();
88
- $this->post_terms = array();
89
- $this->post_taxonomies = array();
90
 
91
  // Check if content has any taxonomies supported
92
  foreach (get_object_taxonomies(get_post_type()) as $taxonomy) {
@@ -104,32 +110,11 @@ class WPCAModule_taxonomy extends WPCAModule_Base
104
  }
105
  }
106
  }
107
- return !!$this->post_terms;
108
  }
109
  return is_tax() || is_category() || is_tag();
110
  }
111
 
112
- /**
113
- * Remove posts if they have data from
114
- * other contexts (meaning conditions arent met)
115
- *
116
- * @since 3.2
117
- * @param array $posts
118
- * @return array
119
- */
120
- public function filter_excluded_context($posts)
121
- {
122
- $posts = parent::filter_excluded_context($posts);
123
- if ($posts) {
124
- global $wpdb;
125
- $obj_w_tags = $wpdb->get_col("SELECT object_id FROM $wpdb->term_relationships WHERE object_id IN (".implode(',', array_keys($posts)).') GROUP BY object_id');
126
- if ($obj_w_tags) {
127
- $posts = array_diff_key($posts, array_flip($obj_w_tags));
128
- }
129
- }
130
- return $posts;
131
- }
132
-
133
  /**
134
  * Query join
135
  *
@@ -157,16 +142,19 @@ class WPCAModule_taxonomy extends WPCAModule_Base
157
  //In more recent WP versions, term_id = term_tax_id
158
  //but term_tax_id has always been unique
159
  if (is_singular()) {
160
- $terms = array();
161
  foreach ($this->post_terms as $term) {
162
  $terms[] = $term->term_taxonomy_id;
163
  }
164
-
165
- return '(term.term_taxonomy_id IS NULL OR term.term_taxonomy_id IN ('.implode(',', $terms).")) AND ($name.meta_value IS NULL OR $name.meta_value IN('".implode("','", $this->post_taxonomies)."'))";
 
 
 
166
  }
167
- $term = get_queried_object();
168
 
169
- return "(term.term_taxonomy_id IS NULL OR term.term_taxonomy_id = '".$term->term_taxonomy_id."') AND ($name.meta_value IS NULL OR $name.meta_value = '".$term->taxonomy."')";
 
170
  }
171
 
172
  /**
@@ -176,16 +164,16 @@ class WPCAModule_taxonomy extends WPCAModule_Base
176
  * @param array $args
177
  * @return array
178
  */
179
- protected function _get_content($args = array())
180
  {
181
- $total_items = wp_count_terms($args['taxonomy'], array(
182
  'hide_empty' => $args['hide_empty']
183
- ));
184
 
185
  $start = $args['offset'];
186
  $end = $start + $args['number'];
187
  $walk_tree = false;
188
- $retval = array();
189
 
190
  if ($total_items) {
191
  $taxonomy = get_taxonomy($args['taxonomy']);
@@ -200,7 +188,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
200
  $terms = new WP_Term_Query($args);
201
 
202
  if ($walk_tree) {
203
- $sorted_terms = array();
204
  foreach ($terms->terms as $term) {
205
  $sorted_terms[$term->parent][] = $term;
206
  }
@@ -241,11 +229,11 @@ class WPCAModule_taxonomy extends WPCAModule_Base
241
  }
242
 
243
  if ($i >= $start) {
244
- $retval[] = array(
245
  'id' => $term->term_id,
246
  'text' => htmlspecialchars_decode($term->name),
247
  'level' => $level
248
- );
249
  }
250
 
251
  $i++;
@@ -266,7 +254,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
266
  {
267
  // List public taxonomies
268
  if (empty($this->taxonomy_objects)) {
269
- foreach (get_taxonomies(array('public' => true), 'objects') as $tax) {
270
  $this->taxonomy_objects[$tax->name] = $tax;
271
  }
272
  if (defined('POLYLANG_VERSION')) {
@@ -296,7 +284,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
296
  // 'update_term_meta_cache' => false
297
  // )
298
  );
299
- $terms_by_tax = array();
300
  foreach ($terms as $term) {
301
  $terms_by_tax[$term->taxonomy][] = $term;
302
  }
@@ -310,7 +298,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
310
  $group_data[$this->id.'-'.$taxonomy->name]['label'] = $group_data[$this->id.'-'.$taxonomy->name]['text'];
311
 
312
  if ($posts) {
313
- $retval = array();
314
 
315
  //Hierarchical taxonomies use ids instead of slugs
316
  //see http://codex.wordpress.org/Function_Reference/wp_set_post_objects
@@ -333,7 +321,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
333
  */
334
  protected function get_title_count()
335
  {
336
- $title_count = array();
337
  foreach ($this->_get_taxonomies() as $taxonomy) {
338
  if (!isset($title_count[$taxonomy->label])) {
339
  $title_count[$taxonomy->label] = 0;
@@ -354,11 +342,11 @@ class WPCAModule_taxonomy extends WPCAModule_Base
354
  $label .= ' (' . $post_type->label . ')';
355
  }
356
 
357
- return array(
358
  'text' => $label,
359
  'placeholder' => $placeholder,
360
  'default_value' => $taxonomy->name
361
- );
362
  }
363
 
364
  /**
@@ -393,7 +381,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
393
  $taxonomy_name = 'category';
394
  }
395
 
396
- return array(
397
  'include' => $args['include'],
398
  'taxonomy' => $taxonomy_name,
399
  'number' => $args['limit'],
@@ -403,7 +391,7 @@ class WPCAModule_taxonomy extends WPCAModule_Base
403
  'search' => $args['search'],
404
  'hide_empty' => false,
405
  'update_term_meta_cache' => false
406
- );
407
  }
408
 
409
  /**
@@ -415,18 +403,19 @@ class WPCAModule_taxonomy extends WPCAModule_Base
415
  */
416
  public function save_data($post_id)
417
  {
418
- //parent::save_data($post_id);
419
  $meta_key = WPCACore::PREFIX . $this->id;
420
  $old = array_flip(get_post_meta($post_id, $meta_key, false));
421
  $tax_input = $_POST['conditions'];
422
 
 
 
423
  //Save terms
424
  //Loop through each public taxonomy
425
  foreach ($this->_get_taxonomies() as $taxonomy) {
426
 
427
  //If no terms, maybe delete old ones
428
  if (!isset($tax_input[$this->id.'-'.$taxonomy->name])) {
429
- $terms = array();
430
  if (isset($old[$taxonomy->name])) {
431
  delete_post_meta($post_id, $meta_key, $taxonomy->name);
432
  }
@@ -452,8 +441,18 @@ class WPCAModule_taxonomy extends WPCAModule_Base
452
  }
453
  }
454
 
 
 
 
 
455
  wp_set_object_terms($post_id, $terms, $taxonomy->name);
456
  }
 
 
 
 
 
 
457
  }
458
 
459
  /**
@@ -472,25 +471,25 @@ class WPCAModule_taxonomy extends WPCAModule_Base
472
 
473
  if ($term->parent != '0') {
474
  // Get sidebars with term ancestor wanting to auto-select term
475
- $query = new WP_Query(array(
476
  'post_type' => WPCACore::TYPE_CONDITION_GROUP,
477
- 'post_status' => array(WPCACore::STATUS_OR,WPCACore::STATUS_EXCEPT,WPCACore::STATUS_PUBLISHED),
478
- 'meta_query' => array(
479
- array(
480
  'key' => WPCACore::PREFIX . 'autoselect',
481
  'value' => 1,
482
  'compare' => '='
483
- )
484
- ),
485
- 'tax_query' => array(
486
- array(
487
  'taxonomy' => $taxonomy,
488
  'field' => 'id',
489
  'terms' => get_ancestors($term_id, $taxonomy),
490
  'include_children' => false
491
- )
492
- )
493
- ));
494
  if ($query && $query->found_posts) {
495
  foreach ($query->posts as $post) {
496
  wp_set_post_terms($post->ID, $term_id, $taxonomy, true);
19
  */
20
  class WPCAModule_taxonomy extends WPCAModule_Base
21
  {
22
+ /**
23
+ * when condition has select terms,
24
+ * set this value in postmeta
25
+ * @see parent::filter_excluded_context()
26
+ */
27
+ const VALUE_HAS_TERMS = '-1';
28
 
29
  /**
30
  * @var string
36
  *
37
  * @var array
38
  */
39
+ private $taxonomy_objects = [];
40
 
41
  /**
42
  * Terms of a given singular
66
  parent::initiate();
67
  add_action(
68
  'created_term',
69
+ [$this,'term_ancestry_check'],
70
  10,
71
  3
72
  );
75
  foreach ($this->_get_taxonomies() as $taxonomy) {
76
  add_action(
77
  'wp_ajax_wpca/module/'.$this->id.'-'.$taxonomy->name,
78
+ [$this,'ajax_print_content']
79
  );
80
  }
81
  }
91
  {
92
  if (is_singular()) {
93
  $tax = $this->_get_taxonomies();
94
+ $this->post_terms = [];
95
+ $this->post_taxonomies = [];
96
 
97
  // Check if content has any taxonomies supported
98
  foreach (get_object_taxonomies(get_post_type()) as $taxonomy) {
110
  }
111
  }
112
  }
113
+ return !empty($this->post_terms);
114
  }
115
  return is_tax() || is_category() || is_tag();
116
  }
117
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  /**
119
  * Query join
120
  *
142
  //In more recent WP versions, term_id = term_tax_id
143
  //but term_tax_id has always been unique
144
  if (is_singular()) {
145
+ $terms = [];
146
  foreach ($this->post_terms as $term) {
147
  $terms[] = $term->term_taxonomy_id;
148
  }
149
+ $tax = $this->post_taxonomies;
150
+ } else {
151
+ $term = get_queried_object();
152
+ $terms = [$term->term_taxonomy_id];
153
+ $tax = [$term->taxonomy];
154
  }
 
155
 
156
+ $tax[] = self::VALUE_HAS_TERMS;
157
+ return '(term.term_taxonomy_id IS NULL OR term.term_taxonomy_id IN ('.implode(',', $terms).")) AND ($name.meta_value IS NULL OR $name.meta_value IN('".implode("','", $tax)."'))";
158
  }
159
 
160
  /**
164
  * @param array $args
165
  * @return array
166
  */
167
+ protected function _get_content($args = [])
168
  {
169
+ $total_items = wp_count_terms($args['taxonomy'], [
170
  'hide_empty' => $args['hide_empty']
171
+ ]);
172
 
173
  $start = $args['offset'];
174
  $end = $start + $args['number'];
175
  $walk_tree = false;
176
+ $retval = [];
177
 
178
  if ($total_items) {
179
  $taxonomy = get_taxonomy($args['taxonomy']);
188
  $terms = new WP_Term_Query($args);
189
 
190
  if ($walk_tree) {
191
+ $sorted_terms = [];
192
  foreach ($terms->terms as $term) {
193
  $sorted_terms[$term->parent][] = $term;
194
  }
229
  }
230
 
231
  if ($i >= $start) {
232
+ $retval[] = [
233
  'id' => $term->term_id,
234
  'text' => htmlspecialchars_decode($term->name),
235
  'level' => $level
236
+ ];
237
  }
238
 
239
  $i++;
254
  {
255
  // List public taxonomies
256
  if (empty($this->taxonomy_objects)) {
257
+ foreach (get_taxonomies(['public' => true], 'objects') as $tax) {
258
  $this->taxonomy_objects[$tax->name] = $tax;
259
  }
260
  if (defined('POLYLANG_VERSION')) {
284
  // 'update_term_meta_cache' => false
285
  // )
286
  );
287
+ $terms_by_tax = [];
288
  foreach ($terms as $term) {
289
  $terms_by_tax[$term->taxonomy][] = $term;
290
  }
298
  $group_data[$this->id.'-'.$taxonomy->name]['label'] = $group_data[$this->id.'-'.$taxonomy->name]['text'];
299
 
300
  if ($posts) {
301
+ $retval = [];
302
 
303
  //Hierarchical taxonomies use ids instead of slugs
304
  //see http://codex.wordpress.org/Function_Reference/wp_set_post_objects
321
  */
322
  protected function get_title_count()
323
  {
324
+ $title_count = [];
325
  foreach ($this->_get_taxonomies() as $taxonomy) {
326
  if (!isset($title_count[$taxonomy->label])) {
327
  $title_count[$taxonomy->label] = 0;
342
  $label .= ' (' . $post_type->label . ')';
343
  }
344
 
345
+ return [
346
  'text' => $label,
347
  'placeholder' => $placeholder,
348
  'default_value' => $taxonomy->name
349
+ ];
350
  }
351
 
352
  /**
381
  $taxonomy_name = 'category';
382
  }
383
 
384
+ return [
385
  'include' => $args['include'],
386
  'taxonomy' => $taxonomy_name,
387
  'number' => $args['limit'],
391
  'search' => $args['search'],
392
  'hide_empty' => false,
393
  'update_term_meta_cache' => false
394
+ ];
395
  }
396
 
397
  /**
403
  */
404
  public function save_data($post_id)
405
  {
 
406
  $meta_key = WPCACore::PREFIX . $this->id;
407
  $old = array_flip(get_post_meta($post_id, $meta_key, false));
408
  $tax_input = $_POST['conditions'];
409
 
410
+ $has_select_terms = false;
411
+
412
  //Save terms
413
  //Loop through each public taxonomy
414
  foreach ($this->_get_taxonomies() as $taxonomy) {
415
 
416
  //If no terms, maybe delete old ones
417
  if (!isset($tax_input[$this->id.'-'.$taxonomy->name])) {
418
+ $terms = [];
419
  if (isset($old[$taxonomy->name])) {
420
  delete_post_meta($post_id, $meta_key, $taxonomy->name);
421
  }
441
  }
442
  }
443
 
444
+ if (!empty($terms)) {
445
+ $has_select_terms = true;
446
+ }
447
+
448
  wp_set_object_terms($post_id, $terms, $taxonomy->name);
449
  }
450
+
451
+ if ($has_select_terms && !isset($old[self::VALUE_HAS_TERMS])) {
452
+ add_post_meta($post_id, $meta_key, self::VALUE_HAS_TERMS);
453
+ } elseif (!$has_select_terms && isset($old[self::VALUE_HAS_TERMS])) {
454
+ delete_post_meta($post_id, $meta_key, self::VALUE_HAS_TERMS);
455
+ }
456
  }
457
 
458
  /**
471
 
472
  if ($term->parent != '0') {
473
  // Get sidebars with term ancestor wanting to auto-select term
474
+ $query = new WP_Query([
475
  'post_type' => WPCACore::TYPE_CONDITION_GROUP,
476
+ 'post_status' => [WPCACore::STATUS_OR,WPCACore::STATUS_EXCEPT,WPCACore::STATUS_PUBLISHED],
477
+ 'meta_query' => [
478
+ [
479
  'key' => WPCACore::PREFIX . 'autoselect',
480
  'value' => 1,
481
  'compare' => '='
482
+ ]
483
+ ],
484
+ 'tax_query' => [
485
+ [
486
  'taxonomy' => $taxonomy,
487
  'field' => 'id',
488
  'terms' => get_ancestors($term_id, $taxonomy),
489
  'include_children' => false
490
+ ]
491
+ ]
492
+ ]);
493
  if ($query && $query->found_posts) {
494
  foreach ($query->posts as $post) {
495
  wp_set_post_terms($post->ID, $term_id, $taxonomy, true);
lib/wp-content-aware-engine/module/translatepress.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * TranslatePress Module
14
- *
15
- * Detects if current content is:
16
- * a) in specific language
17
- *
18
- */
19
- class WPCAModule_translatepress extends WPCAModule_Base
20
- {
21
-
22
- /**
23
- * @var string
24
- */
25
- protected $category = 'plugins';
26
-
27
- public function __construct()
28
- {
29
- parent::__construct('language', __('Languages', WPCA_DOMAIN));
30
-
31
- $this->query_name = 'cl';
32
- }
33
-
34
- /**
35
- * @since 9.0
36
- * @return boolean
37
- */
38
- public function in_context()
39
- {
40
- return true;
41
- }
42
-
43
- /**
44
- * @return bool
45
- */
46
- public function can_enable()
47
- {
48
- return defined('TRP_PLUGIN_VERSION')
49
- && class_exists('TRP_Translate_Press');
50
- }
51
-
52
- /**
53
- * Get data from context
54
- *
55
- * @since 9.0
56
- * @return array
57
- */
58
- public function get_context_data()
59
- {
60
- $data = array($this->id);
61
- $current_language = get_locale();
62
- if ($current_language) {
63
- $data[] = $current_language;
64
- }
65
- return $data;
66
- }
67
-
68
- /**
69
- * Get languages
70
- *
71
- * @since 9.0
72
- * @param array $args
73
- * @return array
74
- */
75
- protected function _get_content($args = array())
76
- {
77
- $langs = array();
78
- $trp_instance = TRP_Translate_Press::get_trp_instance();
79
- $langs = $trp_instance->get_component('languages')->get_language_names(
80
- $trp_instance->get_component('settings')->get_setting('publish-languages')
81
- );
82
-
83
- if ($args['include']) {
84
- $langs = array_intersect_key($langs, array_flip($args['include']));
85
- }
86
- return $langs;
87
- }
88
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * TranslatePress Module
14
+ *
15
+ * Detects if current content is:
16
+ * a) in specific language
17
+ *
18
+ */
19
+ class WPCAModule_translatepress extends WPCAModule_Base
20
+ {
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ protected $category = 'plugins';
26
+
27
+ public function __construct()
28
+ {
29
+ parent::__construct('language', __('Languages', WPCA_DOMAIN));
30
+
31
+ $this->query_name = 'cl';
32
+ }
33
+
34
+ /**
35
+ * @since 9.0
36
+ * @return boolean
37
+ */
38
+ public function in_context()
39
+ {
40
+ return true;
41
+ }
42
+
43
+ /**
44
+ * @return bool
45
+ */
46
+ public function can_enable()
47
+ {
48
+ return defined('TRP_PLUGIN_VERSION')
49
+ && class_exists('TRP_Translate_Press');
50
+ }
51
+
52
+ /**
53
+ * Get data from context
54
+ *
55
+ * @since 9.0
56
+ * @return array
57
+ */
58
+ public function get_context_data()
59
+ {
60
+ $data = [$this->id];
61
+ $current_language = get_locale();
62
+ if ($current_language) {
63
+ $data[] = $current_language;
64
+ }
65
+ return $data;
66
+ }
67
+
68
+ /**
69
+ * Get languages
70
+ *
71
+ * @since 9.0
72
+ * @param array $args
73
+ * @return array
74
+ */
75
+ protected function _get_content($args = [])
76
+ {
77
+ $langs = [];
78
+ $trp_instance = TRP_Translate_Press::get_trp_instance();
79
+ $langs = $trp_instance->get_component('languages')->get_language_names(
80
+ $trp_instance->get_component('settings')->get_setting('publish-languages')
81
+ );
82
+
83
+ if ($args['include']) {
84
+ $langs = array_intersect_key($langs, array_flip($args['include']));
85
+ }
86
+ return $langs;
87
+ }
88
+ }
lib/wp-content-aware-engine/module/transposh.php CHANGED
@@ -1,104 +1,104 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * Transposh Module
14
- * Requires version 0.9.5+
15
- *
16
- * Detects if current content is:
17
- * a) in specific language
18
- *
19
- */
20
- class WPCAModule_transposh extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
-
35
- $this->query_name = 'cl';
36
- }
37
-
38
-
39
- /**
40
- * @return bool
41
- */
42
- public function can_enable()
43
- {
44
- return defined('TRANSPOSH_PLUGIN_VER')
45
- && function_exists('transposh_get_current_language')
46
- && defined('TRANSPOSH_OPTIONS')
47
- && method_exists('transposh_consts', 'get_language_orig_name');
48
- }
49
-
50
- /**
51
- * @since 1.0
52
- * @return boolean
53
- */
54
- public function in_context()
55
- {
56
- return true;
57
- }
58
-
59
- /**
60
- * Get data from context
61
- *
62
- * @since 1.0
63
- * @return array
64
- */
65
- public function get_context_data()
66
- {
67
- $data = array($this->id);
68
- $data[] = transposh_get_current_language();
69
- return $data;
70
- }
71
-
72
- /**
73
- * Get content for sidebar editor
74
- *
75
- * @global object $my_transposh_plugin
76
- * @since 1.0
77
- * @param array $args
78
- * @return array
79
- */
80
- protected function _get_content($args = array())
81
- {
82
- global $my_transposh_plugin;
83
- $langs = array();
84
-
85
- /**
86
- * isset($my_transposh_plugin->options->viewable_languages)
87
- * returns false because transposh dev has not implemented __isset
88
- * using get_option instead for robustness
89
- */
90
-
91
- $options = get_option(TRANSPOSH_OPTIONS);
92
-
93
- if (isset($options['viewable_languages'])) {
94
- foreach (explode(',', $options['viewable_languages']) as $lng) {
95
- $langs[$lng] = transposh_consts::get_language_orig_name($lng);
96
- }
97
- }
98
-
99
- if ($args['include']) {
100
- $langs = array_intersect_key($langs, array_flip($args['include']));
101
- }
102
- return $langs;
103
- }
104
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * Transposh Module
14
+ * Requires version 0.9.5+
15
+ *
16
+ * Detects if current content is:
17
+ * a) in specific language
18
+ *
19
+ */
20
+ class WPCAModule_transposh extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
+
35
+ $this->query_name = 'cl';
36
+ }
37
+
38
+
39
+ /**
40
+ * @return bool
41
+ */
42
+ public function can_enable()
43
+ {
44
+ return defined('TRANSPOSH_PLUGIN_VER')
45
+ && function_exists('transposh_get_current_language')
46
+ && defined('TRANSPOSH_OPTIONS')
47
+ && method_exists('transposh_consts', 'get_language_orig_name');
48
+ }
49
+
50
+ /**
51
+ * @since 1.0
52
+ * @return boolean
53
+ */
54
+ public function in_context()
55
+ {
56
+ return true;
57
+ }
58
+
59
+ /**
60
+ * Get data from context
61
+ *
62
+ * @since 1.0
63
+ * @return array
64
+ */
65
+ public function get_context_data()
66
+ {
67
+ $data = [$this->id];
68
+ $data[] = transposh_get_current_language();
69
+ return $data;
70
+ }
71
+
72
+ /**
73
+ * Get content for sidebar editor
74
+ *
75
+ * @global object $my_transposh_plugin
76
+ * @since 1.0
77
+ * @param array $args
78
+ * @return array
79
+ */
80
+ protected function _get_content($args = [])
81
+ {
82
+ global $my_transposh_plugin;
83
+ $langs = [];
84
+
85
+ /**
86
+ * isset($my_transposh_plugin->options->viewable_languages)
87
+ * returns false because transposh dev has not implemented __isset
88
+ * using get_option instead for robustness
89
+ */
90
+
91
+ $options = get_option(TRANSPOSH_OPTIONS);
92
+
93
+ if (isset($options['viewable_languages'])) {
94
+ foreach (explode(',', $options['viewable_languages']) as $lng) {
95
+ $langs[$lng] = transposh_consts::get_language_orig_name($lng);
96
+ }
97
+ }
98
+
99
+ if ($args['include']) {
100
+ $langs = array_intersect_key($langs, array_flip($args['include']));
101
+ }
102
+ return $langs;
103
+ }
104
+ }
lib/wp-content-aware-engine/module/wpml.php CHANGED
@@ -1,91 +1,91 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- *
13
- * WPML Module
14
- * Requires version 2.4.3+
15
- *
16
- * Detects if current content is:
17
- * a) in specific language
18
- *
19
- */
20
- class WPCAModule_wpml extends WPCAModule_Base
21
- {
22
-
23
- /**
24
- * @var string
25
- */
26
- protected $category = 'plugins';
27
-
28
- /**
29
- * Constructor
30
- */
31
- public function __construct()
32
- {
33
- parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
-
35
- $this->query_name = 'cl';
36
- }
37
-
38
-
39
- /**
40
- * @return bool
41
- */
42
- public function can_enable()
43
- {
44
- return defined('ICL_SITEPRESS_VERSION')
45
- && defined('ICL_LANGUAGE_CODE')
46
- && function_exists('icl_get_languages');
47
- }
48
-
49
- /**
50
- * @since 1.0
51
- * @return boolean
52
- */
53
- public function in_context()
54
- {
55
- return true;
56
- }
57
-
58
- /**
59
- * Get data from context
60
- *
61
- * @since 1.0
62
- * @return array
63
- */
64
- public function get_context_data()
65
- {
66
- $data = array($this->id);
67
- $data[] = ICL_LANGUAGE_CODE;
68
- return $data;
69
- }
70
-
71
- /**
72
- * Get languages
73
- *
74
- * @since 1.0
75
- * @param array $args
76
- * @return array
77
- */
78
- protected function _get_content($args = array())
79
- {
80
- $langs = array();
81
-
82
- foreach (icl_get_languages('skip_missing=N') as $lng) {
83
- $langs[$lng['language_code']] = $lng['native_name'];
84
- }
85
-
86
- if ($args['include']) {
87
- $langs = array_intersect_key($langs, array_flip($args['include']));
88
- }
89
- return $langs;
90
- }
91
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ *
13
+ * WPML Module
14
+ * Requires version 2.4.3+
15
+ *
16
+ * Detects if current content is:
17
+ * a) in specific language
18
+ *
19
+ */
20
+ class WPCAModule_wpml extends WPCAModule_Base
21
+ {
22
+
23
+ /**
24
+ * @var string
25
+ */
26
+ protected $category = 'plugins';
27
+
28
+ /**
29
+ * Constructor
30
+ */
31
+ public function __construct()
32
+ {
33
+ parent::__construct('language', __('Languages', WPCA_DOMAIN));
34
+
35
+ $this->query_name = 'cl';
36
+ }
37
+
38
+
39
+ /**
40
+ * @return bool
41
+ */
42
+ public function can_enable()
43
+ {
44
+ return defined('ICL_SITEPRESS_VERSION')
45
+ && defined('ICL_LANGUAGE_CODE')
46
+ && function_exists('icl_get_languages');
47
+ }
48
+
49
+ /**
50
+ * @since 1.0
51
+ * @return boolean
52
+ */
53
+ public function in_context()
54
+ {
55
+ return true;
56
+ }
57
+
58
+ /**
59
+ * Get data from context
60
+ *
61
+ * @since 1.0
62
+ * @return array
63
+ */
64
+ public function get_context_data()
65
+ {
66
+ $data = [$this->id];
67
+ $data[] = ICL_LANGUAGE_CODE;
68
+ return $data;
69
+ }
70
+
71
+ /**
72
+ * Get languages
73
+ *
74
+ * @since 1.0
75
+ * @param array $args
76
+ * @return array
77
+ */
78
+ protected function _get_content($args = [])
79
+ {
80
+ $langs = [];
81
+
82
+ foreach (icl_get_languages('skip_missing=N') as $lng) {
83
+ $langs[$lng['language_code']] = $lng['native_name'];
84
+ }
85
+
86
+ if ($args['include']) {
87
+ $langs = array_intersect_key($langs, array_flip($args['include']));
88
+ }
89
+ return $langs;
90
+ }
91
+ }
lib/wp-content-aware-engine/objectmanager.php CHANGED
@@ -1,145 +1,145 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- if (!class_exists('WPCAObjectManager')) {
12
- /**
13
- * Manage a list of objects nicely
14
- */
15
- class WPCAObjectManager implements IteratorAggregate
16
- {
17
-
18
- /**
19
- * List of objects
20
- *
21
- * @var array
22
- */
23
- private $objects = array();
24
-
25
- /**
26
- * Constructor
27
- *
28
- * @since 1.0
29
- */
30
- public function __construct()
31
- {
32
- }
33
-
34
- /**
35
- * Add object to the manager if key is
36
- * not already added
37
- *
38
- * @since 1.0
39
- * @param mixed $object
40
- * @param string $name
41
- * @return WPCAObjectManager
42
- */
43
- public function add($object, $name)
44
- {
45
- if (!$this->has($name)) {
46
- $this->set($object, $name);
47
- }
48
- return $this;
49
- }
50
-
51
- /**
52
- * Remove object with key from manager
53
- *
54
- * @since 1.0
55
- * @param string $name
56
- * @return void
57
- */
58
- public function remove($name)
59
- {
60
- unset($this->objects[$name]);
61
- }
62
-
63
- /**
64
- * Check if manager has key
65
- *
66
- * @since 1.0
67
- * @param string $name
68
- * @return boolean
69
- */
70
- public function has($name)
71
- {
72
- return isset($this->objects[$name]);
73
- }
74
-
75
- /**
76
- * Get object with key
77
- * Returns null if not found
78
- *
79
- * @since 1.0
80
- * @param string $name
81
- * @return mixed|null
82
- */
83
- public function get($name)
84
- {
85
- return $this->has($name) ? $this->objects[$name] : null;
86
- }
87
-
88
- /**
89
- * Add object to manager regardless if
90
- * key exists already
91
- *
92
- * @since 1.0
93
- * @param mixed $object
94
- * @param string $name
95
- */
96
- public function set($object, $name)
97
- {
98
- $this->objects[$name] = $object;
99
- }
100
-
101
- /**
102
- * Get all objects in manager
103
- *
104
- * @since 1.0
105
- * @return array
106
- */
107
- public function get_all()
108
- {
109
- return $this->objects;
110
- }
111
-
112
- /**
113
- * Set all objects in manager
114
- *
115
- * @since 1.0
116
- * @param array $objects
117
- */
118
- public function set_all($objects)
119
- {
120
- $this->objects = (array)$objects;
121
- }
122
-
123
- /**
124
- * Count objects
125
- *
126
- * @since 1.0
127
- * @return int
128
- */
129
- public function count()
130
- {
131
- return count($this->objects);
132
- }
133
-
134
- /**
135
- * Make objects traversable
136
- *
137
- * @since 4.2
138
- * @return ArrayIterator
139
- */
140
- public function getIterator()
141
- {
142
- return new ArrayIterator($this->objects);
143
- }
144
- }
145
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ if (!class_exists('WPCAObjectManager')) {
12
+ /**
13
+ * Manage a list of objects nicely
14
+ */
15
+ class WPCAObjectManager implements IteratorAggregate
16
+ {
17
+
18
+ /**
19
+ * List of objects
20
+ *
21
+ * @var array
22
+ */
23
+ private $objects = [];
24
+
25
+ /**
26
+ * Constructor
27
+ *
28
+ * @since 1.0
29
+ */
30
+ public function __construct()
31
+ {
32
+ }
33
+
34
+ /**
35
+ * Add object to the manager if key is
36
+ * not already added
37
+ *
38
+ * @since 1.0
39
+ * @param mixed $object
40
+ * @param string $name
41
+ * @return WPCAObjectManager
42
+ */
43
+ public function add($object, $name)
44
+ {
45
+ if (!$this->has($name)) {
46
+ $this->set($object, $name);
47
+ }
48
+ return $this;
49
+ }
50
+
51
+ /**
52
+ * Remove object with key from manager
53
+ *
54
+ * @since 1.0
55
+ * @param string $name
56
+ * @return void
57
+ */
58
+ public function remove($name)
59
+ {
60
+ unset($this->objects[$name]);
61
+ }
62
+
63
+ /**
64
+ * Check if manager has key
65
+ *
66
+ * @since 1.0
67
+ * @param string $name
68
+ * @return boolean
69
+ */
70
+ public function has($name)
71
+ {
72
+ return isset($this->objects[$name]);
73
+ }
74
+
75
+ /**
76
+ * Get object with key
77
+ * Returns null if not found
78
+ *
79
+ * @since 1.0
80
+ * @param string $name
81
+ * @return mixed|null
82
+ */
83
+ public function get($name)
84
+ {
85
+ return $this->has($name) ? $this->objects[$name] : null;
86
+ }
87
+
88
+ /**
89
+ * Add object to manager regardless if
90
+ * key exists already
91
+ *
92
+ * @since 1.0
93
+ * @param mixed $object
94
+ * @param string $name
95
+ */
96
+ public function set($object, $name)
97
+ {
98
+ $this->objects[$name] = $object;
99
+ }
100
+
101
+ /**
102
+ * Get all objects in manager
103
+ *
104
+ * @since 1.0
105
+ * @return array
106
+ */
107
+ public function get_all()
108
+ {
109
+ return $this->objects;
110
+ }
111
+
112
+ /**
113
+ * Set all objects in manager
114
+ *
115
+ * @since 1.0
116
+ * @param array $objects
117
+ */
118
+ public function set_all($objects)
119
+ {
120
+ $this->objects = (array)$objects;
121
+ }
122
+
123
+ /**
124
+ * Count objects
125
+ *
126
+ * @since 1.0
127
+ * @return int
128
+ */
129
+ public function count()
130
+ {
131
+ return count($this->objects);
132
+ }
133
+
134
+ /**
135
+ * Make objects traversable
136
+ *
137
+ * @since 4.2
138
+ * @return ArrayIterator
139
+ */
140
+ public function getIterator()
141
+ {
142
+ return new ArrayIterator($this->objects);
143
+ }
144
+ }
145
+ }
lib/wp-content-aware-engine/typemanager.php CHANGED
@@ -1,107 +1,107 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
-
12
- if (!class_exists('WPCATypeManager')) {
13
- /**
14
- * Manage module objects
15
- */
16
- final class WPCATypeManager extends WPCAObjectManager
17
- {
18
-
19
- /**
20
- * Constructor
21
- */
22
- public function __construct()
23
- {
24
- parent::__construct();
25
- add_action(
26
- 'init',
27
- array($this,'set_modules'),
28
- 999
29
- );
30
- }
31
-
32
- /**
33
- * Add module to manager
34
- *
35
- * @since 1.0
36
- * @param object $class
37
- * @param string $name
38
- */
39
- public function add($name, $arg = '')
40
- {
41
- parent::add(new WPCAObjectManager(), $name);
42
- }
43
-
44
- /**
45
- * Set initial modules
46
- *
47
- * @since 4.0
48
- * @return void
49
- */
50
- public function set_modules()
51
- {
52
- do_action('wpca/types/init', $this);
53
-
54
- $modules = array(
55
- 'static',
56
- 'post_type',
57
- 'author',
58
- 'page_template',
59
- 'taxonomy',
60
- 'date',
61
- 'bbpress',
62
- 'bp_member',
63
- 'pods',
64
- 'polylang',
65
- 'qtranslate',
66
- 'translatepress',
67
- 'transposh',
68
- 'wpml'
69
- );
70
-
71
- foreach ($modules as $name) {
72
- $class_name = WPCACore::CLASS_PREFIX.'Module_'.$name;
73
-
74
- if (!class_exists($class_name)) {
75
- continue;
76
- }
77
-
78
- $class = new $class_name();
79
-
80
- if (!($class instanceof WPCAModule_Base) || !$class->can_enable()) {
81
- continue;
82
- }
83
-
84
- foreach ($this->get_all() as $post_type) {
85
- $post_type->add($class, $name);
86
- }
87
- }
88
-
89
- do_action('wpca/modules/init', $this);
90
-
91
- //initiate all modules once with backwards compatibility on can_enable()
92
- $initiated = array();
93
- foreach ($this->get_all() as $post_type_name => $post_type) {
94
- if (!WPCACore::get_option($post_type_name, 'legacy.date_module', false)) {
95
- $post_type->remove('date');
96
- }
97
-
98
- foreach ($post_type->get_all() as $key => $module) {
99
- if (!isset($initiated[$key])) {
100
- $initiated[$key] = 1;
101
- $module->initiate();
102
- }
103
- }
104
- }
105
- }
106
- }
107
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+
12
+ if (!class_exists('WPCATypeManager')) {
13
+ /**
14
+ * Manage module objects
15
+ */
16
+ final class WPCATypeManager extends WPCAObjectManager
17
+ {
18
+
19
+ /**
20
+ * Constructor
21
+ */
22
+ public function __construct()
23
+ {
24
+ parent::__construct();
25
+ add_action(
26
+ 'init',
27
+ [$this,'set_modules'],
28
+ 999
29
+ );
30
+ }
31
+
32
+ /**
33
+ * Add module to manager
34
+ *
35
+ * @since 1.0
36
+ * @param object $class
37
+ * @param string $name
38
+ */
39
+ public function add($name, $arg = '')
40
+ {
41
+ parent::add(new WPCAObjectManager(), $name);
42
+ }
43
+
44
+ /**
45
+ * Set initial modules
46
+ *
47
+ * @since 4.0
48
+ * @return void
49
+ */
50
+ public function set_modules()
51
+ {
52
+ do_action('wpca/types/init', $this);
53
+
54
+ $modules = [
55
+ 'static',
56
+ 'post_type',
57
+ 'author',
58
+ 'page_template',
59
+ 'taxonomy',
60
+ 'date',
61
+ 'bbpress',
62
+ 'bp_member',
63
+ 'pods',
64
+ 'polylang',
65
+ 'qtranslate',
66
+ 'translatepress',
67
+ 'transposh',
68
+ 'wpml'
69
+ ];
70
+
71
+ foreach ($modules as $name) {
72
+ $class_name = WPCACore::CLASS_PREFIX.'Module_'.$name;
73
+
74
+ if (!class_exists($class_name)) {
75
+ continue;
76
+ }
77
+
78
+ $class = new $class_name();
79
+
80
+ if (!($class instanceof WPCAModule_Base) || !$class->can_enable()) {
81
+ continue;
82
+ }
83
+
84
+ foreach ($this->get_all() as $post_type) {
85
+ $post_type->add($class, $name);
86
+ }
87
+ }
88
+
89
+ do_action('wpca/modules/init', $this);
90
+
91
+ //initiate all modules once with backwards compatibility on can_enable()
92
+ $initiated = [];
93
+ foreach ($this->get_all() as $post_type_name => $post_type) {
94
+ if (!WPCACore::get_option($post_type_name, 'legacy.date_module', false)) {
95
+ $post_type->remove('date');
96
+ }
97
+
98
+ foreach ($post_type->get_all() as $key => $module) {
99
+ if (!isset($initiated[$key])) {
100
+ $initiated[$key] = 1;
101
+ $module->initiate();
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
lib/wp-content-aware-engine/view.php CHANGED
@@ -1,124 +1,124 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- defined('ABSPATH') || exit;
10
-
11
- /**
12
- * View Class
13
- */
14
- class WPCAView
15
- {
16
-
17
- /**
18
- * Path to view template
19
- *
20
- * @var string
21
- */
22
- private $_path;
23
-
24
- /**
25
- * Parameters for view template
26
- *
27
- * @var array
28
- */
29
- private $_params;
30
-
31
- /**
32
- * Template content
33
- *
34
- * @var string
35
- */
36
- private $_content;
37
-
38
- /**
39
- * Constructor
40
- *
41
- * @since 1.0
42
- * @param string $path
43
- * @param array $params
44
- */
45
- private function __construct($path, $params = array())
46
- {
47
- $this->_path = $path;
48
- $this->_params = $params;
49
- }
50
-
51
- /**
52
- * Create instance of view
53
- *
54
- * @since 1.0
55
- * @param string $name
56
- * @param array $params
57
- * @return WPCAView
58
- */
59
- public static function make($name, $params = array())
60
- {
61
- return new self($name, $params);
62
- }
63
-
64
- /**
65
- * Add possibility to set params dynamically
66
- *
67
- * @since 1.0
68
- * @param string $method
69
- * @param array $args
70
- * @return mixed
71
- */
72
- public function __call($method, $args)
73
- {
74
- if (substr($method, 0, 3) == 'set' && count($args) == 1) {
75
- $this->_params[strtolower(substr($method, 2))] = $args[0];
76
- return $this;
77
- }
78
- return call_user_func_array($method, $args);
79
- }
80
-
81
- /**
82
- * Get path to file
83
- *
84
- * @since 1.0
85
- * @return string
86
- */
87
- private function resolve_path()
88
- {
89
- if (stripos(strrev($this->_path), 'php.') === 0) {
90
- return $this->_path;
91
- }
92
- return WPCA_PATH.'view/'.str_replace('.', '/', $this->_path).'.php';
93
- }
94
-
95
- /**
96
- * Get content
97
- *
98
- * @since 1.0
99
- * @return string
100
- */
101
- private function get_content()
102
- {
103
- if (!$this->_content) {
104
- ob_start();
105
- if ($this->_params) {
106
- extract($this->_params);
107
- }
108
- require($this->resolve_path());
109
- $this->_content = ob_get_clean();
110
- }
111
- return $this->_content;
112
- }
113
-
114
- /**
115
- * Render content
116
- *
117
- * @since 1.0
118
- * @return void
119
- */
120
- public function render()
121
- {
122
- echo $this->get_content();
123
- }
124
- }
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ defined('ABSPATH') || exit;
10
+
11
+ /**
12
+ * View Class
13
+ */
14
+ class WPCAView
15
+ {
16
+
17
+ /**
18
+ * Path to view template
19
+ *
20
+ * @var string
21
+ */
22
+ private $_path;
23
+
24
+ /**
25
+ * Parameters for view template
26
+ *
27
+ * @var array
28
+ */
29
+ private $_params;
30
+
31
+ /**
32
+ * Template content
33
+ *
34
+ * @var string
35
+ */
36
+ private $_content;
37
+
38
+ /**
39
+ * Constructor
40
+ *
41
+ * @since 1.0
42
+ * @param string $path
43
+ * @param array $params
44
+ */
45
+ private function __construct($path, $params = [])
46
+ {
47
+ $this->_path = $path;
48
+ $this->_params = $params;
49
+ }
50
+
51
+ /**
52
+ * Create instance of view
53
+ *
54
+ * @since 1.0
55
+ * @param string $name
56
+ * @param array $params
57
+ * @return WPCAView
58
+ */
59
+ public static function make($name, $params = [])
60
+ {
61
+ return new self($name, $params);
62
+ }
63
+
64
+ /**
65
+ * Add possibility to set params dynamically
66
+ *
67
+ * @since 1.0
68
+ * @param string $method
69
+ * @param array $args
70
+ * @return mixed
71
+ */
72
+ public function __call($method, $args)
73
+ {
74
+ if (substr($method, 0, 3) == 'set' && count($args) == 1) {
75
+ $this->_params[strtolower(substr($method, 2))] = $args[0];
76
+ return $this;
77
+ }
78
+ return call_user_func_array($method, $args);
79
+ }
80
+
81
+ /**
82
+ * Get path to file
83
+ *
84
+ * @since 1.0
85
+ * @return string
86
+ */
87
+ private function resolve_path()
88
+ {
89
+ if (stripos(strrev($this->_path), 'php.') === 0) {
90
+ return $this->_path;
91
+ }
92
+ return WPCA_PATH.'view/'.str_replace('.', '/', $this->_path).'.php';
93
+ }
94
+
95
+ /**
96
+ * Get content
97
+ *
98
+ * @since 1.0
99
+ * @return string
100
+ */
101
+ private function get_content()
102
+ {
103
+ if (!$this->_content) {
104
+ ob_start();
105
+ if ($this->_params) {
106
+ extract($this->_params);
107
+ }
108
+ require($this->resolve_path());
109
+ $this->_content = ob_get_clean();
110
+ }
111
+ return $this->_content;
112
+ }
113
+
114
+ /**
115
+ * Render content
116
+ *
117
+ * @since 1.0
118
+ * @return void
119
+ */
120
+ public function render()
121
+ {
122
+ echo $this->get_content();
123
+ }
124
+ }
lib/wp-content-aware-engine/view/index.php CHANGED
@@ -1,2 +1,2 @@
1
- <?php
2
- /**/
1
+ <?php
2
+ /**/
lib/wp-content-aware-engine/view/meta_box.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
- /**
3
- * @package WP Content Aware Engine
4
- * @author Joachim Jensen <joachim@dev.institute>
5
- * @license GPLv3
6
- * @copyright 2020 by Joachim Jensen
7
- */
8
-
9
- $quick_links = array(
10
- __('Blog', WPCA_DOMAIN) => array(
11
- 'modules' => array('post_type-post'),
12
- 'options' => array('exposure' => 2)
13
- ),
14
- __('Posts by Author', WPCA_DOMAIN) => array(
15
- 'modules' => array('post_type-post','author'),
16
- 'options' => array('exposure' => 0)
17
- ),
18
- __('Posts in Category', WPCA_DOMAIN) => array(
19
- 'modules' => array('post_type-post','taxonomy-category'),
20
- 'options' => array('exposure' => 0)
21
- )
22
- );
23
-
24
- if (post_type_exists('product')) {
25
- $quick_links[__('Shop', WPCA_DOMAIN)] = array(
26
- 'modules' => array('post_type-product'),
27
- 'options' => array('exposure' => 2)
28
- );
29
- }
30
-
31
- echo $nonce; ?>
32
  <div id="cas-groups">
33
- <?php do_action('wpca/meta_box/before', $post_type); ?>
34
  <ul data-vm="collection:$collection"></ul>
35
  <div class="cas-group-sep" data-vm="toggle:length($collection)">
36
  <span><?php _e('Or', WPCA_DOMAIN); ?></span>
@@ -43,11 +43,11 @@ echo $nonce; ?>
43
  <span style="vertical-align: middle;"><em>or</em> <strong>Quick Add:</strong></span>
44
  </div>
45
  <div>
46
- <?php foreach ($quick_links as $label => $conditions) : ?>
47
  <a class="js-wpca-add-quick" href="#"
48
  data-config='<?php echo json_encode($conditions); ?>'><?php echo $label; ?></a>
49
- <?php endforeach; ?>
50
  </div>
51
  </div>
52
- <?php do_action('wpca/meta_box/after', $post_type); ?>
53
  </div>
1
+ <?php
2
+ /**
3
+ * @package WP Content Aware Engine
4
+ * @author Joachim Jensen <joachim@dev.institute>
5
+ * @license GPLv3
6
+ * @copyright 2020 by Joachim Jensen
7
+ */
8
+
9
+ $quick_links = [
10
+ __('Blog', WPCA_DOMAIN) => [
11
+ 'modules' => ['post_type-post'],
12
+ 'options' => ['exposure' => 2]
13
+ ],
14
+ __('Posts by Author', WPCA_DOMAIN) => [
15
+ 'modules' => ['post_type-post','author'],
16
+ 'options' => ['exposure' => 0]
17
+ ],
18
+ __('Posts in Category', WPCA_DOMAIN) => [
19
+ 'modules' => ['post_type-post','taxonomy-category'],
20
+ 'options' => ['exposure' => 0]
21
+ ]
22
+ ];
23
+
24
+ if (post_type_exists('product')) {
25
+ $quick_links[__('Shop', WPCA_DOMAIN)] = [
26
+ 'modules' => ['post_type-product'],
27
+ 'options' => ['exposure' => 2]
28
+ ];
29
+ }
30
+
31
+ echo $nonce; ?>
32
  <div id="cas-groups">
33
+ <?php do_action('wpca/meta_box/before', $post_type); ?>
34
  <ul data-vm="collection:$collection"></ul>
35
  <div class="cas-group-sep" data-vm="toggle:length($collection)">
36
  <span><?php _e('Or', WPCA_DOMAIN); ?></span>
43
  <span style="vertical-align: middle;"><em>or</em> <strong>Quick Add:</strong></span>
44
  </div>
45
  <div>
46
+ <?php foreach ($quick_links as $label => $conditions) : ?>
47
  <a class="js-wpca-add-quick" href="#"
48
  data-config='<?php echo json_encode($conditions); ?>'><?php echo $label; ?></a>
49
+ <?php endforeach; ?>
50
  </div>
51
  </div>
52
+ <?php do_action('wpca/meta_box/after', $post_type); ?>
53
  </div>
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: #
4
  Tags: custom sidebars, sidebar, hide sidebar, display widgets, widget, bbpress, buddypress, sidebar manager
5
  Requires at least: 4.9
6
  Requires PHP: 5.6
7
- Tested up to: 5.6
8
- Stable tag: 3.15.1
9
  License: GPLv3
10
 
11
  Display new sidebars and widget areas on any post, page, category etc. Works with all themes, no code required.
@@ -184,6 +184,22 @@ Of course! Check out the links below:
184
 
185
  ####Highlights
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  = 3.15.1 =
188
 
189
  * [fixed] toolbar menu compatibility with php5.6
4
  Tags: custom sidebars, sidebar, hide sidebar, display widgets, widget, bbpress, buddypress, sidebar manager
5
  Requires at least: 4.9
6
  Requires PHP: 5.6
7
+ Tested up to: 5.7
8
+ Stable tag: 3.15.2
9
  License: GPLv3
10
 
11
  Display new sidebars and widget areas on any post, page, category etc. Works with all themes, no code required.
184
 
185
  ####Highlights
186
 
187
+ = 3.15.2 =
188
+
189
+ * [new] performance improvements
190
+ * [new] publishpress authors compatibility
191
+ * [new] wordpress 5.7 support
192
+ * [fixed] toolbar menu now supports theme areas registered without titles
193
+ * [fixed] toolbar menu now displays nested custom sidebars properly
194
+ * [updated] ui improvements for screen readers
195
+ * [updated] wp-content-aware-engine library
196
+ * [updated] freemius sdk
197
+
198
+ **Pro Plan:**
199
+
200
+ * [fixed] url condition compatible with wordpress installed in subdirectories
201
+ * [fixed] acf condition supports more field types
202
+
203
  = 3.15.1 =
204
 
205
  * [fixed] toolbar menu compatibility with php5.6
sidebar.php CHANGED
@@ -367,6 +367,14 @@ final class CAS_Sidebar_Manager
367
  }
368
  }
369
 
 
 
 
 
 
 
 
 
370
  /**
371
  * @param string $i
372
  * @return void
367
  }
368
  }
369
 
370
+ /**
371
+ * @return array
372
+ */
373
+ public function get_replacement_map()
374
+ {
375
+ return $this->replace_map;
376
+ }
377
+
378
  /**
379
  * @param string $i
380
  * @return void
view/meta_box_advanced.php CHANGED
@@ -14,21 +14,22 @@ if (!EMPTY_TRASH_DAYS) {
14
 
15
  ?>
16
 
17
- <table class="form-table cas-form-table" width="100%"><tbody>
 
18
  <tr>
19
- <td scope="row"><?php _e('Order'); ?></td>
20
  <td>
21
  <label for="menu_order" class="screen-reader-text"><?php _e('Order'); ?></label>
22
  <input type="number" value="<?php echo $post->menu_order; ?>" id="menu_order" size="4" name="menu_order">
23
  </td>
24
  </tr>
25
-
26
  <?php if (current_user_can('delete_post', $post->ID)) : ?>
27
  <tr>
28
- <td scope="row"></td>
29
  <td>
30
  <a class="button button-cas-upgrade" href="<?php echo get_delete_post_link($post->ID); ?>"><?php echo $delete_text; ?></a>
31
  </td>
32
  </tr>
33
  <?php endif; ?>
 
34
  </table>
14
 
15
  ?>
16
 
17
+ <table class="form-table cas-form-table" role="presentation">
18
+ <tbody>
19
  <tr>
20
+ <th scope="row"><?php _e('Order'); ?></th>
21
  <td>
22
  <label for="menu_order" class="screen-reader-text"><?php _e('Order'); ?></label>
23
  <input type="number" value="<?php echo $post->menu_order; ?>" id="menu_order" size="4" name="menu_order">
24
  </td>
25
  </tr>
 
26
  <?php if (current_user_can('delete_post', $post->ID)) : ?>
27
  <tr>
28
+ <th scope="row"></th>
29
  <td>
30
  <a class="button button-cas-upgrade" href="<?php echo get_delete_post_link($post->ID); ?>"><?php echo $delete_text; ?></a>
31
  </td>
32
  </tr>
33
  <?php endif; ?>
34
+ </tbody>
35
  </table>
view/meta_box_design.php CHANGED
@@ -11,7 +11,7 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
11
 
12
  ?>
13
 
14
- <table class="form-table cas-form-table" width="100%">
15
  <tbody>
16
  <tr>
17
  <td></td>
@@ -19,9 +19,7 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
19
  </td>
20
  </tr>
21
  <tr>
22
- <td scope="row">
23
- <?php _e('Sticky', 'content-aware-sidebars'); ?>
24
- </td>
25
  <td>
26
  <label class="cae-toggle js-cas-pro-notice"
27
  data-url="<?php echo $url; ?>">
@@ -34,31 +32,27 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
34
  </td>
35
  </tr>
36
  <tr>
37
- <td scope="row"><?php _e('Columns', 'content-aware-sidebars'); ?>
38
- </td>
39
  <td>
40
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="1" readonly
41
  data-url="<?php echo $url; ?>" /> <?php _e('columns', 'content-aware-sidebars'); ?>
42
  </td>
43
  </tr>
44
  <tr>
45
- <td scope="row"><?php _e('Gap', 'content-aware-sidebars'); ?>
46
- </td>
47
  <td>
48
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
49
  data-url="<?php echo $url; ?>" /> px
50
  </td>
51
  </tr>
52
  <tr>
53
- <td scope="row"><?php _e('Background Color', 'content-aware-sidebars'); ?>
54
- </td>
55
  <td>
56
  <input type="text" class="js-cas-color-field" value="" readonly />
57
  </td>
58
  </tr>
59
  <tr>
60
- <td scope="row"><?php _e('Padding', 'content-aware-sidebars'); ?>
61
- </td>
62
  <td>
63
  <input class="cas-input-sm js-cas-pro-notice" type="number"
64
  placeholder="<?php _e('Top', 'content-aware-sidebars'); ?>"
@@ -84,15 +78,13 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
84
  </td>
85
  </tr>
86
  <tr>
87
- <td scope="row"><?php _e('Background Color', 'content-aware-sidebars'); ?>
88
- </td>
89
  <td>
90
  <input type="text" class="js-cas-color-field testing-something" value="" readonly />
91
  </td>
92
  </tr>
93
  <tr>
94
- <td scope="row"><?php _e('Padding', 'content-aware-sidebars'); ?>
95
- </td>
96
  <td>
97
  <input class="cas-input-sm js-cas-pro-notice" type="number"
98
  placeholder="<?php _e('Top', 'content-aware-sidebars'); ?>"
@@ -113,24 +105,21 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
113
  </td>
114
  </tr>
115
  <tr>
116
- <td scope="row"><?php _e('Border Width', 'content-aware-sidebars'); ?>
117
- </td>
118
  <td>
119
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
120
  data-url="<?php echo $url; ?>" /> px
121
  </td>
122
  </tr>
123
  <tr>
124
- <td scope="row"><?php _e('Border Radius', 'content-aware-sidebars'); ?>
125
- </td>
126
  <td>
127
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
128
  data-url="<?php echo $url; ?>" /> px
129
  </td>
130
  </tr>
131
  <tr>
132
- <td scope="row"><?php _e('Border Color', 'content-aware-sidebars'); ?>
133
- </td>
134
  <td>
135
  <input type="text" class="js-cas-color-field" value="" readonly />
136
  </td>
@@ -141,29 +130,25 @@ $sticky_url = 'https://dev.institute/docs/content-aware-sidebars/faq/sticky-side
141
  </td>
142
  </tr>
143
  <tr>
144
- <td scope="row"><?php _e('Text Color', 'content-aware-sidebars'); ?>
145
- </td>
146
  <td>
147
  <input type="text" class="js-cas-color-field" value="" readonly />
148
  </td>
149
  </tr>
150
  <tr>
151
- <td scope="row"><?php _e('Title Color', 'content-aware-sidebars'); ?>
152
- </td>
153
  <td>
154
  <input type="text" class="js-cas-color-field" value="" readonly />
155
  </td>
156
  </tr>
157
  <tr>
158
- <td scope="row"><?php _e('Link Color', 'content-aware-sidebars'); ?>
159
- </td>
160
  <td>
161
  <input type="text" class="js-cas-color-field" value="" readonly />
162
  </td>
163
  </tr>
164
  <tr>
165
- <td scope="row"><?php _e('Link Hover Color', 'content-aware-sidebars'); ?>
166
- </td>
167
  <td>
168
  <input type="text" class="js-cas-color-field" value="" readonly />
169
  </td>
11
 
12
  ?>
13
 
14
+ <table class="form-table cas-form-table" role="presentation">
15
  <tbody>
16
  <tr>
17
  <td></td>
19
  </td>
20
  </tr>
21
  <tr>
22
+ <th scope="row"><?php _e('Sticky', 'content-aware-sidebars'); ?></th>
 
 
23
  <td>
24
  <label class="cae-toggle js-cas-pro-notice"
25
  data-url="<?php echo $url; ?>">
32
  </td>
33
  </tr>
34
  <tr>
35
+ <th scope="row"><?php _e('Columns', 'content-aware-sidebars'); ?></th>
 
36
  <td>
37
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="1" readonly
38
  data-url="<?php echo $url; ?>" /> <?php _e('columns', 'content-aware-sidebars'); ?>
39
  </td>
40
  </tr>
41
  <tr>
42
+ <th scope="row"><?php _e('Gap', 'content-aware-sidebars'); ?></th>
 
43
  <td>
44
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
45
  data-url="<?php echo $url; ?>" /> px
46
  </td>
47
  </tr>
48
  <tr>
49
+ <th scope="row"><?php _e('Background Color', 'content-aware-sidebars'); ?></th>
 
50
  <td>
51
  <input type="text" class="js-cas-color-field" value="" readonly />
52
  </td>
53
  </tr>
54
  <tr>
55
+ <th scope="row"><?php _e('Padding', 'content-aware-sidebars'); ?></th>
 
56
  <td>
57
  <input class="cas-input-sm js-cas-pro-notice" type="number"
58
  placeholder="<?php _e('Top', 'content-aware-sidebars'); ?>"
78
  </td>
79
  </tr>
80
  <tr>
81
+ <th scope="row"><?php _e('Background Color', 'content-aware-sidebars'); ?></th>
 
82
  <td>
83
  <input type="text" class="js-cas-color-field testing-something" value="" readonly />
84
  </td>
85
  </tr>
86
  <tr>
87
+ <th scope="row"><?php _e('Padding', 'content-aware-sidebars'); ?></th>
 
88
  <td>
89
  <input class="cas-input-sm js-cas-pro-notice" type="number"
90
  placeholder="<?php _e('Top', 'content-aware-sidebars'); ?>"
105
  </td>
106
  </tr>
107
  <tr>
108
+ <th scope="row"><?php _e('Border Width', 'content-aware-sidebars'); ?></th>
 
109
  <td>
110
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
111
  data-url="<?php echo $url; ?>" /> px
112
  </td>
113
  </tr>
114
  <tr>
115
+ <th scope="row"><?php _e('Border Radius', 'content-aware-sidebars'); ?></th>
 
116
  <td>
117
  <input class="cas-input-sm js-cas-pro-notice" type="number" value="" readonly
118
  data-url="<?php echo $url; ?>" /> px
119
  </td>
120
  </tr>
121
  <tr>
122
+ <th scope="row"><?php _e('Border Color', 'content-aware-sidebars'); ?></th>
 
123
  <td>
124
  <input type="text" class="js-cas-color-field" value="" readonly />
125
  </td>
130
  </td>
131
  </tr>
132
  <tr>
133
+ <th scope="row"><?php _e('Text Color', 'content-aware-sidebars'); ?></th>
 
134
  <td>
135
  <input type="text" class="js-cas-color-field" value="" readonly />
136
  </td>
137
  </tr>
138
  <tr>
139
+ <th scope="row"><?php _e('Title Color', 'content-aware-sidebars'); ?></th>
 
140
  <td>
141
  <input type="text" class="js-cas-color-field" value="" readonly />
142
  </td>
143
  </tr>
144
  <tr>
145
+ <th scope="row"><?php _e('Link Color', 'content-aware-sidebars'); ?></th>
 
146
  <td>
147
  <input type="text" class="js-cas-color-field" value="" readonly />
148
  </td>
149
  </tr>
150
  <tr>
151
+ <th scope="row"><?php _e('Link Hover Color', 'content-aware-sidebars'); ?></th>
 
152
  <td>
153
  <input type="text" class="js-cas-color-field" value="" readonly />
154
  </td>
view/meta_box_html.php CHANGED
@@ -37,9 +37,10 @@ $widget_title_opts = [
37
 
38
  ?>
39
 
40
- <table class="form-table cas-form-table" width="100%"><tbody>
 
41
  <tr>
42
- <td scope="row"><?php _e('Sidebar'); ?></td>
43
  <td>
44
  <label class="cae-toggle">
45
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['sidebar'],$data['sidebar_class']), true); ?> data-target=".js-cas-html-sidebar" />
@@ -57,7 +58,7 @@ $widget_title_opts = [
57
  </td>
58
  </tr>
59
  <tr>
60
- <td scope="row"><?php _e('Widget'); ?></td>
61
  <td>
62
  <label class="cae-toggle">
63
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['widget'],$data['widget_class']), true); ?> data-target=".js-cas-html-widget" />
@@ -75,7 +76,7 @@ $widget_title_opts = [
75
  </td>
76
  </tr>
77
  <tr>
78
- <td scope="row"><?php _e('Widget Title'); ?></td>
79
  <td>
80
  <label class="cae-toggle">
81
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['title'],$data['title_class']), true); ?> data-target=".js-cas-html-widget-title" />
@@ -92,5 +93,6 @@ $widget_title_opts = [
92
  </code>
93
  </td>
94
  </tr>
95
- </tbody></table>
 
96
  <p><?php _e('By default styling will be inherited from the Target Sidebar.', 'content-aware-sidebars'); ?></p>
37
 
38
  ?>
39
 
40
+ <table class="form-table cas-form-table" role="presentation">
41
+ <tbody>
42
  <tr>
43
+ <th scope="row"><?php _e('Sidebar'); ?></th>
44
  <td>
45
  <label class="cae-toggle">
46
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['sidebar'],$data['sidebar_class']), true); ?> data-target=".js-cas-html-sidebar" />
58
  </td>
59
  </tr>
60
  <tr>
61
+ <th scope="row"><?php _e('Widget'); ?></th>
62
  <td>
63
  <label class="cae-toggle">
64
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['widget'],$data['widget_class']), true); ?> data-target=".js-cas-html-widget" />
76
  </td>
77
  </tr>
78
  <tr>
79
+ <th scope="row"><?php _e('Widget Title'); ?></th>
80
  <td>
81
  <label class="cae-toggle">
82
  <input class="js-cas-html" type="checkbox" <?php checked(isset($data['title'],$data['title_class']), true); ?> data-target=".js-cas-html-widget-title" />
93
  </code>
94
  </td>
95
  </tr>
96
+ </tbody>
97
+ </table>
98
  <p><?php _e('By default styling will be inherited from the Target Sidebar.', 'content-aware-sidebars'); ?></p>
view/meta_box_status.php CHANGED
@@ -11,11 +11,10 @@ $deactivate_date = get_post_meta($post->ID, CAS_App::META_PREFIX.'deactivate_tim
11
 
12
  ?>
13
 
14
- <table class="form-table cas-form-table" width="100%">
15
  <tbody>
16
  <tr>
17
- <td scope="row"><?php _e('Activate', 'content-aware-sidebars'); ?>
18
- </td>
19
  <td>
20
  <span class="js-cas-activation">
21
  <input type="text" name="sidebar_activate"
@@ -32,8 +31,7 @@ $deactivate_date = get_post_meta($post->ID, CAS_App::META_PREFIX.'deactivate_tim
32
  </td>
33
  </tr>
34
  <tr>
35
- <td scope="row"><?php _e('Deactivate', 'content-aware-sidebars'); ?>
36
- </td>
37
  <td>
38
  <span class="js-cas-expiry">
39
  <input type="text" name="sidebar_deactivate"
@@ -49,4 +47,5 @@ $deactivate_date = get_post_meta($post->ID, CAS_App::META_PREFIX.'deactivate_tim
49
  </span>
50
  </td>
51
  </tr>
 
52
  </table>
11
 
12
  ?>
13
 
14
+ <table class="form-table cas-form-table" role="presentation">
15
  <tbody>
16
  <tr>
17
+ <th scope="row"><?php _e('Activate', 'content-aware-sidebars'); ?></th>
 
18
  <td>
19
  <span class="js-cas-activation">
20
  <input type="text" name="sidebar_activate"
31
  </td>
32
  </tr>
33
  <tr>
34
+ <th scope="row"><?php _e('Deactivate', 'content-aware-sidebars'); ?></th>
 
35
  <td>
36
  <span class="js-cas-expiry">
37
  <input type="text" name="sidebar_deactivate"
47
  </span>
48
  </td>
49
  </tr>
50
+ </tbody>
51
  </table>
view/meta_box_submit.php CHANGED
@@ -45,6 +45,6 @@ if (post_type_supports($post->post_type, 'revisions')) {
45
  </div>
46
  </li>
47
  <li>
48
- <?php echo CAS_Sidebar_Edit::form_field('visibility', '', 'dashicons dashicons-visibility'); ?>
49
  </li>
50
  </ul>
45
  </div>
46
  </li>
47
  <li>
48
+ <?php CAS_Sidebar_Edit::form_field('visibility', '', 'dashicons dashicons-visibility'); ?>
49
  </li>
50
  </ul>
view/meta_box_support.php CHANGED
@@ -9,13 +9,13 @@
9
  $locale = get_locale();
10
  global $cas_fs;
11
  ?>
12
- <img class="wpca-pull-right" style="border-radius:3px;" src="<?php echo $cas_fs->get_local_icon_url(); ?>" width="48" height="48" />
13
  <ul>
14
  <li><a href="https://dev.institute/docs/content-aware-sidebars/getting-started/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Get Started', 'content-aware-sidebars'); ?></a></li>
15
  <li><a href="https://dev.institute/docs/content-aware-sidebars/getting-started/display-sidebar-advanced/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Sidebar not displayed where expected?', 'content-aware-sidebars'); ?></a></li>
16
  <li><a href="https://dev.institute/docs/content-aware-sidebars/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Documentation & FAQ', 'content-aware-sidebars'); ?></a></li>
17
  <?php if (!$cas_fs->can_use_premium_code()) : ?>
18
- <li><a href="https://wordpress.org/support/plugin/content-aware-sidebars/" target="_blank" rel="noopener"><?php _e('Support Forums', 'content-aware-sidebars'); ?></a></li>
19
  <?php if (stripos($locale, 'en') !== 0) : ?>
20
  <li><a href="https://dev.institute/translate-content-aware-sidebars/" target="_blank" rel="noopener"><?php _e('Translate plugin &amp; get Pro version', 'content-aware-sidebars'); ?></a></li>
21
  <?php endif; ?>
9
  $locale = get_locale();
10
  global $cas_fs;
11
  ?>
12
+ <img class="wpca-pull-right" style="border-radius:3px;" src="<?php echo $cas_fs->get_local_icon_url(); ?>" width="48" height="48" alt="" />
13
  <ul>
14
  <li><a href="https://dev.institute/docs/content-aware-sidebars/getting-started/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Get Started', 'content-aware-sidebars'); ?></a></li>
15
  <li><a href="https://dev.institute/docs/content-aware-sidebars/getting-started/display-sidebar-advanced/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Sidebar not displayed where expected?', 'content-aware-sidebars'); ?></a></li>
16
  <li><a href="https://dev.institute/docs/content-aware-sidebars/?utm_source=plugin&amp;utm_medium=referral&amp;utm_content=info-box&amp;utm_campaign=cas" target="_blank" rel="noopener"><?php _e('Documentation & FAQ', 'content-aware-sidebars'); ?></a></li>
17
  <?php if (!$cas_fs->can_use_premium_code()) : ?>
18
+ <li><a href="https://wordpress.org/support/plugin/content-aware-sidebars/" target="_blank" rel="noopener noreferrer"><?php _e('Support Forums', 'content-aware-sidebars'); ?></a></li>
19
  <?php if (stripos($locale, 'en') !== 0) : ?>
20
  <li><a href="https://dev.institute/translate-content-aware-sidebars/" target="_blank" rel="noopener"><?php _e('Translate plugin &amp; get Pro version', 'content-aware-sidebars'); ?></a></li>
21
  <?php endif; ?>
view/notice_review.php CHANGED
@@ -5,9 +5,6 @@
5
  * @license GPLv3
6
  * @copyright 2021 by Joachim Jensen
7
  */
8
-
9
- //updated class for wp4.0 and below
10
-
11
  ?>
12
  <div class="notice notice-success updated js-cas-notice-review is-dismissible">
13
  <p>
@@ -19,7 +16,7 @@
19
  <br>
20
  <?php printf(
21
  __('May I ask you to %ssupport it with a 5-star rating%s? I have spent countless hours on the plugin, and this will help make it even better.', 'content-aware-sidebars'),
22
- '<strong><a target="_blank" href="https://wordpress.org/support/plugin/content-aware-sidebars/reviews/?rate=5#new-post" data-cas-rating="1">',
23
  '</a></strong>'
24
  ); ?>
25
  <br><br>
@@ -27,5 +24,5 @@
27
  <br>
28
  - Joachim Jensen
29
  </p>
30
- <p><a target="_blank" class="button-primary" href="https://wordpress.org/support/plugin/content-aware-sidebars/reviews/?rate=5#new-post" data-cas-rating="1"><?php _e('OK, you deserve it', 'content-aware-sidebars'); ?></a> <button class="button-secondary"><?php _e('No, not good enough', 'content-aware-sidebars'); ?></button> <button class="button-secondary" data-cas-rating="1"><?php _e('I already rated it', 'content-aware-sidebars'); ?></button></p>
31
  </div>
5
  * @license GPLv3
6
  * @copyright 2021 by Joachim Jensen
7
  */
 
 
 
8
  ?>
9
  <div class="notice notice-success updated js-cas-notice-review is-dismissible">
10
  <p>
16
  <br>
17
  <?php printf(
18
  __('May I ask you to %ssupport it with a 5-star rating%s? I have spent countless hours on the plugin, and this will help make it even better.', 'content-aware-sidebars'),
19
+ '<strong><a target="_blank" href="https://wordpress.org/support/plugin/content-aware-sidebars/reviews/?rate=5#new-post" data-cas-rating="1" rel="noopener noreferrer">',
20
  '</a></strong>'
21
  ); ?>
22
  <br><br>
24
  <br>
25
  - Joachim Jensen
26
  </p>
27
+ <p><a target="_blank" class="button-primary" href="https://wordpress.org/support/plugin/content-aware-sidebars/reviews/?rate=5#new-post" data-cas-rating="1" rel="noopener noreferrer"><?php _e('OK, you deserve it', 'content-aware-sidebars'); ?></a> <button class="button-secondary"><?php _e('No, not good enough', 'content-aware-sidebars'); ?></button> <button class="button-secondary" data-cas-rating="1"><?php _e('I already rated it', 'content-aware-sidebars'); ?></button></p>
28
  </div>