PluginProbe
MailPoet – Newsletters, Email Marketing, and Automation / 3.0.8
MailPoet – Newsletters, Email Marketing, and Automation v3.0.8
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.8, at lib/Config/Menu.php

715 lines 19.5 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 do_action('mailpoet_menu_after_lists');
232
233 // Settings page
234 add_submenu_page(
235 self::MAIN_PAGE_SLUG,
236 $this->setPageTitle(__('Settings', 'mailpoet')),
237 __('Settings', 'mailpoet'),
238 AccessControl::PERMISSION_MANAGE_SETTINGS,
239 'mailpoet-settings',
240 array(
241 $this,
242 'settings'
243 )
244 );
245
246 // Help page
247 add_submenu_page(
248 self::MAIN_PAGE_SLUG,
249 $this->setPageTitle(__('Help', 'mailpoet')),
250 __('Help', 'mailpoet'),
251 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
252 'mailpoet-help',
253 array(
254 $this,
255 'help'
256 )
257 );
258
259 // Premium page
260 // Only show this page in menu if the Premium plugin is not activated
261 add_submenu_page(
262 License::getLicense() ? true : self::MAIN_PAGE_SLUG,
263 $this->setPageTitle(__('Premium', 'mailpoet')),
264 __('Premium', 'mailpoet'),
265 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
266 'mailpoet-premium',
267 array(
268 $this,
269 'premium'
270 )
271 );
272
273 // Welcome page
274 add_submenu_page(
275 true,
276 $this->setPageTitle(__('Welcome', 'mailpoet')),
277 __('Welcome', 'mailpoet'),
278 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
279 'mailpoet-welcome',
280 array(
281 $this,
282 'welcome'
283 )
284 );
285
286 // Update page
287 add_submenu_page(
288 true,
289 $this->setPageTitle(__('Update', 'mailpoet')),
290 __('Update', 'mailpoet'),
291 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
292 'mailpoet-update',
293 array(
294 $this,
295 'update'
296 )
297 );
298
299 // Migration page
300 add_submenu_page(
301 true,
302 $this->setPageTitle(__('Migration', 'mailpoet')),
303 '',
304 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
305 'mailpoet-migration',
306 array(
307 $this,
308 'migration'
309 )
310 );
311 }
312
313 function disableWPEmojis() {
314 remove_action('admin_print_scripts', 'print_emoji_detection_script');
315 remove_action('admin_print_styles', 'print_emoji_styles');
316 }
317
318 function welcome() {
319 if((bool)(defined('DOING_AJAX') && DOING_AJAX)) return;
320
321 global $wp;
322 $current_url = home_url(add_query_arg($wp->query_string, $wp->request));
323 $redirect_url =
324 (!empty($_GET['mailpoet_redirect']))
325 ? urldecode($_GET['mailpoet_redirect'])
326 : wp_get_referer();
327
328 if(
329 $redirect_url === $current_url
330 or
331 strpos($redirect_url, 'mailpoet') === false
332 ) {
333 $redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
334 }
335
336 $data = array(
337 'settings' => Setting::getAll(),
338 'current_user' => wp_get_current_user(),
339 'redirect_url' => $redirect_url,
340 'sub_menu' => self::MAIN_PAGE_SLUG
341 );
342 $this->displayPage('welcome.html', $data);
343 }
344
345 function migration() {
346 $mp2_migrator = new MP2Migrator($this->access_control);
347 $mp2_migrator->init();
348 $data = array(
349 'log_file_url' => $mp2_migrator->log_file_url,
350 'progress_url' => $mp2_migrator->progressbar->url,
351 );
352 $this->displayPage('mp2migration.html', $data);
353 }
354
355 function update() {
356 global $wp;
357 $current_url = home_url(add_query_arg($wp->query_string, $wp->request));
358 $redirect_url =
359 (!empty($_GET['mailpoet_redirect']))
360 ? urldecode($_GET['mailpoet_redirect'])
361 : wp_get_referer();
362
363 if(
364 $redirect_url === $current_url
365 or
366 strpos($redirect_url, 'mailpoet') === false
367 ) {
368 $redirect_url = admin_url('admin.php?page=' . self::MAIN_PAGE_SLUG);
369 }
370
371 $data = array(
372 'settings' => Setting::getAll(),
373 'current_user' => wp_get_current_user(),
374 'redirect_url' => $redirect_url,
375 'sub_menu' => self::MAIN_PAGE_SLUG
376 );
377
378 $readme_file = Env::$path . '/readme.txt';
379 if(is_readable($readme_file)) {
380 $changelog = Readme::parseChangelog(file_get_contents($readme_file), 1);
381 if($changelog) {
382 $data['changelog'] = $changelog;
383 }
384 }
385
386 $this->displayPage('update.html', $data);
387 }
388
389 function premium() {
390 $data = array(
391 'subscriber_count' => Subscriber::getTotalSubscribers(),
392 'sub_menu' => self::MAIN_PAGE_SLUG
393 );
394
395 $this->displayPage('premium.html', $data);
396 }
397
398
399 function settings() {
400 $settings = Setting::getAll();
401 $flags = $this->_getFlags();
402
403 // force MSS key check even if the method isn't active
404 $checker = new ServicesChecker();
405 $mp_api_key_valid = $checker->isMailPoetAPIKeyValid(false, true);
406
407 $data = array(
408 'settings' => $settings,
409 'segments' => Segment::getSegmentsWithSubscriberCount(),
410 'cron_trigger' => CronTrigger::getAvailableMethods(),
411 'total_subscribers' => Subscriber::getTotalSubscribers(),
412 'premium_plugin_active' => License::getLicense(),
413 'premium_key_valid' => !empty($this->premium_key_valid),
414 'mss_active' => Bridge::isMPSendingServiceEnabled(),
415 'mss_key_valid' => !empty($mp_api_key_valid),
416 'members_plugin_active' => is_plugin_active('members/members.php'),
417 'pages' => Pages::getAll(),
418 'flags' => $flags,
419 'current_user' => wp_get_current_user(),
420 'hosts' => array(
421 'web' => Hosts::getWebHosts(),
422 'smtp' => Hosts::getSMTPHosts()
423 )
424 );
425
426 $data = array_merge($data, Installer::getPremiumStatus());
427
428 $this->displayPage('settings.html', $data);
429 }
430
431 function help() {
432 $this->displayPage('help.html', array('data' => Beacon::getData()));
433 }
434
435 private function _getFlags() {
436 // flags (available features on WP install)
437 $flags = array();
438
439 if(is_multisite()) {
440 // get multisite registration option
441 $registration = apply_filters(
442 'wpmu_registration_enabled',
443 get_site_option('registration', 'all')
444 );
445
446 // check if users can register
447 $flags['registration_enabled'] =
448 !(in_array($registration, array(
449 'none',
450 'blog'
451 )));
452 } else {
453 // check if users can register
454 $flags['registration_enabled'] =
455 (bool)get_option('users_can_register', false);
456 }
457
458 return $flags;
459 }
460
461 function subscribers() {
462 $data = array();
463
464 $data['items_per_page'] = $this->getLimitPerPage('subscribers');
465 $segments = Segment::getSegmentsWithSubscriberCount($type = false);
466 $segments = apply_filters('mailpoet_segments_with_subscriber_count', $segments);
467 usort($segments, function ($a, $b) {
468 return strcasecmp($a["name"], $b["name"]);
469 });
470 $data['segments'] = $segments;
471
472 $data['custom_fields'] = array_map(function($field) {
473 $field['params'] = unserialize($field['params']);
474
475 if(!empty($field['params']['values'])) {
476 $values = array();
477
478 foreach($field['params']['values'] as $value) {
479 $values[$value['value']] = $value['value'];
480 }
481 $field['params']['values'] = $values;
482 }
483 return $field;
484 }, CustomField::findArray());
485
486 $data['date_formats'] = Block\Date::getDateFormats();
487 $data['month_names'] = Block\Date::getMonthNames();
488
489 $data['premium_plugin_active'] = License::getLicense();
490
491 $this->displayPage('subscribers/subscribers.html', $data);
492 }
493
494 function segments() {
495 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
496
497 $data = array();
498 $data['items_per_page'] = $this->getLimitPerPage('segments');
499 $this->displayPage('segments.html', $data);
500 }
501
502 function forms() {
503 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
504
505 $data = array();
506
507 $data['items_per_page'] = $this->getLimitPerPage('forms');
508 $data['segments'] = Segment::findArray();
509
510 $this->displayPage('forms.html', $data);
511 }
512
513 function newsletters() {
514 if($this->subscribers_over_limit) return $this->displaySubscriberLimitExceededTemplate();
515 if(isset($this->mp_api_key_valid) && $this->mp_api_key_valid === false) {
516 return $this->displayMailPoetAPIKeyInvalidTemplate();
517 }
518
519 global $wp_roles;
520
521 $data = array();
522
523 $data['items_per_page'] = $this->getLimitPerPage('newsletters');
524 $segments = Segment::getSegmentsWithSubscriberCount($type = false);
525 $segments = apply_filters('mailpoet_segments_with_subscriber_count', $segments);
526 usort($segments, function ($a, $b) {
527 return strcasecmp($a["name"], $b["name"]);
528 });
529 $data['segments'] = $segments;
530 $data['settings'] = Setting::getAll();
531 $data['roles'] = $wp_roles->get_names();
532 $data['roles']['mailpoet_all'] = __('In any WordPress role', 'mailpoet');
533
534 $date_time = new DateTime();
535 $data['current_date'] = $date_time->getCurrentDate(DateTime::DEFAULT_DATE_FORMAT);
536 $data['current_time'] = $date_time->getCurrentTime();
537 $data['schedule_time_of_day'] = $date_time->getTimeInterval(
538 '00:00:00',
539 '+1 hour',
540 24
541 );
542
543 $data['tracking_enabled'] = Setting::getValue('tracking.enabled');
544 $data['premium_plugin_active'] = License::getLicense();
545
546 wp_enqueue_script('jquery-ui');
547 wp_enqueue_script('jquery-ui-datepicker');
548
549 $this->displayPage('newsletters.html', $data);
550 }
551
552 function newletterEditor() {
553 $data = array(
554 'shortcodes' => ShortcodesHelper::getShortcodes(),
555 'settings' => Setting::getAll(),
556 'current_wp_user' => Subscriber::getCurrentWPUser(),
557 'sub_menu' => self::MAIN_PAGE_SLUG,
558 'mss_active' => Bridge::isMPSendingServiceEnabled()
559 );
560 wp_enqueue_media();
561 wp_enqueue_script('tinymce-wplink', includes_url('js/tinymce/plugins/wplink/plugin.js'));
562 wp_enqueue_style('editor', includes_url('css/editor.css'));
563
564 $this->displayPage('newsletter/editor.html', $data);
565 }
566
567 function import() {
568 $import = new ImportExportFactory('import');
569 $data = $import->bootstrap();
570 $data = array_merge($data, array(
571 'date_types' => Block\Date::getDateTypes(),
572 'date_formats' => Block\Date::getDateFormats(),
573 'month_names' => Block\Date::getMonthNames(),
574 'sub_menu' => 'mailpoet-subscribers'
575 ));
576 $this->displayPage('subscribers/importExport/import.html', $data);
577 }
578
579 function export() {
580 $export = new ImportExportFactory('export');
581 $data = $export->bootstrap();
582 $data['sub_menu'] = 'mailpoet-subscribers';
583 $this->displayPage('subscribers/importExport/export.html', $data);
584 }
585
586 function formEditor() {
587 $id = (isset($_GET['id']) ? (int)$_GET['id'] : 0);
588 $form = Form::findOne($id);
589 if($form !== false) {
590 $form = $form->asArray();
591 }
592
593 $data = array(
594 'form' => $form,
595 'pages' => Pages::getAll(),
596 'segments' => Segment::getSegmentsWithSubscriberCount(),
597 'styles' => FormRenderer::getStyles($form),
598 'date_types' => Block\Date::getDateTypes(),
599 'date_formats' => Block\Date::getDateFormats(),
600 'month_names' => Block\Date::getMonthNames(),
601 'sub_menu' => 'mailpoet-forms'
602 );
603
604 $this->displayPage('form/editor.html', $data);
605 }
606
607 function setPageTitle($title) {
608 return sprintf(
609 '%s - %s',
610 __('MailPoet', 'mailpoet'),
611 $title
612 );
613 }
614
615 function displaySubscriberLimitExceededTemplate() {
616 $this->displayPage('limit.html', array(
617 'limit' => SubscribersFeature::SUBSCRIBERS_LIMIT
618 ));
619 exit;
620 }
621
622 function displayMailPoetAPIKeyInvalidTemplate() {
623 $this->displayPage('invalidkey.html', array(
624 'subscriber_count' => Subscriber::getTotalSubscribers()
625 ));
626 exit;
627 }
628
629 static function isOnMailPoetAdminPage(array $exclude = null, $screen_id = null) {
630 if(is_null($screen_id)) {
631 if(empty($_REQUEST['page'])) {
632 return false;
633 }
634 $screen_id = $_REQUEST['page'];
635 }
636 if(!empty($exclude)) {
637 foreach($exclude as $slug) {
638 if(stripos($screen_id, $slug) !== false) {
639 return false;
640 }
641 }
642 }
643 return (stripos($screen_id, 'mailpoet-') !== false);
644 }
645
646 /**
647 * This error page is used when the initialization is failed
648 * to display admin notices only
649 */
650 static function addErrorPage(AccessControl $access_control) {
651 if(!self::isOnMailPoetAdminPage()) {
652 return false;
653 }
654 // Check if page already exists
655 if(get_plugin_page_hook($_REQUEST['page'], '')
656 || get_plugin_page_hook($_REQUEST['page'], self::MAIN_PAGE_SLUG)
657 ) {
658 return false;
659 }
660 add_submenu_page(
661 true,
662 'MailPoet',
663 'MailPoet',
664 AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
665 $_REQUEST['page'],
666 array(
667 __CLASS__,
668 'errorPageCallback'
669 )
670 );
671 }
672
673 static function errorPageCallback() {
674 // Used for displaying admin notices only
675 }
676
677 function checkMailPoetAPIKey(ServicesChecker $checker = null) {
678 if(self::isOnMailPoetAdminPage()) {
679 $show_notices = isset($_REQUEST['page'])
680 && stripos($_REQUEST['page'], self::MAIN_PAGE_SLUG) === false;
681 $checker = $checker ?: new ServicesChecker();
682 $this->mp_api_key_valid = $checker->isMailPoetAPIKeyValid($show_notices);
683 }
684 }
685
686 function checkPremiumKey(ServicesChecker $checker = null) {
687 $show_notices = isset($_SERVER['SCRIPT_NAME'])
688 && stripos($_SERVER['SCRIPT_NAME'], 'plugins.php') !== false;
689 $checker = $checker ?: new ServicesChecker();
690 $this->premium_key_valid = $checker->isPremiumKeyValid($show_notices);
691 }
692
693 function getLimitPerPage($model = null) {
694 if($model === null) {
695 return Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
696 }
697
698 $listing_per_page = get_user_meta(
699 get_current_user_id(), 'mailpoet_' . $model . '_per_page', true
700 );
701 return (!empty($listing_per_page))
702 ? (int)$listing_per_page
703 : Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
704 }
705
706 function displayPage($template, $data) {
707 try {
708 echo $this->renderer->render($template, $data);
709 } catch(\Exception $e) {
710 $notice = new WPNotice(WPNotice::TYPE_ERROR, $e->getMessage());
711 $notice->displayWPNotice();
712 }
713 }
714 }
715