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

timber / timber / 20696760243

04 Jan 2026 05:44PM UTC coverage: 89.681%. Remained the same
20696760243

Pull #3172

travis-ci

web-flow
Merge d1e7c1c72 into c49cd8fc2
Pull Request #3172: fix: PHP 8.5 `null` index deprecations

33 of 33 new or added lines in 3 files covered. (100.0%)

21 existing lines in 1 file now uncovered.

4615 of 5146 relevant lines covered (89.68%)

63.45 hits per line

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

79.46
/src/Integration/AcfIntegration.php
1
<?php
2

3
/**
4
 * Integration with Advanced Custom Fields (ACF)
5
 *
6
 * @package Timber
7
 */
8

9
namespace Timber\Integration;
10

11
use ACF;
12
use DateTimeImmutable;
13
use Timber\Timber;
14

15
/**
16
 * Class used to handle integration with Advanced Custom Fields
17
 */
18
class AcfIntegration implements IntegrationInterface
19
{
UNCOV
20
    public function should_init(): bool
×
21
    {
UNCOV
22
        return \class_exists(ACF::class);
×
23
    }
24

UNCOV
25
    public function init(): void
×
26
    {
UNCOV
27
        \add_filter('timber/post/pre_meta', [self::class, 'post_get_meta_field'], 10, 5);
×
UNCOV
28
        \add_filter('timber/post/meta_object_field', [self::class, 'post_meta_object'], 10, 3);
×
29
        \add_filter('timber/term/pre_meta', [self::class, 'term_get_meta_field'], 10, 5);
×
UNCOV
30
        \add_filter('timber/user/pre_meta', [self::class, 'user_get_meta_field'], 10, 5);
×
31

32
        /**
33
         * Allowed a user to set a meta value
34
         *
35
         * @deprecated 2.0.0 with no replacement
36
         */
UNCOV
37
        \add_filter('timber/term/meta/set', [self::class, 'term_set_meta'], 10, 4);
×
38
    }
39

40
    /**
41
     * Gets meta value for a post through ACF’s API.
42
     *
43
     * @param string       $value      The field value. Default null.
44
     * @param int          $post_id    The post ID.
45
     * @param string       $field_name The name of the meta field to get the value for.
46
     * @param \Timber\Post $post       The post object.
47
     * @param array        $args       An array of arguments.
48
     * @return mixed|false
49
     */
50
    public static function post_get_meta_field($value, $post_id, $field_name, $post, $args)
20✔
51
    {
52
        return self::get_meta($value, $post_id, $field_name, $args);
20✔
53
    }
54

55
    public static function post_meta_object($value, $post_id, $field_name)
1✔
56
    {
57
        return \get_field_object($field_name, $post_id);
1✔
58
    }
59

60
    /**
61
     * Gets meta value for a term through ACF’s API.
62
     *
63
     * @param string       $value      The field value. Default null.
64
     * @param int          $term_id    The term ID.
65
     * @param string       $field_name The name of the meta field to get the value for.
66
     * @param \Timber\Term $term       The term object.
67
     * @param array        $args       An array of arguments.
68
     * @return mixed|false
69
     */
70
    public static function term_get_meta_field($value, $term_id, $field_name, $term, $args)
5✔
71
    {
72
        return self::get_meta($value, $term->taxonomy . '_' . $term_id, $field_name, $args);
5✔
73
    }
74

75
    /**
76
     * @deprecated 2.0.0, with no replacement
77
     *
78
     * @return mixed
79
     */
UNCOV
80
    public static function term_set_meta($value, $field, $term_id, $term)
×
81
    {
UNCOV
82
        $searcher = $term->taxonomy . '_' . $term->ID;
×
UNCOV
83
        \update_field($field, $value, $searcher);
×
84
        return $value;
×
85
    }
86

87
    /**
88
     * Gets meta value for a user through ACF’s API.
89
     *
90
     * @param string       $value      The field value. Default null.
91
     * @param int          $user_id    The user ID.
92
     * @param string       $field_name The name of the meta field to get the value for.
93
     * @param \Timber\User $user       The user object.
94
     * @param array        $args       An array of arguments.
95
     * @return mixed|false
96
     */
97
    public static function user_get_meta_field($value, $user_id, $field_name, $user, $args)
1✔
98
    {
99
        return self::get_meta($value, 'user_' . $user_id, $field_name, $args);
1✔
100
    }
101

102
    /**
103
     * Transform ACF file field
104
     *
105
     * @param string $value
106
     * @param int    $id
107
     * @param array  $field
108
     */
109
    public static function transform_file($value, $id, $field)
1✔
110
    {
111
        if (empty($value)) {
1✔
112
            return false;
1✔
113
        }
UNCOV
114
        return Timber::get_attachment($value);
×
115
    }
116

117
    /**
118
     * Transform ACF image field
119
     *
120
     * @param string $value
121
     * @param int    $id
122
     * @param array  $field
123
     */
124
    public static function transform_image($value, $id, $field)
2✔
125
    {
126
        if (empty($value)) {
2✔
UNCOV
127
            return false;
×
128
        }
129
        return Timber::get_image($value);
2✔
130
    }
131

132
    /**
133
     * Transform ACF gallery field
134
     *
135
     * @param array $value
136
     * @param int   $id
137
     * @param array $field
138
     */
UNCOV
139
    public static function transform_gallery($value, $id, $field)
×
140
    {
UNCOV
141
        if (empty($value)) {
×
UNCOV
142
            return false;
×
143
        }
UNCOV
144
        return Timber::get_posts($value);
×
145
    }
146

147
    /**
148
     * Transform ACF date picker field
149
     *
150
     * @param string $value
151
     * @param int    $id
152
     * @param array  $field
153
     */
154
    public static function transform_date_picker($value, $id, $field)
2✔
155
    {
156
        if (!$value) {
2✔
UNCOV
157
            return $value;
×
158
        }
159
        return new DateTimeImmutable(\acf_format_date($value, 'Y-m-d H:i:s'), \wp_timezone());
2✔
160
    }
161

162
    /**
163
     * Transform ACF post object field
164
     *
165
     * @param string $value
166
     * @param int    $id
167
     * @param array  $field
168
     */
169
    public static function transform_post_object($value, $id, $field)
2✔
170
    {
171
        if (empty($value)) {
2✔
UNCOV
172
            return false;
×
173
        }
174
        if (!$field['multiple']) {
2✔
175
            return Timber::get_post($value);
1✔
176
        }
177
        return Timber::get_posts($value);
1✔
178
    }
179

180
    /**
181
     * Transform ACF relationship field
182
     *
183
     * @param string $value
184
     * @param int    $id
185
     * @param array  $field
186
     */
187
    public static function transform_relationship($value, $id, $field)
1✔
188
    {
189
        if (empty($value)) {
1✔
UNCOV
190
            return false;
×
191
        }
192
        return Timber::get_posts($value);
1✔
193
    }
194

195
    /**
196
     * Transform ACF taxonomy field
197
     *
198
     * @param string $value
199
     * @param int    $id
200
     * @param array  $field
201
     */
202
    public static function transform_taxonomy($value, $id, $field)
2✔
203
    {
204
        if (empty($value)) {
2✔
UNCOV
205
            return false;
×
206
        }
207
        if ($field['field_type'] === 'select' || $field['field_type'] === 'radio') {
2✔
208
            return Timber::get_term((int) $value);
1✔
209
        }
210
        return Timber::get_terms((array) $value);
1✔
211
    }
212

213
    /**
214
     * Transform ACF user field
215
     *
216
     * @param string $value
217
     * @param int    $id
218
     * @param array  $field
219
     */
220
    public static function transform_user($value, $id, $field)
2✔
221
    {
222
        if (empty($value)) {
2✔
UNCOV
223
            return false;
×
224
        }
225
        if (!$field['multiple']) {
2✔
226
            return Timber::get_user((int) $value);
1✔
227
        }
228
        return Timber::get_users((array) $value);
1✔
229
    }
230

231
    /**
232
     * Gets meta value through ACF’s API.
233
     *
234
     * @param string     $value
235
     * @param int|string $id
236
     * @param string     $field_name
237
     * @param array      $args
238
     * @return mixed|false
239
     */
240
    private static function get_meta($value, $id, $field_name, $args)
26✔
241
    {
242
        $args = \wp_parse_args($args, [
26✔
243
            'format_value' => true,
26✔
244
            'transform_value' => false,
26✔
245
        ]);
26✔
246

247
        if (!$args['transform_value']) {
26✔
248
            return \get_field($field_name, $id, $args['format_value']);
14✔
249
        }
250

251
        /**
252
         * We use acf()->fields->get_field_type() instead of acf_get_field_type(), because of some function stub issues
253
         * in the php-stubs/acf-pro-stubs package. The ACF plugin doesn’t use the right parameter and return values for
254
         * some functions in the DocBlocks.
255
         *
256
         * @ticket https://github.com/timber/timber/pull/2630
257
         */
258
        $file_field_type = \acf_get_field_type('file');
12✔
259
        $image_field_type = \acf_get_field_type('image');
12✔
260
        $gallery_field_type = \acf_get_field_type('gallery');
12✔
261
        $date_picker_field_type = \acf_get_field_type('date_picker');
12✔
262
        $date_time_picker_field_type = \acf_get_field_type('date_time_picker');
12✔
263
        $post_object_field_type = \acf_get_field_type('post_object');
12✔
264
        $relationship_field_type = \acf_get_field_type('relationship');
12✔
265
        $taxonomy_field_type = \acf_get_field_type('taxonomy');
12✔
266
        $user_field_type = \acf_get_field_type('user');
12✔
267

268
        \remove_filter('acf/format_value/type=file', [$file_field_type, 'format_value']);
12✔
269
        \remove_filter('acf/format_value/type=image', [$image_field_type, 'format_value']);
12✔
270
        \remove_filter('acf/format_value/type=gallery', [$gallery_field_type, 'format_value']);
12✔
271
        \remove_filter('acf/format_value/type=date_picker', [$date_picker_field_type, 'format_value']);
12✔
272
        \remove_filter('acf/format_value/type=date_time_picker', [$date_time_picker_field_type, 'format_value']);
12✔
273
        \remove_filter('acf/format_value/type=post_object', [$post_object_field_type, 'format_value']);
12✔
274
        \remove_filter('acf/format_value/type=relationship', [$relationship_field_type, 'format_value']);
12✔
275
        \remove_filter('acf/format_value/type=taxonomy', [$taxonomy_field_type, 'format_value']);
12✔
276
        \remove_filter('acf/format_value/type=user', [$user_field_type, 'format_value']);
12✔
277

278
        \add_filter('acf/format_value/type=file', [self::class, 'transform_file'], 10, 3);
12✔
279
        \add_filter('acf/format_value/type=image', [self::class, 'transform_image'], 10, 3);
12✔
280
        \add_filter('acf/format_value/type=gallery', [self::class, 'transform_gallery'], 10, 3);
12✔
281
        \add_filter('acf/format_value/type=date_picker', [self::class, 'transform_date_picker'], 10, 3);
12✔
282
        \add_filter('acf/format_value/type=date_time_picker', [self::class, 'transform_date_picker'], 10, 3);
12✔
283
        \add_filter('acf/format_value/type=post_object', [self::class, 'transform_post_object'], 10, 3);
12✔
284
        \add_filter('acf/format_value/type=relationship', [self::class, 'transform_relationship'], 10, 3);
12✔
285
        \add_filter('acf/format_value/type=taxonomy', [self::class, 'transform_taxonomy'], 10, 3);
12✔
286
        \add_filter('acf/format_value/type=user', [self::class, 'transform_user'], 10, 3);
12✔
287

288
        $value = \get_field($field_name, $id, true);
12✔
289

290
        \add_filter('acf/format_value/type=file', [$file_field_type, 'format_value'], 10, 3);
12✔
291
        \add_filter('acf/format_value/type=image', [$image_field_type, 'format_value'], 10, 3);
12✔
292
        \add_filter('acf/format_value/type=gallery', [$gallery_field_type, 'format_value'], 10, 3);
12✔
293
        \add_filter('acf/format_value/type=date_picker', [$date_picker_field_type, 'format_value'], 10, 3);
12✔
294
        \add_filter('acf/format_value/type=date_time_picker', [$date_time_picker_field_type, 'format_value'], 10, 3);
12✔
295
        \add_filter('acf/format_value/type=post_object', [$post_object_field_type, 'format_value'], 10, 3);
12✔
296
        \add_filter('acf/format_value/type=relationship', [$relationship_field_type, 'format_value'], 10, 3);
12✔
297
        \add_filter('acf/format_value/type=taxonomy', [$taxonomy_field_type, 'format_value'], 10, 3);
12✔
298
        \add_filter('acf/format_value/type=user', [$user_field_type, 'format_value'], 10, 3);
12✔
299

300
        \remove_filter('acf/format_value/type=file', [self::class, 'transform_file']);
12✔
301
        \remove_filter('acf/format_value/type=image', [self::class, 'transform_image']);
12✔
302
        \remove_filter('acf/format_value/type=gallery', [self::class, 'transform_gallery']);
12✔
303
        \remove_filter('acf/format_value/type=date_picker', [self::class, 'transform_date_picker']);
12✔
304
        \remove_filter('acf/format_value/type=date_time_picker', [self::class, 'transform_date_picker']);
12✔
305
        \remove_filter('acf/format_value/type=post_object', [self::class, 'transform_post_object']);
12✔
306
        \remove_filter('acf/format_value/type=relationship', [self::class, 'transform_relationship']);
12✔
307
        \remove_filter('acf/format_value/type=taxonomy', [self::class, 'transform_taxonomy']);
12✔
308
        \remove_filter('acf/format_value/type=user', [self::class, 'transform_user']);
12✔
309

310
        return $value;
12✔
311
    }
312
}
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