PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.3.2
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.3.2
3.3.2 3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 All 157 releases
← All changes | includes/Extensions/WooCommerce/WooInline.php +105 -11 3.2.133.3.2 View file →
@@ -6,8 +6,10 @@
6 6 */
7 7
8 8 namespace NotificationX\Extensions\WooCommerce;
9 9
10 +use NotificationX\Admin\Settings;
11 +use NotificationX\Core\Modules;
10 12 use NotificationX\Core\PostType;
11 13 use NotificationX\Core\Rules;
12 14 use NotificationX\GetInstance;
13 15 use NotificationX\Extensions\Extension;
@@ -119,8 +121,35 @@
119 121 'custom_fifth_param' => __( 'on our site!', 'notificationx' ),
120 122 ],
121 123 ),
122 124 ];
125 + // Google Analytics live-viewer design. Only offered when the Google
126 + // Analytics module is switched on — the number comes from a connected
127 + // GA4 property, so without it the design could never render anything.
128 + if ( Modules::get_instance()->is_enabled( 'modules_google_analytics' ) ) {
129 + $this->themes['live-viewers'] = array(
130 + 'is_pro' => true,
131 + 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/pro/ga-live-viewers.jpg',
132 + 'image_shape' => 'rounded',
133 + 'inline_location' => [ 'woocommerce_before_add_to_cart_form' ],
134 + 'template' => [
135 + 'first_param' => 'tag_live_viewers',
136 + 'second_param' => __( 'people are viewing', 'notificationx' ),
137 + 'third_param' => 'tag_product_title',
138 + 'custom_third_param' => ' ',
139 + // A real tag rather than `tag_custom`: `custom_fourth_param`
140 + // is one text field shared by every design, so seeding it is
141 + // not reliable — switching in from the sales-count design can
142 + // leave its "in last {{day:7}}" text behind. The tag renders
143 + // from `fallback_data()` and cannot go stale; merchants who
144 + // want their own wording pick "Custom" in the select, which
145 + // seeds from `custom_fourth_param` below.
146 + 'fourth_param' => 'tag_right_now',
147 + 'custom_fourth_param' => __( 'right now', 'notificationx' ),
148 + ],
149 + );
150 + }
151 +
123 152 $this->templates = [
124 153 'woo_template_sales_count' => [
125 154 'first_param' => [
126 155 'tag_sales_count' => __( 'Sales Count', 'notificationx' ),
@@ -154,25 +183,90 @@
154 183 "{$this->id}_stock-theme-two",
155 184 ],
156 185 ],
157 186 ];
187 +
188 + if ( Modules::get_instance()->is_enabled( 'modules_google_analytics' ) ) {
189 + $this->templates['woo_live_viewers_template'] = [
190 + 'first_param' => [
191 + 'tag_live_viewers' => __( 'Live Product Viewers', 'notificationx' ),
192 + ],
193 + 'third_param' => [
194 + 'tag_product_title' => __( 'Product Title', 'notificationx' ),
195 + ],
196 + 'fourth_param' => [
197 + 'tag_right_now' => __( 'right now', 'notificationx' ),
198 + ],
199 + '_themes' => [
200 + "{$this->id}_live-viewers",
201 + ],
202 + ];
203 + }
158 204 }
159 205
160 206 /**
161 - * @todo Something
207 + * The live-viewer design needs a connected GA4 property on top of
208 + * WooCommerce, so it gets its own message keyed separately from the
209 + * parent's "install WooCommerce" one and scoped to that theme.
162 210 *
163 - * @param [type] $exclude
164 - * @param [type] $settings
165 - * @return void
211 + * @param array $messages
212 + * @return array
166 213 */
214 + public function source_error_message( $messages ) {
215 + $messages = parent::source_error_message( $messages );
216 +
217 + $url = admin_url( 'admin.php?page=nx-settings&tab=tab-api-integrations#google_analytics_settings_section' );
218 + $pa_settings = Settings::get_instance()->get( 'settings.nx_pa_settings' );
219 + $profile = Settings::get_instance()->get( 'settings.ga_profile' );
220 + $message = '';
221 +
222 + if ( empty( $pa_settings ) ) {
223 + /* translators: %1$s: leading sentence, %2$s: settings URL, %3$s: link text, %4$s: trailing word. */
224 + $message = sprintf( '%1$s <a href="%2$s" target="_blank">%3$s</a> %4$s.',
225 + __( 'This design needs live traffic data. Connect your', 'notificationx' ),
226 + $url,
227 + __( 'Google Analytics Account', 'notificationx' ),
228 + __( 'first', 'notificationx' )
229 + );
230 + } elseif ( empty( $profile ) || strpos( $profile, 'properties/' ) !== 0 ) {
231 + // Realtime per-page data only exists on GA4 properties; legacy
232 + // Universal Analytics views cannot serve this design.
233 + /* translators: %1$s: leading sentence, %2$s: settings URL, %3$s: link text. */
234 + $message = sprintf( '%1$s <a href="%2$s" target="_blank">%3$s</a>.',
235 + __( 'This design needs a Google Analytics 4 property. Select one in', 'notificationx' ),
236 + $url,
237 + __( 'API Integrations', 'notificationx' )
238 + );
239 + }
240 +
241 + if ( $message ) {
242 + $messages[ "{$this->id}_ga" ] = [
243 + 'message' => $message,
244 + 'html' => true,
245 + 'type' => 'error',
246 + 'rules' => Rules::includes( 'themes', [ "{$this->id}_live-viewers" ] ),
247 + ];
248 + }
249 +
250 + return $messages;
251 + }
252 +
253 + /**
254 + * Keep this source's notifications out of the popup loop in
255 + * FrontEnd::get_notifications_ids(). They render inline at the hooks
256 + * chosen in `inline_location`, never as a floating popup.
257 + *
258 + * `inline_location` is not read here on purpose: it can be saved as ''
259 + * (MCP or Quick Builder create without the field), and passing that to
260 + * array_diff() is a TypeError on PHP 8 that white-screens every page.
261 + *
262 + * @param bool $exclude Whether an earlier callback already excluded it.
263 + * @param array $settings Notification settings.
264 + * @return bool
265 + */
167 266 public function show_on_exclude( $exclude, $settings ) {
168 - if ( $settings['source'] === $this->id ) {
169 - $woo_location = $settings['inline_location'];
170 - $hooks = ['woocommerce_before_add_to_cart_form', 'woocommerce_after_shop_loop_item_title', 'woocommerce_after_shop_loop_item', 'woocommerce_after_cart_item_name'];
171 - $diff = array_diff( $hooks, $woo_location );
172 - if ( count( $diff ) <= count( $hooks ) ) {
173 - return true;
174 - }
267 + if ( isset( $settings['source'] ) && $this->id === $settings['source'] ) {
268 + return true;
175 269 }
176 270 return $exclude;
177 271 }
178 272