Completed
Push — master ( d62f97...a73947 )
by Esteban De La Fuente
02:23
created

PDF::getTableCellWidth()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 3
nop 2
1
<?php
2
3
/**
4
 * LibreDTE
5
 * Copyright (C) SASCO SpA (https://sasco.cl)
6
 *
7
 * Este programa es software libre: usted puede redistribuirlo y/o
8
 * modificarlo bajo los términos de la Licencia Pública General Affero de GNU
9
 * publicada por la Fundación para el Software Libre, ya sea la versión
10
 * 3 de la Licencia, o (a su elección) cualquier versión posterior de la
11
 * misma.
12
 *
13
 * Este programa se distribuye con la esperanza de que sea útil, pero
14
 * SIN GARANTÍA ALGUNA; ni siquiera la garantía implícita
15
 * MERCANTIL o de APTITUD PARA UN PROPÓSITO DETERMINADO.
16
 * Consulte los detalles de la Licencia Pública General Affero de GNU para
17
 * obtener una información más detallada.
18
 *
19
 * Debería haber recibido una copia de la Licencia Pública General Affero de GNU
20
 * junto a este programa.
21
 * En caso contrario, consulte <http://www.gnu.org/licenses/agpl.html>.
22
 */
23
24
namespace sasco\LibreDTE;
25
26
// Directorio para imágenes (no se asume nada)
27
define ('K_PATH_IMAGES', '');
28
29
/**
30
 * Clase para generar PDFs
31
 *
32
 * Los métodos se copiaron desde la clase \sowerphp\general\View_Helper_PDF
33
 * disponible en:
34
 *
35
 * <https://github.com/SowerPHP/extension-general/blob/master/View/Helper/PDF.php>
36
 *
37
 * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
38
 * @version 2016-10-06
39
 */
40
class PDF extends \TCPDF
41
{
42
43
    private $footer; ///< Mensaje a colocar en el footer
44
45
    protected $defaultOptions = [
46
        'font' => ['family' => 'helvetica', 'size' => 10],
47
        'table' => [
48
            'fontsize' => 10,
49
            'width' => 186,
50
            'height' => 6,
51
            'end' => null, // indica la coordenada 'y' donde termina la tabla
52
            'align' => 'C',
53
            'bordercolor' => [0, 0, 0],
54
            'borderwidth' => 0.1,
55
            'tdborder' => 'LR',
56
            'headerbackground' => [255, 255, 255],
57
            'headercolor' => [0, 0, 0],
58
            'bodybackground' => [255, 255, 255],
59
            'bodycolor' => [0, 0, 0],
60
            'colorchange' => false,
61
        ],
62
    ];
63
64
    /**
65
     * Constructor de la clase
66
     * @param o Orientación
67
     * @param u Unidad de medida
68
     * @param s Tipo de hoja
69
     * @param top Margen extra (al normal) para la parte de arriba del PDF
70
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
71
     * @version 2016-03-20
72
     */
73
    public function __construct($o = 'P', $u = 'mm', $s = 'LETTER', $top = 0)
74
    {
75
        parent::__construct($o, $u, $s);
76
        $this->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP+$top, PDF_MARGIN_RIGHT);
77
        $this->SetHeaderMargin(PDF_MARGIN_HEADER+$top);
78
        $this->SetFooterMargin(PDF_MARGIN_FOOTER+6);
79
        $this->SetAuthor('Un proyecto de SASCO SpA - https://sasco.cl');
80
        $this->SetCreator('LibreDTE - https://libredte.cl');
81
        $this->setFont($this->defaultOptions['font']['family']);
82
    }
83
84
    /**
85
     * Método para evitar que se renderice el de TCPDF
86
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
87
     * @version 2015-09-08
88
     */
89
    public function Header()
90
    {
91
    }
92
93
    /**
94
     * Método que genera el footer del PDF
95
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
96
     * @version 2015-03-20
97
     */
98
    public function Footer()
99
    {
100
        if (is_array($this->footer) and (!empty($this->footer['left']) or !empty($this->footer['right']))) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
101
            $style = ['width' => 0.5, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => [50, 50, 50]];
102
            $this->Line(0, $this->getY()-1, 290, $this->getY()-2, $style);
103
            $this->SetFont('', 'B', 6);
104
            if (empty($this->papelContinuo)) {
105
                if (!empty($this->footer['left']))
106
                    $this->Texto($this->footer['left']);
107
                if (!empty($this->footer['right']))
108
                    $this->Texto($this->footer['right'], null, null, 'R');
109
            } else {
110 View Code Duplication
                if (!empty($this->footer['left']))
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...
111
                    $this->Texto($this->footer['left'], null, null, 'C');
112 View Code Duplication
                if (!empty($this->footer['right'])) {
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...
113
                    $this->Ln();
114
                    $this->Texto($this->footer['right'], null, null, 'C');
115
                }
116
            }
117
        }
118
    }
119
120
    /**
121
     * Método que asigna el texto que se deberá usar en el footer
122
     * @param footer =true se asignará texto por defecto. String al lado izquiero o bien arreglo con índices left y right con sus textos
123
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
124
     * @version 2016-03-20
125
     */
126
    public function setFooterText($footer = true)
127
    {
128
        if ($footer) {
129
            // asignar valor por defecto
130
            if ($footer===true) {
131
                $footer = [
132
                    'left' => 'LibreDTE ¡facturación electrónica libre para Chile!',
133
                    'right' => 'https://libredte.cl',
134
                ];
135
            }
136
            // si no es arreglo se convierte en uno
137
            if (!is_array($footer))
138
                $footer = ['left'=>$footer];
139
            // asignar footer
140
            $this->footer = array_merge(['left'=>'', 'right'=>''], $footer);
141
        } else {
142
            $this->footer = null;
143
        }
144
    }
145
146
    /**
147
     * Obtener el ancho de las columnas de una tabla
148
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
149
     * @version 2016-01-22
150
     */
151
    private function getTableCellWidth($total, $cells)
152
    {
153
        $widths = [];
154
        if (is_int($cells)) {
155
            $width = floor($total/$cells);
156
            for ($i=0; $i<$cells; ++$i) {
157
                $widths[] = $width;
158
            }
159
        }
160
        else if (is_array($cells)){
161
            $width = floor($total/count($cells));
162
            foreach ($cells as $i) {
163
                $widths[$i] = $width;
164
            }
165
        }
166
        return $widths;
167
    }
168
169
    /**
170
     * Agregar una tabla al PDF removiendo aquellas columnas donde no existen
171
     * datos en la columna para todas las filas
172
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
173
     * @version 2016-10-06
174
     */
175
    public function addTableWithoutEmptyCols($titles, $data, $options = [], $html = true)
176
    {
177
        $cols_empty = [];
178
        foreach ($data as $row) {
179
            foreach ($row as $col => $value) {
180
                if (empty($value)) {
181
                    if (!array_key_exists($col, $cols_empty))
182
                        $cols_empty[$col] = 0;
183
                    $cols_empty[$col]++;
184
                }
185
            }
186
        }
187
        $n_rows = count($data);
188
        $titles_keys = array_flip(array_keys($titles));
189
        foreach ($cols_empty as $col => $rows) {
190
            if ($rows==$n_rows) {
191
                unset($titles[$col]);
192
                foreach ($data as &$row) {
193
                    unset($row[$col]);
194
                }
195
                if (isset($options['width']))
196
                    unset($options['width'][$titles_keys[$col]]);
197
                if (isset($options['align']))
198
                    unset($options['align'][$titles_keys[$col]]);
199
            }
200
        }
201
        if (isset($options['width'])) {
202
            $options['width'] = array_slice($options['width'], 0);
203
            $key_0 = null;
204
            $suma = 0;
205
            foreach ($options['width'] as $key => $val) {
206
                if ($val===0)
207
                    $key_0 = $key;
208
                $suma += $val;
209
            }
210
            if ($key_0!==null) {
211
                $options['width'][$key_0] = 190 - $suma;
212
            }
213
        }
214
        if (isset($options['align']))
215
            $options['align'] = array_slice($options['align'], 0);
216
        $this->addTable($titles, $data, $options, $html);
217
    }
218
219
    /**
220
     * Agregar una tabla generada al PDF (puede ser en HTML o normal)
221
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
222
     * @version 2016-10-06
223
     */
224
    public function addTable($headers, $data, $options = [], $html = true)
225
    {
226
        $options = array_merge($this->defaultOptions['table'], $options);
227
        if ($html) {
228
            $this->addHTMLTable($headers, $data, $options);
229
        } else {
230
            $this->addNormalTable($headers, $data, $options);
231
        }
232
    }
233
234
    /**
235
     * Agregar una tabla generada a través de código HTML al PDF
236
     * @todo Utilizar las opciones para definir estilo de la tabla HTML
237
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
238
     * @version 2016-10-06
239
     */
240
    private function addHTMLTable($headers, $data, $options = [])
241
    {
242
        $w = (isset($options['width']) and is_array($options['width'])) ? $options['width'] : null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
243
        $a = (isset($options['align']) and is_array($options['align'])) ? $options['align'] : [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
244
        $buffer = '<table style="border:1px solid #333">';
245
        // Definir títulos de columnas
246
        $thead = isset($options['width']) and is_array($options['width']) and count($options['width']) == count($headers);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
247
        if ($thead)
248
            $buffer .= '<thead>';
249
        $buffer .= '<tr>';
250
        $i = 0;
251 View Code Duplication
        foreach ($headers as &$col) {
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...
252
            $width = ($w and isset($w[$i])) ? (';width:'.$w[$i].'mm') : '';
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
253
            $align = isset($a[$i]) ? $a[$i] : 'center';
254
            $buffer .= '<th style="border-right:1px solid #333;border-bottom:1px solid #333;text-align:'.$align.$width.'"><strong>'.strip_tags($col).'</strong></th>';
255
            $i++;
256
        }
257
        $buffer .= '</tr>';
258
        if ($thead)
259
            $buffer .= '</thead>';
260
        // Definir datos de la tabla
261
        if ($thead)
262
            $buffer .= '<tbody>';
263
        foreach ($data as &$row) {
264
            $buffer .= '<tr>';
265
            $i = 0;
266 View Code Duplication
            foreach ($row as &$col) {
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...
267
                $width = ($w and isset($w[$i])) ? (';width:'.$w[$i].'mm') : '';
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
268
                $align = isset($a[$i]) ? $a[$i] : 'center';
269
                $buffer .= '<td style="border-right:1px solid #333;text-align:'.$align.$width.'">'.$col.'</td>';
270
                $i++;
271
            }
272
            $buffer .= '</tr>';
273
        }
274
        if ($thead)
275
            $buffer .= '</tbody>';
276
        // Finalizar tabla
277
        $buffer .= '</table>';
278
        // generar tabla en HTML
279
        $this->writeHTML($buffer, true, false, false, false, '');
280
    }
281
282
    /**
283
     * Agregar una tabla generada mediante el método Cell
284
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
285
     * @version 2018-04-15
286
     */
287
    private function addNormalTable(array $headers, array $data, array $options = [])
288
    {
289
        // Colors, line width and bold font
290
        $this->SetFillColor(
291
            $options['headerbackground'][0],
292
            $options['headerbackground'][1],
293
            $options['headerbackground'][2]
294
        );
295
        $this->SetTextColor(
296
            $options['headercolor'][0],
297
            $options['headercolor'][1],
298
            $options['headercolor'][2]
299
        );
300
        $this->SetDrawColor(
301
            $options['bordercolor'][0],
302
            $options['bordercolor'][1],
303
            $options['bordercolor'][2]
304
        );
305
        $this->SetLineWidth($options['borderwidth']);
306
        $this->SetFont($this->defaultOptions['font']['family'], 'B',  $options['fontsize']);
307
        // corregir indices
308
        $headers_keys = array_keys($headers);
309
        if (is_array($options['width'])) {
310
            $options['width'] = array_combine($headers_keys, $options['width']);
311
        } else {
312
            $options['width'] = $this->getTableCellWidth($options['width'], $headers_keys);
313
        }
314
        if (is_array($options['align'])) {
315
            $options['align'] = array_combine($headers_keys, $options['align']);
316
            foreach ($options['align'] as &$a) {
317
                $a = strtoupper($a[0]);
318
            }
319
        } else if (is_string($options['align'])) {
320
            $align = $options['align'];
321
            $options['align'] = [];
322
            foreach ($headers_keys as $key) {
323
                $options['align'][$key] = $align;
324
            }
325
        }
326
        // Header
327
        $x = $this->GetX();
328 View Code Duplication
        foreach($headers as $i => $header) {
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
            $this->Cell($options['width'][$i], $options['height'], $headers[$i], 1, 0, $options['align'][$i], 1);
330
        }
331
        $this->Ln();
332
        $y = $this->GetY();
333
        // Color and font restoration
334
        $this->SetFillColor (
335
            $options['bodybackground'][0],
336
            $options['bodybackground'][1],
337
            $options['bodybackground'][2]
338
        );
339
        $this->SetTextColor(
340
            $options['bodycolor'][0],
341
            $options['bodycolor'][1],
342
            $options['bodycolor'][2]
343
        );
344
        $this->SetDrawColor(
345
            $options['bordercolor'][0],
346
            $options['bordercolor'][1],
347
            $options['bordercolor'][2]
348
        );
349
        $this->SetLineWidth($options['borderwidth']);
350
        $this->SetFont($this->defaultOptions['font']['family']);
351
        // Data
352
        foreach ($data as &$row) {
353
            $num_pages = $this->getNumPages();
354
            $this->startTransaction();
355
            // agregar datos de la fila
356
            $this->SetX($x);
357
            $y_0 = $this->GetY();
358
            $y_s = [];
359 View Code Duplication
            foreach($headers as $i => $header) {
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...
360
                $x_0 = $this->GetX();
361
                $this->SetXY($x_0, $y_0);
362
                $aux = explode("\n", $row[$i]);
363
                $value1 = $aux[0];
364
                $value2 = isset($aux[1]) ? $aux[1] : null;
365
                $y_1 = $this->MultiCell($options['width'][$i], $options['height'], $value1, $options['tdborder'], $options['align'][$i], false, 0);
366
                if ($value2) {
367
                    $this->Ln();
368
                    $this->SetX($x_0);
369
                    $this->SetFont($this->defaultOptions['font']['family'], '',  $options['fontsize']-2);
370
                    $y_2 = $this->MultiCell($options['width'][$i], $options['height'], $value2, $options['tdborder'], $options['align'][$i], false, 0);
371
                    $this->SetFont($this->defaultOptions['font']['family'], '',  $options['fontsize']);
372
                    $y_s[] = $y_1 + $y_2*0.9;
373
                } else {
374
                    $y_s[] = $y_1;
375
                }
376
            }
377
            $this->Ln(max($y_s)*5);
378
            // si se pasó a página siguiente se hace rollback y se crea nueva página con cabecera nuevamente en la tabla
379
            if($num_pages < $this->getNumPages()) {
380
                $this->rollbackTransaction(true);
381
                $this->AddPage();
382
                $this->SetX($x);
383 View Code Duplication
                foreach($headers as $i => $header) {
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...
384
                    $this->Cell($options['width'][$i], $options['height'], $headers[$i], 1, 0, $options['align'][$i], 1);
385
                }
386
                $this->Ln();
387
                $this->SetX($x);
388
                $y_0 = $this->GetY();
389
                $y_s = [];
390 View Code Duplication
                foreach($headers as $i => $header) {
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...
391
                    $x_0 = $this->GetX();
392
                    $this->SetXY($x_0, $y_0);
393
                    $aux = explode("\n", $row[$i]);
394
                    $value1 = $aux[0];
395
                    $value2 = isset($aux[1]) ? $aux[1] : null;
396
                    $y_1 = $this->MultiCell($options['width'][$i], $options['height'], $value1, $options['tdborder'], $options['align'][$i], false, 0);
397
                    if ($value2) {
398
                        $this->Ln();
399
                        $this->SetX($x_0);
400
                        $this->SetFont($this->defaultOptions['font']['family'], '',  $options['fontsize']-2);
401
                        $y_2 = $this->MultiCell($options['width'][$i], $options['height'], $value2, $options['tdborder'], $options['align'][$i], false, 0);
402
                        $this->SetFont($this->defaultOptions['font']['family'], '',  $options['fontsize']);
403
                        $y_s[] = $y_1 + $y_2*0.9;
404
                    } else {
405
                        $y_s[] = $y_1;
406
                    }
407
                }
408
                $this->Ln(max($y_s)*5);
409
            } else {
410
                $this->commitTransaction();
411
            }
412
        }
413
        // si la tabla tiene indicado un punto específico en Y donde terminar se usa ese punto
414
        if ($options['end']) {
415
            $lx = $x;
416
            $this->Line($lx, $y, $lx, $options['end']);
417
            foreach ($options['width'] as $ancho) {
418
                $lx += $ancho;
419
                $this->Line($lx, $y, $lx, $options['end']);
420
            }
421
            $this->SetXY($x, $options['end']);
422
        } else {
423
            $this->SetX($x);
424
        }
425
        // asignar línea final
426
        $this->Cell(array_sum($options['width']), 0, '', 'T');
427
        $this->Ln();
428
    }
429
430
    /**
431
     * Agregar texto al PDF, es una variación del método Text que permite
432
     * definir un ancho al texto. Además recibe menos parámetros para ser
433
     * más simple (parámetros comunes solamente).
434
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
435
     * @version 2014-09-20
436
     */
437 View Code Duplication
    public function Texto($txt, $x=null, $y=null, $align='', $w=0, $link='', $border=0, $fill=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...
438
    {
439
        if ($x==null) $x = $this->GetX();
440
        if ($y==null) $y = $this->GetY();
441
        $textrendermode = $this->textrendermode;
442
        $textstrokewidth = $this->textstrokewidth;
443
        $this->setTextRenderingMode(0, true, false);
444
        $this->SetXY($x, $y);
445
        $this->Cell($w, 0, $txt, $border, 0, $align, $fill, $link);
446
        // restore previous rendering mode
447
        $this->textrendermode = $textrendermode;
448
        $this->textstrokewidth = $textstrokewidth;
449
    }
450
451
    /**
452
     * Método idéntico a Texto, pero en vez de utilizar Cell utiliza
453
     * MultiCell. La principal diferencia es que este método no permite
454
     * agregar un enlace y Texto si.
455
     * @author Esteban De La Fuente Rubio, DeLaF (esteban[at]delaf.cl)
456
     * @version 2014-09-20
457
     */
458 View Code Duplication
    public function MultiTexto($txt, $x=null, $y=null, $align='', $w=0, $border=0, $fill=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...
459
    {
460
        if ($x==null) $x = $this->GetX();
461
        if ($y==null) $y = $this->GetY();
462
        $textrendermode = $this->textrendermode;
463
        $textstrokewidth = $this->textstrokewidth;
464
        $this->setTextRenderingMode(0, true, false);
465
        $this->SetXY($x, $y);
466
        $this->MultiCell($w, 0, $txt, $border, $align, $fill);
467
        // restore previous rendering mode
468
        $this->textrendermode = $textrendermode;
469
        $this->textstrokewidth = $textstrokewidth;
470
    }
471
472
}
473