Plugin Directory

Changeset 3356010


Ignore:
Timestamp:
09/04/2025 11:40:56 AM (6 months ago)
Author:
progressplanner
Message:

Update to version 1.7.2 from GitHub

Location:
progress-planner
Files:
2 added
4 deleted
42 edited
1 copied

Legend:

Unmodified
Added
Removed
  • progress-planner/tags/1.7.2/CHANGELOG.md

    r3347435 r3356010  
     1
     2= 1.7.2 =
     3
     4* Backported some features from the Progress Planner Pro plugin.
     5
    16= 1.7.1 =
    27
  • progress-planner/tags/1.7.2/classes/admin/class-editor.php

    r3332738 r3356010  
    3131            $request = \sanitize_text_field( \wp_unslash( $_SERVER['REQUEST_URI'] ) );
    3232        }
    33         if ( $request && str_contains( $request, 'site-editor.php' ) ) {
     33        if ( $request && \str_contains( $request, 'site-editor.php' ) ) {
    3434            return;
    3535        }
  • progress-planner/tags/1.7.2/classes/admin/class-enqueue.php

    r3347435 r3356010  
    411411     */
    412412    public function maybe_empty_session_storage() {
    413         $screen = get_current_screen();
     413        $screen = \get_current_screen();
    414414
    415415        if ( ! $screen ) {
  • progress-planner/tags/1.7.2/classes/admin/class-page-settings.php

    r3316864 r3356010  
    173173        $this->save_settings();
    174174        $this->save_post_types();
    175         $this->save_license();
    176175
    177176        \do_action( 'progress_planner_settings_form_options_stored' );
     
    212211        \progress_planner()->get_settings()->set( 'include_post_types', $include_post_types );
    213212    }
    214 
    215     /**
    216      * Save the license key.
    217      *
    218      * @return void
    219      */
    220     public function save_license() {
    221         // Check the nonce.
    222         \check_admin_referer( 'progress_planner' );
    223 
    224         $license = isset( $_POST['prpl-pro-license-key'] )
    225             ? \sanitize_text_field( \wp_unslash( $_POST['prpl-pro-license-key'] ) )
    226             : '';
    227 
    228         $previous = \get_option( 'progress_planner_pro_license_key' );
    229         $is_new   = $previous !== $license;
    230 
    231         if ( ! $is_new ) {
    232             return;
    233         }
    234 
    235         \update_option( 'progress_planner_pro_license_key', $license );
    236         \update_option( 'progress_planner_pro_license_status', null );
    237 
    238         // Do nothing if user just cleared the license.
    239         if ( empty( $license ) ) {
    240             return;
    241         }
    242 
    243         // Call the custom API.
    244         $response = \wp_remote_post(
    245             \progress_planner()->get_remote_server_root_url(),
    246             [
    247                 'timeout'   => 15,
    248                 'sslverify' => false,
    249                 'body'      => [
    250                     'edd_action'  => 'activate_license',
    251                     'license'     => $license,
    252                     'item_id'     => 1136,
    253                     'item_name'   => \rawurlencode( 'Progress Planner Pro' ),
    254                     'url'         => \home_url(),
    255                     'environment' => \function_exists( 'wp_get_environment_type' ) ? \wp_get_environment_type() : 'production',
    256                 ],
    257             ]
    258         );
    259 
    260         // Make sure the response came back okay.
    261         if ( \is_wp_error( $response ) || 200 !== \wp_remote_retrieve_response_code( $response ) ) {
    262             if ( \is_wp_error( $response ) ) {
    263                 \wp_send_json_error( $response->get_error_message() );
    264             }
    265             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    266         }
    267         $license_data = \json_decode( \wp_remote_retrieve_body( $response ), true );
    268         if ( ! $license_data || ! \is_array( $license_data ) ) {
    269             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    270         }
    271 
    272         \update_option( 'progress_planner_pro_license_status', $license_data['license'] );
    273 
    274         if ( true === $license_data['success'] ) {
    275             return;
    276         }
    277 
    278         if ( false !== $license_data['success'] ) {
    279             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    280         }
    281 
    282         if ( ! isset( $license_data['error'] ) ) {
    283             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    284         }
    285 
    286         // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
    287         switch ( $license_data['error'] ) {
    288             case 'expired':
    289                 \wp_send_json_error( \esc_html__( 'Your license key has expired.', 'progress-planner' ) );
    290 
    291             case 'disabled':
    292             case 'revoked':
    293                 \wp_send_json_error( \esc_html__( 'Your license key has been disabled.', 'progress-planner' ) );
    294 
    295             case 'missing':
    296                 \wp_send_json_error( \esc_html__( 'Invalid license.', 'progress-planner' ) );
    297 
    298             case 'invalid':
    299             case 'site_inactive':
    300                 \wp_send_json_error( \esc_html__( 'Your license is not active for this URL.', 'progress-planner' ) );
    301 
    302             case 'item_name_mismatch':
    303                 \wp_send_json_error(
    304                     \sprintf(
    305                         /* translators: the plugin name */
    306                         \esc_html__( 'This appears to be an invalid license key for %s.', 'progress-planner' ),
    307                         'Progress Planner Pro'
    308                     )
    309                 );
    310 
    311             case 'no_activations_left':
    312                 \wp_send_json_error( \esc_html__( 'Your license key has reached its activation limit.', 'progress-planner' ) );
    313 
    314             default:
    315                 \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    316         }
    317         // phpcs:enable
    318     }
    319213}
  • progress-planner/tags/1.7.2/classes/admin/widgets/class-challenge.php

    r3316864 r3356010  
    2323     * Get the feed from the blog.
    2424     *
    25      * @param bool $force_free Whether to force the free version.
    26      *
    2725     * @return array
    2826     */
    29     public function get_challenge( $force_free = false ) {
    30         $cache_key = $this->get_cache_key( $force_free );
     27    public function get_challenge() {
     28        $cache_key = $this->get_cache_key();
    3129        $feed_data = \progress_planner()->get_utils__cache()->get( $cache_key );
    3230
     
    4240        if ( $feed_data['expires'] < \time() ) {
    4341            // Get the feed using the REST API.
    44             $response = \wp_remote_get( $this->get_remote_api_url( $force_free ) );
     42            $response = \wp_remote_get( $this->get_remote_api_url() );
    4543
    4644            if ( 200 !== \wp_remote_retrieve_response_code( $response ) ) {
    47                 // Fallback to free response if PRO but the license is invalid.
    48                 if ( ! $force_free && \progress_planner()->is_pro_site() ) {
    49                     return $this->get_challenge( true );
    50                 }
    51 
    5245                // If we cant fetch the feed, we will try again later.
    5346                $feed_data['expires'] = \time() + 5 * MINUTE_IN_SECONDS;
     
    8477     * Get the cache key.
    8578     *
    86      * @param bool $force_free Whether to force the free version.
    87      *
    8879     * @return string
    8980     */
    90     public function get_cache_key( $force_free = false ) {
    91         return \md5( $this->get_remote_api_url( $force_free ) );
     81    public function get_cache_key() {
     82        return \md5( $this->get_remote_api_url() );
    9283    }
    9384
     
    9586     * Get the remote-API URL.
    9687     *
    97      * @param bool $force_free Whether to force the free version.
    98      *
    9988     * @return string
    10089     */
    101     public function get_remote_api_url( $force_free = false ) {
    102         $url = \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/challenges';
    103         $url = ( ! $force_free && \progress_planner()->is_pro_site() )
    104             ? \add_query_arg(
    105                 [
    106                     'license_key' => \get_option( 'progress_planner_pro_license_key' ),
    107                     'site'        => \get_site_url(),
    108                 ],
    109                 $url
    110             )
    111             : \add_query_arg( [ 'site' => \get_site_url() ], $url );
    112 
    113         return $url;
     90    public function get_remote_api_url() {
     91        return \add_query_arg(
     92            [
     93                'license_key' => \get_option( 'progress_planner_license_key' ),
     94                'site'        => \get_site_url(),
     95            ],
     96            \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/challenges'
     97        );
    11498    }
    11599}
  • progress-planner/tags/1.7.2/classes/class-base.php

    r3347435 r3356010  
    114114
    115115        // Post-meta.
    116         if ( $this->is_pro_site() ) {
    117             $this->get_page_todos();
    118         }
     116        $this->get_page_todos();
    119117
    120118        \add_filter( 'plugin_action_links_' . \plugin_basename( PROGRESS_PLANNER_FILE ), [ $this, 'add_action_links' ] );
     
    435433
    436434    /**
    437      * Check if this is a PRO site.
    438      *
    439      * @return bool
    440      */
    441     public function is_pro_site() {
    442         return \get_option( 'progress_planner_pro_license_key' )
    443             && 'valid' === \get_option( 'progress_planner_pro_license_status' );
    444     }
    445 
    446     /**
    447435     * Redirect on login.
    448436     *
  • progress-planner/tags/1.7.2/classes/class-lessons.php

    r3316864 r3356010  
    3838    public function get_remote_api_items() {
    3939        $url = \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/lessons';
    40         $url = ( \progress_planner()->is_pro_site() )
    41             ? \add_query_arg(
    42                 [
    43                     'site'        => \get_site_url(),
    44                     'license_key' => \get_option( 'progress_planner_pro_license_key' ),
    45                 ],
    46                 $url
    47             )
    48             : \add_query_arg( [ 'site' => \get_site_url() ], $url );
     40        $url = \add_query_arg(
     41            [
     42                'site'        => \get_site_url(),
     43                'license_key' => \get_option( 'progress_planner_license_key' ),
     44            ],
     45            $url
     46        );
    4947
    5048        $cache_key = \md5( $url );
  • progress-planner/tags/1.7.2/classes/class-plugin-installer.php

    r3343364 r3356010  
    260260
    261261        // If the is_plugin_active function does not exist, include the necessary file.
    262         if ( ! function_exists( 'is_plugin_active' ) ) {
     262        if ( ! \function_exists( 'is_plugin_active' ) ) {
    263263            require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore-line
    264264        }
     
    282282
    283283        // If the get_plugins function does not exist, include the necessary file.
    284         if ( ! function_exists( 'get_plugins' ) ) {
     284        if ( ! \function_exists( 'get_plugins' ) ) {
    285285            require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore-line
    286286        }
  • progress-planner/tags/1.7.2/classes/rest/class-stats.php

    r3316864 r3356010  
    7373     */
    7474    public function validate_token( $token ) {
    75         $token = \str_replace( 'token/', '', $token );
    76         if ( \progress_planner()->is_pro_site() && $token === \get_option( 'progress_planner_pro_license_key' ) ) {
    77             return true;
    78         }
     75        $token       = \str_replace( 'token/', '', $token );
    7976        $license_key = \get_option( 'progress_planner_license_key', false );
    8077        if ( ! $license_key || 'no-license' === $license_key ) {
  • progress-planner/tags/1.7.2/classes/rest/class-tasks.php

    r3343364 r3356010  
    6161        }
    6262
    63         if ( \progress_planner()->is_pro_site() && $token === \get_option( 'progress_planner_pro_license_key' ) ) {
    64             return true;
    65         }
    6663        $license_key = \get_option( 'progress_planner_license_key', false );
    6764        if ( ! $license_key || 'no-license' === $license_key ) {
  • progress-planner/tags/1.7.2/classes/suggested-tasks/class-tasks-manager.php

    r3347435 r3356010  
    305305    public function handle_task_unsnooze( $new_status, $old_status, $post ) {
    306306        // Early exit if it's not task for which snooze period is over.
    307         if ( 'future' !== $old_status || 'publish' !== $new_status || 'prpl_recommendations' !== get_post_type( $post ) ) {
     307        if ( 'future' !== $old_status || 'publish' !== $new_status || 'prpl_recommendations' !== \get_post_type( $post ) ) {
    308308            return;
    309309        }
  • progress-planner/tags/1.7.2/classes/suggested-tasks/providers/class-disable-comments.php

    r3343364 r3356010  
    120120            \esc_html_e( 'Your site currently has no approved comments. Therefore, it seems your site might not need comments. If that is true for most posts or pages on your site, you can use WordPress\'s default setting to disable comments.', 'progress-planner' );
    121121        } else {
    122             printf(
     122            \printf(
    123123                \esc_html(
    124124                    // translators: %d is the number of approved comments.
  • progress-planner/tags/1.7.2/classes/suggested-tasks/providers/class-select-locale.php

    r3343364 r3356010  
    202202    public function print_popover_form_contents() {
    203203
    204         if ( ! function_exists( 'wp_get_available_translations' ) ) {
     204        if ( ! \function_exists( 'wp_get_available_translations' ) ) {
    205205            require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
    206206        }
     
    209209        $translations = \wp_get_available_translations();
    210210        $locale       = \get_locale();
    211         if ( ! in_array( $locale, $languages, true ) ) {
     211        if ( ! \in_array( $locale, $languages, true ) ) {
    212212            $locale = '';
    213213        }
    214214
    215         wp_dropdown_languages(
     215        \wp_dropdown_languages(
    216216            [
    217217                'name'                        => 'language',
     
    220220                'languages'                   => $languages,
    221221                'translations'                => $translations,
    222                 'show_available_translations' => current_user_can( 'install_languages' ) && wp_can_install_language_pack(),
     222                'show_available_translations' => \current_user_can( 'install_languages' ) && \wp_can_install_language_pack(),
    223223            ]
    224224        );
     
    271271
    272272        // Handle translation installation.
    273         if ( current_user_can( 'install_languages' ) ) {
     273        if ( \current_user_can( 'install_languages' ) ) {
    274274            require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
    275275
    276             if ( wp_can_install_language_pack() ) {
    277                 $language = wp_download_language_pack( $language_for_update );
     276            if ( \wp_can_install_language_pack() ) {
     277                $language = \wp_download_language_pack( $language_for_update );
    278278                if ( $language ) {
    279279                    $language_for_update = $language;
  • progress-planner/tags/1.7.2/classes/suggested-tasks/providers/class-select-timezone.php

    r3343364 r3356010  
    120120
    121121        // Remove old Etc mappings. Fallback to gmt_offset.
    122         if ( str_contains( $tzstring, 'Etc/GMT' ) ) {
     122        if ( \str_contains( $tzstring, 'Etc/GMT' ) ) {
    123123            $tzstring = '';
    124124        }
     
    187187
    188188        // Map UTC+- timezones to gmt_offsets and set timezone_string to empty.
    189         if ( preg_match( '/^UTC[+-]/', $timezone_string ) ) {
     189        if ( \preg_match( '/^UTC[+-]/', $timezone_string ) ) {
    190190            // Set the gmt_offset to the value of the timezone_string, strip the UTC prefix.
    191             $gmt_offset = preg_replace( '/UTC\+?/', '', $timezone_string );
     191            $gmt_offset = \preg_replace( '/UTC\+?/', '', $timezone_string );
    192192
    193193            // Reset the timezone_string to empty.
     
    195195
    196196            $update_options = true;
    197         } elseif ( in_array( $timezone_string, \timezone_identifiers_list( \DateTimeZone::ALL_WITH_BC ), true ) ) {
     197        } elseif ( \in_array( $timezone_string, \timezone_identifiers_list( \DateTimeZone::ALL_WITH_BC ), true ) ) {
    198198            // $timezone_string is already set, reset the value for $gmt_offset.
    199199            $gmt_offset = '';
  • progress-planner/tags/1.7.2/classes/suggested-tasks/providers/class-settings-saved.php

    r3316864 r3356010  
    6767     */
    6868    public function should_add_task() {
    69         return false === \get_option( 'progress_planner_pro_license_key', false );
     69        return ! \progress_planner()->get_settings()->get( 'include_post_types' );
    7070    }
    7171}
  • progress-planner/tags/1.7.2/classes/utils/class-debug-tools.php

    r3316864 r3356010  
    493493            ]
    494494        );
    495 
    496         $prpl_pro_license = \get_option( 'progress_planner_pro_license_key', false );
    497         $admin_bar->add_node(
    498             [
    499                 'id'     => 'prpl-pro-license',
    500                 'parent' => 'prpl-more-info',
    501                 'title'  => 'Pro License: ' . ( false !== $prpl_pro_license ? $prpl_pro_license : 'Not set' ),
    502             ]
    503         );
    504 
    505         $prpl_pro_license_status = \get_option( 'progress_planner_pro_license_status', false );
    506         $admin_bar->add_node(
    507             [
    508                 'id'     => 'prpl-pro-license-status',
    509                 'parent' => 'prpl-more-info',
    510                 'title'  => 'Pro License Status: ' . ( false !== $prpl_pro_license_status ? $prpl_pro_license_status : 'Not set' ),
    511             ]
    512         );
    513495    }
    514496
     
    592574        // Delete the option.
    593575        \delete_option( 'progress_planner_license_key' );
    594         \delete_option( 'progress_planner_pro_license_key' );
    595         \delete_option( 'progress_planner_pro_license_status' );
    596576
    597577        // Redirect to the same page without the parameter.
  • progress-planner/tags/1.7.2/classes/wp-cli/class-task-command.php

    r3343364 r3356010  
    7777                        break;
    7878                    case 'provider_id':
    79                         $formatted[ $field ] = is_object( $task->provider ?? null ) && isset( $task->provider->name ) ? $task->provider->name : '';
     79                        $formatted[ $field ] = \is_object( $task->provider ?? null ) && isset( $task->provider->name ) ? $task->provider->name : '';
    8080                        break;
    8181                    case 'category':
    82                         $formatted[ $field ] = is_object( $task->category ?? null ) && isset( $task->category->name ) ? $task->category->name : '';
     82                        $formatted[ $field ] = \is_object( $task->category ?? null ) && isset( $task->category->name ) ? $task->category->name : '';
    8383                        break;
    8484                    default:
  • progress-planner/tags/1.7.2/progress-planner.php

    r3347435 r3356010  
    1010 * Requires at least: 6.6
    1111 * Requires PHP:      7.4
    12  * Version:           1.7.1
     12 * Version:           1.7.2
    1313 * Author:            Team Emilia Projects
    1414 * Author URI:        https://prpl.fyi/about
  • progress-planner/tags/1.7.2/readme.txt

    r3347435 r3356010  
    55Tested up to: 6.8
    66Requires PHP: 7.4
    7 Stable tag: 1.7.1
     7Stable tag: 1.7.2
    88License: GPL3+
    99License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
     
    3636Your dashboard gives you a clear overview of your website’s progress. See your recommendations, to-do list and achievements at a glance — so you can jump right into the most important tasks.
    3737
    38 ### 🆘 Want expert guidance? Get Progress Planner Pro
    39 
    40 If you’re ready to take things further, [Progress Planner Pro](https://progressplanner.com/pro/) gives you access to in-depth guidance and structured challenges that walk you through key website improvements step by step.
    41 
    42 #### Get results with guided challenges
    43 Maintaining a website can feel overwhelming — but you don’t have to do it alone. With Progress Planner Pro, you get access to expert-led challenges that guide you through key website improvements step by step.
    44 
    45 Each challenge is interactive and tailored to help you make real progress. You can expect:
    46 
    47 * Live **webinars & workshops** with experts sharing insights and strategies
    48 * Actionable **reports & exercises** to apply what you’ve learned to your own site
    49 * Personal **feedback & support**, like having your copywriting reviewed
    50 * A **structured plan**, so you always know what to do next
    51 
    52 It’s not just advice — it’s a hands-on, practical experience that helps you take real action and see results.
    53 
    54 #### Learn with practical mini courses
    55 
    56 Want to sharpen your skills while improving your site? [Progress Planner Pro](https://progressplanner.com/pro/) includes mini courses that give you the knowledge you need — without the fluff.
    57 
    58 #### Get support when you need it
    59 Sometimes you just need a little extra help. With Pro, you get access to our support team, ready to answer your questions and guide you through website improvements.
    60 
    6138### 🧹 Ready to make website maintenance easier?
    6239Progress Planner takes the frustration out of keeping your website in top shape. Whether you’re tackling quick fixes or diving into bigger improvements, you’ll always know what to do next.
     
    7451
    7552Currently, Progress Planner supports tracking for one website per WordPress installation. We are exploring multi-site support for future updates.
    76 
    77 = Is there a Pro version of Progress Planner? =
    78 
    79 Yes! You can [find it right here](https://progressplanner.com/pro/).
    8053
    8154= Where do I file bugs? =
     
    11083
    11184== Changelog ==
     85
     86= 1.7.2 =
     87
     88* Backported some features from the Progress Planner Pro plugin.
    11289
    11390= 1.7.1 =
  • progress-planner/tags/1.7.2/views/admin-page-header.php

    r3316864 r3356010  
    2020<div class="prpl-header">
    2121    <div class="prpl-header-logo">
    22         <?php
    23         if ( \progress_planner()->is_pro_site() ) {
    24             \progress_planner()->the_asset( 'images/logo_progress_planner_pro.svg' );
    25         } else {
    26             \progress_planner()->the_asset( 'images/logo_progress_planner.svg' );
    27         }
    28         ?>
     22        <?php \progress_planner()->the_asset( 'images/logo_progress_planner.svg' ); ?>
    2923    </div>
    3024
  • progress-planner/tags/1.7.2/views/admin-page-settings.php

    r3316864 r3356010  
    1515    <div class="prpl-header">
    1616        <div class="prpl-header-logo">
    17             <?php
    18             if ( \progress_planner()->is_pro_site() ) {
    19                 \progress_planner()->the_asset( 'images/logo_progress_planner_pro.svg' );
    20             } else {
    21                 \progress_planner()->the_asset( 'images/logo_progress_planner.svg' );
    22             }
    23             ?>
     17            <?php \progress_planner()->the_asset( 'images/logo_progress_planner.svg' ); ?>
    2418        </div>
    2519    </div>
     
    3933            <?php \progress_planner()->the_view( 'page-settings/post-types.php' ); ?>
    4034            <?php \progress_planner()->the_view( 'page-settings/settings.php' ); ?>
    41             <?php \progress_planner()->the_view( 'page-settings/license.php' ); ?>
    4235        </div>
    4336
  • progress-planner/trunk/CHANGELOG.md

    r3347435 r3356010  
     1
     2= 1.7.2 =
     3
     4* Backported some features from the Progress Planner Pro plugin.
     5
    16= 1.7.1 =
    27
  • progress-planner/trunk/classes/admin/class-editor.php

    r3332738 r3356010  
    3131            $request = \sanitize_text_field( \wp_unslash( $_SERVER['REQUEST_URI'] ) );
    3232        }
    33         if ( $request && str_contains( $request, 'site-editor.php' ) ) {
     33        if ( $request && \str_contains( $request, 'site-editor.php' ) ) {
    3434            return;
    3535        }
  • progress-planner/trunk/classes/admin/class-enqueue.php

    r3347435 r3356010  
    411411     */
    412412    public function maybe_empty_session_storage() {
    413         $screen = get_current_screen();
     413        $screen = \get_current_screen();
    414414
    415415        if ( ! $screen ) {
  • progress-planner/trunk/classes/admin/class-page-settings.php

    r3316864 r3356010  
    173173        $this->save_settings();
    174174        $this->save_post_types();
    175         $this->save_license();
    176175
    177176        \do_action( 'progress_planner_settings_form_options_stored' );
     
    212211        \progress_planner()->get_settings()->set( 'include_post_types', $include_post_types );
    213212    }
    214 
    215     /**
    216      * Save the license key.
    217      *
    218      * @return void
    219      */
    220     public function save_license() {
    221         // Check the nonce.
    222         \check_admin_referer( 'progress_planner' );
    223 
    224         $license = isset( $_POST['prpl-pro-license-key'] )
    225             ? \sanitize_text_field( \wp_unslash( $_POST['prpl-pro-license-key'] ) )
    226             : '';
    227 
    228         $previous = \get_option( 'progress_planner_pro_license_key' );
    229         $is_new   = $previous !== $license;
    230 
    231         if ( ! $is_new ) {
    232             return;
    233         }
    234 
    235         \update_option( 'progress_planner_pro_license_key', $license );
    236         \update_option( 'progress_planner_pro_license_status', null );
    237 
    238         // Do nothing if user just cleared the license.
    239         if ( empty( $license ) ) {
    240             return;
    241         }
    242 
    243         // Call the custom API.
    244         $response = \wp_remote_post(
    245             \progress_planner()->get_remote_server_root_url(),
    246             [
    247                 'timeout'   => 15,
    248                 'sslverify' => false,
    249                 'body'      => [
    250                     'edd_action'  => 'activate_license',
    251                     'license'     => $license,
    252                     'item_id'     => 1136,
    253                     'item_name'   => \rawurlencode( 'Progress Planner Pro' ),
    254                     'url'         => \home_url(),
    255                     'environment' => \function_exists( 'wp_get_environment_type' ) ? \wp_get_environment_type() : 'production',
    256                 ],
    257             ]
    258         );
    259 
    260         // Make sure the response came back okay.
    261         if ( \is_wp_error( $response ) || 200 !== \wp_remote_retrieve_response_code( $response ) ) {
    262             if ( \is_wp_error( $response ) ) {
    263                 \wp_send_json_error( $response->get_error_message() );
    264             }
    265             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    266         }
    267         $license_data = \json_decode( \wp_remote_retrieve_body( $response ), true );
    268         if ( ! $license_data || ! \is_array( $license_data ) ) {
    269             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    270         }
    271 
    272         \update_option( 'progress_planner_pro_license_status', $license_data['license'] );
    273 
    274         if ( true === $license_data['success'] ) {
    275             return;
    276         }
    277 
    278         if ( false !== $license_data['success'] ) {
    279             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    280         }
    281 
    282         if ( ! isset( $license_data['error'] ) ) {
    283             \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    284         }
    285 
    286         // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
    287         switch ( $license_data['error'] ) {
    288             case 'expired':
    289                 \wp_send_json_error( \esc_html__( 'Your license key has expired.', 'progress-planner' ) );
    290 
    291             case 'disabled':
    292             case 'revoked':
    293                 \wp_send_json_error( \esc_html__( 'Your license key has been disabled.', 'progress-planner' ) );
    294 
    295             case 'missing':
    296                 \wp_send_json_error( \esc_html__( 'Invalid license.', 'progress-planner' ) );
    297 
    298             case 'invalid':
    299             case 'site_inactive':
    300                 \wp_send_json_error( \esc_html__( 'Your license is not active for this URL.', 'progress-planner' ) );
    301 
    302             case 'item_name_mismatch':
    303                 \wp_send_json_error(
    304                     \sprintf(
    305                         /* translators: the plugin name */
    306                         \esc_html__( 'This appears to be an invalid license key for %s.', 'progress-planner' ),
    307                         'Progress Planner Pro'
    308                     )
    309                 );
    310 
    311             case 'no_activations_left':
    312                 \wp_send_json_error( \esc_html__( 'Your license key has reached its activation limit.', 'progress-planner' ) );
    313 
    314             default:
    315                 \wp_send_json_error( \esc_html__( 'An error occurred, please try again.', 'progress-planner' ) );
    316         }
    317         // phpcs:enable
    318     }
    319213}
  • progress-planner/trunk/classes/admin/widgets/class-challenge.php

    r3316864 r3356010  
    2323     * Get the feed from the blog.
    2424     *
    25      * @param bool $force_free Whether to force the free version.
    26      *
    2725     * @return array
    2826     */
    29     public function get_challenge( $force_free = false ) {
    30         $cache_key = $this->get_cache_key( $force_free );
     27    public function get_challenge() {
     28        $cache_key = $this->get_cache_key();
    3129        $feed_data = \progress_planner()->get_utils__cache()->get( $cache_key );
    3230
     
    4240        if ( $feed_data['expires'] < \time() ) {
    4341            // Get the feed using the REST API.
    44             $response = \wp_remote_get( $this->get_remote_api_url( $force_free ) );
     42            $response = \wp_remote_get( $this->get_remote_api_url() );
    4543
    4644            if ( 200 !== \wp_remote_retrieve_response_code( $response ) ) {
    47                 // Fallback to free response if PRO but the license is invalid.
    48                 if ( ! $force_free && \progress_planner()->is_pro_site() ) {
    49                     return $this->get_challenge( true );
    50                 }
    51 
    5245                // If we cant fetch the feed, we will try again later.
    5346                $feed_data['expires'] = \time() + 5 * MINUTE_IN_SECONDS;
     
    8477     * Get the cache key.
    8578     *
    86      * @param bool $force_free Whether to force the free version.
    87      *
    8879     * @return string
    8980     */
    90     public function get_cache_key( $force_free = false ) {
    91         return \md5( $this->get_remote_api_url( $force_free ) );
     81    public function get_cache_key() {
     82        return \md5( $this->get_remote_api_url() );
    9283    }
    9384
     
    9586     * Get the remote-API URL.
    9687     *
    97      * @param bool $force_free Whether to force the free version.
    98      *
    9988     * @return string
    10089     */
    101     public function get_remote_api_url( $force_free = false ) {
    102         $url = \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/challenges';
    103         $url = ( ! $force_free && \progress_planner()->is_pro_site() )
    104             ? \add_query_arg(
    105                 [
    106                     'license_key' => \get_option( 'progress_planner_pro_license_key' ),
    107                     'site'        => \get_site_url(),
    108                 ],
    109                 $url
    110             )
    111             : \add_query_arg( [ 'site' => \get_site_url() ], $url );
    112 
    113         return $url;
     90    public function get_remote_api_url() {
     91        return \add_query_arg(
     92            [
     93                'license_key' => \get_option( 'progress_planner_license_key' ),
     94                'site'        => \get_site_url(),
     95            ],
     96            \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/challenges'
     97        );
    11498    }
    11599}
  • progress-planner/trunk/classes/class-base.php

    r3347435 r3356010  
    114114
    115115        // Post-meta.
    116         if ( $this->is_pro_site() ) {
    117             $this->get_page_todos();
    118         }
     116        $this->get_page_todos();
    119117
    120118        \add_filter( 'plugin_action_links_' . \plugin_basename( PROGRESS_PLANNER_FILE ), [ $this, 'add_action_links' ] );
     
    435433
    436434    /**
    437      * Check if this is a PRO site.
    438      *
    439      * @return bool
    440      */
    441     public function is_pro_site() {
    442         return \get_option( 'progress_planner_pro_license_key' )
    443             && 'valid' === \get_option( 'progress_planner_pro_license_status' );
    444     }
    445 
    446     /**
    447435     * Redirect on login.
    448436     *
  • progress-planner/trunk/classes/class-lessons.php

    r3316864 r3356010  
    3838    public function get_remote_api_items() {
    3939        $url = \progress_planner()->get_remote_server_root_url() . '/wp-json/progress-planner-saas/v1/lessons';
    40         $url = ( \progress_planner()->is_pro_site() )
    41             ? \add_query_arg(
    42                 [
    43                     'site'        => \get_site_url(),
    44                     'license_key' => \get_option( 'progress_planner_pro_license_key' ),
    45                 ],
    46                 $url
    47             )
    48             : \add_query_arg( [ 'site' => \get_site_url() ], $url );
     40        $url = \add_query_arg(
     41            [
     42                'site'        => \get_site_url(),
     43                'license_key' => \get_option( 'progress_planner_license_key' ),
     44            ],
     45            $url
     46        );
    4947
    5048        $cache_key = \md5( $url );
  • progress-planner/trunk/classes/class-plugin-installer.php

    r3343364 r3356010  
    260260
    261261        // If the is_plugin_active function does not exist, include the necessary file.
    262         if ( ! function_exists( 'is_plugin_active' ) ) {
     262        if ( ! \function_exists( 'is_plugin_active' ) ) {
    263263            require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore-line
    264264        }
     
    282282
    283283        // If the get_plugins function does not exist, include the necessary file.
    284         if ( ! function_exists( 'get_plugins' ) ) {
     284        if ( ! \function_exists( 'get_plugins' ) ) {
    285285            require_once ABSPATH . 'wp-admin/includes/plugin.php'; // @phpstan-ignore-line
    286286        }
  • progress-planner/trunk/classes/rest/class-stats.php

    r3316864 r3356010  
    7373     */
    7474    public function validate_token( $token ) {
    75         $token = \str_replace( 'token/', '', $token );
    76         if ( \progress_planner()->is_pro_site() && $token === \get_option( 'progress_planner_pro_license_key' ) ) {
    77             return true;
    78         }
     75        $token       = \str_replace( 'token/', '', $token );
    7976        $license_key = \get_option( 'progress_planner_license_key', false );
    8077        if ( ! $license_key || 'no-license' === $license_key ) {
  • progress-planner/trunk/classes/rest/class-tasks.php

    r3343364 r3356010  
    6161        }
    6262
    63         if ( \progress_planner()->is_pro_site() && $token === \get_option( 'progress_planner_pro_license_key' ) ) {
    64             return true;
    65         }
    6663        $license_key = \get_option( 'progress_planner_license_key', false );
    6764        if ( ! $license_key || 'no-license' === $license_key ) {
  • progress-planner/trunk/classes/suggested-tasks/class-tasks-manager.php

    r3347435 r3356010  
    305305    public function handle_task_unsnooze( $new_status, $old_status, $post ) {
    306306        // Early exit if it's not task for which snooze period is over.
    307         if ( 'future' !== $old_status || 'publish' !== $new_status || 'prpl_recommendations' !== get_post_type( $post ) ) {
     307        if ( 'future' !== $old_status || 'publish' !== $new_status || 'prpl_recommendations' !== \get_post_type( $post ) ) {
    308308            return;
    309309        }
  • progress-planner/trunk/classes/suggested-tasks/providers/class-disable-comments.php

    r3343364 r3356010  
    120120            \esc_html_e( 'Your site currently has no approved comments. Therefore, it seems your site might not need comments. If that is true for most posts or pages on your site, you can use WordPress\'s default setting to disable comments.', 'progress-planner' );
    121121        } else {
    122             printf(
     122            \printf(
    123123                \esc_html(
    124124                    // translators: %d is the number of approved comments.
  • progress-planner/trunk/classes/suggested-tasks/providers/class-select-locale.php

    r3343364 r3356010  
    202202    public function print_popover_form_contents() {
    203203
    204         if ( ! function_exists( 'wp_get_available_translations' ) ) {
     204        if ( ! \function_exists( 'wp_get_available_translations' ) ) {
    205205            require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
    206206        }
     
    209209        $translations = \wp_get_available_translations();
    210210        $locale       = \get_locale();
    211         if ( ! in_array( $locale, $languages, true ) ) {
     211        if ( ! \in_array( $locale, $languages, true ) ) {
    212212            $locale = '';
    213213        }
    214214
    215         wp_dropdown_languages(
     215        \wp_dropdown_languages(
    216216            [
    217217                'name'                        => 'language',
     
    220220                'languages'                   => $languages,
    221221                'translations'                => $translations,
    222                 'show_available_translations' => current_user_can( 'install_languages' ) && wp_can_install_language_pack(),
     222                'show_available_translations' => \current_user_can( 'install_languages' ) && \wp_can_install_language_pack(),
    223223            ]
    224224        );
     
    271271
    272272        // Handle translation installation.
    273         if ( current_user_can( 'install_languages' ) ) {
     273        if ( \current_user_can( 'install_languages' ) ) {
    274274            require_once ABSPATH . 'wp-admin/includes/translation-install.php'; // @phpstan-ignore requireOnce.fileNotFound
    275275
    276             if ( wp_can_install_language_pack() ) {
    277                 $language = wp_download_language_pack( $language_for_update );
     276            if ( \wp_can_install_language_pack() ) {
     277                $language = \wp_download_language_pack( $language_for_update );
    278278                if ( $language ) {
    279279                    $language_for_update = $language;
  • progress-planner/trunk/classes/suggested-tasks/providers/class-select-timezone.php

    r3343364 r3356010  
    120120
    121121        // Remove old Etc mappings. Fallback to gmt_offset.
    122         if ( str_contains( $tzstring, 'Etc/GMT' ) ) {
     122        if ( \str_contains( $tzstring, 'Etc/GMT' ) ) {
    123123            $tzstring = '';
    124124        }
     
    187187
    188188        // Map UTC+- timezones to gmt_offsets and set timezone_string to empty.
    189         if ( preg_match( '/^UTC[+-]/', $timezone_string ) ) {
     189        if ( \preg_match( '/^UTC[+-]/', $timezone_string ) ) {
    190190            // Set the gmt_offset to the value of the timezone_string, strip the UTC prefix.
    191             $gmt_offset = preg_replace( '/UTC\+?/', '', $timezone_string );
     191            $gmt_offset = \preg_replace( '/UTC\+?/', '', $timezone_string );
    192192
    193193            // Reset the timezone_string to empty.
     
    195195
    196196            $update_options = true;
    197         } elseif ( in_array( $timezone_string, \timezone_identifiers_list( \DateTimeZone::ALL_WITH_BC ), true ) ) {
     197        } elseif ( \in_array( $timezone_string, \timezone_identifiers_list( \DateTimeZone::ALL_WITH_BC ), true ) ) {
    198198            // $timezone_string is already set, reset the value for $gmt_offset.
    199199            $gmt_offset = '';
  • progress-planner/trunk/classes/suggested-tasks/providers/class-settings-saved.php

    r3316864 r3356010  
    6767     */
    6868    public function should_add_task() {
    69         return false === \get_option( 'progress_planner_pro_license_key', false );
     69        return ! \progress_planner()->get_settings()->get( 'include_post_types' );
    7070    }
    7171}
  • progress-planner/trunk/classes/utils/class-debug-tools.php

    r3316864 r3356010  
    493493            ]
    494494        );
    495 
    496         $prpl_pro_license = \get_option( 'progress_planner_pro_license_key', false );
    497         $admin_bar->add_node(
    498             [
    499                 'id'     => 'prpl-pro-license',
    500                 'parent' => 'prpl-more-info',
    501                 'title'  => 'Pro License: ' . ( false !== $prpl_pro_license ? $prpl_pro_license : 'Not set' ),
    502             ]
    503         );
    504 
    505         $prpl_pro_license_status = \get_option( 'progress_planner_pro_license_status', false );
    506         $admin_bar->add_node(
    507             [
    508                 'id'     => 'prpl-pro-license-status',
    509                 'parent' => 'prpl-more-info',
    510                 'title'  => 'Pro License Status: ' . ( false !== $prpl_pro_license_status ? $prpl_pro_license_status : 'Not set' ),
    511             ]
    512         );
    513495    }
    514496
     
    592574        // Delete the option.
    593575        \delete_option( 'progress_planner_license_key' );
    594         \delete_option( 'progress_planner_pro_license_key' );
    595         \delete_option( 'progress_planner_pro_license_status' );
    596576
    597577        // Redirect to the same page without the parameter.
  • progress-planner/trunk/classes/wp-cli/class-task-command.php

    r3343364 r3356010  
    7777                        break;
    7878                    case 'provider_id':
    79                         $formatted[ $field ] = is_object( $task->provider ?? null ) && isset( $task->provider->name ) ? $task->provider->name : '';
     79                        $formatted[ $field ] = \is_object( $task->provider ?? null ) && isset( $task->provider->name ) ? $task->provider->name : '';
    8080                        break;
    8181                    case 'category':
    82                         $formatted[ $field ] = is_object( $task->category ?? null ) && isset( $task->category->name ) ? $task->category->name : '';
     82                        $formatted[ $field ] = \is_object( $task->category ?? null ) && isset( $task->category->name ) ? $task->category->name : '';
    8383                        break;
    8484                    default:
  • progress-planner/trunk/progress-planner.php

    r3347435 r3356010  
    1010 * Requires at least: 6.6
    1111 * Requires PHP:      7.4
    12  * Version:           1.7.1
     12 * Version:           1.7.2
    1313 * Author:            Team Emilia Projects
    1414 * Author URI:        https://prpl.fyi/about
  • progress-planner/trunk/readme.txt

    r3347435 r3356010  
    55Tested up to: 6.8
    66Requires PHP: 7.4
    7 Stable tag: 1.7.1
     7Stable tag: 1.7.2
    88License: GPL3+
    99License URI: https://www.gnu.org/licenses/gpl-3.0.en.html
     
    3636Your dashboard gives you a clear overview of your website’s progress. See your recommendations, to-do list and achievements at a glance — so you can jump right into the most important tasks.
    3737
    38 ### 🆘 Want expert guidance? Get Progress Planner Pro
    39 
    40 If you’re ready to take things further, [Progress Planner Pro](https://progressplanner.com/pro/) gives you access to in-depth guidance and structured challenges that walk you through key website improvements step by step.
    41 
    42 #### Get results with guided challenges
    43 Maintaining a website can feel overwhelming — but you don’t have to do it alone. With Progress Planner Pro, you get access to expert-led challenges that guide you through key website improvements step by step.
    44 
    45 Each challenge is interactive and tailored to help you make real progress. You can expect:
    46 
    47 * Live **webinars & workshops** with experts sharing insights and strategies
    48 * Actionable **reports & exercises** to apply what you’ve learned to your own site
    49 * Personal **feedback & support**, like having your copywriting reviewed
    50 * A **structured plan**, so you always know what to do next
    51 
    52 It’s not just advice — it’s a hands-on, practical experience that helps you take real action and see results.
    53 
    54 #### Learn with practical mini courses
    55 
    56 Want to sharpen your skills while improving your site? [Progress Planner Pro](https://progressplanner.com/pro/) includes mini courses that give you the knowledge you need — without the fluff.
    57 
    58 #### Get support when you need it
    59 Sometimes you just need a little extra help. With Pro, you get access to our support team, ready to answer your questions and guide you through website improvements.
    60 
    6138### 🧹 Ready to make website maintenance easier?
    6239Progress Planner takes the frustration out of keeping your website in top shape. Whether you’re tackling quick fixes or diving into bigger improvements, you’ll always know what to do next.
     
    7451
    7552Currently, Progress Planner supports tracking for one website per WordPress installation. We are exploring multi-site support for future updates.
    76 
    77 = Is there a Pro version of Progress Planner? =
    78 
    79 Yes! You can [find it right here](https://progressplanner.com/pro/).
    8053
    8154= Where do I file bugs? =
     
    11083
    11184== Changelog ==
     85
     86= 1.7.2 =
     87
     88* Backported some features from the Progress Planner Pro plugin.
    11289
    11390= 1.7.1 =
  • progress-planner/trunk/views/admin-page-header.php

    r3316864 r3356010  
    2020<div class="prpl-header">
    2121    <div class="prpl-header-logo">
    22         <?php
    23         if ( \progress_planner()->is_pro_site() ) {
    24             \progress_planner()->the_asset( 'images/logo_progress_planner_pro.svg' );
    25         } else {
    26             \progress_planner()->the_asset( 'images/logo_progress_planner.svg' );
    27         }
    28         ?>
     22        <?php \progress_planner()->the_asset( 'images/logo_progress_planner.svg' ); ?>
    2923    </div>
    3024
  • progress-planner/trunk/views/admin-page-settings.php

    r3316864 r3356010  
    1515    <div class="prpl-header">
    1616        <div class="prpl-header-logo">
    17             <?php
    18             if ( \progress_planner()->is_pro_site() ) {
    19                 \progress_planner()->the_asset( 'images/logo_progress_planner_pro.svg' );
    20             } else {
    21                 \progress_planner()->the_asset( 'images/logo_progress_planner.svg' );
    22             }
    23             ?>
     17            <?php \progress_planner()->the_asset( 'images/logo_progress_planner.svg' ); ?>
    2418        </div>
    2519    </div>
     
    3933            <?php \progress_planner()->the_view( 'page-settings/post-types.php' ); ?>
    4034            <?php \progress_planner()->the_view( 'page-settings/settings.php' ); ?>
    41             <?php \progress_planner()->the_view( 'page-settings/license.php' ); ?>
    4235        </div>
    4336
Note: See TracChangeset for help on using the changeset viewer.