| @@ -1,0 +1,1009 @@ | ||
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * Extension Factory | |
| 5 | + * | |
| 6 | + * @package NotificationX\Extensions | |
| 7 | + */ | |
| 8 | + | |
| 9 | +namespace NotificationX\Admin; | |
| 10 | + | |
| 11 | +use NotificationX\Core\Database; | |
| 12 | +use NotificationX\Core\Modules; | |
| 13 | +use NotificationX\Core\REST; | |
| 14 | +use NotificationX\Core\Rules; | |
| 15 | +use NotificationX\Core\Upgrader; | |
| 16 | +use NotificationX\Extensions\GlobalFields; | |
| 17 | +use NotificationX\GetInstance; | |
| 18 | +use NotificationX\NotificationX; | |
| 19 | +use UsabilityDynamics\Settings as UsabilityDynamicsSettings; | |
| 20 | +use NotificationX\Core\Helper; | |
| 21 | + | |
| 22 | +/** | |
| 23 | + * Settings Class | |
| 24 | + * @method static Settings get_instance($args = null) | |
| 25 | + */ | |
| 26 | +class Settings extends UsabilityDynamicsSettings { | |
| 27 | + /** | |
| 28 | + * Instance of Settings | |
| 29 | + * | |
| 30 | + * @var Settings | |
| 31 | + */ | |
| 32 | + use GetInstance; | |
| 33 | + | |
| 34 | + protected $wpdb; | |
| 35 | + protected $defaults = []; | |
| 36 | + | |
| 37 | + /** | |
| 38 | + * Initially Invoked when initialized. | |
| 39 | + * | |
| 40 | + * @hook init | |
| 41 | + */ | |
| 42 | + public function __construct( $args ) { | |
| 43 | + global $wpdb; | |
| 44 | + $this->wpdb = $wpdb; | |
| 45 | + parent::__construct( $args ); | |
| 46 | + add_action( 'init', [ $this, 'init' ] ); | |
| 47 | + // add_filter('user_has_cap', array($this, 'allow_admin'), 10, 4); | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * Called from Admin::init(); | |
| 52 | + * NotificationX | |
| 53 | + * | |
| 54 | + * @return void | |
| 55 | + */ | |
| 56 | + public function init() { | |
| 57 | + // add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']); | |
| 58 | + add_action( 'admin_menu', [ $this, 'menu' ], 25 ); | |
| 59 | + add_filter( 'nx_branding_url', array( $this, 'nx_branding_url' ), 12 ); | |
| 60 | + add_filter( 'nx_rest_miscellaneous', array( $this, 'miscellaneous' ), 10, 2 ); | |
| 61 | + } | |
| 62 | + | |
| 63 | + /** | |
| 64 | + * This method is responsible for Admin Menu of | |
| 65 | + * NotificationX | |
| 66 | + * | |
| 67 | + * @return void | |
| 68 | + */ | |
| 69 | + public function menu() { | |
| 70 | + add_submenu_page( 'nx-admin', 'Settings', 'Settings', 'edit_notificationx_settings', 'nx-settings', [ Admin::get_instance(), 'views' ], 3 ); | |
| 71 | + } | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Register scripts and styles. | |
| 75 | + * | |
| 76 | + * @param string $hook | |
| 77 | + * @return void | |
| 78 | + */ | |
| 79 | + function get_form_data() { | |
| 80 | + $data = NotificationX::get_instance()->normalize( $this->settings_form() ); | |
| 81 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 82 | + $settings = apply_filters('nx_settings_page_settings', $this->get( 'settings', [] )); | |
| 83 | + | |
| 84 | + /* | |
| 85 | + * `/builder` resolves `read_notificationx` -- the lowest capability the | |
| 86 | + * product defines -- and this blob is handed straight to it. The | |
| 87 | + * `settingsRedirect` flag below only tells the admin app not to render | |
| 88 | + * the settings screen; it is a client-side routing hint, not a boundary. | |
| 89 | + * Without this, a view-only delegate received every API key, client | |
| 90 | + * secret and OAuth token stored on the site. | |
| 91 | + */ | |
| 92 | + if ( ! current_user_can( 'edit_notificationx_settings' ) ) { | |
| 93 | + $settings = self::redact_secret_settings( $settings ); | |
| 94 | + } | |
| 95 | + | |
| 96 | + $data['current_page'] = 'settings'; | |
| 97 | + $data['rest'] = REST::get_instance()->rest_data(); | |
| 98 | + $data['savedValues'] = $settings; | |
| 99 | + $data['values'] = $settings; | |
| 100 | + $data['assets'] = [ | |
| 101 | + 'admin' => NOTIFICATIONX_ADMIN_URL, | |
| 102 | + 'public' => NOTIFICATIONX_PUBLIC_URL, | |
| 103 | + ]; | |
| 104 | + return $data; | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Admin Views | |
| 109 | + * | |
| 110 | + * @return void | |
| 111 | + */ | |
| 112 | + public function settings_page() { | |
| 113 | + include_once NOTIFICATIONX_INCLUDES . 'Admin/views/settings.views.php'; | |
| 114 | + } | |
| 115 | + | |
| 116 | + | |
| 117 | + public function settings_form( $nx_id = 0 ) { | |
| 118 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 119 | + do_action( 'nx_before_settings_fields' ); | |
| 120 | + $wp_roles = GlobalFields::get_instance()->normalize_fields( $this->get_roles() ); | |
| 121 | + $site_name = get_bloginfo( 'name' ); | |
| 122 | + $settings = [ | |
| 123 | + 'id' => 'notificationx_metabox_wrapper', | |
| 124 | + 'title' => __( 'NotificationX', 'notificationx' ), | |
| 125 | + 'object_types' => array( 'notificationx' ), | |
| 126 | + 'context' => 'normal', | |
| 127 | + 'priority' => 'high', | |
| 128 | + 'show_header' => false, | |
| 129 | + 'tabnumber' => true, | |
| 130 | + 'layout' => 'horizontal', | |
| 131 | + 'is_pro_active' => NotificationX::get_instance()->is_pro(), | |
| 132 | + 'cus_imp_limit' => Settings::get_instance()->get('settings.custom_notification_import_limit', 100), | |
| 133 | + 'is_wpml_active'=> Helper::is_wpml_setup(), | |
| 134 | + 'config' => [ | |
| 135 | + 'active' => 'tab-general', | |
| 136 | + 'sidebar' => false, | |
| 137 | + 'title' => false, | |
| 138 | + ], | |
| 139 | + 'submit' => [ | |
| 140 | + 'show' => true, | |
| 141 | + 'label' => __( 'Save Settings', 'notificationx' ), | |
| 142 | + 'class' => 'save-settings', | |
| 143 | + ], | |
| 144 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 145 | + 'tabs' => apply_filters('nx_settings_tab', [ | |
| 146 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 147 | + 'tab-general' => apply_filters('nx_settings_tab_general', [ | |
| 148 | + 'id' => 'tab-general', | |
| 149 | + 'label' => __( 'General', 'notificationx' ), | |
| 150 | + 'classes' => 'tab-general', | |
| 151 | + 'priority' => 10, | |
| 152 | + 'fields' => [ | |
| 153 | + 'section-modules' => [ | |
| 154 | + 'label' => __( 'Modules', 'notificationx' ), | |
| 155 | + 'name' => 'section-modules', | |
| 156 | + 'type' => 'section', | |
| 157 | + 'classes' => NotificationX::get_instance()->is_pro() ? 'section-modules pro-activated' : 'section-modules', | |
| 158 | + 'fields' => [ | |
| 159 | + 'modules' => [ | |
| 160 | + // 'label' => "Modules", | |
| 161 | + 'name' => 'modules', | |
| 162 | + 'type' => 'toggle', | |
| 163 | + 'multiple' => true, | |
| 164 | + 'default' => true, | |
| 165 | + 'style' => [ | |
| 166 | + 'type' => 'card', | |
| 167 | + 'column' => 3, | |
| 168 | + ], | |
| 169 | + 'options' => array_values( Modules::get_instance()->get_all() ), | |
| 170 | + ], | |
| 171 | + ], | |
| 172 | + ], | |
| 173 | + ], | |
| 174 | + ] | |
| 175 | + ), | |
| 176 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 177 | + 'advanced-settings-tab' => apply_filters('nx_settings_tab_advanced', [ | |
| 178 | + 'id' => 'tab-advanced-settings', | |
| 179 | + 'label' => __( 'Advanced Settings', 'notificationx' ), | |
| 180 | + 'classes' => 'tab-advanced-settings', | |
| 181 | + 'priority' => 20, | |
| 182 | + 'fields' => [ | |
| 183 | + 'advanced-general' => [ | |
| 184 | + 'name' => 'advanced-general', | |
| 185 | + 'type' => 'section', | |
| 186 | + 'label' => __( 'General', 'notificationx' ), | |
| 187 | + 'priority' => 5, | |
| 188 | + 'fields' => array( | |
| 189 | + 'enable_rest_api' => [ | |
| 190 | + 'name' => "enable_rest_api", | |
| 191 | + 'type' => 'checkbox', | |
| 192 | + 'label' => __('Enable REST API', 'notificationx'), | |
| 193 | + 'default' => false, | |
| 194 | + 'priority' => 10, | |
| 195 | + 'description' => __( 'Forcefully enable anonymous REST API for NotificationX.', 'notificationx' ), | |
| 196 | + ], | |
| 197 | + 'omit_credentials' => [ | |
| 198 | + 'name' => "omit_credentials", | |
| 199 | + 'type' => 'checkbox', | |
| 200 | + 'label' => __('Exclude Credentials', 'notificationx'), | |
| 201 | + 'default' => true, | |
| 202 | + 'priority' => 15, | |
| 203 | + 'description' => __( 'Enabling it will remove cookies, HTTP authentication entries, and TLS client certificates from API calls on the frontend.', 'notificationx' ), | |
| 204 | + 'help' => __( 'Note: Recommended if you use any caching plugins.', 'notificationx' ), | |
| 205 | + ], | |
| 206 | + 'notification_image_size' => [ | |
| 207 | + 'name' => "notification_image_size", | |
| 208 | + 'type' => 'select', | |
| 209 | + 'label' => __('Image Size', 'notificationx'), | |
| 210 | + 'default' => '100_100', | |
| 211 | + 'options' => GlobalFields::get_instance()->normalize_fields([ | |
| 212 | + '100_100' => __('100 x 100 px', 'notificationx'), | |
| 213 | + '200_200' => __('200 x 200 px', 'notificationx'), | |
| 214 | + '300_300' => __('300 x 300 px', 'notificationx'), | |
| 215 | + '400_400' => __('400 x 400 px', 'notificationx'), | |
| 216 | + '500_500' => __('500 x 500 px', 'notificationx'), | |
| 217 | + ]), | |
| 218 | + 'priority' => 20, | |
| 219 | + 'help' => __('Select the size for your notification image.', 'notificationx'), | |
| 220 | + ], | |
| 221 | + 'custom_notification_import_limit' => [ | |
| 222 | + 'name' => "custom_notification_import_limit", | |
| 223 | + 'type' => 'number', | |
| 224 | + 'label' => __('Custom Notification Import Limit', 'notificationx'), | |
| 225 | + 'default' => 100, | |
| 226 | + 'priority' => 25, | |
| 227 | + ], | |
| 228 | + ), | |
| 229 | + ], | |
| 230 | + 'powered_by' => [ | |
| 231 | + 'name' => 'powered_by', | |
| 232 | + 'label' => __( 'Powered By', 'notificationx' ), | |
| 233 | + 'type' => 'section', | |
| 234 | + 'priority' => 15, | |
| 235 | + 'fields' => [ | |
| 236 | + 'disable_powered_by' => [ | |
| 237 | + 'type' => 'checkbox', | |
| 238 | + 'label' => __( 'Disable Powered By', 'notificationx' ), | |
| 239 | + 'name' => 'disable_powered_by', | |
| 240 | + 'default' => 0, | |
| 241 | + 'priority' => 10, | |
| 242 | + 'description' => __( 'Click, if you want to disable powered by text from notification', 'notificationx' ), | |
| 243 | + ], | |
| 244 | + ], | |
| 245 | + ], | |
| 246 | + 'role_management' => array( | |
| 247 | + 'name' => 'role_management', | |
| 248 | + 'type' => 'section', | |
| 249 | + 'label' => __( 'Role Management', 'notificationx' ), | |
| 250 | + 'priority' => 30, | |
| 251 | + 'fields' => array( | |
| 252 | + 'notification_view_roles' => array( | |
| 253 | + 'name' => 'notification_view_roles', | |
| 254 | + 'type' => 'select', | |
| 255 | + 'label' => __( 'Who Can View Notification?', 'notificationx' ), | |
| 256 | + 'priority' => 1, | |
| 257 | + 'multiple' => true, | |
| 258 | + 'is_pro' => true, | |
| 259 | + 'disable' => true, | |
| 260 | + 'default' => [ 'administrator' ], | |
| 261 | + 'options' => $wp_roles, | |
| 262 | + ), | |
| 263 | + 'notification_roles' => array( | |
| 264 | + 'name' => 'notification_roles', | |
| 265 | + 'type' => 'select', | |
| 266 | + 'label' => __( 'Who Can Create Notification?', 'notificationx' ), | |
| 267 | + 'priority' => 1, | |
| 268 | + 'multiple' => true, | |
| 269 | + 'is_pro' => true, | |
| 270 | + 'disable' => true, | |
| 271 | + 'default' => [ 'administrator' ], | |
| 272 | + 'options' => $wp_roles, | |
| 273 | + ), | |
| 274 | + 'settings_roles' => array( | |
| 275 | + 'name' => 'settings_roles', | |
| 276 | + 'type' => 'select', | |
| 277 | + 'label' => __( 'Who Can Edit Settings?', 'notificationx' ), | |
| 278 | + 'priority' => 2, | |
| 279 | + 'multiple' => true, | |
| 280 | + 'is_pro' => true, | |
| 281 | + 'disable' => true, | |
| 282 | + 'default' => [ 'administrator' ], | |
| 283 | + 'options' => $wp_roles, | |
| 284 | + ), | |
| 285 | + 'analytics_roles' => array( | |
| 286 | + 'name' => 'analytics_roles', | |
| 287 | + 'type' => 'select', | |
| 288 | + 'label' => __( 'Who Can Check Analytics?', 'notificationx' ), | |
| 289 | + 'priority' => 3, | |
| 290 | + 'multiple' => true, | |
| 291 | + 'is_pro' => true, | |
| 292 | + 'disable' => true, | |
| 293 | + 'default' => [ 'administrator' ], | |
| 294 | + 'options' => $wp_roles, | |
| 295 | + ), | |
| 296 | + ), | |
| 297 | + ), | |
| 298 | + ], | |
| 299 | + ] | |
| 300 | + ), | |
| 301 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 302 | + 'email-analytics-reporting' => apply_filters('nx_settings_tab_email_analytics', [ | |
| 303 | + 'label' => __( 'Analytics & Reporting', 'notificationx' ), | |
| 304 | + 'id' => 'email-analytics-reporting', | |
| 305 | + 'classes' => 'tab-advanced-settings', | |
| 306 | + 'priority' => 30, | |
| 307 | + 'fields' => [ | |
| 308 | + 'analytics' => array( | |
| 309 | + 'name' => 'analytics', | |
| 310 | + 'priority' => 10, | |
| 311 | + 'type' => 'section', | |
| 312 | + 'label' => __( 'Analytics', 'notificationx' ), | |
| 313 | + 'fields' => array( | |
| 314 | + 'enable_analytics' => array( | |
| 315 | + 'name' => 'enable_analytics', | |
| 316 | + 'type' => 'checkbox', | |
| 317 | + 'label' => __( 'Enable Analytics', 'notificationx' ), | |
| 318 | + 'default' => true, | |
| 319 | + 'priority' => 0, | |
| 320 | + ), | |
| 321 | + 'disable_dashboard_widget' => array( | |
| 322 | + 'name' => 'disable_dashboard_widget', | |
| 323 | + 'type' => 'checkbox', | |
| 324 | + 'label' => __( 'Disable Dashboard Widget', 'notificationx' ), | |
| 325 | + 'default' => false, | |
| 326 | + 'priority' => 5, | |
| 327 | + 'description' => __( 'Click, if you want to disable dashboard widget of analytics only.', 'notificationx' ), | |
| 328 | + 'rules' => Rules::is( 'enable_analytics', true ), | |
| 329 | + ), | |
| 330 | + 'analytics_from' => array( | |
| 331 | + 'name' => 'analytics_from', | |
| 332 | + 'type' => 'select', | |
| 333 | + 'label' => __( 'Analytics From', 'notificationx' ), | |
| 334 | + 'options' => GlobalFields::get_instance()->normalize_fields(array( | |
| 335 | + 'everyone' => __( 'Everyone', 'notificationx' ), | |
| 336 | + 'guests' => __( 'Guests Only', 'notificationx' ), | |
| 337 | + 'registered_users' => __( 'Registered Users Only', 'notificationx' ), | |
| 338 | + ) | |
| 339 | + ), | |
| 340 | + 'default' => 'everyone', | |
| 341 | + 'priority' => 10, | |
| 342 | + 'rules' => Rules::is( 'enable_analytics', true ), | |
| 343 | + ), | |
| 344 | + 'exclude_bot_analytics' => array( | |
| 345 | + 'name' => 'exclude_bot_analytics', | |
| 346 | + 'type' => 'checkbox', | |
| 347 | + 'label' => __( 'Exclude Bot Analytics', 'notificationx' ), | |
| 348 | + 'default' => true, | |
| 349 | + 'priority' => 15, | |
| 350 | + 'description' => __( 'Select if you want to exclude bot analytics.', 'notificationx' ), | |
| 351 | + 'rules' => Rules::is( 'enable_analytics', true ), | |
| 352 | + ), | |
| 353 | + ), | |
| 354 | + ), | |
| 355 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 356 | + 'entries_mail_receiver' => apply_filters( 'nx_settings_entries_mail_receiver', array( | |
| 357 | + 'name' => 'entries_mail_receiver', | |
| 358 | + 'priority' => 15, | |
| 359 | + 'type' => 'section', | |
| 360 | + 'label' => __( 'Entries Mail Receiver', 'notificationx' ), | |
| 361 | + 'fields' => array( | |
| 362 | + 'enable_entries_mail' => array( | |
| 363 | + 'name' => 'enable_entries_mail', | |
| 364 | + 'type' => 'checkbox', | |
| 365 | + 'label' => __( 'Enable Entries Mail Receiver', 'notificationx' ), | |
| 366 | + 'default' => false, | |
| 367 | + 'priority' => 0, | |
| 368 | + 'description' => __( 'Send an email notification whenever a new entry is received.', 'notificationx' ), | |
| 369 | + ), | |
| 370 | + 'entries_mail_email' => array( | |
| 371 | + 'name' => 'entries_mail_email', | |
| 372 | + 'type' => 'text', | |
| 373 | + 'label' => __( 'Entry Recipient Email', 'notificationx' ), | |
| 374 | + 'default' => get_option( 'admin_email' ), | |
| 375 | + 'priority' => 1, | |
| 376 | + 'rules' => Rules::is( 'enable_entries_mail', true ), | |
| 377 | + ), | |
| 378 | + 'entries_mail_subject' => array( | |
| 379 | + 'name' => 'entries_mail_subject', | |
| 380 | + 'type' => 'text', | |
| 381 | + 'label' => __( 'Email Subject', 'notificationx' ), | |
| 382 | + /* translators: %s: site name */ | |
| 383 | + 'default' => sprintf( __( 'New Entry Received on "%s"', 'notificationx' ), $site_name ), | |
| 384 | + 'priority' => 2, | |
| 385 | + 'rules' => Rules::is( 'enable_entries_mail', true ), | |
| 386 | + ), | |
| 387 | + 'test_entries_mail' => array( | |
| 388 | + 'name' => 'test_entries_mail', | |
| 389 | + 'label' => __( 'Test Mail', 'notificationx' ), | |
| 390 | + 'text' => __( 'Send Test Email', 'notificationx' ), | |
| 391 | + 'type' => 'button', | |
| 392 | + 'priority' => 3, | |
| 393 | + 'rules' => Rules::is( 'enable_entries_mail', true ), | |
| 394 | + 'ajax' => [ | |
| 395 | + 'on' => 'click', | |
| 396 | + 'api' => '/notificationx/v1/entries-mail-test', | |
| 397 | + 'data' => [ | |
| 398 | + 'entries_mail_email' => '@entries_mail_email', | |
| 399 | + 'entries_mail_subject' => '@entries_mail_subject', | |
| 400 | + ], | |
| 401 | + 'swal' => [ | |
| 402 | + 'text' => __( 'Test email sent successfully.', 'notificationx' ), | |
| 403 | + 'icon' => 'success', | |
| 404 | + 'autoClose' => 2000, | |
| 405 | + ], | |
| 406 | + ], | |
| 407 | + ), | |
| 408 | + ), | |
| 409 | + ) ), | |
| 410 | + 'email_reporting' => array( | |
| 411 | + 'name' => 'email_reporting', | |
| 412 | + 'priority' => 20, | |
| 413 | + 'type' => 'section', | |
| 414 | + 'label' => __( 'Reporting', 'notificationx' ), | |
| 415 | + 'rules' => Rules::is( 'enable_analytics', true ), | |
| 416 | + 'fields' => array( | |
| 417 | + 'disable_reporting' => array( | |
| 418 | + 'name' => 'disable_reporting', | |
| 419 | + 'label' => __( 'Disable Reporting', 'notificationx' ), | |
| 420 | + 'type' => 'checkbox', | |
| 421 | + 'priority' => 0, | |
| 422 | + 'default' => 0, | |
| 423 | + ), | |
| 424 | + 'reporting_frequency' => array( | |
| 425 | + 'name' => 'reporting_frequency', | |
| 426 | + 'type' => 'select', | |
| 427 | + 'label' => __( 'Reporting Frequency', 'notificationx' ), | |
| 428 | + 'default' => 'nx_weekly', | |
| 429 | + 'is_pro' => true, | |
| 430 | + 'priority' => 1, | |
| 431 | + 'disable' => true, | |
| 432 | + 'options' => GlobalFields::get_instance()->normalize_fields(array( | |
| 433 | + 'nx_daily' => __( 'Once Daily', 'notificationx' ), | |
| 434 | + 'nx_weekly' => __( 'Once Weekly', 'notificationx' ), | |
| 435 | + 'nx_monthly' => __( 'Once Monthly', 'notificationx' ), | |
| 436 | + ) | |
| 437 | + ), | |
| 438 | + 'rules' => Rules::is( 'disable_reporting', false ), | |
| 439 | + 'info' => InfoTooltipManager::get_instance()->render('reporting_frequency'), | |
| 440 | + ), | |
| 441 | + 'reporting_monthly_help_text' => array( | |
| 442 | + 'name' => 'reporting_monthly_help_text', | |
| 443 | + 'type' => 'message', | |
| 444 | + 'class' => 'nx-warning', | |
| 445 | + 'priority' => 1.5, | |
| 446 | + 'message' => __( 'It will be triggered on the first day of next month.', 'notificationx' ), | |
| 447 | + 'rules' => Rules::is( 'reporting_frequency', 'nx_monthly' ), | |
| 448 | + ), | |
| 449 | + 'reporting_day' => array( | |
| 450 | + 'name' => 'reporting_day', | |
| 451 | + 'type' => 'select', | |
| 452 | + 'label' => __( 'Select Reporting Day', 'notificationx' ), | |
| 453 | + 'default' => 'monday', | |
| 454 | + 'priority' => 2, | |
| 455 | + 'options' => GlobalFields::get_instance()->normalize_fields(array( | |
| 456 | + 'sunday' => __( 'Sunday', 'notificationx' ), | |
| 457 | + 'monday' => __( 'Monday', 'notificationx' ), | |
| 458 | + 'tuesday' => __( 'Tuesday', 'notificationx' ), | |
| 459 | + 'wednesday' => __( 'Wednesday', 'notificationx' ), | |
| 460 | + 'thursday' => __( 'Thursday', 'notificationx' ), | |
| 461 | + 'friday' => __( 'Friday', 'notificationx' ), | |
| 462 | + ) | |
| 463 | + ), | |
| 464 | + 'description' => __( 'Select a day for email report.', 'notificationx' ), | |
| 465 | + 'rules' => Rules::logicalRule([ | |
| 466 | + Rules::is( 'reporting_frequency', 'nx_weekly' ), | |
| 467 | + Rules::is( 'disable_reporting', false ), | |
| 468 | + ] | |
| 469 | + ), | |
| 470 | + ), | |
| 471 | + 'reporting_email' => array( | |
| 472 | + 'name' => 'reporting_email', | |
| 473 | + 'type' => 'text', | |
| 474 | + 'label' => __( 'Reporting Email', 'notificationx' ), | |
| 475 | + 'default' => get_option( 'admin_email' ), | |
| 476 | + 'priority' => 3, | |
| 477 | + 'rules' => Rules::is( 'disable_reporting', false ), | |
| 478 | + ), | |
| 479 | + 'reporting_subject' => array( | |
| 480 | + 'name' => 'reporting_subject', | |
| 481 | + 'type' => 'text', | |
| 482 | + 'label' => __( 'Reporting Email Subject', 'notificationx' ), | |
| 483 | + /* translators: %s: site name */ | |
| 484 | + 'default' => sprintf( __( 'Weekly Engagement Summary of “%s”', 'notificationx' ), $site_name ), | |
| 485 | + 'priority' => 4, | |
| 486 | + 'disable' => true, | |
| 487 | + 'rules' => Rules::is( 'disable_reporting', false ), | |
| 488 | + ), | |
| 489 | + 'test_report' => array( | |
| 490 | + 'name' => 'test_report', | |
| 491 | + 'label' => __( 'Reporting Test', 'notificationx' ), | |
| 492 | + 'text' => __( 'Test Report', 'notificationx' ), | |
| 493 | + 'type' => 'button', | |
| 494 | + 'priority' => 5, | |
| 495 | + 'rules' => Rules::is( 'disable_reporting', false ), | |
| 496 | + 'ajax' => [ | |
| 497 | + 'on' => 'click', | |
| 498 | + 'api' => '/notificationx/v1/reporting-test', | |
| 499 | + 'data' => [ | |
| 500 | + 'disable_reporting' => '@disable_reporting', | |
| 501 | + 'reporting_subject' => '@reporting_subject', | |
| 502 | + 'reporting_email' => '@reporting_email', | |
| 503 | + 'reporting_day' => '@reporting_day', | |
| 504 | + 'reporting_frequency' => '@reporting_frequency', | |
| 505 | + ], | |
| 506 | + 'swal' => [ | |
| 507 | + 'text' => __( 'Successfully Sent a Test Report in Your Email.', 'notificationx' ), | |
| 508 | + 'icon' => 'success', | |
| 509 | + 'autoClose' => 2000, | |
| 510 | + ], | |
| 511 | + ], | |
| 512 | + ), | |
| 513 | + ), | |
| 514 | + ), | |
| 515 | + ], | |
| 516 | + ] | |
| 517 | + ), | |
| 518 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 519 | + 'entries' => apply_filters('nx_settings_tab_entries', [ | |
| 520 | + 'label' => __( 'Entries', 'notificationx' ), | |
| 521 | + 'id' => 'entries', | |
| 522 | + 'classes' => 'tab-advanced-settings', | |
| 523 | + 'priority' => 35, | |
| 524 | + 'fields' => [ | |
| 525 | + 'feedback_entries' => array( | |
| 526 | + 'name' => 'feedback_entries', | |
| 527 | + 'priority' => 10, | |
| 528 | + 'type' => 'feedback-entries', | |
| 529 | + 'label' => __( 'Analytics', 'notificationx' ), | |
| 530 | + ), | |
| 531 | + ], | |
| 532 | + ] | |
| 533 | + ), | |
| 534 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 535 | + 'cache_settings_tab' => apply_filters('nx_settings_tab_cache', [ | |
| 536 | + 'id' => 'tab-cache-settings', | |
| 537 | + 'label' => __( 'Cache Settings', 'notificationx' ), | |
| 538 | + 'priority' => 40, | |
| 539 | + 'fields' => [ | |
| 540 | + 'cache_settings' => array( | |
| 541 | + 'name' => 'cache_settings', | |
| 542 | + 'type' => 'section', | |
| 543 | + 'label' => __( 'Cache Settings', 'notificationx' ), | |
| 544 | + 'priority' => 5, | |
| 545 | + 'fields' => array( | |
| 546 | + 'cache_limit' => array( | |
| 547 | + 'name' => 'cache_limit', | |
| 548 | + 'type' => 'text', | |
| 549 | + 'label' => __( 'Cache Limit', 'notificationx' ), | |
| 550 | + 'description' => __( 'Number of Notification Data to be saved in Database.', 'notificationx' ), | |
| 551 | + 'default' => '100', | |
| 552 | + 'priority' => 1, | |
| 553 | + ), | |
| 554 | + 'download_stats_cache_duration' => array( | |
| 555 | + 'name' => 'download_stats_cache_duration', | |
| 556 | + 'type' => 'text', | |
| 557 | + 'label' => __( 'Download Stats Cache Duration', 'notificationx' ), | |
| 558 | + 'description' => __( 'Minutes (Schedule Duration to fetch new data).', 'notificationx' ), | |
| 559 | + 'default' => 3, | |
| 560 | + 'priority' => 2, | |
| 561 | + ), | |
| 562 | + 'reviews_cache_duration' => array( | |
| 563 | + 'name' => 'reviews_cache_duration', | |
| 564 | + 'type' => 'text', | |
| 565 | + 'label' => __( 'Reviews Cache Duration', 'notificationx' ), | |
| 566 | + 'description' => __( 'Minutes (Schedule Duration to fetch new data).', 'notificationx' ), | |
| 567 | + 'default' => '3', | |
| 568 | + 'priority' => 3, | |
| 569 | + ), | |
| 570 | + ), | |
| 571 | + ), | |
| 572 | + ], | |
| 573 | + ] | |
| 574 | + ), | |
| 575 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 576 | + 'tab-miscellaneous-settings' => apply_filters('nx_settings_tab_miscellaneous', [ | |
| 577 | + 'id' => 'tab-miscellaneous-settings', | |
| 578 | + 'label' => __( 'Miscellaneous', 'notificationx' ), | |
| 579 | + 'priority' => 50, | |
| 580 | + 'fields' => [ | |
| 581 | + ], | |
| 582 | + ] | |
| 583 | + ), | |
| 584 | + ] | |
| 585 | + ), | |
| 586 | + ]; | |
| 587 | + | |
| 588 | + if ( defined( 'NX_DEBUG' ) && NX_DEBUG ) { | |
| 589 | + $settings['tabs']['tab-miscellaneous-settings']['fields'][] = array( | |
| 590 | + 'name' => 'danger-zone', | |
| 591 | + 'type' => 'section', | |
| 592 | + 'label' => __( 'Danger Zone', 'notificationx' ), | |
| 593 | + 'priority' => 200, | |
| 594 | + 'fields' => array( | |
| 595 | + 'delete-settings' => array( | |
| 596 | + 'name' => 'delete-settings', | |
| 597 | + 'label' => __( 'Delete Settings', 'notificationx' ), | |
| 598 | + 'text' => __( 'Delete Settings', 'notificationx' ), | |
| 599 | + 'type' => 'button', | |
| 600 | + 'priority' => 15, | |
| 601 | + 'ajax' => [ | |
| 602 | + 'on' => 'click', | |
| 603 | + 'reload' => true, | |
| 604 | + 'api' => '/notificationx/v1/settings', | |
| 605 | + 'data' => [ | |
| 606 | + 'delete_settings' => true, | |
| 607 | + ], | |
| 608 | + 'swal' => [ | |
| 609 | + 'text' => __( 'Successfully deleted Settings.', 'notificationx' ), | |
| 610 | + 'icon' => 'deleted', | |
| 611 | + 'autoClose' => 2000, | |
| 612 | + ], | |
| 613 | + ], | |
| 614 | + ), | |
| 615 | + 'delete-transient' => array( | |
| 616 | + 'name' => 'delete-transient', | |
| 617 | + 'label' => __( 'Delete Transient', 'notificationx' ), | |
| 618 | + 'text' => __( 'Delete Transient', 'notificationx' ), | |
| 619 | + 'type' => 'button', | |
| 620 | + 'priority' => 25, | |
| 621 | + 'ajax' => [ | |
| 622 | + 'on' => 'click', | |
| 623 | + 'reload' => true, | |
| 624 | + 'api' => '/notificationx/v1/miscellaneous', | |
| 625 | + 'data' => [ | |
| 626 | + 'delete_transient' => true, | |
| 627 | + ], | |
| 628 | + 'swal' => [ | |
| 629 | + 'text' => __( 'Successfully deleted Transient.', 'notificationx' ), | |
| 630 | + 'icon' => 'deleted', | |
| 631 | + 'autoClose' => 2000, | |
| 632 | + ], | |
| 633 | + ], | |
| 634 | + ), | |
| 635 | + ), | |
| 636 | + ); | |
| 637 | + } | |
| 638 | + | |
| 639 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 640 | + $settings = apply_filters( 'nx_settings_configs', $settings ); | |
| 641 | + return $settings; | |
| 642 | + } | |
| 643 | + | |
| 644 | + /** | |
| 645 | + * Get All Roles | |
| 646 | + * dynamically | |
| 647 | + * | |
| 648 | + * @return array | |
| 649 | + */ | |
| 650 | + public function get_roles() { | |
| 651 | + $roles = wp_roles()->role_names; | |
| 652 | + unset( $roles['subscriber'] ); | |
| 653 | + return $roles; | |
| 654 | + } | |
| 655 | + /** | |
| 656 | + * Get All Roles | |
| 657 | + * dynamically | |
| 658 | + * user_has_cap | |
| 659 | + * | |
| 660 | + * @return array | |
| 661 | + */ | |
| 662 | + public function allow_admin( $allcaps, $caps, $args, $user ) { | |
| 663 | + $nx_roles = [ | |
| 664 | + 'read_notificationx', | |
| 665 | + 'edit_notificationx', | |
| 666 | + 'edit_notificationx_settings', | |
| 667 | + 'read_notificationx_analytics', | |
| 668 | + ]; | |
| 669 | + if ( ! empty( $caps[0] ) && array_key_exists( 'administrator', $allcaps ) && ! array_key_exists( $caps[0], $allcaps ) && in_array( $caps[0], $nx_roles ) ) { | |
| 670 | + $role = get_role( 'administrator' ); | |
| 671 | + $role->add_cap( $caps[0] ); | |
| 672 | + $allcaps[ $caps[0] ] = true; | |
| 673 | + } | |
| 674 | + return $allcaps; | |
| 675 | + } | |
| 676 | + | |
| 677 | + public function save_settings( $settings ) { | |
| 678 | + if ( ! current_user_can( 'edit_notificationx_settings' ) ) { | |
| 679 | + return false; | |
| 680 | + } | |
| 681 | + $remove_before_save = [ | |
| 682 | + 'empty', | |
| 683 | + ]; | |
| 684 | + | |
| 685 | + // Must run before the role map is derived below, or the posted values | |
| 686 | + // would still reach `nx_settings_saved` and be written to the roles. | |
| 687 | + $settings = $this->preserve_role_settings( $settings ); | |
| 688 | + $settings = $this->preserve_secret_settings( $settings ); | |
| 689 | + | |
| 690 | + $roles = $this->get_selected_roles( $settings ); | |
| 691 | + $settings = array_merge( $settings, $roles ); | |
| 692 | + | |
| 693 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 694 | + $settings = apply_filters( 'nx_settings', $settings ); | |
| 695 | + | |
| 696 | + foreach ( $remove_before_save as $key ) { | |
| 697 | + if ( isset( $settings[ $key ] ) ) { | |
| 698 | + unset( $settings[ $key ] ); | |
| 699 | + } | |
| 700 | + } | |
| 701 | + $settings = $this->preserve_protected_settings( $settings ); | |
| 702 | + | |
| 703 | + // need this to ensure saved value don't return empty array instead of object. | |
| 704 | + if ( ! empty( $settings['delete_settings'] ) ) { | |
| 705 | + $settings = [ 'empty' => true ]; | |
| 706 | + // The reset discards everything preserved above, so re-apply the | |
| 707 | + // role gate: a settings administrator must not be able to rewrite | |
| 708 | + // role assignments by routing through a settings reset. | |
| 709 | + $settings = $this->preserve_role_settings( $settings ); | |
| 710 | + } | |
| 711 | + | |
| 712 | + $this->set( 'settings', $settings ); | |
| 713 | + delete_transient( 'nx_get_field_names' ); | |
| 714 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 715 | + do_action( 'nx_settings_saved', $settings ); | |
| 716 | + return true; | |
| 717 | + } | |
| 718 | + | |
| 719 | + /** | |
| 720 | + * Force server-owned settings back to their stored values. | |
| 721 | + * | |
| 722 | + * `save_settings()` replaces the whole blob with the posted one, so every key | |
| 723 | + * the admin app is holding wins -- right for fields a merchant edits, wrong | |
| 724 | + * for state only the server writes. OAuth tokens are the case that bites: | |
| 725 | + * they live inside `settings`, so they are handed to the admin app on page | |
| 726 | + * load and posted straight back. Disconnecting an account and then saving | |
| 727 | + * from a tab opened *before* the disconnect wrote the revoked token back and | |
| 728 | + * the integration silently kept working -- with Google Analytics that showed | |
| 729 | + * up as live viewer counts on a supposedly disconnected site. | |
| 730 | + * | |
| 731 | + * Keys listed here can only be changed by the code that owns them. | |
| 732 | + * | |
| 733 | + * @param array $settings Incoming settings. | |
| 734 | + * @return array | |
| 735 | + */ | |
| 736 | + protected function preserve_protected_settings( $settings ) { | |
| 737 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 738 | + $protected = apply_filters( 'nx_protected_settings', [ | |
| 739 | + 'nx_pa_settings', // Google Analytics OAuth token. | |
| 740 | + ] ); | |
| 741 | + | |
| 742 | + // `get()` returns false for a missing key, and false is also what a | |
| 743 | + // disconnect stores -- so only a sentinel separates "stored as false" | |
| 744 | + // from "never stored", and the two need different handling. | |
| 745 | + $missing = new \stdClass(); | |
| 746 | + | |
| 747 | + foreach ( (array) $protected as $key ) { | |
| 748 | + if ( ! is_string( $key ) || '' === $key ) { | |
| 749 | + continue; | |
| 750 | + } | |
| 751 | + $stored = $this->get( "settings.{$key}", $missing ); | |
| 752 | + if ( $missing === $stored ) { | |
| 753 | + unset( $settings[ $key ] ); | |
| 754 | + continue; | |
| 755 | + } | |
| 756 | + $settings[ $key ] = $stored; | |
| 757 | + } | |
| 758 | + | |
| 759 | + return $settings; | |
| 760 | + } | |
| 761 | + | |
| 762 | + /** | |
| 763 | + * Settings keys holding credentials rather than configuration. | |
| 764 | + * | |
| 765 | + * These are values a site owner pastes in once and which grant access to a | |
| 766 | + * third-party account. They must never reach a client that is not entitled | |
| 767 | + * to edit settings, and must never be written into an export file. | |
| 768 | + * | |
| 769 | + * Pro registers its own integrations, so the list is filterable; keep the | |
| 770 | + * free baseline broad rather than minimal, because a key omitted here is a | |
| 771 | + * key that leaks. | |
| 772 | + * | |
| 773 | + * @return array | |
| 774 | + */ | |
| 775 | + public static function get_secret_settings_keys() { | |
| 776 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 777 | + return (array) apply_filters( 'nx_secret_settings', [ | |
| 778 | + 'nx_pa_settings', // Google Analytics OAuth access + refresh token. | |
| 779 | + 'token_info', | |
| 780 | + 'ga_client_secret', | |
| 781 | + 'yt_client_secret', | |
| 782 | + 'openai_access_token', | |
| 783 | + 'mailchimp_api_key', | |
| 784 | + 'activecampaign_api_key', | |
| 785 | + 'brevo_api_key', | |
| 786 | + 'convertkit_api_key', | |
| 787 | + 'convertkit_api_secret', | |
| 788 | + 'google_review_api_key', | |
| 789 | + 'google_youtube_api_key', | |
| 790 | + 'zapier_api_key', | |
| 791 | + 'ifttt_api_key', | |
| 792 | + 'envato_token', | |
| 793 | + 'gmap_token', | |
| 794 | + ] ); | |
| 795 | + } | |
| 796 | + | |
| 797 | + /** | |
| 798 | + * Strip credentials out of a settings blob. | |
| 799 | + * | |
| 800 | + * Keys are removed outright rather than blanked. A blanked value is | |
| 801 | + * indistinguishable from "the user cleared this field" once it is posted | |
| 802 | + * back, which would silently destroy working integrations; an absent key is | |
| 803 | + * unambiguous and is restored by `preserve_secret_settings()` on save. | |
| 804 | + * | |
| 805 | + * @param array $settings | |
| 806 | + * @return array | |
| 807 | + */ | |
| 808 | + public static function redact_secret_settings( $settings ) { | |
| 809 | + if ( ! is_array( $settings ) ) { | |
| 810 | + return $settings; | |
| 811 | + } | |
| 812 | + foreach ( self::get_secret_settings_keys() as $key ) { | |
| 813 | + unset( $settings[ $key ] ); | |
| 814 | + } | |
| 815 | + return $settings; | |
| 816 | + } | |
| 817 | + | |
| 818 | + /** | |
| 819 | + * Carry stored credentials across a save that does not carry them. | |
| 820 | + * | |
| 821 | + * Counterpart to `redact_secret_settings()`. An export has its credentials | |
| 822 | + * stripped, so importing one would otherwise blank every integration on the | |
| 823 | + * target site. Absent key means "unchanged"; a key that *is* present wins, | |
| 824 | + * so a settings administrator editing an API key in the UI still works, and | |
| 825 | + * deliberately clearing a field still clears it. | |
| 826 | + * | |
| 827 | + * Unlike `preserve_protected_settings()` these values are user-owned, so | |
| 828 | + * they must stay editable -- that is why this cannot simply force the | |
| 829 | + * stored value back. | |
| 830 | + * | |
| 831 | + * @param array $settings Incoming settings. | |
| 832 | + * @return array | |
| 833 | + */ | |
| 834 | + protected function preserve_secret_settings( $settings ) { | |
| 835 | + if ( ! is_array( $settings ) ) { | |
| 836 | + return $settings; | |
| 837 | + } | |
| 838 | + | |
| 839 | + $missing = new \stdClass(); | |
| 840 | + | |
| 841 | + foreach ( self::get_secret_settings_keys() as $key ) { | |
| 842 | + if ( array_key_exists( $key, $settings ) ) { | |
| 843 | + continue; | |
| 844 | + } | |
| 845 | + $stored = $this->get( "settings.{$key}", $missing ); | |
| 846 | + if ( $missing !== $stored ) { | |
| 847 | + $settings[ $key ] = $stored; | |
| 848 | + } | |
| 849 | + } | |
| 850 | + | |
| 851 | + return $settings; | |
| 852 | + } | |
| 853 | + | |
| 854 | + /** | |
| 855 | + * Keep role assignments out of reach of a plain settings administrator. | |
| 856 | + * | |
| 857 | + * The role selectors grant and revoke capabilities across every role on the | |
| 858 | + * site, which is authority well beyond "may edit NotificationX settings". | |
| 859 | + * Pro hides these fields from the settings form unless the user can | |
| 860 | + * `delete_users` (RoleManagement::tab_advanced), but that is a filter on the | |
| 861 | + * form schema -- it never runs on save, so posting the keys directly to | |
| 862 | + * `/settings` bypassed it entirely. | |
| 863 | + * | |
| 864 | + * @param array $settings Incoming settings. | |
| 865 | + * @return array | |
| 866 | + */ | |
| 867 | + protected function preserve_role_settings( $settings ) { | |
| 868 | + if ( ! is_array( $settings ) || current_user_can( 'delete_users' ) ) { | |
| 869 | + return $settings; | |
| 870 | + } | |
| 871 | + | |
| 872 | + $role_keys = [ | |
| 873 | + 'notification_view_roles', | |
| 874 | + 'notification_roles', | |
| 875 | + 'settings_roles', | |
| 876 | + 'analytics_roles', | |
| 877 | + ]; | |
| 878 | + | |
| 879 | + $missing = new \stdClass(); | |
| 880 | + | |
| 881 | + foreach ( $role_keys as $key ) { | |
| 882 | + $stored = $this->get( "settings.{$key}", $missing ); | |
| 883 | + if ( $missing === $stored ) { | |
| 884 | + unset( $settings[ $key ] ); | |
| 885 | + continue; | |
| 886 | + } | |
| 887 | + $settings[ $key ] = $stored; | |
| 888 | + } | |
| 889 | + | |
| 890 | + return $settings; | |
| 891 | + } | |
| 892 | + | |
| 893 | + public function get_role_map( $settings = [] ) { | |
| 894 | + if ( empty( $settings ) || count( $settings ) == 1 ) { | |
| 895 | + $settings = $this->get_selected_roles(); | |
| 896 | + } | |
| 897 | + return [ | |
| 898 | + 'read_notificationx' => [ | |
| 899 | + 'roles' => $settings['notification_view_roles'], | |
| 900 | + 'map' => [], | |
| 901 | + ], | |
| 902 | + 'edit_notificationx' => [ | |
| 903 | + 'roles' => $settings['notification_roles'], | |
| 904 | + 'map' => [ 'read_notificationx' ], | |
| 905 | + ], | |
| 906 | + 'edit_notificationx_settings' => [ | |
| 907 | + 'roles' => $settings['settings_roles'], | |
| 908 | + 'map' => [ 'read_notificationx' ], | |
| 909 | + ], | |
| 910 | + 'read_notificationx_analytics' => [ | |
| 911 | + 'roles' => $settings['analytics_roles'], | |
| 912 | + 'map' => [ 'read_notificationx' ], | |
| 913 | + ], | |
| 914 | + ]; | |
| 915 | + } | |
| 916 | + | |
| 917 | + public function get_selected_roles( $settings = [] ) { | |
| 918 | + $notification_view_roles = isset( $settings['notification_view_roles'] ) ? $settings['notification_view_roles'] : self::get_instance()->get( 'settings.notification_view_roles', [] ); | |
| 919 | + $notification_roles = isset( $settings['notification_roles'] ) ? $settings['notification_roles'] : self::get_instance()->get( 'settings.notification_roles', [] ); | |
| 920 | + $settings_roles = isset( $settings['settings_roles'] ) ? $settings['settings_roles'] : self::get_instance()->get( 'settings.settings_roles', [] ); | |
| 921 | + $analytics_roles = isset( $settings['analytics_roles'] ) ? $settings['analytics_roles'] : self::get_instance()->get( 'settings.analytics_roles', [] ); | |
| 922 | + | |
| 923 | + if ( ! is_array( $notification_view_roles ) ) { | |
| 924 | + $notification_view_roles = [ $notification_view_roles ]; | |
| 925 | + } | |
| 926 | + if ( ! is_array( $notification_roles ) ) { | |
| 927 | + $notification_roles = [ $notification_roles ]; | |
| 928 | + } | |
| 929 | + if ( ! is_array( $settings_roles ) ) { | |
| 930 | + $settings_roles = [ $settings_roles ]; | |
| 931 | + } | |
| 932 | + if ( ! is_array( $analytics_roles ) ) { | |
| 933 | + $analytics_roles = [ $analytics_roles ]; | |
| 934 | + } | |
| 935 | + | |
| 936 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 937 | + return apply_filters('nx_role_management', [ | |
| 938 | + 'notification_view_roles' => array_values( array_unique( array_merge( [ 'administrator' ], $notification_view_roles ) ) ), | |
| 939 | + 'notification_roles' => array_values( array_unique( array_merge( [ 'administrator' ], $notification_roles ) ) ), | |
| 940 | + 'settings_roles' => array_values( array_unique( array_merge( [ 'administrator' ], $settings_roles ) ) ), | |
| 941 | + 'analytics_roles' => array_values( array_unique( array_merge( [ 'administrator' ], $analytics_roles ) ) ), | |
| 942 | + ] | |
| 943 | + ); | |
| 944 | + } | |
| 945 | + | |
| 946 | + /** | |
| 947 | + * Getter for options | |
| 948 | + * | |
| 949 | + * @param bool|\UsabilityDynamics\type $key | |
| 950 | + * | |
| 951 | + * @param bool $default | |
| 952 | + * | |
| 953 | + * @return type | |
| 954 | + */ | |
| 955 | + public function Xget( $key = false, $default = false ) { | |
| 956 | + if ( empty( $default ) && strpos( $key, 'settings.' ) === 0 ) { | |
| 957 | + // getting default value from settings form. | |
| 958 | + $_key = str_replace( 'settings.', '', $key ); | |
| 959 | + if ( empty( $default ) ) { | |
| 960 | + $defaults = $this->get_defaults(); | |
| 961 | + $default = ! empty( $defaults[ $_key ] ) ? $defaults[ $_key ]['default'] : $default; | |
| 962 | + } | |
| 963 | + } | |
| 964 | + return parent::get( $key, $default ); | |
| 965 | + } | |
| 966 | + | |
| 967 | + /** | |
| 968 | + * Setter for options | |
| 969 | + * | |
| 970 | + * @param string|\UsabilityDynamics\type $key | |
| 971 | + * @param bool|\UsabilityDynamics\type $value | |
| 972 | + * @param bool $bypass_validation | |
| 973 | + * | |
| 974 | + * @internal param bool|\UsabilityDynamics\type $force_save | |
| 975 | + * | |
| 976 | + * @return \UsabilityDynamics\Settings | |
| 977 | + */ | |
| 978 | + public function set( $key = '', $value = false, $bypass_validation = false ) { | |
| 979 | + if ( strpos( $key, '.' ) === false ) { | |
| 980 | + parent::flush( false, $key ); | |
| 981 | + } | |
| 982 | + return parent::set( $key, $value, $bypass_validation ); | |
| 983 | + } | |
| 984 | + | |
| 985 | + public function nx_branding_url( $link ) { | |
| 986 | + $affiliate_link = $this->get( 'settings.affiliate_link' ); | |
| 987 | + if ( ! empty( $affiliate_link ) ) { | |
| 988 | + $link = $affiliate_link; | |
| 989 | + } | |
| 990 | + return $link; | |
| 991 | + } | |
| 992 | + | |
| 993 | + // @todo maybe remove | |
| 994 | + public function get_defaults( $key = null ) { | |
| 995 | + if ( empty( $this->defaults ) ) { | |
| 996 | + $tabs = $this->settings_form(); | |
| 997 | + $this->defaults = NotificationX::get_instance()->get_field_names( $tabs['tabs'] ); | |
| 998 | + } | |
| 999 | + return $this->defaults; | |
| 1000 | + } | |
| 1001 | + | |
| 1002 | + public function miscellaneous( $return, $params ) { | |
| 1003 | + if ( !empty( $params['delete_transient'] ) && $params['delete_transient'] ) { | |
| 1004 | + Upgrader::get_instance()->clear_transient(); | |
| 1005 | + $return = true; | |
| 1006 | + } | |
| 1007 | + return $return; | |
| 1008 | + } | |
| 1009 | +} | |