• File: PushNotifications.php
  • Full Path: /home/slvgwrnz/public_html/wp-content/plugins/woocommerce/src/Internal/PushNotifications/PushNotifications.php
  • Date Modified: 10/26/2026 10:38 AM
  • File size: 5.5 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php

declare(strict_types=1);

namespace Automattic\WooCommerce\Internal\PushNotifications;

defined( 'ABSPATH' ) || exit;

use Automattic\WooCommerce\Internal\PushNotifications\Controllers\NotificationPreferencesRestController;
use Automattic\WooCommerce\Internal\PushNotifications\Controllers\PushNotificationRestController;
use Automattic\WooCommerce\Internal\PushNotifications\Controllers\PushNotificationStatusRestController;
use Automattic\WooCommerce\Internal\PushNotifications\Controllers\PushTokenRestController;
use Automattic\WooCommerce\Internal\PushNotifications\Controllers\StepLogRestController;
use Automattic\WooCommerce\Internal\PushNotifications\Entities\PushToken;
use Automattic\WooCommerce\Internal\PushNotifications\Services\DriverAvailabilityService;
use Automattic\WooCommerce\Internal\PushNotifications\Services\NotificationProcessor;
use Automattic\WooCommerce\Internal\PushNotifications\Services\NotificationRetryHandler;
use Automattic\WooCommerce\Internal\PushNotifications\Services\UserDataCleanupService;
use Automattic\WooCommerce\Internal\PushNotifications\Services\PendingNotificationStore;
use Automattic\WooCommerce\Internal\PushNotifications\Triggers\NewOrderNotificationTrigger;
use Automattic\WooCommerce\Internal\PushNotifications\Triggers\NewReviewNotificationTrigger;
use Automattic\WooCommerce\Internal\PushNotifications\Triggers\StockNotificationRecoveryHandler;
use Automattic\WooCommerce\Internal\PushNotifications\Triggers\StockNotificationTrigger;

/**
 * WC Push Notifications
 *
 * Class for setting up the WooCommerce-driven push notifications.
 *
 * @since 10.4.0
 */
class PushNotifications {
	/**
	 * Feature name for the push notifications feature.
	 */
	const FEATURE_NAME = 'push_notifications';

	/**
	 * Roles that can receive push notifications.
	 *
	 * This will be used to gate functionality access to just these roles.
	 */
	const ROLES_WITH_PUSH_NOTIFICATIONS_ENABLED = array(
		'administrator',
		'shop_manager',
	);

	/**
	 * 'Memoized' enablement flag.
	 *
	 * @var bool|null
	 */
	private ?bool $enabled = null;

	/**
	 * Registers initialisation tasks to the `init` hook.
	 *
	 * @return void
	 *
	 * @since 10.4.0
	 */
	public function register(): void {
		add_action( 'init', array( $this, 'on_init' ) );
	}

	/**
	 * Loads the push notifications class.
	 *
	 * @return void
	 *
	 * @since 10.6.0
	 */
	public function on_init(): void {
		// Registered ahead of the enablement check, so the status endpoint stays
		// available when push notifications are disabled and clients can discover
		// the state and fall back if needed.
		wc_get_container()->get( PushNotificationStatusRestController::class )->register();

		// Also registered ahead of the enablement check. Tokens stored while the
		// feature was on stay in the database once it is off, and a user deleted
		// in the meantime must not leave records behind for a later reconnection
		// to start sending against.
		wc_get_container()->get( UserDataCleanupService::class )->register();

		// Registered ahead of the enablement check so the token list can still be
		// read on a store that has been switched off. The controller registers the
		// write routes only while the module is enabled, like everything below.
		( new PushTokenRestController() )->register();

		// Registered ahead of the enablement check for the same reason: a store
		// is most worth reading the step log for once push notifications have
		// been switched off, which is often why they were switched off.
		wc_get_container()->get( StepLogRestController::class )->register();

		if ( ! $this->should_be_enabled() ) {
			return;
		}

		$this->register_post_types();

		wc_get_container()->get( PendingNotificationStore::class )->register();

		( new PushNotificationRestController() )->register();
		( new NotificationPreferencesRestController() )->register();
		( new NewOrderNotificationTrigger() )->register();
		( new NewReviewNotificationTrigger() )->register();
		( new StockNotificationTrigger() )->register();
		( new StockNotificationRecoveryHandler() )->register();

		wc_get_container()->get( NotificationProcessor::class )->register();
		wc_get_container()->get( NotificationRetryHandler::class )->register();
	}

	/**
	 * Registers the push token custom post type.
	 *
	 * @since 10.5.0
	 * @return void
	 */
	public function register_post_types(): void {
		register_post_type(
			PushToken::POST_TYPE,
			array(
				'labels'             => array(
					'name'          => __( 'Push Tokens', 'woocommerce' ),
					'singular_name' => __( 'Push Token', 'woocommerce' ),
				),
				'public'             => false,
				'publicly_queryable' => false,
				'show_ui'            => false,
				'show_in_menu'       => false,
				'query_var'          => false,
				'rewrite'            => false,
				'capability_type'    => 'post',
				'has_archive'        => false,
				'hierarchical'       => false,
				'supports'           => array( 'author' ),
				'can_export'         => false,
				'delete_with_user'   => true,
			)
		);
	}

	/**
	 * Determines if local push notification functionality should be enabled.
	 * The module runs on the remote proxy driver, so it is enabled exactly when
	 * that driver can send (feature not disabled and Jetpack connected). Memoize
	 * the value so we only check once per request.
	 *
	 * @return bool
	 *
	 * @since 10.4.0
	 */
	public function should_be_enabled(): bool {
		if ( null !== $this->enabled ) {
			return $this->enabled;
		}

		$this->enabled = wc_get_container()->get( DriverAvailabilityService::class )->is_remote_proxy_available();

		return $this->enabled;
	}
}