• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

timber / timber / 5690593717

pending completion
5690593717

Pull #1617

github

web-flow
Merge f587ceffa into b563d274e
Pull Request #1617: 2.x

4433 of 4433 new or added lines in 57 files covered. (100.0%)

3931 of 4433 relevant lines covered (88.68%)

58.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.59
/src/User.php
1
<?php
2

3
namespace Timber;
4

5
use WP_User;
6

7
/**
8
 * Class User
9
 *
10
 * A user object represents a WordPress user.
11
 *
12
 * The currently logged-in user will be available as `{{ user }}` in your Twig files through the
13
 * global context. If a user is not logged in, it will be `false`. This will make it possible for
14
 * you to check if a user is logged by checking for `user` instead of calling `is_user_logged_in()`
15
 * in your Twig templates.
16
 *
17
 * @api
18
 * @example
19
 * ```twig
20
 * {% if user %}
21
 *     Hello {{ user.name }}
22
 * {% endif %}
23
 * ```
24
 *
25
 * The difference between a logged-in user and a post author:
26
 *
27
 * ```php
28
 * $context = Timber::context();
29
 *
30
 * Timber::render( 'single.twig', $context );
31
 * ```
32
 * ```twig
33
 * <p class="current-user-info">Your name is {{ user.name }}</p>
34
 * <p class="article-info">This article is called "{{ post.title }}"
35
 *     and it’s by {{ post.author.name }}</p>
36
 * ```
37
 * ```html
38
 * <p class="current-user-info">Your name is Jesse Eisenberg</p>
39
 * <p class="article-info">This article is called "Consider the Lobster"
40
 *     and it’s by David Foster Wallace</p>
41
 * ```
42
 */
