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

timber / timber / 15920925840

27 Jun 2025 07:39AM UTC coverage: 88.19%. Remained the same
15920925840

push

github

web-flow
chore(deps): update .lock file and update ci steps

* chore(deps): update package versions in composer.lock
* ci: run ci also on .lock file
* chore(deps): remove deprecated twig/cache-extension dependency
* chore: add step to remove composer.lock before installing dependencies
* chore: fix shell command syntax for removing composer.lock

3883 of 4403 relevant lines covered (88.19%)

64.55 hits per line

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

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

3
namespace Timber;
4

5
use Stringable;
6
use WP_User;
7

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

57
    public $object_type = 'user';
58

59
    public static $representation = 'user';
60

61
    public $_link;
62

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

69
    /**
70
     * @api
71
     * @var int The ID from WordPress
72
     */
73
    public $id;
74

75
    /**
76
     * @api
77
     * @var string
78
     */
79
    public $user_nicename;
80

81
    /**
82
     * User email address.
83
     *
84
     * @api
85
     * @var string
86
     */
87
    public $user_email;
88

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

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

109
    /**
110
     * Build a new User object.
111
     */
112
    public static function build(WP_User $wp_user): static
113
    {
114
        $user = new static();
62✔
115
        $user->init($wp_user);
62✔
116

117
        return $user;
62✔
118
    }
119

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

137
    /**
138
     * @internal
139
     */
140
    protected function init($wp_user)
141
    {
142
        $this->wp_object = $wp_user;
62✔
143

144
        $data = \get_userdata($wp_user->ID);
62✔
145
        if (!isset($data->data)) {
62✔
146
            return;
×
147
        }
148
        $this->import($data->data);
62✔
149

150
        if (isset($data->roles)) {
62✔
151
            $this->roles = $this->get_roles($data->roles);
62✔
152
        }
153

154
        // Never leak password data
155
        unset($this->user_pass);
62✔
156
        $this->id = $this->ID = (int) $wp_user->ID;
62✔
157
    }
158

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

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

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

203
        return $this->meta($field_name);
×
204
    }
205

206
    /**
207
     * Check if the user object is the current user
208
     *
209
     * @api
210
     *
211
     * @return bool true if the user is the current user
212
     */
213
    public function is_current(): bool
214
    {
215
        return \get_current_user_id() === $this->ID;
2✔
216
    }
217

218
    /**
219
     * Get the name of the User
220
     *
221
     * @api
222
     * @return string the human-friendly name of the user (ex: "Buster Bluth")
223
     */
224
    public function name()
225
    {
226
        /**
227
         * Filters the name of a user.
228
         *
229
         * @since 1.1.4
230
         *
231
         * @param string       $name The name of the user. Default `display_name`.
232
         * @param User $user The user object.
233
         */
234
        return \apply_filters('timber/user/name', $this->display_name, $this);
16✔
235
    }
236

237
    /**
238
     * Get the relative path to the user's profile
239
     *
240
     * @api
241
     * @return string ex: /author/lincoln
242
     */
243
    public function path()
244
    {
245
        return URLHelper::get_rel_url($this->link());
1✔
246
    }
247

248
    /**
249
     * @api
250
     * @return string ex baberaham-lincoln
251
     */
252
    public function slug()
253
    {
254
        return $this->user_nicename;
3✔
255
    }
256

257
    /**
258
     * Gets a user meta value.
259
     *
260
     * @api
261
     * @deprecated 2.0.0, use `{{ user.meta('field_name') }}` instead.
262
     *
263
     * @param string $field_name The field name for which you want to get the value.
264
     * @return mixed The meta field value.
265
     */
266
    public function get_meta_field($field_name)
267
    {
268
        Helper::deprecated(
×
269
            "{{ user.get_meta_field('field_name') }}",
×
270
            "{{ user.meta('field_name') }}",
×
271
            '2.0.0'
×
272
        );
×
273

274
        return $this->meta($field_name);
×
275
    }
