PluginProbe
The Innovative Form Builder – IvyForms / 1.5.1
The Innovative Form Builder – IvyForms v1.5.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / backend / src / Services / Menu / MenuMapper.php

MenuMapper.php in The Innovative Form Builder – IvyForms 1.5.1, at backend/src/Services/Menu/MenuMapper.php

169 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IvyForms\Services\Menu;
4
5 use IvyForms\Services\API\IvyFormsAPI;
6 use IvyForms\Services\Payment\PaymentsFeature;
7 use IvyForms\Services\Permissions\IvyFormsAccess;
8 use IvyForms\Services\Permissions\PermissionResolver;
9 use IvyForms\Services\Translations\BackendStrings;
10
11 /**
12 * Class Menu
13 */
14 class MenuMapper
15 {
16 private ?PermissionResolver $permissionResolver;
17
18 public function __construct(
19 ?PermissionResolver $permissionResolver = null
20 ) {
21 $this->permissionResolver = $permissionResolver;
22 }
23
24 /**
25 * @return mixed[]
26 */
27 public function __invoke(): array
28 {
29 $menus =
30 [
31 // [
32 // 'parentSlug' => 'ivyforms',
33 // 'pageTitle' => 'Dashboard',
34 // 'menuTitle' => BackendStrings::getDashboardStrings()['dashboard'],
35 // 'capability' => 'manage_options',
36 // 'menuSlug' => 'ivyforms-dashboard',
37 // ],
38 [
39 'parentSlug' => 'ivyforms',
40 'pageTitle' => 'All Forms',
41 'menuTitle' => BackendStrings::getCommonStrings()['all_forms'],
42 // WP checks this cap on the admin menu row; fine-grained access uses PermissionResolver below.
43 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
44 'menuSlug' => 'ivyforms-forms',
45 ],
46 [
47 'parentSlug' => 'ivyforms',
48 'pageTitle' => 'New form',
49 'menuTitle' => BackendStrings::getCommonStrings()['new_form'],
50 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
51 'menuSlug' => 'ivyforms-builder',
52 ],
53 [
54 'parentSlug' => 'ivyforms',
55 'pageTitle' => 'Entries',
56 'menuTitle' => BackendStrings::getEntriesStrings()['entries'],
57 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
58 'menuSlug' => 'ivyforms-entries',
59 ],
60 [
61 'parentSlug' => 'ivyforms',
62 'pageTitle' => 'Payments',
63 'menuTitle' => BackendStrings::getPaymentStrings()['payments'],
64 'capability' => 'manage_options',
65 'menuSlug' => 'ivyforms-payments',
66 ],
67 [
68 'parentSlug' => 'ivyforms',
69 'pageTitle' => 'Settings',
70 'menuTitle' => BackendStrings::getCommonStrings()['settings'],
71 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
72 'menuSlug' => 'ivyforms-settings',
73 ],
74 [
75 'parentSlug' => 'ivyforms',
76 'pageTitle' => 'Integrations',
77 'menuTitle' => BackendStrings::getIntegrationsStrings()['integrations'],
78 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
79 'menuSlug' => 'ivyforms-integrations',
80 ],
81 ];
82
83 // Payments page stays hidden while Stripe and PayPal are turned off
84 if (!PaymentsFeature::isEnabled()) {
85 $menus = array_values(array_filter(
86 $menus,
87 static fn(array $menu): bool => $menu['menuSlug'] !== 'ivyforms-payments'
88 ));
89 }
90
91 // Add "Upgrade to PRO" menu only if Pro plugin is not installed/activated
92 if (!IvyFormsAPI::isProPluginActive()) {
93 $menus[] = [
94 'parentSlug' => 'ivyforms',
95 'pageTitle' => 'Upgrade to PRO',
96 // phpcs:ignore Generic.Files.LineLength.TooLong
97 'menuTitle' => '<span class="ivyforms-upgrade-to-pro">' . __('Upgrade to PRO', 'ivyforms') . '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M3.30739 5.78346L5.09363 3.36669C6.24826 1.80449 6.82558 1.02339 7.3642 1.18846C7.90283 1.35352 7.90283 2.31153 7.90283 4.22757V4.40823C7.90283 5.0993 7.90283 5.44483 8.12364 5.66157L8.13533 5.6728C8.36091 5.88496 8.72054 5.88496 9.4398 5.88496C10.7341 5.88496 11.3813 5.88496 11.6 6.27751C11.6037 6.28401 11.6072 6.29056 11.6106 6.29716C11.8171 6.69579 11.4424 7.20277 10.6929 8.21673L8.90667 10.6335C7.75202 12.1957 7.1747 12.9768 6.63607 12.8117C6.09744 12.6466 6.09746 11.6886 6.09748 9.77256L6.09749 9.59198C6.0975 8.9009 6.0975 8.55536 5.87669 8.33861L5.865 8.32739C5.63942 8.11522 5.27979 8.11522 4.56052 8.11522C3.26618 8.11522 2.61901 8.11522 2.40029 7.72267C2.39666 7.71617 2.39314 7.70962 2.38973 7.70302C2.18325 7.3044 2.55796 6.79742 3.30739 5.78346Z" fill="white"/></svg></span>',
98 'capability' => IvyFormsAccess::CAP_ACCESS_PLUGIN,
99 // phpcs:ignore Generic.Files.LineLength.TooLong
100 'menuSlug' => 'https://ivyforms.com/pricing?utm_source=ivy-lite&utm_medium=lite-upgrade&utm_content=ivy&utm_campaign=ivy',
101 'isExternal' => true,
102 ];
103 }
104
105 $visibleMenus = [];
106 foreach ($menus as $menu) {
107 if (!$this->canAccessMenu($menu)) {
108 continue;
109 }
110 $visibleMenus[] = $menu;
111 }
112
113 return $visibleMenus;
114 }
115
116 /**
117 * @param mixed[] $menu
118 */
119 private function canAccessMenu(array $menu): bool
120 {
121 if (IvyFormsAccess::hasImplicitElevatedAccess()) {
122 return true;
123 }
124
125 $resolver = $this->permissionResolver;
126 $user = wp_get_current_user();
127 if (!$resolver || !$user instanceof \WP_User || (int) $user->ID <= 0) {
128 return false;
129 }
130
131 $slug = (string) ($menu['menuSlug'] ?? '');
132 if ($slug === '' || strpos($slug, 'http') === 0) {
133 return true;
134 }
135
136 return $this->canAccessBySlug($slug, $resolver, $user);
137 }
138
139 /**
140 * @param list<string> $permissionKeys
141 */
142 private function userCanAnyOf(PermissionResolver $resolver, \WP_User $user, array $permissionKeys): bool
143 {
144 return $resolver->userCanAnyOf($user, $permissionKeys);
145 }
146
147 private function canAccessBySlug(string $slug, PermissionResolver $resolver, \WP_User $user): bool
148 {
149 if ($slug === 'ivyforms-forms') {
150 return $this->userCanAnyOf($resolver, $user, [
151 'view_forms_list',
152 'add_edit_forms',
153 'delete_forms',
154 ]);
155 }
156 if ($slug === 'ivyforms-builder') {
157 return $resolver->userCanIncludingFormScoped('add_edit_forms', $user, null);
158 }
159 if ($slug === 'ivyforms-entries') {
160 return $this->userCanAnyOf($resolver, $user, ['view_entries_admin', 'delete_entries_admin']);
161 }
162 if (in_array($slug, ['ivyforms-settings', 'ivyforms-integrations'], true)) {
163 return $resolver->userCanIncludingFormScoped('access_settings_page', $user, null);
164 }
165
166 return true;
167 }
168 }
169