PluginProbe
MailPoet – Newsletters, Email Marketing, and Automation / 3.0.2
MailPoet – Newsletters, Email Marketing, and Automation v3.0.2
5.38.0 5.37.0 5.36.1 5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 All 542 releases
mailpoet / lib / Config / Menu.php

Menu.php in MailPoet – Newsletters, Email Marketing, and Automation 3.0.2, at lib/Config/Menu.php

702 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace MailPoet\Config;
4
5 use MailPoet\Cron\CronTrigger;
6 use MailPoet\Form\Block;
7 use MailPoet\Form\Renderer as FormRenderer;
8 use MailPoet\Helpscout\Beacon;
9 use MailPoet\Listing;
10 use MailPoet\Models\CustomField;
11 use MailPoet\Models\Form;
12 use MailPoet\Models\Segment;
13 use MailPoet\Models\Setting;
14 use MailPoet\Models\Subscriber;
15 use MailPoet\Newsletter\Shortcodes\ShortcodesHelper;
16 use MailPoet\Services\Bridge;
17 use MailPoet\Settings\Hosts;
18 use MailPoet\Settings\Pages;
19 use MailPoet\Subscribers\ImportExport\ImportExportFactory;
20 use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
21 use MailPoet\Util\License\License;
22 use MailPoet\WP\DateTime;
23 use MailPoet\WP\Notice as WPNotice;
24 use MailPoet\WP\Readme;
25
26 if(!defined('ABSPATH')) exit;
27
28 class Menu {
29 const MAIN_PAGE_SLUG = 'mailpoet-newsletters';
30
31 public $renderer;
32 public $assets_url;
33 private $access_control;
34 private $subscribers_over_limit;
35
36 function __construct($renderer, $assets_url, AccessControl $access_control) {
37 $this->renderer = $renderer;
38 $this->assets_url = $assets_url;
39 $this->access_control = $access_control;
40 $subscribers_feature = new SubscribersFeature();
41 $this->subscribers_over_limit = $subscribers_feature->check();
42 $this->checkMailPoetAPIKey();
43 $this->checkPremiumKey();
44 }
45
46 function init() {
47 add_action(
48 'admin_menu',
49 array(
50 $this,
51 'setup'
52 )
53 );
54 }
55
56 function setup() {
57 if(!$this->access_control->validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN)) return;
58 if(self::isOnMailPoetAdminPage()) {
59 do_action('mailpoet_conflict_resolver_styles');
60 do_action('mailpoet_conflict_resolver_scripts');
61
62 if($_REQUEST['page'] === 'mailpoet-newsletter-editor') {
63 // Disable WP emojis to not interfere with the newsletter editor emoji handling
64 $this->disableWPEmojis();
65 }
66 }
67
68 // Main page
69 add_menu_page(
70 'MailPoet',
71 'MailPoet',
72 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
73 self::MAIN_PAGE_SLUG,
74 null,
75 $this->assets_url . '/img/menu_icon.png',
76 30
77 );
78
79 // Emails page
80 $newsletters_page = add_submenu_page(
81 self::MAIN_PAGE_SLUG,
82 $this->setPageTitle(__('Emails', 'mailpoet')),
83 __('Emails', 'mailpoet'),
84 AccessControl::PERMISSION_MANAGE_EMAILS,
85 self::MAIN_PAGE_SLUG,
86 array(
87 $this,
88 'newsletters'
89 )
90 );
91
92 // add limit per page to screen options
93 add_action('load-' . $newsletters_page, function() {
94 add_screen_option('per_page', array(
95 'label' => _x(
96 'Number of newsletters per page',
97 'newsletters per page (screen options)',
98 'mailpoet'
99 ),
100 'option' => 'mailpoet_newsletters_per_page'
101 ));
102 });
103
104 // newsletter editor
105 add_submenu_page(
106 true,
107 $this->setPageTitle(__('Newsletter', 'mailpoet')),
108 __('Newsletter Editor', 'mailpoet'),
109 AccessControl::PERMISSION_MANAGE_EMAILS,
110 'mailpoet-newsletter-editor',
111 array(
112 $this,
113 'newletterEditor'
114 )
115 );
116
117 // Forms page
118 $forms_page = add_submenu_page(
119 self::MAIN_PAGE_SLUG,
120 $this->setPageTitle(__('Forms', 'mailpoet')),
121 __('Forms', 'mailpoet'),
122 AccessControl::PERMISSION_MANAGE_FORMS,
123 'mailpoet-forms',
124 array(
125 $this,
126 'forms'
127 )
128 );
129
130 // add limit per page to screen options
131 add_action('load-' . $forms_page, function() {
132 add_screen_option('per_page', array(
133 'label' => _x(
134 'Number of forms per page',
135 'forms per page (screen options)',
136 'mailpoet'
137 ),
138 'option' => 'mailpoet_forms_per_page'
139 ));
140 });
141
142 // form editor
143 add_submenu_page(
144 true,
145 $this->setPageTitle(__('Form Editor', 'mailpoet')),
146 __('Form Editor', 'mailpoet'),
147 AccessControl::PERMISSION_MANAGE_FORMS,
148 'mailpoet-form-editor',
149 array(
150 $this,
151 'formEditor'
152 )
153 );
154
155 // Subscribers page
156 $subscribers_page = add_submenu_page(
157 self::MAIN_PAGE_SLUG,
158 $this->setPageTitle(__('Subscribers', 'mailpoet')),
159 __('Subscribers', 'mailpoet'),
160 AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
161 'mailpoet-subscribers',
162 array(
163 $this,
164 'subscribers'
165 )
166 );
167
168 // add limit per page to screen options
169 add_action('load-' . $subscribers_page, function() {
170 add_screen_option('per_page', array(
171 'label' => _x(
172 'Number of subscribers per page',
173 'subscribers per page (screen options)',
174 'mailpoet'
175 ),
176 'option' => 'mailpoet_subscribers_per_page'
177 ));
178 });
179
180 // import
181 add_submenu_page(
182 'admin.php?page=mailpoet-subscribers',
183 $this->setPageTitle(__('Import', 'mailpoet')),
184 __('Import', 'mailpoet'),
185 AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
186 'mailpoet-import',
187 array(
188 $this,
189 'import'
190 )
191 );
192
193 // export
194 add_submenu_page(
195 true,
196 $this->setPageTitle(__('Export', 'mailpoet')),
197 __('Export', 'mailpoet'),
198 AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
199 'mailpoet-export',
200 array(
201 $this,
202 'export'
203 )
204 );
205
206 // Segments page
207 $segments_page = add_submenu_page(
208 self::MAIN_PAGE_SLUG,
209 $this->setPageTitle(__('Lists', 'mailpoet')),
210 __('Lists', 'mailpoet'),
211 AccessControl::PERMISSION_MANAGE_SEGMENTS,
212 'mailpoet-segments',
213 array(
214 $this,
215 'segments'
216 )
217 );
218
219 // add limit per page to screen options
220 add_action('load-' . $segments_page, function() {
221 add_screen_option('per_page', array(
222 'label' => _x(
223 'Number of segments per page',
224 'segments per page (screen options)',
225 'mailpoet'
226 ),
227 'option' => 'mailpoet_segments_per_page'
228 ));
229 });
230
231 // Settings page
232 add_submenu_page(
233 self::MAIN_PAGE_SLUG,
234 $this->setPageTitle(__('Settings', 'mailpoet')),
235 __('Settings', 'mailpoet'),
236 AccessControl::PERMISSION_MANAGE_SETTINGS,
237 'mailpoet-settings',
238 array(
239 $this,
240 'settings'
241 )
242 );
243
244 // Help page
245 add_submenu_page(
246 self::MAIN_PAGE_SLUG,
247 $this->setPageTitle(__('Help', 'mailpoet')),
248 __('Help', 'mailpoet'),
249 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
250 'mailpoet-help',
251 array(
252 $this,
253 'help'
254 )
255 );
256
257 // Premium page
258 // Only show this page in menu if the Premium plugin is not activated
259 add_submenu_page(
260 License::getLicense() ? true : self::MAIN_PAGE_SLUG,
261 $this->setPageTitle(__('Premium', 'mailpoet')),
262 __('Premium', 'mailpoet'),
263 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
264 'mailpoet-premium',
265 array(
266 $this,
267 'premium'
268 )
269 );
270
271 // Welcome page
272 add_submenu_page(
273 true,
274 $this->setPageTitle(__('Welcome', 'mailpoet')),
275 __('Welcome', 'mailpoet'),
276 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
277 'mailpoet-welcome',
278 array(
279 $this,
280 'welcome'
281 )
282 );
283
284 // Update page
285 add_submenu_page(
286 true,
287 $this->setPageTitle(__('Update', 'mailpoet')),
288 __('Update', 'mailpoet'),
289 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
290 'mailpoet-update',
291 array(
292 $this,
293 'update'
294 )
295 );
296
297 // Migration page
298 add_submenu_page(
299 true,
300 $this->setPageTitle(__('Migration', 'mailpoet')),
301 '',
302 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
303 'mailpoet-migration',
304 array(
305 $this,
306 'migration'
307 )
308 );
309 }
310
311 function disableWPEmojis() {
312 remove_action('admin_print_scripts', 'print_emoji_detection_script');
313 remove_action('admin_print_styles', 'print_emoji_styles');
314 }
315
316 function welcome() {
317 if((bool)(defined('DOING_AJAX') && DOING_AJAX)) return;
318
319 global $wp;
320 $current_url = home_url(add_query_arg($wp->query_string, $wp->request));
321 $redirect_url =
322 (!empty($_GET['mailpoet_redirect']))
323 ? urldecode($_GET['mailpoet_redirect'])
324 : wp_get_referer();
325
326 if(
327 $redirect_url === $current_url
328 or
329 strpos($redirect_url, 'mailpoet') === false
330 ) {
331 $redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
332 }
333
334 $data = array(
335 'settings' => Setting::getAll(),
336 'current_user' => wp_get_current_user(),
337 'redirect_url' => $redirect_url,
338 'sub_menu' => self::MAIN_PAGE_SLUG
339 );
340 $this->displayPage('welcome.html', $data);
341 }
342
343 function migration() {
344 $mp2_migrator = new MP2Migrator($this->access_control);
345 $mp2_migrator->init();
346 $data = array(
347 'log_file_url' => $mp2_migrator->log_file_url,
348 'progress_url' => $mp2_migrator->progressbar->url,
349 );
350 $this->displayPage('mp2migration.html', $data);
351 }
352
353 function update() {
354 global $wp;
355 $current_url = home_url(add_query_arg($wp->query_string, $wp->request));
356 $redirect_url =
357 (!empty($_GET['mailpoet_redirect']))
358 ? urldecode($_GET['mailpoet_redirect'])
359 : wp_get_referer();
360
361 if(
362 $redirect_url === $current_url
363 or
364 strpos($redirect_url, 'mailpoet') === false
365 ) {
366 $redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
367 }
368
369 $data = array(
370 'settings' => Setting::getAll(),
371 'current_user' => wp_get_current_user(),
372 'redirect_url' => $redirect_url,
373 'sub_menu' => self::MAIN_PAGE_SLUG
374 );
375
376 $readme_file = Env::$path . '/readme.txt';
377 if(is_readable($readme_file)) {
378 $changelog = Readme::parseChangelog(file_get_contents($readme_file), 1);
379 if($changelog) {
380 $data['changelog'] = $changelog;
381 }
382 }
383
384 $this->displayPage('update.html', $data);
385 }
386
387 function premium() {
388 $data = array(
389 'subscriber_count' => Subscriber::getTotalSubscribers(),
390 'sub_menu' => self::MAIN_PAGE_SLUG
391 );
392
393 $this->displayPage('premium.html', $data);
394 }
395
396
397 function settings() {
398 $settings = Setting::getAll();
399 $flags = $this->_getFlags();
400
401 // force MSS key check even if the method isn't active
402 $checker = new ServicesChecker();
403 $mp_api_key_valid = $checker->isMailPoetAPIKeyValid(false, true);
404
405 $data = array(
406 'settings' => $settings,
407 'segments' => Segment::getSegmentsWithSubscriberCount(),
408 'cron_trigger' => CronTrigger::getAvailableMethods(),
409 'total_subscribers' => Subscriber::getTotalSubscribers(),
410 'premium_plugin_active' => License::getLicense(),
411 'premium_key_valid' => !empty($this->premium_key_valid),
412 'mss_active' => Bridge::isMPSendingServiceEnabled(),
413 'mss_key_valid' => !empty($mp_api_key_valid),
414 'members_plugin_active' => is_plugin_active('members/members.php'),
415 'pages' => Pages::getAll(),
416 'flags' => $flags,
417 'current_user' => wp_get_current_user(),
418 'hosts' => array(
419 'web' => Hosts::getWebHosts(),
420 'smtp' => Hosts::getSMTPHosts()
421 )
422 );
423
424 $data = array_merge($data, Installer::getPremiumStatus());
425
426 $this->displayPage('settings.html', $data);
427 }
428
429 function help() {
430 $this->displayPage('help.html', array('data' => Beacon::getData()));
431 }
432
433 private function _getFlags() {
434 // flags (available features on WP install)
435 $flags = array();
436
437 if(is_multisite()) {
438 // get multisite registration option
439 $registration = apply_filters(
440 'wpmu_registration_enabled',
441 get_site_option('registration', 'all')
442 );
443
444 // check if users can register
445 $flags['registration_enabled'] =
446 !(in_array($registration, array(
447 'none',
448 'blog'
449 )));
450 } else {
451 // check if users can register
452 $flags['registration_enabled'] =
453 (bool)get_option('users_can_register', false);
454 }
455
456 return $flags;
457 }
458
459 function subscribers() {
460 $data = array();
461
462 $data['items_per_page'] = $this->getLimitPerPage('subscribers');
463 $data['segments'] = Segment::getSegmentsWithSubscriberCount($type = false);
464
465 $data['custom_fields'] = array_map(function($field) {
466 $field['params'] = unserialize($field['params']);
467
468 if(!empty($field['params']['values'])) {
469 $values = array();
470
471 foreach($field['params']['values'] as $value) {
472 $values[$value['value']] = $value['value'];
473 }
474 $field['params']['values'] = $values;
475 }
476 return $field;
477 }, CustomField::findArray());
478
479 $data['date_formats'] = Block\Date::getDateFormats();
480 $data['month_names'] = Block\Date::getMonthNames();
481
482 $data['premium_plugin_active'] = License::getLicense();
483
484 $this->displayPage('subscribers/subscribers.html', $data);
485 }
486
487 function segments() {
488 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
489
490 $data = array();
491 $data['items_per_page'] = $this->getLimitPerPage('segments');
492 $this->displayPage('segments.html', $data);
493 }
494
495 function forms() {
496 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
497
498 $data = array();
499
500 $data['items_per_page'] = $this->getLimitPerPage('forms');
501 $data['segments'] = Segment::findArray();
502
503 $this->displayPage('forms.html', $data);
504 }
505
506 function newsletters() {
507 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
508 if(isset($this->mp_api_key_valid) && $this->mp_api_key_valid === false) {
509 return $this->displayMailPoetAPIKeyInvalidTemplate();
510 }
511
512 global $wp_roles;
513
514 $data = array();
515
516 $data['items_per_page'] = $this->getLimitPerPage('newsletters');
517 $data['segments'] = Segment::getSegmentsWithSubscriberCount($type = false);
518 $data['settings'] = Setting::getAll();
519 $data['roles'] = $wp_roles->get_names();
520 $data['roles']['mailpoet_all'] = __('In any WordPress role', 'mailpoet');
521
522 $date_time = new DateTime();
523 $data['current_date'] = $date_time->getCurrentDate(DateTime::DEFAULT_DATE_FORMAT);
524 $data['current_time'] = $date_time->getCurrentTime();
525 $data['schedule_time_of_day'] = $date_time->getTimeInterval(
526 '00:00:00',
527 '+1 hour',
528 24
529 );
530
531 $data['tracking_enabled'] = Setting::getValue('tracking.enabled');
532
533 wp_enqueue_script('jquery-ui');
534 wp_enqueue_script('jquery-ui-datepicker');
535
536 $this->displayPage('newsletters.html', $data);
537 }
538
539 function newletterEditor() {
540 $data = array(
541 'shortcodes' => ShortcodesHelper::getShortcodes(),
542 'settings' => Setting::getAll(),
543 'current_wp_user' => Subscriber::getCurrentWPUser(),
544 'sub_menu' => self::MAIN_PAGE_SLUG,
545 'mss_active' => Bridge::isMPSendingServiceEnabled()
546 );
547 wp_enqueue_media();
548 wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
549 wp_enqueue_style('editor', includes_url('css/editor.css'));
550
551 $this->displayPage('newsletter/editor.html', $data);
552 }
553
554 function import() {
555 $import = new ImportExportFactory('import');
556 $data = $import->bootstrap();
557 $data = array_merge($data, array(
558 'date_types' => Block\Date::getDateTypes(),
559 'date_formats' => Block\Date::getDateFormats(),
560 'month_names' => Block\Date::getMonthNames(),
561 'sub_menu' => 'mailpoet-subscribers'
562 ));
563 $this->displayPage('subscribers/importExport/import.html', $data);
564 }
565
566 function export() {
567 $export = new ImportExportFactory('export');
568 $data = $export->bootstrap();
569 $data['sub_menu'] = 'mailpoet-subscribers';
570 $this->displayPage('subscribers/importExport/export.html', $data);
571 }
572
573 function formEditor() {
574 $id = (isset($_GET['id']) ? (int)$_GET['id'] : 0);
575 $form = Form::findOne($id);
576 if($form !== false) {
577 $form = $form->asArray();
578 }
579
580 $data = array(
581 'form' => $form,
582 'pages' => Pages::getAll(),
583 'segments' => Segment::getSegmentsWithSubscriberCount(),
584 'styles' => FormRenderer::getStyles($form),
585 'date_types' => Block\Date::getDateTypes(),
586 'date_formats' => Block\Date::getDateFormats(),
587 'month_names' => Block\Date::getMonthNames(),
588 'sub_menu' => 'mailpoet-forms'
589 );
590
591 $this->displayPage('form/editor.html', $data);
592 }
593
594 function setPageTitle($title) {
595 return sprintf(
596 '%s - %s',
597 __('MailPoet', 'mailpoet'),
598 $title
599 );
600 }
601
602 function displaySubscriberLimitExceededTemplate() {
603 $this->displayPage('limit.html', array(
604 'limit' => SubscribersFeature::SUBSCRIBERS_LIMIT
605 ));
606 exit;
607 }
608
609 function displayMailPoetAPIKeyInvalidTemplate() {
610 $this->displayPage('invalidkey.html', array(
611 'subscriber_count' => Subscriber::getTotalSubscribers()
612 ));
613 exit;
614 }
615
616 static function isOnMailPoetAdminPage(array $exclude = null, $screen_id = null) {
617 if(is_null($screen_id)) {
618 if(empty($_REQUEST['page'])) {
619 return false;
620 }
621 $screen_id = $_REQUEST['page'];
622 }
623 if(!empty($exclude)) {
624 foreach($exclude as $slug) {
625 if(stripos($screen_id, $slug) !== false) {
626 return false;
627 }
628 }
629 }
630 return (stripos($screen_id, 'mailpoet-') !== false);
631 }
632
633 /**
634 * This error page is used when the initialization is failed
635 * to display admin notices only
636 */
637 static function addErrorPage(AccessControl $access_control) {
638 if(!self::isOnMailPoetAdminPage()) {
639 return false;
640 }
641 // Check if page already exists
642 if(get_plugin_page_hook($_REQUEST['page'], '')
643 || get_plugin_page_hook($_REQUEST['page'], self::MAIN_PAGE_SLUG)
644 ) {
645 return false;
646 }
647 add_submenu_page(
648 true,
649 'MailPoet',
650 'MailPoet',
651 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
652 $_REQUEST['page'],
653 array(
654 __CLASS__,
655 'errorPageCallback'
656 )
657 );
658 }
659
660 static function errorPageCallback() {
661 // Used for displaying admin notices only
662 }
663
664 function checkMailPoetAPIKey(ServicesChecker $checker = null) {
665 if(self::isOnMailPoetAdminPage()) {
666 $show_notices = isset($_REQUEST['page'])
667 && stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
668 $checker = $checker ?: new ServicesChecker();
669 $this->mp_api_key_valid = $checker->isMailPoetAPIKeyValid($show_notices);
670 }
671 }
672
673 function checkPremiumKey(ServicesChecker $checker = null) {
674 $show_notices = isset($_SERVER['SCRIPT_NAME'])
675 && stripos($_SERVER['SCRIPT_NAME'], 'plugins.php') !== false;
676 $checker = $checker ?: new ServicesChecker();
677 $this->premium_key_valid = $checker->isPremiumKeyValid($show_notices);
678 }
679
680 private function getLimitPerPage($model = null) {
681 if($model === null) {
682 return Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
683 }
684
685 $listing_per_page = get_user_meta(
686 get_current_user_id(), 'mailpoet_' . $model . '_per_page', true
687 );
688 return (!empty($listing_per_page))
689 ? (int)$listing_per_page
690 : Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
691 }
692
693 private function displayPage($template, $data) {
694 try {
695 echo $this->renderer->render($template, $data);
696 } catch(\Exception $e) {
697 $notice = new WPNotice(WPNotice::TYPE_ERROR, $e->getMessage());
698 $notice->displayWPNotice();
699 }
700 }
701 }
702