PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.3.0
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.3.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 2.3.0, at admin/class-convertkit-admin-restrict-content.php

301 lines 9.5 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 Products resource class.
22 *
23 * @since 2.1.0
24 *
25 * @var bool|ConvertKit_Resource_Products
26 */
27 public $products = false;
28
29 /**
30 * Holds the Restrict Content Settings class.
31 *
32 * @since 2.1.0
33 *
34 * @var bool|ConvertKit_Settings_Restrict_Content
35 */
36 public $restrict_content_settings = false;
37
38 /**
39 * Holds the value chosen for the Restrict Content filter dropdown
40 * in the WP_List_Table.
41 *
42 * @since 2.1.0
43 *
44 * @var int|string
45 */
46 public $restrict_content_filter = 0;
47
48 /**
49 * Registers action and filter hooks.
50 *
51 * @since 2.1.0
52 */
53 public function __construct() {
54
55 // Initialize classes that will be used.
56 $this->restrict_content_settings = new ConvertKit_Settings_Restrict_Content();
57
58 // Bail if Restrict Content isn't enabled.
59 if ( ! $this->restrict_content_settings->enabled() ) {
60 return;
61 }
62
63 // Add New Member Content button.
64 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_and_css' ) );
65 foreach ( convertkit_get_supported_restrict_content_post_types() as $post_type ) {
66 add_filter( 'views_edit-' . $post_type, array( $this, 'output_wp_list_table_buttons' ) );
67 }
68
69 // Filter WP_List_Table by Restrict Content setting.
70 add_action( 'pre_get_posts', array( $this, 'filter_wp_list_table_output' ) );
71 add_action( 'restrict_manage_posts', array( $this, 'output_wp_list_table_filters' ) );
72
73 }
74
75 /**
76 * Enqueue JavaScript and CSS when viewing a list of Pages, Posts or Custom Post Types
77 * in a WP_List_Table that supports Restrict Content functionality.
78 *
79 * @since 2.1.0
80 */
81 public function enqueue_scripts_and_css() {
82
83 // Bail if we're not on a WP_List_Table screen for a supported Post Type.
84 if ( ! $this->is_wp_list_table_request_for_supported_post_type() ) {
85 return;
86 }
87
88 // Enqueue JS and CSS.
89 wp_enqueue_script( 'convertkit-admin-wp-list-table-buttons', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/wp-list-table-buttons.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
90 wp_enqueue_style( 'convertkit-admin-wp-list-table-buttons', CONVERTKIT_PLUGIN_URL . 'resources/backend/css/wp-list-table-buttons.css', array(), CONVERTKIT_PLUGIN_VERSION );
91
92 // Filter Page's post state to maybe include a label denoting that Restricted Content is enabled.
93 // We do this here so we don't run this on Post Types that don't support Restricted Content.
94 add_filter( 'display_post_states', array( $this, 'maybe_display_restrict_content_post_state' ), 10, 2 );
95
96 }
97
98 /**
99 * Query Pages in the WP_List_Table by the Restrict Content filter, if a filter
100 * was included in the request.
101 *
102 * @since 2.1.0
103 *
104 * @param WP_Query $query WordPress Query.
105 */
106 public function filter_wp_list_table_output( $query ) {
107
108 // Bail if no Restrict Content filter specified.
109 if ( ! array_key_exists( 'convertkit_restrict_content', $_REQUEST ) ) { // phpcs:ignore WordPress.Security.NonceVerification
110 return;
111 }
112 if ( ! $_REQUEST['convertkit_restrict_content'] ) { // phpcs:ignore WordPress.Security.NonceVerification
113 return;
114 }
115
116 // Don't filter if we're not querying a Post Type that supports Restricted Content.
117 if ( ! in_array( $query->get( 'post_type' ), convertkit_get_supported_restrict_content_post_types(), true ) ) {
118 return;
119 }
120
121 // Build query.
122 // Because WordPress stores metadata in a single serialized string for a single key, we have to search
123 // the string for the Restrict Content setting. However, other settings will also be in this serialized string,
124 // so to avoid false positives, we define our search value formatted as a serialized string comprising of the
125 // setting name and value, to be as accurate as possible.
126 $value = maybe_serialize(
127 array(
128 'restrict_content' => sanitize_text_field( $_REQUEST['convertkit_restrict_content'] ), // phpcs:ignore WordPress.Security.NonceVerification
129 )
130 );
131
132 // Strip a:1:{ and final }, as a Post's serialized settings will include other settings.
133 $value = str_replace( 'a:1:{', '', $value ); // e.g. s:16:"restrict_content";s:13:"product_36377";}.
134 $value = substr( $value, 0, strlen( $value ) - 1 ); // e.g. s:16:"restrict_content";s:13:"product_36377";.
135
136 // Add value to query.
137 $meta_query = array(
138 'key' => '_wp_convertkit_post_meta',
139 'value' => $value,
140 'compare' => 'LIKE',
141 );
142
143 // If the existing meta query is an array, append our query to it, so we honor
144 // any other constraints that have been defined by WordPress or third party code.
145 $existing_meta_query = $query->get( 'meta_query' );
146 if ( is_array( $existing_meta_query ) ) {
147 $existing_meta_query[] = $meta_query;
148 $query->set( 'meta_query', $existing_meta_query );
149 } else {
150 $query->set( 'meta_query', array( $meta_query ) );
151 }
152
153 // Store Restrict Content filter value.
154 $this->restrict_content_filter = sanitize_text_field( $_REQUEST['convertkit_restrict_content'] ); // phpcs:ignore WordPress.Security.NonceVerification
155
156 }
157
158 /**
159 * Outputs a button in the WP_List_Table filters to run the Restrict Content Setup process.
160 *
161 * JS will move this button to be displayed next to the "Add New" button when viewing the table of Pages or Posts,
162 * as there is not a native WordPress action/filter for registering buttons next to the "Add New" button.
163 *
164 * @since 2.1.0
165 *
166 * @param array $views Views.
167 * @return array Views
168 */
169 public function output_wp_list_table_buttons( $views ) {
170
171 // If no API credentials have been set, don't output the button.
172 $settings = new ConvertKit_Settings();
173 if ( ! $settings->has_api_key_and_secret() ) {
174 return $views;
175 }
176
177 // Get current post type that we're viewing.
178 $post_type = $this->get_current_post_type();
179
180 // Don't output button if we couldn't determine the current post type.
181 if ( ! $post_type ) {
182 return $views;
183 }
184
185 $views['convertkit_restrict_content_setup'] = '<a href="admin.php?page=convertkit-restrict-content-setup&post_type=' . esc_attr( $post_type ) . '" class="convertkit-action page-title-action hidden">' . esc_html__( 'Add New Member Content', 'convertkit' ) . '</a>';
186 return $views;
187
188 }
189
190 /**
191 * Outputs a dropdown filter on a WP_List_Table filter section to permit
192 * filtering by a Restrict Content Form, Tag or Product.
193 *
194 * @since 2.1.0
195 *
196 * @param string $post_type Post Type.
197 */
198 public function output_wp_list_table_filters( $post_type ) {
199
200 // Don't output filters if we're not viewing a Post Type that supports Restricted Content.
201 if ( ! in_array( $post_type, convertkit_get_supported_restrict_content_post_types(), true ) ) {
202 return;
203 }
204
205 // Don't output filters if API credentials have not been defined in the Plugin's settings.
206 $settings = new ConvertKit_Settings();
207 if ( ! $settings->has_api_key_and_secret() ) {
208 return;
209 }
210
211 // Fetch Products.
212 $this->products = new ConvertKit_Resource_Products();
213
214 // Don't display filter if no Products exist.
215 if ( ! $this->products->exist() ) {
216 return;
217 }
218
219 // Output filter.
220 include_once CONVERTKIT_PLUGIN_PATH . '/views/backend/post/wp-list-table-filter.php';
221
222 }
223
224 /**
225 * Appends the 'ConvertKit Member Content' text to a Page's Title in the WP_List_Table,
226 * if the given Page has a Restrict Content setting.
227 *
228 * @param string[] $post_states An array of post display states.
229 * @param WP_Post $post The current post object.
230 * @return string[] An array of post display states
231 */
232 public function maybe_display_restrict_content_post_state( $post_states, $post ) {
233
234 // Fetch Post's settings.
235 $convertkit_post = new ConvertKit_Post( $post->ID );
236
237 // Return post states, unedited, if Restrict Content isn't enabled on this Post.
238 if ( ! $convertkit_post->restrict_content_enabled() ) {
239 return $post_states;
240 }
241
242 // Add Post State.
243 $post_states['convertkit_restrict_content'] = esc_html__( 'ConvertKit Member Content', 'convertkit' );
244
245 // Return.
246 return $post_states;
247
248 }
249
250 /**
251 * Determines if the current request is for a WP_List_Table, and if so that
252 * the Post Type we're viewing supports Restrict Content functionality.
253 *
254 * @since 2.1.0
255 *
256 * @return bool Is WP_List_Table request for a supported Post Type.
257 */
258 private function is_wp_list_table_request_for_supported_post_type() {
259
260 // Bail if we cannot determine the screen.
261 if ( ! function_exists( 'get_current_screen' ) ) {
262 return false;
263 }
264
265 // Get screen.
266 $screen = get_current_screen();
267
268 // Bail if we're not on an edit.php screen.
269 if ( $screen->base !== 'edit' ) {
270 return false;
271 }
272
273 // Return whether Post Type is supported for Restrict Content functionality.
274 return in_array( $screen->post_type, convertkit_get_supported_restrict_content_post_types(), true );
275
276 }
277
278 /**
279 * Get the current post type based on the screen that is viewed.
280 *
281 * @since 2.1.0
282 *
283 * @return bool|string
284 */
285 private function get_current_post_type() {
286
287 // Bail if we cannot determine the screen.
288 if ( ! function_exists( 'get_current_screen' ) ) {
289 return false;
290 }
291
292 // Get screen.
293 $screen = get_current_screen();
294
295 // Return post type.
296 return $screen->post_type;
297
298 }
299
300 }
301