JezK
Edit File: class-clever-reach-frontend-controller.php
<?php /** * CleverReach WordPress Integration. * * @package CleverReach */ namespace CleverReach\WordPress\Controllers; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } use CleverReach\WordPress\Components\InfrastructureServices\Config_Service; use CleverReach\WordPress\Components\Sync\Default_Newsletter_Status_Sync_Task; use CleverReach\WordPress\Components\Sync\Initial_Sync_Task; use CleverReach\WordPress\Components\Utility\Helper; use CleverReach\WordPress\Components\Utility\Task_Queue; use CleverReach\WordPress\IntegrationCore\BusinessLogic\Entity\TagCollection; use CleverReach\WordPress\IntegrationCore\BusinessLogic\Interfaces\Recipients; use CleverReach\WordPress\IntegrationCore\BusinessLogic\Proxy\AuthProxy; use CleverReach\WordPress\IntegrationCore\BusinessLogic\Surveys\SurveyType; use CleverReach\WordPress\IntegrationCore\BusinessLogic\Utility\SingleSignOn\SingleSignOnProvider; use CleverReach\WordPress\IntegrationCore\Infrastructure\Interfaces\Required\Configuration; use CleverReach\WordPress\IntegrationCore\Infrastructure\Logger\Logger; use CleverReach\WordPress\IntegrationCore\Infrastructure\ServiceRegister; use CleverReach\WordPress\IntegrationCore\Infrastructure\TaskExecution\Exceptions\QueueStorageUnavailableException; use CleverReach\WordPress\IntegrationCore\Infrastructure\TaskExecution\Queue; use CleverReach\WordPress\IntegrationCore\Infrastructure\TaskExecution\QueueItem; /** * Class Clever_Reach_Frontend_Controller * * @package CleverReach\WordPress\Controllers */ class Clever_Reach_Frontend_Controller extends Clever_Reach_Base_Controller { const CURL_NOT_ENABLED_STATE_CODE = 'curl-not-enabled'; const WELCOME_STATE_CODE = 'welcome'; const INITIAL_SYNC_STATE_CODE = 'initial-sync'; const INITIAL_SYNC_SETTINGS_STATE_CODE = 'initial-sync-settings'; const TOKEN_EXPIRED_STATE_CODE = 'token-expired'; const DASHBOARD_STATE_CODE = 'dashboard'; const GROUP_DELETED_STATE_CODE = 'group-deleted'; const CLEVERREACH_HELP_URL = 'https://support.cleverreach.de/hc/en-us'; const CLEVERREACH_DASHBOARD_URL = '/admin'; const CLEVERREACH_GDPR_URL = 'https://www.cleverreach.com/en/features/privacy-security/eu-general-data-protection-regulation-gdpr/'; const SCRIPT_VERSION = 9; /** * Configuration service * * @var Config_Service */ private $config_service; /** * Queue service * * @var Queue */ private $queue_service; /** * Proxy service * * @var AuthProxy */ private $proxy; /** * Plugin page * * @var string */ private $page; /** * CleverReachFrontendController constructor */ public function __construct() { $this->load_global_css(); $this->load_global_js(); } /** * Renders appropriate view */ public function render() { $this->set_page(); $this->load_css(); $this->load_js(); Task_Queue::wakeup(); if ( self::WELCOME_STATE_CODE !== $this->page ) { include dirname( __DIR__ ) . '/resources/views/wrapper-start.php'; } include dirname( __DIR__ ) . '/resources/views/' . $this->page . '.php'; include dirname( __DIR__ ) . '/resources/views/wrapper-end.php'; } /** * Marks that first email is built */ public function build_first_email() { $this->get_config_service()->setIsFirstEmailBuilt( '1' ); $this->die_json( array( 'status' => 'success' ) ); } /** * Saves initial sync settings */ public function set_initial_sync_settings() { $newsletter_status = $this->get_param( 'newsletterStatus' ); $this->get_config_service()->set_default_newsletter_status( $newsletter_status ); try { Task_Queue::enqueue( new Default_Newsletter_Status_Sync_Task(), true ); } catch ( QueueStorageUnavailableException $e ) { $this->get_config_service()->set_default_newsletter_status( '' ); $error_message = 'Error starting default newsletter task: ' . $e->getMessage(); Logger::logError( $error_message ); $this->die_json( array( 'status' => 'failed', 'message' => $error_message, ) ); } $this->die_json( array( 'status' => 'success' ) ); } /** * Retry initial synchronization */ public function retry_sync() { try { $this->get_queue_service()->enqueue( $this->get_config_service()->getQueueName(), new Initial_Sync_Task() ); } catch ( QueueStorageUnavailableException $e ) { Logger::logError( 'Error restarting sync: ' . $e->getMessage() ); $this->die_json( array( 'status' => 'failed' ) ); } $this->die_json( array( 'status' => 'success' ) ); } /** * Gets configuration for welcome page * * @return array * * @throws \Exception */ public function get_welcome_config() { $redirect_url = Helper::get_auth_redirect_url(); $register_data = base64_encode( wp_json_encode( Helper::get_register_data() ) ); $user_language = explode( '_', Helper::get_site_language() ); $trigger_type = $this->get_trigger_type(); if ( ! $this->get_config_service()->is_plugin_opened_for_the_first_time() ) { $this->get_config_service()->set_plugin_opened_for_the_first_time( true ); } return array( 'checkStatusUrl' => Helper::get_controller_url( 'Check_Status', array( 'action' => 'refresh_user_info' ) ), 'authUrl' => $this->get_proxy_service()->getAuthUrl( $redirect_url, $register_data, array( 'lang' => $user_language[ 0 ] ) ), 'triggerType' => $trigger_type, 'surveyUrl' => Helper::get_controller_url( 'Survey', array( 'action' => 'handle' ) ), 'ignoreSurveyUrl' => Helper::get_controller_url( 'Survey', array( 'action' => 'ignore' ) ), ); } /** * Gets configuration for dashboard page * * @return array * * @throws \Exception */ public function get_dashboard_config() { $user_info = $this->get_config_service()->getUserInfo(); $failure_parameters = $this->get_initial_sync_failure_parameters(); $import_statistics_displayed = $this->get_config_service()->isImportStatisticsDisplayed(); $trigger_type = $this->get_trigger_type( $import_statistics_displayed ); $recipient_sync_enabled = $this->get_config_service()->is_recipient_sync_enabled(); $tags = new TagCollection(); if ( ! $import_statistics_displayed ) { if ( $recipient_sync_enabled ) { $recipient_service = ServiceRegister::getService( Recipients::CLASS_NAME ); $tags = $recipient_service->getAllTags(); } $this->get_config_service()->setImportStatisticsDisplayed( true ); } return array( 'logoUrl' => Helper::get_clever_reach_base_url( '/resources/images/icon_quickstartmailing.svg' ), 'buildFirstEmailUrl' => Helper::get_controller_url( 'Frontend', array( 'action' => 'build_first_email' ) ), 'retrySyncUrl' => Helper::get_controller_url( 'Frontend', array( 'action' => 'retry_sync' ) ), 'importStatisticsDisplayed' => $import_statistics_displayed, 'numberOfSyncedRecipients' => ! $import_statistics_displayed ? $this->get_config_service()->getNumberOfSyncedRecipients() : 0, 'tags' => $tags, 'recipientId' => $user_info[ 'id' ], 'helpUrl' => self::CLEVERREACH_HELP_URL, 'gdprUrl' => self::CLEVERREACH_GDPR_URL, 'buildEmailUrl' => SingleSignOnProvider::getUrl( self::CLEVERREACH_DASHBOARD_URL ), 'isFirstEmailBuilt' => $this->get_config_service()->isFirstEmailBuilt(), 'integrationName' => $this->get_config_service()->getIntegrationListName(), 'isInitialSyncTaskFailed' => $failure_parameters[ 'isFailed' ], 'initialSyncTaskFailureMessage' => $failure_parameters[ 'description' ], 'triggerType' => $trigger_type, 'surveyUrl' => Helper::get_controller_url( 'Survey', array( 'action' => 'handle' ) ), 'ignoreSurveyUrl' => Helper::get_controller_url( 'Survey', array( 'action' => 'ignore' ) ), 'recipientSyncEnabled' => $recipient_sync_enabled, ); } /** * Gets configuration for token expired page * * @return array */ public function get_token_expired_config() { $user_info = $this->get_config_service()->getUserInfo(); $redirect_url = Helper::get_refresh_auth_redirect_url(); $register_data = base64_encode( wp_json_encode( Helper::get_register_data() ) ); $user_language = explode( '_', Helper::get_site_language() ); $message = ''; $refresh_token = $this->get_config_service()->getRefreshToken(); if ( ! empty( $refresh_token ) ) { $connection_status_response = $this->get_proxy_service()->checkConnectionStatus(); $message = $connection_status_response->getMessage(); } return array( 'logoUrl' => Helper::get_clever_reach_base_url( '/resources/images/icon_quickstartmailing.svg' ), 'checkStatusUrl' => Helper::get_controller_url( 'Check_Status', array( 'action' => 'refresh_user_info' ) ), 'authUrl' => $this->get_proxy_service()->getAuthUrl( $redirect_url, $register_data, array( 'lang' => $user_language[ 0 ] ) ) . '#login', 'clientId' => $user_info[ 'id' ], 'apiMessage' => $message, ); } /** * Gets configuration for initial sync settings page * * @return array * * @throws \Exception */ public function get_initial_sync_settings_config() { $user_info = $this->get_config_service()->getUserInfo(); $config = array( 'helloUrl' => Helper::get_clever_reach_base_url( '/resources/images/icon_' . __( 'hello', 'cleverreach-wp' ) . '.png' ), 'helpUrl' => self::CLEVERREACH_HELP_URL, 'recipientId' => $user_info[ 'id' ], 'configurationUrl' => Helper::get_controller_url( 'Frontend', array( 'action' => 'set_initial_sync_settings' ) ), 'hasSubscriberRole' => ! is_null( get_role( 'subscriber' ) ), ); return $config; } /** * Gets configuration for initial sync page * * @return array * * @throws \Exception */ public function get_initial_sync_config() { $recipient_sync_enabled = $this->get_config_service()->is_recipient_sync_enabled(); return array( 'statusCheckUrl' => Helper::get_controller_url( 'Check_Status', array( 'action' => 'initial_sync' ) ), 'integrationName' => $this->get_config_service()->getIntegrationName(), 'recipientSyncEnabled' => $recipient_sync_enabled, ); } /** * Gets configuration for initial sync page * * @return array * * @throws \Exception */ public function get_group_deleted_config() { $redirect_url = Helper::get_auth_redirect_url(); $register_data = base64_encode( wp_json_encode( Helper::get_register_data() ) ); $user_language = explode( '_', Helper::get_site_language() ); return array( 'logoUrl' => Helper::get_clever_reach_base_url( '/resources/images/icon_quickstartmailing.svg' ), 'checkStatusUrl' => Helper::get_controller_url( 'Check_Status', array( 'action' => 'refresh_user_info' ) ), 'authUrl' => $this->get_proxy_service()->getAuthUrl( $redirect_url, $register_data, array( 'lang' => $user_language[ 0 ] ) ) . '#login' ); } /** * Wraps tags into segments and prepares them for rendering. * * @param TagCollection $tags All tags in the system. * * @return string HTML prepared segment list. */ public function build_segments( $tags ) { $segment_list = ''; foreach ( $tags as $index => $tag ) { if ( 3 === $index ) { $segment_list .= '<div class="value">...</div>'; break; } $first = ( $index + 1 ) . ') ' . substr( $tag->getTitle(), 0, - 3 ); $last = substr( $tag->getTitle(), strlen( $tag->getTitle() ) - 3 ); $segment_list .= '<div class="value" title="' . $tag->getTitle() . '">' . '<span class="cr-first-part">' . $first . '</span>' . '<span class="cr-last-part">' . $last . '</span>' . '</div>'; } return $segment_list; } /** * Set current page code */ private function set_page() { if ( ! Helper::is_curl_enabled() ) { $this->page = self::CURL_NOT_ENABLED_STATE_CODE; } elseif ( $this->get_config_service()->is_group_connected() === '0' ) { $this->page = self::GROUP_DELETED_STATE_CODE; } elseif ( ! $this->is_auth_token_valid() ) { $this->page = self::WELCOME_STATE_CODE; } elseif ( ! $this->is_initial_sync_config_set() && $this->get_config_service()->is_recipient_sync_enabled() ) { $this->page = self::INITIAL_SYNC_SETTINGS_STATE_CODE; } elseif ( $this->is_initial_sync_in_progress() ) { $this->page = self::INITIAL_SYNC_STATE_CODE; } elseif ( ! $this->check_if_refresh_token_exists() || ! $this->is_token_alive() ) { $this->page = self::TOKEN_EXPIRED_STATE_CODE; } else { $this->page = self::DASHBOARD_STATE_CODE; } if ( ( ! empty( $_REQUEST[ 'notification_type' ] ) ) && 'user_offline' === $_REQUEST[ 'notification_type' ] && ! in_array( $this->page, array( self::INITIAL_SYNC_SETTINGS_STATE_CODE, self::INITIAL_SYNC_STATE_CODE ), true ) ) { $this->get_config_service()->set_show_oauth_connection_lost_notice( false ); } } /** * Loads css that is used outside CleverReach pages. */ public function load_global_css() { $base_url = Helper::get_clever_reach_base_url( '/resources/' ); wp_enqueue_style( 'wp-cleverreach-global-admin-styles', $base_url . 'css/cleverreach.css', array(), self::SCRIPT_VERSION ); } /** * Loads all css files needed for plugin */ public function load_css() { $base_url = Helper::get_clever_reach_base_url( '/resources/' ); wp_enqueue_style( 'wp-cleverreach-global-admin-icofont', $base_url . 'css/cleverreach-icofont.css', array(), self::SCRIPT_VERSION ); wp_enqueue_style( 'wp-cleverreach-survey-styles', $base_url . 'css/cr-survey.css', array(), self::SCRIPT_VERSION ); wp_enqueue_style( 'font-awesome', 'https://use.fontawesome.com/releases/v5.5.0/css/all.css', array(), self::SCRIPT_VERSION ); if ( in_array( $this->page, array( self::WELCOME_STATE_CODE, self::TOKEN_EXPIRED_STATE_CODE, self::GROUP_DELETED_STATE_CODE ), true ) ) { wp_enqueue_style( 'wp-cleverreach-auth-iframe-style', $base_url . 'css/cleverreach-auth-iframe.css', array(), self::SCRIPT_VERSION ); } } /** * Loads JS that is used outside CleverReach pages. */ private function load_global_js() { $base_url = Helper::get_clever_reach_base_url( '/resources/' ); wp_enqueue_script( 'wp_cr_ajax', esc_url( $base_url . 'js/cleverreach.ajax.js' ), array(), self::SCRIPT_VERSION, true ); } /** * Loads JS script for the current page */ private function load_js() { $base_url = Helper::get_clever_reach_base_url( '/resources/' ); wp_enqueue_script( 'wp_cr_authorization', esc_url( $base_url . 'js/cleverreach.authorization.js' ), array(), self::SCRIPT_VERSION, true ); wp_enqueue_script( 'wp_cr_status_checker', esc_url( $base_url . 'js/cleverreach.status-checker.js' ), array(), self::SCRIPT_VERSION, true ); wp_enqueue_script( 'wp_cr_survey', esc_url( $base_url . 'js/cleverreach.survey.js' ), array(), self::SCRIPT_VERSION, true ); if ( self::GROUP_DELETED_STATE_CODE === $this->page || self::TOKEN_EXPIRED_STATE_CODE === $this->page ) { wp_enqueue_script( "wp_cr_token-expired", esc_url( $base_url . "js/cleverreach.token-expired.js" ), array(), self::SCRIPT_VERSION, true ); return; } if ( self::WELCOME_STATE_CODE !== $this->page ) { wp_enqueue_script( "wp_cr_$this->page", esc_url( $base_url . "js/cleverreach.$this->page.js" ), array(), self::SCRIPT_VERSION, true ); } if ( self::DASHBOARD_STATE_CODE === $this->page ) { wp_enqueue_script( 'wp_cr_forms', esc_url( $base_url . 'js/cleverreach.forms.js' ), array(), self::SCRIPT_VERSION, true ); wp_enqueue_script( 'wp_cr_integrations', esc_url( $base_url . 'js/cleverreach.integrations.js' ), array(), self::SCRIPT_VERSION, true ); wp_localize_script( 'wp_cr_forms', 'cleverreachForms', array( 'forms_endpoint_url' => Helper::get_controller_url( 'Forms', array( 'action' => 'get_all_forms' ) ), 'integration_name' => $this->get_config_service()->getIntegrationName(), 'edit_in_cleverreach_text' => __( 'Edit in CleverReach®', 'cleverreach-wp' ), ) ); wp_localize_script( 'wp_cr_integrations', 'cleverreachIntegrations', array( 'integrations_endpoint_url' => Helper::get_controller_url( 'Integrations', array( 'action' => 'get_all_integrations' ) ), 'integration_manual_text' => __( 'How to use?', 'cleverreach-wp' ), ) ); } } /** * Gets fail parameters for initial sync task if it failed * * @return array */ private function get_initial_sync_failure_parameters() { $params = array( 'isFailed' => false, 'description' => '', ); /** * Initial sync task * * @var QueueItem $initial_sync_task */ $initial_sync_task = $this->get_queue_service()->findLatestByType( 'Initial_Sync_Task' ); if ( $initial_sync_task && $initial_sync_task->getStatus() === QueueItem::FAILED ) { $params = array( 'isFailed' => true, 'description' => $initial_sync_task->getFailureDescription(), ); } return $params; } /** * Checks if auth token is valid * * @return bool */ private function is_auth_token_valid() { $access_token = $this->get_config_service()->getAccessToken(); return ! empty( $access_token ); } /** * Checks if initial sync configuration is set * * @return bool */ private function is_initial_sync_config_set() { $default_newsletter_status = $this->get_config_service()->get_default_newsletter_status(); return null !== $default_newsletter_status && '' !== $default_newsletter_status; } /** * Checks if initial sync is in progress * * @return bool */ private function is_initial_sync_in_progress() { /** * Initial sync task * * @var QueueItem $initial_sync_task_item */ $initial_sync_task_item = $this->get_queue_service()->findLatestByType( 'Initial_Sync_Task' ); if ( ! $initial_sync_task_item ) { try { $this->get_queue_service()->enqueue( $this->get_config_service()->getQueueName(), new Initial_Sync_Task() ); } catch ( QueueStorageUnavailableException $e ) { return true; } return true; } return $initial_sync_task_item->getStatus() !== QueueItem::COMPLETED && $initial_sync_task_item->getStatus() !== QueueItem::FAILED; } /** * Returns survey form trigger type. * * @param bool $import_statistics_displayed Whether import statistics are displayed or not. * * @return string */ private function get_trigger_type( $import_statistics_displayed = false ) { if ( self::WELCOME_STATE_CODE === $this->page && ! $this->get_config_service()->is_plugin_opened_for_the_first_time() ) { return SurveyType::PLUGIN_INSTALLED; } if ( self::DASHBOARD_STATE_CODE === $this->page && ! $import_statistics_displayed ) { return SurveyType::INITIAL_SYNC_FINISHED; } return SurveyType::PERIODIC; } /** * Checks if refresh token exists in the database * * @return bool */ private function check_if_refresh_token_exists() { return null !== $this->get_config_service()->getRefreshToken(); } /** * Checks whether auth token is alive and accessible. * * @return bool */ private function is_token_alive() { return $this->get_proxy_service()->isConnected(); } /** * Gets config service * * @return Config_Service */ private function get_config_service() { if ( empty( $this->config_service ) ) { $this->config_service = ServiceRegister::getService( Configuration::CLASS_NAME ); } return $this->config_service; } /** * Gets queue service * * @return Queue */ private function get_queue_service() { if ( empty( $this->queue_service ) ) { $this->queue_service = ServiceRegister::getService( Queue::CLASS_NAME ); } return $this->queue_service; } /** * Gets proxy service * * @return AuthProxy */ private function get_proxy_service() { if ( empty( $this->proxy ) ) { $this->proxy = ServiceRegister::getService( AuthProxy::CLASS_NAME ); } return $this->proxy; } }