PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 3.7.2
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v3.7.2
3.7.2 3.7.1 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 All 73 releases
← All changes | src/class-stockpackquery.php +464 -118 2.4.3 → 3.7.2 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'] );
@@ -156,9 +192,9 @@
156 192 if ( isset( $_REQUEST['query'] ) ) {
157 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() {
@@ -225,17 +352,27 @@
225 352 $post_id = 0;
226 353 if ( isset( $_REQUEST['post_id'] ) ) {
227 354 $post_id = sanitize_text_field( $_REQUEST['post_id'] );
228 355 }
356 + $provider = 0;
357 + if ( isset( $_REQUEST['provider'] ) ) {
358 + $provider = sanitize_text_field( $_REQUEST['provider'] );
359 + }
229 360 $must_license = false;
230 361 if ( isset( $_REQUEST['must_license'] ) ) {
231 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
@@ -333,8 +545,12 @@
333 545 switch ( $response->code ) {
334 546 case 'token_expired':
335 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 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 }
@@ -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 StockPack, 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,38 +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 }
493 771 $name = $this->update_extension( $name, $type );
494 772
773 + $name = apply_filters( 'stockpack_attachment_filename', $name, $image );
774 +
495 775 $mirror = wp_upload_bits( $name, '', wp_remote_retrieve_body( $get ) );
496 776 $attachment = array(
497 - 'post_title' => $name,
777 + 'post_title' => $this->strip_extension($name),
498 778 'post_content' => $description,
499 - 'post_excerpt' => $this->support_caption_translation( $caption ),
779 + 'post_excerpt' => apply_filters( 'stockpack_caption', $this->support_caption_translation( $caption ), $image ),
500 780 'post_mime_type' => $type
501 781 );
502 782 $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );
503 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 +
504 795 $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );
505 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 + }
506 801 update_post_meta( $attach_id, '_wp_attachment_image_alt', $description );
802 + $this->store_attachment_meta($attach_id,$image);
507 803
804 + do_action( 'stockpack_after_attachment_uploaded', $attach_id, $image );
805 +
508 806 return $attach_id;
509 807
510 808 }
511 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 +
512 821 /**
513 822 * @return mixed
514 823 */
515 824 private function get_domain() {
@@ -534,8 +843,43 @@
534 843 return $name[0] . '.' . $name[1];
535 844
536 845 }
537 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 +
538 882 private function mime2ext( $mime ) {
539 883 $mime = str_replace( ';charset=UTF-8', '', $mime );
540 884 $mime_map = [
541 885 'video/3gpp2' => '3g2',
@@ -610,10 +954,10 @@
610 954 'image/jp2' => 'jp2',
611 955 'video/mj2' => 'jp2',
612 956 'image/jpx' => 'jp2',
613 957 'image/jpm' => 'jp2',
614 - 'image/jpeg' => 'jpeg',
615 - 'image/pjpeg' => 'jpeg',
958 + 'image/jpeg' => 'jpg',
959 + 'image/pjpeg' => 'jpg',
616 960 'application/x-javascript' => 'js',
617 961 'application/json' => 'json',
618 962 'text/json' => 'json',
619 963 'application/vnd.google-earth.kml+xml' => 'kml',
@@ -724,8 +1068,10 @@
724 1068 ];
725 1069
726 1070 return isset( $mime_map[ $mime ] ) === true ? $mime_map[ $mime ] : false;
727 1071 }
1072 +
1073 +
728 1074
729 1075 }
730 1076
731 1077 $GLOBALS['stockpack_query'] = StockpackQuery::get_instance();