PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.2
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.2
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / helpers / social-profiles-helper.php

social-profiles-helper.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.2, at src/helpers/social-profiles-helper.php

331 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Helpers;
4
5 /**
6 * Class Social_Profiles_Helper.
7 */
8 class Social_Profiles_Helper {
9
10 /**
11 * The fields for the person social profiles payload.
12 *
13 * @var array
14 */
15 private $person_social_profile_fields = [
16 'facebook' => 'get_non_valid_url',
17 'instagram' => 'get_non_valid_url',
18 'linkedin' => 'get_non_valid_url',
19 'myspace' => 'get_non_valid_url',
20 'pinterest' => 'get_non_valid_url',
21 'soundcloud' => 'get_non_valid_url',
22 'tumblr' => 'get_non_valid_url',
23 'twitter' => 'get_non_valid_twitter',
24 'youtube' => 'get_non_valid_url',
25 'wikipedia' => 'get_non_valid_url',
26 ];
27
28 /**
29 * The fields for the organization social profiles payload.
30 *
31 * @var array
32 */
33 private $organization_social_profile_fields = [
34 'facebook_site' => 'get_non_valid_url',
35 'twitter_site' => 'get_non_valid_twitter',
36 'other_social_urls' => 'get_non_valid_url_array',
37 ];
38
39 /**
40 * The Options_Helper instance.
41 *
42 * @var Options_Helper
43 */
44 protected $options_helper;
45
46 /**
47 * Social_Profiles_Helper constructor.
48 *
49 * @param Options_Helper $options_helper The WPSEO options helper.
50 */
51 public function __construct( Options_Helper $options_helper ) {
52 $this->options_helper = $options_helper;
53 }
54
55 /**
56 * Gets the person social profile fields supported by us.
57 *
58 * @return array The social profile fields.
59 */
60 public function get_person_social_profile_fields() {
61 /**
62 * Filter: Allow changes to the social profiles fields available for a person.
63 *
64 * @param array $person_social_profile_fields The social profile fields.
65 */
66 $person_social_profile_fields = \apply_filters( 'wpseo_person_social_profile_fields', $this->person_social_profile_fields );
67
68 return (array) $person_social_profile_fields;
69 }
70
71 /**
72 * Gets the organization social profile fields supported by us.
73 *
74 * @return array The organization profile fields.
75 */
76 public function get_organization_social_profile_fields() {
77 /**
78 * Filter: Allow changes to the social profiles fields available for an organization.
79 *
80 * @param array $organization_social_profile_fields The social profile fields.
81 */
82 $organization_social_profile_fields = \apply_filters( 'wpseo_organization_social_profile_fields', $this->organization_social_profile_fields );
83
84 return (array) $organization_social_profile_fields;
85 }
86
87 /**
88 * Gets the person social profiles stored in the database.
89 *
90 * @param int $person_id The id of the person.
91 *
92 * @return array The person's social profiles.
93 */
94 public function get_person_social_profiles( $person_id ) {
95 $social_profile_fields = \array_keys( $this->get_person_social_profile_fields() );
96 $person_social_profiles = \array_combine( $social_profile_fields, \array_fill( 0, \count( $social_profile_fields ), '' ) );
97
98 // If no person has been selected, $person_id is set to false.
99 if ( \is_numeric( $person_id ) ) {
100 foreach ( \array_keys( $person_social_profiles ) as $field_name ) {
101 $value = \get_user_meta( $person_id, $field_name, true );
102 // If $person_id is an integer but does not represent a valid user, get_user_meta returns false.
103 if ( ! \is_bool( $value ) ) {
104 $person_social_profiles[ $field_name ] = $value;
105 }
106 }
107 }
108
109 return $person_social_profiles;
110 }
111
112 /**
113 * Gets the organization social profiles stored in the database.
114 *
115 * @return array<string, string> The social profiles for the organization.
116 */
117 public function get_organization_social_profiles() {
118 $organization_social_profiles_fields = \array_keys( $this->get_organization_social_profile_fields() );
119 $organization_social_profiles = [];
120
121 foreach ( $organization_social_profiles_fields as $field_name ) {
122 $default_value = '';
123 if ( $field_name === 'other_social_urls' ) {
124 $default_value = [];
125 }
126 $social_profile_value = $this->options_helper->get( $field_name, $default_value );
127
128 if ( $field_name === 'other_social_urls' ) {
129 $other_social_profiles = \array_map( '\urldecode', \array_filter( $social_profile_value ) );
130 $organization_social_profiles['other_social_urls'] = $other_social_profiles;
131 continue;
132 }
133
134 if ( $field_name === 'twitter_site' && $social_profile_value !== '' ) {
135 $organization_social_profiles[ $field_name ] = 'https://x.com/' . $social_profile_value;
136 continue;
137 }
138
139 $organization_social_profiles[ $field_name ] = \urldecode( $social_profile_value );
140 }
141
142 return $organization_social_profiles;
143 }
144
145 /**
146 * Stores the values for the person's social profiles.
147 *
148 * @param int $person_id The id of the person to edit.
149 * @param array $social_profiles The array of the person's social profiles to be set.
150 *
151 * @return string[] An array of field names which failed to be saved in the db.
152 */
153 public function set_person_social_profiles( $person_id, $social_profiles ) {
154 $failures = [];
155 $person_social_profile_fields = $this->get_person_social_profile_fields();
156
157 // First validate all social profiles, before even attempting to save them.
158 foreach ( $person_social_profile_fields as $field_name => $validation_method ) {
159 if ( ! isset( $social_profiles[ $field_name ] ) ) {
160 // Just skip social profiles that were not passed.
161 continue;
162 }
163
164 if ( $social_profiles[ $field_name ] === '' ) {
165 continue;
166 }
167
168 $value_to_validate = $social_profiles[ $field_name ];
169 $failures = \array_merge( $failures, \call_user_func( [ $this, $validation_method ], $value_to_validate, $field_name ) );
170 }
171
172 if ( ! empty( $failures ) ) {
173 return $failures;
174 }
175
176 // All social profiles look good, now let's try to save them.
177 foreach ( \array_keys( $person_social_profile_fields ) as $field_name ) {
178 if ( ! isset( $social_profiles[ $field_name ] ) ) {
179 // Just skip social profiles that were not passed.
180 continue;
181 }
182 $social_profiles[ $field_name ] = $this->sanitize_social_field( $social_profiles[ $field_name ] );
183 \update_user_meta( $person_id, $field_name, $social_profiles[ $field_name ] );
184 }
185
186 return $failures;
187 }
188
189 /**
190 * Stores the values for the organization's social profiles.
191 *
192 * @param array $social_profiles An array with the social profiles values to be saved in the db.
193 *
194 * @return string[] An array of field names which failed to be saved in the db.
195 */
196 public function set_organization_social_profiles( $social_profiles ) {
197 $failures = [];
198 $organization_social_profile_fields = $this->get_organization_social_profile_fields();
199
200 // First validate all social profiles, before even attempting to save them.
201 foreach ( $organization_social_profile_fields as $field_name => $validation_method ) {
202 if ( ! isset( $social_profiles[ $field_name ] ) ) {
203 // Just skip social profiles that were not passed.
204 continue;
205 }
206 $social_profiles[ $field_name ] = $this->sanitize_social_field( $social_profiles[ $field_name ] );
207
208 $value_to_validate = $social_profiles[ $field_name ];
209 $failures = \array_merge( $failures, \call_user_func( [ $this, $validation_method ], $value_to_validate, $field_name ) );
210 }
211
212 if ( ! empty( $failures ) ) {
213 return $failures;
214 }
215
216 // All social profiles look good, now let's try to save them.
217 foreach ( \array_keys( $organization_social_profile_fields ) as $field_name ) {
218 if ( ! isset( $social_profiles[ $field_name ] ) ) {
219 // Just skip social profiles that were not passed.
220 continue;
221 }
222
223 // Remove empty strings in Other Social URLs.
224 if ( $field_name === 'other_social_urls' ) {
225 $other_social_urls = \array_filter(
226 $social_profiles[ $field_name ],
227 static function ( $other_social_url ) {
228 return $other_social_url !== '';
229 },
230 );
231
232 $social_profiles[ $field_name ] = \array_values( $other_social_urls );
233 }
234
235 $result = $this->options_helper->set( $field_name, $social_profiles[ $field_name ] );
236 if ( ! $result ) {
237 /**
238 * The value for Twitter might have been sanitised from URL to username.
239 * If so, $result will be false. We should check if the option value is part of the received value.
240 */
241 if ( $field_name === 'twitter_site' ) {
242 $current_option = $this->options_helper->get( $field_name );
243 if ( ! \strpos( $social_profiles[ $field_name ], 'twitter.com/' . $current_option ) && ! \strpos( $social_profiles[ $field_name ], 'x.com/' . $current_option ) ) {
244 $failures[] = $field_name;
245 }
246 }
247 else {
248 $failures[] = $field_name;
249 }
250 }
251 }
252
253 if ( ! empty( $failures ) ) {
254 return $failures;
255 }
256
257 return [];
258 }
259
260 /**
261 * Returns a sanitized social field.
262 *
263 * @param string|array $social_field The social field to sanitize.
264 *
265 * @return string|array The sanitized social field.
266 */
267 protected function sanitize_social_field( $social_field ) {
268 if ( \is_array( $social_field ) ) {
269 foreach ( $social_field as $key => $value ) {
270 $social_field[ $key ] = \sanitize_text_field( $value );
271 }
272
273 return $social_field;
274 }
275
276 return \sanitize_text_field( $social_field );
277 }
278
279 /**
280 * Checks if url is not valid and returns the name of the setting if it's not.
281 *
282 * @param string $url The url to be validated.
283 * @param string $url_setting The name of the setting to be updated with the url.
284 *
285 * @return array An array with the setting that the non-valid url is about to update.
286 */
287 protected function get_non_valid_url( $url, $url_setting ) {
288 if ( $this->options_helper->is_social_url_valid( $url ) ) {
289 return [];
290 }
291
292 return [ $url_setting ];
293 }
294
295 /**
296 * Checks if urls in an array are not valid and return the name of the setting if one of them is not, including the non-valid url's index in the array
297 *
298 * @param array $urls The urls to be validated.
299 * @param string $urls_setting The name of the setting to be updated with the urls.
300 *
301 * @return array An array with the settings that the non-valid urls are about to update, suffixed with a dash-separated index of the positions of those settings, eg. other_social_urls-2.
302 */
303 protected function get_non_valid_url_array( $urls, $urls_setting ) {
304 $non_valid_url_array = [];
305
306 foreach ( $urls as $key => $url ) {
307 if ( ! $this->options_helper->is_social_url_valid( $url ) ) {
308 $non_valid_url_array[] = $urls_setting . '-' . $key;
309 }
310 }
311
312 return $non_valid_url_array;
313 }
314
315 /**
316 * Checks if the twitter value is not valid and returns the name of the setting if it's not.
317 *
318 * @param array $twitter_site The twitter value to be validated.
319 * @param string $twitter_setting The name of the twitter setting to be updated with the value.
320 *
321 * @return array An array with the setting that the non-valid twitter value is about to update.
322 */
323 protected function get_non_valid_twitter( $twitter_site, $twitter_setting ) {
324 if ( $this->options_helper->is_twitter_id_valid( $twitter_site, false ) ) {
325 return [];
326 }
327
328 return [ $twitter_setting ];
329 }
330 }
331