Pages
1 week ago
AssetsController.php
2 weeks ago
PageRenderer.php
2 months ago
index.php
3 years ago
PageRenderer.php
255 lines
| 1 | <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing |
| 2 | |
| 3 | namespace MailPoet\AdminPages; |
| 4 | |
| 5 | if (!defined('ABSPATH')) exit; |
| 6 | |
| 7 | |
| 8 | use MailPoet\AdminPages\Pages\WelcomeWizard; |
| 9 | use MailPoet\Cache\TransientCache; |
| 10 | use MailPoet\Config\Installer; |
| 11 | use MailPoet\Config\Menu; |
| 12 | use MailPoet\Config\Renderer; |
| 13 | use MailPoet\Config\ServicesChecker; |
| 14 | use MailPoet\Cron\Workers\SubscribersCountCacheRecalculation; |
| 15 | use MailPoet\Entities\SegmentEntity; |
| 16 | use MailPoet\Entities\TagEntity; |
| 17 | use MailPoet\Features\FeaturesController; |
| 18 | use MailPoet\Referrals\ReferralDetector; |
| 19 | use MailPoet\Segments\SegmentsRepository; |
| 20 | use MailPoet\Services\Bridge; |
| 21 | use MailPoet\Settings\SettingsController; |
| 22 | use MailPoet\Settings\TrackingConfig; |
| 23 | use MailPoet\Settings\UserFlagsController; |
| 24 | use MailPoet\Tags\TagRepository; |
| 25 | use MailPoet\Tracy\DIPanel\DIPanel; |
| 26 | use MailPoet\Util\Installation; |
| 27 | use MailPoet\Util\License\Features\CapabilitiesManager; |
| 28 | use MailPoet\Util\License\Features\Subscribers as SubscribersFeature; |
| 29 | use MailPoet\Util\License\License; |
| 30 | use MailPoet\WooCommerce; |
| 31 | use MailPoet\WP\Functions as WPFunctions; |
| 32 | use MailPoet\WP\Notice as WPNotice; |
| 33 | use MailPoetVendor\Carbon\Carbon; |
| 34 | use Tracy\Debugger; |
| 35 | |
| 36 | class PageRenderer { |
| 37 | /** @var Bridge */ |
| 38 | private $bridge; |
| 39 | |
| 40 | /** @var Renderer */ |
| 41 | private $renderer; |
| 42 | |
| 43 | /** @var ServicesChecker */ |
| 44 | private $servicesChecker; |
| 45 | |
| 46 | /** @var FeaturesController */ |
| 47 | private $featuresController; |
| 48 | |
| 49 | /** @var Installation */ |
| 50 | private $installation; |
| 51 | |
| 52 | /** @var SettingsController */ |
| 53 | private $settings; |
| 54 | |
| 55 | /** @var UserFlagsController */ |
| 56 | private $userFlags; |
| 57 | |
| 58 | /** @var SegmentsRepository */ |
| 59 | private $segmentRepository; |
| 60 | |
| 61 | private $tagRepository; |
| 62 | |
| 63 | /** @var SubscribersCountCacheRecalculation */ |
| 64 | private $subscribersCountCacheRecalculation; |
| 65 | |
| 66 | /** @var SubscribersFeature */ |
| 67 | private $subscribersFeature; |
| 68 | |
| 69 | /** @var TrackingConfig */ |
| 70 | private $trackingConfig; |
| 71 | |
| 72 | /** @var TransientCache */ |
| 73 | private $transientCache; |
| 74 | |
| 75 | /** @var WPFunctions */ |
| 76 | private $wp; |
| 77 | |
| 78 | /*** @var AssetsController */ |
| 79 | private $assetsController; |
| 80 | |
| 81 | /** @var WooCommerce\Helper */ |
| 82 | private $wooCommerceHelper; |
| 83 | |
| 84 | /** @var WooCommerce\WooCommerceSubscriptions\Helper */ |
| 85 | private $wooCommerceSubscriptionsHelper; |
| 86 | |
| 87 | private WooCommerce\WooCommerceBookings\Helper $wooCommerceBookingsHelper; |
| 88 | |
| 89 | private CapabilitiesManager $capabilitiesManager; |
| 90 | |
| 91 | public function __construct( |
| 92 | Bridge $bridge, |
| 93 | Renderer $renderer, |
| 94 | ServicesChecker $servicesChecker, |
| 95 | FeaturesController $featuresController, |
| 96 | Installation $installation, |
| 97 | SettingsController $settings, |
| 98 | UserFlagsController $userFlags, |
| 99 | SegmentsRepository $segmentRepository, |
| 100 | TagRepository $tagRepository, |
| 101 | SubscribersCountCacheRecalculation $subscribersCountCacheRecalculation, |
| 102 | SubscribersFeature $subscribersFeature, |
| 103 | TrackingConfig $trackingConfig, |
| 104 | TransientCache $transientCache, |
| 105 | WPFunctions $wp, |
| 106 | AssetsController $assetsController, |
| 107 | WooCommerce\Helper $wooCommerceHelper, |
| 108 | WooCommerce\WooCommerceSubscriptions\Helper $wooCommerceSubscriptionsHelper, |
| 109 | WooCommerce\WooCommerceBookings\Helper $wooCommerceBookingsHelper, |
| 110 | CapabilitiesManager $capabilitiesManager |
| 111 | ) { |
| 112 | $this->bridge = $bridge; |
| 113 | $this->renderer = $renderer; |
| 114 | $this->servicesChecker = $servicesChecker; |
| 115 | $this->featuresController = $featuresController; |
| 116 | $this->installation = $installation; |
| 117 | $this->settings = $settings; |
| 118 | $this->userFlags = $userFlags; |
| 119 | $this->segmentRepository = $segmentRepository; |
| 120 | $this->tagRepository = $tagRepository; |
| 121 | $this->subscribersCountCacheRecalculation = $subscribersCountCacheRecalculation; |
| 122 | $this->subscribersFeature = $subscribersFeature; |
| 123 | $this->trackingConfig = $trackingConfig; |
| 124 | $this->transientCache = $transientCache; |
| 125 | $this->wp = $wp; |
| 126 | $this->assetsController = $assetsController; |
| 127 | $this->wooCommerceHelper = $wooCommerceHelper; |
| 128 | $this->wooCommerceSubscriptionsHelper = $wooCommerceSubscriptionsHelper; |
| 129 | $this->wooCommerceBookingsHelper = $wooCommerceBookingsHelper; |
| 130 | $this->capabilitiesManager = $capabilitiesManager; |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Set common data for template and display template |
| 135 | * @param string $template |
| 136 | * @param array $data |
| 137 | */ |
| 138 | public function displayPage($template, array $data = []) { |
| 139 | $installer = new Installer(Installer::PREMIUM_PLUGIN_SLUG); |
| 140 | $premiumDownloadUrl = $this->subscribersFeature->hasValidPremiumKey() |
| 141 | ? $installer->generatePluginDownloadUrl() |
| 142 | : null; |
| 143 | |
| 144 | $wpSegment = $this->segmentRepository->getWPUsersSegment(); |
| 145 | $wpSegmentState = ($wpSegment instanceof SegmentEntity) && $wpSegment->getDeletedAt() === null ? |
| 146 | SegmentEntity::SEGMENT_ENABLED : SegmentEntity::SEGMENT_DISABLED; |
| 147 | $installedAtDiff = (new \DateTime($this->settings->get('installed_at')))->diff(new \DateTime()); |
| 148 | $subscriberCount = $this->subscribersFeature->getSubscribersCount(); |
| 149 | $subscribersCacheCreatedAt = Carbon::now(); |
| 150 | if ($this->subscribersFeature->isSubscribersCountEnoughForCache($subscriberCount)) { |
| 151 | $subscribersCacheCreatedAt = $this->transientCache->getOldestCreatedAt(TransientCache::SUBSCRIBERS_STATISTICS_COUNT_KEY) ?: Carbon::now(); |
| 152 | } |
| 153 | |
| 154 | $defaults = [ |
| 155 | 'current_page' => sanitize_text_field(wp_unslash(is_string($_GET['page'] ?? null) ? $_GET['page'] : '')), |
| 156 | 'site_name' => $this->wp->wpSpecialcharsDecode($this->wp->getOption('blogname'), ENT_QUOTES), |
| 157 | 'main_page' => Menu::MAIN_PAGE_SLUG, |
| 158 | 'site_url' => $this->wp->siteUrl(), |
| 159 | 'site_address' => $this->wp->wpParseUrl($this->wp->homeUrl(), PHP_URL_HOST), |
| 160 | 'feature_flags' => $this->featuresController->getAllFlags(), |
| 161 | 'referral_id' => $this->settings->get(ReferralDetector::REFERRAL_SETTING_NAME), |
| 162 | 'mailpoet_api_key_state' => $this->settings->get('mta.mailpoet_api_key_state'), |
| 163 | 'mta_method' => $this->settings->get('mta.method'), |
| 164 | 'premium_key_state' => $this->settings->get('premium.premium_key_state'), |
| 165 | 'wp_segment_state' => $wpSegmentState, |
| 166 | 'tracking_config' => $this->trackingConfig->getConfig(), |
| 167 | 'is_new_user' => $this->installation->isNewInstallation(), |
| 168 | 'installed_days_ago' => (int)$installedAtDiff->format('%a'), |
| 169 | 'deactivate_subscriber_after_inactive_days' => $this->settings->get('deactivate_subscriber_after_inactive_days'), |
| 170 | 'send_transactional_emails' => (bool)$this->settings->get('send_transactional_emails'), |
| 171 | 'transactional_emails_opt_in_notice_dismissed' => (bool)$this->userFlags->get('transactional_emails_opt_in_notice_dismissed'), |
| 172 | 'track_wizard_loaded_via_woocommerce' => (bool)$this->settings->get(WelcomeWizard::TRACK_LOADDED_VIA_WOOCOMMERCE_SETTING_NAME), |
| 173 | 'track_wizard_loaded_via_woocommerce_marketing_dashboard' => (bool)$this->settings->get(WelcomeWizard::TRACK_LOADDED_VIA_WOOCOMMERCE_MARKETING_DASHBOARD_SETTING_NAME), |
| 174 | // @phpstan-ignore-next-line function.alreadyNarrowedType -- is_callable() detects functions disabled at runtime via disable_functions |
| 175 | 'mail_function_enabled' => function_exists('mail') && is_callable('mail'), |
| 176 | 'admin_plugins_url' => WPFunctions::get()->adminUrl('plugins.php'), |
| 177 | |
| 178 | // Premium & plan upgrade info |
| 179 | 'current_wp_user_email' => $this->wp->wpGetCurrentUser()->user_email, |
| 180 | 'link_premium' => $this->wp->getSiteUrl(null, '/wp-admin/admin.php?page=mailpoet-upgrade'), |
| 181 | 'premium_plugin_installed' => Installer::isPluginInstalled(Installer::PREMIUM_PLUGIN_SLUG), |
| 182 | 'premium_plugin_active' => $this->servicesChecker->isPremiumPluginActive(), |
| 183 | 'premium_plugin_download_url' => $premiumDownloadUrl, |
| 184 | 'premium_plugin_activation_url' => $installer->generatePluginActivationUrl(Installer::PREMIUM_PLUGIN_PATH), |
| 185 | 'has_valid_api_key' => $this->subscribersFeature->hasValidApiKey(), |
| 186 | 'has_valid_premium_key' => $this->subscribersFeature->hasValidPremiumKey(), |
| 187 | 'has_premium_support' => $this->subscribersFeature->hasPremiumSupport(), |
| 188 | 'has_mss_key_specified' => Bridge::isMSSKeySpecified(), |
| 189 | 'mss_key_invalid' => $this->servicesChecker->isMailPoetAPIKeyValid() === false, |
| 190 | 'mss_key_valid' => $this->subscribersFeature->hasValidMssKey(), |
| 191 | 'mss_key_pending_approval' => $this->servicesChecker->isMailPoetAPIKeyPendingApproval(), |
| 192 | 'mss_active' => $this->bridge->isMailpoetSendingServiceEnabled(), |
| 193 | 'plugin_partial_key' => $this->servicesChecker->generatePartialApiKey(), |
| 194 | 'subscriber_count' => $subscriberCount, |
| 195 | 'subscribers_counts_cache_created_at' => $subscribersCacheCreatedAt->format('Y-m-d\TH:i:sO'), |
| 196 | 'subscribers_limit' => $this->subscribersFeature->getSubscribersLimit(), |
| 197 | 'subscribers_limit_reached' => $this->subscribersFeature->check(), |
| 198 | 'email_volume_limit' => $this->subscribersFeature->getEmailVolumeLimit(), |
| 199 | 'email_volume_limit_reached' => $this->subscribersFeature->checkEmailVolumeLimitIsReached(), |
| 200 | 'capabilities' => $this->capabilitiesManager->getCapabilities(), |
| 201 | 'tier' => $this->capabilitiesManager->getTier(), |
| 202 | 'urls' => [ |
| 203 | 'automationListing' => admin_url('admin.php?page=mailpoet-automation'), |
| 204 | 'automationEditor' => admin_url('admin.php?page=mailpoet-automation-editor'), |
| 205 | 'automationTemplates' => admin_url('admin.php?page=mailpoet-automation-templates'), |
| 206 | 'automationAnalytics' => admin_url('admin.php?page=mailpoet-automation-analytics'), |
| 207 | ], |
| 208 | 'woocommerce_store_config' => $this->wooCommerceHelper->isWooCommerceActive() ? $this->wooCommerceHelper->getWoocommerceStoreConfig() : null, |
| 209 | 'tags' => array_map(function (TagEntity $tag): array { |
| 210 | return [ |
| 211 | 'id' => $tag->getId(), |
| 212 | 'name' => $tag->getName(), |
| 213 | ]; |
| 214 | }, $this->tagRepository->findAll()), |
| 215 | 'display_chatbot_widget' => $this->displayChatBotWidget(), |
| 216 | 'is_woocommerce_subscriptions_active' => $this->wooCommerceSubscriptionsHelper->isWooCommerceSubscriptionsActive(), |
| 217 | 'is_woocommerce_bookings_active' => $this->wooCommerceBookingsHelper->isWooCommerceBookingsActive(), |
| 218 | 'cron_trigger_method' => $this->settings->get('cron_trigger.method'), |
| 219 | ]; |
| 220 | |
| 221 | if (!$defaults['premium_plugin_active']) { |
| 222 | $defaults['free_premium_subscribers_limit'] = License::FREE_PREMIUM_SUBSCRIBERS_LIMIT; |
| 223 | } |
| 224 | |
| 225 | try { |
| 226 | if ( |
| 227 | class_exists(Debugger::class) |
| 228 | && class_exists(DIPanel::class) |
| 229 | ) { |
| 230 | DIPanel::init(); |
| 231 | } |
| 232 | if ($this->wp->isAdmin() && $this->subscribersCountCacheRecalculation->shouldBeScheduled()) { |
| 233 | $this->subscribersCountCacheRecalculation->schedule(); |
| 234 | } |
| 235 | |
| 236 | // If the page didn't enqueue any assets, this will act as a fallback. |
| 237 | // If some assets were enqueued, this won't change the queue ordering. |
| 238 | $this->assetsController->setupAdminPagesDependencies(); |
| 239 | $this->wp->doAction('mailpoet_styles_admin_after'); |
| 240 | |
| 241 | // We are in control of the template and the data can be considered safe at this point |
| 242 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 243 | echo $this->renderer->render($template, $data + $defaults); |
| 244 | } catch (\Exception $e) { |
| 245 | $notice = new WPNotice(WPNotice::TYPE_ERROR, $e->getMessage()); |
| 246 | $notice->displayWPNotice(); |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | public function displayChatBotWidget(): bool { |
| 251 | $display = $this->wp->applyFilters('mailpoet_display_docsbot_widget', $this->settings->get('3rd_party_libs.enabled') === '1'); |
| 252 | return (bool)$display; |
| 253 | } |
| 254 | } |
| 255 |