276

277
    /**
278
     * Gets a user meta value.
279
     *
280
     * @api
281
     * @deprecated 2.0.0, use `{{ user.meta('field_name') }}` instead.
282
     *
283
     * @param string $field_name The field name for which you want to get the value.
284
     * @return mixed The meta field value.
285
     */
286
    public function get_meta($field_name)
287
    {
288
        Helper::deprecated(
×
289
            "{{ user.get_meta('field_name') }}",
×
290
            "{{ user.meta('field_name') }}",
×
291
            '2.0.0'
×
292
        );
×
293
        return $this->meta($field_name);
×
294
    }
295

296
    /**
297
     * Creates an associative array with user role slugs and their translated names.
298
     *
299
     * @internal
300
     * @since 1.8.5
301
     * @param array $roles user roles.
302
     * @return array|null
303
     */
304
    protected function get_roles($roles)
305
    {
306
        if (empty($roles)) {
62✔
307
            // @codeCoverageIgnoreStart
308
            return null;
309
            // @codeCoverageIgnoreEnd
310
        }
311

312
        $wp_roles = \wp_roles();
62✔
313
        $names = $wp_roles->get_names();
62✔
314

315
        $values = [];
62✔
316

317
        foreach ($roles as $role) {
62✔
318
            $name = $role;
62✔
319
            if (isset($names[$role])) {
62✔
320
                $name = \translate_user_role($names[$role]);
62✔
321
            }
322
            $values[$role] = $name;
62✔
323
        }
324

325
        return $values;
62✔
326
    }
327

328
    /**
329
     * Gets the user roles.
330
     * Roles shouldn’t be used to check whether a user has a capability. Use roles only for
331
     * displaying purposes. For example, if you want to display the name of the subscription a user
332
     * has on the site behind a paywall.
333
     *
334
     * If you want to check for capabilities, use `{{ user.can('capability') }}`. If you only want
335
     * to check whether a user is logged in, you can use `{% if user %}`.
336
     *
337
     * @api
338
     * @since 1.8.5
339
     * @example
340
     * ```twig
341
     * <h2>Role name</h2>
342
     * {% for role in post.author.roles %}
343
     *     {{ role }}
344
     * {% endfor %}
345
     * ```
346
     * ```twig
347
     * <h2>Role name</h2>
348
     * {{ post.author.roles|join(', ') }}
349
     * ```
350
     * ```twig
351
     * {% for slug, name in post.author.roles %}
352
     *     {{ slug }}
353
     * {% endfor %}
354
     * ```
355
     *
356
     * @return array|null
357
     */
358
    public function roles()
359
    {
360
        return $this->roles;
1✔
361
    }
362

363
    /**
364
     * Gets the profile link to the user’s profile in the WordPress admin if the ID in the user object
365
     * is the same as the current user’s ID.
366
     *
367
     * @api
368
     * @since 2.1.0
369
     * @example
370
     *
371
     * Get the profile URL for the current user:
372
     *
373
     * ```twig
374
     * {% if user.profile_link %}
375
     *     <a href="{{ user.profile_link }}">My profile</a>
376
     * {% endif %}
377
     * ```
378
     * @return string|null The profile link for the current user.
379
     */
380
    public function profile_link(): ?string
381
    {
382
        if (!$this->is_current()) {
1✔
383
            return null;
×
384
        }
385

386
        return \get_edit_profile_url($this->ID);
1✔
387
    }
388

