PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.0.2
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.0.2
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 / includes / class-convertkit-output.php

class-convertkit-output.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.0.2, at includes/class-convertkit-output.php

402 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Output class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Outputs Forms and Landing Pages on the frontend web site, based on
11 * the Post and Plugin's configuration.
12 *
13 * @since 1.9.6
14 */
15 class ConvertKit_Output {
16
17 /**
18 * Holds the ConvertKit Plugin Settings class
19 *
20 * @since 1.9.6
21 *
22 * @var bool|ConvertKit_Settings
23 */
24 private $settings = false;
25
26 /**
27 * Holds the ConvertKit Post Settings class
28 *
29 * @since 1.9.6
30 *
31 * @var bool|ConvertKit_Post
32 */
33 private $post_settings = false;
34
35 /**
36 * Holds the available ConvertKit Forms
37 *
38 * @since 1.9.6
39 *
40 * @var bool|ConvertKit_Resource_Forms
41 */
42 private $forms = false;
43
44 /**
45 * Holds the available ConvertKit Landing Pages
46 *
47 * @since 1.9.6
48 *
49 * @var bool|ConvertKit_Resource_Landing_Pages
50 */
51 private $landing_pages = false;
52
53 /**
54 * Constructor. Registers actions and filters to output ConvertKit Forms and Landing Pages
55 * on the frontend web site.
56 *
57 * @since 1.9.6
58 */
59 public function __construct() {
60
61 add_action( 'template_redirect', array( $this, 'output_form' ) );
62 add_action( 'template_redirect', array( $this, 'page_takeover' ) );
63 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
64 add_filter( 'the_content', array( $this, 'append_form_to_content' ) );
65
66 }
67
68 /**
69 * Runs the `convertkit_output_output_form` action for singular Post Types that don't use the_content()
70 * or apply_filters( 'the_content' ) to output a ConvertKit Form.
71 *
72 * @since 1.9.6
73 */
74 public function output_form() {
75
76 /**
77 * Outputs a ConvertKit Form on singular Post Types that don't use the_content()
78 * or apply_filters( 'the_content' ).
79 *
80 * @since 1.9.6
81 *
82 * @return string Post Content with Form Appended, if applicable
83 */
84 do_action( 'convertkit_output_output_form' );
85
86 }
87
88 /**
89 * Outputs a ConvertKit Landing Page if configured, replacing all output for the singular Post Type.
90 *
91 * @since 1.9.6
92 */
93 public function page_takeover() {
94
95 $queried_object = get_queried_object();
96
97 // Bail if the queried object cannot be inspected.
98 if ( ! isset( $queried_object->post_type ) ) {
99 return;
100 }
101
102 // Get Post ID.
103 $post_id = $queried_object->ID;
104
105 // Bail if the queried object isn't a supported Post Type for Landing Pages.
106 if ( $queried_object->post_type !== 'page' ) {
107 return;
108 }
109
110 // Get ConvertKit Post's Settings, if they have not yet been loaded.
111 if ( ! $this->post_settings ) {
112 $this->post_settings = new ConvertKit_Post( $post_id );
113 }
114
115 // Get Landing Page ID.
116 $landing_page_id = $this->post_settings->get_landing_page();
117
118 /**
119 * Define the ConvertKit Landing Page ID to display for the given Post ID,
120 * overriding the Post settings.
121 *
122 * Return false to not display any ConvertKit Landing Page.
123 *
124 * @since 1.9.6
125 *
126 * @param int $landing_page_id Landing Page ID
127 * @param int $post_id Post ID
128 */
129 $landing_page_id = apply_filters( 'convertkit_output_page_takeover_landing_page_id', $landing_page_id, $post_id );
130
131 // Bail if no Landing Page is configured to be output.
132 if ( empty( $landing_page_id ) ) {
133 return;
134 }
135
136 // Get available ConvertKit Landing Pages, if they have not yet been loaded.
137 if ( ! $this->landing_pages ) {
138 $this->landing_pages = new ConvertKit_Resource_Landing_Pages( 'output_landing_page' );
139 }
140
141 // Get Landing Page.
142 $landing_page = $this->landing_pages->get_html( $this->post_settings->get_landing_page() );
143
144 // Bail if an error occured.
145 if ( is_wp_error( $landing_page ) ) {
146 return;
147 }
148
149 // Output Landing Page.
150 // Output is supplied from ConvertKit's API, which is already sanitized.
151 echo $landing_page; // phpcs:ignore WordPress.Security.EscapeOutput
152 exit;
153
154 }
155
156 /**
157 * Appends a form to the singular Page, Post or Custom Post Type's Content.
158 *
159 * @param string $content Post Content.
160 * @return string Post Content with Form Appended, if applicable
161 */
162 public function append_form_to_content( $content ) {
163
164 // Bail if not a singular Post Type.
165 if ( ! is_singular() ) {
166 return $content;
167 }
168
169 // Get Post ID and ConvertKit Form ID for the Post.
170 $post_id = get_the_ID();
171 $form_id = $this->get_post_form_id( $post_id );
172
173 /**
174 * Define the ConvertKit Form ID to display for the given Post ID,
175 * overriding the Post, Category or Plugin settings.
176 *
177 * Return false to not display any ConvertKit Form.
178 *
179 * @since 1.9.6
180 *
181 * @param bool|int $form_id Form ID
182 * @param int $post_id Post ID
183 */
184 $form_id = apply_filters( 'convertkit_output_append_form_to_content_form_id', $form_id, $post_id );
185
186 // Return the Post Content, unedited, if the Form ID is false or zero.
187 if ( ! $form_id ) {
188 return $content;
189 }
190
191 // Get available ConvertKit Forms, if they have not yet been loaded.
192 if ( ! $this->forms ) {
193 $this->forms = new ConvertKit_Resource_Forms( 'output_form' );
194 }
195
196 // Get Form HTML.
197 $form = $this->forms->get_html( $form_id );
198
199 // If an error occured, it could be because the specified Form ID for the Post either:
200 // - belongs to another ConvertKit account (i.e. API credentials were changed in the Plugin, but this Post's specified Form was not changed), or
201 // - the form was deleted from the ConvertKit account.
202 // Attempt to fallback to the default form for this Post Type.
203 if ( is_wp_error( $form ) ) {
204 if ( $this->settings->debug_enabled() ) {
205 $content .= '<!-- ConvertKit append_form_to_content(): ' . $form->get_error_message() . ' Attempting fallback to Default Form. -->';
206 }
207
208 // Get Default Form ID for this Post's Type.
209 $form_id = $this->settings->get_default_form( get_post_type( $post_id ) );
210
211 // If no Default Form is specified, just return the Post Content, unedited.
212 if ( ! $form_id ) {
213 if ( $this->settings->debug_enabled() ) {
214 $content .= '<!-- ConvertKit append_form_to_content(): No Default Form exists as a fallback. -->';
215 }
216
217 return $content;
218 }
219
220 // Get Form HTML.
221 $form = $this->forms->get_html( $form_id );
222
223 // If an error occured again, the default form doesn't exist in this ConvertKit account.
224 // Just return the Post Content, unedited.
225 if ( is_wp_error( $form ) ) {
226 if ( $this->settings->debug_enabled() ) {
227 $content .= '<!-- ConvertKit append_form_to_content(): Default Form: ' . $form->get_error_message() . ' -->';
228 }
229
230 return $content;
231 }
232 }
233
234 // If here, we have a ConvertKit Form.
235 // Append form to Post's Content.
236 $content = $content .= $form;
237
238 /**
239 * Filter the Post's Content, which includes a ConvertKit Form, immediately before it is output.
240 *
241 * @since 1.9.6
242 *
243 * @param string $content Post Content
244 * @param string $form ConvertKit Form HTML
245 * @param int $post_id Post ID
246 * @param int $form_id ConvertKit Form ID
247 */
248 $content = apply_filters( 'convertkit_frontend_append_form', $content, $form, $post_id, $form_id );
249
250 return $content;
251
252 }
253
254 /**
255 * Returns the Post, Category or Plugin ConvertKit Form ID for the given Post.
256 *
257 * If the Post specifies a form to use, returns that Form ID.
258 * If the Post uses the 'Default' setting, and an assigned Category has a Form ID, uses the Category's Form ID.
259 * Otherwise falls back to the Plugin's Default Form ID (if any).
260 *
261 * @since 1.9.6
262 *
263 * @param int $post_id Post ID.
264 * @return bool|string|int false|'default'|Form ID
265 */
266 private function get_post_form_id( $post_id ) {
267
268 // Get Settings, if they have not yet been loaded.
269 if ( ! $this->settings ) {
270 $this->settings = new ConvertKit_Settings();
271 }
272
273 // Get ConvertKit Post's Settings, if they have not yet been loaded.
274 if ( ! $this->post_settings ) {
275 $this->post_settings = new ConvertKit_Post( $post_id );
276 }
277
278 // If the Post specifies a Form to use, return its ID now.
279 if ( $this->post_settings->has_form() ) {
280 return $this->post_settings->get_form();
281 }
282
283 // If the Post specifies that no Form should be used, return false.
284 if ( $this->post_settings->uses_no_form() ) {
285 return false;
286 }
287
288 // Sanity check that the Post uses the Default Form setting, which should be the case
289 // because the above conditions were not met.
290 if ( ! $this->post_settings->uses_default_form() ) {
291 return false;
292 }
293
294 // Get Post's Categories.
295 $categories = wp_get_post_categories(
296 $post_id,
297 array(
298 'fields' => 'ids',
299 )
300 );
301
302 // If no Categories exist, use the Default Form.
303 if ( ! is_array( $categories ) || ! count( $categories ) ) {
304 // Get Post Type.
305 return $this->settings->get_default_form( get_post_type( $post_id ) );
306 }
307
308 /**
309 * Iterate through Categories in reverse order.
310 * This honors the behaviour < 1.9.6, which states that if multiple Categories each have a Form.
311 * assigned, the last Category with a Form in the wp_get_post_categories() call will be used.
312 */
313 $categories = array_reverse( $categories );
314 foreach ( $categories as $term_id ) {
315 // Load Term Settings.
316 $term_settings = new ConvertKit_Term( $term_id );
317
318 // If a Form ID exists, return it now.
319 if ( $term_settings->has_form() ) {
320 return $term_settings->get_form();
321 }
322 }
323
324 // If here, use the Plugin's Default Form.
325 return $this->settings->get_default_form( get_post_type( $post_id ) );
326
327 }
328
329 /**
330 * Enqueue scripts.
331 *
332 * @since 1.9.6
333 */
334 public function enqueue_scripts() {
335
336 // Get Post.
337 $post = get_post();
338
339 // Bail if no Post could be fetched.
340 if ( ! $post ) {
341 return;
342 }
343
344 // Get ConvertKit Settings and Post's Settings.
345 $settings = new ConvertKit_Settings();
346 $convertkit_post = new ConvertKit_Post( $post->ID );
347
348 // Register scripts that we might use.
349 wp_register_script(
350 'convertkit-js',
351 CONVERTKIT_PLUGIN_URL . 'resources/frontend/js/convertkit.js',
352 array( 'jquery' ),
353 CONVERTKIT_PLUGIN_VERSION,
354 true
355 );
356 wp_localize_script(
357 'convertkit-js',
358 'convertkit',
359 array(
360 'ajaxurl' => admin_url( 'admin-ajax.php' ),
361 'debug' => $settings->debug_enabled(),
362 'nonce' => wp_create_nonce( 'convertkit' ),
363 'subscriber_id' => $this->get_subscriber_id_from_request(),
364 'tag' => ( ( is_singular() && $convertkit_post->has_tag() ) ? $convertkit_post->get_tag() : false ),
365 'post_id' => $post->ID,
366 )
367 );
368
369 // Bail if the no scripts setting is enabled.
370 if ( $settings->scripts_disabled() ) {
371 return;
372 }
373
374 // Enqueue.
375 wp_enqueue_script( 'convertkit-js' );
376
377 }
378
379 /**
380 * Gets the subscriber ID from the request (either the cookie or the URL).
381 *
382 * @since 1.9.6
383 *
384 * @return int Subscriber ID
385 */
386 public function get_subscriber_id_from_request() {
387
388 // Use ConvertKit_Subscriber class to fetch and validate the subscriber ID.
389 $subscriber = new ConvertKit_Subscriber();
390 $subscriber_id = $subscriber->get_subscriber_id();
391
392 // If an error occured, the subscriber ID in the request/cookie is not a valid subscriber.
393 if ( is_wp_error( $subscriber_id ) ) {
394 return 0;
395 }
396
397 return $subscriber_id;
398
399 }
400
401 }
402