Completed
Push — master ( 230805...a75156 )
by cam
05:02
created

svg.php ➔ svg_filtrer_couleurs()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 13
nop 2
dl 0
loc 38
rs 8.3786
c 0
b 0
f 0
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
		var_dump('fail1');
0 ignored issues
show
Security Debugging Code introduced by
var_dump('fail1'); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
52
		// encodage inconnu ou autre format d'image ?
53
		return false;
54
	}
55
	// c'est peut etre deja une image svg ?
56
	if (strpos($fichier, "<svg") !== false) {
57
		return $fichier;
58
	}
59
	if (!file_exists($fichier)) {
60
		$fichier  = supprimer_timestamp($fichier);
61
		if (!file_exists($fichier)) {
62
			var_dump('fail2');
63
			return false;
64
		}
65
	}
66
	if (is_null($maxlen)) {
67
		$image = file_get_contents($fichier);
68
	}
69
	else {
70
		$image = file_get_contents($fichier, false,null,0, $maxlen);
71
	}
72
	// est-ce bien une image svg ?
73
	if (strpos($image, "<svg") !== false) {
74
		return $image;
75
	}
76
	return false;
77
}
78
79
/**
80
 * Lire la balise <svg...> qui demarre le fichier et la parser pour renvoyer un tableau de ses attributs
81
 * @param string $fichier
82
 * @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...
83
 */
84
function svg_lire_balise_svg($fichier) {
85
	if (!$debut_fichier = svg_charger($fichier, 4096)) {
86
		return false;
87
	}
88
89
	if (($ps = stripos($debut_fichier, "<svg")) !== false) {
90
91
		$pe = stripos($debut_fichier, ">", $ps);
92
		$balise_svg = substr($debut_fichier, $ps, $pe - $ps +1);
93
94
		if (preg_match_all(",([\w\-]+)=,Uims", $balise_svg, $matches)) {
95
			if (!function_exists('extraire_attribut')) {
96
				include_spip('inc/filtres');
97
			}
98
			$attributs = [];
99
			foreach ($matches[1] as $att) {
100
				$attributs[$att] = extraire_attribut($balise_svg, $att);
101
			}
102
103
			return [$balise_svg, $attributs];
104
		}
105
	}
106
107
	return false;
108
}
109
110
/**
111
 * Attributs de la balise SVG
112
 * @param string $img
113
 * @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...
114
 */
115
function svg_lire_attributs($img) {
116
117
	if ($svg_infos = svg_lire_balise_svg($img)) {
118
		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...
119
		return $attributs;
120
	}
121
122
	return false;
123
}
124
125
/**
126
 * Convertir l'attribut widht/height d'un SVG en pixels
127
 * (approximatif eventuellement, du moment qu'on respecte le ratio)
128
 * @param $dimension
129
 * @return bool|float|int
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|integer.

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...
130
 */
131
function svg_dimension_to_pixels($dimension) {
132
	if (preg_match(',^(-?\d+)([^\d]*),i', trim($dimension), $m)){
133
		switch (strtolower($m[2])) {
134
			case '%':
135
				// on ne sait pas faire :(
136
				return false;
137
				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...
138
			case 'em':
139
				return intval($m[1])*16; // 16px font-size par defaut
140
				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...
141
			case 'ex':
142
				return intval($m[1])*16; // 16px font-size par defaut
143
				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...
144
			case 'pc':
145
				return intval($m[1])*16; // 1/6 inch = 96px/6 in CSS
146
				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...
147
			case 'cm':
148
				return intval(round($m[1]*96/2.54)); // 96px / 2.54cm;
149
				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...
150
			case 'mm':
151
				return intval(round($m[1]*96/25.4)); // 96px / 25.4mm;
152
				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...
153
			case 'in':
154
				return intval($m[1])*96; // 1 inch = 96px in CSS
155
				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...
156
			case 'px':
157
			case 'pt':
158
			default:
159
				return intval($m[1]);
160
				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...
161
		}
162
	}
163
	return false;
164
}
165
166
/**
167
 * Modifier la balise SVG en entete du source
168
 * @param string $svg
169
 * @param string $old_balise_svg
170
 * @param array $attributs
171
 * @return string
172
 */
173
function svg_change_balise_svg($svg, $old_balise_svg, $attributs) {
174
	$new_balise_svg = "<svg";
175
	foreach ($attributs as $k=>$v) {
176
		$new_balise_svg .= " $k=\"".entites_html($v)."\"";
177
	}
178
	$new_balise_svg .= ">";
179
180
	$p = strpos($svg, $old_balise_svg);
181
	$svg = substr_replace($svg, $new_balise_svg, $p, strlen($old_balise_svg));
182
	return $svg;
183
}
184
185
/**
186
 * @param string $svg
187
 * @param string $shapes
188
 * @param bool|string $start
189
 *   inserer au debut (true) ou a la fin (false)
190
 * @return string
191
 */
