| @@ -24,9 +24,9 @@ | ||
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | 26 | * @var string plugin version |
| 27 | 27 | */ |
| 28 | - public $version = '3.6.1'; | |
| 28 | + public $version = '3.7.2'; | |
| 29 | 29 | |
| 30 | 30 | /** |
| 31 | 31 | * Returns the *Singleton* instance of this class. |
| 32 | 32 | * |
| @@ -183,8 +183,10 @@ | ||
| 183 | 183 | wp_localize_script( 'stockpack-upscale', 'stockpackUpscale', array( |
| 184 | 184 | 'nonceGenerate' => wp_create_nonce( 'stockpack_generate' ), |
| 185 | 185 | 'nonceDownload' => wp_create_nonce( 'stockpack_download' ), |
| 186 | 186 | 'editUrl' => admin_url( 'post.php?action=edit&post=' ), |
| 187 | + 'wallet' => $this->ai_wallet(), | |
| 188 | + 'upscale' => $this->upscale_quotes(), | |
| 187 | 189 | 'strings' => array( |
| 188 | 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' ), |
| 189 | 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' ), |
| 190 | 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,8 +195,9 @@ | ||
| 193 | 195 | 'done' => __( 'Upscaled image saved. Opening it now...', 'stockpack' ), |
| 194 | 196 | 'timeout' => __( 'The upscale is taking longer than expected. Check your Magnific account before retrying.', |
| 195 | 197 | 'stockpack' ), |
| 196 | 198 | 'failed' => __( 'The upscale could not be completed.', 'stockpack' ), |
| 199 | + 'topUp' => __( 'Top up credits', 'stockpack' ), | |
| 197 | 200 | ), |
| 198 | 201 | ) ); |
| 199 | 202 | } |
| 200 | 203 | |
| @@ -395,8 +398,9 @@ | ||
| 395 | 398 | 'invalid_token' => __( 'Double check the token on the settings page!', 'stockpack' ), |
| 396 | 399 | 'premium_limit_reached' => __( 'Premium account requests limit reached', 'stockpack' ), |
| 397 | 400 | 'free_limit_reached' => __( 'Free account requests limit reached', 'stockpack' ), |
| 398 | 401 | 'anonymous_limit_reached' => __( 'Anonymous requests limit reached', 'stockpack' ), |
| 402 | + 'insufficient_credits' => __( 'Not enough credits', 'stockpack' ), | |
| 399 | 403 | ], |
| 400 | 404 | 'link' => __( 'Set token', 'stockpack' ), |
| 401 | 405 | 'search' => __( 'Search images', 'stockpack' ), |
| 402 | 406 | 'generate' => [ |
| @@ -414,9 +418,10 @@ | ||
| 414 | 418 | 'multiply' => $this->ai_refine_multiplier(), |
| 415 | 419 | ], |
| 416 | 420 | /* translators: %s: price per image, already formatted */ |
| 417 | 421 | 'cost' => __( '%s / image', 'stockpack' ), |
| 418 | - 'note' => __( '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' ), | |
| 422 | + 'note' => $this->ai_cost_note(), | |
| 423 | + 'wallet' => $this->ai_wallet_l10n(), | |
| 419 | 424 | ], |
| 420 | 425 | 'close' => __( 'Close', 'stockpack' ), |
| 421 | 426 | 'download' => __( 'Download', 'stockpack' ), |
| 422 | 427 | 'licenseAction' => __( 'License', 'stockpack' ), |
| @@ -535,9 +540,9 @@ | ||
| 535 | 540 | 'link' => 'https://www.magnific.com/legal/terms-of-use' |
| 536 | 541 | ], |
| 537 | 542 | 'magnific' => [ |
| 538 | 543 | 'title' => __( 'Terms agreement', 'stockpack' ), |
| 539 | - 'message' => __( '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' ), | |
| 544 | + 'message' => $this->ai_terms_message(), | |
| 540 | 545 | 'link' => 'https://www.magnific.com/legal/terms-of-use' |
| 541 | 546 | ], |
| 542 | 547 | ], |
| 543 | 548 | 'licensePopup' => [ |
| @@ -631,10 +636,11 @@ | ||
| 631 | 636 | 'link' => 'https://www.magnific.com', |
| 632 | 637 | 'link_title' => 'Freepik', |
| 633 | 638 | ], |
| 634 | 639 | 'magnific' => [ |
| 635 | - 'author_info' => __( 'Beta. 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' ), | |
| 636 | - 'message' => __( 'You are generating images with', 'stockpack' ), | |
| 640 | + 'author_info' => $this->ai_attribution(), | |
| 641 | + /* translators: attribution required by Magnific, shown directly before a link reading "Magnific" */ | |
| 642 | + 'message' => __( 'Powered by', 'stockpack' ), | |
| 637 | 643 | 'link' => 'https://www.magnific.com', |
| 638 | 644 | 'link_title' => 'Magnific', |
| 639 | 645 | ], |
| 640 | 646 | ], |
| @@ -726,13 +732,25 @@ | ||
| 726 | 732 | } |
| 727 | 733 | |
| 728 | 734 | |
| 729 | 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 | + | |
| 730 | 748 | private function ai_models() { |
| 731 | 749 | $prices = StockPack::get_instance()->query->get_ai_prices(); |
| 732 | 750 | |
| 733 | 751 | if ( isset( $prices['models'] ) && is_array( $prices['models'] ) && $prices['models'] ) { |
| 734 | - return $prices['models']; | |
| 752 | + return $this->sellable_ai_models( $prices['models'] ); | |
| 735 | 753 | } |
| 736 | 754 | |
| 737 | 755 | return array( |
| 738 | 756 | 'flux-1' => array( 'label' => 'Flux.1', 'eur' => 0.01, 'default' => true ), |
| @@ -761,9 +779,15 @@ | ||
| 761 | 779 | }, $this->enabled_ai_models() ); |
| 762 | 780 | } |
| 763 | 781 | |
| 764 | 782 | private function ai_model_costs() { |
| 765 | - return array_map( function ( $model ) { | |
| 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 | + | |
| 766 | 790 | if ( ! isset( $model['eur'] ) ) { |
| 767 | 791 | return ''; |
| 768 | 792 | } |
| 769 | 793 | |
| @@ -770,8 +794,119 @@ | ||
| 770 | 794 | return '€' . rtrim( rtrim( number_format( (float) $model['eur'], 3 ), '0' ), '.' ); |
| 771 | 795 | }, $this->enabled_ai_models() ); |
| 772 | 796 | } |
| 773 | 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 | + | |
| 774 | 909 | private function ai_refine_multiplier() { |
| 775 | 910 | $prices = StockPack::get_instance()->query->get_ai_prices(); |
| 776 | 911 | |
| 777 | 912 | return isset( $prices['refine_multiplier'] ) ? (int) $prices['refine_multiplier'] : 2; |
| @@ -783,9 +918,9 @@ | ||
| 783 | 918 | $providers = array( |
| 784 | 919 | 'Adobe Stock' => __('Adobe Stock', 'stockpack'), |
| 785 | 920 | 'Deposit Photos' => __('Deposit Photos', 'stockpack'), |
| 786 | 921 | 'Freepik' => __('Freepik (Magnific, beta)', 'stockpack'), |
| 787 | - 'Magnific AI' => __('Magnific AI (generate, beta)', 'stockpack'), | |
| 922 | + 'Magnific AI' => __('Magnific AI (generate)', 'stockpack'), | |
| 788 | 923 | 'Getty' => __('Getty Images', 'stockpack'), |
| 789 | 924 | 'iStock' => __('iStock', 'stockpack'), |
| 790 | 925 | 'Pixabay' => __('Pixabay', 'stockpack'), |
| 791 | 926 | 'Pexels' => __('Pexels', 'stockpack'), |