| @@ -144,17 +144,38 @@ | ||
| 144 | 144 | $has_free_plan = true; |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | 147 | if ( is_array( $pricing ) && 0 < count( $pricing ) ) { |
| 148 | - $has_paid_plan = true; | |
| 148 | + $filtered_pricing = array(); | |
| 149 | 149 | |
| 150 | - foreach ( $pricing as &$prices ) { | |
| 150 | + foreach ( $pricing as $prices ) { | |
| 151 | 151 | $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 | + } | |
| 152 | 169 | } |
| 153 | 170 | |
| 154 | - $plan->pricing = $pricing; | |
| 171 | + if ( ! empty( $filtered_pricing ) ) { | |
| 172 | + $has_paid_plan = true; | |
| 155 | 173 | |
| 156 | - $has_pricing = true; | |
| 174 | + $plan->pricing = $filtered_pricing; | |
| 175 | + | |
| 176 | + $has_pricing = true; | |
| 177 | + } | |
| 157 | 178 | } |
| 158 | 179 | |
| 159 | 180 | if ( is_array( $features ) && 0 < count( $features ) ) { |
| 160 | 181 | $plan->features = $features; |
| @@ -216,9 +237,9 @@ | ||
| 216 | 237 | // Fetch latest version from Freemius. |
| 217 | 238 | $latest = $this->_fs->_fetch_latest_version( |
| 218 | 239 | $selected_addon->id, |
| 219 | 240 | true, |
| 220 | - WP_FS__TIME_24_HOURS_IN_SEC, | |
| 241 | + FS_Plugin_Updater::UPDATES_CHECK_CACHE_EXPIRATION, | |
| 221 | 242 | $current_addon_version |
| 222 | 243 | ); |
| 223 | 244 | |
| 224 | 245 | if ( $has_paid_plan ) { |
| @@ -238,16 +259,22 @@ | ||
| 238 | 259 | |
| 239 | 260 | if ( $has_valid_blog_id ) { |
| 240 | 261 | restore_current_blog(); |
| 241 | 262 | } |
| 263 | + } | |
| 242 | 264 | |
| 243 | - if ( is_object( $fs_addon ) ) { | |
| 244 | - $data->has_purchased_license = $fs_addon->has_active_valid_license(); | |
| 245 | - } else { | |
| 246 | - $account_addons = $this->_fs->get_account_addons(); | |
| 247 | - if ( ! empty( $account_addons ) && in_array( $selected_addon->id, $account_addons ) ) { | |
| 248 | - $data->has_purchased_license = true; | |
| 249 | - } | |
| 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; | |
| 250 | 277 | } |
| 251 | 278 | } |
| 252 | 279 | |
| 253 | 280 | if ( $has_free_plan || $data->has_purchased_license ) { |
| @@ -283,8 +310,9 @@ | ||
| 283 | 310 | if ( is_object( $latest ) ) { |
| 284 | 311 | $data->version = $latest->version; |
| 285 | 312 | $data->last_updated = $latest->created; |
| 286 | 313 | $data->requires = $latest->requires_platform_version; |
| 314 | + $data->requires_php = $latest->requires_programming_language_version; | |
| 287 | 315 | $data->tested = $latest->tested_up_to_version; |
| 288 | 316 | } else if ( ! empty( $current_addon_version ) ) { |
| 289 | 317 | $data->version = $current_addon_version; |
| 290 | 318 | } else { |
| @@ -555,9 +583,9 @@ | ||
| 555 | 583 | $is_premium_installed = null; |
| 556 | 584 | |
| 557 | 585 | $has_installed_version = ( 'install' !== $this->status['status'] ); |
| 558 | 586 | |
| 559 | - if ( ! $api->has_paid_plan ) { | |
| 587 | + if ( ! $api->has_paid_plan && ! $api->has_purchased_license ) { | |
| 560 | 588 | /** |
| 561 | 589 | * Free-only add-on. |
| 562 | 590 | * |
| 563 | 591 | * @author Leo Fajardo (@leorw) |
| @@ -809,14 +837,10 @@ | ||
| 809 | 837 | $action = ( 'install' === $status ) ? |
| 810 | 838 | 'install-plugin' : |
| 811 | 839 | 'upgrade-plugin'; |
| 812 | 840 | |
| 813 | - $query = parse_url( $network_status_url, PHP_URL_QUERY ); | |
| 814 | - if ( empty( $query ) ) { | |
| 815 | - return $network_status_url; | |
| 816 | - } | |
| 841 | + $url_params = fs_parse_url_params( $network_status_url, true ); | |
| 817 | 842 | |
| 818 | - parse_str( html_entity_decode( $query ), $url_params ); | |
| 819 | 843 | if ( empty( $url_params ) || ! isset( $url_params['plugin'] ) ) { |
| 820 | 844 | return $network_status_url; |
| 821 | 845 | } |
| 822 | 846 | |
| @@ -858,11 +882,13 @@ | ||
| 858 | 882 | if ( $is_disabled ) { |
| 859 | 883 | $classes[] = 'disabled'; |
| 860 | 884 | } |
| 861 | 885 | |
| 886 | + $rel = ( '_blank' === $target ) ? ' rel="noopener noreferrer"' : ''; | |
| 887 | + | |
| 862 | 888 | return sprintf( |
| 863 | 889 | '<a %s class="button %s">%s</a>', |
| 864 | - empty( $href ) ? '' : 'href="' . $href . '" target="' . $target . '"', | |
| 890 | + empty( $href ) ? '' : 'href="' . $href . '" target="' . $target . '"' . $rel, | |
| 865 | 891 | implode( ' ', $classes ), |
| 866 | 892 | $label |
| 867 | 893 | ); |
| 868 | 894 | } |
| @@ -1046,9 +1072,9 @@ | ||
| 1046 | 1072 | $class = ( $section_name === $section ) ? ' class="current"' : ''; |
| 1047 | 1073 | $href = add_query_arg( array( 'tab' => $tab, 'section' => $section_name ) ); |
| 1048 | 1074 | $href = esc_url( $href ); |
| 1049 | 1075 | $san_section = esc_attr( $section_name ); |
| 1050 | - echo "\t<a name='$san_section' href='$href' $class>$title</a>\n"; | |
| 1076 | + echo "\t<a name='$san_section' href='$href' $class>" . esc_html( $title ) . "</a>\n"; | |
| 1051 | 1077 | } |
| 1052 | 1078 | |
| 1053 | 1079 | echo "</div>\n"; |
| 1054 | 1080 | |
| @@ -1179,9 +1205,9 @@ | ||
| 1179 | 1205 | }; |
| 1180 | 1206 | |
| 1181 | 1207 | $(document).ready(function () { |
| 1182 | 1208 | var $plan = $('.plugin-information-pricing .fs-plan[data-plan-id=<?php echo $plan->id ?>]'); |
| 1183 | - $plan.find('input[type=radio]').live('click', function () { | |
| 1209 | + $plan.find('input[type=radio]').on('click', function () { | |
| 1184 | 1210 | _updateCtaUrl( |
| 1185 | 1211 | $plan.attr('data-plan-id'), |
| 1186 | 1212 | $(this).val(), |
| 1187 | 1213 | $plan.find('.nav-tab-active').attr('data-billing-cycle') |
| @@ -1276,10 +1302,10 @@ | ||
| 1276 | 1302 | </ul> |
| 1277 | 1303 | <?php endif ?> |
| 1278 | 1304 | </div> |
| 1279 | 1305 | </div> |
| 1280 | - </div> | |
| 1281 | 1306 | <?php endforeach ?> |
| 1307 | + </div> | |
| 1282 | 1308 | <?php endif ?> |
| 1283 | 1309 | <?php endif ?> |
| 1284 | 1310 | <div> |
| 1285 | 1311 | <h3><?php fs_echo_inline( 'Details', 'details', $api->slug ) ?></h3> |
| @@ -1314,9 +1340,12 @@ | ||
| 1314 | 1340 | if ( ! empty( $api->requires ) ) { |
| 1315 | 1341 | ?> |
| 1316 | 1342 | <li> |
| 1317 | 1343 | <strong><?php fs_esc_html_echo_inline( 'Requires WordPress Version', 'requires-wordpress-version', $api->slug ) ?> |
| 1318 | - :</strong> <?php echo esc_html( sprintf( fs_text_inline( '%s or higher', 'x-or-higher', $api->slug ), $api->requires ) ) ?> | |
| 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 | + ) ?> | |
| 1319 | 1348 | </li> |
| 1320 | 1349 | <?php |
| 1321 | 1350 | } |
| 1322 | 1351 | if ( ! empty( $api->tested ) ) { |
| @@ -1326,8 +1355,21 @@ | ||
| 1326 | 1355 | :</strong> <?php echo $api->tested; ?> |
| 1327 | 1356 | </li> |
| 1328 | 1357 | <?php |
| 1329 | 1358 | } |
| 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 | + } | |
| 1330 | 1372 | if ( ! empty( $api->downloaded ) ) { |
| 1331 | 1373 | ?> |
| 1332 | 1374 | <li> |
| 1333 | 1375 | <strong><?php fs_esc_html_echo_inline( 'Downloaded', 'downloaded', $api->slug ) ?> |
| @@ -1345,8 +1387,9 @@ | ||
| 1345 | 1387 | } |
| 1346 | 1388 | if ( ! empty( $api->slug ) && true == $api->is_wp_org_compliant ) { |
| 1347 | 1389 | ?> |
| 1348 | 1390 | <li><a target="_blank" |
| 1391 | + rel="noopener noreferrer" | |
| 1349 | 1392 | 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 ) ?> |
| 1350 | 1393 | »</a> |
| 1351 | 1394 | </li> |
| 1352 | 1395 | <?php |
| @@ -1353,8 +1396,9 @@ | ||
| 1353 | 1396 | } |
| 1354 | 1397 | if ( ! empty( $api->homepage ) ) { |
| 1355 | 1398 | ?> |
| 1356 | 1399 | <li><a target="_blank" |
| 1400 | + rel="noopener noreferrer" | |
| 1357 | 1401 | href="<?php echo esc_url( $api->homepage ); ?>"><?php fs_esc_html_echo_inline( 'Plugin Homepage', 'plugin-homepage', $api->slug ) ?> |
| 1358 | 1402 | »</a> |
| 1359 | 1403 | </li> |
| 1360 | 1404 | <?php |
| @@ -1361,8 +1405,9 @@ | ||
| 1361 | 1405 | } |
| 1362 | 1406 | if ( ! empty( $api->donate_link ) && empty( $api->contributors ) ) { |
| 1363 | 1407 | ?> |
| 1364 | 1408 | <li><a target="_blank" |
| 1409 | + rel="noopener noreferrer" | |
| 1365 | 1410 | href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_esc_html_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?> |
| 1366 | 1411 | »</a> |
| 1367 | 1412 | </li> |
| 1368 | 1413 | <?php } ?> |
| @@ -1404,20 +1449,21 @@ | ||
| 1404 | 1449 | number_format_i18n( $key ) |
| 1405 | 1450 | ); |
| 1406 | 1451 | ?> |
| 1407 | 1452 | <div class="counter-container"> |
| 1408 | - <span class="counter-label"><a | |
| 1409 | - href="https://wordpress.org/support/view/plugin-reviews/<?php echo $api->slug; ?>?filter=<?php echo $key; ?>" | |
| 1410 | - target="_blank" | |
| 1411 | - title="<?php echo esc_attr( sprintf( | |
| 1412 | - /* translators: %s: # of stars (e.g. 5 stars) */ | |
| 1413 | - fs_text_inline( 'Click to see reviews that provided a rating of %s', 'click-to-reviews', $api->slug ), | |
| 1414 | - $stars_label | |
| 1415 | - ) ) ?>"><?php echo $stars_label ?></a></span> | |
| 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> | |
| 1416 | 1462 | <span class="counter-back"> |
| 1417 | - <span class="counter-bar" style="width: <?php echo 92 * $_rating; ?>px;"></span> | |
| 1418 | - </span> | |
| 1419 | - <span class="counter-count"><?php echo number_format_i18n( $ratecount ); ?></span> | |
| 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> | |
| 1420 | 1466 | </div> |
| 1421 | 1467 | <?php |
| 1422 | 1468 | } |
| 1423 | 1469 | } |
| @@ -1436,9 +1482,9 @@ | ||
| 1436 | 1482 | $contrib_username = sanitize_user( $contrib_username ); |
| 1437 | 1483 | if ( empty( $contrib_profile ) ) { |
| 1438 | 1484 | echo "<li><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' />{$contrib_username}</li>"; |
| 1439 | 1485 | } else { |
| 1440 | - echo "<li><a href='{$contrib_profile}' target='_blank'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' />{$contrib_username}</a></li>"; | |
| 1486 | + echo "<li><a href='{$contrib_profile}' target='_blank' rel='noopener noreferrer'><img src='https://wordpress.org/grav-redirect.php?user={$contrib_username}&s=36' width='18' height='18' />{$contrib_username}</a></li>"; | |
| 1441 | 1487 | } |
| 1442 | 1488 | } |
| 1443 | 1489 | ?> |
| 1444 | 1490 | </ul> |
| @@ -1443,8 +1489,9 @@ | ||
| 1443 | 1489 | ?> |
| 1444 | 1490 | </ul> |
| 1445 | 1491 | <?php if ( ! empty( $api->donate_link ) ) { ?> |
| 1446 | 1492 | <a target="_blank" |
| 1493 | + rel="noopener noreferrer" | |
| 1447 | 1494 | href="<?php echo esc_url( $api->donate_link ); ?>"><?php fs_echo_inline( 'Donate to this plugin', 'donate-to-plugin', $api->slug ) ?> |
| 1448 | 1495 | »</a> |
| 1449 | 1496 | <?php } ?> |
| 1450 | 1497 | <?php } ?> |
| @@ -1450,11 +1497,45 @@ | ||
| 1450 | 1497 | <?php } ?> |
| 1451 | 1498 | </div> |
| 1452 | 1499 | <div id="section-holder" class="wrap"> |
| 1453 | 1500 | <?php |
| 1454 | - if ( ! empty( $api->tested ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->tested ) ), $api->tested, '>' ) ) { | |
| 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 ) { | |
| 1455 | 1536 | 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>'; |
| 1456 | - } else if ( ! empty( $api->requires ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $api->requires ) ), $api->requires, '<' ) ) { | |
| 1537 | + } else if ( ! $compatible_wp ) { | |
| 1457 | 1538 | 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>'; |
| 1458 | 1539 | } |
| 1459 | 1540 | |
| 1460 | 1541 | foreach ( (array) $api->sections as $section_name => $content ) { |
| @@ -1606,5 +1687,5 @@ | ||
| 1606 | 1687 | <?php |
| 1607 | 1688 | iframe_footer(); |
| 1608 | 1689 | exit; |
| 1609 | 1690 | } |
| 1610 | - } | |
| 1691 | + } | |