192
function svg_insert_shapes($svg, $shapes, $start=true) {
193
194
	if ($start === false or $start === 'end') {
195
		$svg = str_replace("</svg>", $shapes . "</svg>", $svg);
196
	}
197
	else {
198
		$p = stripos($svg, "<svg");
199
		$p = strpos($svg, ">", $p);
200
		$svg = substr_replace($svg, $shapes, $p+1, 0);
201
	}
202
	return $svg;
203
}
204
205
/**
206
 * Clipper le SVG dans une box
207
 * @param string $svg
208
 * @param int $x
209
 * @param int $y
210
 * @param int $width
211
 * @param int $height
212
 * @return string
213
 */
214
function svg_clip_in_box($svg, $x, $y, $width, $height) {
215
	$rect = "<rect x=\"$x\" y=\"$y\" width=\"$width\" height=\"$height\" />";
216
	$id = 'clip-'.substr(md5($rect . strlen($svg)),0,8);
217
	$clippath = "<clipPath id=\"$id\">$rect</clipPath>";
218
	$g = "<g clip-path=\"url(#$id)\">";
219
	$svg = svg_insert_shapes($svg, $clippath . $g);
220
	$svg = svg_insert_shapes($svg, "</g>", false);
221
	return $svg;
222
}
223
224
/**
225
 * Redimensionner le SVG via le width/height de la balise
226
 * @param string $img
227
 * @param $new_width
228
 * @param $new_height
229
 * @return bool|string
230
 */
231
function svg_redimensionner($img, $new_width, $new_height) {
232
	if ($svg = svg_charger($img)
233
	  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 232 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...
234
235
		list($balise_svg, $attributs) = $svg_infos;
236 View Code Duplication
		if (!isset($attributs['viewBox'])) {
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...
237
			$attributs['viewBox'] = "0 0 " . $attributs['width'] . " " . $attributs['height'];
238
		}
239
		$attributs['width'] = strval($new_width);
240
		$attributs['height'] = strval($new_height);
241
242
		$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...
243
		return $svg;
244
	}
245
246
	return $img;
247
}
248
249
/**
250
 * Transformer une couleur extraite du SVG en hexa
251
 * @param string $couleur
252
 * @return string
253
 */
254
function svg_couleur_to_hexa($couleur) {
255
	if (strpos($couleur, "rgb(")===0) {
256
		$c = explode(',', substr($couleur, 4));
257
		$couleur = _couleur_dec_to_hex(intval($c[0]), intval($c[1]), intval($c[2]));
258
	}
259
	else {
260
		$couleur = couleur_html_to_hex($couleur);
261
	}
262
	$couleur = '#'.ltrim($couleur,'#');
263
	return $couleur;
264
}
265
266
/**
267
 * Transformer une couleur extraite du SVG en rgb
268
 * @param string $couleur
269
 * @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...
270
 */
271
function svg_couleur_to_rgb($couleur) {
272
	if (strpos($couleur, "rgb(")===0) {
273
		$c = explode(',', substr($couleur, 4));
274
		return ['red' => intval($c[0]),'green' => intval($c[1]),'blue' => intval($c[2])];
275
	}
276
	return _couleur_hex_to_dec($couleur);
277
}
278
279
280
/**
281
 * Forcer la viewBox du SVG, en px
282
 * cree l'attribut viewBox si il n'y en a pas
283
 * convertit les unites en px si besoin
284
 *
285
 * Les manipulations d'image par les filtres images se font en px, on a donc besoin d'une viewBox en px
286
 * Certains svg produits avec des unites exotiques subiront donc peut etre des deformations...
287
 *
288
 * @param string $img
289
 * @return string
290
 */
291
function svg_force_viewBox_px($img) {
292
	if ($svg = svg_charger($img)
293
	  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 292 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...
294
295
		list($balise_svg, $attributs) = $svg_infos;
296
297
		// il nous faut une viewBox
298 View Code Duplication
		if (!isset($attributs['viewBox'])) {
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...
299
			$viewBox = "0 0 " . $attributs['width'] . " " . $attributs['height'];
300
		}
301
		else {
302
			$viewBox = $attributs['viewBox'];
303
		}
304
		// et on la convertit en px
305
		$viewBox = explode(' ', $viewBox);
306
		$viewBox = array_map('svg_dimension_to_pixels', $viewBox);
307
		$viewBox = array_map('intval', $viewBox);
308
		if (!$viewBox[2]) {
309
			$viewBox[2] = '300';
310
		}
311
		if (!$viewBox[3]) {
312
			$viewBox[3] = '150';
313
		}
314
315
		$attributs['viewBox'] = implode(' ', $viewBox);
316
317
		$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...
318
		return $svg;
319
	}
320
	return $img;
321
}
322
323
/**
324
 * Extract all colors in SVG
325
 * @param $img
326
 * @return array|mixed
327
 */
