PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 1.4.9
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v1.4.9
3.4.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 All 195 releases
convertkit / lib / class-convertkit-api.php

class-convertkit-api.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 1.4.9, at lib/class-convertkit-api.php

394 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 PI class
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * ConvertKit_API Class
11 * Establishes API connection to ConvertKit App
12 */
13 class ConvertKit_API {
14
15 /**
16 * ConvertKit API Key
17 *
18 * @var string
19 */
20 protected $api_key;
21
22 /**
23 * ConvertKit API Secret
24 *
25 * @var string
26 */
27 protected $api_secret;
28
29 /**
30 * Save debug data to log
31 *
32 * @var string
33 */
34 protected $debug;
35
36 /**
37 * Version of ConvertKit API
38 *
39 * @var string
40 */
41 protected $api_version = 'v3';
42
43 /**
44 * ConvertKit API URL
45 *
46 * @var string
47 */
48 protected $api_url_base = 'https://api.convertkit.com/';
49
50 /**
51 * API resources
52 *
53 * @var array
54 */
55 protected $resources = array();
56
57 /**
58 * Additional markup
59 *
60 * @var array
61 */
62 protected $markup = array();
63
64 /**
65 * Constructor for ConvertKitAPI instance
66 *
67 * @param string $api_key ConvertKit API Key.
68 * @param string $api_secret ConvertKit API Secret.
69 * @param string $debug Save data to log.
70 */
71 public function __construct( $api_key, $api_secret, $debug ) {
72 $this->api_key = $api_key;
73 $this->api_secret = $api_secret;
74 $this->debug = $debug;
75 }
76
77 /**
78 * Adds a tag to a subscriber
79 *
80 * @param int $tag Tag ID
81 * @param array $options Array of user data
82 * @return object
83 */
84 public function add_tag( $tag, $options ) {
85 $request = $this->api_version . sprintf( '/tags/%s/subscribe', $tag );
86
87 $args = array(
88 'api_key' => $this->api_key,
89 'email' => $options['email'],
90 );
91
92 return $this->make_request( $request, 'POST', $args );
93 }
94
95 /**
96 * Gets a resource index
97 *
98 * GET /{$resource}/
99 *
100 * @param string $resource Resource type.
101 * @return object API response
102 */
103 public function get_resources( $resource ) {
104
105 if ( ! array_key_exists( $resource, $this->resources ) ) {
106
107 if ( 'landing_pages' === $resource ) {
108 $api_response = $this->_get_api_response( 'forms' );
109 } else {
110 $api_response = $this->_get_api_response( $resource );
111 }
112
113 if ( is_null( $api_response ) || is_wp_error( $api_response ) || isset( $api_response['error'] ) || isset( $api_response['error_message'] ) ) {
114 $this->resources[ $resource ] = array(
115 array(
116 'id' => '-2',
117 'name' => 'Error contacting API',
118 ),
119 );
120 } else {
121 $_resource = array();
122
123 if ( 'forms' === $resource ) {
124 $response = isset( $api_response['forms'] ) ? $api_response['forms'] : array();
125 foreach ( $response as $form ) {
126 if ( isset( $form['archived'] ) && $form['archived'] ) {
127 continue;
128 }
129 $_resource[] = $form;
130 }
131 } elseif ( 'landing_pages' === $resource ) {
132
133 $response = isset( $api_response['forms'] ) ? $api_response['forms'] : array();
134 foreach ( $response as $landing_page ) {
135 if ( 'hosted' === $landing_page['type'] ) {
136 if ( isset( $landing_page['archived'] ) && $landing_page['archived'] ) {
137 continue;
138 }
139 $_resource[] = $landing_page;
140 }
141 }
142 } elseif ( 'subscription_forms' === $resource ) {
143 foreach ( $api_response as $mapping ) {
144 if ( isset( $mapping['archived'] ) && $mapping['archived'] ) {
145 continue;
146 }
147 $_resource[ $mapping['id'] ] = $mapping['form_id'];
148 }
149 } elseif ( 'tags' === $resource ) {
150 $response = isset( $api_response['tags'] ) ? $api_response['tags'] : array();
151 foreach ( $response as $tag ) {
152 $_resource[] = $tag;
153 }
154 }
155
156 $this->resources[ $resource ] = $_resource;
157 } // End if().
158 } // End if().
159
160 return $this->resources[ $resource ];
161 }
162
163 /**
164 * Adds a subscriber to a form.
165 *
166 * @param string $form_id Form ID.
167 * @param array $options Array of user data.
168 */
169 public function form_subscribe( $form_id, $options ) {
170 $request = $this->api_version . sprintf( '/forms/%s/subscribe', $form_id );
171
172 $args = array(
173 'api_key' => $this->api_key,
174 'email' => $options['email'],
175 'name' => $options['name'],
176 );
177
178 $this->make_request( $request, 'POST', $args );
179 }
180
181 /**
182 * Remove subscription from a form
183 *
184 * @param array $options Array of user data.
185 */
186 public function form_unsubscribe( $options ) {
187 $request = $this->api_version . '/unsubscribe';
188
189 $args = array(
190 'api_secret' => $this->api_secret,
191 'email' => $options['email'],
192 );
193
194 $this->make_request( $request, 'PUT', $args );
195 }
196
197 /**
198 * Get markup from ConvertKit for the provided $url
199 *
200 * @param string $url URL of API action.
201 * @return string
202 */
203 public function get_resource( $url ) {
204 $resource = '';
205
206 if ( ! empty( $url ) && isset( $this->markup[ $url ] ) ) {
207 $resource = $this->markup[ $url ];
208 } elseif ( ! empty( $url ) ) {
209 $this->log( 'API Request (get_resource): ' . $url );
210
211 $response = wp_remote_get(
212 $url,
213 array(
214 'timeout' => 10,
215 'Accept-Encoding' => 'gzip',
216 )
217 );
218
219 if ( ! is_wp_error( $response ) ) {
220
221 if ( ! function_exists( 'str_get_html' ) ) {
222 require_once( dirname( __FILE__ ) . '/../vendor/simple-html-dom/simple-html-dom.php' );
223 }
224
225 if ( ! function_exists( 'url_to_absolute' ) ) {
226 require_once( dirname( __FILE__ ) . '/../vendor/url-to-absolute/url-to-absolute.php' );
227 }
228
229 // Maybe inflate response body.
230 // @see https://wordpress.stackexchange.com/questions/10088/how-do-i-troubleshoot-responses-with-wp-http-api
231 $inflate = @gzinflate( $response['body'] );
232 if( false !== $inflate ) {
233 $response['body'] = $inflate;
234 }
235
236 $body = wp_remote_retrieve_body( $response );
237
238 $html = str_get_html( $body );
239 foreach ( $html->find( 'a, link' ) as $element ) {
240 if ( isset( $element->href ) ) {
241 $element->href = url_to_absolute( $url, $element->href );
242 }
243 }
244
245 foreach ( $html->find( 'img, script' ) as $element ) {
246 if ( isset( $element->src ) ) {
247 $element->src = url_to_absolute( $url, $element->src );
248 }
249 }
250
251 foreach ( $html->find( 'form' ) as $element ) {
252 if ( isset( $element->action ) ) {
253 $element->action = url_to_absolute( $url, $element->action );
254 } else {
255 $element->action = $url;
256 }
257 }
258
259 // Check `status_code` for 200, otherwise log error.
260 if ( 200 === $response['response']['code'] ) {
261 $resource = $html->save();
262 $this->markup[ $url ] = $resource;
263 } else {
264 $this->log( 'Status Code (' . $response['response']['code'] . ') for URL (' . $url . '): ' . $html->save() );
265 }
266 } else {
267 $this->log( 'API Response was WP_Error (get_resource): ' .
268 'Code: ' . $response->get_error_code() . ' ' .
269 'Message: ' . $response->get_error_message() );
270 } // End if().
271 } // End if().
272
273 return $resource;
274 }
275
276 /**
277 * Do a remote request.
278 *
279 * @param string $path Part of URL.
280 * @return array
281 */
282 private function _get_api_response( $path = '' ) {
283
284 $args = array(
285 'api_key' => $this->api_key,
286 );
287 $api_path = $this->api_url_base . $this->api_version;
288 $url = add_query_arg( $args, path_join( $api_path, $path ) );
289
290 $this->log( 'API Request (_get_api_response): ' . $url );
291
292 $data = get_transient( 'convertkit_get_api_response_' . $path );
293
294 if ( ! $data ) {
295
296 $response = wp_remote_get(
297 $url,
298 array(
299 'timeout' => 10,
300 'Accept-Encoding' => 'gzip',
301 'sslverify' => false,
302 )
303 );
304
305 if ( is_wp_error( $response ) ) {
306 $this->log( 'Error: ' . $response->get_error_message() );
307
308 return array(
309 'error' => $response->get_error_message(),
310 );
311 } else {
312
313 // Maybe inflate response body.
314 // @see https://wordpress.stackexchange.com/questions/10088/how-do-i-troubleshoot-responses-with-wp-http-api
315 $inflate = @gzinflate( $response['body'] );
316 if( false !== $inflate ) {
317 $response['body'] = $inflate;
318 }
319
320 $body = wp_remote_retrieve_body( $response );
321 $data = json_decode( $body, true );
322 }
323
324 set_transient( 'convertkit_get_api_response_' . $path , $data, 300 );
325
326 $this->log( 'API Response (_get_api_response): ' . $body );
327 } else {
328 $this->log( 'Transient Response ' . $path . ' (_get_api_response)' );
329 }
330
331 return $data;
332 }
333
334 /**
335 * Make a request to the ConvertKit API
336 *
337 * @param string $request Request string.
338 * @param string $method HTTP Method.
339 * @param array $args Request arguments.
340 * @return object Response object
341 */
342 private function make_request( $request, $method, $args = array() ) {
343
344 $this->log( 'API Request (make_request): ' . $request . ' Args: ' . wp_json_encode( $args ) );
345
346 $url = $this->api_url_base . $request;
347
348 $headers = array(
349 'Content-Type' => 'application/json; charset=utf-8',
350 );
351
352 $settings = array(
353 'headers' => $headers,
354 'method' => $method,
355 'body' => wp_json_encode( $args ),
356 );
357
358 $result = wp_remote_request( $url, $settings );
359
360 if ( is_wp_error( $result ) ) {
361 $this->log( 'API Response (make_request): WPError: ' . $result->get_error_message() );
362 } elseif ( isset( $result['response']['code'] ) && '200' === $result['response']['code'] ) {
363 if ( isset( $result['body'] ) ) {
364 $this->log( 'API Response (make_request): ' . $result['body'] );
365 } else {
366 $this->log( 'API Response (make_request): Response code 200, but body is not set.' );
367 }
368 } else {
369 $this->log( 'API Response (make_request): Result code: ' . $result['response']['code'] . ' ' . $result['response']['message'] );
370 }
371
372 }
373
374 /**
375 * Output data to log file
376 *
377 * @param string $message String to add to log.
378 */
379 public function log( $message ) {
380
381 if ( 'on' === $this->debug ) {
382 $dir = dirname( __FILE__ );
383 $handle = fopen( trailingslashit( $dir ) . 'log.txt', 'a' );
384 if ( $handle ) {
385 $time = date_i18n( 'm-d-Y @ H:i:s -' );
386 fwrite( $handle, $time . ' ' . $message . "\n" );
387 fclose( $handle );
388 }
389 }
390
391 }
392
393 }
394