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

Yoast / wordpress-seo / aaea12fe12c7195d02e0f7ea5fe67d379d3e3227

12 Sep 2025 10:36AM UTC coverage: 41.602%. First build
aaea12fe12c7195d02e0f7ea5fe67d379d3e3227

Pull #22551

github

web-flow
Merge 67ccafc8d into 166ff8a05
Pull Request #22551: Add delayed premium upsell

2370 of 9166 branches covered (25.86%)

Branch coverage included in aggregate %.

15 of 89 new or added lines in 10 files covered. (16.85%)

22173 of 49829 relevant lines covered (44.5%)

4.7 hits per line

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

81.97
/src/introductions/user-interface/introductions-integration.php
1
<?php
2

3
namespace Yoast\WP\SEO\Introductions\User_Interface;
4

5
use WPSEO_Admin_Asset_Manager;
6
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
7
use Yoast\WP\SEO\Conditionals\WooCommerce_Conditional;
8
use Yoast\WP\SEO\Helpers\Product_Helper;
9
use Yoast\WP\SEO\Helpers\Short_Link_Helper;
10
use Yoast\WP\SEO\Helpers\User_Helper;
11
use Yoast\WP\SEO\Integrations\Integration_Interface;
12
use Yoast\WP\SEO\Introductions\Application\Current_Page_Trait;
13
use Yoast\WP\SEO\Introductions\Application\Introductions_Collector;
14
use Yoast\WP\SEO\Introductions\Infrastructure\Introductions_Seen_Repository;
15
use Yoast\WP\SEO\Introductions\Infrastructure\Wistia_Embed_Permission_Repository;
16

17
/**
18
 * Loads introduction modal scripts, when there are applicable introductions.
19
 */
