Completed
Push — master ( c4957a...984033 )
by cam
05:10 queued 11s
created

svg.php ➔ svg_getimagesize_from_attr()   C

Complexity

Conditions 14
Paths 200

Size

Total Lines 62

Duplication

Lines 33
Ratio 53.23 %

Importance

Changes 0
Metric Value
cc 14
nc 200
nop 1
dl 33
loc 62
rs 5.4333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2019                                                *
7
 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8
 *                                                                         *
9
 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10
 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11
\***************************************************************************/
12
13
/**
14
 * Outils pour lecture/manipulation simple de SVG
15
 *
16
 * @package SPIP\Core\SVG
17
 **/
18
19
if (!defined('_ECRIRE_INC_VERSION')) {
20
	return;
21
}
22
23
if (!defined('IMG_SVG')) {
24
	// complete 	IMG_BMP | IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP | IMG_XPM | IMG_WEBP
25
	define('IMG_SVG',128);
26
	define('IMAGETYPE_SVG', 19);
27
}
28
29
/**
30
 * Charger une image SVG a partir d'une source qui peut etre
31
 * - l'image svg deja chargee
32
 * - une data-url
33
 * - un nom de fichier
34
 *
35
 * @param string $fichier
36
 * @param null|int $maxlen
37
 *   pour limiter la taille chargee en memoire si on lit depuis le disque et qu'on a besoin que du debut du fichier
38
 * @return bool|string
39
 *   false si on a pas pu charger l'image
40
 */
41
function svg_charger($fichier, $maxlen=null) {
42
	if (strpos($fichier, "data:image/svg+xml") === 0) {
43
		$image = explode(";", $fichier, 2);
44
		$image = end($image);
45
		if (strpos($image, "base64,") === 0) {
46
			$image = base64_decode(substr($image, 7));
47
		}
48
		if (strpos($image, "<svg") !== false) {
49
			return $image;
50
		}
51
		// encodage inconnu ou autre format d'image ?
52
		return false;
53
	}
54
	// c'est peut etre deja une image svg ?
55
	if (strpos($fichier, "<svg") !== false) {
56
		return $fichier;
57
	}
58
	if (!file_exists($fichier)) {
59
		$fichier  = supprimer_timestamp($fichier);
60
		if (!file_exists($fichier)) {
61
			return false;
62
		}
63
	}
64
	if (is_null($maxlen)) {
65
		$image = file_get_contents($fichier);
66
	}
67
	else {
68
		$image = file_get_contents($fichier, false,null,0, $maxlen);
69
	}
70
	// est-ce bien une image svg ?
71
	if (strpos($image, "<svg") !== false) {
72
		return $image;
73
	}
74
	return false;
75
}
76
77
/**
78
 * Lire la balise <svg...> qui demarre le fichier et la parser pour renvoyer un tableau de ses attributs
79
 * @param string $fichier
80
 * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|array<string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
81
 */
82
function svg_lire_balise_svg($fichier) {
83
	if (!$debut_fichier = svg_charger($fichier, 4096)) {
84
		return false;
85
	}
86
87
	if (($ps = stripos($debut_fichier, "<svg")) !== false) {
88
89
		$pe = stripos($debut_fichier, ">", $ps);
90
		$balise_svg = substr($debut_fichier, $ps, $pe - $ps +1);
91
92
		if (preg_match_all(",([\w:\-]+)=,Uims", $balise_svg, $matches)) {
93
			if (!function_exists('extraire_attribut')) {
94
				include_spip('inc/filtres');
95
			}
96
			$attributs = [];
97
			foreach ($matches[1] as $att) {
98
				$attributs[$att] = extraire_attribut($balise_svg, $att);
99
			}
100
101
			return [$balise_svg, $attributs];
102
		}
103
	}
104
105
	return false;
106
}
107
108
/**
109
 * Attributs de la balise SVG
110
 * @param string $img
111
 * @return array|bool
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array|false.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
112
 */
113
function svg_lire_attributs($img) {
114
115
	if ($svg_infos = svg_lire_balise_svg($img)) {
116
		list($balise_svg, $attributs) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
117
		return $attributs;
118
	}
119
120
	return false;
121
}
122
123
/**
124
 * Convertir l'attribut widht/height d'un SVG en pixels
125
 * (approximatif eventuellement, du moment qu'on respecte le ratio)
126
 * @param $dimension
127
 * @return bool|float|int
0 ignored issues
show
Documentation introduced by
Should the return type not be false|double|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
128
 */
