Нет описания

Menu.php 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. <?php
  2. namespace MailPoet\Config;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\AdminPages\Pages\ExperimentalFeatures;
  5. use MailPoet\AdminPages\Pages\FormEditor;
  6. use MailPoet\AdminPages\Pages\Forms;
  7. use MailPoet\AdminPages\Pages\Help;
  8. use MailPoet\AdminPages\Pages\Logs;
  9. use MailPoet\AdminPages\Pages\MP2Migration;
  10. use MailPoet\AdminPages\Pages\NewsletterEditor;
  11. use MailPoet\AdminPages\Pages\Newsletters;
  12. use MailPoet\AdminPages\Pages\Premium;
  13. use MailPoet\AdminPages\Pages\Segments;
  14. use MailPoet\AdminPages\Pages\Settings;
  15. use MailPoet\AdminPages\Pages\Subscribers;
  16. use MailPoet\AdminPages\Pages\SubscribersExport;
  17. use MailPoet\AdminPages\Pages\SubscribersImport;
  18. use MailPoet\AdminPages\Pages\WelcomeWizard;
  19. use MailPoet\AdminPages\Pages\WooCommerceSetup;
  20. use MailPoet\DI\ContainerWrapper;
  21. use MailPoet\Util\License\License;
  22. use MailPoet\WP\Functions as WPFunctions;
  23. class Menu {
  24. const MAIN_PAGE_SLUG = 'mailpoet-newsletters';
  25. public $mpApiKeyValid;
  26. public $premiumKeyValid;
  27. /** @var AccessControl */
  28. private $accessControl;
  29. /** @var WPFunctions */
  30. private $wp;
  31. /** @var ServicesChecker */
  32. private $servicesChecker;
  33. /** @var ContainerWrapper */
  34. private $container;
  35. /** @var Router */
  36. private $router;
  37. public function __construct(
  38. AccessControl $accessControl,
  39. WPFunctions $wp,
  40. ServicesChecker $servicesChecker,
  41. ContainerWrapper $container,
  42. Router $router
  43. ) {
  44. $this->accessControl = $accessControl;
  45. $this->wp = $wp;
  46. $this->servicesChecker = $servicesChecker;
  47. $this->container = $container;
  48. $this->router = $router;
  49. }
  50. public function init() {
  51. $this->checkPremiumKey();
  52. $this->wp->addAction(
  53. 'admin_menu',
  54. [
  55. $this,
  56. 'setup',
  57. ]
  58. );
  59. }
  60. public function setup() {
  61. if (!$this->accessControl->validatePermission(AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN)) return;
  62. $this->router->checkRedirects();
  63. if (self::isOnMailPoetAdminPage()) {
  64. $this->wp->doAction('mailpoet_conflict_resolver_styles');
  65. $this->wp->doAction('mailpoet_conflict_resolver_scripts');
  66. if ($_REQUEST['page'] === 'mailpoet-newsletter-editor') {
  67. // Disable WP emojis to not interfere with the newsletter editor emoji handling
  68. $this->disableWPEmojis();
  69. $this->wp->addAction('admin_head', function() {
  70. $fonts = 'Arvo:400,400i,700,700i'
  71. . '|Lato:400,400i,700,700i'
  72. . '|Lora:400,400i,700,700i'
  73. . '|Merriweather:400,400i,700,700i'
  74. . '|Merriweather+Sans:400,400i,700,700i'
  75. . '|Noticia+Text:400,400i,700,700i'
  76. . '|Open+Sans:400,400i,700,700i'
  77. . '|Playfair+Display:400,400i,700,700i'
  78. . '|Roboto:400,400i,700,700i'
  79. . '|Source+Sans+Pro:400,400i,700,700i'
  80. . '|Oswald:400,400i,700,700i'
  81. . '|Raleway:400,400i,700,700i'
  82. . '|Permanent+Marker:400,400i,700,700i'
  83. . '|Pacifico:400,400i,700,700i';
  84. echo '<link href="https://fonts.googleapis.com/css?family=' . $fonts . '" rel="stylesheet">';
  85. });
  86. }
  87. }
  88. // Main page
  89. $this->wp->addMenuPage(
  90. 'MailPoet',
  91. 'MailPoet',
  92. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  93. self::MAIN_PAGE_SLUG,
  94. null,
  95. 'none',
  96. 30
  97. );
  98. // Emails page
  99. $newslettersPage = $this->wp->addSubmenuPage(
  100. self::MAIN_PAGE_SLUG,
  101. $this->setPageTitle(__('Emails', 'mailpoet')),
  102. $this->wp->__('Emails', 'mailpoet'),
  103. AccessControl::PERMISSION_MANAGE_EMAILS,
  104. self::MAIN_PAGE_SLUG,
  105. [
  106. $this,
  107. 'newsletters',
  108. ]
  109. );
  110. // add limit per page to screen options
  111. $this->wp->addAction('load-' . $newslettersPage, function() {
  112. $this->wp->addScreenOption('per_page', [
  113. 'label' => $this->wp->_x(
  114. 'Number of newsletters per page',
  115. 'newsletters per page (screen options)',
  116. 'mailpoet'
  117. ),
  118. 'option' => 'mailpoet_newsletters_per_page',
  119. ]);
  120. });
  121. // newsletter editor
  122. $this->wp->addSubmenuPage(
  123. true,
  124. $this->setPageTitle(__('Newsletter', 'mailpoet')),
  125. $this->wp->__('Newsletter Editor', 'mailpoet'),
  126. AccessControl::PERMISSION_MANAGE_EMAILS,
  127. 'mailpoet-newsletter-editor',
  128. [
  129. $this,
  130. 'newletterEditor',
  131. ]
  132. );
  133. // Forms page
  134. $formsPage = $this->wp->addSubmenuPage(
  135. self::MAIN_PAGE_SLUG,
  136. $this->setPageTitle(__('Forms', 'mailpoet')),
  137. $this->wp->__('Forms', 'mailpoet'),
  138. AccessControl::PERMISSION_MANAGE_FORMS,
  139. 'mailpoet-forms',
  140. [
  141. $this,
  142. 'forms',
  143. ]
  144. );
  145. // add limit per page to screen options
  146. $this->wp->addAction('load-' . $formsPage, function() {
  147. $this->wp->addScreenOption('per_page', [
  148. 'label' => $this->wp->_x(
  149. 'Number of forms per page',
  150. 'forms per page (screen options)',
  151. 'mailpoet'
  152. ),
  153. 'option' => 'mailpoet_forms_per_page',
  154. ]);
  155. });
  156. // form editor
  157. $formEditorPage = $this->wp->addSubmenuPage(
  158. true,
  159. $this->setPageTitle(__('Form Editor', 'mailpoet')),
  160. $this->wp->__('Form Editor', 'mailpoet'),
  161. AccessControl::PERMISSION_MANAGE_FORMS,
  162. 'mailpoet-form-editor',
  163. [
  164. $this,
  165. 'formEditor',
  166. ]
  167. );
  168. // add body class for form editor page
  169. $this->wp->addAction('load-' . $formEditorPage, function() {
  170. $this->wp->addAction('admin_body_class', function ($classes) {
  171. return ltrim($classes . ' block-editor-page');
  172. });
  173. });
  174. // form editor templates
  175. $formTemplateSelectionEditorPage = $this->wp->addSubmenuPage(
  176. true,
  177. $this->setPageTitle(__('Select Form Template', 'mailpoet')),
  178. $this->wp->__('Select Form Template', 'mailpoet'),
  179. AccessControl::PERMISSION_MANAGE_FORMS,
  180. 'mailpoet-form-editor-template-selection',
  181. [
  182. $this,
  183. 'formEditorTemplateSelection',
  184. ]
  185. );
  186. // add body class for form editor page
  187. $this->wp->addAction('load-' . $formTemplateSelectionEditorPage, function() {
  188. $this->wp->addAction('admin_body_class', function ($classes) {
  189. return ltrim($classes . ' block-editor-page');
  190. });
  191. });
  192. // Subscribers page
  193. $subscribersPage = $this->wp->addSubmenuPage(
  194. self::MAIN_PAGE_SLUG,
  195. $this->setPageTitle(__('Subscribers', 'mailpoet')),
  196. $this->wp->__('Subscribers', 'mailpoet'),
  197. AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
  198. 'mailpoet-subscribers',
  199. [
  200. $this,
  201. 'subscribers',
  202. ]
  203. );
  204. // add limit per page to screen options
  205. $this->wp->addAction('load-' . $subscribersPage, function() {
  206. $this->wp->addScreenOption('per_page', [
  207. 'label' => $this->wp->_x(
  208. 'Number of subscribers per page',
  209. 'subscribers per page (screen options)',
  210. 'mailpoet'
  211. ),
  212. 'option' => 'mailpoet_subscribers_per_page',
  213. ]);
  214. });
  215. // import
  216. $this->wp->addSubmenuPage(
  217. 'admin.php?page=mailpoet-subscribers',
  218. $this->setPageTitle(__('Import', 'mailpoet')),
  219. $this->wp->__('Import', 'mailpoet'),
  220. AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
  221. 'mailpoet-import',
  222. [
  223. $this,
  224. 'import',
  225. ]
  226. );
  227. // export
  228. $this->wp->addSubmenuPage(
  229. true,
  230. $this->setPageTitle(__('Export', 'mailpoet')),
  231. $this->wp->__('Export', 'mailpoet'),
  232. AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
  233. 'mailpoet-export',
  234. [
  235. $this,
  236. 'export',
  237. ]
  238. );
  239. // Segments page
  240. $segmentsPage = $this->wp->addSubmenuPage(
  241. self::MAIN_PAGE_SLUG,
  242. $this->setPageTitle(__('Lists', 'mailpoet')),
  243. $this->wp->__('Lists', 'mailpoet'),
  244. AccessControl::PERMISSION_MANAGE_SEGMENTS,
  245. 'mailpoet-segments',
  246. [
  247. $this,
  248. 'segments',
  249. ]
  250. );
  251. // add limit per page to screen options
  252. $this->wp->addAction('load-' . $segmentsPage, function() {
  253. $this->wp->addScreenOption('per_page', [
  254. 'label' => $this->wp->_x(
  255. 'Number of segments per page',
  256. 'segments per page (screen options)',
  257. 'mailpoet'
  258. ),
  259. 'option' => 'mailpoet_segments_per_page',
  260. ]);
  261. });
  262. // Settings page
  263. $this->wp->addSubmenuPage(
  264. self::MAIN_PAGE_SLUG,
  265. $this->setPageTitle(__('Settings', 'mailpoet')),
  266. $this->wp->__('Settings', 'mailpoet'),
  267. AccessControl::PERMISSION_MANAGE_SETTINGS,
  268. 'mailpoet-settings',
  269. [
  270. $this,
  271. 'settings',
  272. ]
  273. );
  274. // Help page
  275. $this->wp->addSubmenuPage(
  276. self::MAIN_PAGE_SLUG,
  277. $this->setPageTitle(__('Help', 'mailpoet')),
  278. $this->wp->__('Help', 'mailpoet'),
  279. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  280. 'mailpoet-help',
  281. [
  282. $this,
  283. 'help',
  284. ]
  285. );
  286. // Premium page
  287. // Only show this page in menu if the Premium plugin is not activated
  288. $this->wp->addSubmenuPage(
  289. License::getLicense() ? true : self::MAIN_PAGE_SLUG,
  290. $this->setPageTitle(__('Premium', 'mailpoet')),
  291. $this->wp->__('Premium', 'mailpoet'),
  292. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  293. 'mailpoet-premium',
  294. [
  295. $this,
  296. 'premium',
  297. ]
  298. );
  299. // Welcome wizard page
  300. $this->wp->addSubmenuPage(
  301. true,
  302. $this->setPageTitle(__('Welcome Wizard', 'mailpoet')),
  303. $this->wp->__('Welcome Wizard', 'mailpoet'),
  304. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  305. 'mailpoet-welcome-wizard',
  306. [
  307. $this,
  308. 'welcomeWizard',
  309. ]
  310. );
  311. // WooCommerce Setup
  312. $this->wp->addSubmenuPage(
  313. true,
  314. $this->setPageTitle($this->wp->__('WooCommerce Setup', 'mailpoet')),
  315. $this->wp->__('WooCommerce Setup', 'mailpoet'),
  316. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  317. 'mailpoet-woocommerce-setup',
  318. [
  319. $this,
  320. 'wooCommerceSetup',
  321. ]
  322. );
  323. // Migration page
  324. $this->wp->addSubmenuPage(
  325. true,
  326. $this->setPageTitle(__('Migration', 'mailpoet')),
  327. '',
  328. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  329. 'mailpoet-migration',
  330. [
  331. $this,
  332. 'migration',
  333. ]
  334. );
  335. // Experimental page
  336. $this->wp->addSubmenuPage(
  337. true,
  338. $this->setPageTitle('Experimental Features'),
  339. '',
  340. AccessControl::PERMISSION_MANAGE_FEATURES,
  341. 'mailpoet-experimental',
  342. [$this, 'experimentalFeatures']
  343. );
  344. // display loggs page
  345. $this->wp->addSubmenuPage(
  346. true,
  347. $this->setPageTitle('Logs'),
  348. '',
  349. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  350. 'mailpoet-logs',
  351. [$this, 'logs']
  352. );
  353. }
  354. public function disableWPEmojis() {
  355. $this->wp->removeAction('admin_print_scripts', 'print_emoji_detection_script');
  356. $this->wp->removeAction('admin_print_styles', 'print_emoji_styles');
  357. }
  358. public function migration() {
  359. $this->container->get(MP2Migration::class)->render();
  360. }
  361. public function welcomeWizard() {
  362. $this->container->get(WelcomeWizard::class)->render();
  363. }
  364. public function wooCommerceSetup() {
  365. $this->container->get(WooCommerceSetup::class)->render();
  366. }
  367. public function premium() {
  368. $this->container->get(Premium::class)->render();
  369. }
  370. public function settings() {
  371. $this->container->get(Settings::class)->render();
  372. }
  373. public function help() {
  374. $this->container->get(Help::class)->render();
  375. }
  376. public function experimentalFeatures() {
  377. $this->container->get(ExperimentalFeatures::class)->render();
  378. }
  379. public function logs() {
  380. $this->container->get(Logs::class)->render();
  381. }
  382. public function subscribers() {
  383. $this->container->get(Subscribers::class)->render();
  384. }
  385. public function segments() {
  386. $this->container->get(Segments::class)->render();
  387. }
  388. public function forms() {
  389. $this->container->get(Forms::class)->render();
  390. }
  391. public function newsletters() {
  392. $this->container->get(Newsletters::class)->render();
  393. }
  394. public function newletterEditor() {
  395. $this->container->get(NewsletterEditor::class)->render();
  396. }
  397. public function import() {
  398. $this->container->get(SubscribersImport::class)->render();
  399. }
  400. public function export() {
  401. $this->container->get(SubscribersExport::class)->render();
  402. }
  403. public function formEditor() {
  404. $this->container->get(FormEditor::class)->render();
  405. }
  406. public function formEditorTemplateSelection() {
  407. $this->container->get(FormEditor::class)->renderTemplateSelection();
  408. }
  409. public function setPageTitle($title) {
  410. return sprintf(
  411. '%s - %s',
  412. $this->wp->__('MailPoet', 'mailpoet'),
  413. $title
  414. );
  415. }
  416. public static function isOnMailPoetAdminPage(array $exclude = null, $screenId = null) {
  417. if (is_null($screenId)) {
  418. if (empty($_REQUEST['page'])) {
  419. return false;
  420. }
  421. $screenId = $_REQUEST['page'];
  422. }
  423. if (!empty($exclude)) {
  424. foreach ($exclude as $slug) {
  425. if (stripos($screenId, $slug) !== false) {
  426. return false;
  427. }
  428. }
  429. }
  430. return (stripos($screenId, 'mailpoet-') !== false);
  431. }
  432. /**
  433. * This error page is used when the initialization is failed
  434. * to display admin notices only
  435. */
  436. public static function addErrorPage(AccessControl $accessControl) {
  437. if (!self::isOnMailPoetAdminPage()) {
  438. return false;
  439. }
  440. // Check if page already exists
  441. if (get_plugin_page_hook($_REQUEST['page'], '')
  442. || WPFunctions::get()->getPluginPageHook($_REQUEST['page'], self::MAIN_PAGE_SLUG)
  443. ) {
  444. return false;
  445. }
  446. WPFunctions::get()->addSubmenuPage(
  447. true,
  448. 'MailPoet',
  449. 'MailPoet',
  450. AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
  451. $_REQUEST['page'],
  452. [
  453. __CLASS__,
  454. 'errorPageCallback',
  455. ]
  456. );
  457. }
  458. public static function errorPageCallback() {
  459. // Used for displaying admin notices only
  460. }
  461. public function checkPremiumKey(ServicesChecker $checker = null) {
  462. $showNotices = isset($_SERVER['SCRIPT_NAME'])
  463. && stripos($_SERVER['SCRIPT_NAME'], 'plugins.php') !== false;
  464. $checker = $checker ?: $this->servicesChecker;
  465. $this->premiumKeyValid = $checker->isPremiumKeyValid($showNotices);
  466. }
  467. }