Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 115 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
SettingsController | |
0.00% |
0 / 115 |
|
0.00% |
0 / 6 |
1260 | |
0.00% |
0 / 1 |
register_routes | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
2 | |||
get_item | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
update_item | |
0.00% |
0 / 42 |
|
0.00% |
0 / 1 |
272 | |||
get_current_settings | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
72 | |||
initialize | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
30 | |||
validate_twitter_id | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | namespace NewfoldLabs\WP\Module\Onboarding\RestApi; |
3 | |
4 | use NewfoldLabs\WP\Module\Onboarding\Permissions; |
5 | use NewfoldLabs\WP\Module\Onboarding\Data\Options; |
6 | use NewfoldLabs\WP\Module\Onboarding\Data\Config; |
7 | use NewfoldLabs\WP\Module\Onboarding\WP_Config; |
8 | |
9 | /** |
10 | * Class SettingsController |
11 | */ |
12 | class SettingsController { |
13 | |
14 | /** |
15 | * The namespace of this controller's route. |
16 | * |
17 | * @var string |
18 | */ |
19 | protected $namespace = 'newfold-onboarding/v1'; |
20 | |
21 | /** |
22 | * The endpoint base |
23 | * |
24 | * @var string |
25 | */ |
26 | protected $rest_base = '/settings'; |
27 | |
28 | /** |
29 | * Array of defaults for the option. |
30 | * |
31 | * Shouldn't be requested directly, use $this->get_defaults(); |
32 | * |
33 | * @var array |
34 | */ |
35 | protected $defaults = array( |
36 | 'facebook_site' => '', // Text field. |
37 | 'instagram_url' => '', |
38 | 'linkedin_url' => '', |
39 | 'myspace_url' => '', |
40 | 'og_default_image' => '', // Text field. |
41 | 'og_default_image_id' => '', |
42 | 'og_frontpage_title' => '', // Text field. |
43 | 'og_frontpage_desc' => '', // Text field. |
44 | 'og_frontpage_image' => '', // Text field. |
45 | 'og_frontpage_image_id' => '', |
46 | 'opengraph' => true, |
47 | 'pinterest_url' => '', |
48 | 'pinterestverify' => '', |
49 | 'twitter' => true, |
50 | 'twitter_site' => '', // Text field. |
51 | 'twitter_card_type' => 'summary_large_image', |
52 | 'youtube_url' => '', |
53 | 'wikipedia_url' => '', |
54 | 'other_social_urls' => array(), |
55 | 'mastodon_url' => '', |
56 | ); |
57 | |
58 | /** |
59 | * Validate these URL keys in the data provided |
60 | * |
61 | * @var array |
62 | */ |
63 | protected $social_urls_to_validate = array( |
64 | 'facebook_site', |
65 | 'instagram_url', |
66 | 'linkedin_url', |
67 | 'twitter_site', |
68 | 'myspace_url', |
69 | 'pinterest_url', |
70 | 'youtube_url', |
71 | 'wikipedia_url', |
72 | 'other_social_urls', |
73 | 'mastodon_url', |
74 | ); |
75 | |
76 | /** |
77 | * Store for invalid urls |
78 | * |
79 | * @var array |
80 | */ |
81 | protected $invalid_urls = array(); |
82 | |
83 | /** |
84 | * Registers the settings route |
85 | */ |
86 | public function register_routes() { |
87 | \register_rest_route( |
88 | $this->namespace, |
89 | $this->rest_base, |
90 | array( |
91 | array( |
92 | 'methods' => \WP_REST_Server::READABLE, |
93 | 'callback' => array( $this, 'get_item' ), |
94 | 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ), |
95 | ), |
96 | array( |
97 | 'methods' => \WP_REST_Server::EDITABLE, |
98 | 'callback' => array( $this, 'update_item' ), |
99 | 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ), |
100 | ), |
101 | ) |
102 | ); |
103 | |
104 | \register_rest_route( |
105 | $this->namespace, |
106 | $this->rest_base . '/initialize', |
107 | array( |
108 | array( |
109 | 'methods' => \WP_REST_Server::EDITABLE, |
110 | 'callback' => array( $this, 'initialize' ), |
111 | 'permission_callback' => array( Permissions::class, 'rest_is_authorized_admin' ), |
112 | ), |
113 | ) |
114 | ); |
115 | } |
116 | |
117 | /** |
118 | * Retrieves the settings handled by the plugin. |
119 | * |
120 | * @return \WP_REST_Response |
121 | */ |
122 | public function get_item() { |
123 | return new \WP_REST_Response( $this->get_current_settings() ); |
124 | } |
125 | |
126 | /** |
127 | * Updates settings for the settings object. |
128 | * |
129 | * @param \WP_REST_Request $request Full details about the request. |
130 | * |
131 | * @return \WP_REST_Response|\WP_Error |
132 | */ |
133 | public function update_item( \WP_REST_Request $request ) { |
134 | $settings = $this->get_current_settings(); |
135 | $params = $request->get_json_params(); |
136 | |
137 | // Check if $params is an array, else return the current settings that we have. |
138 | if ( ! is_array( $params ) ) { |
139 | return $settings; |
140 | } |
141 | |
142 | // check if all the param keys are present in the yoast social keys |
143 | foreach ( $params as $param_key => $param_value ) { |
144 | if ( ! array_key_exists( $param_key, $this->defaults ) ) { |
145 | $this->invalid_urls[] = $param_key; |
146 | unset( $params[ $param_key ] ); |
147 | continue; |
148 | } |
149 | |
150 | // check for proper url |
151 | if ( in_array( $param_key, $this->social_urls_to_validate, true ) ) { |
152 | switch ( $param_key ) { |
153 | case 'twitter_site': |
154 | if ( ! empty( $params['twitter_site'] ) ) { |
155 | $twitter_id = $this->validate_twitter_id( $params['twitter_site'] ); |
156 | if ( false === $twitter_id ) { |
157 | $this->invalid_urls[] = 'twitter_site'; |
158 | unset( $params['twitter_site'] ); |
159 | } else { |
160 | $params['twitter_site'] = $twitter_id; |
161 | } |
162 | } |
163 | break; |
164 | case 'other_social_urls': |
165 | $filtered_social_urls = array(); |
166 | foreach ( $param_value as $param_key_osu => $param_url ) { |
167 | if ( ! empty( $param_url ) ) { |
168 | if ( \wp_http_validate_url( $param_url ) ) { |
169 | $filtered_social_urls[] = \sanitize_text_field( $param_url ); |
170 | } else { |
171 | $this->invalid_urls[] = $param_key_osu; |
172 | } |
173 | } |
174 | } |
175 | $params[ $param_key ] = $filtered_social_urls; |
176 | break; |
177 | default: |
178 | $param[ $param_key ] = \sanitize_text_field( $param_value ); |
179 | if ( ! empty( $param_value ) && ! \wp_http_validate_url( $param_value ) ) { |
180 | $this->invalid_urls[] = $param_key; |
181 | unset( $params[ $param_key ] ); |
182 | } |
183 | break; |
184 | } |
185 | } |
186 | } |
187 | $settings = array_merge( $settings, $params ); |
188 | |
189 | \update_option( Options::get_option_name( 'wpseo_social', false ), $settings ); |
190 | |
191 | if ( ! empty( $this->invalid_urls ) ) { |
192 | $error_keys = implode( ', ', $this->invalid_urls ); |
193 | return new \WP_Error( |
194 | 'invalid_urls', |
195 | "Invalid url(s) provided for {$error_keys}.", |
196 | array( 'status' => 400 ) |
197 | ); |
198 | } |
199 | return $this->get_item(); |
200 | } |
201 | |
202 | /** |
203 | * Retrieve the existing saved array of settings |
204 | * |
205 | * @return array $settings List of the settings and their values |
206 | */ |
207 | public function get_current_settings() { |
208 | |
209 | $social_data = \get_option( Options::get_option_name( 'wpseo_social', false ), false ); |
210 | // incase yoast plugin is not installed then we need to save the values in the yoast_wp_options_key |
211 | if ( false === $social_data ) { |
212 | |
213 | // initialize an array with default values |
214 | $social_data = $this->defaults; |
215 | |
216 | // update database |
217 | \add_option( Options::get_option_name( 'wpseo_social', false ), $social_data ); |
218 | } |
219 | // add the full url for twitter cause only the handle is saved in the database |
220 | $twitter_handle = $this->validate_twitter_id( $social_data['twitter_site'] ); |
221 | if ( ( ! empty( $social_data['twitter_site'] ) ) && ( false !== $twitter_handle ) ) { |
222 | $social_data['twitter_site'] = 'https://www.twitter.com/' . $twitter_handle; |
223 | } |
224 | |
225 | $filtered_social_urls = array(); |
226 | // handle other social urls for onboarding |
227 | foreach ( $social_data['other_social_urls'] as $index => $social_url ) { |
228 | if ( ! empty( $social_url ) ) { |
229 | if ( preg_match( '/(?:https?:\/\/)?(www\.)?yelp\.com/', $social_url ) ) { |
230 | $filtered_social_urls['yelp_url'] = $social_url; |
231 | } elseif ( preg_match( '/(?:https?:\/\/)?(www\.)?tiktok\.com/', $social_url ) ) { |
232 | $filtered_social_urls['tiktok_url'] = $social_url; |
233 | } else { |
234 | $filtered_social_urls[ 'social_url_' . $index ] = $social_url; |
235 | } |
236 | } |
237 | } |
238 | $social_data['other_social_urls'] = $filtered_social_urls; |
239 | return $social_data; |
240 | } |
241 | |
242 | /** |
243 | * Initialize WordPress Options, Permalinks and Configuration. |
244 | * |
245 | * @return \WP_REST_Response |
246 | */ |
247 | public function initialize() { |
248 | |
249 | if ( \get_option( Options::get_option_name( 'settings_initialized' ), false ) ) { |
250 | return new \WP_REST_Response( |
251 | array(), |
252 | 200 |
253 | ); |
254 | } |
255 | |
256 | // Update wp_options |
257 | $init_options = Options::get_initialization_options(); |
258 | foreach ( $init_options as $option_key => $option_value ) { |
259 | \update_option( Options::get_option_name( $option_key, false ), $option_value ); |
260 | } |
261 | // Can't be part of initialization constants as they are static. |
262 | \update_option( Options::get_option_name( 'start_date' ), gmdate( 'U' ) ); |
263 | |
264 | // Flush permalinks |
265 | flush_rewrite_rules(); |
266 | |
267 | // Add constants to the WordPress configuration (wp-config.php) |
268 | $wp_config_constants = Config::get_wp_config_initialization_constants(); |
269 | $wp_config = new WP_Config(); |
270 | foreach ( $wp_config_constants as $constant_key => $constant_value ) { |
271 | if ( $wp_config->constant_exists( $constant_key ) ) { |
272 | $wp_config->update_constant( $constant_key, $constant_value ); |
273 | continue; |
274 | } |
275 | $wp_config->add_constant( $constant_key, $constant_value ); |
276 | } |
277 | |
278 | \update_option( Options::get_option_name( 'settings_initialized' ), true ); |
279 | |
280 | return new \WP_REST_Response( |
281 | array(), |
282 | 201 |
283 | ); |
284 | } |
285 | |
286 | /** |
287 | * Validates a twitter id. |
288 | * |
289 | * @param string $twitter_id The twitter id to be validated. |
290 | * @param bool $strip_at_sign Whether or not to strip the `@` sign. |
291 | * |
292 | * @return string|false The validated twitter id or false if it is not valid. |
293 | */ |
294 | private function validate_twitter_id( $twitter_id, $strip_at_sign = true ) { |
295 | $twitter_id = ( $strip_at_sign ) ? sanitize_text_field( ltrim( $twitter_id, '@' ) ) : sanitize_text_field( $twitter_id ); |
296 | |
297 | /* |
298 | * From the Twitter documentation about twitter screen names: |
299 | * Typically a maximum of 15 characters long, but some historical accounts may exist with longer names. |
300 | * A username can only contain alphanumeric characters (letters A-Z, numbers 0-9) with the exception of underscores. |
301 | * |
302 | * @link https://support.twitter.com/articles/101299-why-can-t-i-register-certain-usernames |
303 | */ |
304 | if ( preg_match( '`^[A-Za-z0-9_]{1,25}$`', $twitter_id ) ) { |
305 | return $twitter_id; |
306 | } |
307 | |
308 | if ( preg_match( '`^http(?:s)?://(?:www\.)?twitter\.com/(?P<handle>[A-Za-z0-9_]{1,25})/?$`', $twitter_id, $matches ) ) { |
309 | return $matches['handle']; |
310 | } |
311 | |
312 | return false; |
313 | } |
314 | } |