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