PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / app / AutoLaunch / Admin.php

Admin.php in Extendify 3.1.5, at app/AutoLaunch/Admin.php

274 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Admin.
5 */
6
7 namespace Extendify\AutoLaunch;
8
9 defined('ABSPATH') || die('No direct access.');
10
11 use Extendify\Config;
12 use Extendify\Insights;
13 use Extendify\PartnerData;
14 use Extendify\Shared\Services\LaunchUpdate\LaunchUpdater;
15
16 /**
17 * This class handles any file loading for the admin area.
18 */
19
20 class Admin
21 {
22 /**
23 * Adds various actions to set up the page
24 *
25 * @return void
26 */
27 public function __construct()
28 {
29 \add_action('admin_enqueue_scripts', [$this, 'addScopedScriptsAndStyles']);
30 }
31
32 /**
33 * Adds various JS scripts
34 *
35 * @return void
36 */
37 public function addScopedScriptsAndStyles()
38 {
39 $version = constant('EXTENDIFY_DEVMODE') ? uniqid() : Config::$version;
40 $scriptAssetPath = EXTENDIFY_PATH . 'public/build/' . Config::$assetManifest['extendify-launch.php'];
41 $fallback = [
42 'dependencies' => [],
43 'version' => $version,
44 ];
45 $scriptAsset = file_exists($scriptAssetPath) ? require $scriptAssetPath : $fallback;
46 foreach ($scriptAsset['dependencies'] as $style) {
47 wp_enqueue_style($style);
48 }
49
50 \wp_enqueue_script(
51 Config::$slug . '-launch-scripts',
52 EXTENDIFY_BASE_URL . 'public/build/' . Config::$assetManifest['extendify-auto-launch.js'],
53 array_merge([Config::$slug . '-shared-scripts'], $scriptAsset['dependencies']),
54 $scriptAsset['version'],
55 true
56 );
57
58 if (constant('EXTENDIFY_DEVMODE')) {
59 // In dev, reset the variaton to the default.
60 wp_update_post([
61 'ID' => \WP_Theme_JSON_Resolver::get_user_global_styles_post_id(),
62 'post_content' => \wp_json_encode([
63 'styles' => [],
64 'settings' => [],
65 'isGlobalStylesUserThemeJSON' => true,
66 'version' => 2,
67 ]),
68 ]);
69 }
70
71 $showLaunchUpdate = PartnerData::setting('showLaunchUpdate');
72 $launchUpdate = $showLaunchUpdate ? LaunchUpdater::claimPendingUpdates() : [];
73 \wp_add_inline_script(
74 Config::$slug . '-launch-scripts',
75 'window.extLaunchData = ' . \wp_json_encode([
76 'editorStyles' => \get_block_editor_settings([], new \WP_Block_Editor_Context()),
77 'wpRoot' => \rest_url(),
78 'activeTests' => \get_option(Insights::ACTIVE_TESTS_OPTION, []),
79 'showLaunchTitle' => (bool) PartnerData::setting('showLaunchTitle'),
80 'resetSiteInformation' => [
81 'pagesIds' => array_map('esc_attr', $this->getLaunchCreatedPages()),
82 'navigationsIds' => array_map('esc_attr', $this->getLaunchCreatedNavigations()),
83 'templatePartsIds' => array_map('esc_attr', $this->getTemplatePartIds()),
84 'pageWithTitleTemplateId' => esc_attr($this->getPageWithTitleTemplateId()),
85 ],
86 'urlParams' => (object) $this->getURLParams(),
87 'helloWorldPostSlug' =>
88 // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
89 \_x(
90 'hello-world',
91 'Default post slug'
92 ),
93 'hideAutoLaunchExitLink' => (bool) PartnerData::setting('hideLaunchExitLink'),
94 'themeUpdateNeeded' => !empty($launchUpdate['theme']),
95 'pluginUpdateNeeded' => !empty($launchUpdate['plugin']),
96 'launchUpdateAttempt' => $launchUpdate['attempt'] ?? 0,
97 'launchUpdateStale' => (object) ($launchUpdate['stale'] ?? []),
98 'pluginUpdateViaRest' => LaunchUpdater::isWpOrgBuild(),
99 'pluginSlug' => Config::$slug,
100 ]),
101 'before'
102 );
103
104 \wp_set_script_translations(
105 Config::$slug . '-launch-scripts',
106 'extendify-local',
107 EXTENDIFY_PATH . 'languages/js'
108 );
109
110 \wp_enqueue_style(
111 Config::$slug . '-launch-styles',
112 EXTENDIFY_BASE_URL . 'public/build/' . Config::$assetManifest['extendify-auto-launch.css'],
113 [Config::$slug . '-shared-common-styles'],
114 Config::$version
115 );
116 }
117
118 /**
119 * Returns all the pages created by Extendify.
120 *
121 * @return array
122 */
123 public static function getLaunchCreatedPages()
124 {
125 $posts = get_posts([
126 'numberposts' => -1,
127 'post_status' => 'publish',
128 'post_type' => ['page', 'post'],
129 // only return the ID field.
130 'fields' => 'ids',
131 ]);
132
133 return array_values(array_filter(array_map(function ($post) {
134 return get_post_meta($post, 'made_with_extendify_launch') ? $post : false;
135 }, $posts)));
136 }
137
138 /**
139 * Returns all the navigations created by Extendify.
140 *
141 * @return array
142 */
143 public static function getLaunchCreatedNavigations()
144 {
145 $posts = get_posts([
146 'numberposts' => -1,
147 'post_status' => 'publish',
148 'post_type' => 'wp_navigation',
149 // only return the ID field.
150 'fields' => 'ids',
151 ]);
152
153 return array_values(array_filter(array_map(function ($post) {
154 return get_post_meta($post, 'made_with_extendify_launch') ? $post : false;
155 }, $posts)));
156 }
157
158 /**
159 * Returns the idz of the header and footer template part created by extendify.
160 *
161 * @return array
162 */
163 public static function getTemplatePartIds()
164 {
165 return [
166 (get_block_template(get_stylesheet() . '//header', 'wp_template_part')->id ?? ''),
167 (get_block_template(get_stylesheet() . '//footer', 'wp_template_part')->id ?? ''),
168 ];
169 }
170
171
172 /**
173 * Returns the id of the page-with-title template for the current theme.
174 *
175 * @return string
176 */
177 public static function getPageWithTitleTemplateId()
178 {
179 $template = get_block_template(get_stylesheet() . '//page-with-title', 'wp_template');
180 return $template && !empty($template->id) ? $template->id : '';
181 }
182
183 /**
184 * Parses and sanitizes URL parameters against an allowlist.
185 *
186 * @return array
187 */
188 private function getURLParams()
189 {
190 $allowed = [
191 'type' => 'string',
192 'title' => 'string',
193 'description' => 'string',
194 'objective' => 'string',
195 'category' => 'string',
196 'structure' => 'string',
197 'tone' => 'string[]',
198 'products' => 'string|boolean',
199 'appointments' => 'boolean',
200 'events' => 'boolean',
201 'donations' => 'boolean',
202 'multilingual' => 'boolean',
203 'contact' => 'boolean',
204 'address' => 'string|boolean',
205 'blog' => 'boolean',
206 'landing-page' => 'string',
207 'cta-link' => 'string|boolean',
208 'build-id' => 'string',
209 'go' => 'boolean',
210 ];
211
212 $params = [];
213 foreach ($allowed as $param => $type) {
214 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
215 if (!isset($_GET[$param])) {
216 continue;
217 }
218
219 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
220 $raw = sanitize_text_field(wp_unslash($_GET[$param]));
221 if ($raw === '') {
222 continue;
223 }
224
225 if ($type === 'string[]') {
226 $parts = is_array($raw) ? $raw : explode(',', (string) $raw);
227
228 $items = array_values(array_filter(
229 array_map(
230 static function ($v) {
231 return sanitize_text_field((string) $v);
232 },
233 $parts
234 ),
235 static function ($v) {
236 return $v !== '';
237 }
238 ));
239
240 if (empty($items)) {
241 continue;
242 }
243
244 $params[$param] = $items;
245 continue;
246 }
247
248 if (strtolower($raw) === 'none') {
249 $params[$param] = false;
250 continue;
251 }
252
253 $asBool = filter_var($raw, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
254
255 if ($type === 'boolean') {
256 if ($asBool === null) {
257 continue;
258 }
259 $params[$param] = $asBool;
260 continue;
261 }
262
263 if ($type === 'string|boolean' && $asBool !== null) {
264 $params[$param] = $asBool;
265 continue;
266 }
267
268 $params[$param] = $raw;
269 }
270
271 return $params;
272 }
273 }
274