129
function svg_dimension_to_pixels($dimension, $precision = 2) {
130
	if (preg_match(',^(-?\d+(\.\d+)?)([^\d]*),i', trim($dimension), $m)){
131
		switch (strtolower($m[2])) {
132
			case '%':
133
				// on ne sait pas faire :(
134
				return false;
135
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
136
			case 'em':
137
				return round($m[1]*16, $precision); // 16px font-size par defaut
138
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
139
			case 'ex':
140
				return round($m[1]*16, $precision); // 16px font-size par defaut
141
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
142
			case 'pc':
143
				return round($m[1]*16, $precision); // 1/6 inch = 96px/6 in CSS
144
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
145
			case 'cm':
146
				return round($m[1]*96/2.54, $precision); // 96px / 2.54cm;
147
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
148
			case 'mm':
149
				return round($m[1]*96/25.4, $precision); // 96px / 25.4mm;
150
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
151
			case 'in':
152
				return round($m[1]*96, $precision); // 1 inch = 96px in CSS
153
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
154
			case 'px':
155
			case 'pt':
156
			default:
157
				return $m[1];
158
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
159
		}
160
	}
161
	return false;
162
}
163
164
/**
165
 * Modifier la balise SVG en entete du source
166
 * @param string $svg
167
 * @param string $old_balise_svg
168
 * @param array $attributs
169
 * @return string
170
 */
171
function svg_change_balise_svg($svg, $old_balise_svg, $attributs) {
172
	$new_balise_svg = "<svg";
173
	foreach ($attributs as $k=>$v) {
174
		$new_balise_svg .= " $k=\"".entites_html($v)."\"";
175
	}
176
	$new_balise_svg .= ">";
177
178
	$p = strpos($svg, $old_balise_svg);
179
	$svg = substr_replace($svg, $new_balise_svg, $p, strlen($old_balise_svg));
180
	return $svg;
181
}
182
183
/**
184
 * @param string $svg
185
 * @param string $shapes
186
 * @param bool|string $start
187
 *   inserer au debut (true) ou a la fin (false)
188
 * @return string
189
 */
190
function svg_insert_shapes($svg, $shapes, $start=true) {
191
192
	if ($start === false or $start === 'end') {
193
		$svg = str_replace("</svg>", $shapes . "</svg>", $svg);
194
	}
195
	else {
196
		$p = stripos($svg, "<svg");
197
		$p = strpos($svg, ">", $p);
198
		$svg = substr_replace($svg, $shapes, $p+1, 0);
199
	}
200
	return $svg;
201
}
202
203
/**
204
 * Clipper le SVG dans une box
205
 * @param string $svg
206
 * @param int $x
207
 * @param int $y
208
 * @param int $width
209
 * @param int $height
210
 * @return string
211
 */
212
function svg_clip_in_box($svg, $x, $y, $width, $height) {
213
	$rect = "<rect x=\"$x\" y=\"$y\" width=\"$width\" height=\"$height\" />";
214
	$id = 'clip-'.substr(md5($rect . strlen($svg)),0,8);
215
	$clippath = "<clipPath id=\"$id\">$rect</clipPath>";
216
	$g = "<g clip-path=\"url(#$id)\">";
217
	$svg = svg_insert_shapes($svg, $clippath . $g);
218
	$svg = svg_insert_shapes($svg, "</g>", false);
219
	return $svg;
220
}
221
222
/**
223
 * Redimensionner le SVG via le width/height de la balise
224
 * @param string $img
225
 * @param $new_width
226
 * @param $new_height
227
 * @return bool|string
228
 */
229
function svg_redimensionner($img, $new_width, $new_height) {
230
	if ($svg = svg_charger($img)
231
	  and $svg_infos = svg_lire_balise_svg($svg)) {
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 230 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
232
233
		list($balise_svg, $attributs) = $svg_infos;
234
		if (!isset($attributs['viewBox'])) {
235
			$attributs['viewBox'] = "0 0 " . $attributs['width'] . " " . $attributs['height'];
236
		}
237
		$attributs['width'] = strval($new_width);
238
		$attributs['height'] = strval($new_height);
239
240
		$svg = svg_change_balise_svg($svg, $balise_svg, $attributs);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_change_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
241
		return $svg;
242
	}
243
244
	return $img;
245
}
246
247
/**
248
 * Transformer une couleur extraite du SVG en hexa
249
 * @param string $couleur
250
 * @return string
251
 */
