• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 5798061939

pending completion
5798061939

push

github

FAMarfuaty
Merge branch 'trunk' of github.com:Yoast/wordpress-seo into feature/html-parser

135 of 154 new or added lines in 24 files covered. (87.66%)

12419 of 26427 relevant lines covered (46.99%)

3.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/integrations/admin/workouts-integration.php
1
<?php
2

3
namespace Yoast\WP\SEO\Integrations\Admin;
4

5
use WPSEO_Addon_Manager;
6
use WPSEO_Admin_Asset_Manager;
7
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
8
use Yoast\WP\SEO\Helpers\Options_Helper;
9
use Yoast\WP\SEO\Helpers\Product_Helper;
10
use Yoast\WP\SEO\Integrations\Integration_Interface;
11
use Yoast\WP\SEO\Presenters\Admin\Notice_Presenter;
12

13
/**
14
 * WorkoutsIntegration class
15
 */
16
class Workouts_Integration implements Integration_Interface {
17

18
        /**
19
         * The admin asset manager.
20
         *
21
         * @var WPSEO_Admin_Asset_Manager
22
         */
23
        private $admin_asset_manager;
24

25
        /**
26
         * The addon manager.
27
         *
28
         * @var WPSEO_Addon_Manager
29
         */
30
        private $addon_manager;
31

32
        /**
33
         * The options helper.
34
         *
35
         * @var Options_Helper
36
         */
37
        private $options_helper;
38

39
        /**
40
         * The product helper.
41
         *
42
         * @var Product_Helper
43
         */
44
        private $product_helper;
45

46
        /**
47
         * {@inheritDoc}
48
         */
49
        public static function get_conditionals() {
50
                return [ Admin_Conditional::class ];
×
51
        }
52

53
        /**
54
         * Workouts_Integration constructor.
55
         *
56
         * @param WPSEO_Addon_Manager       $addon_manager       The addon manager.
57
         * @param WPSEO_Admin_Asset_Manager $admin_asset_manager The admin asset manager.
58
         * @param Options_Helper            $options_helper      The options helper.
59
         * @param Product_Helper            $product_helper      The product helper.
60
         */
61
        public function __construct(
62
                WPSEO_Addon_Manager $addon_manager,
63
                WPSEO_Admin_Asset_Manager $admin_asset_manager,
64
                Options_Helper $options_helper,
65
                Product_Helper $product_helper
66
        ) {
67
                $this->addon_manager       = $addon_manager;
×
68
                $this->admin_asset_manager = $admin_asset_manager;
×
69
                $this->options_helper      = $options_helper;
×
70
                $this->product_helper      = $product_helper;
×
71
        }
72

73
        /**
74
         * {@inheritDoc}
75
         */
76
        public function register_hooks() {
77
                \add_filter( 'wpseo_submenu_pages', [ $this, 'add_submenu_page' ], 8 );
×
78
                \add_filter( 'wpseo_submenu_pages', [ $this, 'remove_old_submenu_page' ], 10 );
×
79
                \add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ], 11 );
×
80
        }
81

82
        /**
83
         * Adds the workouts submenu page.
84
         *
85
         * @param array $submenu_pages The Yoast SEO submenu pages.
86
         *
87
         * @return array The filtered submenu pages.
88
         */
89
        public function add_submenu_page( $submenu_pages ) {
90
                $submenu_pages[] = [
×
91
                        'wpseo_dashboard',
×
92
                        '',
×
93
                        \__( 'Workouts', 'wordpress-seo' ) . ' <span class="yoast-badge yoast-premium-badge"></span>',
×
94
                        'edit_others_posts',
×
95
                        'wpseo_workouts',
×
96
                        [ $this, 'render_target' ],
×
97
                ];
98

99
                return $submenu_pages;
×
100
        }
101

102
        /**
103
         * Removes the workouts submenu page from older Premium versions
104
         *
105
         * @param array $submenu_pages The Yoast SEO submenu pages.
106
         *
107
         * @return array The filtered submenu pages.
108
         */
109
        public function remove_old_submenu_page( $submenu_pages ) {
110
                if ( ! $this->should_update_premium() ) {
×
111
                        return $submenu_pages;
×
112
                }
113

114
                // Copy only the Workouts page item that comes first in the array.
115
                $result_submenu_pages      = [];
×
116
                $workouts_page_encountered = false;
×
117
                foreach ( $submenu_pages as $item ) {
×
118
                        if ( $item[4] !== 'wpseo_workouts' || ! $workouts_page_encountered ) {
×
119
                                $result_submenu_pages[] = $item;
×
120
                        }
121
                        if ( $item[4] === 'wpseo_workouts' ) {
×
122
                                $workouts_page_encountered = true;
×
123
                        }
124
                }
125

126
                return $result_submenu_pages;
×
127
        }
128

129
        /**
130
         * Enqueue the workouts app.
131
         */