328
function svg_extract_couleurs($img) {
329
	if ($svg = svg_charger($img)) {
330
		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)) {
331
			return $matches[0];
332
		}
333
	}
334
	return [];
335
}
336
337
/**
338
 * Redimensionner le SVG via le width/height de la balise
339
 * @param string $img
340
 * @param $new_width
341
 * @param $new_height
342
 * @return bool|string
343
 */
344
function svg_recadrer($img, $new_width, $new_height, $offset_width, $offset_height, $background_color='') {
345
	if ($svg = svg_force_viewBox_px($img)
346
	  and $svg_infos = svg_lire_balise_svg($svg)) {
347
348
		list($balise_svg, $attributs) = $svg_infos;
349
		$viewBox = explode(' ', $attributs['viewBox']);
350
351
		$viewport_w = $new_width;
352
		$viewport_h = $new_height;
353
		$viewport_ox = $offset_width;
354
		$viewport_oy = $offset_height;
355
356
		// si on a un width/height qui rescale, il faut rescaler
357
		if (isset ($attributs['width'])
358
		  and $w = svg_dimension_to_pixels($attributs['width'])
359
		  and isset ($attributs['height'])
360
		  and $h = svg_dimension_to_pixels($attributs['height'])) {
361
362
			$xscale = $viewBox[2] / $w;
363
			$viewport_w = intval(round($viewport_w * $xscale));
364
			$viewport_ox = intval(round($viewport_ox * $xscale));
365
			$yscale = $viewBox[3] / $h;
366
			$viewport_h = intval(round($viewport_h * $yscale));
367
			$viewport_oy = intval(round($viewport_oy * $yscale));
368
		}
369
370
		if ($viewport_w>$viewBox[2] or $viewport_h>$viewBox[3]) {
371
			$svg = svg_clip_in_box($svg, $viewBox[0], $viewBox[1], $viewBox[2], $viewBox[3]);
372
		}
373
374
		// maintenant on redefinit la viewBox
375
		$viewBox[0] += $viewport_ox;
376
		$viewBox[1] += $viewport_oy;
377
		$viewBox[2] = $viewport_w;
378
		$viewBox[3] = $viewport_h;
379
380
		$attributs['viewBox'] = implode(' ', $viewBox);
381
		$attributs['width'] = strval($new_width);
382
		$attributs['height'] = strval($new_height);
383
384
		$svg = svg_change_balise_svg($svg, $balise_svg, $attributs);
385
386
		// ajouter un background
387
		if ($background_color and $background_color!=='transparent') {
388
			$svg = svg_ajouter_background($svg, $background_color);
389
		}
390
391
		return $svg;
392
	}
393
394
	return $img;
395
}
396
397
/**
398
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
399
 * @param $img
400
 * @param $background_color
401
 * @return bool|string
402
 */
403 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...
404
	if ($svg = svg_charger($img)
405
	  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 404 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...
406
407
		if ($background_color and $background_color!=='transparent') {
408
			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...
409
410
			$background_color = svg_couleur_to_hexa($background_color);
411
			if (isset($attributs['viewBox'])) {
412
				$viewBox = explode(' ', $attributs['viewBox']);
413
				$rect = "<rect x=\"".$viewBox[0]."\" y=\"".$viewBox[1]."\" width=\"".$viewBox[2]."\" height=\"".$viewBox[3]."\" fill=\"$background_color\"/>";
414
			}
415
			else {
416
				$rect = "<rect width=\"100%\" height=\"100%\" fill=\"$background_color\"/>";
417
			}
418
			$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...
419
		}
420
		return $svg;
421
	}
422
	return $img;
423
}
424
425
426
/**
427
 * Ajouter un voile au SVG : un rect pleine taille avec la bonne couleur/opacite, en premier plan
428
 * @param $img
429
 * @param $background_color
430
 * @return bool|string
431
 */
432 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...
433
	if ($svg = svg_charger($img)
434
	  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 433 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...
435
436
		if ($background_color and $background_color!=='transparent') {
437
			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...
438
439
			$background_color = svg_couleur_to_hexa($background_color);
440
			if (isset($attributs['viewBox'])) {
441
				$viewBox = explode(' ', $attributs['viewBox']);
442
				$rect = "<rect x=\"".$viewBox[0]."\" y=\"".$viewBox[1]."\" width=\"".$viewBox[2]."\" height=\"".$viewBox[3]."\" fill=\"$background_color\" opacity=\"$opacity\"/>";
443
			}
444
			else {
445
				$rect = "<rect width=\"100%\" height=\"100%\" fill=\"$background_color\"/>";
446
			}
447
			$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...
448
		}
449
		return $svg;
450
	}
