PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.0
3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 2.3.2 2.3.3 All 194 releases
convertkit / admin / class-convertkit-admin-restrict-content.php

class-convertkit-admin-restrict-content.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.0, at admin/class-convertkit-admin-restrict-content.php

363 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Admin Restrict Content class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Modifies the Pages WP_List_Table to provide:
11 * - an 'Add New Member Content' button next to the 'Add New' button
12 * - a dropdown filter to show Pages restricted to a Form, Tag or Product
13 * - a 'ConvertKit Member Content' label appended to the Page's title when a Form, Tag or Product is selected
14 *
15 * @package ConvertKit
16 * @author ConvertKit
17 */
18 class ConvertKit_Admin_Restrict_Content {
19
20 /**
21 * Holds the ConvertKit Forms resource class.
22 *
23 * @since 2.7.3
24 *
25 * @var bool|ConvertKit_Resource_Forms
26 */
27 public $forms = false;
28
29 /**
30 * Holds the ConvertKit Tags resource class.
31 *
32 * @since 2.3.2
33 *
34 * @var bool|ConvertKit_Resource_Tags
35 */
36 public $tags = false;
37
38 /**
39 * Holds the ConvertKit Products resource class.
40 *
41 * @since 2.1.0
42 *
43 * @var bool|ConvertKit_Resource_Products
44 */
45 public $products = false;
46
47 /**
48 * Holds the Restrict Content Settings class.
49 *
50 * @since 2.1.0
51 *
52 * @var bool|ConvertKit_Settings_Restrict_Content
53 */
54 public $restrict_content_settings = false;
55
56 /**
57 * Holds the value chosen for the Restrict Content filter dropdown
58 * in the WP_List_Table.
59 *
60 * @since 2.1.0
61 *
62 * @var int|string
63 */
64 public $restrict_content_filter = 0;
65
66 /**
67 * Holds the key for the restrict content enabled flag in the WordPress options table.
68 *
69 * @since 3.0.4
70 *
71 * @var string
72 */
73 public $restrict_content_enabled_key = 'convertkit_restrict_content_enabled';
74
75 /**
76 * Registers action and filter hooks.
77 *
78 * @since 2.1.0
79 */
80 public function __construct() {
81
82 // Add New Member Content Wizard button to Pages.
83 add_filter( 'convertkit_admin_post_register_add_new_buttons', array( $this, 'register_add_new_button' ), 10, 2 );
84
85 // Filter Page's post state to maybe include a label denoting that Restricted Content is enabled.
86 // We do this here so we don't run this on Post Types that don't support Restricted Content.
87 add_filter( 'display_post_states', array( $this, 'maybe_display_restrict_content_post_state' ), 10, 2 );
88
89 // Filter WP_List_Table by Restrict Content setting.
90 add_action( 'pre_get_posts', array( $this, 'filter_wp_list_table_output' ) );
91 add_action( 'restrict_manage_posts', array( $this, 'output_wp_list_table_filters' ) );
92
93 // Update whether any Pages, Posts or CPTs are configured to use Restrict Content when a Page, Post or CPT is created, edited, trashed or deleted.
94 add_action( 'wp_insert_post', array( $this, 'update_restrict_content_enabled' ) );
95 add_action( 'trashed_post', array( $this, 'update_restrict_content_enabled' ) );
96 add_action( 'delete_post', array( $this, 'update_restrict_content_enabled' ) );
97
98 }
99
100 /**
101 * Update whether any Pages, Posts or CPTs are configured to use Restrict Content when a
102 * Page, Post or CPT is created, edited or deleted.
103 *
104 * @since 3.0.4
105 */
106 public function update_restrict_content_enabled() {
107
108 global $wpdb;
109
110 // We don't use WP_Query, as it's expensive on sites with many Pages/Posts/CPTs.
111 $results = $wpdb->get_results(
112 $wpdb->prepare(
113 'SELECT ' . $wpdb->posts . '.ID
114 FROM ' . $wpdb->postmeta . '
115 LEFT JOIN ' . $wpdb->posts . ' ON ' . $wpdb->postmeta . '.post_id = ' . $wpdb->posts . ".ID
116 WHERE (
117 (meta_key = '_wp_convertkit_post_meta' AND meta_value LIKE %s)
118 AND
119 (meta_key = '_wp_convertkit_post_meta' AND meta_value NOT LIKE %s)
120 AND
121 (meta_key = '_wp_convertkit_post_meta' AND meta_value NOT LIKE %s)
122 )
123 AND
124 " . $wpdb->posts . ".post_status = 'publish'
125 AND
126 " . $wpdb->posts . ".post_type IN ('" . implode( "', '", convertkit_get_supported_post_types() ) . "') LIMIT 1;", // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
127 '%' . $wpdb->esc_like( '"restrict_content";' ) . '%',
128 '%' . $wpdb->esc_like( '"restrict_content";s:0:' ) . '%',
129 '%' . $wpdb->esc_like( '"restrict_content";s:1:"0"' ) . '%'
130 )
131 );
132
133 // If results are not empty, a Page, Post or CPT is configured to use Restrict Content.
134 $restrict_content_enabled = ! empty( $results );
135
136 // Update option.
137 update_option( $this->restrict_content_enabled_key, $restrict_content_enabled );
138
139 }
140
141 /**
142 * Returns whether any Pages, Posts or CPTs are configured to use Restrict Content.
143 *
144 * @since 3.0.4
145 *
146 * @return bool
147 */
148 public function restrict_content_enabled() {
149
150 return (bool) get_option( $this->restrict_content_enabled_key, false );
151
152 }
153
154 /**
155 * Query Pages in the WP_List_Table by the Restrict Content filter, if a filter
156 * was included in the request.
157 *
158 * @since 2.1.0
159 *
160 * @param WP_Query $query WordPress Query.
161 */
162 public function filter_wp_list_table_output( $query ) {
163
164 // Bail if no Restrict Content filter specified.
165 if ( ! filter_has_var( INPUT_GET, 'convertkit_restrict_content' ) ) {
166 return;
167 }
168
169 // Bail if the filter is empty.
170 if ( empty( filter_input( INPUT_GET, 'convertkit_restrict_content', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) ) {
171 return;
172 }
173
174 // Don't filter if we're not querying a Post Type that supports Restricted Content.
175 if ( ! in_array( $query->get( 'post_type' ), convertkit_get_supported_post_types(), true ) ) {
176 return;
177 }
178
179 // Store Restrict Content filter value.
180 $this->restrict_content_filter = filter_input( INPUT_GET, 'convertkit_restrict_content', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
181
182 switch ( $this->restrict_content_filter ) {
183 case 'all-member-only':
184 $meta_query = array(
185 'key' => '_wp_convertkit_post_meta',
186 'value' => '.*?(form|tag|product)_[0-9]+.*?',
187 'compare' => 'REGEXP',
188 );
189 break;
190 default:
191 // Build query.
192 // Because WordPress stores metadata in a single serialized string for a single key, we have to search
193 // the string for the Restrict Content setting. However, other settings will also be in this serialized string,
194 // so to avoid false positives, we define our search value formatted as a serialized string comprising of the
195 // setting name and value, to be as accurate as possible.
196 $value = maybe_serialize(
197 array(
198 'restrict_content' => $this->restrict_content_filter,
199 )
200 );
201
202 // Strip a:1:{ and final }, as a Post's serialized settings will include other settings.
203 $value = str_replace( 'a:1:{', '', $value ); // e.g. s:16:"restrict_content";s:13:"product_36377";}.
204 $value = substr( $value, 0, strlen( $value ) - 1 ); // e.g. s:16:"restrict_content";s:13:"product_36377";.
205
206 // Add value to query.
207 $meta_query = array(
208 'key' => '_wp_convertkit_post_meta',
209 'value' => $value,
210 'compare' => 'LIKE',
211 );
212 break;
213 }
214
215 // If the existing meta query is an array, append our query to it, so we honor
216 // any other constraints that have been defined by WordPress or third party code.
217 $existing_meta_query = $query->get( 'meta_query' );
218 if ( is_array( $existing_meta_query ) ) {
219 $existing_meta_query[] = $meta_query;
220 $query->set( 'meta_query', $existing_meta_query );
221 } else {
222 $query->set( 'meta_query', array( $meta_query ) );
223 }
224
225 }
226
227 /**
228 * Registers a button in the Pages WP_List_Table linking to the the Restrict Content Setup Wizard.
229 *
230 * @since 2.5.5
231 *
232 * @param array $buttons Buttons.
233 * @param string $post_type Post Type.
234 * @return array Views
235 */
236 public function register_add_new_button( $buttons, $post_type ) {
237
238 // If no API credentials have been set, don't output the button.
239 $settings = new ConvertKit_Settings();
240 if ( ! $settings->has_access_and_refresh_token() ) {
241 return $buttons;
242 }
243
244 // If the Add New Landing Page / Member Content button is disabled, don't output the button.
245 if ( $settings->add_new_button_disabled() ) {
246 return $buttons;
247 }
248
249 // Bail if the Post Type isn't supported.
250 if ( ! in_array( $post_type, convertkit_get_supported_post_types(), true ) ) {
251 return $buttons;
252 }
253
254 // Don't show the button if the user cannot create and publish this Post Type.
255 if ( ! convertkit_user_can_create_published_post_type( $post_type ) ) {
256 return $buttons;
257 }
258
259 // Register button.
260 $buttons['convertkit_restrict_content_setup'] = array(
261 'url' => add_query_arg(
262 array(
263 'page' => 'convertkit-restrict-content-setup',
264 'ck_post_type' => $post_type,
265 ),
266 admin_url( 'options.php' )
267 ),
268 'label' => __( 'Member Content', 'convertkit' ),
269 );
270
271 return $buttons;
272
273 }
274
275 /**
276 * Outputs a dropdown filter on a WP_List_Table filter section to permit
277 * filtering by a Restrict Content Form, Tag or Product.
278 *
279 * @since 2.1.0
280 *
281 * @param string $post_type Post Type.
282 */
283 public function output_wp_list_table_filters( $post_type ) {
284
285 // Don't output filters if we're not viewing a Post Type that supports Restricted Content.
286 if ( ! in_array( $post_type, convertkit_get_supported_post_types(), true ) ) {
287 return;
288 }
289
290 // Don't output filters if API credentials have not been defined in the Plugin's settings.
291 $settings = new ConvertKit_Settings();
292 if ( ! $settings->has_access_and_refresh_token() ) {
293 return;
294 }
295
296 // Initialize Forms, Products and Tags resource classes.
297 $this->forms = new ConvertKit_Resource_Forms();
298 $this->products = new ConvertKit_Resource_Products();
299 $this->tags = new ConvertKit_Resource_Tags();
300
301 // Don't display filter if no Tags and no Products exist.
302 if ( ! $this->products->exist() && ! $this->tags->exist() ) {
303 return;
304 }
305
306 // Output filter.
307 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/post/wp-list-table-filter.php';
308
309 }
310
311 /**
312 * Appends the 'Kit Member Content' text to a Page's Title in the WP_List_Table,
313 * if the given Page has a Restrict Content setting.
314 *
315 * @param string[] $post_states An array of post display states.
316 * @param WP_Post $post The current post object.
317 * @return string[] An array of post display states
318 */
319 public function maybe_display_restrict_content_post_state( $post_states, $post ) {
320
321 // Bail if we're not on a WP_List_Table screen for a supported Post Type.
322 if ( ! $this->is_wp_list_table_request_for_supported_post_type() ) {
323 return $post_states;
324 }
325
326 // Fetch Post's settings.
327 $convertkit_post = new ConvertKit_Post( $post->ID );
328
329 // Return post states, unedited, if Restrict Content isn't enabled on this Post.
330 if ( ! $convertkit_post->restrict_content_enabled() ) {
331 return $post_states;
332 }
333
334 // Add Post State.
335 $post_states['convertkit_restrict_content'] = esc_html__( 'Kit Member Content', 'convertkit' );
336
337 // Return.
338 return $post_states;
339
340 }
341
342 /**
343 * Determines if the current request is for a WP_List_Table, and if so that
344 * the Post Type we're viewing supports Restrict Content functionality.
345 *
346 * @since 2.1.0
347 *
348 * @return bool Is WP_List_Table request for a supported Post Type.
349 */
350 private function is_wp_list_table_request_for_supported_post_type() {
351
352 // Bail if we're not on an edit.php screen.
353 if ( convertkit_get_current_screen( 'base' ) !== 'edit' ) {
354 return false;
355 }
356
357 // Return whether Post Type is supported for Restrict Content functionality.
358 return in_array( convertkit_get_current_screen( 'post_type' ), convertkit_get_supported_post_types(), true );
359
360 }
361
362 }
363