132
        public function enqueue_assets() {
133
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Date is not processed or saved.
134
                if ( ! isset( $_GET['page'] ) || $_GET['page'] !== 'wpseo_workouts' ) {
×
135
                        return;
×
136
                }
137

138
                if ( $this->should_update_premium() ) {
×
139
                        \wp_dequeue_script( 'yoast-seo-premium-workouts' );
×
140
                }
141

142
                $this->admin_asset_manager->enqueue_style( 'workouts' );
×
143

144
                $workouts_option = $this->get_workouts_option();
×
145

146
                $this->admin_asset_manager->enqueue_script( 'workouts' );
×
147
                $this->admin_asset_manager->localize_script(
×
148
                        'workouts',
×
149
                        'wpseoWorkoutsData',
×
150
                        [
151
                                'workouts'                  => $workouts_option,
×
152
                                'homeUrl'                   => \home_url(),
×
153
                                'pluginUrl'                 => \esc_url( \plugins_url( '', \WPSEO_FILE ) ),
×
154
                                'toolsPageUrl'              => \esc_url( \admin_url( 'admin.php?page=wpseo_tools' ) ),
×
155
                                'usersPageUrl'              => \esc_url( \admin_url( 'users.php' ) ),
×
156
                                'firstTimeConfigurationUrl' => \esc_url( \admin_url( 'admin.php?page=wpseo_dashboard#top#first-time-configuration' ) ),
×
157
                                'isPremium'                 => $this->product_helper->is_premium(),
×
158
                                'shouldUpdatePremium'       => $this->should_update_premium(),
×
159
                                'upsellText'                => $this->get_upsell_text(),
×
160
                                'upsellLink'                => $this->get_upsell_link(),
×
161
                        ]
162
                );
163
        }
164

165
        /**
166
         * Renders the target for the React to mount to.
167
         */
168
        public function render_target() {
169
                if ( $this->should_update_premium() ) {
×
170
                        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in get_update_premium_notice.
171
                        echo $this->get_update_premium_notice();
×
172
                }
173

174
                echo '<div id="wpseo-workouts-container-free" class="yoast"></div>';
×
175
        }
176

177
        /**
178
         * Gets the workouts option.
179
         *
180
         * @return mixed|null Returns workouts option if found, null if not.
181
         */
182
        private function get_workouts_option() {
183
                $workouts_option = $this->options_helper->get( 'workouts_data' );
×
184

185
                // This filter is documented in src/routes/workouts-route.php.
186
                return \apply_filters( 'Yoast\WP\SEO\workouts_options', $workouts_option );
×
187
        }
188

189
        /**
190
         * Returns the notification to show when Premium needs to be updated.
191
         *
192
         * @return string The notification to update Premium.
193
         */
194
        private function get_update_premium_notice() {
195
                $url = $this->get_upsell_link();
×
196

197
                if ( $this->has_premium_subscription_expired() ) {
×
198
                        /* translators: %s: expands to 'Yoast SEO Premium'. */
199
                        $title = \sprintf( \__( 'Renew your subscription of %s', 'wordpress-seo' ), 'Yoast SEO Premium' );
×
200
                        $copy  = \sprintf(
×
201
                                /* translators: %s: expands to 'Yoast SEO Premium'. */
202
                                \esc_html__(
×
203
                                        'Accessing the latest workouts requires an updated version of %s (at least 17.7), but it looks like your subscription has expired. Please renew your subscription to update and gain access to all the latest features.',
×
204
                                        'wordpress-seo'
×
205
                                ),
206
                                'Yoast SEO Premium'
×
207
                        );
208
                        $button = '<a class="yoast-button yoast-button-upsell yoast-button--small" href="' . \esc_url( $url ) . '" target="_blank">'
×
209
                                        . \esc_html__( 'Renew your subscription', 'wordpress-seo' )
×
210
                                        . '<span class="screen-reader-text">' . \__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '</span>'
×
211
                                        . '<span aria-hidden="true" class="yoast-button-upsell__caret"></span>'
×
212
                                        . '</a>';
×
213
                }
214
                elseif ( $this->has_premium_subscription_activated() ) {
×
215
                        /* translators: %s: expands to 'Yoast SEO Premium'. */
216
                        $title = \sprintf( \__( 'Update to the latest version of %s', 'wordpress-seo' ), 'Yoast SEO Premium' );
×
217
                        $copy  = \sprintf(
×
218
                                /* translators: 1: expands to 'Yoast SEO Premium', 2: Link start tag to the page to update Premium, 3: Link closing tag. */
219
                                \esc_html__( 'It looks like you\'re running an outdated version of %1$s, please %2$supdate to the latest version (at least 17.7)%3$s to gain access to our updated workouts section.', 'wordpress-seo' ),
×
220
                                'Yoast SEO Premium',
×
221
                                '<a href="' . \esc_url( $url ) . '">',
×
222
                                '</a>'
×
223
                        );
224
                        $button = null;
×
225
                }
226
                else {
227
                        /* translators: %s: expands to 'Yoast SEO Premium'. */
228
                        $title      = \sprintf( \__( 'Activate your subscription of %s', 'wordpress-seo' ), 'Yoast SEO Premium' );
×
229
                        $url_button = 'https://yoa.st/workouts-activate-notice-help';
×
230
                        $copy       = \sprintf(
×
231
                                /* translators: 1: expands to 'Yoast SEO Premium', 2: Link start tag to the page to update Premium, 3: Link closing tag. */
232
                                \esc_html__( 'It looks like you’re running an outdated and unactivated version of %1$s, please activate your subscription in %2$sMyYoast%3$s and update to the latest version (at least 17.7) to gain access to our updated workouts section.', 'wordpress-seo' ),
×
233
                                'Yoast SEO Premium',
×
234
                                '<a href="' . \esc_url( $url ) . '">',
×
235
                                '</a>'
×
236
                        );
237
                        $button = '<a class="yoast-button yoast-button--primary yoast-button--small" href="' . \esc_url( $url_button ) . '" target="_blank">'
×
238
                                        . \esc_html__( 'Get help activating your subscription', 'wordpress-seo' )
×
239
                                        . '<span class="screen-reader-text">' . \__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '</span>'
×
240
                                        . '</a>';
×
241
                }
242

243
                $notice = new Notice_Presenter(
×
244
                        $title,
×
245
                        $copy,
×
NEW
246
                        null,
×
247
                        $button
×
248
                );
249

250
                return $notice->present();
×
251
        }
