PluginProbe
The Innovative Form Builder – IvyForms / 1.5
The Innovative Form Builder – IvyForms v1.5
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
← All changes | backend/src/Services/Menu/MenuService.php +106 -16 1.1 → 1.5 View file →
@@ -2,9 +2,13 @@
2 2
3 3 namespace IvyForms\Services\Menu;
4 4
5 5 use IvyForms\Routes\Routes;
6 +use IvyForms\Services\Ai\AiAvailability;
7 +use IvyForms\Services\Payment\PaymentsFeature;
6 8 use IvyForms\Services\Settings\SettingsService;
9 +use IvyForms\Services\Permissions\IvyFormsAccess;
10 +use IvyForms\Services\Permissions\RoutePermissionService;
7 11 use IvyForms\Services\Translations\BackendStrings;
8 12
9 13 /**
10 14 * Renders menu pages
@@ -10,9 +14,65 @@
10 14 * Renders menu pages
11 15 */
12 16 class MenuService
13 17 {
18 + private ?RoutePermissionService $routePermissionService;
19 +
20 + public function __construct(?RoutePermissionService $routePermissionService = null)
21 + {
22 + $this->routePermissionService = $routePermissionService;
23 + }
24 +
14 25 /**
26 + * Effective IvyForms permissions for the current user, keyed by permission key.
27 + *
28 + * Exposed to the frontend so the UI can gate actions (hide "+ Form", etc.) to match
29 + * the backend permission checks. Backend validation always remains the source of truth.
30 + *
31 + * @return array<string, bool>
32 + */
33 + private function currentUserPermissions(): array
34 + {
35 + $perm = $this->routePermissionService;
36 + if ($perm === null) {
37 + return [];
38 + }
39 +
40 + return [
41 + 'view_forms_list' => $perm->canViewForms(),
42 + 'add_edit_forms' => $perm->canEditForms(),
43 + 'delete_forms' => $perm->canDeleteForms(),
44 + 'view_entries_admin' => $perm->canViewEntries(),
45 + 'delete_entries_admin' => $perm->canDeleteEntries(),
46 + 'access_settings_page' => $perm->canAccessSettings(),
47 + ];
48 + }
49 +
50 + /**
51 + * @return array{available: bool, status: string, actionUrl: string, connectorsUrl: string}
52 + */
53 + private function currentAiAvailability(): array
54 + {
55 + $status = AiAvailability::getStatus();
56 + $actionUrl = '';
57 +
58 + if ($status === AiAvailability::STATUS_WORDPRESS_UPDATE_REQUIRED) {
59 + $actionUrl = AiAvailability::getWordPressUpdateUrl();
60 + } elseif ($status === AiAvailability::STATUS_AI_CLIENT_MISSING) {
61 + $actionUrl = AiAvailability::getAiPluginInstallUrl();
62 + } elseif ($status === AiAvailability::STATUS_TEXT_GENERATION_UNAVAILABLE) {
63 + $actionUrl = AiAvailability::getConnectorsSettingsUrl();
64 + }
65 +
66 + return [
67 + 'available' => $status === AiAvailability::STATUS_AVAILABLE,
68 + 'status' => $status,
69 + 'actionUrl' => $actionUrl,
70 + 'connectorsUrl' => AiAvailability::getConnectorsSettingsUrl(),
71 + ];
72 + }
73 +
74 + /**
15 75 * Submenu page render function
16 76 * @param string $page
17 77 */
18 78 public function render(string $page): void
@@ -85,9 +145,35 @@
85 145 // $scriptVersion
86 146 // );
87 147 }
88 148
89 - // Localize scripts
149 + $this->localizeScripts($scriptId);
150 +
151 + /**
152 + * Hook to enqueue additional scripts and styles in admin area
153 + * @since 0.1.0
154 + *
155 + * Arguments:
156 + * - string $scriptId The main script handle ID (for dependencies)
157 + * - string $page WordPress admin menu slug (e.g. ivyforms-builder)
158 + */
159 + do_action('ivyforms/admin/enqueue_scripts', $scriptId, $page);
160 +
161 + if ($page === 'ivyforms-builder') {
162 + // FormBuilder.vue welcome-page image picker (Pro); not needed on other admin pages
163 + wp_enqueue_media();
164 + }
165 +
166 + include IVYFORMS_PATH . '/view/backend/view.php';
167 + }
168 +
169 + /**
170 + * Localize all admin data required by the frontend app.
171 + *
172 + * @param string $scriptId Main script handle used as the localization target.
173 + */
174 + private function localizeScripts(string $scriptId): void
175 + {
90 176 $settingsStorage = new SettingsService();
91 177
92 178 wp_localize_script(
93 179 $scriptId,
@@ -98,8 +184,9 @@
98 184 $backendLabels = array_merge(
99 185 BackendStrings::getNewFormStrings(),
100 186 BackendStrings::getStylesFormBuilderStrings(),
101 187 BackendStrings::getSettingsFormBuilderStrings(),
188 + BackendStrings::getWelcomePageStrings(),
102 189 BackendStrings::getResultsFormBuilderStrings(),
103 190 BackendStrings::getEmptyStatesStrings(),
104 191 BackendStrings::getEntityFormStrings(),
105 192 BackendStrings::getAllFormsStrings(),
@@ -109,12 +196,15 @@
109 196 BackendStrings::getEntriesStrings(),
110 197 BackendStrings::getIntegrationsStrings(),
111 198 BackendStrings::getExceptionStrings(),
112 199 BackendStrings::getTemplateStrings(),
200 + BackendStrings::getAiStrings(),
113 201 BackendStrings::getSettingsStrings(),
114 202 BackendStrings::getSecurityStrings(),
203 + BackendStrings::getPermissionsStrings(),
115 204 BackendStrings::getProUpgradeDialogStrings(),
116 - BackendStrings::getChangelogStrings()
205 + BackendStrings::getChangelogStrings(),
206 + BackendStrings::getPaymentStrings()
117 207 );
118 208
119 209 /**
120 210 * Filter backend labels before localizing
@@ -138,17 +228,28 @@
138 228 'pluginURL' => IVYFORMS_URL,
139 229 'siteURL' => esc_url_raw(site_url()),
140 230 ]
141 231 );
232 +
233 + $aiAvailability = $this->currentAiAvailability();
234 +
142 235 wp_localize_script(
143 236 $scriptId,
144 237 'wpIvyApiSettings',
145 238 [
146 - 'root' => esc_url_raw(rest_url()),
147 - 'nonce' => wp_create_nonce('wp_rest'),
148 - 'namespace' => Routes::$routeNamespace,
239 + 'root' => esc_url_raw(rest_url()),
240 + 'nonce' => wp_create_nonce('wp_rest'),
241 + 'namespace' => Routes::$routeNamespace,
242 + 'isAdministrator' => IvyFormsAccess::currentUserCanAccessPermissionsSettings(),
243 + 'permissions' => $this->currentUserPermissions(),
244 + 'aiAvailable' => $aiAvailability['available'],
245 + 'aiStatus' => $aiAvailability['status'],
246 + 'aiActionUrl' => $aiAvailability['actionUrl'],
247 + 'aiConnectorsUrl' => $aiAvailability['connectorsUrl'],
248 + 'paymentsEnabled' => PaymentsFeature::isEnabled(),
149 249 ]
150 250 );
251 +
151 252 wp_localize_script(
152 253 $scriptId,
153 254 'wpIvyDateFormat',
154 255 [
@@ -157,17 +258,6 @@
157 258 'dateTimeFormat' => get_option('date_format') . ' ' . get_option('time_format'),
158 259 'locale' => get_locale(),
159 260 ]
160 261 );
161 -
162 - /**
163 - * Hook to enqueue additional scripts and styles in admin area
164 - * @since 0.1.0
165 - *
166 - * Arguments:
167 - * - string $scriptId The main script handle ID (for dependencies)
168 - */
169 - do_action('ivyforms/admin/enqueue_scripts', $scriptId);
170 -
171 - include IVYFORMS_PATH . '/view/backend/view.php';
172 262 }
173 263 }