PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 3.7.0
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v3.7.0
3.7.0 3.6.0 3.6.1 3.5.2 trunk 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.6.0 2.6.1 3.0.0 3.0.1 All 71 releases
← All changes | src/class-stockpackquery.php +678 -128 2.13.7.0 View file →
@@ -1,12 +1,7 @@
1 1 <?php
2 2
3 3
4 -use GuzzleHttp\Client;
5 -use GuzzleHttp\Cookie\CookieJar;
6 -use GuzzleHttp\Exception\GuzzleException;
7 -use GuzzleHttp\TransferStats;
8 -
9 4 if ( ! defined( 'ABSPATH' ) ) {
10 5 exit;
11 6 }
12 7 if ( ! class_exists( 'StockpackQuery' ) ) {
@@ -24,17 +19,11 @@
24 19 * Api version
25 20 */
26 21 const VERSION = 'v1';
27 22
28 - /**
29 - * @var string
30 - */
31 - private $api_key;
23 + public $admin;
32 24
33 - /**
34 - * @var Client
35 - */
36 - private $client;
25 + public $settings;
37 26
38 27 public static function get_instance() {
39 28 if ( null === self::$instance ) {
40 29 self::$instance = new self();
@@ -52,10 +41,9 @@
52 41 } else {
53 42 $this->url = STOCKPACK_URL;
54 43 }
55 44
56 - $this->api_key =
57 - add_action( 'plugins_loaded', array( $this, 'init' ) );
45 + add_action( 'init', array( $this, 'init' ) );
58 46 }
59 47
60 48 /**
61 49 *
@@ -60,12 +48,21 @@
60 48 /**
61 49 *
62 50 */
63 51 public function init() {
52 + $this->admin = \StockpackAdmin::get_instance();
53 + $this->settings = \StockpackSettings::get_instance();
64 54 $this->actions();
55 + $this->filters();
65 56 }
66 57
58 + /**
59 + *
60 + */
61 + public function filters() {
67 62
63 + }
64 +
68 65 /**
69 66 *
70 67 */
71 68 public function actions() {
@@ -74,12 +71,21 @@
74 71 $this,
75 72 'license_cost'
76 73 ) ); // executed when logged in
77 74 add_action( 'wp_ajax_download-stockpack', array( $this, 'download' ) ); // executed when logged in
75 + add_action( 'wp_ajax_generate-stockpack', array( $this, 'generate' ) ); // executed when logged in
76 + add_action( 'wp_ajax_generate_status-stockpack', array(
77 + $this,
78 + 'generate_status'
79 + ) ); // executed when logged in
78 80 add_action( 'wp_ajax_cache-stockpack', array( $this, 'cache' ) ); // executed when logged in
79 81 add_action( 'wp_ajax_validate-stockpack', array( $this, 'validate' ) ); // executed when logged in
80 82 add_action( 'wp_ajax_terms-stockpack', array( $this, 'terms' ) ); // executed when logged in
81 83 add_action( 'wp_ajax_token-stockpack', array( $this, 'token' ) ); // executed when logged in
84 +
85 + if($this->settings->get_url_debugging_setting() ==='yes') {
86 + add_action('http_api_debug', array($this, 'debug_wp_remote_post_and_get_request'), 10, 5);
87 + }
82 88 }
83 89
84 90 public function terms() {
85 91 check_ajax_referer( 'stockpack_terms', 'security' );
@@ -98,10 +104,15 @@
98 104 if ( isset( $_REQUEST['media_id'] ) ) {
99 105 $media_id = sanitize_text_field( $_REQUEST['media_id'] );
100 106 }
101 107
102 - $response = $this->get_license_cost( $media_id );
108 + $provider = 0;
109 + if ( isset( $_REQUEST['provider'] ) ) {
110 + $provider = sanitize_text_field( $_REQUEST['provider'] );
111 + }
103 112
113 + $response = $this->get_license_cost( $media_id, $provider );
114 +
104 115 if ( isset( $response->data->error ) ) {
105 116 wp_send_json_error( $this->handle_license_errors( $response->data ) );
106 117 die();
107 118 }
@@ -118,13 +129,38 @@
118 129 if ( $response->data->cost == 1 && ! $response->data->cost_message ) {
119 130 $response->data->cost_message = __( 'You will be charged for one image on you provider account', 'stockpack' );
120 131 }
121 132
133 + if ( $this->already_in_library( $media_id ) ) {
134 + $response->data->cost_message = __( 'This image is already in your library. Adding it again reuses the file you downloaded before, so it will not use another download.', 'stockpack' );
135 + }
136 +
122 137 wp_send_json_success( $response->data, true );
123 138 }
124 139
140 + private function already_in_library( $media_id ) {
141 + if ( ! $media_id ) {
142 + return false;
143 + }
144 +
145 + $query = new WP_Query( array(
146 + 'post_type' => 'attachment',
147 + 'post_status' => 'inherit',
148 + 'fields' => 'ids',
149 + 'posts_per_page' => 1,
150 + 'meta_query' => array(
151 + array(
152 + 'key' => 'stockpack_id',
153 + 'value' => $media_id
154 + )
155 + )
156 + ) );
157 +
158 + return $query->have_posts();
159 + }
160 +
125 161 public function token() {
126 - global $stockpack;
162 + $stockpack = StockPack::get_instance();
127 163 check_ajax_referer( 'stockpack_token', 'security' );
128 164 $token = '';
129 165 if ( isset( $_REQUEST['token'] ) ) {
130 166 $token = sanitize_text_field( $_REQUEST['token'] );
@@ -140,9 +176,9 @@
140 176 $key = '';
141 177 if ( isset( $_REQUEST['key'] ) ) {
142 178 $key = sanitize_key( $_REQUEST['key'] );
143 179 }
144 - wp_send_json_success( $this->call( 'GET', 'validate/token', array( 'key' => $key )));
180 + wp_send_json_success( $this->call( 'GET', 'validate/token', array( 'key' => $key ) ) );
145 181 }
146 182
147 183 /**
148 184 *
@@ -151,14 +187,14 @@
151 187 check_ajax_referer( 'stockpack_query', 'security' );
152 188 if ( ! current_user_can( 'upload_files' ) ) {
153 189 wp_send_json_error();
154 190 }
155 - $query=array();
191 + $query = array();
156 192 if ( isset( $_REQUEST['query'] ) ) {
157 - $query = array_map( 'sanitize_text_field', wp_unslash($_REQUEST['query']));
193 + $query = array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['query'] ) );
158 194 }
159 195
160 - if ( ! $query['query'] ) {
196 + if ( ! isset( $query['query'] ) ) {
161 197 return wp_send_json_success( array() );
162 198 }
163 199
164 200 $images = $this->images( $query );
@@ -175,8 +211,99 @@
175 211
176 212 wp_send_json_success( $this->format( $images->data ) );
177 213 }
178 214
215 + public function generate() {
216 + check_ajax_referer( 'stockpack_generate', 'security' );
217 + if ( ! current_user_can( 'upload_files' ) ) {
218 + wp_send_json_error( array( 'message' => __( 'You are not allowed to upload files', 'stockpack' ) ) );
219 + }
220 +
221 + /** @var StockPack $stockpack */
222 + $stockpack = StockPack::get_instance();
223 + if ( ! $stockpack->settings->get_api_key() ) {
224 + wp_send_json_error( array(
225 + 'message' => __( 'Add your StockPack API key in the plugin settings before generating images.',
226 + 'stockpack' )
227 + ) );
228 + }
229 +
230 + $args = array(
231 + 'action' => $this->request_value( 'generate_action', 'generate' ),
232 + );
233 +
234 + if ( 'upscale' === $args['action'] ) {
235 + $args['image_url'] = esc_url_raw( $this->request_value( 'image_url' ) );
236 + $args['scale_factor'] = (int) $this->request_value( 'scale_factor', 2 );
237 +
238 + if ( ! $args['image_url'] ) {
239 + wp_send_json_error( array( 'message' => __( 'Pick an image to upscale.', 'stockpack' ) ) );
240 + }
241 + } else {
242 + $args['prompt'] = $this->request_value( 'prompt' );
243 + $args['model'] = $this->request_value( 'model', 'mystic-25' );
244 + $args['resolution'] = $this->request_value( 'resolution', '2k' );
245 +
246 + $refine = esc_url_raw( $this->request_value( 'refine_url' ) );
247 +
248 + if ( $refine ) {
249 + $args['refine_url'] = $refine;
250 + }
251 +
252 + if ( ! $args['prompt'] ) {
253 + wp_send_json_error( array( 'message' => __( 'Describe the image you want first.', 'stockpack' ) ) );
254 + }
255 + }
256 +
257 + $response = $this->call( 'POST', 'generate', $args );
258 +
259 + if ( is_wp_error( $response ) ) {
260 + wp_send_json_error( $this->error_payload( $response ) );
261 + }
262 +
263 + if ( isset( $response->error ) ) {
264 + wp_send_json_error( $this->handle_search_errors( $response ) );
265 + }
266 +
267 + wp_send_json_success( $this->with_wallet( $response->data ) );
268 + }
269 +
270 + public function generate_status() {
271 + check_ajax_referer( 'stockpack_generate', 'security' );
272 + if ( ! current_user_can( 'upload_files' ) ) {
273 + wp_send_json_error( array( 'message' => __( 'You are not allowed to upload files', 'stockpack' ) ) );
274 + }
275 +
276 + $task = $this->request_value( 'task' );
277 + if ( ! $task ) {
278 + wp_send_json_error( array( 'message' => __( 'Unknown generation task.', 'stockpack' ) ) );
279 + }
280 +
281 + $response = $this->call( 'GET', 'generate/' . rawurlencode( $task ) );
282 +
283 + if ( is_wp_error( $response ) ) {
284 + wp_send_json_error( $this->error_payload( $response ) );
285 + }
286 +
287 + if ( isset( $response->error ) ) {
288 + wp_send_json_error( $this->handle_search_errors( $response ) );
289 + }
290 +
291 + if ( isset( $response->data->status ) && 'pending' === $response->data->status ) {
292 + wp_send_json_success( $response->data );
293 + }
294 +
295 + wp_send_json_success( $this->with_wallet( $response->data ) );
296 + }
297 +
298 + private function request_value( $key, $default = '' ) {
299 + if ( ! isset( $_REQUEST[ $key ] ) ) {
300 + return $default;
301 + }
302 +
303 + return sanitize_text_field( wp_unslash( $_REQUEST[ $key ] ) );
304 + }
305 +
179 306 /**
180 307 *
181 308 */
182 309 public function cache() {
@@ -184,12 +311,12 @@
184 311
185 312 if ( ! current_user_can( 'upload_files' ) ) {
186 313 wp_send_json_error();
187 314 }
188 - $id=0;
315 + $id = 0;
189 316
190 317 if ( isset( $_REQUEST['media_id'] ) ) {
191 - $id = sanitize_text_field($_REQUEST['media_id']);
318 + $id = sanitize_text_field( $_REQUEST['media_id'] );
192 319 }
193 320 $args = array(
194 321 'post_type' => 'attachment',
195 322 'post_status' => 'inherit',
@@ -219,23 +346,33 @@
219 346 }
220 347
221 348 $id = 0;
222 349 if ( isset( $_REQUEST['media_id'] ) ) {
223 - $id = sanitize_text_field($_REQUEST['media_id']);
350 + $id = sanitize_text_field( $_REQUEST['media_id'] );
224 351 }
225 - $post_id=0;
352 + $post_id = 0;
226 353 if ( isset( $_REQUEST['post_id'] ) ) {
227 - $post_id = sanitize_text_field($_REQUEST['post_id']);
354 + $post_id = sanitize_text_field( $_REQUEST['post_id'] );
228 355 }
229 - $must_license=false;
356 + $provider = 0;
357 + if ( isset( $_REQUEST['provider'] ) ) {
358 + $provider = sanitize_text_field( $_REQUEST['provider'] );
359 + }
360 + $must_license = false;
230 361 if ( isset( $_REQUEST['must_license'] ) ) {
231 - $must_license = sanitize_text_field($_REQUEST['must_license']);
362 + $must_license = sanitize_text_field( $_REQUEST['must_license'] );
232 363 }
364 + $new_filename = "";
365 + if ( isset( $_REQUEST['new_filename'] ) ) {
366 + $new_filename = sanitize_text_field( $_REQUEST['new_filename'] );
367 + }
368 + $search = isset( $_REQUEST['search_key'] ) ? sanitize_title( $_REQUEST['search_key'] ) : $this->get_domain();
369 + $description = isset( $_REQUEST['description'] ) ? sanitize_textarea_field( $_REQUEST['description'] ) : '';
233 370
234 - $search = isset( $_REQUEST['search'] ) ? sanitize_title( $_REQUEST['search'] ) : $this->get_domain();
235 - $description = isset( $_REQUEST['description'] ) ? sanitize_textarea_field( $_REQUEST['description'] ) : '';
236 - $image = $this->image( $id, $post_id, $description, $search, $must_license );
237 371
372 +
373 + $image = $this->image( $id, $post_id, $description, $search, $must_license, $provider, $new_filename );
374 +
238 375 if ( is_wp_error( $image ) ) {
239 376 if ( strpos( $image->get_error_code(), 'limit_reached' ) !== false ) {
240 377 wp_send_json_error( $image );
241 378 die();
@@ -247,8 +384,31 @@
247 384
248 385 }
249 386
250 387
388 +
389 + public function is_provider_premium( $provider ) {
390 + return in_array( $provider, array(
391 + 'adobe_stock',
392 + 'getty',
393 + 'istock',
394 + 'deposit_photos'
395 + )
396 + );
397 + }
398 +
399 + public function images( $query = [] ) {
400 + if ( empty( $query['provider'] ) ) {
401 + $available = $this->settings->get_available_search_provider_slugs();
402 + if ( $available ) {
403 + $query['available_providers'] = implode( ',', $available );
404 + }
405 + }
406 +
407 + return $this->call( 'GET', 'images/search', $query );
408 + }
409 +
410 +
251 411 /**
252 412 * @param $data
253 413 *
254 414 * @return array
@@ -256,54 +416,104 @@
256 416 private function format( $data ) {
257 417 return $data;
258 418 }
259 419
260 - /**
261 - * @param $image
262 - *
263 - * @return array
264 - */
265 - private function individual( $image ) {
266 - return [
267 - 'id' => $image->id,
268 - 'description' => $image->description,
269 - 'caption' => $image->caption ? $image->caption : '',
270 - 'url' => $image->assets->huge_thumb->url,
271 - 'sizes' => [
272 - 'full' => $this->size( $image, 'huge_thumb' ),
273 - 'medium' => $this->size( $image, 'preview' ),
274 - 'thumbnail' => $this->size( $image, 'large_thumb' )
275 - ]
276 - ];
420 +
421 + public function get_license_cost( $media_id, $provider ) {
422 +
423 + return $this->call( 'GET', 'images/license-cost', array(
424 + 'id' => $media_id,
425 + 'locale' => get_locale(),
426 + 'provider' => $provider
427 + ) );
428 +
277 429 }
278 430
279 - private function size( $image, $format ) {
280 - return [
281 - 'height' => $image->assets->$format->height,
282 - 'width' => $image->assets->$format->width,
283 - 'orientation' => ( $image->aspect > 1 ? 'landscape' : 'portrait' ),
284 - 'url' => $image->assets->$format->url
285 - ];
431 + public function get_ai_prices() {
432 + $cached = get_transient( 'stockpack_ai_prices' );
433 +
434 + if ( is_array( $cached ) ) {
435 + return $cached;
436 + }
437 +
438 + return $this->fetch_ai_prices();
286 439 }
287 440
288 - private function get_license_cost( $media_id ) {
441 + public function get_ai_wallet( $fresh = false ) {
442 + $cached = get_transient( 'stockpack_ai_wallet' );
289 443
290 - $response = $this->call( 'GET', 'images/license-cost', array(
291 - 'id' => $media_id,
292 - 'locale' => get_locale(),
293 - ) );
444 + if ( is_array( $cached ) && ! $fresh ) {
445 + return $cached;
446 + }
294 447
295 - return $response;
448 + $prices = $this->fetch_ai_prices();
296 449
450 + if ( ! $prices && is_array( $cached ) ) {
451 + return $cached;
452 + }
297 453
454 + return $this->wallet_from( $prices );
298 455 }
299 456
300 - private function image( $media_id, $post_id, $description = '', $search = '', $must_license = 0 ) {
457 + public function dashboard_url( $path = '' ) {
458 + $base = defined( 'STOCKPACK_DASHBOARD_URL' ) ? STOCKPACK_DASHBOARD_URL : 'https://stockpack.co';
301 459
460 + return rtrim( $base, '/' ) . ( $path ? '/' . ltrim( $path, '/' ) : '' );
461 + }
462 +
463 + private function fetch_ai_prices() {
464 + $response = $this->call( 'GET', 'generate/prices' );
465 + $prices = array();
466 +
467 + if ( isset( $response->data ) ) {
468 + $prices = json_decode( wp_json_encode( $response->data ), true );
469 + }
470 +
471 + set_transient( 'stockpack_ai_prices', $prices, $prices ? DAY_IN_SECONDS : 5 * MINUTE_IN_SECONDS );
472 +
473 + if ( $prices ) {
474 + set_transient( 'stockpack_ai_wallet', $this->wallet_from( $prices ), MINUTE_IN_SECONDS );
475 + }
476 +
477 + return $prices;
478 + }
479 +
480 + private function wallet_from( $prices ) {
481 + $wallet = isset( $prices['wallet'] ) && is_array( $prices['wallet'] ) ? $prices['wallet'] : array();
482 + $balance = isset( $wallet['balance'] ) ? (int) $wallet['balance'] : null;
483 +
484 + return array(
485 + 'mode' => isset( $wallet['mode'] ) ? $wallet['mode'] : 'byok',
486 + 'balance' => $balance,
487 + 'balance_text' => null === $balance ? '' : number_format_i18n( $balance ),
488 + 'top_up_url' => ! empty( $wallet['top_up_url'] ) ? $wallet['top_up_url'] : $this->dashboard_url( 'billing/credits' ),
489 + 'connect_url' => $this->dashboard_url( 'providers' ),
490 + );
491 + }
492 +
493 + private function with_wallet( $data ) {
494 + $wallet = $this->get_ai_wallet();
495 +
496 + if ( 'managed' === $wallet['mode'] ) {
497 + $data->wallet = $this->get_ai_wallet( true );
498 + }
499 +
500 + return $data;
501 + }
502 +
503 + public function image( $media_id, $post_id, $description = '', $search = '', $must_license = 0, $provider = 0, $new_filename = '' ) {
504 +
505 + do_action( 'stockpack_before_attachment_download', $provider,$new_filename, $media_id, $must_license );
506 +
507 + $big_image_threshold = (int) apply_filters( 'big_image_size_threshold', 2560, array( 0, 0 ), '', 0 );
508 +
302 509 $image = $this->call( 'GET', 'images/download',
303 510 array(
304 511 'id' => $media_id,
305 - 'must_license' => $must_license
512 + 'must_license' => $must_license,
513 + 'provider' => $provider,
514 + 'min_width'=> $big_image_threshold,
515 + 'min_height'=> $big_image_threshold,
306 516 )
307 517 );
308 518
309 519 if ( ! isset( $image->data->download ) ) {
@@ -313,15 +523,17 @@
313 523
314 524 return $this->handle_download_errors( $image->data );
315 525 }
316 526
527 + $filename = $this->getFilename($image, $new_filename, $must_license);
528 +
317 529 $caption = $image->data->caption ?: '';
318 - $attachment_id = $this->upload_remote_image_and_attach( $image->data->download, $post_id, $description, $image->data->name, $search, $caption );
530 + $attachment_id = $this->upload_remote_image_and_attach( $image->data->download, $post_id, $description, $filename,$image, $search, $caption );
319 531 if ( is_wp_error( $attachment_id ) ) {
320 532 return $attachment_id;
321 533 }
322 534 if ( ! $attachment_id ) {
323 - return new WP_Error( __( 'upload_failure', 'There has been a problem with the upload. Please try again', 'stockpack' ) );
535 + return new WP_Error( 'upload_failure', __( 'There has been a problem with the upload. Please try again', 'stockpack' ) );
324 536 }
325 537
326 538 update_post_meta( $attachment_id, 'stockpack_id', $media_id );
327 539
@@ -331,13 +543,17 @@
331 543 private function handle_license_errors( $response ) {
332 544 if ( isset( $response->code ) ) {
333 545 switch ( $response->code ) {
334 546 case 'token_expired':
335 - return new WP_Error( 'license_cost_failure', __( 'Please reconnect the account on shutterstock, the permissions have expired. Go the providers page on stockpack.co/providers', 'stockpack' ) );
547 + return new WP_Error( 'license_cost_failure', __( 'Please reconnect the account on StockPack, the permissions have expired. Go the providers page on stockpack.co/providers', 'stockpack' ) );
336 548 }
549 +
550 + if ( ! empty( $response->message ) ) {
551 + return new WP_Error( $response->code, $response->message );
552 + }
337 553 }
338 554
339 - return new WP_Error( 'license_cost_failure', __( 'There has been a problem fetching the cost. Please try to reconnect the account on the providers page on shutterstock.co/providers', 'stockpack' ) );
555 + return new WP_Error( 'license_cost_failure', __( 'There has been a problem fetching the cost. Please try to reconnect the account on the providers page on stockpack.co/providers', 'stockpack' ) );
340 556 }
341 557
342 558 private function handle_download_errors( $response ) {
343 559 if ( isset( $response->code ) ) {
@@ -342,10 +558,14 @@
342 558 private function handle_download_errors( $response ) {
343 559 if ( isset( $response->code ) ) {
344 560 switch ( $response->code ) {
345 561 case 'token_expired':
346 - return new WP_Error( 'download_failure', __( 'Please reconnect the account on shutterstock, the permissions have expired. Go the providers page on stockpack.co/providers', 'stockpack' ) );
562 + return new WP_Error( 'token_expired', __( 'Please reconnect the account on StockPack, the permissions have expired. Go the providers page on stockpack.co/providers', 'stockpack' ) );
347 563 }
564 +
565 + if ( ! empty( $response->message ) ) {
566 + return new WP_Error( $response->code, $response->message );
567 + }
348 568 }
349 569
350 570 return new WP_Error( 'download_failure', __( 'There has been a problem with the download. Try to reconnect the account for the provider on StockPack. If the issue persists, contact stockpack support.', 'stockpack' ) );
351 571 }
@@ -353,9 +573,9 @@
353 573 private function handle_search_errors( $response ) {
354 574 if ( isset( $response->code ) ) {
355 575 switch ( $response->code ) {
356 576 case 'token_expired':
357 - return new WP_Error( 'search_failure', __( 'Please reconnect the account on stockpack, the permissions have expired. Go to the providers page on stockpack.co/providers', 'stockpack' ) );
577 + return new WP_Error( 'token_expired', __( 'Please reconnect the account on stockpack, the permissions have expired. Go to the providers page on stockpack.co/providers', 'stockpack' ) );
358 578 }
359 579 }
360 580
361 581 return new WP_Error( 'search_failure', __( 'There has been a problem with the api, please check the accounts on the providers page in stockpack.co/providers', 'stockpack' ) );
@@ -361,13 +581,9 @@
361 581 return new WP_Error( 'search_failure', __( 'There has been a problem with the api, please check the accounts on the providers page in stockpack.co/providers', 'stockpack' ) );
362 582
363 583 }
364 584
365 - private function images( $query = [] ) {
366 585
367 - return $this->call( 'GET', 'images/search', $query );
368 - }
369 -
370 586 /**
371 587 * @param $method
372 588 * @param $path
373 589 * @param array $query
@@ -375,57 +591,126 @@
375 591 * @return mixed|null
376 592 */
377 593 private function call( $method, $path, $query = [] ) {
378 594 /** @var StockPack $stockpack */
379 - global $stockpack;
595 + $stockpack = StockPack::get_instance();
380 596
381 - try {
382 - if ( ! isset( $query['key'] ) ) {
383 - $api_key = $stockpack->admin->get_api_key();
384 - if ( $api_key ) {
385 - $query = array_merge( $query,
386 - [
387 - 'api_token' => $api_key
388 - ]
389 - );
390 - } else {
391 - $path .= '-trial';
392 - }
597 +
598 + if ( ! isset( $query['key'] ) ) {
599 + $api_key = $stockpack->settings->get_api_key();
600 + if ( $api_key ) {
601 + $query = array_merge( $query,
602 + [
603 + 'api_token' => $api_key
604 + ]
605 + );
606 + } else {
607 + $path .= '-trial';
393 608 }
609 + }
394 610
395 - $query = array_merge( $query,
396 - [
397 - 'referral' => get_bloginfo( 'url' ),
398 - 'safe_search' => $stockpack->admin->get_safe_search(),
399 - 'user_data' => $stockpack->admin->get_license_state(),
400 - ]
401 - );
611 + $query = array_merge( $query,
612 + [
613 + 'referral' => get_bloginfo( 'url' ),
614 + 'safe_search' => $stockpack->settings->get_safe_search(),
615 + 'user_data' => $stockpack->settings->get_license_state(),
616 + ]
617 + );
402 618
403 - $response = $this->client()->request( $method, $path,
404 - [
405 - 'query' => $query
406 - ]
407 - );
619 + $url = $this->url . '/' . self::VERSION . '/' . $path;
620 + $is_post = 'post' === strtolower( $method );
408 621
409 - return json_decode( $response->getBody() );
410 - } catch ( GuzzleException $exception ) {
411 - switch ( $exception->getCode() ) {
622 + if ( ! $is_post ) {
623 + $url .= '?' . http_build_query( $query );
624 + }
625 +
626 + do_action( 'stockpack_before_api_request', $url, $query );
627 +
628 + $headers = array( 'Accept' => 'application/json' );
629 +
630 + if ( $is_post ) {
631 + $response = wp_remote_post( $url, array(
632 + 'timeout' => 20,
633 + 'sslverify' => false,
634 + 'headers' => $headers,
635 + 'body' => $query,
636 + ) );
637 + } else {
638 + $response = wp_remote_get( $url, array(
639 + 'timeout' => apply_filters( 'stockpack_api_timeout', $this->timeout_for( $path ), $path ),
640 + 'sslverify' => false,
641 + 'headers' => $headers,
642 + ) );
643 + }
644 +
645 + do_action( 'stockpack_after_api_request', $url, $query, $response );
646 +
647 + if ( is_wp_error( $response ) ) {
648 + return $response;
649 + }
650 +
651 + $response_code = wp_remote_retrieve_response_code( $response );
652 + if ( $response_code !== 200 ) {
653 + switch ( $response_code ) {
412 654 case 429: // too many requests
413 - return $this->limit_exceeded( $exception );
414 -
655 + return $this->limit_exceeded( $response );
656 + case 401: // access denied
657 + return $this->invalid_token( $response );
415 658 default:
416 - return new WP_Error( 1, __( 'Can\'t connect to StockPack server.', 'stockpack' ) );
659 + return $this->server_error( $response, $response_code );
417 660 }
418 661 }
662 +
663 + $response_body = wp_remote_retrieve_body( $response );
664 +
665 + return json_decode( $response_body );
419 666 }
420 667
421 - private function limit_exceeded( $exception ) {
668 + private function timeout_for( $path ) {
669 + return strpos( $path, 'images/download' ) === 0 ? 30 : 10;
670 + }
671 +
672 + private function error_payload( $error ) {
673 + $payload = array(
674 + 'code' => $error->get_error_code(),
675 + 'message' => $error->get_error_message(),
676 + );
677 + $wallet = $this->get_ai_wallet();
678 +
679 + if ( 'insufficient_credits' === $payload['code'] ) {
680 + $data = $error->get_error_data();
681 + $payload['link'] = ! empty( $data->top_up_url ) ? $data->top_up_url : $wallet['top_up_url'];
682 + $payload['link_text'] = __( 'Top up credits', 'stockpack' );
683 + }
684 +
685 + if ( 'managed' === $wallet['mode'] ) {
686 + $payload['wallet'] = $this->get_ai_wallet( true );
687 + }
688 +
689 + return $payload;
690 + }
691 +
692 + private function server_error( $response, $response_code ) {
693 + $body = json_decode( wp_remote_retrieve_body( $response ) );
694 +
695 + if ( ! empty( $body->message ) ) {
696 + return new WP_Error( ! empty( $body->code ) ? $body->code : 1, $body->message, $body );
697 + }
698 +
699 + return new WP_Error( 1, sprintf(
700 + /* translators: %d: HTTP status code returned by the StockPack API */
701 + __( 'The StockPack server returned an error (HTTP %d). If this keeps happening, contact StockPack support.', 'stockpack' ),
702 + $response_code
703 + ) );
704 + }
705 +
706 + private function limit_exceeded( $response ) {
422 707 /** @var StockPack $stockpack */
423 - global $stockpack;
708 + $stockpack = StockPack::get_instance();
424 709
425 - $response = $exception->getResponse();
426 - $limit = $response->getHeaderLine( 'x-ratelimit-limit' );
427 - $retry_after = $response->getHeaderLine( 'retry-after' );
710 +
711 + $limit = wp_remote_retrieve_header( $response, 'x-ratelimit-limit' );
712 + $retry_after = wp_remote_retrieve_header( $response, 'retry-after' );
428 713 $retry_after = $this->human_seconds( $retry_after );
429 714 $retry_after = '<span class ="stockpack-timer">' . $retry_after . '</span>';
430 715 if ( $limit > 50 ) {
431 716 return new WP_Error( 'premium_limit_reached', __( 'Request limit reached, the reset will be in ', 'stockpack' ) . $retry_after );
@@ -438,22 +723,10 @@
438 723
439 724 return new WP_Error( 'anonymous_limit_reached', __( 'Request limit reached, the reset will be in ', 'stockpack' ) . $retry_after );
440 725 }
441 726
442 - /**
443 - * @return Client
444 - */
445 - private function client() {
446 -
447 - if ( ! $this->client ) {
448 - $this->client = new Client(
449 - [
450 - 'base_uri' => $this->url . '/' . self::VERSION . '/',
451 - ]
452 - );
453 - }
454 -
455 - return $this->client;
727 + private function invalid_token( $response ) {
728 + return new WP_Error( 'invalid_token', __( 'Request denied. Please check your token!', 'stockpack' ) );
456 729 }
457 730
458 731 private function support_caption_translation( $caption ) {
459 732 if ( ! $caption ) {
@@ -478,36 +751,74 @@
478 751 * @param string $caption
479 752 *
480 753 * @return bool|int|WP_Error
481 754 */
482 - private function upload_remote_image_and_attach( $image_url, $parent_id, $description, $name, $search = '', $caption = '' ) {
755 + private function upload_remote_image_and_attach( $image_url, $parent_id, $description, $name, $image, $search = '', $caption = '' ) {
483 756
484 - $image = $image_url;
485 - $get = wp_remote_get( $image, array( 'timeout' => 30 ) );
757 + $get = wp_remote_get( $image_url, array(
758 + 'timeout' => apply_filters( 'stockpack_download_timeout', 30 )
759 + )
760 + );
486 761 if ( is_wp_error( $get ) ) {
487 762 return new WP_Error( 100, __( 'Image download failed, please try again. Errors:', 'stockpack' ) . PHP_EOL . $get->get_error_message() );
488 763 }
489 764 $type = wp_remote_retrieve_header( $get, 'content-type' );
490 765 if ( ! $type ) {
766 + $type = wp_check_filetype( $name )['type'];
767 + }
768 + if ( ! $type ) {
491 769 return new WP_Error( 100, __( 'Image type couldn\'t be determined', 'stockpack' ) );
492 770 }
771 + $name = $this->update_extension( $name, $type );
772 +
773 + $name = apply_filters( 'stockpack_attachment_filename', $name, $image );
774 +
493 775 $mirror = wp_upload_bits( $name, '', wp_remote_retrieve_body( $get ) );
494 776 $attachment = array(
495 - 'post_title' => $name,
777 + 'post_title' => $this->strip_extension($name),
496 778 'post_content' => $description,
497 - 'post_excerpt' => $this->support_caption_translation( $caption ),
779 + 'post_excerpt' => apply_filters( 'stockpack_caption', $this->support_caption_translation( $caption ), $image ),
498 780 'post_mime_type' => $type
499 781 );
500 782 $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );
501 783 require_once( ABSPATH . 'wp-admin/includes/image.php' );
784 +
785 + // An upscale that WordPress immediately scales back down is an
786 + // upscale the user paid for and did not get, so the threshold is
787 + // lifted for the result of one. Priority 999 so it wins over a theme
788 + // or plugin that lowers it.
789 + $is_upscale = isset( $image->data->meta->action ) && 'upscale' === $image->data->meta->action;
790 +
791 + if ( $is_upscale ) {
792 + add_filter( 'big_image_size_threshold', '__return_false', 999 );
793 + }
794 +
502 795 $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );
503 796 wp_update_attachment_metadata( $attach_id, $attach_data );
797 +
798 + if ( $is_upscale ) {
799 + remove_filter( 'big_image_size_threshold', '__return_false', 999 );
800 + }
504 801 update_post_meta( $attach_id, '_wp_attachment_image_alt', $description );
802 + $this->store_attachment_meta($attach_id,$image);
505 803
804 + do_action( 'stockpack_after_attachment_uploaded', $attach_id, $image );
805 +
506 806 return $attach_id;
507 807
508 808 }
509 809
810 + private function store_attachment_meta($attach_id, $image){
811 + $data = $image->data;
812 + $meta = isset($data->meta) ? $data->meta : new stdClass();
813 + update_post_meta($attach_id,'stockpack_media_id',$data->id);
814 + update_post_meta($attach_id,'stockpack_provider',isset($meta->provider) ? $meta->provider : '');
815 + update_post_meta($attach_id,'stockpack_author_url',isset($meta->author_url) ? $meta->author_url : '');
816 + update_post_meta($attach_id,'stockpack_author_name',isset($meta->author_name) ? $meta->author_name : '');
817 + update_post_meta($attach_id,'stockpack_image_url',isset($meta->image_url) ? $meta->image_url : '');
818 + update_post_meta($attach_id,'stockpack_download_timestamp',time());
819 + }
820 +
510 821 /**
511 822 * @return mixed
512 823 */
513 824 private function get_domain() {
@@ -520,8 +831,247 @@
520 831
521 832 private function human_seconds( $seconds, $separator = ":" ) {
522 833 return sprintf( "%02d%s%02d%s%02d", floor( $seconds / 3600 ), $separator, ( $seconds / 60 ) % 60, $separator, $seconds % 60 );
523 834 }
835 +
836 + private function update_extension( $name, $mime ) {
837 + $name = explode( '.', $name );
838 + $extension = $this->mime2ext( $mime );
839 + if ( $extension ) {
840 + return $name[0] . '.' . $extension;
841 + }
842 +
843 + return $name[0] . '.' . $name[1];
844 +
845 + }
846 +
847 + private function strip_extension( $name ) {
848 + $name = explode( '.', $name );
849 + return $name[0];
850 + }
851 +
852 + private function getFilename($image, $new_filename, $must_license)
853 + {
854 + $stockpack = StockPack::get_instance();
855 +
856 + $filename = $image->data->name;
857 +
858 + if($new_filename) {
859 + $filename = $new_filename;
860 + }
861 +
862 + if(!$this->is_provider_premium($image->data->provider) || $must_license) {
863 + return $filename;
864 + }
865 +
866 + if($stockpack->settings->add_license_state_to_filename()==='yes') {
867 + $filename = '--sto--placeholder--' . $image->data->provider.'--'.$image->data->id.'--'.$filename;
868 + }
869 +
870 + return $filename;
871 + }
872 +
873 + public function debug_wp_remote_post_and_get_request( $response, $context, $class, $r, $url ) {
874 + error_log( '------------------------------' );
875 + error_log( $url );
876 + error_log( json_encode( $response ) );
877 + error_log( $class );
878 + error_log( $context );
879 + error_log( json_encode( $r ) );
880 + }
881 +
882 + private function mime2ext( $mime ) {
883 + $mime = str_replace( ';charset=UTF-8', '', $mime );
884 + $mime_map = [
885 + 'video/3gpp2' => '3g2',
886 + 'video/3gp' => '3gp',
887 + 'video/3gpp' => '3gp',
888 + 'application/x-compressed' => '7zip',
889 + 'audio/x-acc' => 'aac',
890 + 'audio/ac3' => 'ac3',
891 + 'application/postscript' => 'ai',
892 + 'audio/x-aiff' => 'aif',
893 + 'audio/aiff' => 'aif',
894 + 'audio/x-au' => 'au',
895 + 'video/x-msvideo' => 'avi',
896 + 'video/msvideo' => 'avi',
897 + 'video/avi' => 'avi',
898 + 'application/x-troff-msvideo' => 'avi',
899 + 'application/macbinary' => 'bin',
900 + 'application/mac-binary' => 'bin',
901 + 'application/x-binary' => 'bin',
902 + 'application/x-macbinary' => 'bin',
903 + 'image/bmp' => 'bmp',
904 + 'image/x-bmp' => 'bmp',
905 + 'image/x-bitmap' => 'bmp',
906 + 'image/x-xbitmap' => 'bmp',
907 + 'image/x-win-bitmap' => 'bmp',
908 + 'image/x-windows-bmp' => 'bmp',
909 + 'image/ms-bmp' => 'bmp',
910 + 'image/x-ms-bmp' => 'bmp',
911 + 'application/bmp' => 'bmp',
912 + 'application/x-bmp' => 'bmp',
913 + 'application/x-win-bitmap' => 'bmp',
914 + 'application/cdr' => 'cdr',
915 + 'application/coreldraw' => 'cdr',
916 + 'application/x-cdr' => 'cdr',
917 + 'application/x-coreldraw' => 'cdr',
918 + 'image/cdr' => 'cdr',
919 + 'image/x-cdr' => 'cdr',
920 + 'zz-application/zz-winassoc-cdr' => 'cdr',
921 + 'application/mac-compactpro' => 'cpt',
922 + 'application/pkix-crl' => 'crl',
923 + 'application/pkcs-crl' => 'crl',
924 + 'application/x-x509-ca-cert' => 'crt',
925 + 'application/pkix-cert' => 'crt',
926 + 'text/css' => 'css',
927 + 'text/x-comma-separated-values' => 'csv',
928 + 'text/comma-separated-values' => 'csv',
929 + 'application/vnd.msexcel' => 'csv',
930 + 'application/x-director' => 'dcr',
931 + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
932 + 'application/x-dvi' => 'dvi',
933 + 'message/rfc822' => 'eml',
934 + 'application/x-msdownload' => 'exe',
935 + 'video/x-f4v' => 'f4v',
936 + 'audio/x-flac' => 'flac',
937 + 'video/x-flv' => 'flv',
938 + 'image/gif' => 'gif',
939 + 'application/gpg-keys' => 'gpg',
940 + 'application/x-gtar' => 'gtar',
941 + 'application/x-gzip' => 'gzip',
942 + 'application/mac-binhex40' => 'hqx',
943 + 'application/mac-binhex' => 'hqx',
944 + 'application/x-binhex40' => 'hqx',
945 + 'application/x-mac-binhex40' => 'hqx',
946 + 'text/html' => 'html',
947 + 'image/x-icon' => 'ico',
948 + 'image/x-ico' => 'ico',
949 + 'image/vnd.microsoft.icon' => 'ico',
950 + 'text/calendar' => 'ics',
951 + 'application/java-archive' => 'jar',
952 + 'application/x-java-application' => 'jar',
953 + 'application/x-jar' => 'jar',
954 + 'image/jp2' => 'jp2',
955 + 'video/mj2' => 'jp2',
956 + 'image/jpx' => 'jp2',
957 + 'image/jpm' => 'jp2',
958 + 'image/jpeg' => 'jpg',
959 + 'image/pjpeg' => 'jpg',
960 + 'application/x-javascript' => 'js',
961 + 'application/json' => 'json',
962 + 'text/json' => 'json',
963 + 'application/vnd.google-earth.kml+xml' => 'kml',
964 + 'application/vnd.google-earth.kmz' => 'kmz',
965 + 'text/x-log' => 'log',
966 + 'audio/x-m4a' => 'm4a',
967 + 'application/vnd.mpegurl' => 'm4u',
968 + 'audio/midi' => 'mid',
969 + 'application/vnd.mif' => 'mif',
970 + 'video/quicktime' => 'mov',
971 + 'video/x-sgi-movie' => 'movie',
972 + 'audio/mpeg' => 'mp3',
973 + 'audio/mpg' => 'mp3',
974 + 'audio/mpeg3' => 'mp3',
975 + 'audio/mp3' => 'mp3',
976 + 'video/mp4' => 'mp4',
977 + 'video/mpeg' => 'mpeg',
978 + 'application/oda' => 'oda',
979 + 'audio/ogg' => 'ogg',
980 + 'video/ogg' => 'ogg',
981 + 'application/ogg' => 'ogg',
982 + 'application/x-pkcs10' => 'p10',
983 + 'application/pkcs10' => 'p10',
984 + 'application/x-pkcs12' => 'p12',
985 + 'application/x-pkcs7-signature' => 'p7a',
986 + 'application/pkcs7-mime' => 'p7c',
987 + 'application/x-pkcs7-mime' => 'p7c',
988 + 'application/x-pkcs7-certreqresp' => 'p7r',
989 + 'application/pkcs7-signature' => 'p7s',
990 + 'application/pdf' => 'pdf',
991 + 'application/octet-stream' => 'pdf',
992 + 'application/x-x509-user-cert' => 'pem',
993 + 'application/x-pem-file' => 'pem',
994 + 'application/pgp' => 'pgp',
995 + 'application/x-httpd-php' => 'php',
996 + 'application/php' => 'php',
997 + 'application/x-php' => 'php',
998 + 'text/php' => 'php',
999 + 'text/x-php' => 'php',
1000 + 'application/x-httpd-php-source' => 'php',
1001 + 'image/png' => 'png',
1002 + 'image/x-png' => 'png',
1003 + 'application/powerpoint' => 'ppt',
1004 + 'application/vnd.ms-powerpoint' => 'ppt',
1005 + 'application/vnd.ms-office' => 'ppt',
1006 + 'application/msword' => 'doc',
1007 + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'pptx',
1008 + 'application/x-photoshop' => 'psd',
1009 + 'image/vnd.adobe.photoshop' => 'psd',
1010 + 'audio/x-realaudio' => 'ra',
1011 + 'audio/x-pn-realaudio' => 'ram',
1012 + 'application/x-rar' => 'rar',
1013 + 'application/rar' => 'rar',
1014 + 'application/x-rar-compressed' => 'rar',
1015 + 'audio/x-pn-realaudio-plugin' => 'rpm',
1016 + 'application/x-pkcs7' => 'rsa',
1017 + 'text/rtf' => 'rtf',
1018 + 'text/richtext' => 'rtx',
1019 + 'video/vnd.rn-realvideo' => 'rv',
1020 + 'application/x-stuffit' => 'sit',
1021 + 'application/smil' => 'smil',
1022 + 'text/srt' => 'srt',
1023 + 'image/svg+xml' => 'svg',
1024 + 'application/x-shockwave-flash' => 'swf',
1025 + 'application/x-tar' => 'tar',
1026 + 'application/x-gzip-compressed' => 'tgz',
1027 + 'image/tiff' => 'tiff',
1028 + 'text/plain' => 'txt',
1029 + 'text/x-vcard' => 'vcf',
1030 + 'application/videolan' => 'vlc',
1031 + 'text/vtt' => 'vtt',
1032 + 'audio/x-wav' => 'wav',
1033 + 'audio/wave' => 'wav',
1034 + 'audio/wav' => 'wav',
1035 + 'application/wbxml' => 'wbxml',
1036 + 'video/webm' => 'webm',
1037 + 'audio/x-ms-wma' => 'wma',
1038 + 'application/wmlc' => 'wmlc',
1039 + 'video/x-ms-wmv' => 'wmv',
1040 + 'video/x-ms-asf' => 'wmv',
1041 + 'application/xhtml+xml' => 'xhtml',
1042 + 'application/excel' => 'xl',
1043 + 'application/msexcel' => 'xls',
1044 + 'application/x-msexcel' => 'xls',
1045 + 'application/x-ms-excel' => 'xls',
1046 + 'application/x-excel' => 'xls',
1047 + 'application/x-dos_ms_excel' => 'xls',
1048 + 'application/xls' => 'xls',
1049 + 'application/x-xls' => 'xls',
1050 + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
1051 + 'application/vnd.ms-excel' => 'xlsx',
1052 + 'application/xml' => 'xml',
1053 + 'text/xml' => 'xml',
1054 + 'text/xsl' => 'xsl',
1055 + 'application/xspf+xml' => 'xspf',
1056 + 'application/x-compress' => 'z',
1057 + 'application/x-zip' => 'zip',
1058 + 'application/zip' => 'zip',
1059 + 'application/x-zip-compressed' => 'zip',
1060 + 'application/s-compressed' => 'zip',
1061 + 'multipart/x-zip' => 'zip',
1062 + 'text/x-scriptzsh' => 'zsh',
1063 + 'application/illustrator' => 'ai',
1064 + 'application/eps' => 'eps',
1065 + 'application/x-eps' => 'eps',
1066 + 'image/eps' => 'eps',
1067 + 'image/x-eps' => 'eps'
1068 + ];
1069 +
1070 + return isset( $mime_map[ $mime ] ) === true ? $mime_map[ $mime ] : false;
1071 + }
1072 +
1073 +
524 1074
525 1075 }
526 1076
527 1077 $GLOBALS['stockpack_query'] = StockpackQuery::get_instance();