| @@ -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 | +} | |