PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / trunk
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar vtrunk
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 1.2.1 All 156 releases
← All changes | includes/NotificationX.php +394 -0 0.2.5.6trunk View file →
@@ -1,0 +1,394 @@
1 +<?php
2 +
3 +/**
4 + * NotificationX File
5 + *
6 + * @package NotificationX
7 + */
8 +
9 +namespace NotificationX;
10 +
11 +use NotificationX\Admin\Admin;
12 +use NotificationX\Admin\Cron;
13 +use NotificationX\Admin\EntriesMailReceiver;
14 +use NotificationX\Admin\Settings;
15 +use NotificationX\Blocks\Blocks;
16 +use NotificationX\Core\Database;
17 +use NotificationX\Core\PostType;
18 +use NotificationX\Core\QuickBuild;
19 +use NotificationX\Core\REST;
20 +use NotificationX\Core\ShortcodeInline;
21 +use NotificationX\Core\Targeting;
22 +use NotificationX\Core\Upgrader;
23 +use NotificationX\Extensions\GlobalFields;
24 +use NotificationX\FrontEnd\FrontEnd;
25 +use NotificationX\Types\TypeFactory;
26 +use NotificationX\Extensions\ExtensionFactory;
27 +use NotificationX\ThirdParty\WPML;
28 +use NotificationX\Core\WPDRoleManagement;
29 +use NotificationX\ThirdParty\VisualPortfolio;
30 +use NotificationX\Extensions\Elementor\ElementorManager;
31 +
32 +/**
33 + * Plugin Engine.
34 + * @method static NotificationX get_instance($args = null)
35 + */
36 +class NotificationX {
37 + /**
38 + * Instance of NotificationX
39 + * @var NotificationX
40 + */
41 + use GetInstance;
42 + /**
43 + * Option flag recording that NotificationX has already gone through its
44 + * initial (first-ever) activation on this site.
45 + *
46 + * Set on the first activation and seeded for pre-existing installs by
47 + * Upgrader, so a re-activation is never mistaken for a first run.
48 + *
49 + * @since 3.3.0
50 + */
51 + const FIRST_ACTIVATION_OPTION = 'nx_first_activation';
52 + /**
53 + * Settings
54 + * @var Settings
55 + */
56 + public $settings;
57 + /**
58 + * WP_CLI
59 + * @var boolean
60 + */
61 + public static $WP_CLI = false;
62 + /**
63 + * Invoked initially.
64 + */
65 + public function __construct() {
66 + static::$WP_CLI = defined('WP_CLI') && WP_CLI;
67 + $this->settings = Settings::get_instance([
68 + 'key' => 'notificationx',
69 + 'auto_commit' => true,
70 + 'debug' => false,
71 + 'store' => 'options',
72 + ]);
73 +
74 + $args = Settings::get_instance()->get_role_map();
75 + new WPDRoleManagement($args);
76 +
77 + Upgrader::get_instance();
78 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
79 + if (is_admin() || empty($_GET['frontend']) || $_GET['frontend'] != true) {
80 + Admin::get_instance();
81 + }
82 + FrontEnd::get_instance();
83 + add_action('admin_init', [$this, 'maybe_redirect'], 10);
84 + add_action('init', [$this, 'init'], 10);
85 + add_action('plugins_loaded', array($this, 'init_extension'));
86 + add_filter('nx_pro_alert_popup', array($this, 'pro_alert_popup'));
87 + add_action( 'init', [ $this, 'register_custom_image_size' ] );
88 + /**
89 + * Register all REST Endpoint
90 + */
91 + REST::get_instance();
92 + // Country/user-role targeting for ALL notification types (decoupled from the bar module).
93 + Targeting::get_instance();
94 + Cron::get_instance();
95 + QuickBuild::get_instance();
96 + ShortcodeInline::get_instance();
97 + Blocks::get_instance();
98 +
99 + CoreInstaller::get_instance(basename(NOTIFICATIONX_FILE, '.php'));
100 +
101 + // 3rd Party features.
102 + WPML::get_instance();
103 + VisualPortfolio::get_instance();
104 + if ( did_action( 'elementor/loaded' ) ) {
105 + ElementorManager::get_instance();
106 + } else {
107 + add_action( 'elementor/loaded', [ ElementorManager::class, 'get_instance' ] );
108 + }
109 + EntriesMailReceiver::get_instance();
110 +
111 + // MCP server (AI-assistant integration). Progressive enhancement:
112 + // loads only on a capable PHP runtime and stays off until enabled.
113 + \NotificationX\MCP\Bootstrap::init();
114 + }
115 + /**
116 + * The Plugin Activator
117 + * @return void
118 + */
119 + public function activator(){
120 + // nx_activated
121 + Database::get_instance()->Create_DB();
122 +
123 + // A first-ever activation is the only moment the onboarding wizard may
124 + // be auto-launched; an abandoned wizard still counts as "already
125 + // activated", so re-activations never force it again.
126 + $is_first_activation = ! self::has_activated_before();
127 + if ( $is_first_activation ) {
128 + update_option( self::FIRST_ACTIVATION_OPTION, time(), 'no' );
129 + }
130 +
131 + if( ! static::$WP_CLI && current_user_can( 'delete_users' ) ) {
132 + set_transient( 'nx_activated', $is_first_activation ? 'first' : 'again', 30 );
133 + }
134 +
135 + // Usage insights are normally wired up on `init`, which WordPress has
136 + // already fired by the time it activates a plugin — so the
137 + // register_activation_hook() callback registered inside the insights
138 + // constructor never runs and the tracking event is left unscheduled.
139 + // Build the instance and run its activation routine explicitly here so
140 + // data collection is live from activation onwards.
141 + Admin::get_instance()->plugin_usage_insights()->activate_this_plugin();
142 +
143 + Upgrader::get_instance()->clear_transient();
144 + }
145 +
146 + /**
147 + * Whether NotificationX has already gone through its initial activation on
148 + * this site — i.e. it has been activated before, regardless of whether the
149 + * Setup Wizard was ever opened or completed.
150 + *
151 + * @since 3.3.0
152 + * @return bool
153 + */
154 + public static function has_activated_before() {
155 + return (bool) get_option( self::FIRST_ACTIVATION_OPTION, false );
156 + }
157 +
158 + public function maybe_redirect(){
159 + if( static::$WP_CLI || wp_doing_ajax() ) {
160 + return;
161 + }
162 + // Bail if no activation transient is set.
163 + $activation = get_transient( 'nx_activated' );
164 + if ( ! $activation ) {
165 + return;
166 + }
167 + // Delete the activation transient.
168 + delete_transient( 'nx_activated' );
169 +
170 + if ( ! is_multisite() ) {
171 + // Only a genuine first-ever activation may launch the onboarding
172 + // Setup Wizard (and only while it has not been completed/skipped).
173 + // Every returning activation lands on the dashboard, as before.
174 + // Transients written by an older version hold `true`, which is
175 + // treated as a returning activation.
176 + $is_first_activation = ( 'first' === $activation );
177 + $page = ( $is_first_activation && ! \NotificationX\Core\SetupWizard::is_completed() ) ? 'nx-setup-wizard' : 'nx-dashboard';
178 + wp_safe_redirect( add_query_arg( array(
179 + 'page' => $page
180 + ), admin_url( 'admin.php' ) ) );
181 + }
182 + }
183 +
184 + public function init_extension() {
185 + // TypeFactory::get_instance();
186 + ExtensionFactory::get_instance();
187 + }
188 +
189 + public function init() {
190 + /**
191 + * Run All Actions and Filters
192 + * for GOOD.
193 + */
194 + // load_plugin_textdomain( 'notificationx', false, dirname( plugin_basename( NOTIFICATIONX_FILE ) ) . '/languages' );
195 +
196 + // @todo remove
197 + if(defined('NX_DEBUG') && NX_DEBUG){
198 + add_action('wp_ajax_nx', [$this, 'get_tabs']); // executed when logged in
199 + }
200 +
201 + add_action( 'plugin_action_links_' . NOTIFICATIONX_BASENAME, array($this, 'nx_action_links'), 10, 1);
202 + }
203 +
204 + public function pro_alert_popup($args) {
205 + if ( !empty($args)){
206 + $args = wp_parse_args($args, [
207 + "showConfirmButton"=> true,
208 + "showCloseButton"=>true,
209 + "title" => __('Opps! This is PRO Feature.', 'notificationx'),
210 + "customClass"=> [
211 + "container"=> 'pro-video-popup',
212 + "closeButton"=> 'pro-video-close-button',
213 + "icon"=> 'pro-video-icon',
214 + "title"=> 'pro-video-title',
215 + "content"=> 'pro-video-content',
216 + "actions"=> 'nx-pro-alert-actions',
217 + "confirmButton"=> 'pro-video-confirm-button',
218 + "denyButton"=> 'pro-video-deny-button',
219 + ],
220 + ]);
221 + }
222 + return $args;
223 + }
224 +
225 + /**
226 + * This function is hooked
227 + * @hooked plugin_action_links_
228 + * @param array $links
229 + * @return array
230 + * @since 1.2.4
231 + */
232 + public function nx_action_links( $links ) {
233 + $deactivate_link = isset( $links['deactivate'] ) ? $links['deactivate'] : '';
234 + unset($links['deactivate']);
235 + $links['settings'] = '<a href="' . admin_url('admin.php?page=nx-settings') . '">' . __('Settings','notificationx') .'</a>';
236 + if( ! empty( $deactivate_link ) ) {
237 + $links['deactivate'] = $deactivate_link;
238 + }
239 + if( ! is_plugin_active('notificationx-pro/notificationx-pro.php' ) ) {
240 + $links['pro'] = '<a href="' . esc_url('https://notificationx.com/#pricing') . '" target="_blank" style="color: #349e34;"><b>' . __('Go Pro','notificationx') .'</b></a>';
241 + }
242 + return $links;
243 + }
244 +
245 + /**
246 + * Checks whether pro plugin is active.
247 + *
248 + * @return boolean
249 + */
250 + public static function is_pro() {
251 + return class_exists('\NotificationXPro\NotificationX');
252 + }
253 + /**
254 + * Get Tabs array in json.
255 + *
256 + * @return json
257 + */
258 + public function get_tabs() {
259 + $tabs = GlobalFields::get_instance()->tabs();
260 + // $tabs = Settings::get_instance()->get_form_data();
261 + $fields = $this->get_field_names($tabs['tabs']);
262 + wp_send_json($tabs);
263 + }
264 + /**
265 + * Convert `fields` associative array to numeric array recursively.
266 + * @todo improve implementation.
267 + *
268 + * @param array $arr
269 + * @return array
270 + */
271 + public function normalize($arr) {
272 +
273 + if (!empty($arr['fields'])) {
274 + $arr['fields'] = array_values($arr['fields']);
275 + }
276 +
277 + if (!empty($arr['options'])) {
278 + $arr['options'] = array_values($arr['options']);
279 + }
280 +
281 + if (!empty($arr['tabs'])) {
282 + $arr['tabs'] = array_values($arr['tabs']);
283 + }
284 +
285 + if (is_array($arr)) {
286 + foreach ($arr as $key => $value) {
287 + if (is_array($value)) {
288 + $arr[$key] = $this->normalize($value);
289 + }
290 + }
291 + }
292 + return $arr;
293 + }
294 +
295 + public function normalize_post($settings) {
296 + $fields = $this->get_field_names();
297 + foreach ($fields as $key => $value) {
298 + if (!isset($settings[$key]) && isset($value['default'])) {
299 + $settings[$key] = $value['default'];
300 + }
301 + if (isset( $value['type'] ) && ($value['type'] == 'checkbox' || $value['type'] == 'toggle')) {
302 + $settings[$key] = (bool) (isset($settings[$key]) ? $settings[$key] : false);
303 + }
304 + if (isset( $value['type'] ) && $value['type'] == 'number') {
305 + $settings[$key] = isset($settings[$key]) ? $settings[$key] : 0;
306 + $settings[$key] = is_numeric($settings[$key]) ? $settings[$key] + 0 : 0;
307 + }
308 + }
309 + return $settings;
310 + }
311 +
312 + public function get_tab(){
313 + $tabs = get_transient('nx_builder_fields');
314 + if(empty($tabs) || (defined('NX_DEBUG') && NX_DEBUG)){
315 + $tabs = GlobalFields::get_instance()->tabs();
316 + set_transient( 'nx_builder_fields', $tabs, DAY_IN_SECONDS );
317 + }
318 + return $tabs;
319 + }
320 +
321 + public function get_field_names($tabs = null){
322 + $fields = [];
323 + if(empty($tabs)){
324 + $tabs = $this->get_tab();
325 + }
326 + if(!empty($tabs['tabs'])){
327 + $fields = $this->_get_field_names($tabs['tabs']);
328 + }
329 + return $fields;
330 + }
331 +
332 + public function get_field($field_name){
333 + $fields = $this->get_field_names();
334 + if(!empty($fields[$field_name])){
335 + return $fields[$field_name];
336 + }
337 + }
338 +
339 + // @todo maybe remove if not used in future.
340 + public function _get_field_names($fields, $names = []) {
341 + foreach ($fields as $key => $field) {
342 + if (empty($field['type'])) {
343 + $names = $this->_get_field_names($field['fields'], $names);
344 + } else if ($field['type'] == 'section' || $field['type'] == 'group') { //
345 + $_names = $this->_get_field_names($field['fields'], []);
346 + if ($field['type'] == 'section')
347 + $names = array_merge($names, $_names);
348 + else
349 + foreach ($_names as $key => $value) {
350 + $names[$field['name']][$key] = [
351 + 'type' => $value['type'],
352 + 'default' => isset($value['default']) ? $value['default'] : '',
353 + 'help' => isset($value['help']) ? $value['help'] : '',
354 + 'label' => isset($value['label']) ? $value['label'] : '',
355 + 'parent_label' => isset($field['label']) ? $field['label'] : '',
356 + ];
357 + }
358 + } elseif (!empty($field['name'])) {
359 + $names[$field['name']] = [
360 + 'type' => $field['type'],
361 + 'default' => isset($field['default']) ? $field['default'] : '',
362 + 'help' => isset($field['help']) ? $field['help'] : '',
363 + 'label' => isset($field['label']) ? $field['label'] : '',
364 + 'multiple' => isset($field['multiple']) ? $field['multiple'] : '',
365 + ];
366 + }
367 + }
368 +
369 + return $names;
370 + }
371 +
372 + function my_upgrade_function( $upgrader_object, $options ) {
373 + $current_plugin_path_name = plugin_basename( __FILE__ );
374 +
375 + if ($options['action'] == 'update' && $options['type'] == 'plugin' ) {
376 + foreach($options['plugins'] as $each_plugin) {
377 + if ($each_plugin==$current_plugin_path_name) {
378 + // .......................... YOUR CODES .............
379 +
380 + }
381 + }
382 + }
383 + }
384 +
385 +
386 + public function register_custom_image_size() {
387 + add_image_size('_nx_notification_thumb_100_100', 100, 100, true);
388 + add_image_size('_nx_notification_thumb_200_200', 200, 200, true);
389 + add_image_size('_nx_notification_thumb_300_300', 300, 300, true);
390 + add_image_size('_nx_notification_thumb_400_400', 400, 400, true);
391 + add_image_size('_nx_notification_thumb_500_500', 500, 500, true);
392 + }
393 +
394 +}