PluginProbe ʕ •ᴥ•ʔ
FAPI Member / 2.2.25
FAPI Member v2.2.25
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 9 months ago Container 9 months ago Divi 9 months ago Elementor 9 months ago Mioweb 9 months ago Model 9 months ago Repository 9 months ago Service 9 months ago Templates 9 months ago Utils 9 months ago Bootstrap.php 9 months ago FapiMemberPlugin.php 9 months ago
Bootstrap.php
600 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('wp_enqueue_scripts', [$this, 'addPublicScripts']);
140
141 add_action('rest_api_init', [$this, 'addRestEndpoints']);
142
143 // adds meta boxed to setting page/post side bar
144 add_action('add_meta_boxes', [$this->elementService, 'addMetaBoxes']);
145 add_action('save_post', [$this->elementService, 'savePostMetadata']);
146
147 // check if page in fapi level
148 add_action('template_redirect', [$this->redirectService, 'checkPageForRedirects']);
149
150 // user profile
151 add_action('edit_user_profile', [$this->elementService, 'addUserMenuPage']);
152 add_action('plugins_loaded', [$this, 'initializeStatisticsIfNeeded']);
153
154 add_action('wp_enqueue_scripts', [$this, 'addPublicScripts']);
155
156 $this->addMiowebHooks();
157 $this->addDiviHooks();
158
159 add_image_size('level-selection', 300, 164, true);
160 add_filter('login_redirect', [$this->fapiMemberPlugin, 'loginRedirect'], 5, 3);
161 add_filter('show_admin_bar', [$this->elementService, 'hideAdminBar']);
162
163 // filters block to render by section and levels provided
164 add_filter(
165 'render_block',
166 function ($blockContent, $block) {
167 if (!isset($block['attrs']['hasSectionOrLevel'])) {
168 return $blockContent;
169 }
170
171 if (!isset($block['attrs']['fapiSectionAndLevels'])) {
172 return $blockContent;
173 }
174
175 if (DisplayHelper::shouldContentBeRendered(
176 (string) $block['attrs']['hasSectionOrLevel'],
177 $block['attrs']['fapiSectionAndLevels']
178 )) {
179 return $blockContent;
180 }
181
182 return '';
183 },
184 15,
185 2
186 );
187
188 // WPS hide login plugin
189 add_filter('whl_logged_in_redirect', [$this->redirectService, 'loggedInRedirect'], 1);
190 add_filter('whl_logged_in_redirect', [$this->redirectService, 'loggedInRedirect'], 1);
191 }
192
193 private function addInitHooks(): void
194 {
195 add_action('init', [$this, 'registerLevelsTaxonomy']);
196 add_action('init', [$this, 'registerRoles']);
197 add_action('init', [$this, 'addShortcodes']);
198 add_action('init', [$this->fapiMemberPlugin, 'checkTimedLevelUnlock']);
199 add_action('init', [$this->statisticsService, 'handleUserActive']);
200 }
201
202 private function addAdminHooks(): void
203 {
204 add_action('admin_init', [$this, 'registerSettings']);
205 add_action('admin_menu', [$this->elementService, 'addAdminMenu']);
206 add_action('admin_enqueue_scripts', [$this, 'addScripts']);
207 add_action('admin_enqueue_scripts', [$this, 'addApiNonce']);
208 add_action('admin_enqueue_scripts', [$this, 'checkFapiMemberPlusStatus']);
209 add_action('admin_enqueue_scripts', [$this, 'checkSimpleShopStatus']);
210
211 }
212
213 private function addMiowebHooks(): void
214 {
215 add_action('wp_ajax_open_element_setting', [$this->fapiMemberMioweb, 'addSetting']);
216 add_action('wp_ajax_open_row_setting', [$this->fapiMemberMioweb, 'addSetting']);
217 add_action('mw_page_init', [$this->fapiMemberMioweb, 'hideContentIfNeeded']);
218 }
219
220 public function addDiviHooks(): void
221 {
222 add_action('divi_extensions_init', [$this, 'initializeDiviExtension']);
223
224 add_filter('et_builder_get_parent_modules', [$this->fapiMemberDivi, 'addToggle']);
225
226 foreach ($this->fapiMemberDivi->allowedModuleSlugs as $slug) {
227 add_filter("et_pb_all_fields_unprocessed_" . $slug, [$this->fapiMemberDivi, 'addFields']);
228 }
229
230 add_filter('et_pb_module_content', [$this->fapiMemberDivi, 'hideElements'], 10, 4);
231 }
232
233 public function initializeDiviExtension(): void
234 {
235 require_once plugin_dir_path(__FILE__) . 'Divi/includes/FmDivi.php';
236 }
237
238 function addApiNonce(): void
239 {
240 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
241 $nonce = wp_create_nonce('wp_rest');
242 echo "<script>window.apiInternalAccessNonce = '{$nonce}'</script>";
243 }
244
245 }
246
247 function checkFapiMemberPlusStatus(): void
248 {
249 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
250 $licenceActive = $this->apiService->checkLicence();
251
252 echo "<script>
253 window.licenceActive = '{$licenceActive}'
254 </script>";
255 }
256 }
257
258 function checkSimpleShopStatus(): void
259 {
260 if (current_user_can(UserPermission::REQUIRED_CAPABILITY)) {
261 $simpleShopActive = is_plugin_active('simpleshop-cz/simpleshop-cz.php') && class_exists('Redbit\SimpleShop\WpPlugin\Group');
262
263 $ssSections = [];
264
265 if (!$simpleShopActive) {
266 echo "<script>
267 window.simpleShopToFAPIMember = false
268 </script>";
269
270 return;
271 }
272
273 $groups = new \Redbit\SimpleShop\WpPlugin\Group();
274
275 foreach ($groups->get_groups() as $groupId => $group) {
276 $group = new \Redbit\SimpleShop\WpPlugin\Group($groupId);
277
278 $ssSections[] = [
279 'id' => $group->id,
280 'name' => $group->name,
281 'users' => array_values(array_map(function ($user) use ($groupId) {
282 $membership = new \Redbit\SimpleShop\WpPlugin\Membership($user->ID);
283
284 return [
285 'id' => $user->ID,
286 'email' => $user->user_email,
287 'registered' => $membership->groups[$groupId]['subscription_date'] ?? null,
288 'until' => $membership->groups[$groupId]['valid_to'] ?? null,
289 ];
290 }, $group->get_users())),
291 ];
292 }
293
294 $pagesGroups = [];
295
296 $pages = get_posts([
297 'post_type' => 'page',
298 'numberposts' => -1,
299 ]);
300
301 $ss = \Redbit\SimpleShop\WpPlugin\SimpleShop::getInstance();
302
303 foreach ($pages as $page) {
304 $pagesGroups[] = [
305 'id' => $page->ID,
306 'name' => $page->post_title,
307 'groups' => $ss->get_access()->get_post_groups($page->ID),
308 ];
309 }
310
311 echo "<script>
312 window.simpleShopToFAPIMember = true
313 window.ssSections = " . json_encode($ssSections) . "
314 window.ssPagesGroups = " . json_encode($pagesGroups) . "
315 </script>";
316 }
317 }
318
319 public function addRestEndpoints(): void
320 {
321 $this->addRestEndpointV1('sections', 'handleApiSections', RequestMethodType::GET);
322 $this->addRestEndpointV1('sections-simple', 'handleApiSectionsSimple', RequestMethodType::GET);
323 $this->addRestEndpointV1('callback', 'handleApiCallback', RequestMethodType::POST);
324 $this->addRestEndpointV1('check-connection', 'handleApiCheckConnectionCallback', RequestMethodType::POST);
325 $this->addRestEndpointV1(
326 'list-forms/(?P<user>[^/]+(?:\+[^/]+)?)',
327 'handleApiListFormsCallback',
328 RequestMethodType::GET,
329 );
330 $this->addRestEndpointV1('list-users', 'handleApiUsernamesCallback', RequestMethodType::GET);
331
332 $this->addRestEndpointV2('sections');
333 $this->addRestEndpointV2('pages');
334 $this->addRestEndpointV2('emails');
335 $this->addRestEndpointV2('memberships');
336 $this->addRestEndpointV2('users');
337 $this->addRestEndpointV2('apiConnections');
338 $this->addRestEndpointV2('statistics');
339 }
340
341 public function addRestEndpointV2(
342 string $route
343 ): void
344 {
345 register_rest_route(
346 'fapi/v2',
347 '/' . $route,
348 [
349 'methods' => [RequestMethodType::GET, RequestMethodType::POST],
350 'callback' => [$this->apiController, 'handleRequest'],
351 'permission_callback' => function () {
352 return true;
353 },
354 ],
355 );
356 }
357
358 public function addRestEndpointV1(
359 string $route, string $functionName, string $method
360 ): void
361 {
362 register_rest_route(
363 'fapi/v1',
364 '/' . $route,
365 [
366 'methods' => $method,
367 'callback' => [$this->requestHandler, $functionName],
368 'permission_callback' => function () {
369 return true;
370 },
371 ],
372 );
373 }
374
375 public function addShortcodes(): void
376 {
377 add_shortcode('fapi-member-login', [$this->shortcodeSubstitutor, 'shortcodeLoginForm']);
378 add_shortcode('fapi-member-user', [$this->shortcodeSubstitutor, 'shortcodeUser']);
379 add_shortcode('fapi-member-user-section-expiration', [$this->shortcodeSubstitutor, 'shortcodeSectionExpirationDate']);
380 add_shortcode('fapi-member-level-unlock-date', [$this->shortcodeSubstitutor, 'shortcodeLevelUnlockDate']);
381 add_shortcode('fapi-member-unlock-level', [$this->shortcodeSubstitutor, 'shortcodeUnlockLevel']);
382 }
383
384 public function addScripts(): void
385 {
386 $this->registerStyles();
387 $this->registerScripts();
388
389 global $pagenow;
390
391 if ($pagenow === 'admin.php' || $pagenow === 'options-general.php') {
392 wp_enqueue_style('fapi-member-admin-font', '', [], FAPI_MEMBER_PLUGIN_VERSION);
393 wp_enqueue_style('fapi-member-swal-css', '', [], FAPI_MEMBER_PLUGIN_VERSION);
394 wp_enqueue_script('fapi-member-swal', '', [], FAPI_MEMBER_PLUGIN_VERSION);
395 wp_enqueue_script('fapi-member-swal-promise-polyfill', '', [], FAPI_MEMBER_PLUGIN_VERSION);
396 wp_enqueue_script('fapi-member-clipboard', '', [], FAPI_MEMBER_PLUGIN_VERSION);
397 wp_enqueue_script('fapi-member-main', '', [], FAPI_MEMBER_PLUGIN_VERSION);
398 }
399 if ($pagenow === 'user-edit.php') {
400 wp_enqueue_style('fapi-member-user-profile', '', [], FAPI_MEMBER_PLUGIN_VERSION);
401 wp_enqueue_script('fapi-member-main', '', [], FAPI_MEMBER_PLUGIN_VERSION);
402 }
403
404 wp_enqueue_script(
405 'fm-react-app',
406 trailingslashit(plugins_url('/', __FILE__)) . '../app/dist/bundle.js',
407 ['jquery', 'wp-element'],
408 FAPI_MEMBER_PLUGIN_VERSION,
409 true,
410 );
411
412 wp_localize_script('fm-react-app', 'environmentData', [
413 'timeZoneOffset' => get_option('gmt_offset'),
414 ]);
415 }
416
417 public function registerStyles(): void
418 {
419 wp_register_style(
420 'fapi-member-user-profile',
421 plugins_url('fapi-member/media/fapi-user-profile.css'),
422 [],
423 FAPI_MEMBER_PLUGIN_VERSION
424 );
425 wp_register_style(
426 'fapi-member-admin-font',
427 plugins_url('fapi-member/media/font/stylesheet.css'),
428 [],
429 FAPI_MEMBER_PLUGIN_VERSION
430 );
431 wp_register_style(
432 'fapi-member-swal-css',
433 plugins_url('fapi-member/media/dist/sweetalert2.min.css'),
434 [],
435 FAPI_MEMBER_PLUGIN_VERSION
436 );
437 wp_register_style(
438 'fapi-member-public-style',
439 plugins_url('fapi-member/media/fapi-member-public.css'),
440 [],
441 FAPI_MEMBER_PLUGIN_VERSION
442 );
443 }
444
445 public function registerScripts(): void
446 {
447 wp_register_script(
448 'fapi-member-swal',
449 plugins_url('fapi-member/media/dist/sweetalert2.js'),
450 [],
451 FAPI_MEMBER_PLUGIN_VERSION
452 );
453
454 wp_register_script(
455 'fapi-member-swal-promise-polyfill',
456 plugins_url('fapi-member/media/dist/polyfill.min.js'),
457 [],
458 FAPI_MEMBER_PLUGIN_VERSION
459 );
460
461 wp_register_script(
462 'fapi-member-clipboard',
463 plugins_url('fapi-member/media/dist/clipboard.min.js'),
464 [],
465 FAPI_MEMBER_PLUGIN_VERSION
466 );
467
468 if (FapiMemberPlugin::isDevelopment()) {
469 wp_register_script(
470 'fapi-member-main',
471 plugins_url('fapi-member/media/dist/fapi.dev.js'),
472 [],
473 FAPI_MEMBER_PLUGIN_VERSION
474 );
475 } else {
476 wp_register_script(
477 'fapi-member-main',
478 plugins_url('fapi-member/media/dist/fapi.dist.js'),
479 [],
480 FAPI_MEMBER_PLUGIN_VERSION
481 );
482 }
483 }
484
485 public
486 function addPublicScripts(): void
487 {
488 $this->registerPublicStyles();
489
490 wp_enqueue_style('fapi-member-public-style', '',
491 [],
492 FAPI_MEMBER_PLUGIN_VERSION);
493
494 if (defined('FAPI_SHOWING_LEVEL_SELECTION')) {
495 wp_register_style(
496 'fapi-member-public-levelselection-font',
497 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap',
498 [],
499 FAPI_MEMBER_PLUGIN_VERSION
500 );
501 wp_enqueue_style('fapi-member-public-levelselection-font', '',
502 [],
503 FAPI_MEMBER_PLUGIN_VERSION);
504 }
505 }
506
507 public function registerPublicStyles(): void
508 {
509 wp_register_style(
510 'fapi-member-public-style',
511 plugins_url('fapi-member/media/fapi-member-public.css'),
512 [],
513 FAPI_MEMBER_PLUGIN_VERSION
514 );
515 }
516
517 public function registerRoles(): void
518 {
519 if (get_role('member') === null) {
520 add_role('member', __('Člen', 'fapi-member'), get_role('subscriber')->capabilities);
521 }
522 }
523
524 public function registerSettings(): void
525 {
526 register_setting(
527 'options',
528 'fapiMemberApiEmail',
529 [
530 'type' => 'string',
531 'description' => __('Fapi Member - API e-mail', 'fapi-member'),
532 'show_in_rest' => false,
533 'default' => null,
534 ]
535 );
536 register_setting(
537 'options',
538 'fapiMemberApiKey',
539 [
540 'type' => 'string',
541 'description' => __('Fapi Member - API key', 'fapi-member'),
542 'show_in_rest' => false,
543 'default' => null,
544 ]
545 );
546 }
547
548 public function registerLevelsTaxonomy(): void
549 {
550 register_taxonomy(
551 'fapi_levels',
552 PostTypeHelper::getSupportedPostTypes(),
553 [
554 'public' => false,
555 'hierarchical' => true,
556 'show_ui' => false,
557 'show_in_rest' => false,
558 ]
559 );
560 }
561
562 public function initializeStatisticsIfNeeded(): void
563 {
564 if (!$this->membershipChangeRepository->tableExists()) {
565 $this->initializeMembershipChanges();
566 }
567
568 if (!$this->memberActivityRepository->tableExists()) {
569 $this->memberActivityRepository->createTableIfNeeded();
570 }
571 }
572
573 private function initializeMembershipChanges(): void
574 {
575 $this->membershipChangeRepository->createTableIfNeeded();
576
577 $memberships = $this->membershipRepository->getAll();
578
579 foreach ($memberships as $membershipsByUserId) {
580 foreach ($membershipsByUserId as $membership) {
581 $this->membershipChangeRepository->addChange(
582 $membership->toMembershipChange(
583 MembershipChangeType::CREATED,
584 $membership->getRegistered(),
585 )
586 );
587 }
588 }
589 }
590
591 public function registerUserFapiMemberTableColumn(): void
592 {
593 add_filter('manage_users_columns', [$this->elementService, 'addUserColumn']);
594 add_action('manage_users_custom_column', [$this->elementService, 'showUserColumnContent'], 10, 3);
595 add_action('show_user_profile', [$this->elementService, 'addUserProfileSection']);
596 add_action('edit_user_profile', [$this->elementService, 'addUserProfileSection']);
597 }
598
599 }
600