PluginProbe
Tiered Pricing Table for WooCommerce / 2.1.2
Tiered Pricing Table for WooCommerce v2.1.2
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
← All changes | freemius/includes/fs-plugin-info-dialog.php +115 -663 8.0.2 → 2.1.2 View file →
@@ -30,31 +30,8 @@
30 30 * @var Freemius
31 31 */
32 32 private $_fs;
33 33
34 - /**
35 - * Collection of plugin installation, update, download, activation, and purchase actions. This is used in
36 - * populating the actions dropdown list when there are at least 2 actions. If there's only 1 action, a button
37 - * is used instead.
38 - *
39 - * @author Leo Fajardo (@leorw)
40 - * @since 2.3.0
41 - *
42 - * @var string[]
43 - */
44 - private $actions;
45 -
46 - /**
47 - * Contains plugin status information that is used to determine which actions should be part of the actions
48 - * dropdown list.
49 - *
50 - * @author Leo Fajardo (@leorw)
51 - * @since 2.3.0
52 - *
53 - * @var string[]
54 - */
55 - private $status;
56 -
57 34 function __construct( Freemius $fs ) {
58 35 $this->_fs = $fs;
59 36
60 37 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $fs->get_slug() . '_info', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
@@ -144,38 +121,17 @@
144 121 $has_free_plan = true;
145 122 }
146 123
147 124 if ( is_array( $pricing ) && 0 < count( $pricing ) ) {
148 - $filtered_pricing = array();
125 + $has_paid_plan = true;
149 126
150 - foreach ( $pricing as $prices ) {
127 + foreach ( $pricing as &$prices ) {
151 128 $prices = new FS_Pricing( $prices );
152 -
153 - if ( ! $prices->is_usd() ) {
154 - /**
155 - * Skip non-USD pricing.
156 - *
157 - * @author Leo Fajardo (@leorw)
158 - * @since 2.3.1
159 - */
160 - continue;
161 - }
162 -
163 - if ( ( $prices->has_monthly() && $prices->monthly_price > 1.0 ) ||
164 - ( $prices->has_annual() && $prices->annual_price > 1.0 ) ||
165 - ( $prices->has_lifetime() && $prices->lifetime_price > 1.0 )
166 - ) {
167 - $filtered_pricing[] = $prices;
168 - }
169 129 }
170 130
171 - if ( ! empty( $filtered_pricing ) ) {
172 - $has_paid_plan = true;
131 + $plan->pricing = $pricing;
173 132
174 - $plan->pricing = $filtered_pricing;
175 -
176 - $has_pricing = true;
177 - }
133 + $has_pricing = true;
178 134 }
179 135
180 136 if ( is_array( $features ) && 0 < count( $features ) ) {
181 137 $plan->features = $features;
@@ -213,16 +169,13 @@
213 169 }
214 170
215 171 $data->fs_missing = ( ! $has_free_plan || $data->wp_org_missing );
216 172 } else {
217 - $data->has_purchased_license = false;
218 - $data->wp_org_missing = false;
173 + $data->wp_org_missing = false;
219 174
220 - $fs_addon = null;
221 175 $current_addon_version = false;
222 176 if ( $this->_fs->is_addon_activated( $selected_addon->id ) ) {
223 - $fs_addon = $this->_fs->get_addon_instance( $selected_addon->id );
224 - $current_addon_version = $fs_addon->get_plugin_version();
177 + $current_addon_version = $this->_fs->get_addon_instance( $selected_addon->id )->get_plugin_version();
225 178 } else if ( $this->_fs->is_addon_installed( $selected_addon->id ) ) {
226 179 $addon_plugin_data = get_plugin_data(
227 180 ( WP_PLUGIN_DIR . '/' . $this->_fs->get_addon_basename( $selected_addon->id ) ),
228 181 false,
@@ -237,58 +190,21 @@
237 190 // Fetch latest version from Freemius.
238 191 $latest = $this->_fs->_fetch_latest_version(
239 192 $selected_addon->id,
240 193 true,
241 - FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION,
194 + WP_FS__TIME_24_HOURS_IN_SEC,
242 195 $current_addon_version
243 196 );
244 197
245 198 if ( $has_paid_plan ) {
246 - $blog_id = fs_request_get( 'fs_blog_id' );
247 - $has_valid_blog_id = is_numeric( $blog_id );
248 -
249 - if ( $has_valid_blog_id ) {
250 - switch_to_blog( $blog_id );
251 - }
252 -
253 - $data->checkout_link = $this->_fs->checkout_url(
254 - WP_FS__PERIOD_ANNUALLY,
255 - false,
256 - array(),
257 - ( $has_valid_blog_id ? false : null )
258 - );
259 -
260 - if ( $has_valid_blog_id ) {
261 - restore_current_blog();
262 - }
199 + $data->checkout_link = $this->_fs->checkout_url();
263 200 }
264 -
265 - /**
266 - * Check if there's a purchased license in case the add-on can only be installed/downloaded as part of a purchased bundle.
267 - *
268 - * @author Leo Fajardo (@leorw)
269 - * @since 2.4.1
270 - */
271 - if ( is_object( $fs_addon ) ) {
272 - $data->has_purchased_license = $fs_addon->has_active_valid_license();
273 - } else {
274 - $account_addons = $this->_fs->get_account_addons();
275 - if ( ! empty( $account_addons ) && in_array( $selected_addon->id, $account_addons ) ) {
276 - $data->has_purchased_license = true;
277 - }
201 + if ( $has_free_plan ) {
202 + $data->download_link = $this->_fs->_get_latest_download_local_url( $selected_addon->id );
278 203 }
279 204
280 - if ( $has_free_plan || $data->has_purchased_license ) {
281 - $data->download_link = $this->_fs->_get_latest_download_local_url( $selected_addon->id );
282 - }
205 + $data->fs_missing = ( false === $latest );
283 206
284 - $data->fs_missing = (
285 - false === $latest &&
286 - (
287 - empty( $selected_addon->premium_releases_count ) ||
288 - ! ( $selected_addon->premium_releases_count > 0 )
289 - )
290 - );
291 207
292 208 // Fetch as much as possible info from local files.
293 209 $plugin_local_data = $this->_fs->get_plugin_data();
294 210 $data->author = $plugin_local_data['Author'];
@@ -310,12 +226,9 @@
310 226 if ( is_object( $latest ) ) {
311 227 $data->version = $latest->version;
312 228 $data->last_updated = $latest->created;
313 229 $data->requires = $latest->requires_platform_version;
314 - $data->requires_php = $latest->requires_programming_language_version;
315 230 $data->tested = $latest->tested_up_to_version;
316 - } else if ( ! empty( $current_addon_version ) ) {
317 - $data->version = $current_addon_version;
318 231 } else {
319 232 // Add dummy version.
320 233 $data->version = '1.0.0';
321 234
@@ -353,15 +266,9 @@
353 266 $data->has_free_plan = $has_free_plan;
354 267 $data->has_paid_plan = $has_paid_plan;
355 268 $data->is_paid = $has_paid_plan;
356 269 $data->is_wp_org_compliant = $selected_addon->is_wp_org_compliant;
357 - $data->premium_slug = $selected_addon->premium_slug;
358 - $data->addon_id = $selected_addon->id;
359 270
360 - if ( ! isset( $data->has_purchased_license ) ) {
361 - $data->has_purchased_license = false;
362 - }
363 -
364 271 return $data;
365 272 }
366 273
367 274 /**
@@ -425,72 +332,8 @@
425 332 return '$' . $price_tag;
426 333 }
427 334
428 335 /**
429 - * @author Leo Fajardo (@leorw)
430 - * @since 2.3.0
431 - *
432 - * @param object $api
433 - * @param FS_Plugin_Plan $plan
434 - *
435 - * @return string
436 - */
437 - private function get_actions_dropdown( $api, $plan = null ) {
438 - $this->actions = isset( $this->actions ) ?
439 - $this->actions :
440 - $this->get_plugin_actions( $api );
441 -
442 - $actions = $this->actions;
443 -
444 - $checkout_cta = $this->get_checkout_cta( $api, $plan );
445 - if ( ! empty( $checkout_cta ) ) {
446 - /**
447 - * If there's no license yet, make the checkout button the main CTA. Otherwise, make it the last item in
448 - * the actions dropdown.
449 - *
450 - * @author Leo Fajardo (@leorw)
451 - * @since 2.3.0
452 - */
453 - if ( ! $api->has_purchased_license ) {
454 - array_unshift( $actions, $checkout_cta );
455 - } else {
456 - $actions[] = $checkout_cta;
457 - }
458 - }
459 -
460 - if ( empty( $actions ) ) {
461 - return '';
462 - }
463 -
464 - $total_actions = count( $actions );
465 - if ( 1 === $total_actions ) {
466 - return $actions[0];
467 - }
468 -
469 - ob_start();
470 -
471 - ?>
472 - <div class="fs-cta fs-dropdown">
473 - <div class="button-group">
474 - <?php
475 - // This should NOT be sanitized as the $actions are HTML buttons already.
476 - echo $actions[0] ?>
477 - <div class="button button-primary fs-dropdown-arrow-button">
478 - <span class="fs-dropdown-arrow"></span>
479 - <ul class="fs-dropdown-list" style="display: none">
480 - <?php for ( $i = 1; $i < $total_actions; $i ++ ) : ?>
481 - <li><?php echo str_replace( 'button button-primary', '', $actions[ $i ] ) ?></li>
482 - <?php endfor ?>
483 - </ul>
484 - </div>
485 - </div>
486 - </div>
487 - <?php
488 -
489 - return ob_get_clean();
490 - }
491 -
492 - /**
493 336 * @author Vova Feldman (@svovaf)
494 337 * @since 1.1.7
495 338 *
496 339 * @param object $api
@@ -515,34 +358,16 @@
515 358 }
516 359 }
517 360 }
518 361
519 - $blog_id = fs_request_get( 'fs_blog_id' );
520 - $has_valid_blog_id = is_numeric( $blog_id );
521 -
522 - if ( $has_valid_blog_id ) {
523 - switch_to_blog( $blog_id );
524 - }
525 -
526 - $addon_checkout_url = $this->_fs->addon_checkout_url(
362 + return '<a class="button button-primary fs-checkout-button right" href="' . $this->_fs->addon_checkout_url(
527 363 $plan->plugin_id,
528 364 $plan->pricing[0]->id,
529 365 $this->get_billing_cycle( $plan ),
530 - $plan->has_trial(),
531 - ( $has_valid_blog_id ? false : null )
532 - );
533 -
534 - if ( $has_valid_blog_id ) {
535 - restore_current_blog();
536 - }
537 -
538 - return '<a class="button button-primary fs-checkout-button right" href="' . $addon_checkout_url . '" target="_parent">' .
539 - esc_html( ! $plan->has_trial() ?
540 - (
541 - $api->has_purchased_license ?
542 - fs_text_inline( 'Purchase More', 'purchase-more', $api->slug ) :
543 - fs_text_x_inline( 'Purchase', 'verb', 'purchase', $api->slug )
544 - ) :
366 + $plan->has_trial()
367 + ) . '" target="_parent">' .
368 + ( ! $plan->has_trial() ?
369 + fs_text_x_inline( 'Purchase', 'verb', 'purchase', $api->slug ) :
545 370 sprintf(
546 371 /* translators: %s: N-days trial */
547 372 fs_text_inline( 'Start my free %s', 'start-free-x', $api->slug ),
548 373 $this->get_trial_period( $plan )
@@ -551,306 +376,97 @@
551 376 '</a>';
552 377 }
553 378
554 379 /**
555 - * @author Leo Fajardo (@leorw)
556 - * @since 2.3.0
380 + * @author Vova Feldman (@svovaf)
381 + * @since 2.0.0
557 382 *
558 383 * @param object $api
384 + * @param bool $is_primary
559 385 *
560 - * @return string[]
386 + * @return string
561 387 */
562 - private function get_plugin_actions( $api ) {
563 - $this->status = isset( $this->status ) ?
564 - $this->status :
565 - install_plugin_install_status( $api );
566 -
567 - $is_update_available = ( 'update_available' === $this->status['status'] );
568 -
569 - if ( $is_update_available && empty( $this->status['url'] ) ) {
570 - return array();
388 + private function get_download_cta( $api, $is_primary = true ) {
389 + if ( empty( $api->download_link ) ) {
390 + return '';
571 391 }
572 392
573 - $blog_id = fs_request_get( 'fs_blog_id' );
393 + $status = install_plugin_install_status( $api );
574 394
575 - $active_plugins_directories_map = Freemius::get_active_plugins_directories_map( $blog_id );
395 + $has_paid_version = $api->has_paid_plan;
576 396
577 - $actions = array();
578 -
579 - $is_addon_activated = $this->_fs->is_addon_activated( $api->slug );
580 - $fs_addon = null;
581 -
582 - $is_free_installed = null;
583 - $is_premium_installed = null;
584 -
585 - $has_installed_version = ( 'install' !== $this->status['status'] );
586 -
587 - if ( ! $api->has_paid_plan && ! $api->has_purchased_license ) {
588 - /**
589 - * Free-only add-on.
590 - *
591 - * @author Leo Fajardo (@leorw)
592 - * @since 2.3.0
593 - */
594 - $is_free_installed = $has_installed_version;
595 - $is_premium_installed = false;
596 - } else if ( ! $api->has_free_plan ) {
597 - /**
598 - * Premium-only add-on.
599 - *
600 - * @author Leo Fajardo (@leorw)
601 - * @since 2.3.0
602 - */
603 - $is_free_installed = false;
604 - $is_premium_installed = $has_installed_version;
605 - } else {
606 - /**
607 - * Freemium add-on.
608 - *
609 - * @author Leo Fajardo (@leorw)
610 - * @since 2.3.0
611 - */
612 - if ( ! $has_installed_version ) {
613 - $is_free_installed = false;
614 - $is_premium_installed = false;
615 - } else {
616 - $fs_addon = $is_addon_activated ?
617 - $this->_fs->get_addon_instance( $api->slug ) :
618 - null;
619 -
620 - if ( is_object( $fs_addon ) ) {
621 - if ( $fs_addon->is_premium() ) {
622 - $is_premium_installed = true;
623 - } else {
624 - $is_free_installed = true;
397 + // Hosted on WordPress.org.
398 + switch ( $status['status'] ) {
399 + case 'install':
400 + if ( $api->is_wp_org_compliant ||
401 + ! $this->_fs->is_org_repo_compliant() ||
402 + $this->_fs->is_premium()
403 + ) {
404 + /**
405 + * Allow immediate installation if one of the following:
406 + * 1. WordPress.org add-on.
407 + * 2. The core module is NOT wp.org compliant.
408 + * 3. The core module is running the premium version which is not wp.org compliant.
409 + */
410 + if ( $status['url'] ) {
411 + return $this->get_cta(
412 + ( $has_paid_version ?
413 + fs_esc_html_inline( 'Install Free Version Now', 'install-free-version-now', $api->slug ) :
414 + fs_esc_html_inline( 'Install Now', 'install-now', $api->slug ) ),
415 + $is_primary,
416 + false,
417 + $status['url'],
418 + '_parent'
419 + );
625 420 }
626 421 }
627 422
628 - if ( is_null( $is_free_installed ) ) {
629 - $is_free_installed = file_exists( fs_normalize_path( WP_PLUGIN_DIR . "/{$api->slug}/{$api->slug}.php" ) );
630 - if ( ! $is_free_installed ) {
631 - /**
632 - * Check if there's a plugin installed in a directory named `$api->slug`.
633 - *
634 - * @author Leo Fajardo (@leorw)
635 - * @since 2.3.0
636 - */
637 - $installed_plugins = get_plugins( '/' . $api->slug );
638 - $is_free_installed = ( ! empty( $installed_plugins ) );
639 - }
423 + return $this->get_cta(
424 + ( $has_paid_version ?
425 + fs_esc_html_x_inline( 'Download Latest Free Version', 'as download latest version', 'download-latest-free-version', $api->slug ) :
426 + fs_esc_html_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $api->slug ) ),
427 + $is_primary,
428 + false,
429 + esc_url( $api->download_link )
430 + );
431 + break;
432 + case 'update_available':
433 + if ( $status['url'] ) {
434 + return $this->get_cta(
435 + ( $has_paid_version ?
436 + fs_esc_html_inline( 'Install Free Version Update Now', 'install-free-version-update-now', $api->slug ) :
437 + fs_esc_html_inline( 'Install Update Now', 'install-update-now', $api->slug ) ),
438 + $is_primary,
439 + false,
440 + $status['url'],
441 + '_parent'
442 + );
640 443 }
641 -
642 - if ( is_null( $is_premium_installed ) ) {
643 - $is_premium_installed = file_exists( fs_normalize_path( WP_PLUGIN_DIR . "/{$api->premium_slug}/{$api->slug}.php" ) );
644 - if ( ! $is_premium_installed ) {
645 - /**
646 - * Check if there's a plugin installed in a directory named `$api->premium_slug`.
647 - *
648 - * @author Leo Fajardo (@leorw)
649 - * @since 2.3.0
650 - */
651 - $installed_plugins = get_plugins( '/' . $api->premium_slug );
652 - $is_premium_installed = ( ! empty( $installed_plugins ) );
653 - }
654 - }
655 - }
656 -
657 - $has_installed_version = ( $is_free_installed || $is_premium_installed );
444 + break;
445 + case 'newer_installed':
446 + return $this->get_cta(
447 + ( $has_paid_version ?
448 + esc_html( sprintf( fs_text_inline( 'Newer Free Version (%s) Installed', 'newer-free-installed', $api->slug ), $status['version'] ) ) :
449 + esc_html( sprintf( fs_text_inline( 'Newer Version (%s) Installed', 'newer-installed', $api->slug ), $status['version'] ) ) ),
450 + $is_primary,
451 + true
452 + );
453 + break;
454 + case 'latest_installed':
455 + return $this->get_cta(
456 + ( $has_paid_version ?
457 + fs_esc_html_inline( 'Latest Free Version Installed', 'latest-free-installed', $api->slug ) :
458 + fs_esc_html_inline( 'Latest Version Installed', 'latest-installed', $api->slug ) ),
459 + $is_primary,
460 + true
461 + );
462 + break;
658 463 }
659 464
660 - $this->status['is_free_installed'] = $is_free_installed;
661 - $this->status['is_premium_installed'] = $is_premium_installed;
662 -
663 - $can_install_free_version = false;
664 - $can_install_free_version_update = false;
665 - $can_download_free_version = false;
666 - $can_activate_free_version = false;
667 - $can_install_premium_version = false;
668 - $can_install_premium_version_update = false;
669 - $can_download_premium_version = false;
670 - $can_activate_premium_version = false;
671 -
672 - if ( ! $api->has_purchased_license ) {
673 - if ( $api->has_free_plan ) {
674 - if ( $has_installed_version ) {
675 - if ( $is_update_available ) {
676 - $can_install_free_version_update = true;
677 - } else if ( ! $is_premium_installed && ! isset( $active_plugins_directories_map[ dirname( $this->status['file'] ) ] ) ) {
678 - $can_activate_free_version = true;
679 - }
680 - } else {
681 - if (
682 - $this->_fs->is_premium() ||
683 - ! $this->_fs->is_org_repo_compliant() ||
684 - $api->is_wp_org_compliant
685 - ) {
686 - $can_install_free_version = true;
687 - } else {
688 - $can_download_free_version = true;
689 - }
690 - }
691 - }
692 - } else {
693 - if ( ! is_object( $fs_addon ) && $is_addon_activated ) {
694 - $fs_addon = $this->_fs->get_addon_instance( $api->slug );
695 - }
696 -
697 - $can_download_premium_version = true;
698 -
699 - if ( ! isset( $active_plugins_directories_map[ dirname( $this->status['file'] ) ] ) ) {
700 - if ( $is_premium_installed ) {
701 - $can_activate_premium_version = ( ! $is_addon_activated || ! $fs_addon->is_premium() );
702 - } else if ( $is_free_installed ) {
703 - $can_activate_free_version = ( ! $is_addon_activated );
704 - }
705 - }
706 -
707 - if ( $this->_fs->is_premium() || ! $this->_fs->is_org_repo_compliant() ) {
708 - if ( $is_update_available ) {
709 - $can_install_premium_version_update = true;
710 - } else if ( ! $is_premium_installed ) {
711 - $can_install_premium_version = true;
712 - }
713 - }
714 - }
715 -
716 - if (
717 - $can_install_premium_version ||
718 - $can_install_premium_version_update
719 - ) {
720 - if ( is_numeric( $blog_id ) ) {
721 - /**
722 - * Replace the network status URL with a blog admin–based status URL if the `Add-Ons` page is loaded
723 - * from a specific blog admin page (when `fs_blog_id` is valid) in order for plugin installation/update
724 - * to work.
725 - *
726 - * @author Leo Fajardo (@leorw)
727 - * @since 2.3.0
728 - */
729 - $this->status['url'] = self::get_blog_status_url( $blog_id, $this->status['url'], $this->status['status'] );
730 - }
731 -
732 - /**
733 - * Add the `fs_allow_updater_and_dialog` param to the install/update URL so that the add-on can be
734 - * installed/updated.
735 - *
736 - * @author Leo Fajardo (@leorw)
737 - * @since 2.3.0
738 - */
739 - $this->status['url'] = str_replace( '?', '?fs_allow_updater_and_dialog=true&amp;', $this->status['url'] );
740 - }
741 -
742 - if ( $can_install_free_version_update || $can_install_premium_version_update ) {
743 - $actions[] = $this->get_cta(
744 - ( $can_install_free_version_update ?
745 - fs_esc_html_inline( 'Install Free Version Update Now', 'install-free-version-update-now', $api->slug ) :
746 - fs_esc_html_inline( 'Install Update Now', 'install-update-now', $api->slug ) ),
747 - true,
748 - false,
749 - $this->status['url'],
750 - '_parent'
751 - );
752 - } else if ( $can_install_free_version || $can_install_premium_version ) {
753 - $actions[] = $this->get_cta(
754 - ( $can_install_free_version ?
755 - fs_esc_html_inline( 'Install Free Version Now', 'install-free-version-now', $api->slug ) :
756 - fs_esc_html_inline( 'Install Now', 'install-now', $api->slug ) ),
757 - true,
758 - false,
759 - $this->status['url'],
760 - '_parent'
761 - );
762 - }
763 -
764 - $download_latest_action = '';
765 -
766 - if (
767 - ! empty( $api->download_link ) &&
768 - ( $can_download_free_version || $can_download_premium_version )
769 - ) {
770 - $download_latest_action = $this->get_cta(
771 - ( $can_download_free_version ?
772 - fs_esc_html_x_inline( 'Download Latest Free Version', 'as download latest version', 'download-latest-free-version', $api->slug ) :
773 - fs_esc_html_x_inline( 'Download Latest', 'as download latest version', 'download-latest', $api->slug ) ),
774 - true,
775 - false,
776 - esc_url( $api->download_link )
777 - );
778 - }
779 -
780 - if ( ! $can_activate_free_version && ! $can_activate_premium_version ) {
781 - if ( ! empty( $download_latest_action ) ) {
782 - $actions[] = $download_latest_action;
783 - }
784 - } else {
785 - $activate_action = sprintf(
786 - '<a class="button button-primary edit" href="%s" title="%s" target="_parent">%s</a>',
787 - wp_nonce_url( ( is_numeric( $blog_id ) ? trailingslashit( get_admin_url( $blog_id ) ) : '' ) . 'plugins.php?action=activate&amp;plugin=' . $this->status['file'], 'activate-plugin_' . $this->status['file'] ),
788 - fs_esc_attr_inline( 'Activate this add-on', 'activate-this-addon', $api->slug ),
789 - $can_activate_free_version ?
790 - fs_text_inline( 'Activate Free Version', 'activate-free', $api->slug ) :
791 - fs_text_inline( 'Activate', 'activate', $api->slug )
792 - );
793 -
794 - if ( ! $can_download_premium_version && ! empty( $download_latest_action ) ) {
795 - $actions[] = $download_latest_action;
796 -
797 - $download_latest_action = '';
798 - }
799 -
800 - if ( $can_install_premium_version || $can_install_premium_version_update ) {
801 - if ( $can_download_premium_version && ! empty( $download_latest_action ) ) {
802 - $actions[] = $download_latest_action;
803 -
804 - $download_latest_action = '';
805 - }
806 -
807 - $actions[] = $activate_action;
808 - } else {
809 - array_unshift( $actions, $activate_action );
810 - }
811 -
812 - if ( ! empty ($download_latest_action ) ) {
813 - $actions[] = $download_latest_action;
814 - }
815 - }
816 -
817 - return $actions;
465 + return '';
818 466 }
819 467
820 468 /**
821 - * Rebuilds the status URL based on the admin URL.
822 - *
823 - * @author Leo Fajardo (@leorw)
824 - * @since 2.3.0
825 - *
826 - * @param int $blog_id
827 - * @param string $network_status_url
828 - * @param string $status
829 - *
830 - * @return string
831 - */
832 - private static function get_blog_status_url( $blog_id, $network_status_url, $status ) {
833 - if ( ! in_array( $status, array( 'install', 'update_available' ) ) ) {
834 - return $network_status_url;
835 - }
836 -
837 - $action = ( 'install' === $status ) ?
838 - 'install-plugin' :
839 - 'upgrade-plugin';
840 -
841 - $url_params = fs_parse_url_params( $network_status_url, true );
842 -
843 - if ( empty( $url_params ) || ! isset( $url_params['plugin'] ) ) {
844 - return $network_status_url;
845 - }
846 -
847 - $plugin = $url_params['plugin'];
848 -
849 - return wp_nonce_url( get_admin_url( $blog_id,"update.php?action={$action}&plugin={$plugin}"), "{$action}_{$plugin}");
850 - }
851 -
852 - /**
853 469 * Helper method to get a CTA button HTML.
854 470 *
855 471 * @author Vova Feldman (@svovaf)
856 472 * @since 2.0.0
@@ -882,13 +498,11 @@
882 498 if ( $is_disabled ) {
883 499 $classes[] = 'disabled';
884 500 }
885 501
886 - $rel = ( '_blank' === $target ) ? ' rel="noopener noreferrer"' : '';
887 -
888 502 return sprintf(
889 503 '<a %s class="button %s">%s</a>',
890 - empty( $href ) ? '' : 'href="' . $href . '" target="' . $target . '"' . $rel,
504 + empty( $href ) ? '' : 'href="' . $href . '" target="' . $target . '"',
891 505 implode( ' ', $classes ),
892 506 $label
893 507 );
894 508 }
@@ -1072,9 +686,9 @@
1072 686 $class = ( $section_name === $section ) ? ' class="current"' : '';
1073 687 $href = add_query_arg( array( 'tab' => $tab, 'section' => $section_name ) );
1074 688 $href = esc_url( $href );
1075 689 $san_section = esc_attr( $section_name );
1076 - echo "\t<a name='$san_section' href='$href' $class>" . esc_html( $title ) . "</a>\n";
690 + echo "\t<a name='$san_section' href='$href' $class>$title</a>\n";
1077 691 }
1078 692
1079 693 echo "</div>\n";
1080 694
@@ -1200,14 +814,14 @@
1200 814 echo " + '&trial=true'";
1201 815 }?>;
1202 816 },
1203 817 _updateCtaUrl = function (plan, pricing, cycle) {
1204 - $('.plugin-information-pricing .fs-checkout-button, #plugin-information-footer .fs-checkout-button').attr('href', _checkoutUrl(plan, pricing, cycle));
818 + $('.plugin-information-pricing .button, #plugin-information-footer .button.fs-checkout-button').attr('href', _checkoutUrl(plan, pricing, cycle));
1205 819 };
1206 820
1207 821 $(document).ready(function () {
1208 822 var $plan = $('.plugin-information-pricing .fs-plan[data-plan-id=<?php echo $plan->id ?>]');
1209 - $plan.find('input[type=radio]').on('click', function () {
823 + $plan.find('input[type=radio]').live('click', function () {
1210 824 _updateCtaUrl(
1211 825 $plan.attr('data-plan-id'),
1212 826 $(this).val(),
1213 827 $plan.find('.nav-tab-active').attr('data-billing-cycle')
@@ -1287,9 +901,9 @@
1287 901 fs_esc_html_inline( 'Save %s', 'save-x', $api->slug ), $annual_discount . '%' ) ?></span>
1288 902 <?php endif ?>
1289 903 <ul class="fs-licenses">
1290 904 </ul>
1291 - <?php echo $this->get_actions_dropdown( $api, $plan ) ?>
905 + <?php echo $this->get_checkout_cta( $api, $plan, false ) ?>
1292 906 <div style="clear:both"></div>
1293 907 <?php if ( $plan->has_trial() ) : ?>
1294 908 <?php $trial_period = $this->get_trial_period( $plan ) ?>
1295 909 <ul class="fs-trial-terms">
@@ -1302,10 +916,10 @@
1302 916 </ul>
1303 917 <?php endif ?>
1304 918 </div>
1305 919 </div>
920 + </div>
1306 921 <?php endforeach ?>
1307 - </div>
1308 922 <?php endif ?>
1309 923 <?php endif ?>
1310 924 <div>
1311 925 <h3><?php fs_echo_inline( 'Details', 'details', $api->slug ) ?></h3>
@@ -1340,12 +954,9 @@
1340 954 if ( ! empty( $api->requires ) ) {
1341 955 ?>
1342 956 <li>
1343 957 <strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?>
1344 - :</strong> <?php echo esc_html( sprintf(
1345 - /* translators: %s: Version number. */
1346 - fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires )
1347 - ) ?>
958 + :</strong> <?php echo esc_html( sprintf( fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires ) ) ?>
1348 959 </li>
1349 960 <?php
1350 961 }
1351 962 if ( ! empty( $api->tested ) ) {
@@ -1355,21 +966,8 @@
1355 966 :</strong> <?php echo $api->tested; ?>
1356 967 </li>
1357 968 <?php
1358 969 }
1359 - if ( ! empty( $api->requires_php ) ) {
1360 - ?>
1361 - <li>
1362 - <strong><?php fs_esc_html_echo_inline( 'Requires PHP Version', 'requires-php-version', $api->slug ); ?>:</strong>
1363 - <?php
1364 - echo esc_html( sprintf(
1365 - /* translators: %s: Version number. */
1366 - fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires_php )
1367 - );
1368 - ?>
1369 - </li>
1370 - <?php
1371 - }
1372 970 if ( ! empty( $api->downloaded ) ) {
1373 971 ?>
1374 972 <li>
1375 973 <strong><?php fs_esc_html_echo_inline( 'Downloaded', 'downloaded', $api->slug ) ?>
@@ -1387,9 +985,8 @@
1387 985 }
1388 986 if ( ! empty( $api->slug ) && true == $api->is_wp_org_compliant ) {
1389 987 ?>
1390 988 <li><a target="_blank"
1391 - rel="noopener noreferrer"
1392 989 href="https://wordpress.org/plugins/<?php echo $api->slug; ?>/"><?php fs_esc_html_echo_inline( 'WordPress.org Plugin Page', 'wp-org-plugin-page', $api->slug ) ?>
1393 990 &#187;</a>
1394 991 </li>
1395 992 <?php
@@ -1396,9 +993,8 @@
1396 993 }
1397 994 if ( ! empty( $api->homepage ) ) {
1398 995 ?>
1399 996 <li><a target="_blank"
1400 - rel="noopener noreferrer"
1401 997 href="<?php echo esc_url( $api->homepage ); ?>"><?php fs_esc_html_echo_inline( 'Plugin Homepage', 'plugin-homepage', $api->slug ) ?>
1402 998 &#187;</a>
1403 999 </li>
1404 1000 <?php
@@ -1405,9 +1001,8 @@
1405 1001 }
1406 1002 if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) {
1407 1003 ?>
1408 1004 <li><a target="_blank"
1409 - rel="noopener noreferrer"
1410 1005 href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_esc_html_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?>
1411 1006 &#187;</a>
1412 1007 </li>
1413 1008 <?php } ?>
@@ -1449,21 +1044,20 @@
1449 1044 number_format_i18n( $key )
1450 1045 );
1451 1046 ?>
1452 1047 <div class="counter-container">
1453 - <span class="counter-label"><a
1454 - href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
1455 - target="_blank"
1456 - rel="noopener noreferrer"
1457 - title="<?php echo esc_attr( sprintf(
1458 - /* translators: %s: # of stars (e.g. 5 stars) */
1459 - fs_text_inline( 'Click to see reviews that provided a rating of %s', 'click-to-reviews', $api->slug ),
1460 - $stars_label
1461 - ) ) ?>"><?php echo $stars_label ?></a></span>
1048 + <span class="counter-label"><a
1049 + href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>"
1050 + target="_blank"
1051 + title="<?php echo esc_attr( sprintf(
1052 + /* translators: %s: # of stars (e.g. 5 stars) */
1053 + fs_text_inline( 'Click to see reviews that provided a rating of %s', 'click-to-reviews', $api->slug ),
1054 + $stars_label
1055 + ) ) ?>"><?php echo $stars_label ?></a></span>
1462 1056 <span class="counter-back">
1463 - <span class="counter-bar" style="width: <?php echo absint(92 * $_rating); ?>px;"></span>
1464 - </span>
1465 - <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
1057 + <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span>
1058 + </span>
1059 + <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span>
1466 1060 </div>
1467 1061 <?php
1468 1062 }
1469 1063 }
@@ -1482,9 +1076,9 @@
1482 1076 $contrib_username = sanitize_user( $contrib_username );
1483 1077 if ( empty( $contrib_profile ) ) {
1484 1078 echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</li>";
1485 1079 } else {
1486 - echo "<li><a href='{$contrib_profile}' target='_blank' rel='noopener noreferrer'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
1080 + echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&amp;s=36' width='18' height='18' />{$contrib_username}</a></li>";
1487 1081 }
1488 1082 }
1489 1083 ?>
1490 1084 </ul>
@@ -1489,9 +1083,8 @@
1489 1083 ?>
1490 1084 </ul>
1491 1085 <?php if ( ! empty( $api->donate_link ) ) { ?>
1492 1086 <a target="_blank"
1493 - rel="noopener noreferrer"
1494 1087 href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?>
1495 1088 &#187;</a>
1496 1089 <?php } ?>
1497 1090 <?php } ?>
@@ -1497,45 +1090,11 @@
1497 1090 <?php } ?>
1498 1091 </div>
1499 1092 <div id="section-holder" class="wrap">
1500 1093 <?php
1501 - $requires_php = isset( $api->requires_php ) ? $api->requires_php : null;
1502 - $requires_wp = isset( $api->requires ) ? $api->requires : null;
1503 -
1504 - $compatible_php = empty( $requires_php ) || version_compare( PHP_VERSION, $requires_php, '>=' );
1505 -
1506 - // Strip off any -alpha, -RC, -beta, -src suffixes.
1507 - list( $wp_version ) = explode( '-', $GLOBALS['wp_version'] );
1508 -
1509 - $compatible_wp = empty( $requires_wp ) || version_compare( $wp_version, $requires_wp, '>=' );
1510 - $tested_wp = ( empty( $api->tested ) || version_compare( $wp_version, $api->tested, '<=' ) );
1511 -
1512 - if ( ! $compatible_php ) {
1513 - echo '<div class="notice notice-error notice-alt"><p><strong>' . fs_text_inline( 'Error', 'error', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin requires a newer version of PHP.', 'newer-php-required-error', $api->slug );
1514 -
1515 - if ( current_user_can( 'update_php' ) ) {
1516 - $wp_get_update_php_url = function_exists( 'wp_get_update_php_url' ) ?
1517 - wp_get_update_php_url() :
1518 - 'https://wordpress.org/support/update-php/';
1519 -
1520 - printf(
1521 - /* translators: %s: URL to Update PHP page. */
1522 - ' ' . fs_text_inline( '<a href="%s" target="_blank">Click here to learn more about updating PHP</a>.', 'php-update-learn-more-link', $api->slug ),
1523 - esc_url( $wp_get_update_php_url )
1524 - );
1525 -
1526 - if ( function_exists( 'wp_update_php_annotation' ) ) {
1527 - wp_update_php_annotation( '</p><p><em>', '</em>' );
1528 - }
1529 - } else {
1530 - echo '</p>';
1531 - }
1532 - echo '</div>';
1533 - }
1534 -
1535 - if ( ! $tested_wp ) {
1094 + if ( ! empty( $api->tested ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->tested ) ), $api->tested, '>' ) ) {
1536 1095 echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been tested with your current version of WordPress.', 'not-tested-warning', $api->slug ) . '</p></div>';
1537 - } else if ( ! $compatible_wp ) {
1096 + } else if ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) {
1538 1097 echo '<div class="notice notice-warning"><p>' . '<strong>' . fs_text_inline( 'Warning', 'warning', $api->slug ) . ':</strong> ' . fs_text_inline( 'This plugin has not been marked as compatible with your version of WordPress.', 'not-compatible-warning', $api->slug ) . '</p></div>';
1539 1098 }
1540 1099
1541 1100 foreach ( (array) $api->sections as $section_name => $content ) {
@@ -1567,125 +1126,18 @@
1567 1126 echo "</div>\n";
1568 1127 echo "</div>\n"; // #plugin-information-scrollable
1569 1128 echo "<div id='$tab-footer'>\n";
1570 1129
1571 - if (
1572 - ! empty( $api->download_link ) &&
1573 - ! empty( $this->status ) &&
1574 - in_array( $this->status['status'], array( 'newer_installed', 'latest_installed' ) )
1575 - ) {
1576 - if ( 'newer_installed' === $this->status['status'] ) {
1577 - echo $this->get_cta(
1578 - ( $this->status['is_premium_installed'] ?
1579 - esc_html( sprintf( fs_text_inline( 'Newer Version (%s) Installed', 'newer-installed', $api->slug ), $this->status['version'] ) ) :
1580 - esc_html( sprintf( fs_text_inline( 'Newer Free Version (%s) Installed', 'newer-free-installed', $api->slug ), $this->status['version'] ) ) ),
1581 - false,
1582 - true
1583 - );
1584 - } else {
1585 - echo $this->get_cta(
1586 - ( $this->status['is_premium_installed'] ?
1587 - fs_esc_html_inline( 'Latest Version Installed', 'latest-installed', $api->slug ) :
1588 - fs_esc_html_inline( 'Latest Free Version Installed', 'latest-free-installed', $api->slug ) ),
1589 - false,
1590 - true
1591 - );
1592 - }
1130 + if ( $api->has_paid_plan && ! empty( $api->checkout_link ) ) {
1131 + echo $this->get_checkout_cta( $api );
1593 1132 }
1594 1133
1595 - echo $this->get_actions_dropdown( $api, null );
1134 + if ( ! empty( $api->download_link ) ) {
1135 + echo $this->get_download_cta( $api, empty( $api->checkout_link ) );
1136 + }
1596 1137
1597 1138 echo "</div>\n";
1598 - ?>
1599 - <script type="text/javascript">
1600 - ( function( $, undef ) {
1601 - var $dropdowns = $( '.fs-dropdown' );
1602 1139
1603 - $( '#plugin-information' )
1604 - .click( function( evt ) {
1605 - var $target = $( evt.target );
1606 -
1607 - if (
1608 - $target.hasClass( 'fs-dropdown-arrow-button' ) ||
1609 - ( 0 !== $target.parents( '.fs-dropdown-arrow-button' ).length )
1610 - ) {
1611 - var $dropdown = $target.parents( '.fs-dropdown' ),
1612 - isActive = $dropdown.hasClass( 'active' );
1613 -
1614 - if ( ! isActive ) {
1615 - /**
1616 - * Close the other dropdown if it's active.
1617 - *
1618 - * @author Leo Fajardo (@leorw)
1619 - * @since 2.3.0
1620 - */
1621 - $( '.fs-dropdown.active' ).each( function() {
1622 - toggleDropdown( $( this ), false );
1623 - } );
1624 - }
1625 -
1626 - /**
1627 - * Toggle the current dropdown.
1628 - *
1629 - * @author Leo Fajardo (@leorw)
1630 - * @since 2.3.0
1631 - */
1632 - toggleDropdown( $dropdown, ! isActive );
1633 -
1634 - return true;
1635 - }
1636 -
1637 - /**
1638 - * Close all dropdowns.
1639 - *
1640 - * @author Leo Fajardo (@leorw)
1641 - * @since 2.3.0
1642 - */
1643 - toggleDropdown( $( this ).find( '.fs-dropdown' ), false );
1644 - });
1645 -
1646 - if ( 0 !== $dropdowns.length ) {
1647 - /**
1648 - * Add the `up` class so that the bottom dropdown's content will be shown above its buttons.
1649 - *
1650 - * @author Leo Fajardo (@leorw)
1651 - * @since 2.3.0
1652 - */
1653 - $( '#plugin-information-footer' ).find( '.fs-dropdown' ).addClass( 'up' );
1654 - }
1655 -
1656 - /**
1657 - * Returns the default state of the dropdown arrow button and hides the dropdown list.
1658 - *
1659 - * @author Leo Fajardo (@leorw)
1660 - * @since 2.3.0
1661 - *
1662 - * @param {Object} [$dropdown]
1663 - * @param {Boolean} [state]
1664 - */
1665 - function toggleDropdown( $dropdown, state ) {
1666 - if ( undef === $dropdown ) {
1667 - var $activeDropdown = $dropdowns.find( '.active' );
1668 - if ( 0 !== $activeDropdown.length ) {
1669 - $dropdown = $activeDropdown;
1670 - }
1671 - }
1672 -
1673 - if ( undef === $dropdown ) {
1674 - return;
1675 - }
1676 -
1677 - if ( undef === state ) {
1678 - state = false;
1679 - }
1680 -
1681 - $dropdown.toggleClass( 'active', state );
1682 - $dropdown.find( '.fs-dropdown-list' ).toggle( state );
1683 - $dropdown.find( '.fs-dropdown-arrow-button' ).toggleClass( 'active', state );
1684 - }
1685 - } )( jQuery );
1686 - </script>
1687 - <?php
1688 1140 iframe_footer();
1689 1141 exit;
1690 1142 }
1691 - }
1143 + }