• 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

97.73
/src/LocationManager.php
1
<?php
2

3
namespace Timber;
4

5
class LocationManager
6
{
7
    /**
8
     * @param bool|string   $caller the calling directory (or false)
9
     * @return array
10
     */
11
    public static function get_locations($caller = false)
12
    {
13
        //priority: user locations, caller (but not theme), child theme, parent theme, caller, open_basedir
14
        $locs = [];
409✔
15
        $locs = \array_merge_recursive($locs, self::get_locations_user());
409✔
16
        $locs = \array_merge_recursive($locs, self::get_locations_caller($caller));
409✔
17
        //remove themes from caller
18
        $locs = \array_merge_recursive($locs, self::get_locations_theme());
409✔
19
        $locs = \array_merge_recursive($locs, self::get_locations_caller($caller));
409✔
20
        $locs = \array_merge_recursive($locs, self::get_locations_open_basedir());
409✔
21
        $locs = \array_map('array_unique', $locs);
409✔
22

23
        //now make sure theres a trailing slash on everything
24
        $locs = \array_map(function ($loc) {
409✔
25
            return \array_map('trailingslashit', $loc);
409✔
26
        }, $locs);
409✔
27

28
        /**
29
         * Filters …
30
         *
31
         * @todo Add summary, description, example, parameter description
32
         *
33
         * @since 0.20.10
34
         *
35
         * @param array $locs
36
         */
37
        $locs = \apply_filters('timber/locations', $locs);
409✔
38

39
        /**
40
         * Filters …
41
         *
42
         * @todo Add summary
43
         *
44
         * @deprecated 2.0.0, use `timber/locations`
45
         */
46
        $locs = \apply_filters_deprecated('timber_locations', [$locs], '2.0.0', 'timber/locations');
409✔
47

48
        return $locs;
409✔
49
    }
50

51
    /**
52
     * @return array
53
     */
54
    protected static function get_locations_theme()
55
    {
56
        $theme_locs = [];
409✔
57
        $theme_dirs = LocationManager::get_locations_theme_dir();
409✔
58
        $roots = [\get_stylesheet_directory(), \get_template_directory()];
409✔
59
        $roots = \array_map('realpath', $roots);
409✔
60
        $roots = \array_unique($roots);
409✔
61
        foreach ($roots as $root) {
409✔
62
            if (!\is_dir($root)) {
409✔
63
                continue;
×
64
            }
65

66
            $theme_locs[Loader::MAIN_NAMESPACE][] = $root;
409✔
67
            $root = \trailingslashit($root);
409✔
68
            foreach ($theme_dirs as $namespace => $dirnames) {
409✔
69
                $dirnames = self::convert_to_array($dirnames);
409✔
70
                \array_map(function ($dirname) use ($root, $namespace, &$theme_locs) {
409✔
71
                    $tloc = \realpath($root . $dirname);
409✔
72
                    if (\is_dir($tloc)) {
409✔
73
                        $theme_locs[$namespace][] = $tloc;
408✔
74
                    }
75
                }, $dirnames);
409✔
76
            }
77
        }
78

79
        return $theme_locs;
409✔
80
    }
81

82
    /**
83
     * Get calling script file.
84
     * @api
85
     * @param int     $offset
86
     * @return string|null
87
     */
88
    public static function get_calling_script_file($offset = 0)
89
    {
90
        $callers = [];
82✔
91
        $backtrace = \debug_backtrace();
82✔
92
        foreach ($backtrace as $trace) {
82✔
93
            if (\array_key_exists('file', $trace) && $trace['file'] != __FILE__) {
82✔
94
                $callers[] = $trace['file'];
82✔
95
            }
96
        }
97
        $callers = \array_unique($callers);
82✔
98
        $callers = \array_values($callers);
82✔
99
        return $callers[$offset];
82✔
100
    }
101

102
    /**
103
     * Get calling script dir.
104
     * @api
105
     * @return string|null
106
     */
107
    public static function get_calling_script_dir($offset = 0)
108
    {
109
        $caller = self::get_calling_script_file($offset);
81✔
110
        if (!\is_null($caller)) {
81✔
111
            $pathinfo = PathHelper::pathinfo($caller);
81✔
112
            $dir = $pathinfo['dirname'];
81✔
113
            return $dir;
81✔
114
        }
115

116
        return null;
×
117
    }
118

119
    /**
120
     * returns an array of the directory inside themes that holds twig files
121
     * @return array the names of directores, ie: array('__MAIN__' => ['templats', 'views']);
122
     */
123
    public static function get_locations_theme_dir()
124
    {
125
        if (\is_string(Timber::$dirname)) {
409✔
126
            return [
155✔
127
                Loader::MAIN_NAMESPACE => [Timber::$dirname],
155✔
128
            ];
155✔
129
        }
130
        return Timber::$dirname;
254✔
131
    }
132

133
    /**
134
     * @deprecated since 2.0.0 Use `add_filter('timber/locations', $locations)` instead.
135
     * @return array
136
     */
137
    protected static function get_locations_user()
138
    {
139
        $locs = [];
409✔
140
        if (isset(Timber::$locations)) {
409✔
141
            if (\is_string(Timber::$locations)) {
251✔
142
                Timber::$locations = [Timber::$locations];
1✔
143
            }
144
            foreach (Timber::$locations as $tloc => $namespace_or_tloc) {
251✔
145
                if (\is_string($tloc)) {
251✔
146
                    $namespace = $namespace_or_tloc;
250✔
147
                } else {
148
                    $tloc = $namespace_or_tloc;
3✔
149
                    $namespace = null;
3✔
150
                }
151

152
                $tloc = \realpath($tloc);
251✔
153
                if (\is_dir($tloc)) {
251✔
154
                    if (!\is_string($namespace)) {
251✔
155
                        $locs[Loader::MAIN_NAMESPACE][] = $tloc;
3✔
156
                    } else {
157
                        $locs[$namespace][] = $tloc;
250✔
158
                    }
159
                }
160
            }
161
        }
162

163
        return $locs;
409✔
164
    }
165

166
    /**
167
     *
168
     * Converts the variable to an array with the var as the sole element. Ignores if it's already an array
169
     *
170
     * @param mixed $var the variable to test and maybe convert
171
     * @return array
172
     */
173
    protected static function convert_to_array($var)
174
    {
175
        if (\is_string($var)) {
409✔
176
            $var = [$var];
5✔
177
        }
178
        return $var;
409✔
179
    }
180

181
    /**
182
     * @param bool|string   $caller the calling directory
183
     * @return array
184
     */
185
    protected static function get_locations_caller($caller = false)
186
    {
187
        $locs = [];
409✔
188
        if ($caller && \is_string($caller)) {
409✔
189
            $caller = \realpath($caller);
81✔
190
            if (\is_dir($caller)) {
81✔
191
                $locs[Loader::MAIN_NAMESPACE][] = $caller;
81✔
192
            }
193
            $caller = \trailingslashit($caller);
81✔
194
            foreach (LocationManager::get_locations_theme_dir() as $namespace => $dirnames) {
81✔
195
                $dirnames = self::convert_to_array($dirnames);
81✔
196
                \array_map(function ($dirname) use ($caller, $namespace, &$locs) {
81✔
197
                    $caller_sub = \realpath($caller . $dirname);
81✔
198
                    if (\is_dir($caller_sub)) {
81✔
199
                        $locs[$namespace][] = $caller_sub;
1✔
200
                    }
201
                }, $dirnames);
81✔
202
            }
203
        }
204

205
        return $locs;
409✔
206
    }
207

208
    /**
209
     * returns an array of the directory set with "open_basedir"
210
     * see : https://www.php.net/manual/en/ini.core.php#ini.open-basedir
211
     * @return array
212
     */
213
    protected static function get_locations_open_basedir()
214
    {
215
        $open_basedir = \ini_get('open_basedir');
409✔
216

217
        return [
409✔
218
            Loader::MAIN_NAMESPACE => [
409✔
219
                $open_basedir ? ABSPATH : '/',
409✔
220
            ],
409✔
221
        ];
409✔
222
    }
223
}
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