451
	return $img;
452
}
453
454
455
/**
456
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
457
 * @param $img
458
 * @array $attributs
459
 * @return bool|string
460
 */
461
function svg_transformer($img, $attributs) {
462
	if ($svg = svg_charger($img)
463
	  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 462 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...
464
465
		if ($attributs) {
466
			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...
467
			$g = "<g";
468
			foreach ($attributs as $k=>$v) {
469
				if (strlen($v)) {
470
					$g .= " $k=\"".attribut_html($v)."\"";
471
				}
472
			}
473
			if (strlen($g) > 2) {
474
				$g .= ">";
475
				$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...
476
				$svg = svg_insert_shapes($svg, "</g>", false);
477
			}
478
		}
479
		return $svg;
480
	}
481
	return $img;
482
}
483
484
485
/**
486
 * Ajouter un background au SVG : un rect pleine taille avec la bonne couleur
487
 * @param $img
488
 * @array string $HorV
489
 * @return bool|string
490
 */
491
function svg_flip($img, $HorV) {
492
	if ($svg = svg_force_viewBox_px($img)
493
	  and $svg_infos = svg_lire_balise_svg($svg)){
494
495
		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...
496
		$viewBox = explode(' ', $atts['viewBox']);
497
498
		if (!in_array($HorV, ['h', 'H'])) {
499
			$transform = "scale(-1,1)";
500
501
			$x = intval($viewBox[0]) + intval($viewBox[2]/2);
502
			$mx = -$x;
503
			$transform = "translate($x, 0) $transform translate($mx, 0)";
504
		}
505
		else {
506
			$transform = "scale(1,-1)";
507
508
			$y = intval($viewBox[1]) + intval($viewBox[3]/2);
509
			$my = -$y;
510
			$transform = "translate(0, $y) $transform translate(0, $my)";
511
		}
512
		$svg = svg_transformer($svg, ['transform' => $transform]);
513
		return $svg;
514
	}
515
	return $img;
516
}
517
518
/**
519
 * @param string $img
520
 * @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...
521
 *   angle en degres
522
 * @param $center_x
523
 *   centre X de la rotation entre 0 et 1, relatif a la pleine largeur (0=bord gauche, 1=bord droit)
524
 * @param $center_y
525
 *   centre Y de la rotation entre 0 et 1, relatif a la pleine hauteur (0=bord top, 1=bord bottom)
526
 * @return bool|string
527
 */
528
function svg_rotate($img, $angle, $center_x, $center_y) {
529
	if ($svg = svg_force_viewBox_px($img)
530
		and $svg_infos = svg_lire_balise_svg($svg)){
531
532
		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...
533
		$viewBox = explode(' ', $atts['viewBox']);
534
535
		$center_x = round($viewBox[0] + $center_x * $viewBox[2]);
536
		$center_y = round($viewBox[1] + $center_y * $viewBox[3]);
537
		$svg = svg_transformer($svg, ['transform' => "rotate($angle $center_x $center_y)"]);
538
539
		return $svg;
540
	}
541
	return $img;
542
}
543
544
/**
545
 * Filtrer les couleurs d'un SVG avec une callback
546
 * (peut etre lent si beaucoup de couleurs)
547
 *
548
 * @param $img
549
 * @param $callback_filter
550
 * @return bool|mixed|string
551
 */
552
function svg_filtrer_couleurs($img, $callback_filter) {
553
	if ($svg = svg_force_viewBox_px($img)
554
	  and $colors = svg_extract_couleurs($svg)) {
555
556
		$colors = array_unique($colors);
557
558
		$short = [];
559
		$long = [];
560
		while (count($colors)) {
561
			$c = array_shift($colors);
562
			if (strlen($c) == 4) {
563
				$short[] = $c;
564
			}
565
			else {
566
				$long[] = $c;
567
			}
568
		}
569
570
		$colors = array_merge($long, $short);
571
		$new_colors = [];
572
		$colors = array_flip($colors);
573
		foreach ($colors as $c => $k) {
574
			$colors[$c] = "@@@COLOR$$k$@@@";
575
		}
576
577
578
		foreach ($colors as $original => $replace) {
579
			$new = svg_couleur_to_hexa($original);
580
			$new_colors[$replace] = $callback_filter($new);
581
		}
582
583
		$svg = str_replace(array_keys($colors), array_values($colors), $svg);
584
		$svg = str_replace(array_keys($new_colors), array_values($new_colors), $svg);
585
586
		return $svg;
587
	}
588
	return $img;
589
}