252
function svg_couleur_to_hexa($couleur) {
253
	if (strpos($couleur, "rgb(")===0) {
254
		$c = explode(',', substr($couleur, 4));
255
		$couleur = _couleur_dec_to_hex(intval($c[0]), intval($c[1]), intval($c[2]));
256
	}
257
	else {
258
		$couleur = couleur_html_to_hex($couleur);
259
	}
260
	$couleur = '#'.ltrim($couleur,'#');
261
	return $couleur;
262
}
263
264
/**
265
 * Transformer une couleur extraite du SVG en rgb
266
 * @param string $couleur
267
 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,integer|double>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
268
 */
269
function svg_couleur_to_rgb($couleur) {
270
	if (strpos($couleur, "rgb(")===0) {
271
		$c = explode(',', substr($couleur, 4));
272
		return ['red' => intval($c[0]),'green' => intval($c[1]),'blue' => intval($c[2])];
273
	}
274
	return _couleur_hex_to_dec($couleur);
275
}
276
277
278
/**
279
 * Calculer les dimensions width/heigt/viewBox du SVG d'apres les attributs de la balise <svg>
280
 * @param array $attributs
281
 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<double|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
282
 */
283
function svg_getimagesize_from_attr($attributs) {
284
	$width = 350; // default width
285
	$height = 150; // default height
286
287
	$viewBox = "0 0 $width $height";
288
	if (isset($attributs['viewBox'])) {
289
		$viewBox = $attributs['viewBox'];
290
		$viewBox = preg_replace(",\s+,", " ", $viewBox);
291
	}
292
	// et on la convertit en px
293
	$viewBox = explode(' ', $viewBox);
294
	$viewBox = array_map('svg_dimension_to_pixels', $viewBox);
295
	if (!$viewBox[2]) {
296
		$viewBox[2] = $width;
297
	}
298
	if (!$viewBox[3]) {
299
		$viewBox[3] = $height;
300
	}
301
302
	$coeff = 1;
303 View Code Duplication
	if (isset($attributs['width'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
304
	  and $w = svg_dimension_to_pixels($attributs['width'])) {
305
		$width = $w;
306
	}
307
	else {
308
		// si on recupere la taille de la viewbox mais si la viewbox est petite on met un multiplicateur pour la taille finale
309
		$width = $viewBox[2];
310
		if ($width < 1) {
311
			$coeff = max($coeff, 1000);
312
		}
313
		elseif ($width < 10) {
314
			$coeff = max($coeff, 100);
315
		}
316
		elseif ($width < 100) {
317
			$coeff = max($coeff, 10);
318
		}
319
	}
320 View Code Duplication
	if (isset($attributs['height'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321
	  and $h = svg_dimension_to_pixels($attributs['height'])) {
322
		$height = $h;
323
	}
324
	else {
325
		$height = $viewBox[3];
326
		if ($height < 1) {
327
			$coeff = max($coeff, 1000);
328
		}
329
		elseif ($height < 10) {
330
			$coeff = max($coeff, 100);
331
		}
332
		elseif ($height < 100) {
333
			$coeff = max($coeff, 10);
334
		}
335
	}
336
337
	// arrondir le width et height en pixel in fine
338
	$width = round($coeff * $width);
339
	$height = round($coeff * $height);
340
341
	$viewBox = implode(' ', $viewBox);
342
343
	return array($width, $height, $viewBox);
344
}
345
346
/**
347
 * Forcer la viewBox du SVG, en px
348
 * cree l'attribut viewBox si il n'y en a pas
349
 * convertit les unites en px si besoin
350
 *
351
 * Les manipulations d'image par les filtres images se font en px, on a donc besoin d'une viewBox en px
352
 * Certains svg produits avec des unites exotiques subiront donc peut etre des deformations...
353
 *
354
 * @param string $img
355
 * @param bool $force_width_and_height
356
 * @return string
357
 */
358
function svg_force_viewBox_px($img, $force_width_and_height = false) {
359
	if ($svg = svg_charger($img)
360
	  and $svg_infos = svg_lire_balise_svg($svg)){
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 359 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
361
362
		list($balise_svg, $attributs) = $svg_infos;
363
364
		list($width, $height, $viewBox) = svg_getimagesize_from_attr($attributs);
365
366
		if ($force_width_and_height) {
367
			$attributs['width'] = $width;
368
			$attributs['height'] = $height;
369
		}
370
371
		$attributs['viewBox'] = $viewBox;
372
373
		$svg = svg_change_balise_svg($svg, $balise_svg, $attributs);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_change_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
374
		return $svg;
375
	}
376
	return $img;
377
}
378
379
/**
380
 * Extract all colors in SVG
381
 * @param $img
382
 * @return array|mixed
383
 */
384
function svg_extract_couleurs($img) {
385
	if ($svg = svg_charger($img)) {
386
		if (preg_match_all("/(#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])|(rgb\([\s\d]+,[\s\d]+,[\s\d]+\))|(#[0-9a-f][0-9a-f][0-9a-f])/imS", $svg, $matches)) {
387
			return $matches[0];
388
		}
389
	}
390
	return [];
391
}
392
393
/**
394
 * Redimensionner le SVG via le width/height de la balise
395
 * @param string $img
396
 * @param $new_width
397
 * @param $new_height
398
 * @return bool|string
399
 */
400
function svg_recadrer($img, $new_width, $new_height, $offset_width, $offset_height, $background_color='') {
401
	if ($svg = svg_force_viewBox_px($img)
402
	  and $svg_infos = svg_lire_balise_svg($svg)) {
403
404
		list($balise_svg, $attributs) = $svg_infos;
405
		$viewBox = explode(' ', $attributs['viewBox']);
406
407
		$viewport_w = $new_width;
408
		$viewport_h = $new_height;
409
		$viewport_ox = $offset_width;
410
		$viewport_oy = $offset_height;
411
412
		// si on a un width/height qui rescale, il faut rescaler
413
		if (isset ($attributs['width'])
414
		  and $w = svg_dimension_to_pixels($attributs['width'])
415
		  and isset ($attributs['height'])
416
		  and $h = svg_dimension_to_pixels($attributs['height'])) {
417
418
			$xscale = $viewBox[2] / $w;
419
			$viewport_w = round($viewport_w * $xscale, 2);
420
			$viewport_ox = round($viewport_ox * $xscale, 2);
421
			$yscale = $viewBox[3] / $h;
422
			$viewport_h = round($viewport_h * $yscale, 2);
423
			$viewport_oy = round($viewport_oy * $yscale, 2);
424
		}
425
426
		if ($viewport_w>$viewBox[2] or $viewport_h>$viewBox[3]) {
427
			$svg = svg_clip_in_box($svg, $viewBox[0], $viewBox[1], $viewBox[2], $viewBox[3]);
428
		}
429
430
		// maintenant on redefinit la viewBox
431
		$viewBox[0] += $viewport_ox;
432
		$viewBox[1] += $viewport_oy;
433
		$viewBox[2] = $viewport_w;
434
		$viewBox[3] = $viewport_h;
435
436
		$attributs['viewBox'] = implode(' ', $viewBox);
437
		$attributs['width'] = strval($new_width);
438
		$attributs['height'] = strval($new_height);
439
440
		$svg = svg_change_balise_svg($svg, $balise_svg, $attributs);
441
442
		// ajouter un background
443
		if ($background_color and $background_color!=='transparent') {
444
			$svg = svg_ajouter_background($svg, $background_color);
445
		}
446
447
		return $svg;
448
	}
449
450
	return $img;
451
}
452
453
/**
454
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
455
 * @param $img
456
 * @param $background_color
457
 * @return bool|string
458
 */
459 View Code Duplication
function svg_ajouter_background($img, $background_color) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
460
	if ($svg = svg_charger($img)
461
	  and $svg_infos = svg_lire_balise_svg($svg)){
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 460 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
462
463
		if ($background_color and $background_color!=='transparent') {
464
			list($balise_svg, $attributs) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
465
466
			$background_color = svg_couleur_to_hexa($background_color);
467
			if (isset($attributs['viewBox'])) {
468
				$viewBox = explode(' ', $attributs['viewBox']);
469
				$rect = "<rect x=\"".$viewBox[0]."\" y=\"".$viewBox[1]."\" width=\"".$viewBox[2]."\" height=\"".$viewBox[3]."\" fill=\"$background_color\"/>";
470
			}
471
			else {
472
				$rect = "<rect width=\"100%\" height=\"100%\" fill=\"$background_color\"/>";
473
			}
474
			$svg = svg_insert_shapes($svg, $rect);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_insert_shapes() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
475
		}
476
		return $svg;
477
	}
478
	return $img;
479
}
480
481
482
/**
483
 * Ajouter un voile au SVG : un rect pleine taille avec la bonne couleur/opacite, en premier plan
484
 * @param $img
485
 * @param $background_color
486
 * @return bool|string
487
 */
488 View Code Duplication
function svg_ajouter_voile($img, $background_color, $opacity) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
489
	if ($svg = svg_charger($img)
490
	  and $svg_infos = svg_lire_balise_svg($svg)){
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 489 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
491
492
		if ($background_color and $background_color!=='transparent') {
493
			list($balise_svg, $attributs) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
494
495
			$background_color = svg_couleur_to_hexa($background_color);
496
			if (isset($attributs['viewBox'])) {
497
				$viewBox = explode(' ', $attributs['viewBox']);
498
				$rect = "<rect x=\"".$viewBox[0]."\" y=\"".$viewBox[1]."\" width=\"".$viewBox[2]."\" height=\"".$viewBox[3]."\" fill=\"$background_color\" opacity=\"$opacity\"/>";
499
			}
500
			else {
501
				$rect = "<rect width=\"100%\" height=\"100%\" fill=\"$background_color\"/>";
502
			}
503
			$svg = svg_insert_shapes($svg, $rect, false);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_insert_shapes() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
504
		}
505
		return $svg;
506
	}
507
	return $img;
508
}
509
510
511
/**
512
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
513
 * @param $img
514
 * @array $attributs
515
 * @return bool|string
516
 */
517
function svg_transformer($img, $attributs) {
518
	if ($svg = svg_charger($img)
519
	  and $svg_infos = svg_lire_balise_svg($svg)){
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 518 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
520
521
		if ($attributs) {
522
			list($balise_svg, ) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
523
			$g = "<g";
524
			foreach ($attributs as $k=>$v) {
525
				if (strlen($v)) {
526
					$g .= " $k=\"".attribut_html($v)."\"";
527
				}
528
			}
529
			if (strlen($g) > 2) {
530
				$g .= ">";
531
				$svg = svg_insert_shapes($svg, $g);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_insert_shapes() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
532
				$svg = svg_insert_shapes($svg, "</g>", false);
533
			}
534
		}
535
		return $svg;
536
	}
537
	return $img;
538
}
539
540
/**
541
 * Ajouter + appliquer un filtre a un svg
542
 * @param string $img
543
 * @param string $filter_def
544
 *   definition du filtre (contenu de <filter>...</filter>
545
 * @return bool|string
546
 */
547
function svg_apply_filter($img, $filter_def) {
548
	if ($svg = svg_charger($img)
549
	  and $svg_infos = svg_lire_balise_svg($svg)){
0 ignored issues
show
Bug introduced by
It seems like $svg defined by svg_charger($img) on line 548 can also be of type boolean; however, svg_lire_balise_svg() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
550
551
		if ($filter_def) {
552
			list($balise_svg, ) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
553
			$filter_id = "filter-". substr(md5($filter_def . strlen($svg)), 0, 8);
554
			$filter = "<defs><filter id=\"$filter_id\">$filter_def</filter></defs>";
555
			$g = "<g filter=\"url(#$filter_id)\">";
556
			$svg = svg_insert_shapes($svg, $filter . $g);
0 ignored issues
show
Bug introduced by
It seems like $svg can also be of type boolean; however, svg_insert_shapes() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
557
			$svg = svg_insert_shapes($svg, "</g>", false);
558
		}
559
		return $svg;
560
	}
561
	return $img;
562
}
563
564
/**
565
 * Filtre blur en utilisant <filter>
566
 * @param string $img
567
 * @param int $blur_width
568
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
569
 */
570
function svg_filter_blur($img, $blur_width) {
571
	$blur_width = intval($blur_width);
572
	return svg_apply_filter($img, "<feGaussianBlur stdDeviation=\"$blur_width\"/>");
573
}
574
575
/**
576
 * Filtre grayscale en utilisant <filter>
577
 * @param string $img
578
 * @param float $intensity
579
 * @return bool|string
580
 */
581
function svg_filter_grayscale($img, $intensity) {
582
	$value = round(1.0 - $intensity, 2);
583
	//$filter = "<feColorMatrix type=\"matrix\" values=\"0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\"/>";
584
	$filter = "<feColorMatrix type=\"saturate\" values=\"$value\"/>";
585
	return svg_apply_filter($img, $filter);
586
}
587
588
/**
589
 * Filtre sepia en utilisant <filter>
590
 * @param $img
591
 * @param $intensity
592
 * @return bool|string
593
 */
594
function svg_filter_sepia($img, $intensity) {
0 ignored issues
show
Unused Code introduced by
The parameter $intensity is not used and could be removed.

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

Loading history...
595
	$filter = "<feColorMatrix type=\"matrix\" values=\"0.30 0.30 0.30 0.0 0 0.25 0.25 0.25 0.0 0 0.20 0.20 0.20 0.0 0 0.00 0.00 0.00 1 0\"/>";
596
	return svg_apply_filter($img, $filter);
597
}
598
599
/**
600
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
601
 * @param $img
602
 * @array string $HorV
603
 * @return bool|string
604
 */
605
function svg_flip($img, $HorV) {
606
	if ($svg = svg_force_viewBox_px($img)
607
	  and $svg_infos = svg_lire_balise_svg($svg)){
608
609
		list($balise_svg, $atts) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
610
		$viewBox = explode(' ', $atts['viewBox']);
611
612
		if (!in_array($HorV, ['h', 'H'])) {
613
			$transform = "scale(-1,1)";
614
615
			$x = intval($viewBox[0]) + intval($viewBox[2]/2);
616
			$mx = -$x;
617
			$transform = "translate($x, 0) $transform translate($mx, 0)";
618
		}
619
		else {
620
			$transform = "scale(1,-1)";
621
622
			$y = intval($viewBox[1]) + intval($viewBox[3]/2);
623
			$my = -$y;
624
			$transform = "translate(0, $y) $transform translate(0, $my)";
625
		}
626
		$svg = svg_transformer($svg, ['transform' => $transform]);
627
		return $svg;
628
	}
629
	return $img;
630
}
631
632
/**
633
 * @param string $img
634
 * @param int/float $angle
0 ignored issues
show
Documentation introduced by
The doc-type int/float could not be parsed: Unknown type name "int/float" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
635
 *   angle en degres
636
 * @param $center_x
637
 *   centre X de la rotation entre 0 et 1, relatif a la pleine largeur (0=bord gauche, 1=bord droit)
638
 * @param $center_y
639
 *   centre Y de la rotation entre 0 et 1, relatif a la pleine hauteur (0=bord top, 1=bord bottom)
640
 * @return bool|string
641
 */
642
function svg_rotate($img, $angle, $center_x, $center_y) {
643
	if ($svg = svg_force_viewBox_px($img)
644
		and $svg_infos = svg_lire_balise_svg($svg)){
645
646
		list($balise_svg, $atts) = $svg_infos;
0 ignored issues
show
Unused Code introduced by
The assignment to $balise_svg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
647
		$viewBox = explode(' ', $atts['viewBox']);
648
649
		$center_x = round($viewBox[0] + $center_x * $viewBox[2]);
650
		$center_y = round($viewBox[1] + $center_y * $viewBox[3]);
651
		$svg = svg_transformer($svg, ['transform' => "rotate($angle $center_x $center_y)"]);
652
653
		return $svg;
654
	}
655
	return $img;
656
}
657
658
/**
659
 * Filtrer les couleurs d'un SVG avec une callback
660
 * (peut etre lent si beaucoup de couleurs)
661
 *
662
 * @param $img
663
 * @param $callback_filter
664
 * @return bool|mixed|string
665
 */
666
function svg_filtrer_couleurs($img, $callback_filter) {
667
	if ($svg = svg_force_viewBox_px($img)
668
	  and $colors = svg_extract_couleurs($svg)) {
669
670
		$colors = array_unique($colors);
671
672
		$short = [];
673
		$long = [];
674
		while (count($colors)) {
675
			$c = array_shift($colors);
676
			if (strlen($c) == 4) {
677
				$short[] = $c;
678
			}
679
			else {
680
				$long[] = $c;
681
			}
682
		}
683
684
		$colors = array_merge($long, $short);
685
		$new_colors = [];
686
		$colors = array_flip($colors);
687
		foreach ($colors as $c => $k) {
688
			$colors[$c] = "@@@COLOR$$k$@@@";
689
		}
690
691
692
		foreach ($colors as $original => $replace) {
693
			$new = svg_couleur_to_hexa($original);
694
			$new_colors[$replace] = $callback_filter($new);
695
		}
696
697
		$svg = str_replace(array_keys($colors), array_values($colors), $svg);
698
		$svg = str_replace(array_keys($new_colors), array_values($new_colors), $svg);
699
700
		return $svg;
701
	}
702
	return $img;
703
}