389
    /**
390
     * Checks whether a user has a capability.
391
     *
392
     * Don’t use role slugs for capability checks. While checking against a role in place of a
393
     * capability is supported in part, this practice is discouraged as it may produce unreliable
394
     * results. This includes cases where you want to check whether a user is registered. If you
395
     * want to check whether a user is a Subscriber, use `{{ user.can('read') }}`. If you only want
396
     * to check whether a user is logged in, you can use `{% if user %}`.
397
     *
398
     * @api
399
     * @since 1.8.5
400
     *
401
     * @param string $capability The capability to check.
402
     * @param mixed ...$args Additional arguments to pass to the user_can function
403
     *
404
     * @example
405
     * Give moderation users another CSS class to style them differently.
406
     *
407
     * ```twig
408
     * <span class="comment-author {{ comment.author.can('moderate_comments') ? 'comment-author--is-moderator }}">
409
     *     {{ comment.author.name }}
410
     * </span>
411
     * ```
412
     *
413
     * @example
414
     * ```twig
415
     * {# Show edit link for posts that a user can edit. #}
416
     * {% if user.can('edit_post', post.id) %}
417
     *     <a href="{{post.edit_link}}">Edit Post</a>
418
     * {% endif %}
419
     *
420
     * {% if user.can('edit_term', term.id) %}
421
     *     {# do something with privileges #}
422
     * {% endif %}
423
     *
424
     * {% if user.can('edit_user', user.id) %}
425
     *     {# do something with privileges #}
426
     * {% endif %}
427
     *
428
     * {% if user.can('edit_comment', comment.id) %}
429
     *     {# do something with privileges #}
430
     * {% endif %}
431
     * ```
432
     *
433
     * @return bool Whether the user has the capability.
434
     */
435
    public function can($capability, mixed ...$args)
436
    {
437
        return \user_can($this->wp_object, $capability, ...$args);
1✔
438
    }
439

440
    /**
441
     * Checks whether the current user can edit the post.
442
     *
443
     * @api
444
     * @example
445
     * ```twig
446
     * {% if user.can_edit %}
447
     *     <a href="{{ user.edit_link }}">Edit</a>
448
     * {% endif %}
449
     * ```
450
     * @return bool
451
     */
452
    public function can_edit(): bool
453
    {
454
        return \current_user_can('edit_user', $this->ID);
1✔
455
    }
456

457
    /**
458
     * Gets the edit link for a user if the current user has the correct rights or the profile link for the current
459
     * user.
460
     *
461
     * @api
462
     * @since 2.0.0
463
     * @example
464
     * ```twig
465
     * {% if user.can_edit %}
466
     *     <a href="{{ user.edit_link }}">Edit</a>
467
     * {% endif %}
468
     * ```
469
     *
470
     * Get the profile URL for the current user:
471
     *
472
     * ```twig
473
     * {# Assuming user is the current user. #}
474
     * {% if user %}
475
     *     <a href="{{ user.edit_link }}">My profile</a>
476
     * {% endif %}
477
     * ```
478
     * @return string|null The edit URL of a user in the WordPress admin or the profile link if the user object is for
479
     *                     the current user. Null if the current user can’t edit the user.
480
     */
481
    public function edit_link(): ?string
482
    {
483
        if (!$this->can_edit()) {
1✔
484
            return null;
1✔
485
        }
486

487
        return \get_edit_user_link($this->ID);
1✔
488
    }
489

490
    /**
491
     * Gets a user’s avatar URL.
492
     *
493
     * @api
494
     * @since 1.9.1
495
     * @example
496
     * Get a user avatar with a width and height of 150px:
497
     *
498
     * ```twig
499
     * <img src="{{ post.author.avatar({ size: 150 }) }}">
500
     * ```
501
     *
502
     * @param null|array $args Parameters for
503
     *                         [`get_avatar_url()`](https://developer.wordpress.org/reference/functions/get_avatar_url/).
504
     * @return string The avatar URL.
505
     */
506
    public function avatar($args = null)
507
    {
508
        if ($this->avatar_override) {
1✔
509
            return $this->avatar_override;
×
510
        }
511

512
        return \get_avatar_url($this->id, $args);
1✔
513
    }
514
}
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

© 2025 Coveralls, Inc