Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

engine/classes/Elgg/Assets/ExternalFiles.php (2 issues)

1
<?php
2
namespace Elgg\Assets;
3
4
use ElggPriorityList;
5
6
/**
7
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
8
 *
9
 * @access private
10
 * @since  1.10.0
11
 */
12
class ExternalFiles {
13
14
	/**
15
	 * @var ElggPriorityList[]
16
	 */
17
	protected $externals = [];
18
19
	/**
20
	 * @var array
21
	 */
22
	protected $externals_map = [];
23
24
	/**
25
	 * Core registration function for external files
26
	 *
27
	 * @param string $type     Type of external resource (js or css)
28
	 * @param string $name     Identifier used as key
29
	 * @param string $url      URL
30
	 * @param string $location Location in the page to include the file
31
	 * @param int    $priority Loading priority of the file
32
	 *
33
	 * @return bool
34
	 */
35 38
	public function register($type, $name, $url, $location, $priority = 500) {
36 38
		if (empty($name) || empty($url)) {
37 2
			return false;
38
		}
39
	
40 38
		$url = elgg_normalize_url($url);
41
42 38
		$this->setupType($type);
43
	
44 38
		$name = trim(strtolower($name));
45
	
46
		// normalize bogus priorities, but allow empty, null, and false to be defaults.
47 38
		if (!is_numeric($priority)) {
48 37
			$priority = 500;
49
		}
50
	
51
		// no negative priorities right now.
52 38
		$priority = max((int) $priority, 0);
53
	
54 38
		$item = elgg_extract($name, $this->externals_map[$type]);
55
	
56 38
		if ($item) {
57
			// updating a registered item
58
			// don't update loaded because it could already be set
59 15
			$item->url = $url;
60 15
			$item->location = $location;
61
	
62
			// if loaded before registered, that means it hasn't been added to the list yet
63 15
			if ($this->externals[$type]->contains($item)) {
64 15
				$priority = $this->externals[$type]->move($item, $priority);
65
			} else {
66 15
				$priority = $this->externals[$type]->add($item, $priority);
67
			}
68
		} else {
69
			$item = (object) [
70 24
				'loaded' => false,
71 24
				'url' => $url,
72 24
				'location' => $location,
73
			];
74 24
			$priority = $this->externals[$type]->add($item, $priority);
75
		}
76
77 38
		$this->externals_map[$type][$name] = $item;
78
	
79 38
		return $priority !== false;
80
	}
81
	
82
	/**
83
	 * Unregister an external file
84
	 *
85
	 * @param string $type Type of file: js or css
86
	 * @param string $name The identifier of the file
87
	 *
88
	 * @return bool
89
	 */
90 2
	public function unregister($type, $name) {
91 2
		$this->setupType($type);
92
	
93 2
		$name = trim(strtolower($name));
94 2
		$item = elgg_extract($name, $this->externals_map[$type]);
95
	
96 2
		if ($item) {
97 2
			unset($this->externals_map[$type][$name]);
98 2
			return $this->externals[$type]->remove($item);
99
		}
100
	
101 2
		return false;
102
	}
103
104
	/**
105
	 * Get metadata for a registered file
106
	 *
107
	 * @param string $type Type of file: js or css
108
	 * @param string $name The identifier of the file
109
	 *
110
	 * @return \stdClass|null
111
	 */
112 3
	public function getFile($type, $name) {
113 3
		$this->setupType($type);
114
115 3
		$name = trim(strtolower($name));
116 3
		if (!isset($this->externals_map[$type][$name])) {
117 1
			return null;
118
		}
119
120 3
		$item = $this->externals_map[$type][$name];
121 3
		$priority = $this->externals[$type]->getPriority($item);
122
123
		// don't allow internal properties to be altered
124 3
		$clone = clone $item;
125 3
		$clone->priority = $priority;
126
127 3
		return $clone;
128
	}
129
	
130
	/**
131
	 * Load an external resource for use on this page
132
	 *
133
	 * @param string $type Type of file: js or css
134
	 * @param string $name The identifier for the file
135
	 *
136
	 * @return void
137
	 */
138 25
	public function load($type, $name) {
139 25
		$this->setupType($type);
140
	
141 25
		$name = trim(strtolower($name));
142
	
143 25
		$item = elgg_extract($name, $this->externals_map[$type]);
144
	
145 25
		if ($item) {
146
			// update a registered item
147 23
			$item->loaded = true;
148
		} else {
149
			$item = (object) [
150 3
				'loaded' => true,
151
				'url' => '',
152
				'location' => '',
153
			];
154 3
			if (elgg_view_exists($name)) {
155
				$item->url = elgg_get_simplecache_url($name);
156
				$item->location = ($type == 'js') ? 'foot' : 'head';
157
			}
158
159 3
			$this->externals[$type]->add($item);
160 3
			$this->externals_map[$type][$name] = $item;
161
		}
162 25
	}
163
	
164
	/**
165
	 * Get external resource descriptors
166
	 *
167
	 * @param string $type     Type of file: js or css
168
	 * @param string $location Page location
169
	 *
170
	 * @return string[] URLs of files to load
171
	 */
172 7
	public function getLoadedFiles($type, $location) {
173 7
		if (!isset($this->externals[$type])) {
174 1
			return [];
175
		}
176
177 7
		$items = $this->externals[$type]->getElements();
178
179 7
		$items = array_filter($items, function($v) use ($location) {
180 7
			return $v->loaded == true && $v->location == $location;
181 7
		});
182 7
		if ($items) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
183 7
			array_walk($items, function(&$v, $k){
1 ignored issue
show
The parameter $k is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

183
			array_walk($items, function(&$v, /** @scrutinizer ignore-unused */ $k){

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
184 7
				$v = $v->url;
185 7
			});
186
		}
187 7
		return $items;
188
	}
189
190
	/**
191
	 * Get registered file objects
192
	 *
193
	 * @param string $type     Type of file: js or css
194
	 * @param string $location Page location
195
	 *
196
	 * @return \stdClass[]
197
	 */
198 1
	public function getRegisteredFiles($type, $location) {
199 1
		if (!isset($this->externals[$type])) {
200
			return [];
201
		}
202
203 1
		$ret = [];
204 1
		$items = $this->externals[$type]->getElements();
205 1
		$items = array_filter($items, function($v) use ($location) {
206 1
			return ($v->location == $location);
207 1
		});
208
209 1
		foreach ($items as $item) {
210 1
			$ret[] = clone $item;
211
		}
212
213 1
		return $ret;
214
	}
215
216
	/**
217
	 * Unregister all files
218
	 *
219
	 * @return void
220
	 */
221 7
	public function reset() {
222 7
		$this->externals = [];
223 7
		$this->externals_map = [];
224 7
	}
225
	
226
	/**
227
	 * Bootstraps the externals data structure
228
	 *
229
	 * @param string $type The type of external, js or css.
230
	 * @return void
231
	 */
232 41
	protected function setupType($type) {
233 41
		if (!isset($this->externals[$type])) {
234 25
			$this->externals[$type] = new \ElggPriorityList();
235
		}
236
	
237 41
		if (!isset($this->externals_map[$type])) {
238 25
			$this->externals_map[$type] = [];
239
		}
240 41
	}
241
}
242