20
class Introductions_Integration implements Integration_Interface {
21

22
        use Current_Page_Trait;
23

24
        public const SCRIPT_HANDLE = 'introductions';
25

26
        /**
27
         * Holds the admin asset manager.
28
         *
29
         * @var WPSEO_Admin_Asset_Manager
30
         */
31
        private $admin_asset_manager;
32

33
        /**
34
         * Holds the introduction collector.
35
         *
36
         * @var Introductions_Collector
37
         */
38
        private $introductions_collector;
39

40
        /**
41
         * Holds the product helper.
42
         *
43
         * @var Product_Helper
44
         */
45
        private $product_helper;
46

47
        /**
48
         * Holds the user helper.
49
         *
50
         * @var User_Helper
51
         */
52
        private $user_helper;
53

54
        /**
55
         * Holds the short link helper.
56
         *
57
         * @var Short_Link_Helper
58
         */
59
        private $short_link_helper;
60

61
        /**
62
         * Holds the repository.
63
         *
64
         * @var Wistia_Embed_Permission_Repository
65
         */
66
        private $wistia_embed_permission_repository;
67

68
        /**
69
         * Holds the WooCommerce conditional.
70
         *
71
         * @var WooCommerce_Conditional
72
         */
73
        private $woocommerce_conditional;
74

75
        /**
76
         * Returns the conditionals based in which this loadable should be active.
77
         *
78
         * In this case: when on an admin page.
79
         *
80
         * @return array<string>
81
         */
82
        public static function get_conditionals() {
2✔
83
                return [ Admin_Conditional::class ];
2✔
84
        }
85

86
        /**
87
         * Constructs the integration.
88
         *
89
         * @param WPSEO_Admin_Asset_Manager          $admin_asset_manager                The admin asset manager.
90
         * @param Introductions_Collector            $introductions_collector            The introductions' collector.
91
         * @param Product_Helper                     $product_helper                     The product helper.
92
         * @param User_Helper                        $user_helper                        The user helper.
93
         * @param Short_Link_Helper                  $short_link_helper                  The short link helper.
94
         * @param Wistia_Embed_Permission_Repository $wistia_embed_permission_repository The repository.
95
         * @param WooCommerce_Conditional            $woocommerce_conditional            The WooCommerce conditional.
96
         */
97
        public function __construct(
2✔
98
                WPSEO_Admin_Asset_Manager $admin_asset_manager,
99
                Introductions_Collector $introductions_collector,
100
                Product_Helper $product_helper,
101
                User_Helper $user_helper,
102
                Short_Link_Helper $short_link_helper,
103
                Wistia_Embed_Permission_Repository $wistia_embed_permission_repository,
104
                WooCommerce_Conditional $woocommerce_conditional
105
        ) {
106
                $this->admin_asset_manager                = $admin_asset_manager;
2✔
107
                $this->introductions_collector            = $introductions_collector;
2✔
108
                $this->product_helper                     = $product_helper;
2✔
109
                $this->user_helper                        = $user_helper;
2✔
110
                $this->short_link_helper                  = $short_link_helper;
2✔
111
                $this->wistia_embed_permission_repository = $wistia_embed_permission_repository;
2✔
112
                $this->woocommerce_conditional            = $woocommerce_conditional;
2✔
113
        }
114

115
        /**
116
         * Registers the action to enqueue the needed script(s).
117
         *
118
         * @return void
119
         */
120
        public function register_hooks() {
4✔
121
                if ( $this->is_on_installation_page() ) {
4✔
122
                        return;
2✔
123
                }
124
                \add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
2✔
125
        }
126

127
        /**
128
         * Enqueue the new features assets.
129
         *
130
         * @return void
131
         */
132
        public function enqueue_assets() {
4✔
133
                $user_id = $this->user_helper->get_current_user_id();
4✔
134
                $this->update_metadata_for( $user_id );
4✔
135
                $introductions = $this->introductions_collector->get_for( $user_id );
4✔
136

137
                if ( ! $introductions ) {
4✔
138
                        // Bail when there are no introductions to show.
139
                        return;
2✔
140
                }
141
                // Update user meta to have "seen" these introductions.
142
                $this->update_user_introductions( $user_id, $introductions );
2✔
143

144
                $this->admin_asset_manager->enqueue_script( self::SCRIPT_HANDLE );
2✔
145
                $this->admin_asset_manager->localize_script(
2✔
146
                        self::SCRIPT_HANDLE,
2✔
147
                        'wpseoIntroductions',
2✔
148
                        [
2✔
149
                                'introductions'         => $introductions,
2✔
150
                                'isPremium'             => $this->product_helper->is_premium(),
2✔
151
                                'isRtl'                 => \is_rtl(),
2✔
152
                                'linkParams'            => $this->short_link_helper->get_query_params(),
2✔
153
                                'pluginUrl'             => \plugins_url( '', \WPSEO_FILE ),
2✔
154
                                'wistiaEmbedPermission' => $this->wistia_embed_permission_repository->get_value_for_user( $user_id ),
2✔
155
                                'isWooEnabled'          => $this->woocommerce_conditional->is_met(),
2✔
156
                        ]
2✔
157
                );
2✔
158
                $this->admin_asset_manager->enqueue_style( 'introductions' );
2✔
159
        }
160

161
        /**
162
         * Updates the user metadata to have "seen" the introductions.
163
         *
164
         * @param int   $user_id       The user ID.
165
         * @param array $introductions The introductions.
166
         *
167
         * @return void
168
         */
169
        private function update_user_introductions( $user_id, $introductions ) {
4✔
170
                $metadata = $this->user_helper->get_meta( $user_id, Introductions_Seen_Repository::USER_META_KEY, true );
4✔
171
                if ( ! \is_array( $metadata ) ) {
4✔
172
                        $metadata = [];
2✔
173
                }
174

175
                if ( empty( $introductions ) || ! \is_array( $introductions ) ) {
4✔
176
                        return;
×
177
                }
178

179
                // Find the introduction with the highest priority, because JS will only show that one.
180
                $highest_priority_intro = \array_reduce(
4✔
181
                        $introductions,
4✔
182
                        static function ( $carry, $item ) {
4✔
183
                                return ( $carry === null || $item['priority'] < $carry['priority'] ) ? $item : $carry;
4✔
184
                        },
4✔
185
                        null
4✔
186
                );
4✔
187

188
                if ( $highest_priority_intro === null ) {
×
189
                        return;
190
                }
191

192
                // Mark the introduction with the highest priority as seen.
193
                $metadata[ $highest_priority_intro['id'] ]['is_seen'] = true;
4✔
194
                $metadata[ $highest_priority_intro['id'] ]['seen_on'] = \time();
195

196
                $this->user_helper->update_meta( $user_id, Introductions_Seen_Repository::USER_META_KEY, $metadata );
4✔
197
        }
198

199
        /**
200
         * Updates the introductions metadata format for the user
201
         * This is needed because we're introducing timestamps for introductions that have been seen, thus changing the format.
202
         *
203
         * @param int $user_id The user ID.
204
         *
205
         * @return void
206
         */
NEW
207
        private function update_metadata_for( int $user_id ) {
×
NEW
208
                $metadata = $this->introductions_collector->get_metadata( $user_id );
×
NEW
209
                foreach ( $metadata as $introduction_name => $introduction_data ) {
×
NEW
210
                        if ( \is_bool( $introduction_data ) ) {
×
NEW
211
                                $metadata[ $introduction_name ] = [
×
NEW
212
                                        'is_seen' => $introduction_data,
×
NEW
213
                                        'seen_on' => ( $introduction_data === true ) ? \time() : 0,
×
NEW
214
                                ];
×
215
                        }
216
                }
NEW
217
                $this->user_helper->update_meta( $user_id, Introductions_Seen_Repository::USER_META_KEY, $metadata );
×
218
        }
219
}
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