43
class User extends CoreEntity
44
{
45
    /**
46
     * The underlying WordPress Core object.
47
     *
48
     * @since 2.0.0
49
     *
50
     * @var WP_User|null
51
     */
52
    protected ?WP_User $wp_object;
53

54
    public $object_type = 'user';
55

56
    public static $representation = 'user';
57

58
    public $_link;
59

60
    /**
61
     * @api
62
     * @var string A URL to an avatar that overrides anything from Gravatar, etc.
63
     */
64
    public $avatar_override;
65

66
    /**
67
     * @api
68
     * @var int The ID from WordPress
69
     */
70
    public $id;
71

72
    /**
73
     * @api
74
     * @var string
75
     */
76
    public $user_nicename;
77

78
    /**
79
     * User email address.
80
     *
81
     * @api
82
     * @var string
83
     */
84
    public $user_email;
85

86
    /**
87
     * The roles the user is part of.
88
     *
89
     * @api
90
     * @since 1.8.5
91
     *
92
     * @var array
93
     */
94
    protected $roles;
95

96
    /**
97
     * Construct a User object. For internal use only: Do not call directly.
98
     * Call `Timber::get_user()` instead.
99
     *
100
     * @internal
101
     */
102
    final protected function __construct()
103
    {
104
    }
68✔
105

106
    /**
107
     * Build a new User object.
108
     */
109
    public static function build(WP_User $wp_user): self
110
    {
111
        $user = new static();
68✔
112
        $user->init($wp_user);
68✔
113

114
        return $user;
68✔
115
    }
116

117
    /**
118
     * @api
119
     * @example
120
     * ```twig
121
     * This post is by {{ post.author }}
122
     * ```
123
     * ```html
124
     * This post is by Jared Novack
125
     * ```
126
     *
127
     * @return string a fallback for Timber\User::name()
128
     */
129
    public function __toString()
130
    {
131
        return $this->name();
2✔
132
    }
133

134
    /**
135
     * @internal
136
     */
137
    protected function init($wp_user)
138
    {
139
        $this->wp_object = $wp_user;
68✔
140

141
        $data = \get_userdata($wp_user->ID);
68✔
142
        if (!isset($data->data)) {
68✔
143
            return;
4✔
144
        }
145
        $this->import($data->data);
66✔
146

147
        if (isset($data->roles)) {
66✔
148
            $this->roles = $this->get_roles($data->roles);
66✔
149
        }
150

151
        // Never leak password data
152
        unset($this->user_pass);
66✔
153
        $this->id = $this->ID = (int) $wp_user->ID;
66✔
154
    }
155

156
    /**
157
     * Gets the underlying WordPress Core object.
158
     *
159
     * @since 2.0.0
160
     *
161
     * @return WP_User|null
162
     */
163
    public function wp_object(): ?WP_User
164
    {
165
        return $this->wp_object;
1✔
166
    }
167

168
    /**
169
     * Get the URL of the user's profile
170
     *
171
     * @api
172
     * @return string http://example.org/author/lincoln
173
     */
174
    public function link()
175
    {
176
        if (!$this->_link) {
1✔
177
            $this->_link = \user_trailingslashit(\get_author_posts_url($this->ID));
1✔
178
        }
179
        return $this->_link;
1✔
180
    }
181

182
    /**
183
     * Gets a user meta value.
184
     *
185
     * @api
186
     * @deprecated 2.0.0, use `{{ user.meta('field_name') }}` instead.
187
     * @see \Timber\User::meta()
188
     *
189
     * @param string $field_name The field name for which you want to get the value.
190
     * @return mixed The meta field value.
191
     */
192
    public function get_field($field_name = null)
193
    {
194
        Helper::deprecated(
1✔
195
            "{{ user.get_field('field_name') }}",
1✔
196
            "{{ user.meta('field_name') }}",
1✔
197
            '2.0.0'
1✔
198
        );
1✔
199

200
        return $this->meta($field_name);
1✔
201
    }
202

203
    /**
204
     * Get the name of the User
205
     *
206
     * @api
207
     * @return string the human-friendly name of the user (ex: "Buster Bluth")
208
     */
209
    public function name()
210
    {
211
        /**
212
         * Filters the name of a user.
213
         *
214
         * @since 1.1.4
215
         *
216
         * @param string       $name The name of the user. Default `display_name`.
217
         * @param \Timber\User $user The user object.
218
         */
219
        return \apply_filters('timber/user/name', $this->display_name, $this);
19✔
220
    }
221

222
    /**
223
     * Get the relative path to the user's profile
224
     *
225
     * @api
226
     * @return string ex: /author/lincoln
227
     */
228
    public function path()
229
    {
230
        return URLHelper::get_rel_url($this->link());
1✔
231
    }
232

233
    /**
234
     * @api
235
     * @return string ex baberaham-lincoln
236
     */
237
    public function slug()
238
    {
239
        return $this->user_nicename;
3✔
240
    }
241

242
    /**
243
     * Gets a user meta value.
244
     *
245
     * @api
246
     * @deprecated 2.0.0, use `{{ user.meta('field_name') }}` instead.
247
     *
248
     * @param string $field_name The field name for which you want to get the value.
249
     * @return mixed The meta field value.
250
     */
251
    public function get_meta_field($field_name)
252
    {
253
        Helper::deprecated(
×
254
            "{{ user.get_meta_field('field_name') }}",
×
255
            "{{ user.meta('field_name') }}",
×
256
            '2.0.0'
×
257
        );
×
258

259
        return $this->meta($field_name);
×
260
    }
261

262
    /**
263
     * Gets a user meta value.
264
     *
265
     * @api
266
     * @deprecated 2.0.0, use `{{ user.meta('field_name') }}` instead.
267
     *
268
     * @param string $field_name The field name for which you want to get the value.
269
     * @return mixed The meta field value.
270
     */
271
    public function get_meta($field_name)
272
    {
273
        Helper::deprecated(
×
274
            "{{ user.get_meta('field_name') }}",
×
275
            "{{ user.meta('field_name') }}",
×
276
            '2.0.0'
×
277
        );
×
278
        return $this->meta($field_name);
×
279
    }
280

281
    /**
282
       * Creates an associative array with user role slugs and their translated names.
283
       *
284
       * @internal
285
       * @since 1.8.5
286
       * @param array $roles user roles.
287
       * @return array|null
288
       */
289
    protected function get_roles($roles)
290
    {
291
        if (empty($roles)) {
66✔
292
            // @codeCoverageIgnoreStart
293
            return null;
294
            // @codeCoverageIgnoreEnd
295
        }
296

297
        $wp_roles = \wp_roles();
66✔
298
        $names = $wp_roles->get_names();
66✔
299

300
        $values = [];
66✔
301

302
        foreach ($roles as $role) {
66✔
303
            $name = $role;
66✔
304
            if (isset($names[$role])) {
66✔
305
                $name = \translate_user_role($names[$role]);
66✔
306
            }
307
            $values[$role] = $name;
66✔
308
        }
309

310
        return $values;
66✔
311
    }
312

313
    /**
314
     * Gets the user roles.
315
     * Roles shouldn’t be used to check whether a user has a capability. Use roles only for
316
     * displaying purposes. For example, if you want to display the name of the subscription a user
317
     * has on the site behind a paywall.
318
     *
319
     * If you want to check for capabilities, use `{{ user.can('capability') }}`. If you only want
320
     * to check whether a user is logged in, you can use `{% if user %}`.
321
     *
322
     * @api
323
     * @since 1.8.5
324
     * @example
325
     * ```twig
326
     * <h2>Role name</h2>
327
     * {% for role in post.author.roles %}
328
     *     {{ role }}
329
     * {% endfor %}
330
     * ```
331
     * ```twig
332
     * <h2>Role name</h2>
333
     * {{ post.author.roles|join(', ') }}
334
     * ```
335
     * ```twig
336
     * {% for slug, name in post.author.roles %}
337
     *     {{ slug }}
338
     * {% endfor %}
339
     * ```
340
     *
341
     * @return array|null
342
     */
343
    public function roles()
344
    {
345
        return $this->roles;
1✔
346
    }
347

348
    /**
349
     * Checks whether a user has a capability.
350
     *
351
     * Don’t use role slugs for capability checks. While checking against a role in place of a
352
     * capability is supported in part, this practice is discouraged as it may produce unreliable
353
     * results. This includes cases where you want to check whether a user is registered. If you
354
     * want to check whether a user is a Subscriber, use `{{ user.can('read') }}`. If you only want
355
     * to check whether a user is logged in, you can use `{% if user %}`.
356
     *
357
     * @api
358
     * @since 1.8.5
359
     *
360
     * @param string $capability The capability to check.
361
     * @param mixed ...$args Additional arguments to pass to the user_can function
362
     *
363
     * @example
364
     * Give moderation users another CSS class to style them differently.
365
     *
366
     * ```twig
367
     * <span class="comment-author {{ comment.author.can('moderate_comments') ? 'comment-author--is-moderator }}">
368
     *     {{ comment.author.name }}
369
     * </span>
370
     * ```
371
     *
372
     * @example
373
     * ```twig
374
     * {# Show edit link for posts that a user can edit. #}
375
     * {% if user.can('edit_post', post.id) %}
376
     *     <a href="{{post.edit_link}}">Edit Post</a>
377
     * {% endif %}
378
     *
379
     * {% if user.can('edit_term', term.id) %}
380
     *     {# do something with privileges #}
381
     * {% endif %}
382
     *
383
     * {% if user.can('edit_user', user.id) %}
384
     *     {# do something with privileges #}
385
     * {% endif %}
386
     *
387
     * {% if user.can('edit_comment', comment.id) %}
388
     *     {# do something with privileges #}
389
     * {% endif %}
390
     * ```
391
     *
392
     * @return bool Whether the user has the capability.
393
     */
394
    public function can($capability, ...$args)
395
    {
396
        return \user_can($this->wp_object, $capability, ...$args);
1✔
397
    }
398

399
    /**
400
     * Checks whether the current user can edit the post.
401
     *
402
     * @api
403
     * @example
404
     * ```twig
405
     * {% if user.can_edit %}
406
     *     <a href="{{ user.edit_link }}">Edit</a>
407
     * {% endif %}
408
     * ```
409
     * @return bool
410
     */
411
    public function can_edit(): bool
412
    {
413
        return \current_user_can('edit_user', $this->ID);
1✔
414
    }
415

416
    /**
417
     * Gets the edit link for a user if the current user has the correct rights or the profile link for the current
418
     * user.
419
     *
420
     * @api
421
     * @since 2.0.0
422
     * @example
423
     * ```twig
424
     * {% if user.can_edit %}
425
     *     <a href="{{ user.edit_link }}">Edit</a>
426
     * {% endif %}
427
     * ```
428
     *
429
     * Get the profile URL for the current user:
430
     *
431
     * ```twig
432
     * {# Assuming user is the current user. #}
433
     * {% if user %}
434
     *     <a href="{{ user.edit_link }}">My profile</a>
435
     * {% endif %}
436
     * ```
437
     * @return string|null The edit URL of a user in the WordPress admin or the profile link if the user object is for
438
     *                     the current user. Null if the current user can’t edit the user.
439
     */
440
    public function edit_link(): ?string
441
    {
442
        if (!$this->can_edit()) {
1✔
443
            return null;
1✔
444
        }
445

446
        return \get_edit_user_link($this->ID);
1✔
447
    }
448

449
    /**
450
     * Gets a user’s avatar URL.
451
     *
452
     * @api
453
     * @since 1.9.1
454
     * @example
455
     * Get a user avatar with a width and height of 150px:
456
     *
457
     * ```twig
458
     * <img src="{{ post.author.avatar({ size: 150 }) }}">
459
     * ```
460
     *
461
     * @param null|array $args Parameters for
462
     *                         [`get_avatar_url()`](https://developer.wordpress.org/reference/functions/get_avatar_url/).
463
     * @return string The avatar URL.
464
     */
465
    public function avatar($args = null)
466
    {
467
        if ($this->avatar_override) {
1✔
468
            return $this->avatar_override;
×
469
        }
470

471
        return \get_avatar_url($this->id, $args);
1✔
472
    }
473
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc