HTML2PDF_parsingCss::resetStyle()   F
last analyzed

Complexity

Conditions 12
Paths 2048

Size

Total Lines 128
Code Lines 92

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 92
nc 2048
nop 1
dl 0
loc 128
rs 2
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 if ( !defined( 'ABSPATH' ) ) exit;
2
/**
3
 * HTML2PDF Librairy - parsingCss class
4
 *
5
 * HTML => PDF convertor
6
 * distributed under the LGPL License
7
 *
8
 * @author      Laurent MINGUET <[email protected]>
9
 * @version     4.03
10
 */
11
12
class HTML2PDF_parsingCss
13
{
14
    /**
15
     * reference to the pdf object
16
     * @var TCPDF
17
     */
18
    protected $_pdf         = null;
19
20
    protected $_htmlColor   = array(); // list of the HTML colors
21
    protected $_onlyLeft    = false;   // flag if we are in a sub html => only "text-align:left" is used
22
    protected $_defaultFont = null;    // default font to use if the asked font does not exist
23
24
    public    $value        = array(); // current values
25
    public    $css          = array(); // css values
26
    public    $cssKeys      = array(); // css key, for the execution order
27
    public    $table        = array(); // level history
28
29
    /**
30
     * Constructor
31
     *
32
     * @param  &HTML2PDF_myPdf reference to the PDF $object
33
     * @access public
34
     */
35
    public function __construct(&$pdf)
36
    {
37
        $this->_init();
38
        $this->setPdfParent($pdf);
39
    }
40
41
    /**
42
     * Set the HTML2PDF parent object
43
     *
44
     * @param  &HTML2PDF reference to the HTML2PDF parent $object
45
     * @access public
46
     */
47
    public function setPdfParent(&$pdf)
48
    {
49
        $this->_pdf = &$pdf;
50
    }
51
52
    /**
53
     * Inform that we want only "test-align:left" because we are in a sub HTML
54
     *
55
     * @access public
56
     */
57
    public function setOnlyLeft()
58
    {
59
        $this->value['text-align'] = 'left';
60
        $this->_onlyLeft = true;
61
    }
62
63
    /**
64
     * Get the vales of the parent, if exist
65
     *
66
     * @return array CSS values
67
     * @access public
68
     */
69
    public function getOldValues()
70
    {
71
        return isset($this->table[count($this->table)-1]) ? $this->table[count($this->table)-1] : $this->value;
72
    }
73
74
    /**
75
    * define the Default Font to use, if the font does not exist, or if no font asked
76
    *
77
    * @param  string  default font-family. If null : Arial for no font asked, and error fot ont does not exist
78
    * @return string  old default font-family
79
    * @access public
80
    */
81
    public function setDefaultFont($default = null)
82
    {
83
        $old = $this->_defaultFont;
84
        $this->_defaultFont = $default;
85
        if ($default) $this->value['font-family'] = $default;
86
        return $old;
87
    }
88
89
     /**
90
     * Init the object
91
     *
92
     * @access protected
93
     */
94
    protected function _init()
95
    {
96
        // get the Web Colors from TCPDF
97
        require(K_PATH_MAIN.'htmlcolors.php');
98
        $this->_htmlColor = $webcolor;
0 ignored issues
show
Bug introduced by
The variable $webcolor does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
99
100
        // init the Style
101
        $this->table = array();
102
        $this->value = array();
103
        $this->initStyle();
104
105
        // Init the styles without legacy
106
        $this->resetStyle();
107
    }
108
109
    /**
110
     * Init the CSS Style
111
     *
112
     * @access public
113
     */
114
    public function initStyle()
115
    {
116
        $this->value['id_tag']       = 'body';        // tag name
117
        $this->value['id_name']          = null;         // tag - attribute name
118
        $this->value['id_id']            = null;         // tag - attribute id
119
        $this->value['id_class']         = null;         // tag - attribute class
120
        $this->value['id_lst']           = array('*');   // tag - list of legacy
121
        $this->value['mini-size']        = 1.;           // specific size report for sup, sub
122
        $this->value['mini-decal']       = 0;            // specific position report for sup, sub
123
        $this->value['font-family']      = 'Arial';
124
        $this->value['font-bold']        = false;
125
        $this->value['font-italic']      = false;
126
        $this->value['font-underline']   = false;
127
        $this->value['font-overline']    = false;
128
        $this->value['font-linethrough'] = false;
129
        $this->value['text-transform']   = 'none';
130
        $this->value['font-size']        = $this->convertToMM('10pt');
131
        $this->value['text-indent']      = 0;
132
        $this->value['text-align']       = 'left';
133
        $this->value['vertical-align']   = 'middle';
134
        $this->value['line-height']      = 'normal';
135
136
        $this->value['position']         = null;
137
        $this->value['x']                = null;
138
        $this->value['y']                = null;
139
        $this->value['width']            = 0;
140
        $this->value['height']           = 0;
141
        $this->value['top']              = null;
142
        $this->value['right']            = null;
143
        $this->value['bottom']           = null;
144
        $this->value['left']             = null;
145
        $this->value['float']            = null;
146
        $this->value['display']          = null;
147
        $this->value['rotate']           = null;
148
        $this->value['overflow']         = 'visible';
149
150
        $this->value['color']            = array(0, 0, 0);
151
        $this->value['background']       = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
152
        $this->value['border']           = array();
153
        $this->value['padding']          = array();
154
        $this->value['margin']           = array();
155
        $this->value['margin-auto']      = false;
156
157
        $this->value['list-style-type']  = '';
158
        $this->value['list-style-image'] = '';
159
160
        $this->value['xc'] = null;
161
        $this->value['yc'] = null;
162
    }
163
164
    /**
165
     * Init the CSS Style without legacy
166
     *
167
     * @param  string  tag name
168
     * @access public
169
     */
170
    public function resetStyle($tagName = '')
171
    {
172
        // prepare somme values
173
        $border = $this->readBorder('solid 1px #000000');
174
        $units = array(
175
            '1px' => $this->convertToMM('1px'),
176
            '5px' => $this->convertToMM('5px'),
177
        );
178
179
180
        // prepare the Collapse attribute
181
        $collapse = isset($this->value['border']['collapse']) ? $this->value['border']['collapse'] : false;
182
        if (!in_array($tagName, array('tr', 'td', 'th', 'thead', 'tbody', 'tfoot'))) $collapse = false;
183
184
        // set the global css values
185
        $this->value['position']   = null;
186
        $this->value['x']          = null;
187
        $this->value['y']          = null;
188
        $this->value['width']      = 0;
189
        $this->value['height']     = 0;
190
        $this->value['top']        = null;
191
        $this->value['right']      = null;
192
        $this->value['bottom']     = null;
193
        $this->value['left']       = null;
194
        $this->value['float']      = null;
195
        $this->value['display']    = null;
196
        $this->value['rotate']     = null;
197
        $this->value['overflow']   = 'visible';
198
        $this->value['background'] = array('color' => null, 'image' => null, 'position' => null, 'repeat' => null);
199
        $this->value['border']     = array(
200
            't' => $this->readBorder('none'),
201
            'r' => $this->readBorder('none'),
202
            'b' => $this->readBorder('none'),
203
            'l' => $this->readBorder('none'),
204
            'radius' => array(
205
                'tl' => array(0, 0),
206
                'tr' => array(0, 0),
207
                'br' => array(0, 0),
208
                'bl' => array(0, 0)
209
            ),
210
            'collapse' => $collapse,
211
        );
212
213
        // specific values for some tags
214
        if (!in_array($tagName, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) {
215
            $this->value['margin'] = array('t'=>0,'r'=>0,'b'=>0,'l'=>0);
216
        }
217
218
        if (in_array($tagName, array('input', 'select', 'textarea'))) {
219
            $this->value['border']['t'] = null;
220
            $this->value['border']['r'] = null;
221
            $this->value['border']['b'] = null;
222
            $this->value['border']['l'] = null;
223
        }
224
225
        if ($tagName=='p') {
226
            $this->value['margin']['t'] = null;
227
            $this->value['margin']['b'] = null;
228
        }
229
        if ($tagName=='blockquote') {
230
            $this->value['margin']['t'] = 3;
231
            $this->value['margin']['r'] = 3;
232
            $this->value['margin']['b'] = 3;
233
            $this->value['margin']['l'] = 6;
234
        }
235
        $this->value['margin-auto'] = false;
236
237
        if (in_array($tagName, array('blockquote', 'div', 'fieldset'))) {
238
            $this->value['vertical-align'] = 'top';
239
        }
240
241
        if (in_array($tagName, array('fieldset', 'legend'))) {
242
            $this->value['border'] = array(
243
                't' => $border,
244
                'r' => $border,
245
                'b' => $border,
246
                'l' => $border,
247
                'radius' => array(
248
                    'tl' => array($units['5px'], $units['5px']),
249
                    'tr' => array($units['5px'], $units['5px']),
250
                    'br' => array($units['5px'], $units['5px']),
251
                    'bl' => array($units['5px'], $units['5px'])
252
                ),
253
                'collapse' => false,
254
            );
255
        }
256
257
        if (in_array($tagName, array('ul', 'li'))) {
258
            $this->value['list-style-type']  = '';
259
            $this->value['list-style-image'] = '';
260
        }
261
262
        if (!in_array($tagName, array('tr', 'td'))) {
263
            $this->value['padding'] = array(
264
                't' => 0,
265
                'r' => 0,
266
                'b' => 0,
267
                'l' => 0
268
            );
269
        } else {
270
            $this->value['padding'] = array(
271
                't' => $units['1px'],
272
                'r' => $units['1px'],
273
                'b' => $units['1px'],
274
                'l' => $units['1px']
275
            );
276
        }
277
278
        if ($tagName=='hr') {
279
            $this->value['border'] = array(
280
                't' => $border,
281
                'r' => $border,
282
                'b' => $border,
283
                'l' => $border,
284
                'radius' => array(
285
                    'tl' => array(0, 0),
286
                    'tr' => array(0, 0),
287
                    'br' => array(0, 0),
288
                    'bl' => array(0, 0)
289
                ),
290
                'collapse' => false,
291
            );
292
            $this->convertBackground('#FFFFFF', $this->value['background']);
293
        }
294
295
        $this->value['xc'] = null;
296
        $this->value['yc'] = null;
297
    }
298
299
    /**
300
     * Init the PDF Font
301
     *
302
     * @access public
303
     */
304
    public function fontSet()
305
    {
306
        $family = strtolower($this->value['font-family']);
307
308
        $b = ($this->value['font-bold']        ? 'B' : '');
309
        $i = ($this->value['font-italic']      ? 'I' : '');
310
        $u = ($this->value['font-underline']   ? 'U' : '');
311
        $d = ($this->value['font-linethrough'] ? 'D' : '');
312
        $o = ($this->value['font-overline']    ? 'O' : '');
313
314
        // font style
315
        $style = $b.$i;
316
317
        if ($this->_defaultFont) {
318 View Code Duplication
            if($family=='arial')
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...
319
                $family='helvetica';
320
            elseif($family=='symbol' || $family=='zapfdingbats')
321
                $style='';
322
323
            $fontkey = $family.$style;
324
            if (!$this->_pdf->isLoadedFont($fontkey))
325
                $family = $this->_defaultFont;
326
        }
327
328 View Code Duplication
        if($family=='arial')
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...
329
            $family='helvetica';
330
        elseif($family=='symbol' || $family=='zapfdingbats')
331
            $style='';
332
333
        // complete style
334
        $style.= $u.$d.$o;
335
336
        // size : mm => pt
337
        $size = $this->value['font-size'];
338
        $size = 72 * $size / 25.4;
339
340
        // apply the font
341
        $this->_pdf->SetFont($family, $style, $this->value['mini-size']*$size);
342
        $this->_pdf->setTextColorArray($this->value['color']);
343
        if ($this->value['background']['color'])
344
            $this->_pdf->setFillColorArray($this->value['background']['color']);
345
        else
346
            $this->_pdf->setFillColor(255);
347
    }
348
349
     /**
350
     * add a level in the CSS history
351
     *
352
     * @access public
353
     */
354
    public function save()
355
    {
356
        array_push($this->table, $this->value);
357
    }
358
359
     /**
360
     * remove a level in the CSS history
361
     *
362
     * @access public
363
     */
364
    public function load()
365
    {
366
        if (count($this->table)) {
367
            $this->value = array_pop($this->table);
368
        }
369
    }
370
371
     /**
372
     * restore the Y positiony (used after a span)
373
     *
374
     * @access public
375
     */
376
    public function restorePosition()
377
    {
378
        if ($this->value['y']==$this->_pdf->getY()) $this->_pdf->setY($this->value['yc'], false);
379
    }
380
381
     /**
382
     * set the New position for the current Tag
383
     *
384
     * @access public
385
     */
386
    public function setPosition()
387
    {
388
        // get the current position
389
        $currentX = $this->_pdf->getX();
390
        $currentY = $this->_pdf->getY();
391
392
        // save it
393
        $this->value['xc'] = $currentX;
394
        $this->value['yc'] = $currentY;
395
396
        if ($this->value['position']=='relative' || $this->value['position']=='absolute') {
397
            if ($this->value['right']!==null) {
398
                $x = $this->getLastWidth(true) - $this->value['right'] - $this->value['width'];
399
                if ($this->value['margin']['r']) $x-= $this->value['margin']['r'];
400 View Code Duplication
            } else {
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...
401
                $x = $this->value['left'];
402
                if ($this->value['margin']['l']) $x+= $this->value['margin']['l'];
403
            }
404
405
            if ($this->value['bottom']!==null) {
406
                $y = $this->getLastHeight(true) - $this->value['bottom'] - $this->value['height'];
407
                if ($this->value['margin']['b']) $y-= $this->value['margin']['b'];
408 View Code Duplication
            } else {
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...
409
                $y = $this->value['top'];
410
                if ($this->value['margin']['t']) $y+= $this->value['margin']['t'];
411
            }
412
413
            if ($this->value['position']=='relative') {
414
                $this->value['x'] = $currentX + $x;
415
                $this->value['y'] = $currentY + $y;
416
            } else {
417
                $this->value['x'] = $this->_getLastAbsoluteX()+$x;
418
                $this->value['y'] = $this->_getLastAbsoluteY()+$y;
419
            }
420
        } else {
421
            $this->value['x'] = $currentX;
422
            $this->value['y'] = $currentY;
423 View Code Duplication
            if ($this->value['margin']['l']) $this->value['x']+= $this->value['margin']['l'];
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...
424 View Code Duplication
            if ($this->value['margin']['t']) $this->value['y']+= $this->value['margin']['t'];
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...
425
        }
426
427
        // save the new position
428
        $this->_pdf->setXY($this->value['x'], $this->value['y']);
429
    }
430
431
     /**
432
     * Analise the CSS style to convert it into Form style
433
     *
434
     * @access public
435
     * @param  array    styles
436
     */
437
    public function getFormStyle()
438
    {
439
        $prop = array();
440
441
        $prop['alignment'] = $this->value['text-align'];
442
443
        if (isset($this->value['background']['color']) && is_array($this->value['background']['color'])) {
444
            $prop['fillColor'] = $this->value['background']['color'];
445
        }
446
447
        if (isset($this->value['border']['t']['color'])) {
448
            $prop['strokeColor'] = $this->value['border']['t']['color'];
449
        }
450
451
        if (isset($this->value['border']['t']['width'])) {
452
            $prop['lineWidth'] = $this->value['border']['t']['width'];
453
        }
454
455
        if (isset($this->value['border']['t']['type'])) {
456
            $prop['borderStyle'] = $this->value['border']['t']['type'];
457
        }
458
459
        if (!empty($this->value['color'])) {
460
            $prop['textColor'] = $this->value['color'];
461
        }
462
463
        if (!empty($this->value['font-size'])) {
464
            $prop['textSize'] = $this->value['font-size'];
465
        }
466
467
        return $prop;
468
    }
469
470
     /**
471
     * Analise the CSS style to convert it into SVG style
472
     *
473
     * @access public
474
     * @param  string   tag name
475
     * @param  array    styles
476
     */
477
    public function getSvgStyle($tagName, &$param)
478
    {
479
        // prepare
480
        $tagName = strtolower($tagName);
481
        $id   = isset($param['id'])   ? strtolower(trim($param['id']))   : null; if (!$id)   $id   = null;
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
482
        $name = isset($param['name']) ? strtolower(trim($param['name'])) : null; if (!$name) $name = null;
0 ignored issues
show
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
483
484
        // read the class attribute
485
        $class = array();
486
        $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
487
        $tmp = explode(' ', $tmp);
488
        foreach ($tmp as $k => $v) {
489
            $v = trim($v);
490
            if ($v) $class[] = $v;
491
        }
492
493
        // identify the tag, and the direct styles
494
        $this->value['id_tag'] = $tagName;
495
        $this->value['id_name']   = $name;
496
        $this->value['id_id']     = $id;
497
        $this->value['id_class']  = $class;
498
        $this->value['id_lst']    = array();
499
        $this->value['id_lst'][] = '*';
500
        $this->value['id_lst'][] = $tagName;
501
        if (!isset($this->value['svg'])) {
502
            $this->value['svg'] = array(
503
                'stroke'         => null,
504
                'stroke-width'   => $this->convertToMM('1pt'),
505
                'fill'           => null,
506
                'fill-opacity'   => null,
507
            );
508
        }
509
510 View Code Duplication
        if (count($class)) {
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...
511
            foreach ($class as $v) {
512
                $this->value['id_lst'][] = '*.'.$v;
513
                $this->value['id_lst'][] = '.'.$v;
514
                $this->value['id_lst'][] = $tagName.'.'.$v;
515
            }
516
        }
517 View Code Duplication
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
518
            $this->value['id_lst'][] = '*#'.$id;
519
            $this->value['id_lst'][] = '#'.$id;
520
            $this->value['id_lst'][] = $tagName.'#'.$id;
521
        }
522
523
        // CSS style
524
        $styles = $this->_getFromCSS();
525
526
        // adding the style from the tag
527
        $styles = array_merge($styles, $param['style']);
528
529 View Code Duplication
        if (isset($styles['stroke']))        $this->value['svg']['stroke']       = $this->convertToColor($styles['stroke'], $res);
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...
530
        if (isset($styles['stroke-width']))  $this->value['svg']['stroke-width'] = $this->convertToMM($styles['stroke-width']);
531 View Code Duplication
        if (isset($styles['fill']))          $this->value['svg']['fill']         = $this->convertToColor($styles['fill'], $res);
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...
532
        if (isset($styles['fill-opacity']))  $this->value['svg']['fill-opacity'] = 1.*$styles['fill-opacity'];
533
534
        return $this->value['svg'];
535
    }
536
537
    /**
538
     * analyse the css properties from the HTML parsing
539
     *
540
     * @access public
541
     * @param  string  $tagName
542
     * @param  array   $param
543
     * @param  array   $legacy
544
     */
545
    public function analyse($tagName, &$param, $legacy = null)
546
    {
547
        // prepare the informations
548
        $tagName = strtolower($tagName);
549
        $id   = isset($param['id'])   ? strtolower(trim($param['id']))    : null; if (!$id)   $id   = null;
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
550
        $name = isset($param['name']) ? strtolower(trim($param['name']))  : null; if (!$name) $name = null;
0 ignored issues
show
Bug Best Practice introduced by
The expression $name of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
551
552
        // get the class names to use
553
        $class = array();
554
        $tmp = isset($param['class']) ? strtolower(trim($param['class'])) : '';
555
        $tmp = explode(' ', $tmp);
556
        foreach ($tmp as $k => $v) {
557
            $v = trim($v);
558
            if ($v) $class[] = $v;
559
        }
560
561
        // prepare the values, and the list of css tags to identify
562
        $this->value['id_tag']   = $tagName;
563
        $this->value['id_name']  = $name;
564
        $this->value['id_id']    = $id;
565
        $this->value['id_class'] = $class;
566
        $this->value['id_lst']   = array();
567
        $this->value['id_lst'][] = '*';
568
        $this->value['id_lst'][] = $tagName;
569 View Code Duplication
        if (count($class)) {
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...
570
            foreach ($class as $v) {
571
                $this->value['id_lst'][] = '*.'.$v;
572
                $this->value['id_lst'][] = '.'.$v;
573
                $this->value['id_lst'][] = $tagName.'.'.$v;
574
            }
575
        }
576 View Code Duplication
        if ($id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
577
            $this->value['id_lst'][] = '*#'.$id;
578
            $this->value['id_lst'][] = '#'.$id;
579
            $this->value['id_lst'][] = $tagName.'#'.$id;
580
        }
581
582
        // get the css styles from class
583
        $styles = $this->_getFromCSS();
584
585
        // merge with the css styles from tag
586
        $styles = array_merge($styles, $param['style']);
587
        if (isset($param['allwidth']) && !isset($styles['width'])) $styles['width'] = '100%';
588
589
        // reset some styles, depending on the tag name
590
        $this->resetStyle($tagName);
591
592
        // add the legacy values
593
        if ($legacy) {
594
            foreach ($legacy as $legacyName => $legacyValue) {
595
                if (is_array($legacyValue)) {
596
                    foreach($legacyValue as $legacy2Name => $legacy2Value)
597
                        $this->value[$legacyName][$legacy2Name] = $legacy2Value;
598
                } else {
599
                    $this->value[$legacyName] = $legacyValue;
600
                }
601
            }
602
        }
603
604
        // some flags
605
        $correctWidth = false;
606
        $noWidth = true;
607
608
        // read all the css styles
609
        foreach ($styles as $nom => $val) {
610
            switch($nom)
611
            {
612
                case 'font-family':
613
                    $val = explode(',', $val);
614
                    $val = trim($val[0]);
615
                    if ($val) $this->value['font-family'] = $val;
616
                    break;
617
618
                case 'font-weight':
619
                    $this->value['font-bold'] = ($val=='bold');
620
                    break;
621
622
                case 'font-style':
623
                    $this->value['font-italic'] = ($val=='italic');
624
                    break;
625
626
                case 'text-decoration':
627
                    $val = explode(' ', $val);
628
                    $this->value['font-underline']   = (in_array('underline', $val));
629
                    $this->value['font-overline']    = (in_array('overline', $val));
630
                    $this->value['font-linethrough'] = (in_array('line-through', $val));
631
                    break;
632
633
                case 'text-indent':
634
                    $this->value['text-indent'] = $this->convertToMM($val);
635
                    break;
636
637
                case 'text-transform':
638
                    if (!in_array($val, array('none', 'capitalize', 'uppercase', 'lowercase'))) $val = 'none';
639
                    $this->value['text-transform']  = $val;
640
                    break;
641
642
                case 'font-size':
643
                    $val = $this->convertToMM($val, $this->value['font-size']);
644
                    if ($val) $this->value['font-size'] = $val;
645
                    break;
646
647
                case 'color':
648
                    $res = null;
649
                    $this->value['color'] = $this->convertToColor($val, $res);
650
                    if ($tagName=='hr') {
651
                        $this->value['border']['l']['color'] = $this->value['color'];
652
                        $this->value['border']['t']['color'] = $this->value['color'];
653
                        $this->value['border']['r']['color'] = $this->value['color'];
654
                        $this->value['border']['b']['color'] = $this->value['color'];
655
                    }
656
                    break;
657
658
                case 'text-align':
659
                    $val = strtolower($val);
660
                    if (!in_array($val, array('left', 'right', 'center', 'justify', 'li_right'))) $val = 'left';
661
                    $this->value['text-align'] = $val;
662
                    break;
663
664
                case 'vertical-align':
665
                    $this->value['vertical-align'] = $val;
666
                    break;
667
668
                case 'width':
669
                    $this->value['width'] = $this->convertToMM($val, $this->getLastWidth());
670
                    if ($this->value['width'] && substr($val, -1)=='%') $correctWidth=true;
671
                    $noWidth = false;
672
                    break;
673
674
                case 'height':
675
                    $this->value['height'] = $this->convertToMM($val, $this->getLastHeight());
676
                    break;
677
678
                case 'line-height':
679
                    if (preg_match('/^[0-9\.]+$/isU', $val)) $val = floor($val*100).'%';
680
                    $this->value['line-height'] = $val;
681
                    break;
682
683
                case 'rotate':
684
                    if (!in_array($val, array(0, -90, 90, 180, 270, -180, -270))) $val = null;
685
                    if ($val<0) $val+= 360;
686
                    $this->value['rotate'] = $val;
687
                    break;
688
689
                case 'overflow':
690
                    if (!in_array($val, array('visible', 'hidden'))) $val = 'visible';
691
                    $this->value['overflow'] = $val;
692
                    break;
693
694
                case 'padding':
695
                    $val = explode(' ', $val);
696
                    foreach ($val as $k => $v) {
697
                        $v = trim($v);
698
                        if ($v!='') {
699
                            $val[$k] = $v;
700
                        } else {
701
                            unset($val[$k]);
702
                        }
703
                    }
704
                    $val = array_values($val);
705
                    $this->_duplicateBorder($val);
706
                    $this->value['padding']['t'] = $this->convertToMM($val[0], 0);
707
                    $this->value['padding']['r'] = $this->convertToMM($val[1], 0);
708
                    $this->value['padding']['b'] = $this->convertToMM($val[2], 0);
709
                    $this->value['padding']['l'] = $this->convertToMM($val[3], 0);
710
                    break;
711
712
                case 'padding-top':
713
                    $this->value['padding']['t'] = $this->convertToMM($val, 0);
714
                    break;
715
716
                case 'padding-right':
717
                    $this->value['padding']['r'] = $this->convertToMM($val, 0);
718
                    break;
719
720
                case 'padding-bottom':
721
                    $this->value['padding']['b'] = $this->convertToMM($val, 0);
722
                    break;
723
724
                case 'padding-left':
725
                    $this->value['padding']['l'] = $this->convertToMM($val, 0);
726
                    break;
727
728
                case 'margin':
729
                    if ($val=='auto') {
730
                        $this->value['margin-auto'] = true;
731
                        break;
732
                    }
733
                    $val = explode(' ', $val);
734
                    foreach ($val as $k => $v) {
735
                        $v = trim($v);
736
                        if ($v!='') {
737
                            $val[$k] = $v;
738
                        } else {
739
                            unset($val[$k]);
740
                        }
741
                    }
742
                    $val = array_values($val);
743
                    $this->_duplicateBorder($val);
744
                    $this->value['margin']['t'] = $this->convertToMM($val[0], 0);
745
                    $this->value['margin']['r'] = $this->convertToMM($val[1], 0);
746
                    $this->value['margin']['b'] = $this->convertToMM($val[2], 0);
747
                    $this->value['margin']['l'] = $this->convertToMM($val[3], 0);
748
                    break;
749
750
                case 'margin-top':
751
                    $this->value['margin']['t'] = $this->convertToMM($val, 0);
752
                    break;
753
754
                case 'margin-right':
755
                    $this->value['margin']['r'] = $this->convertToMM($val, 0);
756
                    break;
757
758
                case 'margin-bottom':
759
                    $this->value['margin']['b'] = $this->convertToMM($val, 0);
760
                    break;
761
762
                case 'margin-left':
763
                    $this->value['margin']['l'] = $this->convertToMM($val, 0);
764
                    break;
765
766
                case 'border':
767
                    $val = $this->readBorder($val);
768
                    $this->value['border']['t'] = $val;
769
                    $this->value['border']['r'] = $val;
770
                    $this->value['border']['b'] = $val;
771
                    $this->value['border']['l'] = $val;
772
                    break;
773
774
                case 'border-style':
775
                    $val = explode(' ', $val);
776
                    foreach ($val as $valK => $valV) {
777
                        if (!in_array($valV, array('solid', 'dotted', 'dashed'))) {
778
                            $val[$valK] = null;
779
                        }
780
                    }
781
                    $this->_duplicateBorder($val);
782 View Code Duplication
                    if ($val[0]) $this->value['border']['t']['type'] = $val[0];
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...
783 View Code Duplication
                    if ($val[1]) $this->value['border']['r']['type'] = $val[1];
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...
784 View Code Duplication
                    if ($val[2]) $this->value['border']['b']['type'] = $val[2];
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...
785 View Code Duplication
                    if ($val[3]) $this->value['border']['l']['type'] = $val[3];
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...
786
                    break;
787
788 View Code Duplication
                case 'border-top-style':
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...
789
                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
790
                        $this->value['border']['t']['type'] = $val;
791
                    }
792
                    break;
793
794 View Code Duplication
                case 'border-right-style':
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...
795
                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
796
                        $this->value['border']['r']['type'] = $val;
797
                    }
798
                    break;
799
800 View Code Duplication
                case 'border-bottom-style':
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...
801
                    if (in_array($val, array('solid', 'dotted', 'dashed'))) {
802
                        $this->value['border']['b']['type'] = $val;
803
                    }
804
                    break;
805
806 View Code Duplication
                case 'border-left-style':
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...
807
                    if (in_array($val, array('solid', 'dotted', 'dashed')))
808
                        $this->value['border']['l']['type'] = $val;
809
                    break;
810
811
                case 'border-color':
812
                    $res = false;
813
                    $val = preg_replace('/,[\s]+/', ',', $val);
814
                    $val = explode(' ', $val);
815
                    foreach ($val as $valK => $valV) {
816
                            $val[$valK] = $this->convertToColor($valV, $res);
817
                            if (!$res) {
818
                                $val[$valK] = null;
819
                            }
820
                    }
821
                    $this->_duplicateBorder($val);
822 View Code Duplication
                    if (is_array($val[0])) $this->value['border']['t']['color'] = $val[0];
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...
823 View Code Duplication
                    if (is_array($val[1])) $this->value['border']['r']['color'] = $val[1];
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...
824 View Code Duplication
                    if (is_array($val[2])) $this->value['border']['b']['color'] = $val[2];
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...
825 View Code Duplication
                    if (is_array($val[3])) $this->value['border']['l']['color'] = $val[3];
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...
826
827
                    break;
828
829 View Code Duplication
                case 'border-top-color':
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...
830
                    $res = false;
831
                    $val = $this->convertToColor($val, $res);
832
                    if ($res) $this->value['border']['t']['color'] = $val;
833
                    break;
834
835 View Code Duplication
                case 'border-right-color':
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...
836
                    $res = false;
837
                    $val = $this->convertToColor($val, $res);
838
                    if ($res) $this->value['border']['r']['color'] = $val;
839
                    break;
840
841 View Code Duplication
                case 'border-bottom-color':
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...
842
                    $res = false;
843
                    $val = $this->convertToColor($val, $res);
844
                    if ($res) $this->value['border']['b']['color'] = $val;
845
                    break;
846
847 View Code Duplication
                case 'border-left-color':
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...
848
                    $res = false;
849
                    $val = $this->convertToColor($val, $res);
850
                    if ($res) $this->value['border']['l']['color'] = $val;
851
                    break;
852
853
                case 'border-width':
854
                    $val = explode(' ', $val);
855
                    foreach ($val as $valK => $valV) {
856
                            $val[$valK] = $this->convertToMM($valV, 0);
857
                    }
858
                    $this->_duplicateBorder($val);
859 View Code Duplication
                    if ($val[0]) $this->value['border']['t']['width'] = $val[0];
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...
860 View Code Duplication
                    if ($val[1]) $this->value['border']['r']['width'] = $val[1];
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...
861 View Code Duplication
                    if ($val[2]) $this->value['border']['b']['width'] = $val[2];
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...
862 View Code Duplication
                    if ($val[3]) $this->value['border']['l']['width'] = $val[3];
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...
863
                    break;
864
865 View Code Duplication
                case 'border-top-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...
866
                    $val = $this->convertToMM($val, 0);
867
                    if ($val) $this->value['border']['t']['width'] = $val;
868
                    break;
869
870 View Code Duplication
                case 'border-right-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...
871
                    $val = $this->convertToMM($val, 0);
872
                    if ($val) $this->value['border']['r']['width'] = $val;
873
                    break;
874
875 View Code Duplication
                case 'border-bottom-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...
876
                    $val = $this->convertToMM($val, 0);
877
                    if ($val) $this->value['border']['b']['width'] = $val;
878
                    break;
879
880 View Code Duplication
                case 'border-left-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...
881
                    $val = $this->convertToMM($val, 0);
882
                    if ($val) $this->value['border']['l']['width'] = $val;
883
                    break;
884
885
                case 'border-collapse':
886
                    if ($tagName=='table') $this->value['border']['collapse'] = ($val=='collapse');
887
                    break;
888
889
                case 'border-radius':
890
                    $val = explode('/', $val);
891
                    if (count($val)>2) {
892
                        break;
893
                    }
894
                    $valH = $this->convertToRadius(trim($val[0]));
895
                    if (count($valH)<1 || count($valH)>4) {
896
                        break;
897
                    }
898
                    if (!isset($valH[1])) $valH[1] = $valH[0];
899 View Code Duplication
                    if (!isset($valH[2])) $valH = array($valH[0], $valH[0], $valH[1], $valH[1]);
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...
900
                    if (!isset($valH[3])) $valH[3] = $valH[1];
901
                    if (isset($val[1])) {
902
                        $valV = $this->convertToRadius(trim($val[1]));
903
                        if (count($valV)<1 || count($valV)>4) {
904
                            break;
905
                        }
906
                        if (!isset($valV[1])) $valV[1] = $valV[0];
907 View Code Duplication
                        if (!isset($valV[2])) $valV = array($valV[0], $valV[0], $valV[1], $valV[1]);
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...
908
                        if (!isset($valV[3])) $valV[3] = $valV[1];
909
                    } else {
910
                        $valV = $valH;
911
                    }
912
                    $this->value['border']['radius'] = array(
913
                                'tl' => array($valH[0], $valV[0]),
914
                                'tr' => array($valH[1], $valV[1]),
915
                                'br' => array($valH[2], $valV[2]),
916
                                'bl' => array($valH[3], $valV[3])
917
                            );
918
                    break;
919
920 View Code Duplication
                case 'border-top-left-radius':
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...
921
                    $val = $this->convertToRadius($val);
922
                    if (count($val)<1 || count($val)>2) {
923
                        break;
924
                    }
925
                    $this->value['border']['radius']['tl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
926
                    break;
927
928 View Code Duplication
                case 'border-top-right-radius':
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...
929
                    $val = $this->convertToRadius($val);
930
                    if (count($val)<1 || count($val)>2) {
931
                        break;
932
                    }
933
                    $this->value['border']['radius']['tr'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
934
                    break;
935
936 View Code Duplication
                case 'border-bottom-right-radius':
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...
937
                    $val = $this->convertToRadius($val);
938
                    if (count($val)<1 || count($val)>2) {
939
                        break;
940
                    }
941
                    $this->value['border']['radius']['br'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
942
                    break;
943
944 View Code Duplication
                case 'border-bottom-left-radius':
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...
945
                    $val = $this->convertToRadius($val);
946
                    if (count($val)<1 || count($val)>2) {
947
                        break;
948
                    }
949
                    $this->value['border']['radius']['bl'] = array($val[0], isset($val[1]) ? $val[1] : $val[0]);
950
                    break;
951
952
                case 'border-top':
953
                    $this->value['border']['t'] = $this->readBorder($val);
954
                    break;
955
956
                case 'border-right':
957
                    $this->value['border']['r'] = $this->readBorder($val);
958
                    break;
959
960
                case 'border-bottom':
961
                    $this->value['border']['b'] = $this->readBorder($val);
962
                    break;
963
964
                case 'border-left':
965
                    $this->value['border']['l'] = $this->readBorder($val);
966
                    break;
967
968
                case 'background-color':
969
                    $this->value['background']['color'] = $this->convertBackgroundColor($val);
970
                    break;
971
972
                case 'background-image':
973
                    $this->value['background']['image'] = $this->convertBackgroundImage($val);
974
                    break;
975
976
                case 'background-position':
977
                    $res = null;
978
                    $this->value['background']['position'] = $this->convertBackgroundPosition($val, $res);
979
                    break;
980
981
                case 'background-repeat':
982
                    $this->value['background']['repeat'] = $this->convertBackgroundRepeat($val);
983
                    break;
984
985
                case 'background':
986
                    $this->convertBackground($val, $this->value['background']);
987
                    break;
988
989
                case 'position':
990
                    if ($val=='absolute')       $this->value['position'] = 'absolute';
991
                    else if ($val=='relative')  $this->value['position'] = 'relative';
992
                    else                        $this->value['position'] = null;
993
                    break;
994
995
                case 'float':
996
                    if ($val=='left')           $this->value['float'] = 'left';
997
                    else if ($val=='right')     $this->value['float'] = 'right';
998
                    else                        $this->value['float'] = null;
999
                    break;
1000
1001
                case 'display':
1002
                    if ($val=='inline')         $this->value['display'] = 'inline';
1003
                    else if ($val=='block')     $this->value['display'] = 'block';
1004
                    else if ($val=='none')      $this->value['display'] = 'none';
1005
                    else                        $this->value['display'] = null;
1006
                    break;
1007
1008
                case 'top':
1009
                case 'bottom':
1010
                case 'left':
1011
                case 'right':
1012
                    $this->value[$nom] = $val;
1013
                    break;
1014
1015
                case 'list-style':
1016
                case 'list-style-type':
1017
                case 'list-style-image':
1018
                    if ($nom=='list-style') $nom = 'list-style-type';
1019
                    $this->value[$nom] = $val;
1020
                    break;
1021
1022
                default:
1023
                    break;
1024
            }
1025
        }
1026
1027
        $return = true;
1028
1029
        // only for P tag
1030 View Code Duplication
        if ($this->value['margin']['t']===null) $this->value['margin']['t'] = $this->value['font-size'];
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...
1031
        if ($this->value['margin']['b']===null) $this->value['margin']['b'] = $this->value['font-size'];
1032
1033
        // force the text align to left, if asked by html2pdf
1034
        if ($this->_onlyLeft) $this->value['text-align'] = 'left';
1035
1036
        // correction on the width (quick box)
1037
        if ($noWidth && in_array($tagName, array('div', 'blockquote', 'fieldset')) && $this->value['position']!='absolute') {
1038
            $this->value['width'] = $this->getLastWidth();
1039
            $this->value['width']-= $this->value['margin']['l'] + $this->value['margin']['r'];
1040
        } else {
1041
            if ($correctWidth) {
1042
                if (!in_array($tagName, array('table', 'div', 'blockquote', 'fieldset', 'hr'))) {
1043
                    $this->value['width']-= $this->value['padding']['l'] + $this->value['padding']['r'];
1044
                    $this->value['width']-= $this->value['border']['l']['width'] + $this->value['border']['r']['width'];
1045
                }
1046
                if (in_array($tagName, array('th', 'td'))) {
1047
                    $this->value['width']-= $this->convertToMM(isset($param['cellspacing']) ? $param['cellspacing'] : '2px');
1048
                    $return = false;
1049
                }
1050
                if ($this->value['width']<0) $this->value['width']=0;
1051 View Code Duplication
            } else {
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...
1052
                if ($this->value['width']) {
1053
                    if ($this->value['border']['l']['width']) $this->value['width'] += $this->value['border']['l']['width'];
1054
                    if ($this->value['border']['r']['width']) $this->value['width'] += $this->value['border']['r']['width'];
1055
                    if ($this->value['padding']['l'])         $this->value['width'] += $this->value['padding']['l'];
1056
                    if ($this->value['padding']['r'])         $this->value['width'] += $this->value['padding']['r'];
1057
                }
1058
            }
1059
        }
1060 View Code Duplication
        if ($this->value['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...
1061
            if ($this->value['border']['b']['width']) $this->value['height'] += $this->value['border']['b']['width'];
1062
            if ($this->value['border']['t']['width']) $this->value['height'] += $this->value['border']['t']['width'];
1063
            if ($this->value['padding']['b'])         $this->value['height'] += $this->value['padding']['b'];
1064
            if ($this->value['padding']['t'])         $this->value['height'] += $this->value['padding']['t'];
1065
        }
1066
1067
        if ($this->value['top']!=null)      $this->value['top']     = $this->convertToMM($this->value['top'], $this->getLastHeight(true));
1068
        if ($this->value['bottom']!=null)   $this->value['bottom']  = $this->convertToMM($this->value['bottom'], $this->getLastHeight(true));
1069 View Code Duplication
        if ($this->value['left']!=null)     $this->value['left']    = $this->convertToMM($this->value['left'], $this->getLastWidth(true));
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...
1070 View Code Duplication
        if ($this->value['right']!=null)    $this->value['right']   = $this->convertToMM($this->value['right'], $this->getLastWidth(true));
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...
1071
1072
        if ($this->value['top'] && $this->value['bottom'] && $this->value['height'])    $this->value['bottom']  = null;
1073
        if ($this->value['left'] && $this->value['right'] && $this->value['width'])     $this->value['right']   = null;
1074
1075
        return $return;
1076
    }
1077
1078
     /**
1079
     * get the height of the current line
1080
     *
1081
     * @access public
1082
     * @return float $height in mm
1083
     */
1084
    public function getLineHeight()
1085
    {
1086
        $val = $this->value['line-height'];
1087
        if ($val=='normal') $val = '108%';
1088
        return $this->convertToMM($val, $this->value['font-size']);
1089
    }
1090
1091
     /**
1092
     * get the width of the parent
1093
     *
1094
     * @access public
1095
     * @param  boolean $mode true => adding padding and border
1096
     * @return float $width in mm
1097
     */
1098 View Code Duplication
    public function getLastWidth($mode = false)
0 ignored issues
show
Duplication introduced by
This method 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...
1099
    {
1100
        for ($k=count($this->table)-1; $k>=0; $k--) {
1101
            if ($this->table[$k]['width']) {
1102
                $w = $this->table[$k]['width'];
1103
                if ($mode) {
1104
                    $w+= $this->table[$k]['border']['l']['width'] + $this->table[$k]['padding']['l'] + 0.02;
1105
                    $w+= $this->table[$k]['border']['r']['width'] + $this->table[$k]['padding']['r'] + 0.02;
1106
                }
1107
                return $w;
1108
            }
1109
        }
1110
        return $this->_pdf->getW() - $this->_pdf->getlMargin() - $this->_pdf->getrMargin();
1111
    }
1112
1113
     /**
1114
     * get the height of the parent
1115
     *
1116
     * @access public
1117
     * @param  boolean $mode true => adding padding and border
1118
     * @return float $height in mm
1119
     */
1120 View Code Duplication
    public function getLastHeight($mode = false)
0 ignored issues
show
Duplication introduced by
This method 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...
1121
    {
1122
        for ($k=count($this->table)-1; $k>=0; $k--) {
1123
            if ($this->table[$k]['height']) {
1124
                $h = $this->table[$k]['height'];
1125
                if ($mode) {
1126
                    $h+= $this->table[$k]['border']['t']['width'] + $this->table[$k]['padding']['t'] + 0.02;
1127
                    $h+= $this->table[$k]['border']['b']['width'] + $this->table[$k]['padding']['b'] + 0.02;
1128
                }
1129
                return $h;
1130
            }
1131
        }
1132
        return $this->_pdf->getH() - $this->_pdf->gettMargin() - $this->_pdf->getbMargin();
1133
    }
1134
1135
    /**
1136
     * get the value of the float property
1137
     *
1138
     * @access public
1139
     * @return $float left/right
0 ignored issues
show
Documentation introduced by
The doc-type $float could not be parsed: Unknown type name "$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...
1140
     */
1141
    public function getFloat()
1142
    {
1143
        if ($this->value['float']=='left')    return 'left';
1144
        if ($this->value['float']=='right')   return 'right';
1145
        return null;
1146
    }
1147
1148
    /**
1149
     * get the last value for a specific key
1150
     *
1151
     * @access public
1152
     * @param  string $key
1153
     * @return mixed
1154
     */
1155
    public function getLastValue($key)
1156
    {
1157
        $nb = count($this->table);
1158
        if ($nb>0) {
1159
            return $this->table[$nb-1][$key];
1160
        } else {
1161
            return null;
1162
        }
1163
    }
1164
1165
    /**
1166
     * get the last absolute X
1167
     *
1168
     * @access protected
1169
     * @return float $x
1170
     */
1171 View Code Duplication
    protected function _getLastAbsoluteX()
0 ignored issues
show
Duplication introduced by
This method 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...
1172
    {
1173
        for ($k=count($this->table)-1; $k>=0; $k--) {
1174
            if ($this->table[$k]['x'] && $this->table[$k]['position']) return $this->table[$k]['x'];
1175
        }
1176
        return $this->_pdf->getlMargin();
1177
    }
1178
1179
    /**
1180
     * get the last absolute Y
1181
     *
1182
     * @access protected
1183
     * @return float $y
1184
     */
1185 View Code Duplication
    protected function _getLastAbsoluteY()
0 ignored issues
show
Duplication introduced by
This method 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...
1186
    {
1187
        for ($k=count($this->table)-1; $k>=0; $k--) {
1188
            if ($this->table[$k]['y'] && $this->table[$k]['position']) return $this->table[$k]['y'];
1189
        }
1190
        return $this->_pdf->gettMargin();
1191
    }
1192
1193
    /**
1194
     * get the CSS properties of the current tag
1195
     *
1196
     * @access protected
1197
     * @return array $styles
1198
     */
1199
    protected function _getFromCSS()
1200
    {
1201
        // styles to apply
1202
        $styles = array();
1203
1204
        // list of the selectors to get in the CSS files
1205
        $getit  = array();
1206
1207
        // get the list of the selectors of each tags
1208
        $lst = array();
1209
        $lst[] = $this->value['id_lst'];
1210
        for ($i=count($this->table)-1; $i>=0; $i--) {
1211
            $lst[] = $this->table[$i]['id_lst'];
1212
        }
1213
1214
        // foreach selectors in the CSS files, verify if it match with the list of selectors
1215
        foreach ($this->cssKeys as $key => $num) {
1216
            if ($this->_getReccursiveStyle($key, $lst)) {
1217
                $getit[$key] = $num;
1218
            }
1219
        }
1220
1221
        // if we have selectors
1222
        if (count($getit)) {
1223
            // get them, but in the definition order, because of priority
1224
            asort($getit);
1225
            foreach ($getit as $key => $val) $styles = array_merge($styles, $this->css[$key]);
1226
        }
1227
1228
        return $styles;
1229
    }
1230
1231
    /**
1232
     * identify if the selector $key match with the list of tag selectors
1233
     *
1234
     * @access protected
1235
     * @param  string   $key CSS selector to analyse
1236
     * @param  array    $lst list of the selectors of each tags
1237
     * @param  string   $next next step of parsing the selector
1238
     * @return boolean
1239
     */
1240
    protected function _getReccursiveStyle($key, $lst, $next = null)
1241
    {
1242
        // if next step
1243
        if ($next!==null) {
1244
            // we remove this step
1245
            if ($next) $key = trim(substr($key, 0, -strlen($next)));
1246
            array_shift($lst);
1247
1248
            // if no more step to identify => return false
1249
            if (!count($lst)) {
1250
                return false;
1251
            }
1252
        }
1253
1254
        // for each selector of the current step
1255
        foreach ($lst[0] as $name) {
1256
            // if selector = key => ok
1257
            if ($key==$name) {
1258
                return true;
1259
            }
1260
1261
            // if the end of the key = the selector and the next step is ok => ok
1262
            if (substr($key, -strlen(' '.$name))==' '.$name && $this->_getReccursiveStyle($key, $lst, $name)) {
1263
                return true;
1264
            }
1265
        }
1266
1267
        // if we are not in the first step, we analyse the sub steps (the pareng tag of the current tag)
1268
        if ($next!==null && $this->_getReccursiveStyle($key, $lst, '')) {
1269
            return true;
1270
        }
1271
1272
        // no corresponding found
1273
        return false;
1274
    }
1275
1276
    /**
1277
     * Analyse a border
1278
     *
1279
     * @access  public
1280
     * @param   string $css css border properties
1281
     * @return  array  border properties
1282
     */
1283
    public function readBorder($css)
1284
    {
1285
        // border none
1286
        $none = array('type' => 'none', 'width' => 0, 'color' => array(0, 0, 0));
1287
1288
        // default value
1289
        $type  = 'solid';
1290
        $width = $this->convertToMM('1pt');
1291
        $color = array(0, 0, 0);
1292
1293
        // clean up the values
1294
        $css = explode(' ', $css);
1295
        foreach ($css as $k => $v) {
1296
            $v = trim($v);
1297
            if ($v) $css[$k] = $v;
1298
            else    unset($css[$k]);
1299
        }
1300
        $css = array_values($css);
1301
1302
        // read the values
1303
        $res = null;
1304
        foreach ($css as $value) {
1305
1306
            // if no border => return none
1307
            if ($value=='none' || $value=='hidden') {
1308
                return $none;
1309
            }
1310
1311
            // try to convert the value as a distance
1312
            $tmp = $this->convertToMM($value);
1313
1314
            // if the convert is ok => it is a width
1315
            if ($tmp!==null) {
1316
                $width = $tmp;
1317
            // else, it could be the type
1318
            } else if (in_array($value, array('solid', 'dotted', 'dashed', 'double'))) {
1319
                $type = $value;
1320
            // else, it could be the color
1321
            } else {
1322
                $tmp = $this->convertToColor($value, $res);
1323
                if ($res) $color = $tmp;
1324
            }
1325
        }
1326
1327
        // if no witdh => return none
1328
        if (!$width) return $none;
1329
1330
        // return the border properties
1331
        return array('type' => $type, 'width' => $width, 'color' => $color);
1332
    }
1333
1334
    /**
1335
     * duplicate the borders if needed
1336
     *
1337
     * @access protected
1338
     * @param  &array $val
0 ignored issues
show
Documentation introduced by
The doc-type &array could not be parsed: Unknown type name "&array" 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...
1339
     */
1340
    protected function _duplicateBorder(&$val)
1341
    {
1342
        // 1 value => L => RTB
1343
        if (count($val)==1) {
1344
            $val[1] = $val[0];
1345
            $val[2] = $val[0];
1346
            $val[3] = $val[0];
1347
        // 2 values => L => R & T => B
1348
        } else if (count($val)==2) {
1349
            $val[2] = $val[0];
1350
            $val[3] = $val[1];
1351
        // 3 values => T => B
1352
        } else if (count($val)==3) {
1353
            $val[3] = $val[1];
1354
        }
1355
    }
1356
1357
    /**
1358
     * Analyse a background
1359
     *
1360
     * @access public
1361
     * @param  string $css css background properties
1362
     * @param  &array $value parsed values (by reference, because, ther is a legacy of the parent CSS properties)
0 ignored issues
show
Documentation introduced by
The doc-type &array could not be parsed: Unknown type name "&array" 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...
1363
     */
1364
    public function convertBackground($css, &$value)
1365
    {
1366
        // is there a image ?
1367
        $text = '/url\(([^)]*)\)/isU';
1368
        if (preg_match($text, $css, $match)) {
1369
            // get the image
1370
            $value['image'] = $this->convertBackgroundImage($match[0]);
1371
1372
            // remove if from the css properties
1373
            $css = preg_replace($text, '', $css);
1374
            $css = preg_replace('/[\s]+/', ' ', $css);
1375
        }
1376
1377
        // protect some spaces
1378
        $css = preg_replace('/,[\s]+/', ',', $css);
1379
1380
        // explode the values
1381
        $css = explode(' ', $css);
1382
1383
        // background position to parse
1384
        $pos = '';
1385
1386
        // foreach value
1387
        foreach ($css as $val) {
1388
            // try to parse the value as a color
1389
            $ok = false;
1390
            $color = $this->convertToColor($val, $ok);
1391
1392
            // if ok => it is a color
1393
            if ($ok) {
1394
                $value['color'] = $color;
1395
            // else if transparent => no coloàr
1396
            } else if ($val=='transparent') {
1397
                $value['color'] = null;
1398
            // else
1399
            } else {
1400
                // try to parse the value as a repeat
1401
                $repeat = $this->convertBackgroundRepeat($val);
1402
1403
                // if ok => it is repeat
1404
                if ($repeat) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $repeat of type boolean[] 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...
1405
                    $value['repeat'] = $repeat;
1406
                // else => it could only be a position
1407
                } else {
1408
                    $pos.= ($pos ? ' ' : '').$val;
1409
                }
1410
            }
1411
        }
1412
1413
        // if we have a position to parse
1414
        if ($pos) {
1415
            // try to read it
1416
            $pos = $this->convertBackgroundPosition($pos, $ok);
1417
            if ($ok) $value['position'] = $pos;
1418
        }
1419
    }
1420
1421
    /**
1422
     * parse a background color
1423
     *
1424
     * @access public
1425
     * @param  string $css
1426
     * @return string $value
1427
     */
1428
    public function convertBackgroundColor($css)
1429
    {
1430
        $res = null;
1431
        if ($css=='transparent') return null;
1432
        else                     return $this->convertToColor($css, $res);
1433
    }
1434
1435
    /**
1436
     * parse a background image
1437
     *
1438
     * @access public
1439
     * @param  string $css
1440
     * @return string $value
1441
     */
1442
    public function convertBackgroundImage($css)
1443
    {
1444
        if ($css=='none')
1445
            return null;
1446
        else if (preg_match('/^url\(([^)]*)\)$/isU', $css, $match))
1447
            return $match[1];
1448
        else
1449
            return null;
1450
    }
1451
1452
    /**
1453
     * parse a background position
1454
     *
1455
     * @access public
1456
     * @param  string $css
1457
     * @param  &boolean $res flag if conver is ok or not
0 ignored issues
show
Documentation introduced by
The doc-type &boolean could not be parsed: Unknown type name "&boolean" 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...
1458
     * @return array ($x, $y)
1459
     */
1460
    public function convertBackgroundPosition($css, &$res)
1461
    {
1462
        // init the res
1463
        $res = false;
1464
1465
        // explode the value
1466
        $css = explode(' ', $css);
1467
1468
        // we must have 2 values. if 0 or >2 : error. if 1 => put center for 2
1469
        if (count($css)<2) {
1470
            if (!$css[0]) return null;
1471
            $css[1] = 'center';
1472
        }
1473
        if (count($css)>2) return null;
1474
1475
        // prepare the values
1476
        $x = 0;
1477
        $y = 0;
1478
        $res = true;
1479
1480
        // convert the first value
1481 View Code Duplication
        if ($css[0]=='left')        $x = '0%';
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...
1482
        else if ($css[0]=='center') $x = '50%';
1483
        else if ($css[0]=='right')  $x = '100%';
1484
        else if ($css[0]=='top')    $y = '0%';
1485
        else if ($css[0]=='bottom') $y = '100%';
1486
        else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[0])) $x = $css[0];
1487
        else if ($this->convertToMM($css[0])) $x = $this->convertToMM($css[0]);
1488
        else $res = false;
1489
1490
        // convert the second value
1491 View Code Duplication
        if ($css[1]=='left')        $x = '0%';
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...
1492
        else if ($css[1]=='right')  $x = '100%';
1493
        else if ($css[1]=='top')    $y = '0%';
1494
        else if ($css[1]=='center') $y = '50%';
1495
        else if ($css[1]=='bottom') $y = '100%';
1496
        else if (preg_match('/^[-]?[0-9\.]+%$/isU', $css[1])) $y = $css[1];
1497
        else if ($this->convertToMM($css[1])) $y = $this->convertToMM($css[1]);
1498
        else $res = false;
1499
1500
        // return the values
1501
        return array($x, $y);
1502
    }
1503
1504
    /**
1505
     * parse a background repeat
1506
     *
1507
     * @access public
1508
     * @param  string $css
1509
     * @return string $value
1510
     */
1511
    public function convertBackgroundRepeat($css)
1512
    {
1513
        switch($css)
1514
        {
1515
            case 'repeat':
1516
                return array(true, true);
1517
            case 'repeat-x':
1518
                return array(true, false);
1519
            case 'repeat-y':
1520
                return array(false, true);
1521
            case 'no-repeat':
1522
                return array(false, false);
1523
        }
1524
        return null;
1525
    }
1526
1527
     /**
1528
     * convert a distance to mm
1529
     *
1530
     * @access public
1531
     * @param  string $css distance to convert
1532
     * @param  float  $old parent distance
1533
     * @return float  $value
1534
     */
1535
    public function convertToMM($css, $old=0.)
1536
    {
1537
        $css = trim($css);
1538
        if (preg_match('/^[0-9\.\-]+$/isU', $css))        $css.= 'px';
1539
        if (preg_match('/^[0-9\.\-]+px$/isU', $css))      $css = 25.4/96. * str_replace('px', '', $css);
1540
        else if (preg_match('/^[0-9\.\-]+pt$/isU', $css)) $css = 25.4/72. * str_replace('pt', '', $css);
1541
        else if (preg_match('/^[0-9\.\-]+in$/isU', $css)) $css = 25.4 * str_replace('in', '', $css);
1542
        else if (preg_match('/^[0-9\.\-]+mm$/isU', $css)) $css = 1.*str_replace('mm', '', $css);
1543
        else if (preg_match('/^[0-9\.\-]+%$/isU', $css))  $css = 1.*$old*str_replace('%', '', $css)/100.;
1544
        else                                              $css = null;
1545
1546
        return $css;
1547
    }
