PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / trunk
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress vtrunk
4.16.18 4.16.17 4.16.16 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5a 1.1.6 1.1.7 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4 1.4.1 1.4.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.7.1 1.7.2 1.8 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.1.9 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.2 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.13.4 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.15.0 4.15.1 4.15.10 4.15.11 4.15.12 4.15.13 4.15.14 4.15.15 4.15.16 4.15.17 4.15.18 4.15.19 4.15.2 4.15.20 4.15.20.1 4.15.21 4.15.22 4.15.23 4.15.24 4.15.25 4.15.3 4.15.4 4.15.5 4.15.6 4.15.7 4.15.8 4.15.9 4.16.0 4.16.1 4.16.10 4.16.11 4.16.12 4.16.13 4.16.14 4.16.15 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.2.0 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.7.0 4.8.0 4.9.0
wp-user-avatar / src / ShortcodeParser / Builder / FrontendProfileBuilder.php
wp-user-avatar / src / ShortcodeParser / Builder Last commit date
EditProfileBuilder.php 3 years ago FieldsShortcodeCallback.php 4 months ago FrontendProfileBuilder.php 10 months ago GlobalShortcodes.php 3 years ago LoginFormBuilder.php 2 years ago PasswordResetBuilder.php 1 month ago RegistrationFormBuilder.php 1 year ago index.php 5 years ago
FrontendProfileBuilder.php
716 lines
1 <?php
2
3 namespace ProfilePress\Core\ShortcodeParser\Builder;
4
5 use ProfilePress\Core\Classes\ExtensionManager as EM;
6 use ProfilePress\Core\Classes\PROFILEPRESS_sql;
7 use WP_User;
8
9 class FrontendProfileBuilder
10 {
11 private static WP_User $user_data;
12
13 /**
14 * Define all front-end profile sub-shortcode.
15 *
16 * @param $user
17 */
18 public function __construct($user)
19 {
20 self::$user_data = $user;
21
22 add_shortcode('profile-username', array($this, 'profile_username'));
23
24 add_shortcode('profile-email', array($this, 'profile_email'));
25
26 add_shortcode('profile-website', array($this, 'profile_website'));
27
28 add_shortcode('profile-nickname', array($this, 'profile_nickname'));
29
30 add_shortcode('profile-display-name', array($this, 'profile_display_name'));
31
32 add_shortcode('profile-first-name', array($this, 'profile_first_name'));
33
34 add_shortcode('profile-last-name', array($this, 'profile_last_name'));
35
36 add_shortcode('profile-bio', array($this, 'profile_bio'));
37
38 add_shortcode('profile-cpf', array($this, 'profile_custom_profile_field'));
39 add_shortcode('profile-file', array($this, 'profile_user_uploaded_file'));
40
41 add_shortcode('profile-cover-image-url', array($this, 'cover_image_url'));
42
43 add_shortcode('profile-avatar-url', array($this, 'user_avatar_url'));
44 add_shortcode('user-avatar-url', array($this, 'user_avatar_url')); // backward compat
45
46 add_shortcode('profile-hide-empty-data', array($this, 'hide_empty_data'));
47
48 add_shortcode('post-count', array($this, 'post_count'));
49 add_shortcode('profile-post-count', array($this, 'post_count'));
50
51 add_shortcode('comment-count', array($this, 'get_comment_count'));
52 add_shortcode('profile-comment-count', array($this, 'get_comment_count'));
53
54 add_shortcode('profile-post-list', array($this, 'author_post_list'));
55 add_shortcode('profile-comment-list', array($this, 'author_comment_list'));
56
57 add_shortcode('profile-view-url', array($this, 'view_user_profile_url'));
58
59 add_shortcode('profile-author-posts-url', array($this, 'author_post_url'));
60
61 add_shortcode('profile-date-registered', array($this, 'date_user_registered'));
62
63 add_shortcode('jcarousel-author-posts', array($this, 'pp_jcarousel_author_posts'));
64
65 /**
66 * @param object $user WP_User object
67 */
68 do_action('ppress_register_profile_shortcode', $user);
69 }
70
71 public function date_user_registered()
72 {
73 return date('F jS, Y', strtotime(self::$user_data->user_registered));
74 }
75
76 public function view_user_profile_url(): string
77 {
78 return ppress_get_frontend_profile_url(self::$user_data->user_login);
79 }
80
81 public function author_post_url()
82 {
83 return get_author_posts_url(self::$user_data->ID);
84 }
85
86 public static function author_posts_query($user_id, $attributes)
87 {
88 $attributes = shortcode_atts(array('limit' => 10, 'offset' => 0), $attributes);
89
90 $limit = absint($attributes['limit']);
91 $offset = absint($attributes['offset']);
92
93 $posts = get_posts(
94 apply_filters('ppress_frontend_profile_author_post_list_args', [
95 'author' => $user_id,
96 'posts_per_page' => $limit,
97 'offset' => $offset
98 ], $user_id, $attributes)
99 );
100
101 $output = '';
102
103 if ( ! empty($posts)) {
104
105 $output .= "<ul class='pp-user-post-list'>";
106 /** @var \WP_Post $post */
107 foreach ($posts as $post) {
108 $output .= sprintf(
109 '<li class="pp-user-post-item"><a href="%s"><h3 class="pp-post-item-head">%s</h3></a></li>',
110 get_permalink($post->ID),
111 $post->post_title,
112 apply_filters('ppress_author_post_after_title', '', $post, $user_id, $attributes)
113 );
114 }
115
116 $output .= "</ul>";
117
118 } else {
119
120 $note = esc_html__('This user has not created any post.', 'wp-user-avatar');
121
122 if (self::$user_data->ID == get_current_user_id()) {
123 $note = esc_html__('You have not created any post.', 'wp-user-avatar');
124 }
125
126 $output .= sprintf('<div class="pp-user-comment-no-item"><span>%s</span></div>', $note);
127 }
128
129 return [
130 'structure' => $output,
131 'total_post_count' => is_array($posts) ? count($posts) : 0
132 ];
133 }
134
135 public function author_post_list($attributes)
136 {
137 $result = self::author_posts_query(self::$user_data->ID, $attributes);
138
139 return $result['structure'];
140 }
141
142 public static function author_comment_query($user_id, $attributes)
143 {
144 $attributes = shortcode_atts(array('limit' => 10, 'offset' => 0), $attributes);
145
146 $limit = absint($attributes['limit']);
147 $offset = absint($attributes['offset']);
148
149 $comments = get_comments([
150 'number' => $limit,
151 'user_id' => $user_id,
152 'post_status' => ['publish'],
153 'status' => 'approve',
154 'offset' => $offset
155 ]);
156
157 $output = '';
158
159 if ( ! empty($comments)) {
160
161 $output .= '<div class="pp-user-comment-list">';
162 /** @var \WP_Comment $comment */
163 foreach ($comments as $comment) {
164 $output .= '<div class="pp-user-comment-item">';
165 $output .= '<div class="pp-user-comment-item-link">';
166 $output .= sprintf(
167 '<a href="%s">%s</a>',
168 esc_url(get_comment_link($comment->comment_ID)),
169 get_comment_excerpt($comment->comment_ID)
170 );
171 $output .= '</div>';
172 $output .= '<div class="pp-user-comment-item-meta">';
173 $output .= sprintf('On <a href="%s">%s</a>', get_permalink($comment->comment_post_ID), get_the_title($comment->comment_post_ID));
174 $output .= '</div>';
175 $output .= '</div>';
176 }
177
178 $output .= "</div>";
179
180 } else {
181
182 $note = esc_html__('This user has not made any comment.', 'wp-user-avatar');
183
184 if (self::$user_data->ID == get_current_user_id()) {
185 $note = esc_html__('You have not made any comment.', 'wp-user-avatar');
186 }
187
188 $output .= sprintf('<div class="pp-user-comment-no-item"><span>%s</span></div>', $note);
189 }
190
191 return [
192 'structure' => $output,
193 'comment_count' => is_array($comments) ? count($comments) : 0
194 ];
195 }
196
197 public function author_comment_list($attributes)
198 {
199 $result = self::author_comment_query(self::$user_data->ID, $attributes);
200
201 return $result['structure'];
202 }
203
204 /**
205 * Profile username
206 *
207 * @return mixed
208 */
209 public function profile_username()
210 {
211 $capitalization = apply_filters('ppress_capitalize_username', true);
212
213 $username = self::$user_data->user_login;
214
215 $username = $capitalization ? ucwords($username) : $username;
216
217 return apply_filters('ppress_profile_username', $username, self::$user_data);
218 }
219
220
221 /**
222 * User email
223 *
224 * @return mixed
225 */
226 public function profile_email()
227 {
228 return apply_filters('ppress_profile_email', self::$user_data->user_email, self::$user_data);
229 }
230
231 /**
232 * Return the user avatar image URL
233 *
234 * @param array $atts Shortcode attributes
235 *
236 * @return string image url
237 */
238 public function user_avatar_url($atts)
239 {
240 $user_id = self::$user_data->ID;
241
242 $args = ['ppress-full' => true];
243
244 if ( ! empty($atts['size'])) $args['size'] = absint($atts['size']);
245
246 return apply_filters('ppress_profile_avatar_url', get_avatar_url($user_id, $args), self::$user_data);
247 }
248
249 /**
250 * Return user cover photo url
251 *
252 * @return string image url
253 */
254 public function cover_image_url()
255 {
256 $user_id = self::$user_data->ID;
257
258 return apply_filters('ppress_cover_image_url', ppress_get_cover_image_url($user_id), self::$user_data);
259 }
260
261 /**
262 * User website URL
263 *
264 * @return mixed
265 */
266 public function profile_website()
267 {
268 return apply_filters('ppress_profile_website', self::$user_data->user_url, self::$user_data);
269 }
270
271 /**
272 * Nickname of user
273 *
274 * @return mixed
275 */
276 public function profile_nickname()
277 {
278 return apply_filters('ppress_profile_nickname', ucwords(self::$user_data->nickname), self::$user_data);
279 }
280
281 /**
282 * Display name of profile
283 *
284 * @return mixed
285 */
286 public function profile_display_name($atts = false)
287 {
288 $display_name = self::$user_data->display_name;
289
290 if ( ! empty($atts['format']) && ! empty(self::$user_data->first_name) && ! empty(self::$user_data->last_name)) {
291
292 switch ($atts['format']) {
293 case 'first_last_names':
294 $display_name = self::$user_data->first_name . ' ' . self::$user_data->last_name;
295 break;
296 case 'last_first_names':
297 $display_name = self::$user_data->last_name . ' ' . self::$user_data->first_name;
298 break;
299 case 'first_name_initial_l':
300 $display_name = self::$user_data->first_name . ' ' . self::$user_data->last_name[0];
301 break;
302 case 'f_initial_last_name':
303 $display_name = self::$user_data->first_name[0] . ' ' . self::$user_data->last_name;
304 break;
305 }
306 }
307
308 return apply_filters('ppress_profile_display_name', $display_name, self::$user_data);
309 }
310
311 /**
312 * Profile first name
313 *
314 * @return mixed
315 */
316 public function profile_first_name()
317 {
318 return apply_filters('ppress_profile_first_name', ucwords(strip_shortcodes(self::$user_data->first_name)), self::$user_data);
319 }
320
321
322 /**
323 * Last name of user.
324 *
325 * @return mixed
326 */
327 public function profile_last_name()
328 {
329 return apply_filters('ppress_profile_last_name', ucwords(strip_shortcodes(self::$user_data->last_name)), self::$user_data);
330 }
331
332 /**
333 * Description/bio of user.
334 *
335 * @return mixed
336 */
337 public function profile_bio()
338 {
339 return apply_filters('ppress_profile_bio', make_clickable(wpautop(wp_kses_post(html_entity_decode(strip_shortcodes(self::$user_data->description))))), self::$user_data);
340 }
341
342 /**
343 * Custom profile data of user.
344 *
345 * @param $atts array shortcode attributes
346 *
347 * @return string
348 */
349 public function profile_custom_profile_field($atts)
350 {
351 if ( ! EM::is_enabled(EM::CUSTOM_FIELDS)) return '';
352
353 $atts = shortcode_atts(
354 array(
355 'key' => '',
356 'default' => '',
357 ),
358 $atts
359 );
360
361 $key = esc_attr($atts['key']);
362
363 if (empty($key)) return esc_html__('Field key is missing', 'wp-user-avatar');
364
365 $type = PROFILEPRESS_sql::get_field_type($key);
366
367 if ('file' == $type) {
368 return $this->profile_user_uploaded_file($atts);
369 }
370
371 $data = self::$user_data->{$key};
372
373 if (is_array($data)) {
374 $data = implode(', ',
375 array_filter($data, function ($val) {
376 return ! empty($val);
377 })
378 );
379 }
380
381 if (empty($data) && ! ppress_is_boolean($data) && ! empty($atts['default'])) {
382 $data = esc_attr($atts['default']);
383 }
384
385 return apply_filters('ppress_profile_cpf', strip_shortcodes($data), self::$user_data);
386 }
387
388 public static function get_user_uploaded_file($user_id, $field_key, $is_raw = false)
389 {
390 $user_upload_data = get_user_meta($user_id, 'pp_uploaded_files', true);
391
392 if (empty($user_upload_data)) return '';
393
394 $filename = $user_upload_data[$field_key] ?? '';
395
396 if (empty($filename)) return '';
397
398 $link = PPRESS_FILE_UPLOAD_URL . $filename;
399
400 return $is_raw === true || $is_raw == 'true' ? $link : "<a href='$link'>$filename</a>";
401 }
402
403 public function profile_user_uploaded_file($atts)
404 {
405 $atts = ppress_normalize_attributes($atts);
406
407 $atts = shortcode_atts(['key' => '', 'raw' => false], $atts);
408
409 $return = self::get_user_uploaded_file(self::$user_data->ID, esc_attr($atts['key']), $atts['raw']);
410
411 return apply_filters('ppress_profile_file', $return, self::$user_data);
412 }
413
414 /**
415 * Return number of post written by a user
416 *
417 * @return int
418 */
419 public function post_count()
420 {
421 return apply_filters('ppress_profile_post_count', count_user_posts(self::$user_data->ID), self::$user_data, true);
422 }
423
424 public function hide_empty_data($atts, $content)
425 {
426 $atts = shortcode_atts(
427 array(
428 'field' => '',
429 'default' => ''
430 ),
431 $atts
432 );
433
434 $key = ! empty($atts['field']) ? strip_tags($atts['field']) : '';
435
436 switch ($key) {
437 case 'username':
438 $key = 'user_login';
439 break;
440 case 'email':
441 $key = 'user_email';
442 break;
443 case 'website':
444 $key = 'user_url';
445 break;
446 case 'nickname':
447 $key = 'nickname';
448 break;
449 case 'display_name':
450 $key = 'display_name';
451 break;
452 case 'first_name':
453 $key = 'first_name';
454 break;
455 case 'last_name':
456 $key = 'last_name';
457 break;
458 case 'bio':
459 $key = 'description';
460 break;
461 }
462
463 if ( ! empty($key) && ! empty(self::$user_data->$key)) {
464 return do_shortcode($content);
465 }
466
467 return ppress_var($atts, 'default', '', true);
468 }
469
470 /**
471 * Return the total comment count made by a user
472 */
473 public function get_comment_count()
474 {
475 global $wpdb;
476 $userId = self::$user_data->ID;
477
478 $count = $wpdb->get_var('
479 SELECT COUNT(comment_ID)
480 FROM ' . $wpdb->comments . '
481 WHERE user_id = "' . $userId . '" AND comment_type = "" AND comment_approved = 1');
482
483 return apply_filters('ppress_profile_comment_count', $count, self::$user_data);
484 }
485
486 protected function jcarousel_css()
487 {
488 ob_start();
489 ?>
490 <style type="text/css">
491 /* jcarousel responsive */
492 a.jcarousel-control-next, a.jcarousel-control-prev {
493 text-decoration: none !important;
494 }
495
496 .pp-jcarousel-wrapper ul li a {
497 color: #5B5B5B;
498 text-decoration: none
499 }
500
501 .pp-jcarousel-wrapper {
502 color: #5B5B5B;
503 background-color: #F5F5F5;
504 margin: 20px auto;
505 position: relative;
506 border: 10px solid #fff;
507 -webkit-border-radius: 5px;
508 -moz-border-radius: 5px;
509 border-radius: 5px;
510 -webkit-box-shadow: 0 0 2px #999;
511 -moz-box-shadow: 0 0 2px #999;
512 box-shadow: 0 0 2px #999;
513 }
514
515 /** Carousel **/
516 .ppjcarousel {
517 position: relative;
518 overflow: hidden;
519 width: 100%;
520 }
521
522 .ppjcarousel ul {
523 width: 20000em;
524 position: relative;
525 list-style: none;
526 margin: 0;
527 padding: 0;
528 }
529
530 .ppjcarousel li {
531 width: 200px;
532 float: left;
533 margin: 1px 3px 1px 0;
534 -moz-box-sizing: border-box;
535 -webkit-box-sizing: border-box;
536 box-sizing: border-box;
537 }
538
539 .ppjcarousel img {
540 display: block;
541 width: 100%;
542 height: 100px !important;
543 }
544
545 .jc-no-post {
546 font-family: inherit;
547 font-size: 15px;
548 padding: 5px;
549 text-align: center;
550 }
551
552 .jc-title {
553 font-family: inherit;
554 font-size: 15px;
555 word-wrap: break-word;
556 padding: 5px;
557 margin: 0 4px;
558 text-align: center;
559 }
560
561 /** Carousel Controls **/
562 .jcarousel-control-prev, .jcarousel-control-next {
563 position: absolute;
564 top: 50%;
565 margin-top: -15px;
566 width: 30px;
567 height: 30px;
568 text-align: center;
569 background: #4E443C;
570 color: #fff;
571 text-decoration: none;
572 text-shadow: 0 0 1px #000;
573 font: 24px/27px Arial, sans-serif;
574 -webkit-border-radius: 30px;
575 -moz-border-radius: 30px;
576 border-radius: 30px;
577 -webkit-box-shadow: 0 0 4px #F0EFE7;
578 -moz-box-shadow: 0 0 4px #F0EFE7;
579 box-shadow: 0 0 4px #F0EFE7;
580 }
581
582 .jcarousel-control-prev {
583 left: 15px;
584 }
585
586 .jcarousel-control-next {
587 right: 15px;
588 }
589
590 /** Carousel Pagination **/
591 .jcarousel-pagination {
592 position: absolute;
593 bottom: -40px;
594 left: 50%;
595 -webkit-transform: translate(-50%, 0);
596 -ms-transform: translate(-50%, 0);
597 -moz-transform: translate(-50%, 0);
598 transform: translate(-50%, 0);
599 margin: 0;
600 }
601
602 .jcarousel-pagination a {
603 text-decoration: none;
604 display: inline-block;
605 font-size: 11px;
606 height: 10px;
607 width: 10px;
608 line-height: 10px;
609 background: #fff;
610 color: #4E443C;
611 border-radius: 10px;
612 text-indent: -9999px;
613 margin-right: 7px;
614 -webkit-box-shadow: 0 0 2px #4E443C;
615 -moz-box-shadow: 0 0 2px #4E443C;
616 box-shadow: 0 0 2px #4E443C;
617 }
618
619 .jcarousel-pagination a.active {
620 background: #4E443C;
621 color: #fff;
622 opacity: 1;
623 -webkit-box-shadow: 0 0 2px #F0EFE7;
624 -moz-box-shadow: 0 0 2px #F0EFE7;
625 box-shadow: 0 0 2px #F0EFE7;
626 }
627 </style>
628 <?php
629 return ppress_minify_css(ob_get_clean());
630 }
631
632 /**
633 * jCarousel author latest post slider
634 *
635 * @param $atts
636 *
637 * @return string
638 */
639 public function pp_jcarousel_author_posts($atts)
640 {
641 wp_enqueue_script('pp-jcarousel', PPRESS_ASSETS_URL . '/js/jcarousel.min.js', array('jquery'), PPRESS_VERSION_NUMBER, true);
642
643 $atts = shortcode_atts(
644 array(
645 'count' => 10,
646 'default' => PPRESS_ASSETS_URL . '/images/frontend/jc_dft_img.jpg',
647 'width' => '',
648 ),
649 $atts
650 );
651
652 $posts = get_posts(
653 array(
654 'post_type' => 'post',
655 'posts_per_page' => (int)$atts['count'],
656 'author' => self::$user_data->ID,
657 )
658 );
659
660 $default_img = esc_url($atts['default']);
661 $width = ! empty($atts['width']) ? ' style="width: ' . esc_attr($atts['width']) . ';"' : null;
662
663 ob_start();
664 echo $this->jcarousel_css();
665 ?>
666 <div class="pp-jcarousel-wrapper"<?php echo $width; ?>>
667 <div class="ppjcarousel">
668 <?php
669 if (empty($posts)) {
670 echo '<div class="jc-no-post">' . apply_filters('jcarousel_no_post', esc_html__('No post written yet.', 'wp-user-avatar')) . '</div>';
671 } else {
672
673 echo '<ul>';
674 foreach ($posts as $post) {
675 $feature_img = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'medium', false);
676
677 $feature_img = isset($feature_img[0]) ? $feature_img[0] : false;
678
679 if ( ! $feature_img) {
680 $feature_img = $default_img;
681 }
682 ?>
683 <li>
684 <a href="<?php echo get_permalink($post->ID); ?>">
685 <img src="<?php echo esc_url($feature_img); ?>" alt="<?php esc_attr_e($post->post_title); ?>">
686
687 <div class="jc-title"><?php esc_html_e($post->post_title); ?></div>
688 </a>
689 </li>
690 <?php
691 }
692 echo '</ul>';
693 }
694 ?>
695 </div>
696
697 <?php
698 // hide jcarousel nav link if no post is found
699 if ( ! empty($posts)) { ?>
700 <a href="#" class="jcarousel-control-prev">&lsaquo;</a>
701 <a href="#" class="jcarousel-control-next">&rsaquo;</a>
702 <p class="jcarousel-pagination"></p>
703 <?php } ?>
704 </div>
705 <?php
706 return apply_filters('ppress_jcarousel_author_posts', ob_get_clean(), self::$user_data);
707 }
708
709 public static function get_instance($user = '')
710 {
711 $user = ! empty($user) ? $user : wp_get_current_user();
712
713 return new self($user);
714 }
715 }
716