Image   B
last analyzed

Complexity

Total Complexity 50

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 77
c 1
b 0
f 1
dl 0
loc 202
rs 8.4
wmc 50

4 Methods

Rating   Name   Duplication   Size   Complexity  
F map() 0 86 34
A invalidate() 0 12 4
A get_extension() 0 6 1
B find() 0 58 11

How to fix   Complexity   

Complex Class

Complex classes like Image often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Image, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * EGroupware API: Finding template specific images
4
 *
5
 * @link http://www.egroupware.org
6
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
7
 * @package api
8
 * @subpackage image
9
 * @version $Id$
10
 */
11
12
namespace EGroupware\Api;
13
14
/**
15
 * Finding template specific images
16
 *
17
 * Images availability is cached on instance level, cache can be invalidated by
18
 * calling Admin >> Delete cache and register hooks.
19
 */
20
class Image
21
{
22
	/**
23
	 * Searches a appname, template and maybe language and type-specific image
24
	 *
25
	 * @param string $app
26
	 * @param string|array $image one or more image-name in order of precedence
27
	 * @param string $extension ='' extension to $image, makes sense only with an array
28
	 * @param boolean $add_cachebuster =false true: add a cachebuster to the returnd url
29
	 *
30
	 * @return string url of image or null if not found
31
	 */
32
	static function find($app,$image,$extension='',$add_cachebuster=false)
33
	{
34
		$image_map = self::map(null);
35
36
		// array of images in descending precedence
37
		if (is_array($image))
38
		{
39
			foreach($image as $img)
40
			{
41
				if (($url = self::find($app, $img, $extension, $add_cachebuster)))
42
				{
43
					return $url;
44
				}
45
			}
46
			//error_log(__METHOD__."('$app', ".array2string($image).", '$extension') NONE found!");
47
			return null;
48
		}
49
50
		$webserver_url = $GLOBALS['egw_info']['server']['webserver_url'];
51
52
		// instance specific images have highest precedence
53
		if (isset($image_map['vfs'][$image.$extension]))
54
		{
55
			$url = $webserver_url.$image_map['vfs'][$image.$extension];
56
		}
57
		// then app specific ones
58
		elseif(isset($image_map[$app][$image.$extension]))
59
		{
60
			$url = $webserver_url.$image_map[$app][$image.$extension];
61
		}
62
		// then api
63
		elseif(isset($image_map['api'][$image.$extension]))
64
		{
65
			$url = $webserver_url.$image_map['api'][$image.$extension];
66
		}
67
		elseif(isset($image_map['phpgwapi'][$image.$extension]))
68
		{
69
			$url = $webserver_url.$image_map['phpgwapi'][$image.$extension];
70
		}
71
72
		if (!empty($url))
73
		{
74
			if ($add_cachebuster)
75
			{
76
				$url .= '?'.filemtime(EGW_SERVER_ROOT.substr($url, strlen($webserver_url)));
77
			}
78
			return $url;
79
		}
80
81
		// if image not found, check if it has an extension and try withoug
82
		if (strpos($image, '.') !== false)
83
		{
84
			$name = null;
85
			self::get_extension($image, $name);
86
			return self::find($app, $name, $extension, $add_cachebuster);
87
		}
88
		//error_log(__METHOD__."('$app', '$image', '$extension') image NOT found!");
89
		return null;
90
	}
91
92
	/**
93
	 * Get extension (and optional basename without extension) of a given path
94
	 *
95
	 * @param string $path
96
	 * @param string &$name on return basename without extension
97
	 * @return string extension without dot, eg. 'php'
98
	 */
99
	protected static function get_extension($path, &$name=null)
100
	{
101
		$parts = explode('.', Vfs::basename($path));
102
		$ext = array_pop($parts);
103
		$name = implode('.', $parts);
104
		return $ext;
105
	}
106
107
	/**
108
	 * Scan filesystem for images of all apps
109
	 *
110
	 * For each application and image-name (without extension) one full path is returned.
111
	 * The path takes template-set and image-type-priority (now fixed to: png, jpg, gif, ico) into account.
112
	 *
113
	 * VFS image directory is treated like an application named 'vfs'.
114
	 *
115
	 * @param string $template_set =null 'default', 'idots', 'jerryr', default is template-set from user prefs
116
	 *
117
	 * @return array of application => image-name => full path
118
	 */
119
	public static function map($template_set=null)
120
	{
121
		if (is_null($template_set))
122
		{
123
			$template_set = $GLOBALS['egw_info']['server']['template_set'];
124
		}
125
126
		$cache_name = 'image_map_'.$template_set.'_svg'.(Header\UserAgent::mobile() ? '_mobile' : '');
127
		if (($map = Cache::getInstance(__CLASS__, $cache_name)))
128
		{
129
			return $map;
130
		}
131
		//$starttime = microtime(true);
132
133
		// priority: : SVG->PNG->JPG->GIF->ICO
134
		$img_types = array('svg','png','jpg','gif','ico');
135
136
		$map = array();
137
		foreach(scandir(EGW_SERVER_ROOT) as $app)
138
		{
139
			if ($app[0] == '.' || !is_dir(EGW_SERVER_ROOT.'/'.$app) || !file_exists(EGW_SERVER_ROOT.'/'.$app.'/templates')) continue;
140
141
			$app_map =& $map[$app];
142
			if (true) $app_map = array();
143
			$imagedirs = array();
144
			if (Header\UserAgent::mobile())
145
			{
146
				$imagedirs[] = '/'.$app.'/templates/mobile/images';
147
			}
148
			if ($app == 'api')
149
			{
150
				$imagedirs[] = $GLOBALS['egw']->framework->template_dir.'/images';
151
			}
152
			else
153
			{
154
				$imagedirs[] = '/'.$app.'/templates/'.$template_set.'/images';
155
			}
156
			if ($template_set != 'idots') $imagedirs[] = '/'.$app.'/templates/idots/images';
157
			$imagedirs[] = '/'.$app.'/templates/default/images';
158
159
			foreach($imagedirs as $imagedir)
160
			{
161
				if (!file_exists($dir = EGW_SERVER_ROOT.$imagedir) || !is_readable($dir)) continue;
162
163
				foreach(scandir($dir) as $img)
164
				{
165
					if ($img[0] == '.') continue;
166
167
					$subdir = null;
168
					foreach(is_dir($dir.'/'.$img) ? scandir($dir.'/'.($subdir=$img)) : (array) $img as $img)
0 ignored issues
show
Comprehensibility Bug introduced by
$img is overwriting a variable from outer foreach loop.
Loading history...
169
					{
170
						$name = null;
171
						if (!in_array($ext = self::get_extension($img, $name), $img_types) || empty($name)) continue;
172
173
						if (isset($subdir)) $name = $subdir.'/'.$name;
174
175
						if (!isset($app_map[$name]) || array_search($ext, $img_types) < array_search(self::get_extension($app_map[$name]), $img_types))
176
						{
177
							$app_map[$name] = $imagedir.'/'.$name.'.'.$ext;
178
						}
179
					}
180
				}
181
			}
182
		}
183
		$app_map =& $map['vfs'];
184
		if (true) $app_map = array();
185
		if (($dir = $GLOBALS['egw_info']['server']['vfs_image_dir']) && Vfs::file_exists($dir) && Vfs::is_readable($dir))
186
		{
187
			foreach(Vfs::find($dir) as $img)
188
			{
189
				if (!in_array($ext = self::get_extension($img, $name), $img_types) || empty($name)) continue;
190
191
				if (!isset($app_map[$name]) || array_search($ext, $img_types) < array_search(self::get_extension($app_map[$name]), $img_types))
192
				{
193
					$app_map[$name] = Vfs::download_url($img);
194
				}
195
			}
196
		}
197
		else if ($dir)
198
		{
199
			return $map;
200
		}
201
		//error_log(__METHOD__."('$template_set') took ".(microtime(true)-$starttime).' secs');
202
		Cache::setInstance(__CLASS__, $cache_name, $map, 86400);	// cache for one day
203
		//echo "<p>template_set=".array2string($template_set)."</p>\n"; _debug_array($map);
204
		return $map;
205
	}
206
207
	/**
208
	 * Delete image map cache for ALL template sets
209
	 */
210
	public static function invalidate()
211
	{
212
		$templates = array('idots', 'jerryr', 'jdots', 'pixelegg');
213
		if (($template_set = $GLOBALS['egw_info']['user']['preferences']['common']['template_set']) && !in_array($template_set, $templates))
214
		{
215
			$templates[] = $template_set;
216
		}
217
		//error_log(__METHOD__."() for templates ".array2string($templates));
218
		foreach($templates as $template_set)
219
		{
220
			Cache::unsetInstance(__CLASS__, 'image_map_'.$template_set);
221
			Cache::unsetInstance(__CLASS__, 'image_map_'.$template_set.'_svg');
222
		}
223
	}
224
}
225