balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

notifications.php (9627B)


      1 <?php
      2 
      3 /**
      4  * Notifications.
      5  *
      6  * @since 7.10.5
      7  */
      8 if ( ! class_exists( 'SeedProd_Notifications' ) ) {
      9 	class SeedProd_Notifications {
     10 
     11 		protected static $instance = null;
     12 		/**
     13 		 * Source of notifications content.
     14 		 *
     15 		 * @since {VERSION}
     16 		 *
     17 		 * @var string
     18 		 */
     19 		const SOURCE_URL = 'https://seedprod-notifications.s3.amazonaws.com/sp-notifications.json';
     20 
     21 		/**
     22 		 * Option value.
     23 		 *
     24 		 * @since {VERSION}
     25 		 *
     26 		 * @var bool|array
     27 		 */
     28 		public $option = false;
     29 
     30 		/**
     31 		 * The name of the option used to store the data.
     32 		 *
     33 		 * @var string
     34 		 */
     35 		public $option_name = 'seedprod_notifications';
     36 
     37 		/**
     38 		 * Return an instance of this class.
     39 		 */
     40 		public static function get_instance() {
     41 
     42 			// If the single instance hasn't been set, set it now.
     43 			if ( null == self::$instance ) {
     44 				self::$instance = new self();
     45 			}
     46 
     47 			return self::$instance;
     48 		}
     49 
     50 		/**
     51 		 * SeedProd_Notifications constructor.
     52 		 */
     53 		public function __construct() {
     54 			$this->init();
     55 		}
     56 
     57 		/**
     58 		 * Initialize class.
     59 		 *
     60 		 * @since {VERSION}
     61 		 */
     62 		public function init() {
     63 			$this->hooks();
     64 		}
     65 
     66 		/**
     67 		 * Register hooks.
     68 		 *
     69 		 * @since {VERSION}
     70 		 */
     71 		public function hooks() {
     72 			add_action( 'wp_ajax_seedprod_lite_notification_dismiss', array( $this, 'dismiss' ) );
     73 		}
     74 
     75 		/**
     76 		 * Check if user has access and is enabled.
     77 		 *
     78 		 * @return bool
     79 		 * @since {VERSION}
     80 		 *
     81 		 */
     82 		public function has_access() {
     83 			$access = true;
     84 
     85 			if ( current_user_can( 'install_plugins' ) ) {
     86 				$access = true;
     87 			}
     88 
     89 			return apply_filters( 'seedprod_admin_notifications_has_access', $access );
     90 		}
     91 
     92 		/**
     93 		 * Get option value.
     94 		 *
     95 		 * @param bool $cache Reference property cache if available.
     96 		 *
     97 		 * @return array
     98 		 * @since {VERSION}
     99 		 *
    100 		 */
    101 		public function get_option( $cache = true ) {
    102 			if ( $this->option && $cache ) {
    103 				return $this->option;
    104 			}
    105 
    106 			$option = get_option( $this->option_name, array() );
    107 
    108 			$this->option = array(
    109 				'update'    => ! empty( $option['update'] ) ? $option['update'] : 0,
    110 				'events'    => ! empty( $option['events'] ) ? $option['events'] : array(),
    111 				'feed'      => ! empty( $option['feed'] ) ? $option['feed'] : array(),
    112 				'dismissed' => ! empty( $option['dismissed'] ) ? $option['dismissed'] : array(),
    113 			);
    114 
    115 			return $this->option;
    116 		}
    117 
    118 		/**
    119 		 * Fetch notifications from feed.
    120 		 *
    121 		 * @return array
    122 		 * @since {VERSION}
    123 		 *
    124 		 */
    125 		public function fetch_feed() {
    126 			$res = wp_remote_get( self::SOURCE_URL );
    127 
    128 			if ( is_wp_error( $res ) ) {
    129 				return array();
    130 			}
    131 
    132 			$body = wp_remote_retrieve_body( $res );
    133 
    134 			if ( empty( $body ) ) {
    135 				return array();
    136 			}
    137 
    138 			return $this->verify( json_decode( $body, true ) );
    139 		}
    140 
    141 		/**
    142 		 * Verify notification data before it is saved.
    143 		 *
    144 		 * @param array $notifications Array of notifications items to verify.
    145 		 *
    146 		 * @return array
    147 		 * @since {VERSION}
    148 		 *
    149 		 */
    150 		public function verify( $notifications ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
    151 
    152 			$data = array();
    153 
    154 			if ( ! is_array( $notifications ) || empty( $notifications ) ) {
    155 				return $data;
    156 			}
    157 
    158 			$option = $this->get_option();
    159 
    160 			foreach ( $notifications as $notification ) {
    161 
    162 				// The message and license should never be empty, if they are, ignore.
    163 				if ( empty( $notification['content'] ) || empty( $notification['type'] ) ) {
    164 					continue;
    165 				}
    166 
    167 				// Ignore if license type does not match.
    168 				$license_name = get_option( 'seedprod_license_name' );
    169 				if ( empty( $license_name ) ) {
    170 					$license_name = 'unlicensed';
    171 				}
    172 				if ( ! in_array( 'any', $notification['type'] ) ) {
    173 					if ( ! in_array( $license_name, $notification['type'] ) ) {
    174 						continue;
    175 					}
    176 				}
    177 
    178 				// Ignore if expired.
    179 				if ( ! empty( $notification['end'] ) && time() > strtotime( $notification['end'] ) ) {
    180 					continue;
    181 				}
    182 
    183 				// Ignore if notification has already been dismissed.
    184 				if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
    185 					continue;
    186 				}
    187 
    188 				// Ignore if notification existed before installing SeedProd.
    189 				// Prevents bombarding the user with notifications after activation.
    190 				$over_time = get_option( 'seedprod_over_time', array() );
    191 
    192 				if (
    193 				! empty( $over_time['installed_date'] ) &&
    194 				! empty( $notification['start'] ) &&
    195 				$over_time['installed_date'] > strtotime( $notification['start'] )
    196 				) {
    197 					//continue;
    198 				}
    199 
    200 				$data[] = $notification;
    201 			}
    202 
    203 			return $data;
    204 		}
    205 
    206 		/**
    207 		 * Verify saved notification data for active notifications.
    208 		 *
    209 		 * @param array $notifications Array of notifications items to verify.
    210 		 *
    211 		 * @return array
    212 		 * @since {VERSION}
    213 		 *
    214 		 */
    215 		public function verify_active( $notifications ) {
    216 			if ( ! is_array( $notifications ) || empty( $notifications ) ) {
    217 				return array();
    218 			}
    219 
    220 			// Remove notifications that are not active.
    221 			foreach ( $notifications as $key => $notification ) {
    222 				if (
    223 				( ! empty( $notification['start'] ) && time() < strtotime( $notification['start'] ) ) ||
    224 				( ! empty( $notification['end'] ) && time() > strtotime( $notification['end'] ) )
    225 				) {
    226 					unset( $notifications[ $key ] );
    227 				}
    228 			}
    229 
    230 			return $notifications;
    231 		}
    232 
    233 		/**
    234 		 * Get notification data.
    235 		 *
    236 		 * @return array
    237 		 * @since {VERSION}
    238 		 *
    239 		 */
    240 		public function get() {
    241 			if ( ! $this->has_access() ) {
    242 				return array();
    243 			}
    244 
    245 			$option = $this->get_option();
    246 
    247 			$events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
    248 			$feed   = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
    249 
    250 			return array_merge( $events, $feed );
    251 		}
    252 
    253 		/**
    254 		 * Get notification count.
    255 		 *
    256 		 * @return int
    257 		 * @since {VERSION}
    258 		 *
    259 		 */
    260 		public function get_count() {
    261 			$count = count( $this->get() );
    262 
    263 			return $count;
    264 		}
    265 
    266 		/**
    267 		 * Add a manual notification event.
    268 		 *
    269 		 * @param array $notification Notification data.
    270 		 *
    271 		 * @since {VERSION}
    272 		 *
    273 		 */
    274 		public function add( $notification ) {
    275 			if ( empty( $notification['id'] ) ) {
    276 				return;
    277 			}
    278 
    279 			$option = $this->get_option();
    280 
    281 			if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
    282 				return;
    283 			}
    284 
    285 			foreach ( $option['events'] as $item ) {
    286 				if ( $item['id'] === $notification['id'] ) {
    287 					return;
    288 				}
    289 			}
    290 
    291 			$notification = $this->verify( array( $notification ) );
    292 
    293 			update_option(
    294 				$this->option_name,
    295 				array(
    296 					'update'    => $option['update'],
    297 					'feed'      => $option['feed'],
    298 					'events'    => array_merge( $notification, $option['events'] ),
    299 					'dismissed' => $option['dismissed'],
    300 				)
    301 			);
    302 		}
    303 
    304 		/**
    305 		 * Update notification data from feed.
    306 		 *
    307 		 * @since {VERSION}
    308 		 */
    309 		public function update() {
    310 			$feed   = $this->fetch_feed();
    311 			$option = $this->get_option();
    312 
    313 			update_option(
    314 				$this->option_name,
    315 				array(
    316 					'update'    => time(),
    317 					'feed'      => $feed,
    318 					'events'    => $option['events'],
    319 					'dismissed' => $option['dismissed'],
    320 				)
    321 			);
    322 		}
    323 
    324 		/**
    325 		 * Dismiss notification via AJAX.
    326 		 *
    327 		 * @since {VERSION}
    328 		 */
    329 		public function dismiss() {
    330 
    331 			// Run a security check.
    332 			check_ajax_referer( 'seedprod_lite_notification_dismiss', '_wpnonce' );
    333 
    334 			// Check for access and required param.
    335 			if ( ! $this->has_access() || empty( $_POST['id'] ) ) {
    336 				wp_send_json_error();
    337 			}
    338 
    339 			$id     = sanitize_text_field( wp_unslash( $_POST['id'] ) );
    340 			$option = $this->get_option();
    341 			$type   = is_numeric( $id ) ? 'feed' : 'events';
    342 
    343 			$option['dismissed'][] = $id;
    344 			$option['dismissed']   = array_unique( $option['dismissed'] );
    345 
    346 			// Remove notification.
    347 			if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
    348 				foreach ( $option[ $type ] as $key => $notification ) {
    349 					if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
    350 						unset( $option[ $type ][ $key ] );
    351 						break;
    352 					}
    353 				}
    354 			}
    355 
    356 			update_option( $this->option_name, $option );
    357 
    358 			wp_send_json_success();
    359 		}
    360 
    361 		/**
    362 		 * This generates the markup for the notifications indicator if needed.
    363 		 *
    364 		 * @return string
    365 		 */
    366 		public function get_menu_count() {
    367 			if ( $this->get_count() > 0 ) {
    368 				return '<span class="seedprod-menu-notification-indicator"></span>';
    369 			}
    370 
    371 			return '';
    372 		}
    373 
    374 		/**
    375 		 * Retrieve the notifications via an ajax call.
    376 		 */
    377 		public function ajax_get_notifications() {
    378 
    379 			// Run a security check.
    380 			check_ajax_referer( 'sp-admin-nonce', 'nonce' );
    381 
    382 			$notifications_data = array(
    383 				'notifications' => $this->get(),
    384 				'view_url'      => $this->get_view_url(),
    385 			);
    386 
    387 			wp_send_json_success( $notifications_data );
    388 		}
    389 
    390 		/**
    391 		 * Get the URL for the page where users can see/read notifications.
    392 		 *
    393 		 * @return string
    394 		 */
    395 		public function get_view_url() {
    396 			$disabled = get_option( 'dashboards_disabled', false );
    397 
    398 			$url = add_query_arg( 'page', 'seedprod_reports', admin_url( 'admin.php' ) );
    399 
    400 			if ( false !== $disabled ) {
    401 				$url = is_multisite() ? network_admin_url( 'admin.php?page=seedprod_network' ) : admin_url( 'admin.php?page=seedprod_settings' );
    402 			}
    403 
    404 			return $url;
    405 		}
    406 	}
    407 }
    408 
    409 //add_action( 'seedprod_notification', array( 'SeedProd_Notifications', 'update' ) );
    410 if ( ! function_exists( 'seedprod_lite_do_notifications' ) ) {
    411 
    412 	add_action( 'seedprod_notifications', 'seedprod_lite_do_notifications' );
    413 	function seedprod_lite_do_notifications() {
    414 		$notifications = new SeedProd_Notifications();
    415 		$notifications->update();
    416 
    417 	}
    418 }