PluginProbe ʕ •ᴥ•ʔ
FAPI Member / 2.2.28
FAPI Member v2.2.28
2.2.33 2.2.32 trunk 1.9.47 2.1.18 2.2.24 2.2.25 2.2.26 2.2.28 2.2.29 2.2.30 2.2.31
fapi-member / src / Bootstrap.php
fapi-member / src Last commit date
Api 7 months ago Container 7 months ago Divi 7 months ago Elementor 7 months ago Mioweb 7 months ago Model 7 months ago Repository 7 months ago Service 7 months ago Templates 7 months ago Utils 7 months ago Bootstrap.php 7 months ago FapiMemberPlugin.php 7 months ago
Bootstrap.php
610 lines
1 <?php declare(strict_types = 1);
2
3 namespace FapiMember;
4
5 use FapiMember\Api\V1\RequestHandler;
6 use FapiMember\Api\V2\ApiController;
7 use FapiMember\Container\Container;
8 use FapiMember\Divi\FapiMemberDivi;
9 use FapiMember\Mioweb\FapiMemberMioweb;
10 use FapiMember\Model\Enums\Keys\OptionKey;
11 use FapiMember\Model\Enums\Types\MembershipChangeType;
12 use FapiMember\Model\Enums\Types\RequestMethodType;
13 use FapiMember\Model\Enums\UserPermission;
14 use FapiMember\Repository\MemberActivityRepository;
15 use FapiMember\Repository\MembershipChangeRepository;
16 use FapiMember\Repository\MembershipRepository;
17 use FapiMember\Service\ApiService;
18 use FapiMember\Service\ElementService;
19 use FapiMember\Service\RedirectService;
20 use FapiMember\Service\StatisticsService;
21 use FapiMember\Utils\DisplayHelper;
22 use FapiMember\Utils\PostTypeHelper;
23 use FapiMember\Utils\Random;
24 use FapiMember\Utils\ShortcodeSubstitutor;
25
26 final class Bootstrap
27 {
28
29 private FapiMemberPlugin $fapiMemberPlugin;
30
31 private FapiMemberDivi $fapiMemberDivi;
32
33 private FapiMemberMioweb $fapiMemberMioweb;
34
35 private ApiService $apiService;
36
37 private ElementService $elementService;
38
39 private RedirectService $redirectService;
40
41 private RequestHandler $requestHandler;
42
43 private ShortcodeSubstitutor $shortcodeSubstitutor;
44
45 private ApiController $apiController;
46
47 private MembershipRepository $membershipRepository;
48
49 private MembershipChangeRepository $membershipChangeRepository;
50
51 private MemberActivityRepository $memberActivityRepository;
52
53 private StatisticsService $statisticsService;
54
55 public function __construct(FapiMemberPlugin $fapiMemberPlugin)
56 {
57 $this->fapiMemberPlugin = $fapiMemberPlugin;
58 Container::set(FapiMemberPlugin::class, $fapiMemberPlugin);
59
60 $this->apiService = Container::get(ApiService::class);
61 $this->elementService = Container::get(ElementService::class);
62 $this->redirectService = Container::get(RedirectService::class);
63 $this->requestHandler = Container::get(RequestHandler::class);
64 $this->shortcodeSubstitutor = Container::get(ShortcodeSubstitutor::class);
65 $this->apiController = Container::get(ApiController::class);
66 $this->fapiMemberDivi = Container::get(FapiMemberDivi::class);
67 $this->fapiMemberMioweb = Container::get(FapiMemberMioweb::class);
68 $this->membershipRepository = Container::get(MembershipRepository::class);
69 $this->membershipChangeRepository = Container::get(MembershipChangeRepository::class);
70 $this->memberActivityRepository = Container::get(MemberActivityRepository::class);
71 $this->statisticsService = Container::get(StatisticsService::class);
72 }
73
74 public function initialize(): void
75 {
76 $this->addHooks();
77 $this->generateTokenIfNeeded();
78 $this->migrateCredentialsIfNeeded();
79
80 update_option(OptionKey::FAPI_MEMBER_VERSION, FAPI_MEMBER_PLUGIN_VERSION);
81 }
82
83 private function generateTokenIfNeeded(): void
84 {
85 $token = get_option(OptionKey::TOKEN, '');
86
87 if (!$token) {
88 update_option(OptionKey::TOKEN, Random::generate(20, 'A-Za-z'));
89 }
90 }
91
92 public function migrateCredentialsIfNeeded(): void
93 {
94 $oldVersion = get_option(OptionKey::FAPI_MEMBER_VERSION, '');
95
96 if (!empty($oldVersion)) {
97 return;
98 }
99
100 $fapiCredentials = get_option(OptionKey::API_CREDENTIALS, null);
101
102 if ((!empty($fapiCredentials))) {
103 return;
104 }
105
106 $apiUser = get_option(OptionKey::API_USER, null);
107 $apiKey = get_option(OptionKey::API_KEY, null);
108
109 if (empty($apiKey) || empty($apiUser)) {
110 return;
111 }
112
113 update_option(
114 OptionKey::API_CREDENTIALS,
115 json_encode(
116 [
117 [
118 'username' => $apiUser,
119 'token' => $apiKey,
120 ],
121 ]
122 )
123 );
124
125 $credentialsOk = $this->apiService->checkCredentials();
126 update_option(OptionKey::API_CHECKED, $credentialsOk);
127
128 if (!$credentialsOk) {
129 update_option(OptionKey::API_CREDENTIALS, '0');
130 }
131 }
132
133 private function addHooks(): void
134 {
135 $this->addInitHooks();
136 $this->addAdminHooks();
137 $this->registerUserFapiMemberTableColumn();
138
139 add_action('init', function () {
140 load_plugin_textdomain('fapi-member', false, FAPI_MEMBER_PLUGIN_PATH . '/languages');
141 });
142
143 add_action('wp_enqueue_scripts', [$this, 'addPublicScripts']);
144
145 add_action('rest_api_init', [$this, 'addRestEndpoints']);
146
147 // adds meta boxed to setting page/post side bar
148 add_action('add_meta_boxes', [$this->elementService, 'addMetaBoxes']);
149 add_action('save_post', [$this->elementService, 'savePostMetadata']);
150
151 // check if page in fapi level
152 add_action('template_redirect', [$this->redirectService, 'checkPageForRedirects']);
153
154 // user profile
155 add_action('edit_user_profile', [$this->elementService, 'addUserMenuPage']);
156 add_action('plugins_loaded', [$this, 'initializeStatisticsIfNeeded']);
157
158 add_action('wp_enqueue_scripts', [$this, 'addPublicScripts']);
159
160 $this->addMiowebHooks();
161 $this->addDiviHooks();
162
163 add_image_size('level-selection', 300, 164, true);
164 add_filter('login_redirect', [$this->fapiMemberPlugin, 'loginRedirect'], 5, 3);
165 add_filter('show_admin_bar', [$this->elementService, 'hideAdminBar']);
166
167 // filters block to render by section and levels provided
168 add_filter(
169 'render_block',
170 function ($blockContent, $block) {
171 if (!isset($block['attrs']['hasSectionOrLevel'])) {
172 return $blockContent;
173 }
174
175 if (!isset($block['attrs']['fapiSectionAndLevels'])) {
176 return $blockContent;
177 }
178
179 if (DisplayHelper::shouldContentBeRendered(
180 (string) $block['attrs']['hasSectionOrLevel'],
181 $block['attrs']['fapiSectionAndLevels']
182 )) {
183 return $blockContent;
184 }
185
186 return '';
187 },
188 15,
189 2
190 );
191
192 // WPS hide login plugin
193 add_filter('whl_logged_in_redirect', [$this->redirectService, 'loggedInRedirect'], 1);
194 add_filter('whl_logged_in_redirect', [$this->redirectService, 'loggedInRedirect'], 1);
195 }
196
197 private function addInitHooks(): void
198 {
199 add_action('init', [$this, 'registerLevelsTaxonomy']);
200 add_action('init', [$this, 'registerRoles']);
201 add_action('init', [$this, 'addShortcodes']);
202 add_action('init', [$this->fapiMemberPlugin, 'checkTimedLevelUnlock']);
203 add_action('init', [$this->statisticsService, 'handleUserActive']);
204 }
205
206 private function addAdminHooks(): void
207 {
208 add_action('admin_init', [$this, 'registerSettings']);
209 add_action('admin_menu', [$this->elementService, 'addAdminMenu']);
210 add_action('admin_enqueue_scripts', [$this, 'addScripts']);
211 add_action('admin_enqueue_scripts', [$this, 'addApiNonce']);
212 add_action('admin_enqueue_scripts', [$this, 'checkFapiMemberPlusStatus']);
213 add_action('admin_enqueue_scripts', [$this, 'checkSimpleShopStatus']);
214
215 }
216
217 private function addMiowebHooks(): void
218 {
219 add_action('wp_ajax_open_element_setting', [$this->fapiMemberMioweb, 'addSetting']);
220 add_action('wp_ajax_open_row_setting', [$this->fapiMemberMioweb, 'addSetting']);
221 add_action('mw_page_init', [$this->fapiMemberMioweb, 'hideContentIfNeeded']);
222 }
223
224 public function addDiviHooks(): void
225 {
226 add_action('divi_extensions_init', [$this, 'initializeDiviExtension']);
227
228 add_filter('et_builder_get_parent_modules', [$this->fapiMemberDivi, 'addToggle']);
229
230 foreach ($this->fapiMemberDivi->allowedModuleSlugs as $slug) {
231 add_filter("et_pb_all_fields_unprocessed_" . $slug, [$this->fapiMemberDivi, 'addFields']);
232 }
233
234 add_filter('et_pb_module_content', [$this->fapiMemberDivi, 'hideElements'], 10, 4);
235 }
236
237 public function initializeDiviExtension(): void
238 {
239 require_once plugin_dir_path(__FILE__) . 'Divi/includes/FmDivi.php';
240 }
241
242 function addApiNonce(): void
243 {
244 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
245 $nonce = wp_create_nonce('wp_rest');
246 echo "<script>window.apiInternalAccessNonce = '{$nonce}'</script>";
247 }
248
249 }
250
251 function checkFapiMemberPlusStatus(): void
252 {
253 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
254 $licenceActive = $this->apiService->checkLicence();
255
256 echo "<script>
257 window.licenceActive = '{$licenceActive}'
258 </script>";
259 }
260 }
261
262 function checkSimpleShopStatus(): void
263 {
264 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
265 $simpleShopActive = is_plugin_active('simpleshop-cz/simpleshop-cz.php') && class_exists('Redbit\SimpleShop\WpPlugin\Group');
266
267 $ssSections = [];
268
269 if (!$simpleShopActive) {
270 echo "<script>
271 window.simpleShopToFAPIMember = false
272 </script>";
273
274 return;
275 }
276
277 $groups = new \Redbit\SimpleShop\WpPlugin\Group();
278
279 foreach ($groups->get_groups() as $groupId => $group) {
280 $group = new \Redbit\SimpleShop\WpPlugin\Group($groupId);
281
282 $ssSections[] = [
283 'id' => $group->id,
284 'name' => $group->name,
285 'users' => array_values(array_map(function ($user) use ($groupId) {
286 $membership = new \Redbit\SimpleShop\WpPlugin\Membership($user->ID);
287
288 return [
289 'id' => $user->ID,
290 'email' => $user->user_email,
291 'registered' => $membership->groups[$groupId]['subscription_date'] ?? null,
292 'until' => $membership->groups[$groupId]['valid_to'] ?? null,
293 ];
294 }, $group->get_users())),
295 ];
296 }
297
298 $pagesGroups = [];
299
300 $pages = get_posts([
301 'post_type' => 'page',
302 'numberposts' => -1,
303 ]);
304
305 $ss = \Redbit\SimpleShop\WpPlugin\SimpleShop::getInstance();
306
307 foreach ($pages as $page) {
308 $pagesGroups[] = [
309 'id' => $page->ID,
310 'name' => $page->post_title,
311 'groups' => $ss->get_access()->get_post_groups($page->ID),
312 ];
313 }
314
315 echo "<script>
316 window.simpleShopToFAPIMember = true
317 window.ssSections = " . json_encode($ssSections) . "
318 window.ssPagesGroups = " . json_encode($pagesGroups) . "
319 </script>";
320 }
321 }
322
323 public function addRestEndpoints(): void
324 {
325 $this->addRestEndpointV1('sections', 'handleApiSections', RequestMethodType::GET);
326 $this->addRestEndpointV1('sections-simple', 'handleApiSectionsSimple', RequestMethodType::GET);
327 $this->addRestEndpointV1('callback', 'handleApiCallback', RequestMethodType::POST);
328 $this->addRestEndpointV1('check-connection', 'handleApiCheckConnectionCallback', RequestMethodType::POST);
329 $this->addRestEndpointV1(
330 'list-forms/(?P<user>[^/]+(?:\+[^/]+)?)',
331 'handleApiListFormsCallback',
332 RequestMethodType::GET,
333 );
334 $this->addRestEndpointV1('list-users', 'handleApiUsernamesCallback', RequestMethodType::GET);
335
336 $this->addRestEndpointV2('sections');
337 $this->addRestEndpointV2('pages');
338 $this->addRestEndpointV2('emails');
339 $this->addRestEndpointV2('memberships');
340 $this->addRestEndpointV2('users');
341 $this->addRestEndpointV2('apiConnections');
342 $this->addRestEndpointV2('statistics');
343 }
344
345 public function addRestEndpointV2(
346 string $route
347 ): void
348 {
349 register_rest_route(
350 'fapi/v2',
351 '/' . $route,
352 [
353 'methods' => [RequestMethodType::GET, RequestMethodType::POST],
354 'callback' => [$this->apiController, 'handleRequest'],
355 'permission_callback' => function () {
356 return true;
357 },
358 ],
359 );
360 }
361
362 public function addRestEndpointV1(
363 string $route, string $functionName, string $method
364 ): void
365 {
366 register_rest_route(
367 'fapi/v1',
368 '/' . $route,
369 [
370 'methods' => $method,
371 'callback' => [$this->requestHandler, $functionName],
372 'permission_callback' => function () {
373 return true;
374 },
375 ],
376 );
377 }
378
379 public function addShortcodes(): void
380 {
381 add_shortcode('fapi-member-login', [$this->shortcodeSubstitutor, 'shortcodeLoginForm']);
382 add_shortcode('fapi-member-user', [$this->shortcodeSubstitutor, 'shortcodeUser']);
383 add_shortcode('fapi-member-user-section-expiration', [$this->shortcodeSubstitutor, 'shortcodeSectionExpirationDate']);
384 add_shortcode('fapi-member-level-unlock-date', [$this->shortcodeSubstitutor, 'shortcodeLevelUnlockDate']);
385 add_shortcode('fapi-member-unlock-level', [$this->shortcodeSubstitutor, 'shortcodeUnlockLevel']);
386 }
387
388 public function addScripts(): void
389 {
390 $this->registerStyles();
391 $this->registerScripts();
392
393 global $pagenow;
394
395 if ($pagenow === 'admin.php' || $pagenow === 'options-general.php') {
396 wp_enqueue_style('fapi-member-admin-font', '', [], FAPI_MEMBER_PLUGIN_VERSION);
397 wp_enqueue_style('fapi-member-swal-css', '', [], FAPI_MEMBER_PLUGIN_VERSION);
398 wp_enqueue_script('fapi-member-swal', '', [], FAPI_MEMBER_PLUGIN_VERSION);
399 wp_enqueue_script('fapi-member-swal-promise-polyfill', '', [], FAPI_MEMBER_PLUGIN_VERSION);
400 wp_enqueue_script('fapi-member-clipboard', '', [], FAPI_MEMBER_PLUGIN_VERSION);
401 wp_enqueue_script('fapi-member-main', '', [], FAPI_MEMBER_PLUGIN_VERSION);
402 }
403 if ($pagenow === 'user-edit.php') {
404 wp_enqueue_style('fapi-member-user-profile', '', [], FAPI_MEMBER_PLUGIN_VERSION);
405 wp_enqueue_script('fapi-member-main', '', [], FAPI_MEMBER_PLUGIN_VERSION);
406 }
407
408 wp_enqueue_script(
409 'fm-react-app',
410 FAPI_MEMBER_PLUGIN_URL . '/app/dist/bundle.js',
411 ['jquery', 'wp-element'],
412 FAPI_MEMBER_PLUGIN_VERSION,
413 true,
414 );
415
416 wp_set_script_translations(
417 'fm-react-app',
418 'fapi-member',
419 FAPI_MEMBER_PLUGIN_PATH . '/languages'
420 );
421
422 wp_localize_script('fm-react-app', 'environmentData', [
423 'timeZoneOffset' => get_option('gmt_offset'),
424 ]);
425 }
426
427 public function registerStyles(): void
428 {
429 wp_register_style(
430 'fapi-member-user-profile',
431 plugins_url('fapi-member/media/fapi-user-profile.css'),
432 [],
433 FAPI_MEMBER_PLUGIN_VERSION
434 );
435 wp_register_style(
436 'fapi-member-admin-font',
437 plugins_url('fapi-member/media/font/stylesheet.css'),
438 [],
439 FAPI_MEMBER_PLUGIN_VERSION
440 );
441 wp_register_style(
442 'fapi-member-swal-css',
443 plugins_url('fapi-member/media/dist/sweetalert2.min.css'),
444 [],
445 FAPI_MEMBER_PLUGIN_VERSION
446 );
447 wp_register_style(
448 'fapi-member-public-style',
449 plugins_url('fapi-member/media/fapi-member-public.css'),
450 [],
451 FAPI_MEMBER_PLUGIN_VERSION
452 );
453 }
454
455 public function registerScripts(): void
456 {
457 wp_register_script(
458 'fapi-member-swal',
459 plugins_url('fapi-member/media/dist/sweetalert2.js'),
460 [],
461 FAPI_MEMBER_PLUGIN_VERSION
462 );
463
464 wp_register_script(
465 'fapi-member-swal-promise-polyfill',
466 plugins_url('fapi-member/media/dist/polyfill.min.js'),
467 [],
468 FAPI_MEMBER_PLUGIN_VERSION
469 );
470
471 wp_register_script(
472 'fapi-member-clipboard',
473 plugins_url('fapi-member/media/dist/clipboard.min.js'),
474 [],
475 FAPI_MEMBER_PLUGIN_VERSION
476 );
477
478 if (FapiMemberPlugin::isDevelopment()) {
479 wp_register_script(
480 'fapi-member-main',
481 plugins_url('fapi-member/media/dist/fapi.dev.js'),
482 [],
483 FAPI_MEMBER_PLUGIN_VERSION
484 );
485 } else {
486 wp_register_script(
487 'fapi-member-main',
488 plugins_url('fapi-member/media/dist/fapi.dist.js'),
489 [],
490 FAPI_MEMBER_PLUGIN_VERSION
491 );
492 }
493 }
494
495 public
496 function addPublicScripts(): void
497 {
498 $this->registerPublicStyles();
499
500 wp_enqueue_style('fapi-member-public-style', '',
501 [],
502 FAPI_MEMBER_PLUGIN_VERSION);
503
504 if (defined('FAPI_SHOWING_LEVEL_SELECTION')) {
505 wp_register_style(
506 'fapi-member-public-levelselection-font',
507 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap',
508 [],
509 FAPI_MEMBER_PLUGIN_VERSION
510 );
511 wp_enqueue_style('fapi-member-public-levelselection-font', '',
512 [],
513 FAPI_MEMBER_PLUGIN_VERSION);
514 }
515 }
516
517 public function registerPublicStyles(): void
518 {
519 wp_register_style(
520 'fapi-member-public-style',
521 plugins_url('fapi-member/media/fapi-member-public.css'),
522 [],
523 FAPI_MEMBER_PLUGIN_VERSION
524 );
525 }
526
527 public function registerRoles(): void
528 {
529 if (get_role('member') === null) {
530 add_role('member', __('Člen', 'fapi-member'), get_role('subscriber')->capabilities);
531 }
532 }
533
534 public function registerSettings(): void
535 {
536 register_setting(
537 'options',
538 'fapiMemberApiEmail',
539 [
540 'type' => 'string',
541 'description' => __('FAPI Member - API e-mail', 'fapi-member'),
542 'show_in_rest' => false,
543 'default' => null,
544 ]
545 );
546 register_setting(
547 'options',
548 'fapiMemberApiKey',
549 [
550 'type' => 'string',
551 'description' => __('FAPI Member - API key', 'fapi-member'),
552 'show_in_rest' => false,
553 'default' => null,
554 ]
555 );
556 }
557
558 public function registerLevelsTaxonomy(): void
559 {
560 register_taxonomy(
561 'fapi_levels',
562 PostTypeHelper::getSupportedPostTypes(),
563 [
564 'public' => false,
565 'hierarchical' => true,
566 'show_ui' => false,
567 'show_in_rest' => false,
568 ]
569 );
570 }
571
572 public function initializeStatisticsIfNeeded(): void
573 {
574 if (!$this->membershipChangeRepository->tableExists()) {
575 $this->initializeMembershipChanges();
576 }
577
578 if (!$this->memberActivityRepository->tableExists()) {
579 $this->memberActivityRepository->createTableIfNeeded();
580 }
581 }
582
583 private function initializeMembershipChanges(): void
584 {
585 $this->membershipChangeRepository->createTableIfNeeded();
586
587 $memberships = $this->membershipRepository->getAll();
588
589 foreach ($memberships as $membershipsByUserId) {
590 foreach ($membershipsByUserId as $membership) {
591 $this->membershipChangeRepository->addChange(
592 $membership->toMembershipChange(
593 MembershipChangeType::CREATED,
594 $membership->getRegistered(),
595 )
596 );
597 }
598 }
599 }
600
601 public function registerUserFapiMemberTableColumn(): void
602 {
603 add_filter('manage_users_columns', [$this->elementService, 'addUserColumn']);
604 add_action('manage_users_custom_column', [$this->elementService, 'showUserColumnContent'], 10, 3);
605 add_action('show_user_profile', [$this->elementService, 'addUserProfileSection']);
606 add_action('edit_user_profile', [$this->elementService, 'addUserProfileSection']);
607 }
608
609 }
610