PluginProbe
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more / 3.7.1
StockPack – Stock photos and AI images from Unsplash, Adobe Stock, Freepik and more v3.7.1
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-stockpackmedia.php +294 -8 3.5.2 → 3.7.1 View file →
@@ -24,9 +24,9 @@
24 24
25 25 /**
26 26 * @var string plugin version
27 27 */
28 - public $version = '3.5.2';
28 + public $version = '3.7.1';
29 29
30 30 /**
31 31 * Returns the *Singleton* instance of this class.
32 32 *
@@ -145,8 +145,63 @@
145 145 }
146 146 }
147 147 }
148 148
149 + public function upscale_row_action( $actions, $post ) {
150 + if ( ! current_user_can( 'upload_files' ) || ! wp_attachment_is_image( $post->ID ) ) {
151 + return $actions;
152 + }
153 +
154 + $source = function_exists( 'wp_get_original_image_url' )
155 + ? wp_get_original_image_url( $post->ID )
156 + : false;
157 +
158 + $url = esc_url( $source ? $source : wp_get_attachment_url( $post->ID ) );
159 +
160 + foreach ( array( 2, 4 ) as $factor ) {
161 + $actions[ 'stockpack_upscale_' . $factor ] = sprintf(
162 + '<a href="#" class="stockpack-upscale" data-url="%s" data-factor="%d">%s</a>',
163 + $url,
164 + $factor,
165 + /* translators: %d: upscale factor, 2 or 4 */
166 + sprintf( esc_html__( 'Upscale %dx', 'stockpack' ), $factor )
167 + );
168 + }
169 +
170 + return $actions;
171 + }
172 +
173 + public function enqueue_upscale() {
174 + global $pagenow;
175 +
176 + if ( 'upload.php' !== $pagenow || ! current_user_can( 'upload_files' ) ) {
177 + return;
178 + }
179 +
180 + wp_enqueue_script( 'stockpack-upscale', plugins_url( '/dist/js/stockpack-upscale.js', STOCKPACK_DIR ),
181 + array( 'jquery' ), $this->version, true );
182 +
183 + wp_localize_script( 'stockpack-upscale', 'stockpackUpscale', array(
184 + 'nonceGenerate' => wp_create_nonce( 'stockpack_generate' ),
185 + 'nonceDownload' => wp_create_nonce( 'stockpack_download' ),
186 + 'editUrl' => admin_url( 'post.php?action=edit&post=' ),
187 + 'wallet' => $this->ai_wallet(),
188 + 'upscale' => $this->upscale_quotes(),
189 + 'strings' => array(
190 + 'confirm' => __( "Upscaling uses credits on your Magnific plan. Precision upscales are priced by the size of the result, usually 200 credits or more.\n\nUpscale this image?", 'stockpack' ),
191 + 'working' => __( 'Upscaling with Magnific, this can take a minute. Keep this page open, or the upscale is still charged but the image is not saved.', 'stockpack' ),
192 + 'saving' => __( 'Saving the upscaled image to your media library. Keep this page open, it will open the image when it is done.', 'stockpack' ),
193 + 'leaving' => __( 'The upscale is still running. Leaving now still costs credits, but the image will not be saved.', 'stockpack' ),
194 + 'busy' => __( 'An upscale is already running. Wait for it to finish before starting another.', 'stockpack' ),
195 + 'done' => __( 'Upscaled image saved. Opening it now...', 'stockpack' ),
196 + 'timeout' => __( 'The upscale is taking longer than expected. Check your Magnific account before retrying.',
197 + 'stockpack' ),
198 + 'failed' => __( 'The upscale could not be completed.', 'stockpack' ),
199 + 'topUp' => __( 'Top up credits', 'stockpack' ),
200 + ),
201 + ) );
202 + }
203 +
149 204 public function enqueue_frontend() {
150 205 $this->enqueue( false );
151 206 }
152 207
@@ -214,8 +269,10 @@
214 269 /**
215 270 *
216 271 */
217 272 public function filters() {
273 + add_filter( 'media_row_actions', array( $this, 'upscale_row_action' ), 10, 2 );
274 + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_upscale' ) );
218 275 add_filter( 'media_view_strings', array( $this, 'tab_text' ), 10, 2 );
219 276 add_filter( 'media_view_settings', array( $this, 'settings' ), 10, 2 );
220 277 }
221 278
@@ -341,15 +398,36 @@
341 398 'invalid_token' => __( 'Double check the token on the settings page!', 'stockpack' ),
342 399 'premium_limit_reached' => __( 'Premium account requests limit reached', 'stockpack' ),
343 400 'free_limit_reached' => __( 'Free account requests limit reached', 'stockpack' ),
344 401 'anonymous_limit_reached' => __( 'Anonymous requests limit reached', 'stockpack' ),
402 + 'insufficient_credits' => __( 'Not enough credits', 'stockpack' ),
345 403 ],
346 404 'link' => __( 'Set token', 'stockpack' ),
347 405 'search' => __( 'Search images', 'stockpack' ),
406 + 'generate' => [
407 + 'prompt' => __( 'Describe the image you want', 'stockpack' ),
408 + 'button' => __( 'Generate', 'stockpack' ),
409 + 'clear' => __( 'Clear', 'stockpack' ),
410 + 'working' => __( 'Generating...', 'stockpack' ),
411 + 'timeout' => __( 'The image is taking longer than expected. Check your Magnific account before retrying.', 'stockpack' ),
412 + 'models' => $this->ai_model_labels(),
413 + 'credits' => $this->ai_model_costs(),
414 + 'refine' => [
415 + 'label' => __( 'Refine the selected image', 'stockpack' ),
416 + 'hint' => __( 'Select a generated image first, then refine it with a new prompt.', 'stockpack' ),
417 + 'note' => __( 'Refining sends the selected image along with your prompt. Magnific charges more for a reference image, so expect roughly double.', 'stockpack' ),
418 + 'multiply' => $this->ai_refine_multiplier(),
419 + ],
420 + /* translators: %s: price per image, already formatted */
421 + 'cost' => __( '%s / image', 'stockpack' ),
422 + 'note' => $this->ai_cost_note(),
423 + 'wallet' => $this->ai_wallet_l10n(),
424 + ],
348 425 'close' => __( 'Close', 'stockpack' ),
349 426 'download' => __( 'Download', 'stockpack' ),
350 427 'licenseAction' => __( 'License', 'stockpack' ),
351 428 'alreadyLicensed' => __( 'Licensed', 'stockpack' ),
429 + 'noFreeDownload' => __( 'This provider has no free tier. Use License to download, it will tell you the cost first.', 'stockpack' ),
352 430 'license' => __( 'Your token is not valid', 'stockpack' ),
353 431 'advanced' => __( 'Advanced search', 'stockpack' ),
354 432 'filters' => [
355 433 'gender' => [
@@ -455,8 +533,18 @@
455 533 'title' => __( 'Terms agreement', 'stockpack' ),
456 534 'message' => __( 'Before you download the first image you need to agree to the terms of service of Deposit Photos. This will only be asked once and then we will store it for all subsequent downloads. You are a direct user of the Deposit Photos website and their terms apply. ', 'stockpack' ),
457 535 'link' => 'https://depositphotos.com/terms-of-use.html'
458 536 ],
537 + 'freepik' => [
538 + 'title' => __( 'Terms agreement', 'stockpack' ),
539 + 'message' => __( 'Before you download the first image you need to agree to the terms of service of Magnific, formerly Freepik. This will only be asked once and then we will store it for all subsequent downloads. Downloads are made with your own Magnific account, so you are a direct user of their website and their terms apply. ', 'stockpack' ),
540 + 'link' => 'https://www.magnific.com/legal/terms-of-use'
541 + ],
542 + 'magnific' => [
543 + 'title' => __( 'Terms agreement', 'stockpack' ),
544 + 'message' => $this->ai_terms_message(),
545 + 'link' => 'https://www.magnific.com/legal/terms-of-use'
546 + ],
459 547 ],
460 548 'licensePopup' => [
461 549 'proceed' => __( 'Proceed', 'stockpack' ),
462 550 'checkInProgress' => __( 'Cost checking is in progress, please wait', 'stockpack' ),
@@ -488,12 +576,18 @@
488 576 'status' => __( 'Fetching cost...', 'stockpack' ),
489 577 'external' => __( 'Currently only sizes available trough the subscription package are supported by the plugin. You can use the url bellow to license this directly on the Deposit Photos website, in case your account allows that. If you subscription expired renew it and retry.', 'stockpack' ),
490 578 'directLicenseUrl' => __( 'Deposit Photos License Page', 'stockpack' ),
491 579 ],
580 + 'freepik' => [
581 + 'title' => __( 'License and download', 'stockpack' ),
582 + 'message' => __( 'Magnific does not offer watermarked previews, so downloading an image gives you the full file straight away.', 'stockpack' ),
583 + 'status' => __( 'Fetching cost...', 'stockpack' ),
584 + 'external' => __( 'You can also download this image directly from the Magnific website with the account you connected.', 'stockpack' ),
585 + 'directLicenseUrl' => __( 'Open on Magnific', 'stockpack' ),
586 + ],
492 587 ],
493 588 'attribution' => [
494 589 'adobe_stock' => [
495 - 'author_info' => __( 'Image info is available in the sidebar', 'stockpack' ),
496 590 'message' => __( 'You are searching images from', 'stockpack' ),
497 591 'link' => 'https://stockpack.co/recommended/adobe_stock',
498 592 'link_title' => 'Adobe Stock'
499 593 ],
@@ -503,9 +597,8 @@
503 597 'link' => '',
504 598 'link_title' => ''
505 599 ],
506 600 'getty' => [
507 - 'author_info' => __( 'Image info is available in the sidebar', 'stockpack' ),
508 601 'message' => __( 'You are searching images from', 'stockpack' ),
509 602 'link' => 'https://stockpack.co/recommended/getty',
510 603 'link_title' => 'Getty Images',
511 604 'warning' => __( 'Watermarked images from Getty Images are allowed for test only (not publicly available), for up to 30 days following download', 'stockpack' ),
@@ -510,9 +603,8 @@
510 603 'link_title' => 'Getty Images',
511 604 'warning' => __( 'Watermarked images from Getty Images are allowed for test only (not publicly available), for up to 30 days following download', 'stockpack' ),
512 605 ],
513 606 'istock' => [
514 - 'author_info' => __( 'Image info is available in the sidebar', 'stockpack' ),
515 607 'message' => __( 'You are searching images from', 'stockpack' ),
516 608 'link' => 'https://stockpack.co/recommended/istock',
517 609 'link_title' => 'iStock',
518 610 'warning' => __( 'Watermarked images from iStock are allowed for test only (not publicly available), for up to 30 days following download', 'stockpack' ),
@@ -517,32 +609,41 @@
517 609 'link_title' => 'iStock',
518 610 'warning' => __( 'Watermarked images from iStock are allowed for test only (not publicly available), for up to 30 days following download', 'stockpack' ),
519 611 ],
520 612 'pixabay' => [
521 - 'author_info' => __( 'Author info is available in the sidebar', 'stockpack' ),
522 613 'message' => __( 'You are searching images from', 'stockpack' ),
523 614 'link' => 'https://stockpack.co/recommended/pixabay',
524 615 'link_title' => 'Pixabay'
525 616 ],
526 617 'pexels' => [
527 - 'author_info' => __( 'Author info is available in the sidebar', 'stockpack' ),
528 618 'message' => __( 'You are searching images from', 'stockpack' ),
529 619 'link' => 'https://stockpack.co/recommended/pexels',
530 620 'link_title' => 'Pexels'
531 621 ],
532 622 'unsplash' => [
533 - 'author_info' => __( 'Author info is available in the sidebar', 'stockpack' ),
534 623 'message' => __( 'You are searching images from', 'stockpack' ),
535 624 'link' => 'https://stockpack.co/recommended/unsplash',
536 625 'link_title' => 'Unsplash'
537 626 ],
538 627 'deposit_photos' => [
539 - 'author_info' => __( 'Author info is available in the sidebar', 'stockpack' ),
540 628 'message' => __( 'You are searching images from', 'stockpack' ),
541 629 'link' => 'https://stockpack.co/recommended/deposit_photos',
542 630 'link_title' => 'Deposit Photos',
543 631 'warning' => __( 'Watermarked images from Deposit Photos are allowed for testing only', 'stockpack' ),
544 632 ],
633 + 'freepik' => [
634 + 'author_info' => __( 'Beta. Runs on the Magnific API key you connect', 'stockpack' ),
635 + 'message' => __( 'You are searching images from', 'stockpack' ),
636 + 'link' => 'https://www.magnific.com',
637 + 'link_title' => 'Freepik',
638 + ],
639 + 'magnific' => [
640 + 'author_info' => $this->ai_attribution(),
641 + /* translators: attribution required by Magnific, shown directly before a link reading "Magnific" */
642 + 'message' => __( 'Powered by', 'stockpack' ),
643 + 'link' => 'https://www.magnific.com',
644 + 'link_title' => 'Magnific',
645 + ],
545 646 ],
546 647 'limit' => [
547 648 'premium' => [
548 649 'title' => __( 'Requests limit reached', 'stockpack' ),
@@ -600,14 +701,18 @@
600 701 'pixabay' => get_option( 'terms_accepted_pixabay', false ),
601 702 'pexels' => get_option( 'terms_accepted_pexels', false ),
602 703 'unsplash' => get_option( 'terms_accepted_unsplash', false ),
603 704 'deposit_photos' => get_option( 'terms_accepted_deposit_photos', false ),
705 + 'freepik' => get_option( 'terms_accepted_freepik', false ),
706 + 'magnific' => get_option( 'terms_accepted_magnific', false ),
604 707 ],
708 + 'cache_key' => substr( md5( get_current_blog_id() . '|' . get_current_user_id() ), 0, 12 ),
605 709 'nonce_terms' => wp_create_nonce( 'stockpack_terms' ),
606 710 'nonce_license_cost' => wp_create_nonce( 'stockpack_license_cost' ),
607 711 'nonce_query' => wp_create_nonce( 'stockpack_query' ),
608 712 'nonce_download' => wp_create_nonce( 'stockpack_download' ),
609 713 'nonce_cache' => wp_create_nonce( 'stockpack_cache' ),
714 + 'nonce_generate' => wp_create_nonce( 'stockpack_generate' ),
610 715 'nonce_token' => wp_create_nonce( 'stockpack_token' ),
611 716 'nonce_validate' => wp_create_nonce( 'stockpack_validate' ),
612 717 'settings_url' => admin_url( 'options-general.php?page=stockpack' ),
613 718 'contact_url' => 'https://stockpack.co/contact',
@@ -627,8 +732,187 @@
627 732 }
628 733
629 734
630 735
736 + private function sellable_ai_models( $models ) {
737 + if ( 'managed' !== $this->ai_mode() ) {
738 + return $models;
739 + }
740 +
741 + $sellable = array_filter( $models, function ( $model ) {
742 + return isset( $model['wallet_credits'] );
743 + } );
744 +
745 + return $sellable ?: $models;
746 + }
747 +
748 + private function ai_models() {
749 + $prices = StockPack::get_instance()->query->get_ai_prices();
750 +
751 + if ( isset( $prices['models'] ) && is_array( $prices['models'] ) && $prices['models'] ) {
752 + return $this->sellable_ai_models( $prices['models'] );
753 + }
754 +
755 + return array(
756 + 'flux-1' => array( 'label' => 'Flux.1', 'eur' => 0.01, 'default' => true ),
757 + 'mystic-25' => array( 'label' => 'Mystic 2.5', 'eur' => 0.10, 'default' => true ),
758 + );
759 + }
760 +
761 + private function enabled_ai_models() {
762 + $models = $this->ai_models();
763 + $selected = $this->settings->get_selected_ai_models();
764 +
765 + if ( $selected === null ) {
766 + return array_filter( $models, function ( $model ) {
767 + return ! empty( $model['default'] );
768 + } );
769 + }
770 +
771 + $enabled = array_intersect_key( $models, array_flip( $selected ) );
772 +
773 + return $enabled ?: $models;
774 + }
775 +
776 + private function ai_model_labels() {
777 + return array_map( function ( $model ) {
778 + return isset( $model['label'] ) ? $model['label'] : '';
779 + }, $this->enabled_ai_models() );
780 + }
781 +
782 + private function ai_model_costs() {
783 + $managed = 'managed' === $this->ai_mode();
784 +
785 + return array_map( function ( $model ) use ( $managed ) {
786 + if ( $managed ) {
787 + return isset( $model['wallet_credits'] ) ? $this->format_credits( $model['wallet_credits'] ) : '';
788 + }
789 +
790 + if ( ! isset( $model['eur'] ) ) {
791 + return '';
792 + }
793 +
794 + return '€' . rtrim( rtrim( number_format( (float) $model['eur'], 3 ), '0' ), '.' );
795 + }, $this->enabled_ai_models() );
796 + }
797 +
798 + private function ai_wallet() {
799 + return StockPack::get_instance()->query->get_ai_wallet();
800 + }
801 +
802 + private function ai_mode() {
803 + $wallet = $this->ai_wallet();
804 +
805 + return $wallet['mode'];
806 + }
807 +
808 + private function ai_wallet_l10n() {
809 + return $this->ai_wallet() + array(
810 + /* translators: %s: credit balance, already formatted */
811 + 'balance_label' => __( 'Balance: %s credits', 'stockpack' ),
812 + 'top_up' => __( 'Top up', 'stockpack' ),
813 + 'connect' => __( 'Connect Magnific', 'stockpack' ),
814 + 'unavailable' => __( 'Image generation is not set up for this site yet. Connect your own Magnific key on stockpack.co, or buy StockPack credits.', 'stockpack' ),
815 + );
816 + }
817 +
818 + private function ai_cost_note() {
819 + if ( 'managed' === $this->ai_mode() ) {
820 + return __( 'Each image is paid from your StockPack credits at the price shown, and refining costs double. Nothing is charged to a Magnific account.', 'stockpack' );
821 + }
822 +
823 + return __( 'Each image is charged to the Magnific account you connected. Generating through StockPack always costs, even when your plan shows unlimited generation inside the Magnific app.', 'stockpack' );
824 + }
825 +
826 + private function ai_terms_message() {
827 + if ( 'managed' === $this->ai_mode() ) {
828 + return __( 'Before you use the first generated image you need to agree to the terms of service of Magnific. This will only be asked once and then we will store it for all subsequent images. Images are generated on the StockPack Magnific account and paid from your StockPack credits, and Magnific terms still govern the images you receive. ', 'stockpack' );
829 + }
830 +
831 + return __( 'Before you use the first generated image you need to agree to the terms of service of Magnific. This will only be asked once and then we will store it for all subsequent images. Images are generated on your own Magnific account, so you are a direct user of their website and their terms apply. ', 'stockpack' );
832 + }
833 +
834 + private function ai_attribution() {
835 + if ( 'managed' === $this->ai_mode() ) {
836 + return __( 'Runs on your StockPack credits. Earlier images are shown while Magnific still hosts them; download the ones you want to keep.', 'stockpack' );
837 + }
838 +
839 + return __( 'Runs on the Magnific API key you connect. Earlier images are shown while Magnific still hosts them; download the ones you want to keep.', 'stockpack' );
840 + }
841 +
842 + private function format_credits( $credits ) {
843 + $credits = (int) $credits;
844 +
845 + return sprintf(
846 + /* translators: %s: number of credits, already formatted */
847 + _n( '%s credit', '%s credits', $credits, 'stockpack' ),
848 + number_format_i18n( $credits )
849 + );
850 + }
851 +
852 + private function upscale_quotes() {
853 + $wallet = $this->ai_wallet();
854 + $prices = StockPack::get_instance()->query->get_ai_prices();
855 + $quotes = array();
856 +
857 + foreach ( array( 2, 4 ) as $factor ) {
858 + $quotes[ $factor ] = $this->upscale_quote( $factor, $wallet, $prices );
859 + }
860 +
861 + return $quotes;
862 + }
863 +
864 + private function upscale_quote( $factor, $wallet, $prices ) {
865 + if ( 'unavailable' === $wallet['mode'] ) {
866 + $strings = $this->ai_wallet_l10n();
867 +
868 + return array( 'refuse' => $strings['unavailable'] );
869 + }
870 +
871 + if ( 'managed' !== $wallet['mode'] ) {
872 + return array();
873 + }
874 +
875 + if ( ! isset( $prices['upscale']['wallet_credits'][ $factor ] ) ) {
876 + return array(
877 + /* translators: %d: upscale factor, 2 or 4 */
878 + 'refuse' => sprintf( __( 'Upscale %dx is not available on StockPack credits yet. Connect your own Magnific key to upscale.', 'stockpack' ), $factor ),
879 + 'link' => false,
880 + );
881 + }
882 +
883 + $credits = (int) $prices['upscale']['wallet_credits'][ $factor ];
884 + $balance = (int) $wallet['balance'];
885 +
886 + if ( $balance < $credits ) {
887 + return array(
888 + 'refuse' => sprintf(
889 + /* translators: 1: upscale factor, 2: credits needed, 3: current balance, both already formatted */
890 + __( 'Upscale %1$dx needs %2$s credits and your balance is %3$s. Top up on stockpack.co first.', 'stockpack' ),
891 + $factor,
892 + number_format_i18n( $credits ),
893 + number_format_i18n( $balance )
894 + ),
895 + );
896 + }
897 +
898 + return array(
899 + 'confirm' => sprintf(
900 + /* translators: 1: upscale factor, 2: credits, already formatted, 3: balance after the upscale, already formatted */
901 + __( 'Upscale %1$dx for %2$s credits? Balance after: %3$s.', 'stockpack' ),
902 + $factor,
903 + number_format_i18n( $credits ),
904 + number_format_i18n( $balance - $credits )
905 + ),
906 + );
907 + }
908 +
909 + private function ai_refine_multiplier() {
910 + $prices = StockPack::get_instance()->query->get_ai_prices();
911 +
912 + return isset( $prices['refine_multiplier'] ) ? (int) $prices['refine_multiplier'] : 2;
913 + }
914 +
631 915 private function getProviders()
632 916 {
633 917 $selected_providers = $this->settings->get_selected_providers_setting();
634 918 $providers = array(
@@ -633,8 +917,10 @@
633 917 $selected_providers = $this->settings->get_selected_providers_setting();
634 918 $providers = array(
635 919 'Adobe Stock' => __('Adobe Stock', 'stockpack'),
636 920 'Deposit Photos' => __('Deposit Photos', 'stockpack'),
921 + 'Freepik' => __('Freepik (Magnific, beta)', 'stockpack'),
922 + 'Magnific AI' => __('Magnific AI (generate)', 'stockpack'),
637 923 'Getty' => __('Getty Images', 'stockpack'),
638 924 'iStock' => __('iStock', 'stockpack'),
639 925 'Pixabay' => __('Pixabay', 'stockpack'),
640 926 'Pexels' => __('Pexels', 'stockpack'),