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-stockpackadmin.php +399 -24 2.23.7.0 View file →
@@ -16,8 +16,13 @@
16 16 */
17 17 public $settings_api;
18 18
19 19 /**
20 + * @var string plugin version
21 + */
22 + public $version = '3.7.0';
23 +
24 + /**
20 25 * Returns the *Singleton* instance of this class.
21 26 *
22 27 * @return Singleton The *Singleton* instance.
23 28 */
@@ -32,9 +37,9 @@
32 37 /**
33 38 * Stockpack constructor.
34 39 */
35 40 protected function __construct() {
36 - add_action( 'plugins_loaded', array( $this, 'init' ) );
41 + add_action( 'init', array( $this, 'init' ) );
37 42 }
38 43
39 44 /**
40 45 *
@@ -40,19 +45,33 @@
40 45 *
41 46 */
42 47 public function init() {
43 48 $this->actions();
49 + $this->filters();
44 50 }
45 51
46 -
47 52 /**
48 53 *
49 54 */
50 55 public function actions() {
56 + add_action( 'wp_loaded', array( $this, 'maybe_show_notice' ) );
51 57 add_action( 'admin_init', array( $this, 'register_settings' ) );
52 58 add_action( 'admin_menu', array( $this, 'register_settings_page' ) );
53 59 }
54 60
61 + public function filters() {
62 + add_filter( 'stockpack_download_timeout', array( $this, 'download_timeout' ), 10, 1 );
63 + }
64 +
65 + public function download_timeout( $limit ) {
66 + $overwrite_limit = (int) $this->get_option( 'download_timeout', 'stockpack_debug' );
67 + if ( $overwrite_limit > 0 ) {
68 + return $overwrite_limit;
69 + }
70 +
71 + return $limit;
72 + }
73 +
55 74 /**
56 75 * Register settings
57 76 */
58 77 public function register_settings() {
@@ -57,48 +76,78 @@
57 76 */
58 77 public function register_settings() {
59 78
60 79 $this->settings_api = new WeDevs_Settings_API();
80 + // remove settings scripts as we do not use the color picker
81 + if(!(isset($_GET['page']) && $_GET['page'] === 'stockpack')) {
82 + remove_action('admin_enqueue_scripts', array($this->settings_api, 'admin_enqueue_scripts'));
83 + }
84 +
61 85 //set sections and fields
62 86 $this->settings_api->set_sections( $this->get_settings_sections() );
63 87 $this->settings_api->set_fields( $this->get_settings_fields() );
64 88
65 89 //initialize them
90 + add_action( 'wsa_form_top_stockpack_basics', array( $this, 'credits_line' ) );
91 +
66 92 $this->settings_api->admin_init();
67 93 }
68 94
69 - /**
70 - *
71 - */
72 95 public function register_settings_page() {
73 - add_options_page( __( 'StockPack', 'stockpack' ), __( 'StockPack', 'stockpack' ), 'delete_posts', 'stockpack',
96 + $capability = apply_filters( 'stockpack_settings_capability', 'upload_files' );
97 +
98 + add_options_page( __( 'StockPack', 'stockpack' ), __( 'StockPack', 'stockpack' ), $capability, 'stockpack',
74 99 array( $this, 'plugin_page' )
75 100 );
76 101 }
77 102
103 + public function maybe_show_notice() {
78 104
79 - /**
80 - *
81 - */
105 + add_action( 'admin_notices', array( $this, 'compatibility_notice' ) );
106 + if ( ! PAnD::is_admin_notice_active( 'disable-media-notice-forever' ) ) {
107 + return;
108 + }
109 + add_action( 'admin_init', array( 'PAnD', 'init' ) );
110 +
111 + add_action( 'admin_notices', array( $this, 'media_notice' ) );
112 +
113 + add_action( 'wsa_form_bottom_stockpack_debug', array( $this, 'debug_info' ) );
114 + }
115 +
116 + public function compatibility_notice() {
117 + // all compatibility issues were resolved
118 + }
119 +
120 + public function media_notice() {
121 + global $pagenow;
122 + if ( $pagenow != 'upload.php' ) {
123 + return;
124 + }
125 +
126 + $capability = apply_filters( 'stockpack_notices_capability', 'upload_files' );
127 + if ( current_user_can( $capability ) ) {
128 + echo '<div data-dismissible="disable-media-notice-forever" class="notice notice-warning is-dismissible">
129 + <p>' . __( 'If you are looking for StockPack you will find it on the Media Tab when you use the WordPress uploader. Just go to a post or page and try to insert an image. You will see the StockPack tab at the top. You can read more here:', 'stockpack' ) . ' <a href="https://stockpack.co/blog/what-to-do-if-stockpack-tab-is-not-showing-up/">' . __( 'What to do if stockpack tab is not showing up', 'stockpack' ) . '</a></p>
130 + </div>';
131 + }
132 +
133 + }
134 +
82 135 public function plugin_page() {
83 136
84 137 echo '<div class="wrap">';
85 138 $this->settings_api->show_navigation();
86 139 $this->settings_api->show_forms();
87 - $link_text = esc_textarea( __( 'Get your license key', 'stockpack' ) );
140 + $link_text = esc_textarea( __( 'Get your token', 'stockpack' ) );
88 141 echo '<a class="license-key-link" href="https://stockpack.co/register" target="_blank">' . $link_text . '</a>';
89 142
90 143 echo '</div>';
91 144 }
92 145
93 - public function get_license_state() {
94 - return $this->get_option( 'license_state', 'stockpack_basics' );
146 + public function get_featured_caption_setting() {
147 + return $this->get_option( 'caption_featured_image', 'stockpack_advanced' );
95 148 }
96 149
97 - public function get_safe_search() {
98 - return $this->get_option( 'safe_search', 'stockpack_basics' );
99 - }
100 -
101 150 /**
102 151 * @return mixed
103 152 */
104 153 public function get_api_key() {
@@ -111,36 +160,342 @@
111 160 public function set_api_key( $token ) {
112 161 return $this->set_option( 'auth_token', 'stockpack_basics', $token );
113 162 }
114 163
164 + public function debug_info() {
165 + global $wp_version;
166 + $theme = wp_get_theme();
167 + $memory = $this->wc_let_to_num( WP_MEMORY_LIMIT );
115 168
169 + if ( function_exists( 'memory_get_usage' ) ) {
170 + $system_memory = $this->wc_let_to_num( @ini_get( 'memory_limit' ) );
171 + $memory = max( $memory, $system_memory );
172 + }
173 + $data = [
174 + 'active_plugins' => get_option( 'active_plugins' ),
175 + 'theme' => $theme->name,
176 + 'wp_version' => $wp_version,
177 + 'token' => $this->get_api_key(),
178 + 'plugin_version' => $this->version,
179 + 'is_multisite' => is_multisite(),
180 + 'memory' => size_format( $memory ),
181 + 'server_info' => $this->wc_get_server_info()
182 + ];
183 +
184 + echo "<br><br/><i>".__('Copy this information when you write to support with a bug issue','stockpack')."</i><br/>";
185 + echo "<textarea cols='80' rows='10'>" . json_encode( $data ) . "</textarea>";
186 + }
187 +
188 +
116 189 /**
190 + * WC function to convert php data to int
191 + *
192 + * @param $size
193 + *
194 + * @return int
195 + */
196 + private function wc_let_to_num( $size ) {
197 + $l = substr( $size, - 1 );
198 + $ret = (int) substr( $size, 0, - 1 );
199 + switch ( strtoupper( $l ) ) {
200 + case 'P':
201 + $ret *= 1024;
202 + // No break.
203 + case 'T':
204 + $ret *= 1024;
205 + // No break.
206 + case 'G':
207 + $ret *= 1024;
208 + // No break.
209 + case 'M':
210 + $ret *= 1024;
211 + // No break.
212 + case 'K':
213 + $ret *= 1024;
214 + // No break.
215 + }
216 +
217 + return $ret;
218 + }
219 +
220 + /**
221 + * WC function to get server related info.
222 + *
117 223 * @return array
118 224 */
225 + private function wc_get_server_info() {
226 + $server_data = array();
227 +
228 + if ( ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
229 + $server_data['software'] = $_SERVER['SERVER_SOFTWARE']; // @phpcs:ignore
230 + }
231 +
232 + if ( function_exists( 'phpversion' ) ) {
233 + $server_data['php_version'] = phpversion();
234 + }
235 +
236 + if ( function_exists( 'ini_get' ) ) {
237 + $server_data['php_post_max_size'] = size_format( $this->wc_let_to_num( ini_get( 'post_max_size' ) ) );
238 + $server_data['php_time_limt'] = ini_get( 'max_execution_time' );
239 + $server_data['php_max_input_vars'] = ini_get( 'max_input_vars' );
240 + $server_data['php_suhosin'] = extension_loaded( 'suhosin' ) ? 'Yes' : 'No';
241 + }
242 +
243 + $server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
244 + $server_data['php_default_timezone'] = date_default_timezone_get();
245 + $server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
246 + $server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
247 + $server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
248 +
249 + return $server_data;
250 + }
251 +
252 +
253 + /**
254 + * @return array
255 + */
119 256 private function get_settings_sections() {
120 257 return array(
121 258 array(
122 259 'id' => 'stockpack_basics',
123 - 'title' => __( 'StockPack', 'stockpack' ),
260 + 'title' => __( 'General', 'stockpack' ),
124 261 ),
262 + array(
263 + 'id' => 'stockpack_advanced',
264 + 'title' => __( 'Advanced', 'stockpack' ),
265 + ),
266 + array(
267 + 'id' => 'stockpack_debug',
268 + 'title' => __( 'Debug', 'stockpack' ),
269 + ),
125 270 );
126 271 }
127 272
273 + private function ai_models(): array {
274 + $prices = StockPack::get_instance()->query->get_ai_prices();
275 + $models = isset( $prices['models'] ) && is_array( $prices['models'] ) ? $prices['models'] : array();
276 +
277 + if ( ! $models || ! $this->managed_credits() ) {
278 + return $models;
279 + }
280 +
281 + $sellable = array_filter( $models, function ( $model ) {
282 + return isset( $model['wallet_credits'] );
283 + } );
284 +
285 + return $sellable ?: $models;
286 + }
287 +
288 + private function ai_model_options(): array {
289 + $options = array();
290 + $managed = $this->managed_credits();
291 +
292 + foreach ( $this->ai_models() as $key => $model ) {
293 + if ( $managed ) {
294 + $price = isset( $model['wallet_credits'] ) ? sprintf( ' (%s)', $this->format_credits( $model['wallet_credits'] ) ) : '';
295 + } else {
296 + $price = isset( $model['eur'] ) ? sprintf( ' (€%s)', rtrim( rtrim( number_format( (float) $model['eur'], 3 ), '0' ), '.' ) ) : '';
297 + }
298 +
299 + $options[ $key ] = ( isset( $model['label'] ) ? $model['label'] : $key ) . $price;
300 + }
301 +
302 + return $options;
303 + }
304 +
305 + private function ai_wallet(): array {
306 + return StockPack::get_instance()->query->get_ai_wallet();
307 + }
308 +
309 + private function managed_credits(): bool {
310 + $wallet = $this->ai_wallet();
311 +
312 + return 'managed' === $wallet['mode'];
313 + }
314 +
315 + private function format_credits( $credits ): string {
316 + $credits = (int) $credits;
317 +
318 + return sprintf(
319 + /* translators: %s: number of credits, already formatted */
320 + _n( '%s credit', '%s credits', $credits, 'stockpack' ),
321 + number_format_i18n( $credits )
322 + );
323 + }
324 +
325 + public function credits_line() {
326 + $wallet = $this->ai_wallet();
327 +
328 + if ( 'byok' === $wallet['mode'] ) {
329 + return;
330 + }
331 +
332 + if ( 'unavailable' === $wallet['mode'] ) {
333 + printf(
334 + '<p class="description stockpack-credits-line">%s <a href="%s" target="_blank" rel="noopener">%s</a> · <a href="%s" target="_blank" rel="noopener">%s</a></p>',
335 + esc_html__( 'Image generation is not set up for this site yet. Connect your own Magnific key on stockpack.co, or buy StockPack credits.', 'stockpack' ),
336 + esc_url( $wallet['connect_url'] ),
337 + esc_html__( 'Connect Magnific', 'stockpack' ),
338 + esc_url( $wallet['top_up_url'] ),
339 + esc_html__( 'Top up credits', 'stockpack' )
340 + );
341 +
342 + return;
343 + }
344 +
345 + printf(
346 + '<p class="description stockpack-credits-line">%s · <a href="%s" target="_blank" rel="noopener">%s</a></p>',
347 + /* translators: %s: credit balance, already formatted */
348 + esc_html( sprintf( __( 'Credits: %s', 'stockpack' ), $wallet['balance_text'] ) ),
349 + esc_url( $wallet['top_up_url'] ),
350 + esc_html__( 'Manage on stockpack.co', 'stockpack' )
351 + );
352 + }
353 +
354 + private function ai_model_defaults(): array {
355 + $defaults = array();
356 +
357 + foreach ( $this->ai_models() as $key => $model ) {
358 + if ( ! empty( $model['default'] ) ) {
359 + $defaults[ $key ] = $key;
360 + }
361 + }
362 +
363 + return $defaults;
364 + }
365 +
366 + private function ai_models_description(): string {
367 + $all = count( $this->ai_models() );
368 +
369 + if ( $this->managed_credits() ) {
370 + return sprintf(
371 + /* translators: %d: number of models sellable on StockPack credits */
372 + _n(
373 + 'Choose which models appear in the generate dropdown. %d is available on StockPack credits and its price is per image. Models Magnific does not let us resell stay available on your own Magnific key.',
374 + 'Choose which models appear in the generate dropdown. %d are available on StockPack credits and prices are per image. Models Magnific does not let us resell stay available on your own Magnific key.',
375 + $all,
376 + 'stockpack'
377 + ),
378 + $all
379 + );
380 + }
381 +
382 + return sprintf(
383 + /* translators: %d: total number of models offered by the provider */
384 + __( 'Choose which models appear in the generate dropdown. %d are available and prices are per image, charged to the Magnific account you connect. Cheaper models are good for trying out a prompt; switch to a dearer one once you are happy with it.', 'stockpack' ),
385 + $all
386 + );
387 + }
388 +
128 389 /**
129 390 * @return array
130 391 */
131 392 private function get_settings_fields() {
132 393 return array(
133 - 'stockpack_basics' => array(
394 + 'stockpack_basics' => array(
134 395 array(
135 396 'name' => 'auth_token',
136 - 'label' => __( 'License key', 'stockpack' ),
137 - 'desc' => __( 'This is the license key that is used for authentication', 'stockpack' ),
397 + 'label' => __( 'Token', 'stockpack' ),
398 + 'desc' => __( 'This is the token that is used for authentication', 'stockpack' ),
138 399 'type' => 'text',
139 400 'default' => '',
140 401 'size' => 'validate-stockpack-key regular' //small hack to add class
141 402 ),
142 403 array(
404 + 'name' => 'safe_search',
405 + 'label' => __( 'Apply safe search', 'stockpack' ),
406 + 'desc' => __( 'Some providers support this mode to prevent nude images to show up in the search', 'stockpack' ),
407 + 'options' => array(
408 + 'yes' => __( 'Yes', 'stockpack' ),
409 + 'no' => __( 'No', 'stockpack' )
410 + ),
411 + 'type' => 'radio',
412 + 'default' => 'yes',
413 + ),
414 + array(
415 + 'name' => 'providers',
416 + 'label' => __( 'Providers available', 'stockpack' ),
417 + 'desc' => __( 'Select providers you want to use in the select', 'stockpack' ),
418 + 'options' => array(
419 + 'Adobe Stock' => __( 'Adobe Stock', 'stockpack' ),
420 + 'Deposit Photos' => __( 'Deposit Photos', 'stockpack' ),
421 + 'Freepik' => __( 'Freepik (Magnific)', 'stockpack' ),
422 + 'Magnific AI' => __( 'Magnific AI (generate)', 'stockpack' ),
423 + 'Getty' => __( 'Getty Images', 'stockpack' ),
424 + 'iStock' => __( 'iStock', 'stockpack' ),
425 + 'Pixabay' => __( 'Pixabay', 'stockpack' ),
426 + 'Pexels' => __( 'Pexels', 'stockpack' ),
427 + 'Unsplash' => __( 'Unsplash', 'stockpack' ),
428 + ),
429 + 'size' => 'add-links-to-providers',
430 + 'type' => 'multicheck',
431 + 'default' => [
432 + 'Adobe Stock'=> 'Adobe Stock',
433 + 'Deposit Photos'=> 'Deposit Photos',
434 + 'Freepik'=> 'Freepik',
435 + 'Magnific AI'=> 'Magnific AI',
436 + 'Getty'=> 'Getty',
437 + 'iStock'=> 'iStock',
438 + 'Pixabay' => 'Pixabay',
439 + 'Pexels' => 'Pexels',
440 + 'Unsplash' => 'Unsplash',
441 + ],
442 + ),
443 + array(
444 + 'name' => 'ai_models',
445 + 'label' => __( 'AI models available', 'stockpack' ),
446 + 'desc' => $this->ai_models_description(),
447 + 'options' => $this->ai_model_options(),
448 + 'type' => 'multicheck',
449 + 'default' => $this->ai_model_defaults(),
450 + ),
451 + array(
452 + 'name' => 'file_name_change',
453 + 'label' => __( 'Enable file name change', 'stockpack' ),
454 + 'desc' => __( 'You can set the desired filename prior to download. This is a good SEO idea if you want it, but it\'s a small extra step', 'stockpack' ),
455 + 'options' => array(
456 + 'yes' => __( 'Yes', 'stockpack' ),
457 + 'no' => __( 'No', 'stockpack' )
458 + ),
459 + 'type' => 'radio',
460 + 'default' => 'no',
461 + )
462 + ),
463 + 'stockpack_advanced' => array(
464 + array(
465 + 'name' => 'caption_premium_providers',
466 + 'label' => __( 'Enable premium providers caption', 'stockpack' ),
467 + 'desc' => __( 'You can enable automatic caption for premium providers if you want to', 'stockpack' ),
468 + 'options' => array(
469 + 'yes' => __( 'Yes', 'stockpack' ),
470 + 'no' => __( 'No', 'stockpack' )
471 + ),
472 + 'type' => 'radio',
473 + 'default' => 'no',
474 + ),
475 + array(
476 + 'name' => 'caption_standard_fields',
477 + 'label' => __( 'Enable caption fields', 'stockpack' ),
478 + 'desc' => __( 'You can enable additional fields for images that you can use to standardize captions. This is generally used to provide credits.', 'stockpack' ),
479 + 'options' => array(
480 + 'yes' => __( 'Yes', 'stockpack' ),
481 + 'no' => __( 'No', 'stockpack' )
482 + ),
483 + 'type' => 'radio',
484 + 'default' => 'no',
485 + ),
486 + array(
487 + 'name' => 'caption_featured_image',
488 + 'label' => __( 'Enable featured image caption', 'stockpack' ),
489 + 'desc' => __( 'You can enable captions for featured images to be appended. If you want to use this for non stockpack images, you also need the above setting.', 'stockpack' ),
490 + 'options' => array(
491 + 'yes' => __( 'Yes', 'stockpack' ),
492 + 'no' => __( 'No', 'stockpack' )
493 + ),
494 + 'type' => 'radio',
495 + 'default' => 'no',
496 + ),
497 + array(
143 498 'name' => 'license_state',
144 499 'label' => __( 'Search with authorization', 'stockpack' ),
145 500 'desc' => __( 'Providers that support oauth can get the license state for all images directly. You see it in the sidebar. The downside is that the searches are slower', 'stockpack' ),
146 501 'options' => array(
@@ -150,19 +505,39 @@
150 505 'type' => 'radio',
151 506 'default' => 'no',
152 507 ),
153 508 array(
154 - 'name' => 'safe_search',
155 - 'label' => __( 'Apply safe search', 'stockpack' ),
156 - 'desc' => __( 'Some providers support this mode to prevent nude images to show up in the search', 'stockpack' ),
509 + 'name' => 'add_license_state_to_filename',
510 + 'label' => __( 'Update file name with provider name and license state for premium providers', 'stockpack' ),
511 + 'desc' => __( 'By adding details to the image file name you can use unlicensed images as placeholders and if you use Gutenberg you can later license those images directly via StockBlock, the Gutenberg module from StockPack', 'stockpack' ),
157 512 'options' => array(
158 513 'yes' => __( 'Yes', 'stockpack' ),
159 514 'no' => __( 'No', 'stockpack' )
160 515 ),
161 516 'type' => 'radio',
162 - 'default' => 'yes',
517 + 'default' => 'no',
163 518 ),
164 519 ),
520 + 'stockpack_debug' => array(
521 + array(
522 + 'name' => 'download_timeout',
523 + 'label' => __( 'Download timeout in seconds', 'stockpack' ),
524 + 'desc' => __( 'If you have issues downloading the images, increasing this might help', 'stockpack' ),
525 + 'type' => 'number',
526 + 'default' => 30,
527 + ),
528 + array(
529 + 'name' => 'url_debugging',
530 + 'label' => __( 'Enable URL debugging', 'stockpack' ),
531 + 'desc' => __( 'This will log all external calls made and add them to wp-content/debug.log. Make sure you have space on the disk (a few hundred megabytes) and only keep this enabled for short periods of time', 'stockpack' ),
532 + 'options' => array(
533 + 'yes' => __( 'Yes', 'stockpack' ),
534 + 'no' => __( 'No', 'stockpack' )
535 + ),
536 + 'type' => 'radio',
537 + 'default' => 'no',
538 + ),
539 + )
165 540 );
166 541 }
167 542
168 543 /**