# stockpack/2.1/src/class-stockpackquery.php

StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more, version 2.1. 529 lines.

- Page: https://pluginprobe.com/plugins/stockpack/2.1/code/src/class-stockpackquery.php
- Raw: https://pluginprobe.com/plugins/stockpack/2.1/raw/src/class-stockpackquery.php
- Modified: 2019-12-03T06:19:48+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/stockpack/2.1/code/src/class-stockpackquery.php#L10-L20`.

```php
<?php


use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\TransferStats;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}
if ( ! class_exists( 'StockpackQuery' ) ) {
    class StockpackQuery {
        /**
         * @var Singleton The reference the *Singleton* instance of this class
         */
        private static $instance;

        /**
         * Api url
         */
        private $url = 'https://api.stockpack.co/api';
        /**
         * Api version
         */
        const VERSION = 'v1';

        /**
         * @var string
         */
        private $api_key;

        /**
         * @var Client
         */
        private $client;

        public static function get_instance() {
            if ( null === self::$instance ) {
                self::$instance = new self();
            }

            return self::$instance;
        }

        /**
         * StockPack constructor.
         */
        protected function __construct() {
            if ( ! defined( 'STOCKPACK_URL' ) ) {
                $this->url = 'https://api.stockpack.co/api';
            } else {
                $this->url = STOCKPACK_URL;
            }

            $this->api_key =
                add_action( 'plugins_loaded', array( $this, 'init' ) );
        }

        /**
         *
         */
        public function init() {
            $this->actions();
        }


        /**
         *
         */
        public function actions() {
            add_action( 'wp_ajax_query-stockpack', array( $this, 'query' ) ); // executed when logged in
            add_action( 'wp_ajax_license_cost-stockpack', array(
                $this,
                'license_cost'
            ) ); // executed when logged in
            add_action( 'wp_ajax_download-stockpack', array( $this, 'download' ) ); // executed when logged in
            add_action( 'wp_ajax_cache-stockpack', array( $this, 'cache' ) ); // executed when logged in
            add_action( 'wp_ajax_validate-stockpack', array( $this, 'validate' ) ); // executed when logged in
            add_action( 'wp_ajax_terms-stockpack', array( $this, 'terms' ) ); // executed when logged in
            add_action( 'wp_ajax_token-stockpack', array( $this, 'token' ) ); // executed when logged in
        }

        public function terms() {
            check_ajax_referer( 'stockpack_terms', 'security' );

            $provider = '';
            if ( isset( $_REQUEST['provider'] ) ) {
                $provider = sanitize_key( $_REQUEST['provider'] );
            }

            wp_send_json_success( update_option( 'terms_accepted_' . $provider, true ) );
        }

        public function license_cost() {
            check_ajax_referer( 'stockpack_license_cost', 'security' );
            $media_id = '';
            if ( isset( $_REQUEST['media_id'] ) ) {
                $media_id = sanitize_text_field( $_REQUEST['media_id'] );
            }

            $response = $this->get_license_cost( $media_id );

            if ( isset( $response->data->error ) ) {
                wp_send_json_error( $this->handle_license_errors( $response->data ) );
                die();
            }

            if ( is_wp_error( $response ) ) {
                wp_send_json_error( $this->handle_license_errors( $response ) );
                die();
            }

            if ( $response->data->cost == - 1 ) {
                $response->data->cost_message = __( 'You already own the asset, you can proceed without additional cost', 'stockpack' );
            }

            if ( $response->data->cost == 1 && ! $response->data->cost_message ) {
                $response->data->cost_message = __( 'You will be charged for one image on you provider account', 'stockpack' );
            }

            wp_send_json_success( $response->data, true );
        }

        public function token() {
            global $stockpack;
            check_ajax_referer( 'stockpack_token', 'security' );
            $token = '';
            if ( isset( $_REQUEST['token'] ) ) {
                $token = sanitize_text_field( $_REQUEST['token'] );
            }
            wp_send_json_success( $stockpack->admin->set_api_key( $token ), true );
        }

        /**
         *
         */
        public function validate() {
            check_ajax_referer( 'stockpack_validate', 'security' );
            $key = '';
            if ( isset( $_REQUEST['key'] ) ) {
                $key = sanitize_key( $_REQUEST['key'] );
            }
            wp_send_json_success( $this->call( 'GET', 'validate/token', array( 'key' => $key  )));
        }

        /**
         *
         */
        public function query() {
            check_ajax_referer( 'stockpack_query', 'security' );
            if ( ! current_user_can( 'upload_files' ) ) {
                wp_send_json_error();
            }
            $query=array();
            if ( isset( $_REQUEST['query'] ) ) {
                $query = array_map( 'sanitize_text_field', wp_unslash($_REQUEST['query']));
            }

            if ( ! $query['query'] ) {
                return wp_send_json_success( array() );
            }

            $images = $this->images( $query );
            if ( is_wp_error( $images ) ) {
                /** @var WP_Error $images */
                wp_send_json_error( $images );
                die();
            }

            if ( isset( $images->data->error ) ) {
                wp_send_json_error( $this->handle_search_errors( $images->data ) );
                die();
            }

            wp_send_json_success( $this->format( $images->data ) );
        }

        /**
         *
         */
        public function cache() {
            check_ajax_referer( 'stockpack_cache', 'security' );

            if ( ! current_user_can( 'upload_files' ) ) {
                wp_send_json_error();
            }
            $id=0;

            if ( isset( $_REQUEST['media_id'] ) ) {
                $id = sanitize_text_field($_REQUEST['media_id']);
            }
            $args = array(
                'post_type'   => 'attachment',
                'post_status' => 'inherit',
                'meta_query'  => array(
                    array(
                        'key'   => 'stockpack_id',
                        'value' => $id
                    )
                )
            );
            $query = new WP_Query( $args );
            if ( ! $query->have_posts() ) {
                wp_send_json_error( array( 'message' => __( 'Image not found in cache', 'stockpack' ) ) );
            }

            wp_send_json_success( wp_prepare_attachment_for_js( $query->post->ID ) );

        }

        /**
         *
         */
        public function download() {
            check_ajax_referer( 'stockpack_download', 'security' );
            if ( ! current_user_can( 'upload_files' ) ) {
                wp_send_json_error( array( 'message' => __( 'You are not allowed to upload files', 'stockpack' ) ) );
            }

            $id = 0;
            if ( isset( $_REQUEST['media_id'] ) ) {
                $id = sanitize_text_field($_REQUEST['media_id']);
            }
            $post_id=0;
            if ( isset( $_REQUEST['post_id'] ) ) {
                $post_id = sanitize_text_field($_REQUEST['post_id']);
            }
            $must_license=false;
            if ( isset( $_REQUEST['must_license'] ) ) {
                $must_license = sanitize_text_field($_REQUEST['must_license']);
            }

            $search = isset( $_REQUEST['search'] ) ? sanitize_title( $_REQUEST['search'] ) : $this->get_domain();
            $description = isset( $_REQUEST['description'] ) ? sanitize_textarea_field( $_REQUEST['description'] ) : '';
            $image = $this->image( $id, $post_id, $description, $search, $must_license );

            if ( is_wp_error( $image ) ) {
                if ( strpos( $image->get_error_code(), 'limit_reached' ) !== false ) {
                    wp_send_json_error( $image );
                    die();
                }
                wp_send_json_error( array( 'message' => $image->get_error_message() ) );
            }

            wp_send_json_success( wp_prepare_attachment_for_js( $image ) );

        }


        /**
         * @param $data
         *
         * @return array
         */
        private function format( $data ) {
            return $data;
        }

        /**
         * @param $image
         *
         * @return array
         */
        private function individual( $image ) {
            return [
                'id'          => $image->id,
                'description' => $image->description,
                'caption'     => $image->caption ? $image->caption : '',
                'url'         => $image->assets->huge_thumb->url,
                'sizes'       => [
                    'full'      => $this->size( $image, 'huge_thumb' ),
                    'medium'    => $this->size( $image, 'preview' ),
                    'thumbnail' => $this->size( $image, 'large_thumb' )
                ]
            ];
        }

        private function size( $image, $format ) {
            return [
                'height'      => $image->assets->$format->height,
                'width'       => $image->assets->$format->width,
                'orientation' => ( $image->aspect > 1 ? 'landscape' : 'portrait' ),
                'url'         => $image->assets->$format->url
            ];
        }

        private function get_license_cost( $media_id ) {

            $response = $this->call( 'GET', 'images/license-cost', array(
                'id'     => $media_id,
                'locale' => get_locale(),
            ) );

            return $response;


        }

        private function image( $media_id, $post_id, $description = '', $search = '', $must_license = 0 ) {

            $image = $this->call( 'GET', 'images/download',
                array(
                    'id'           => $media_id,
                    'must_license' => $must_license
                )
            );

            if ( ! isset( $image->data->download ) ) {
                if ( is_wp_error( $image ) ) {
                    return $image;
                }

                return $this->handle_download_errors( $image->data );
            }

            $caption = $image->data->caption ?: '';
            $attachment_id = $this->upload_remote_image_and_attach( $image->data->download, $post_id, $description, $image->data->name, $search, $caption );
            if ( is_wp_error( $attachment_id ) ) {
                return $attachment_id;
            }
            if ( ! $attachment_id ) {
                return new WP_Error( __( 'upload_failure', 'There has been a problem with the upload. Please try again', 'stockpack' ) );
            }

            update_post_meta( $attachment_id, 'stockpack_id', $media_id );

            return $attachment_id;
        }

        private function handle_license_errors( $response ) {
            if ( isset( $response->code ) ) {
                switch ( $response->code ) {
                    case 'token_expired':
                        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' ) );
                }
            }

            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' ) );
        }

        private function handle_download_errors( $response ) {
            if ( isset( $response->code ) ) {
                switch ( $response->code ) {
                    case 'token_expired':
                        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' ) );
                }
            }

            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' ) );
        }

        private function handle_search_errors( $response ) {
            if ( isset( $response->code ) ) {
                switch ( $response->code ) {
                    case 'token_expired':
                        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' ) );
                }
            }

            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' ) );

        }

        private function images( $query = [] ) {

            return $this->call( 'GET', 'images/search', $query );
        }

        /**
         * @param       $method
         * @param       $path
         * @param array $query
         *
         * @return mixed|null
         */
        private function call( $method, $path, $query = [] ) {
            /** @var StockPack $stockpack */
            global $stockpack;

            try {
                if ( ! isset( $query['key'] ) ) {
                    $api_key = $stockpack->admin->get_api_key();
                    if ( $api_key ) {
                        $query = array_merge( $query,
                            [
                                'api_token' => $api_key
                            ]
                        );
                    } else {
                        $path .= '-trial';
                    }
                }

                $query = array_merge( $query,
                    [
                        'referral'    => get_bloginfo( 'url' ),
                        'safe_search' => $stockpack->admin->get_safe_search(),
                        'user_data'   => $stockpack->admin->get_license_state(),
                    ]
                );

                $response = $this->client()->request( $method, $path,
                    [
                        'query'    => $query
                    ]
                );

                return json_decode( $response->getBody() );
            } catch ( GuzzleException $exception ) {
                switch ( $exception->getCode() ) {
                    case 429: // too many requests
                        return $this->limit_exceeded( $exception );

                    default:
                        return new WP_Error( 1, __( 'Can\'t connect to StockPack server.', 'stockpack' ) );
                }
            }
        }

        private function limit_exceeded( $exception ) {
            /** @var StockPack $stockpack */
            global $stockpack;

            $response = $exception->getResponse();
            $limit = $response->getHeaderLine( 'x-ratelimit-limit' );
            $retry_after = $response->getHeaderLine( 'retry-after' );
            $retry_after = $this->human_seconds( $retry_after );
            $retry_after = '<span class ="stockpack-timer">' . $retry_after . '</span>';
            if ( $limit > 50 ) {
                return new WP_Error( 'premium_limit_reached', __( 'Request limit reached, the reset will be in ', 'stockpack' ) . $retry_after );
            }
            $api_key = $stockpack->admin->get_api_key();
            if ( $api_key ) {
                return new WP_Error( 'free_limit_reached', __( 'Request limit reached, the reset will be in ', 'stockpack' ) . $retry_after );
            }


            return new WP_Error( 'anonymous_limit_reached', __( 'Request limit reached, the reset will be in ', 'stockpack' ) . $retry_after );
        }

        /**
         * @return Client
         */
        private function client() {

            if ( ! $this->client ) {
                $this->client = new Client(
                    [
                        'base_uri' => $this->url . '/' . self::VERSION . '/',
                    ]
                );
            }

            return $this->client;
        }

        private function support_caption_translation( $caption ) {
            if ( ! $caption ) {
                return '';
            }

            $caption = str_replace( 'Photo by', __( 'Photo by', 'stockpack' ), $caption );
            $caption = str_replace( ' on ', _x( ' on ', 'Make sure to keep the space', 'stockpack' ), $caption );

            return $caption;
        }

        /**
         * @param        $image_url
         * @param        $parent_id
         *
         * @param        $description
         *
         * @param        $name
         * @param string $search
         *
         * @param string $caption
         *
         * @return bool|int|WP_Error
         */
        private function upload_remote_image_and_attach( $image_url, $parent_id, $description, $name, $search = '', $caption = '' ) {

            $image = $image_url;
            $get = wp_remote_get( $image, array( 'timeout' => 30 ) );
            if ( is_wp_error( $get ) ) {
                return new WP_Error( 100, __( 'Image download failed, please try again. Errors:', 'stockpack' ) . PHP_EOL . $get->get_error_message() );
            }
            $type = wp_remote_retrieve_header( $get, 'content-type' );
            if ( ! $type ) {
                return new WP_Error( 100, __( 'Image type couldn\'t be determined', 'stockpack' ) );
            }
            $mirror = wp_upload_bits( $name, '', wp_remote_retrieve_body( $get ) );
            $attachment = array(
                'post_title'     => $name,
                'post_content'   => $description,
                'post_excerpt'   => $this->support_caption_translation( $caption ),
                'post_mime_type' => $type
            );
            $attach_id = wp_insert_attachment( $attachment, $mirror['file'], $parent_id );
            require_once( ABSPATH . 'wp-admin/includes/image.php' );
            $attach_data = wp_generate_attachment_metadata( $attach_id, $mirror['file'] );
            wp_update_attachment_metadata( $attach_id, $attach_data );
            update_post_meta( $attach_id, '_wp_attachment_image_alt', $description );

            return $attach_id;

        }

        /**
         * @return mixed
         */
        private function get_domain() {
            $url = get_bloginfo( 'url' );
            $parse = wp_parse_url( $url );

            return strtok( $parse['host'], '.' );
        }


        private function human_seconds( $seconds, $separator = ":" ) {
            return sprintf( "%02d%s%02d%s%02d", floor( $seconds / 3600 ), $separator, ( $seconds / 60 ) % 60, $separator, $seconds % 60 );
        }

    }

    $GLOBALS['stockpack_query'] = StockpackQuery::get_instance();
}

```