1548
1549
    /**
1550
     * convert a css radius
1551
     *
1552
     * @access public
1553
     * @param  string $css
1554
     * @return float  $value
1555
     */
1556
    public function convertToRadius($css)
1557
    {
1558
        // explode the value
1559
        $css = explode(' ', $css);
1560
1561
        foreach ($css as $k => $v) {
1562
            $v = trim($v);
1563
            if ($v) {
1564
                $v = $this->convertToMM($v, 0);
1565
                if ($v!==null) {
1566
                    $css[$k] = $v;
1567
                } else {
1568
                    unset($css[$k]);
1569
                }
1570
            } else {
1571
                unset($css[$k]);
1572
            }
1573
        }
1574
1575
        return array_values($css);
1576
    }
1577
1578
    /**
1579
     * convert a css color
1580
     *
1581
     * @access public
1582
     * @param  string $css
1583
     * @param  &boolean $res
0 ignored issues
show
Documentation introduced by
The doc-type &boolean could not be parsed: Unknown type name "&boolean" 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...
1584
     * @return array (r,g, b)
1585
     */
1586
    public function convertToColor($css, &$res)
1587
    {
1588
        // prepare the value
1589
        $css = trim($css);
1590
        $res = true;
1591
1592
        // if transparent => return null
1593
        if (strtolower($css)=='transparent') return array(null, null, null);
1594
1595
        // HTML color
1596
        if (isset($this->_htmlColor[strtolower($css)])) {
1597
            $css = $this->_htmlColor[strtolower($css)];
1598
            $r = floatVal(hexdec(substr($css, 0, 2)));
1599
            $v = floatVal(hexdec(substr($css, 2, 2)));
1600
            $b = floatVal(hexdec(substr($css, 4, 2)));
1601
            return array($r, $v, $b);
1602
        }
1603
1604
        // like #FFFFFF
1605
        if (preg_match('/^#[0-9A-Fa-f]{6}$/isU', $css)) {
1606
            $r = floatVal(hexdec(substr($css, 1, 2)));
1607
            $v = floatVal(hexdec(substr($css, 3, 2)));
1608
            $b = floatVal(hexdec(substr($css, 5, 2)));
1609
            return array($r, $v, $b);
1610
        }
1611
1612
        // like #FFF
1613
        if (preg_match('/^#[0-9A-F]{3}$/isU', $css)) {
1614
            $r = floatVal(hexdec(substr($css, 1, 1).substr($css, 1, 1)));
1615
            $v = floatVal(hexdec(substr($css, 2, 1).substr($css, 2, 1)));
1616
            $b = floatVal(hexdec(substr($css, 3, 1).substr($css, 3, 1)));
1617
            return array($r, $v, $b);
1618
        }
1619
1620
        // like rgb(100, 100, 100)
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1621
        if (preg_match('/rgb\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1622
            $r = $this->_convertSubColor($match[1]);
1623
            $v = $this->_convertSubColor($match[2]);
1624
            $b = $this->_convertSubColor($match[3]);
1625
            return array($r*255., $v*255., $b*255.);
1626
        }
1627
1628
        // like cmyk(100, 100, 100, 100)
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1629
        if (preg_match('/cmyk\([\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*,[\s]*([0-9%\.]+)[\s]*\)/isU', $css, $match)) {
1630
            $c = $this->_convertSubColor($match[1]);
1631
            $m = $this->_convertSubColor($match[2]);
1632
            $y = $this->_convertSubColor($match[3]);
1633
            $k = $this->_convertSubColor($match[4]);
1634
            return array($c*100., $m*100., $y*100., $k*100.);
1635
        }
1636
1637
        $res = false;
1638
        return array(0., 0., 0.);
1639
    }
1640
1641
    /**
1642
     * color value to convert
1643
     *
1644
     * @access protected
1645
     * @param  string $c
1646
     * @return float $c 0.->1.
1647
     */
1648
    protected function _convertSubColor($c)
1649
    {
1650
        if (substr($c, -1)=='%') {
1651
            $c = floatVal(substr($c, 0, -1))/100.;
1652
        } else {
1653
            $c = floatVal($c);
1654
            if ($c>1) $c = $c/255.;
1655
        }
1656
1657
        return $c;
1658
    }
1659
1660
    /**
1661
     * read a css content
1662
     *
1663
     * @access protected
1664
     * @param  &string $code
0 ignored issues
show
Documentation introduced by
The doc-type &string could not be parsed: Unknown type name "&string" 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...
1665
     */
1666
    protected function _analyseStyle(&$code)
1667
    {
1668
        // clean the spaces
1669
        $code = preg_replace('/[\s]+/', ' ', $code);
1670
1671
        // remove the comments
1672
        $code = preg_replace('/\/\*.*?\*\//s', '', $code);
1673
1674
        // split each CSS code "selector { value }"
1675
        preg_match_all('/([^{}]+){([^}]*)}/isU', $code, $match);
1676
1677
        // for each CSS code
1678
        for ($k=0; $k<count($match[0]); $k++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1679
1680
            // selectors
1681
            $names = strtolower(trim($match[1][$k]));
1682
1683
            // css style
1684
            $styles = trim($match[2][$k]);
1685
1686
            // explode each value
1687
            $styles = explode(';', $styles);
1688
1689
            // parse each value
1690
            $css = array();
1691
            foreach ($styles as $style) {
1692
                $tmp = explode(':', $style);
1693
                if (count($tmp)>1) {
1694
                    $cod = $tmp[0]; unset($tmp[0]); $tmp = implode(':', $tmp);
1695
                    $css[trim(strtolower($cod))] = trim($tmp);
1696
                }
1697
            }
1698
1699
            // explode the names
1700
            $names = explode(',', $names);
1701
1702
            // save the values for each names
1703
            foreach ($names as $name) {
1704
                // clean the name
1705
                $name = trim($name);
1706
1707
                // if a selector with somethink lige :hover => continue
1708
                if (strpos($name, ':')!==false) continue;
1709
1710
                // save the value
1711
                if (!isset($this->css[$name]))
1712
                    $this->css[$name] = $css;
1713
                else
1714
                    $this->css[$name] = array_merge($this->css[$name], $css);
1715
1716
            }
1717
        }
1718
1719
        // get he list of the keys
1720
        $this->cssKeys = array_flip(array_keys($this->css));
1721
    }
1722
1723
    /**
1724
     * Extract the css files from a html code
1725
     *
1726
     * @access public
1727
     * @param  string   &$html
1728
     */
1729
    public function readStyle(&$html)
1730
    {
1731
        // the CSS content
1732
        $style = ' ';
1733
1734
        // extract the link tags, and remove them in the html code
1735
        preg_match_all('/<link([^>]*)>/isU', $html, $match);
1736
        $html = preg_replace('/<link[^>]*>/isU', '', $html);
1737
        $html = preg_replace('/<\/link[^>]*>/isU', '', $html);
1738
1739
        // analyse each link tag
1740
        foreach ($match[1] as $code) {
1741
            $tmp = array();
1742
1743
            // read the attributes name=value
1744
            $prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
1745
            preg_match_all('/'.$prop.'/is', $code, $match);
1746 View Code Duplication
            for ($k=0; $k<count($match[0]); $k++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
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...
1747
                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1748
            }
1749
1750
            // read the attributes name="value"
1751
            $prop = '([a-zA-Z0-9_]+)=["]([^"]*)["]';
1752
            preg_match_all('/'.$prop.'/is', $code, $match);
1753 View Code Duplication
            for ($k=0; $k<count($match[0]); $k++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
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...
1754
                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1755
            }
1756
1757
            // read the attributes name='value'
1758
            $prop = "([a-zA-Z0-9_]+)=[']([^']*)[']";
1759
            preg_match_all('/'.$prop.'/is', $code, $match);
1760 View Code Duplication
            for ($k=0; $k<count($match[0]); $k++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
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...
1761
                $tmp[trim(strtolower($match[1][$k]))] = trim($match[2][$k]);
1762
            }
1763
1764
            // if type text/css => we keep it
1765
            if (isset($tmp['type']) && strtolower($tmp['type'])=='text/css' && isset($tmp['href'])) {
1766
1767
                // get the href
1768
                $url = $tmp['href'];
1769
1770
                // get the content of the css file
1771
                $content = @file_get_contents($url);
1772
1773
                // if "http://" in the url
1774
                if (strpos($url, 'http://')!==false) {
1775
1776
                    // get the domain "http://xxx/"
1777
                    $url = str_replace('http://', '', $url);
1778
                    $url = explode('/', $url);
1779
                    $urlMain = 'http://'.$url[0].'/';
1780
1781
                    // get the absolute url of the path
1782
                    $urlSelf = $url; unset($urlSelf[count($urlSelf)-1]); $urlSelf = 'http://'.implode('/', $urlSelf).'/';
1783
1784
                    // adapt the url in the css content
1785
                    $content = preg_replace('/url\(([^\\\\][^)]*)\)/isU', 'url('.$urlSelf.'$1)', $content);
1786
                    $content = preg_replace('/url\((\\\\[^)]*)\)/isU', 'url('.$urlMain.'$1)', $content);
1787
                } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
1788
// @TODO correction on url in absolute on a local css content
1789
                    // $content = preg_replace('/url\(([^)]*)\)/isU', 'url('.dirname($url).'/$1)', $content);
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1790
                }
1791
1792
                // add to the CSS content
1793
                $style.= $content."\n";
1794
            }
1795
        }
1796
1797
        // extract the style tags des tags style, and remove them in the html code
1798
        preg_match_all('/<style[^>]*>(.*)<\/style[^>]*>/isU', $html, $match);
1799
        $html = preg_replace('/<style[^>]*>(.*)<\/style[^>]*>/isU', '', $html);
1800
1801
        // analyse each style tags
1802
        foreach ($match[1] as $code) {
1803
            // add to the CSS content
1804
            $code = str_replace('<!--', '', $code);
1805
            $code = str_replace('-->', '', $code);
1806
            $style.= $code."\n";
1807
        }
1808
1809
        //analyse the css content
1810
        $this->_analyseStyle($style);
1811
    }
1812
}