252

253
        /**
254
         * Check whether Premium should be updated.
255
         *
256
         * @return bool Returns true when Premium is enabled and the version is below 17.7.
257
         */
258
        private function should_update_premium() {
259
                $premium_version = $this->product_helper->get_premium_version();
×
260
                return $premium_version !== null && \version_compare( $premium_version, '17.7-RC1', '<' );
×
261
        }
262

263
        /**
264
         * Check whether the Premium subscription has expired.
265
         *
266
         * @return bool Returns true when Premium subscription has expired.
267
         */
268
        private function has_premium_subscription_expired() {
269
                $subscription = $this->addon_manager->get_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG );
×
270

271
                return ( isset( $subscription->expiry_date ) && ( \strtotime( $subscription->expiry_date ) - \time() ) < 0 );
×
272
        }
273

274
        /**
275
         * Check whether the Premium subscription is activated.
276
         *
277
         * @return bool Returns true when Premium subscription is activated.
278
         */
279
        private function has_premium_subscription_activated() {
280
                return $this->addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG );
×
281
        }
282

283
        /**
284
         * Returns the upsell/update copy to show in the card buttons.
285
         *
286
         * @return string Returns a string with the upsell/update copy for the card buttons.
287
         */
288
        private function get_upsell_text() {
289
                if ( ! $this->product_helper->is_premium() || ! $this->should_update_premium() ) {
×
290
                        // Use the default defined in the component.
291
                        return '';
×
292
                }
293
                if ( $this->has_premium_subscription_expired() ) {
×
294
                        return \sprintf(
×
295
                                /* translators: %s: expands to 'Yoast SEO Premium'. */
296
                                \__( 'Renew %s', 'wordpress-seo' ),
×
297
                                'Yoast SEO Premium'
×
298
                        );
299
                }
300
                if ( $this->has_premium_subscription_activated() ) {
×
301
                        return \sprintf(
×
302
                                /* translators: %s: expands to 'Yoast SEO Premium'. */
303
                                \__( 'Update %s', 'wordpress-seo' ),
×
304
                                'Yoast SEO Premium'
×
305
                        );
306
                }
307
                return \sprintf(
×
308
                        /* translators: %s: expands to 'Yoast SEO Premium'. */
309
                        \__( 'Activate %s', 'wordpress-seo' ),
×
310
                        'Yoast SEO Premium'
×
311
                );
312
        }
313

314
        /**
315
         * Returns the upsell/update link to show in the card buttons.
316
         *
317
         * @return string Returns a string with the upsell/update link for the card buttons.
318
         */
319
        private function get_upsell_link() {
320
                if ( ! $this->product_helper->is_premium() || ! $this->should_update_premium() ) {
×
321
                        // Use the default defined in the component.
322
                        return '';
×
323
                }
324
                if ( $this->has_premium_subscription_expired() ) {
×
325
                        return 'https://yoa.st/workout-renew-notice';
×
326
                }
327
                if ( $this->has_premium_subscription_activated() ) {
×
328
                        return \wp_nonce_url( \self_admin_url( 'update.php?action=upgrade-plugin&plugin=wordpress-seo-premium/wp-seo-premium.php' ), 'upgrade-plugin_wordpress-seo-premium/wp-seo-premium.php' );
×
329
                }
330
                return 'https://yoa.st/workouts-activate-notice-myyoast';
×
331
        }
332
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc