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

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