Total Complexity | 227 |
Total Lines | 972 |
Duplicated Lines | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Complex classes like EasyTable often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use EasyTable, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class EasyTable |
||
12 | { |
||
13 | const LP=0.4; |
||
14 | const XPadding=1; |
||
15 | const YPadding=1; |
||
16 | const IMGPadding=0.5; |
||
17 | const PBThreshold=30; |
||
18 | static private $table_counter=false; |
||
19 | static private $style=array('width'=>false, 'border'=>false, 'border-color'=>false, |
||
20 | 'border-width'=>false, 'line-height'=>false, |
||
21 | 'align'=>'', 'valign'=>'', 'bgcolor'=>false, 'split-row'=>false, 'l-margin'=>false, |
||
22 | 'font-family'=>false, 'font-style'=>false,'font-size'=>false, 'font-color'=>false, |
||
23 | 'paddingX'=>false, 'paddingY'=>false); |
||
24 | private $pdf_obj; |
||
25 | private $document_style; |
||
26 | private $table_style; |
||
27 | private $col_num; |
||
28 | private $col_width; |
||
29 | private $baseX; |
||
30 | private $row_style_def; |
||
31 | private $row_style; |
||
32 | private $row_heights; |
||
33 | private $row_data; |
||
34 | private $rows; |
||
35 | private $total_rowspan; |
||
36 | private $col_counter; |
||
37 | private $grid; |
||
38 | private $blocks; |
||
39 | private $overflow; |
||
40 | private $header_row; |
||
41 | private $new_table; |
||
42 | |||
43 | private function get_available($colspan, $rowspan){ |
||
57 | } |
||
58 | |||
59 | private function get_style($str, $c){ |
||
60 | $result=self::$style; |
||
61 | if($c=='C'){ |
||
62 | $result['colspan']=0; |
||
63 | $result['rowspan']=0; |
||
64 | $result['img']=false; |
||
65 | } |
||
66 | if($c=='C' || $c=='R'){ |
||
67 | unset($result['width']); |
||
68 | unset($result['border-width']); |
||
69 | unset($result['split-row']); |
||
70 | unset($result['l-margin']); |
||
71 | } |
||
72 | if($c=='R' || $c=='T'){ |
||
73 | if($c=='R'){ |
||
74 | $result['c-align']=array_pad(array(), $this->col_num, 'L'); |
||
75 | } |
||
76 | else{ |
||
77 | $result['c-align']=array(); |
||
78 | } |
||
79 | } |
||
80 | if($c=='R'){ |
||
81 | $result['min-height']=false; |
||
82 | } |
||
83 | $tmp=explode(';', $str); |
||
84 | foreach($tmp as $x){ |
||
85 | if($x && strpos($x,':')>0){ |
||
86 | $r=explode(':',$x); |
||
87 | $r[0]=trim($r[0]); |
||
88 | $r[1]=trim($r[1]); |
||
89 | if(isset($result[$r[0]])){ |
||
90 | $result[$r[0]]=$r[1]; |
||
91 | } |
||
92 | } |
||
93 | } |
||
94 | return $result; |
||
95 | } |
||
96 | |||
97 | private function inherating(&$sty, $setting, $c){ |
||
98 | if($c=='C'){ |
||
99 | $sty[$setting]=$this->row_style[$setting]; |
||
100 | } |
||
101 | elseif($c=='R'){ |
||
102 | $sty[$setting]=$this->table_style[$setting]; |
||
103 | } |
||
104 | else{ |
||
105 | $sty[$setting]=$this->document_style[$setting]; |
||
106 | } |
||
107 | } |
||
108 | |||
109 | |||
110 | private function set_style($str, $c, $pos=''){ |
||
111 | $sty=$this->get_style($str, $c); |
||
112 | if($c=='T'){ |
||
113 | if(is_numeric($sty['width'])){ |
||
114 | $sty['width']=min(abs($sty['width']),$this->document_style['document_width']); |
||
115 | if($sty['width']==0){ |
||
116 | $sty['width']=$this->document_style['document_width']; |
||
117 | } |
||
118 | } |
||
119 | else{ |
||
120 | $x=strpos($sty['width'], '%'); |
||
121 | if($x!=false){ |
||
|
|||
122 | $x=min(abs(substr($sty['width'], 0, $x)), 100); |
||
123 | if($x){ |
||
124 | $sty['width']=$x*$this->document_style['document_width']/100.0; |
||
125 | } |
||
126 | else{ |
||
127 | $sty['width']=$this->document_style['document_width']; |
||
128 | } |
||
129 | } |
||
130 | else{ |
||
131 | $sty['width']=$this->document_style['document_width']; |
||
132 | } |
||
133 | } |
||
134 | if(!is_numeric($sty['l-margin'])){ |
||
135 | $sty['l-margin']=0; |
||
136 | } |
||
137 | else{ |
||
138 | $sty['l-margin']=abs($sty['l-margin']); |
||
139 | } |
||
140 | if(is_numeric($sty['border-width'])){ |
||
141 | $sty['border-width']=abs($sty['border-width']); |
||
142 | } |
||
143 | else{ |
||
144 | $sty['border-width']=false; |
||
145 | } |
||
146 | if($sty['split-row']=='false'){ |
||
147 | $sty['split-row']=false; |
||
148 | } |
||
149 | elseif($sty['split-row']!==false){ |
||
150 | $sty['split-row']=true; |
||
151 | } |
||
152 | } |
||
153 | if($c=='R'){ |
||
154 | if(!is_numeric($sty['min-height']) || $sty['min-height']<0){ |
||
155 | $sty['min-height']=0; |
||
156 | } |
||
157 | } |
||
158 | if(!is_numeric($sty['paddingX'])){ |
||
159 | if($c=='C' || $c=='R'){ |
||
160 | $this->inherating($sty, 'paddingX', $c); |
||
161 | } |
||
162 | else{ |
||
163 | $sty['paddingX']=self::XPadding; |
||
164 | } |
||
165 | } |
||
166 | $sty['paddingX']=abs($sty['paddingX']); |
||
167 | if(!is_numeric($sty['paddingY'])){ |
||
168 | if($c=='C' || $c=='R'){ |
||
169 | $this->inherating($sty, 'paddingY', $c); |
||
170 | } |
||
171 | else{ |
||
172 | $sty['paddingY']=self::YPadding; |
||
173 | } |
||
174 | } |
||
175 | $sty['paddingY']=abs($sty['paddingY']); |
||
176 | if($sty['border']===false && ($c=='C' || $c=='R')){ |
||
177 | $this->inherating($sty, 'border', $c); |
||
178 | } |
||
179 | else{ |
||
180 | $border=array('T'=>1, 'R'=>1, 'B'=>1, 'L'=>1); |
||
181 | if(!(is_numeric($sty['border']) && $sty['border']==1)){ |
||
182 | foreach($border as $k=>$v){ |
||
183 | $border[$k]=0; |
||
184 | if(strpos($sty['border'], $k)!==false){ |
||
185 | $border[$k]=1; |
||
186 | } |
||
187 | } |
||
188 | } |
||
189 | $sty['border']=$border; |
||
190 | } |
||
191 | $color_settings=array('bgcolor', 'font-color', 'border-color'); |
||
192 | foreach($color_settings as $setting){ |
||
193 | if($sty[$setting]===false || !($this->pdf_obj->is_hex($sty[$setting]) || $this->pdf_obj->is_rgb($sty[$setting]))){ |
||
194 | if($c=='C' || $c=='R'){ |
||
195 | $this->inherating($sty, $setting, $c); |
||
196 | } |
||
197 | elseif($setting=='font-color'){ |
||
198 | $sty[$setting]=$this->document_style[$setting]; |
||
199 | } |
||
200 | } |
||
201 | else{ |
||
202 | $sty[$setting]=$sty[$setting]; |
||
203 | } |
||
204 | } |
||
205 | $font_settings=array('font-family', 'font-style', 'font-size'); |
||
206 | foreach($font_settings as $setting){ |
||
207 | if($sty[$setting]===false){ |
||
208 | $this->inherating($sty, $setting, $c); |
||
209 | } |
||
210 | } |
||
211 | if(is_numeric($sty['line-height'])){ |
||
212 | $sty['line-height']=self::LP*abs($sty['line-height']); |
||
213 | } |
||
214 | else{ |
||
215 | if($c=='C' || $c=='R'){ |
||
216 | $this->inherating($sty,'line-height', $c); |
||
217 | } |
||
218 | else{ |
||
219 | $sty['line-height']=self::LP; |
||
220 | } |
||
221 | } |
||
222 | if($c=='C'){ |
||
223 | if($sty['img']){ |
||
224 | $tmp=explode(',', $sty['img']); |
||
225 | if(file_exists($tmp[0])){ |
||
226 | $sty['img']=array('path'=>'', 'h'=>0, 'w'=>0); |
||
227 | $img=@ getimagesize($tmp[0]); |
||
228 | $sty['img']['path']=$tmp[0]; |
||
229 | for($i=1; $i<3; $i++){ |
||
230 | if(isset($tmp[$i])){ |
||
231 | $tmp[$i]=trim(strtolower($tmp[$i])); |
||
232 | if($tmp[$i][0]=='w' || $tmp[$i][0]=='h'){ |
||
233 | $t=substr($tmp[$i],1); |
||
234 | if(is_numeric($t)){ |
||
235 | $sty['img'][$tmp[$i][0]]=abs($t); |
||
236 | } |
||
237 | } |
||
238 | } |
||
239 | } |
||
240 | $ration=$img[0]/$img[1]; |
||
241 | if($sty['img']['w']+$sty['img']['h']==0){ |
||
242 | $sty['img']['w']=$img[0]; |
||
243 | $sty['img']['h']=$img[1]; |
||
244 | } |
||
245 | elseif($sty['img']['w']==0){ |
||
246 | $sty['img']['w']=$sty['img']['h']*$ration; |
||
247 | } |
||
248 | elseif($sty['img']['h']==0){ |
||
249 | $sty['img']['h']=$sty['img']['w']/$ration; |
||
250 | } |
||
251 | } |
||
252 | else{ |
||
253 | $sty['img']='failed to open stream: file ' . $tmp[0] .' does not exist'; |
||
254 | } |
||
255 | } |
||
256 | if(is_numeric($sty['colspan']) && $sty['colspan']>0){ |
||
257 | $sty['colspan']--; |
||
258 | } |
||
259 | else{ |
||
260 | $sty['colspan']=0; |
||
261 | } |
||
262 | if(is_numeric($sty['rowspan']) && $sty['rowspan']>0){ |
||
263 | $sty['rowspan']--; |
||
264 | } |
||
265 | else{ |
||
266 | $sty['rowspan']=0; |
||
267 | } |
||
268 | if($sty['valign']==false && ($sty['rowspan']>0 || $sty['img']!==false)){ |
||
269 | $sty['valign']='M'; |
||
270 | } |
||
271 | if($sty['align']==false && $sty['img']!==false){ |
||
272 | $sty['align']='C'; |
||
273 | } |
||
274 | } |
||
275 | if($c=='T' || $c=='R'){ |
||
276 | $tmp=explode('{',$sty['align']); |
||
277 | if($c=='T'){ |
||
278 | $sty['align']=trim($tmp[0]); |
||
279 | } |
||
280 | if(isset($tmp[1])){ |
||
281 | $tmp[1]=trim($tmp[1], '}'); |
||
282 | if(strlen($tmp[1])){ |
||
283 | for($i=0; $i<strlen($tmp[1]); $i++){ |
||
284 | if(preg_match("/[LCRJ]/", $tmp[1][$i])!=0){ |
||
285 | $sty['c-align'][$i]=$tmp[1][$i]; |
||
286 | } |
||
287 | else{ |
||
288 | $sty['c-align'][$i]='L'; |
||
289 | } |
||
290 | } |
||
291 | } |
||
292 | if($c=='R'){ |
||
293 | $sty['align']='L'; |
||
294 | $sty['c-align']=array_slice($sty['c-align'],0,$this->col_num); |
||
295 | } |
||
296 | } |
||
297 | } |
||
298 | if($sty['align']!='L' && $sty['align']!='C' && $sty['align']!='R' && $sty['align']!='J'){ |
||
299 | if($c=='C'){ |
||
300 | $sty['align']=$this->row_style['c-align'][$pos]; |
||
301 | } |
||
302 | elseif($c=='R'){ |
||
303 | $sty['align']='L'; |
||
304 | $sty['c-align']=$this->table_style['c-align']; |
||
305 | } |
||
306 | else{ |
||
307 | $sty['align']='C'; |
||
308 | } |
||
309 | } |
||
310 | elseif($c=='T' && $sty['align']=='J'){ |
||
311 | $sty['align']='C'; |
||
312 | } |
||
313 | if($sty['valign']!='T' && $sty['valign']!='M' && $sty['valign']!='B'){ |
||
314 | if($c=='C' || $c=='R'){ |
||
315 | $this->inherating($sty, 'valign', $c); |
||
316 | } |
||
317 | else{ |
||
318 | $sty['valign']='T'; |
||
319 | } |
||
320 | } |
||
321 | return $sty; |
||
322 | } |
||
323 | |||
324 | private function row_content_loop($counter, $f){ |
||
325 | $t=0; |
||
326 | if($counter>0){ |
||
327 | $t=$this->rows[$counter-1]; |
||
328 | } |
||
329 | for($index=$t; $index<$this->rows[$counter]; $index++){ |
||
330 | $f($index); |
||
331 | } |
||
332 | } |
||
333 | |||
334 | private function mk_border($i, $y, $split){ |
||
335 | $w=$this->row_data[$i][2]; |
||
336 | $h=$this->row_data[$i][5]; |
||
337 | if($split){ |
||
338 | $h=$this->pdf_obj->PageBreak()-$y; |
||
339 | } |
||
340 | if($this->row_data[$i][1]['border-color']!=false){ |
||
341 | $this->pdf_obj->resetColor($this->row_data[$i][1]['border-color'], 'D'); |
||
342 | } |
||
343 | $a=array(1, 1, 1, 0); |
||
344 | $borders=array('L'=>3, 'T'=>0, 'R'=>1, 'B'=>2); |
||
345 | foreach($borders as $border=>$j){ |
||
346 | if($this->row_data[$i][1]['border'][$border]){ |
||
347 | if($border=='B'){ |
||
348 | if($split==0){ |
||
349 | $this->pdf_obj->Line($this->row_data[$i][6]+(1+$a[($j+2)%4])%2*$w, $y+(1+$a[($j+1)%4])%2 * $h, $this->row_data[$i][6]+$a[$j%4]*$w, $y+($a[($j+3)%4])%2 *$h); |
||
350 | } |
||
351 | } |
||
352 | else{ |
||
353 | $this->pdf_obj->Line($this->row_data[$i][6]+(1+$a[($j+2)%4])%2*$w, $y+(1+$a[($j+1)%4])%2 * $h, $this->row_data[$i][6]+$a[$j%4]*$w, $y+($a[($j+3)%4])%2 *$h); |
||
354 | } |
||
355 | } |
||
356 | } |
||
357 | |||
358 | if($this->row_data[$i][1]['border-color']!=false){ |
||
359 | $this->pdf_obj->resetColor($this->document_style['bgcolor'], 'D'); |
||
360 | } |
||
361 | if($split){ |
||
362 | $this->pdf_obj->row_data[$i][1]['border']['T']=0; |
||
363 | } |
||
364 | } |
||
365 | |||
366 | private function print_text($i, $y, $split){ |
||
367 | $padding=$this->row_data[$i][1]['padding-y']; |
||
368 | $k=$padding; |
||
369 | if($this->row_data[$i][1]['img']!==false){ |
||
370 | if($this->row_data[$i][1]['valign']=='B'){ |
||
371 | $k+=$this->row_data[$i][1]['img']['h']+self::IMGPadding; |
||
372 | } |
||
373 | } |
||
374 | $l=0; |
||
375 | if(count($this->row_data[$i][0])){ |
||
376 | $x=$this->row_data[$i][6]+$this->row_data[$i][1]['paddingX']; |
||
377 | $xpadding=2*$this->row_data[$i][1]['paddingX']; |
||
378 | $l=count($this->row_data[$i][0])* $this->row_data[$i][1]['line-height']*$this->row_data[$i][1]['font-size']; |
||
379 | $this->pdf_obj->SetXY($x, $y+$k); |
||
380 | $this->pdf_obj->CellBlock($this->row_data[$i][2]-$xpadding, $this->row_data[$i][1]['line-height'], $this->row_data[$i][0], $this->row_data[$i][1]['align']); |
||
381 | $this->pdf_obj->resetFont($this->document_style['font-family'], $this->document_style['font-style'], $this->document_style['font-size']); |
||
382 | $this->pdf_obj->resetColor($this->document_style['font-color'], 'T'); |
||
383 | } |
||
384 | if($this->row_data[$i][1]['img']!==false ){ |
||
385 | $x=$this->row_data[$i][6]; |
||
386 | $k=$padding; |
||
387 | if($this->row_data[$i][1]['valign']!='B'){ |
||
388 | $k+=$l+self::IMGPadding; |
||
389 | } |
||
390 | if($this->imgbreak($i, $y)==0 && $y+$k+$this->row_data[$i][1]['img']['h']<$this->pdf_obj->PageBreak()){ |
||
391 | $x+=$this->row_data[$i][1]['paddingX']; |
||
392 | if($this->row_data[$i][2]>$this->row_data[$i][1]['img']['w']){ |
||
393 | if($this->row_data[$i][1]['align']=='C'){ |
||
394 | $x-=$this->row_data[$i][1]['paddingX']; |
||
395 | $x+=($this->row_data[$i][2]-$this->row_data[$i][1]['img']['w'])/2; |
||
396 | } |
||
397 | elseif($this->row_data[$i][1]['align']=='R'){ |
||
398 | $x+=$this->row_data[$i][2]-$this->row_data[$i][1]['img']['w']; |
||
399 | $x-=2*$this->row_data[$i][1]['paddingX']; |
||
400 | } |
||
401 | } |
||
402 | $this->pdf_obj->Image($this->row_data[$i][1]['img']['path'], $x, $y+$k, $this->row_data[$i][1]['img']['w'], $this->row_data[$i][1]['img']['h']); |
||
403 | } |
||
404 | } |
||
405 | } |
||
406 | |||
407 | |||
408 | private function mk_bg($i, $T, $split){ |
||
409 | $h=$this->row_data[$i][5]; |
||
410 | if($split){ |
||
411 | $h=$this->pdf_obj->PageBreak()-$T; |
||
412 | } |
||
413 | if($this->row_data[$i][1]['bgcolor']!=false){ |
||
414 | $this->pdf_obj->resetColor($this->row_data[$i][1]['bgcolor']); |
||
415 | $this->pdf_obj->Rect($this->row_data[$i][6], $T, $this->row_data[$i][2], $h, 'F'); |
||
416 | $this->pdf_obj->resetColor($this->document_style['bgcolor']); |
||
417 | } |
||
418 | } |
||
419 | |||
420 | private function printing_loop($swap=false){ |
||
421 | $this->swap_data($swap); |
||
422 | $y=$this->pdf_obj->GetY(); |
||
423 | $tmp=array(); |
||
424 | $rw=array(); |
||
425 | $ztmp=array(); |
||
426 | $total_cells=count($this->row_data); |
||
427 | while(count($tmp)!=$total_cells){ |
||
428 | $a=count($this->rows); |
||
429 | $h=0; |
||
430 | $y=$this->pdf_obj->GetY(); |
||
431 | for($j=0; $j<count($this->rows); $j++){ |
||
432 | $T=$y+$h; |
||
433 | if($T<$this->pdf_obj->PageBreak()){ |
||
434 | |||
435 | $this->row_content_loop($j, function($index)use($T, $tmp){ |
||
436 | if(!isset($tmp[$index])){ |
||
437 | $split_cell=$this->scan_for_breaks($index,$T, false); |
||
438 | $this->mk_bg($index, $T, $split_cell); |
||
439 | } |
||
440 | }); |
||
441 | if(!isset($rw[$j])){ |
||
442 | if($this->pdf_obj->PageBreak()-($T+$this->row_heights[$j])>=0){ |
||
443 | $h+=$this->row_heights[$j]; |
||
444 | } |
||
445 | else{ |
||
446 | $a=$j+1; |
||
447 | break; |
||
448 | } |
||
449 | } |
||
450 | } |
||
451 | else{ |
||
452 | $a=$j+1; |
||
453 | break; |
||
454 | } |
||
455 | } |
||
456 | $h=0; |
||
457 | for($j=0; $j<$a; $j++){ |
||
458 | $T=$y+$h; |
||
459 | if($T<$this->pdf_obj->PageBreak()){ |
||
460 | |||
461 | $this->row_content_loop($j, function($index)use($T, &$tmp, &$ztmp){ |
||
462 | if(!isset($tmp[$index])){ |
||
463 | $split_cell=$this->scan_for_breaks($index,$T); |
||
464 | $this->mk_border($index, $T, $split_cell); |
||
465 | $this->print_text($index, $T, $split_cell); |
||
466 | if($split_cell==0){ |
||
467 | $tmp[$index]=$index; |
||
468 | } |
||
469 | else{ |
||
470 | $ztmp[]=$index; |
||
471 | } |
||
472 | } |
||
473 | }); |
||
474 | if(!isset($rw[$j])){ |
||
475 | $tw=$this->pdf_obj->PageBreak()-($T+$this->row_heights[$j]); |
||
476 | if($tw>=0){ |
||
477 | $h+=$this->row_heights[$j]; |
||
478 | $rw[$j]=$j; |
||
479 | } |
||
480 | else{ |
||
481 | $this->row_heights[$j]=$this->overflow-$tw; |
||
482 | } |
||
483 | } |
||
484 | } |
||
485 | } |
||
486 | if(count($tmp)!=$total_cells){ |
||
487 | foreach($ztmp as $index){ |
||
488 | $this->row_data[$index][5]=$this->row_data[$index][7]+$this->overflow; |
||
489 | if(isset($this->row_data[$index][8])){ |
||
490 | $this->row_data[$index][1]['padding-y']=$this->row_data[$index][8]; |
||
491 | unset($this->row_data[$index][8]); |
||
492 | } |
||
493 | } |
||
494 | $this->overflow=0; |
||
495 | $ztmp=array(); |
||
496 | $this->pdf_obj->addPage($this->document_style['orientation']); |
||
497 | } |
||
498 | else{ |
||
499 | $y+=$h; |
||
500 | } |
||
501 | } |
||
502 | $this->pdf_obj->SetXY($this->baseX, $y); |
||
503 | $this->swap_data($swap); |
||
504 | } |
||
505 | |||
506 | private function imgbreak($i, $y){ |
||
507 | $li=$y+$this->row_data[$i][1]['padding-y']; |
||
508 | $ls=$this->row_data[$i][1]['img']['h']; |
||
509 | if($this->row_data[$i][1]['valign']=='B'){ |
||
510 | $ls+=$li; |
||
511 | } |
||
512 | else{ |
||
513 | $li+=$this->row_data[$i][3]-$this->row_data[$i][1]['img']['h']; |
||
514 | $ls+=$li; |
||
515 | } |
||
516 | $result=0; |
||
517 | if($li<$this->pdf_obj->PageBreak() && $this->pdf_obj->PageBreak()<$ls){ |
||
518 | $result=$this->pdf_obj->PageBreak()-$li; |
||
519 | } |
||
520 | return $result; |
||
521 | } |
||
522 | |||
523 | private function scan_for_breaks($index, $H, $l=true){ |
||
524 | $print_cell=0; |
||
525 | $h=($H+$this->row_data[$index][5])-$this->pdf_obj->PageBreak(); |
||
526 | if($h>0){ |
||
527 | if($l){ |
||
528 | $rr=$this->pdf_obj->PageBreak()-($H+$this->row_data[$index][1]['padding-y']); |
||
529 | if($rr>0){ |
||
530 | $mx=0; |
||
531 | if(count($this->row_data[$index][0]) && $this->row_data[$index][1]['img']!==false){ |
||
532 | $mx=$this->imgbreak($index, $H); |
||
533 | if($mx==0){ |
||
534 | if($this->row_data[$index][1]['valign']=='B'){ |
||
535 | $rr-=$this->row_data[$index][1]['img']['h']; |
||
536 | } |
||
537 | } |
||
538 | } |
||
539 | $nh=0; |
||
540 | $keys=array_keys($this->row_data[$index][0]); |
||
541 | foreach($keys as $i){ |
||
542 | $nh+=$this->row_data[$index][0][$i]['height']; |
||
543 | } |
||
544 | $nh*=$this->row_data[$index][1]['line-height']; |
||
545 | if($mx==0 && $rr<$nh){ |
||
546 | $nw=0; |
||
547 | foreach($keys as $i){ |
||
548 | $nw+=$this->row_data[$index][0][$i]['height']*$this->row_data[$index][1]['line-height']; |
||
549 | if($nw>$rr){ |
||
550 | $nw-=$this->row_data[$index][0][$i]['height']*$this->row_data[$index][1]['line-height']; |
||
551 | $mx=$rr-$nw; |
||
552 | break; |
||
553 | } |
||
554 | } |
||
555 | } |
||
556 | $this->overflow=max($this->overflow, $mx); |
||
557 | $this->row_data[$index][8]=1; |
||
558 | } |
||
559 | else{ |
||
560 | $this->row_data[$index][8]=-1*$rr; |
||
561 | } |
||
562 | $this->row_data[$index][7]=$h; |
||
563 | } |
||
564 | $print_cell=1; |
||
565 | } |
||
566 | return $print_cell; |
||
567 | } |
||
568 | |||
569 | private function swap_data($swap){ |
||
570 | if($swap==false){ |
||
571 | return; |
||
572 | } |
||
573 | static $data=array(); |
||
574 | if(count($data)==0){ |
||
575 | $data=array('header_data'=>$this->header_row['row_data'], 'row_heights'=>&$this->row_heights, 'row_data'=>&$this->row_data, 'rows'=>&$this->rows); |
||
576 | unset($this->row_heights, $this->row_data, $this->rows); |
||
577 | $this->row_heights=&$this->header_row['row_heights']; |
||
578 | $this->row_data=&$this->header_row['row_data']; |
||
579 | $this->rows=&$this->header_row['rows']; |
||
580 | } |
||
581 | else{ |
||
582 | $this->header_row['row_data']=$data['header_data']; |
||
583 | unset($this->row_heights, $this->row_data, $this->rows); |
||
584 | $this->row_heights=$data['row_heights']; |
||
585 | $this->row_data=$data['row_data']; |
||
586 | $this->rows=$data['rows']; |
||
587 | $data=array(); |
||
588 | } |
||
589 | } |
||
590 | /******************************************************************** |
||
591 | |||
592 | function __construct( FPDF-object $fpdf_obj, Mix $num_cols[, string $style = '' ]) |
||
593 | ----------------------------------------------------- |
||
594 | Description: |
||
595 | Constructs an easyTable object |
||
596 | Parameters: |
||
597 | fpdf_obj |
||
598 | the current FPDF object (constructed with the FPDF library) |
||
599 | that is being used to write the current PDF document |
||
600 | num_cols |
||
601 | this parameter can be a positive integer (the number of columns) |
||
602 | or a string of the following form |
||
603 | I) a positive integer, the number of columns for the table. The width |
||
604 | of every column will be equal to the width of the table (given by the width property) |
||
605 | divided by the number of columns ($num_cols) |
||
606 | II) a string of the form '{c1, c2, c3,... cN}'. In this case every |
||
607 | element in the curly brackets is a positive numeric value that represent |
||
608 | the width of a column. Thus, the n-th numeric value is the width |
||
609 | of the n-th colum. If the sum of all the width of the columns is bigger than |
||
610 | the width of the table but less than the width of the document, the table |
||
611 | will stretch to the sum of the columns width. However, if the sum of the |
||
612 | columns is bigger than the width of the document, the width of every column |
||
613 | will be reduce proportionally to make the total sum equal to the width of the document. |
||
614 | III) a string of the form '%{c1, c2, c3,... cN}'. Similar to the previous case, but |
||
615 | this time every element represents a percentage of the width of the table. |
||
616 | In this case it the sum of this percentages is bigger than 100, the execution will |
||
617 | be terminated. |
||
618 | style |
||
619 | the global style for the table (see documentation) |
||
620 | a semicolon-separated string of attribute values that defines the |
||
621 | default layout of the table and all the cells and their contents |
||
622 | (see Documentation section in README.md) |
||
623 | Examples: |
||
624 | $table= new easyTable($fpdf, 3); |
||
625 | $table= new easyTable($fpdf, '{35, 45, 55}', 'width:135;'); |
||
626 | $table= new easyTable($fpdf, '%{35, 45, 55}', 'width:190;'); |
||
627 | Return value: |
||
628 | An easyTable object |
||
629 | ***********************************************************************/ |
||
630 | |||
631 | public function __construct($fpdf_obj, $num_cols, $style=''){ |
||
632 | if(self::$table_counter){ |
||
633 | error_log('Please use the end_table method to terminate the last table'); |
||
634 | exit(); |
||
635 | } |
||
636 | self::$table_counter=true; |
||
637 | $this->pdf_obj=&$fpdf_obj; |
||
638 | $this->document_style['bgcolor']=$this->pdf_obj->get_color('fill'); |
||
639 | $this->document_style['font-family']=$this->pdf_obj->current_font('family'); |
||
640 | $this->document_style['font-style']=$this->pdf_obj->current_font('style'); |
||
641 | $this->document_style['font-size']=$this->pdf_obj->current_font('size'); |
||
642 | $this->document_style['font-color']=$this->pdf_obj->get_color('text'); |
||
643 | $this->document_style['document_width']=$this->pdf_obj->GetPageWidth()-$this->pdf_obj->get_margin('l')-$this->pdf_obj->get_margin('r'); |
||
644 | $this->document_style['orientation']=$this->pdf_obj->get_orientation(); |
||
645 | $this->document_style['line-width']=$this->pdf_obj->get_linewidth(); |
||
646 | $this->table_style=$this->set_style($style, 'T'); |
||
647 | $this->col_num=false; |
||
648 | $this->col_width=array(); |
||
649 | if(is_int($num_cols) && $num_cols!=0){ |
||
650 | $this->col_num=abs($num_cols); |
||
651 | $this->col_width=array_pad(array(), abs($num_cols), $this->table_style['width']/abs($num_cols)); |
||
652 | } |
||
653 | elseif(is_string($num_cols)){ |
||
654 | $num_cols=trim($num_cols, '}, '); |
||
655 | if($num_cols[0]!='{' && $num_cols[0]!='%'){ |
||
656 | error_log('Bad format for columns in Table constructor'); |
||
657 | exit(); |
||
658 | } |
||
659 | $tmp=explode('{', $num_cols); |
||
660 | $tp=trim($tmp[0]); |
||
661 | $num_cols=explode(',', $tmp[1]); |
||
662 | $w=0; |
||
663 | foreach($num_cols as $c){ |
||
664 | if(!is_numeric($c)){ |
||
665 | error_log('Bad parameter format for columns in Table constructor'); |
||
666 | exit(); |
||
667 | } |
||
668 | if(abs($c)){ |
||
669 | $w+=abs($c); |
||
670 | $this->col_width[]=abs($c); |
||
671 | } |
||
672 | else{ |
||
673 | error_log('Column width can not be zero'); |
||
674 | } |
||
675 | } |
||
676 | $this->col_num=count($this->col_width); |
||
677 | if($tp=='%'){ |
||
678 | if($w!=100){ |
||
679 | error_log('The sum of the percentages of the columns is not 100'); |
||
680 | exit(); |
||
681 | } |
||
682 | foreach($this->col_width as $i=>$c){ |
||
683 | $this->col_width[$i]=$c*$this->table_style['width']/100; |
||
684 | } |
||
685 | } |
||
686 | elseif($w!=$this->table_style['width'] && $w){ |
||
687 | if($w<$this->document_style['document_width']){ |
||
688 | $this->table_style['width']=$w; |
||
689 | } |
||
690 | else{ |
||
691 | $this->table_style['width']=$this->document_style['document_width']; |
||
692 | $d=$this->table_style['width']/$w; |
||
693 | for($i=0; $i<count($num_cols); $i++){ |
||
694 | $this->col_width[$i]*=$d; |
||
695 | } |
||
696 | } |
||
697 | } |
||
698 | } |
||
699 | if($this->col_num==false){ |
||
700 | error_log('Unspecified number of columns in Table constructor'); |
||
701 | exit(); |
||
702 | } |
||
703 | $this->table_style['c-align']=array_pad($this->table_style['c-align'], $this->col_num, 'L'); |
||
704 | if($this->table_style['l-margin']){ |
||
705 | $this->baseX=$this->pdf_obj->get_margin('l')+min($this->table_style['l-margin'],$this->document_style['document_width']-$this->table_style['width']); |
||
706 | } |
||
707 | else{ |
||
708 | if($this->table_style['align']=='L'){ |
||
709 | $this->baseX=$this->pdf_obj->get_margin('l'); |
||
710 | } |
||
711 | elseif($this->table_style['align']=='R'){ |
||
712 | $this->baseX=$this->pdf_obj->get_margin('l')+$this->document_style['document_width']-$this->table_style['width']; |
||
713 | } |
||
714 | else{ |
||
715 | $this->baseX=$this->pdf_obj->get_margin('l')+($this->document_style['document_width']-$this->table_style['width'])/2; |
||
716 | } |
||
717 | } |
||
718 | $this->row_style_def=$this->set_style('', 'R'); |
||
719 | $this->row_style=$this->row_style_def; |
||
720 | $this->row_heights=array(); |
||
721 | $this->row_data=array(); |
||
722 | $this->rows=array(); |
||
723 | $this->total_rowspan=0; |
||
724 | $this->col_counter=0; |
||
725 | $this->grid=array(); |
||
726 | $this->blocks=array(); |
||
727 | $this->overflow=0; |
||
728 | if($this->table_style['border-width']!=false){ |
||
729 | $this->pdf_obj->SetLineWidth($this->table_style['border-width']); |
||
730 | } |
||
731 | $this->header_row=array(); |
||
732 | $this->new_table=true; |
||
733 | } |
||
734 | /*********************************************************************** |
||
735 | |||
736 | function rowStyle( string $style ) |
||
737 | ------------------------------------------------------------- |
||
738 | Description: |
||
739 | Set or overwrite the style for all the cells in the current row. |
||
740 | Parameters: |
||
741 | style |
||
742 | a semicolon-separated string of attribute values that defines the |
||
743 | layout of all the cells and its content in the current row |
||
744 | (see Documentation section in README.md) |
||
745 | Return values |
||
746 | Void |
||
747 | Notes: |
||
748 | |||
749 | This function should be called before the first cell of the current row |
||
750 | ***********************************************************************/ |
||
751 | |||
752 | public function rowStyle($style){ |
||
753 | $this->row_style=$this->set_style($style, 'R'); |
||
754 | } |
||
755 | /*********************************************************************** |
||
756 | |||
757 | function easyCell( string $data [, string $style = '' ]) |
||
758 | ------------------------------------------------------------------------ |
||
759 | Description: |
||
760 | Makes a cell in the table |
||
761 | Parameters: |
||
762 | data |
||
763 | the content of the respective cell |
||
764 | style (optional) |
||
765 | a semicolon-separated string of attribute values that defines the |
||
766 | layout of the cell and its content (see Documentation section in README.md) |
||
767 | Return value |
||
768 | void |
||
769 | ***********************************************************************/ |
||
770 | |||
771 | public function easyCell($data, $style=''){ |
||
772 | if($this->col_counter<$this->col_num){ |
||
773 | $sty=$this->set_style($style, 'C', $this->col_counter); |
||
774 | $this->col_counter++; |
||
775 | $row_number=count($this->rows); |
||
776 | $cell_index=count($this->row_data); |
||
777 | $cell_pos=$this->get_available($sty['colspan'], $sty['rowspan']); |
||
778 | $colm=$cell_pos %$this->col_num; |
||
779 | if($sty['img']!=false && $data!='' && $sty['valign']=='M'){ |
||
780 | $sty['valign']=$this->row_style['valign']; |
||
781 | } |
||
782 | if($sty['rowspan']){ |
||
783 | $this->total_rowspan=max($this->total_rowspan, $sty['rowspan']); |
||
784 | $this->blocks[$cell_index]=array($cell_index, $row_number, $sty['rowspan']); |
||
785 | } |
||
786 | $w=$this->col_width[$colm]; |
||
787 | $r=0; |
||
788 | while($r<$sty['colspan'] && $this->col_counter<$this->col_num){ |
||
789 | $this->col_counter++; |
||
790 | $colm++; |
||
791 | $w+=$this->col_width[$colm]; |
||
792 | $r++; |
||
793 | } |
||
794 | $w-=2*$sty['paddingX']; |
||
795 | if($sty['img']!==false && is_string($sty['img'])){ |
||
796 | $data=$sty['img']; |
||
797 | $sty['img']=false; |
||
798 | } |
||
799 | $data=& $this->pdf_obj->extMultiCell($sty['font-family'], $sty['font-style'], $sty['font-size'], $sty['font-color'], $w, $data); |
||
800 | $h=0; |
||
801 | $rn=count($data); |
||
802 | for($ri=0; $ri<$rn; $ri++){ |
||
803 | $h+=$data[$ri]['height']*$sty['line-height']; |
||
804 | } |
||
805 | if($sty['img']){ |
||
806 | if($sty['img']['w']>$w){ |
||
807 | $sty['img']['h']=$w*$sty['img']['h']/$sty['img']['w']; |
||
808 | $sty['img']['w']=$w; |
||
809 | } |
||
810 | if($h){ |
||
811 | $h+=self::IMGPadding; |
||
812 | } |
||
813 | $h+=$sty['img']['h']; |
||
814 | } |
||
815 | $w+=2*$sty['paddingX']; |
||
816 | |||
817 | $posx=$this->baseX; |
||
818 | $d=$cell_pos %$this->col_num; |
||
819 | for($k=0; $k<$d; $k++){ |
||
820 | $posx+=$this->col_width[$k]; |
||
821 | } |
||
822 | $this->row_data[$cell_index]=array($data, $sty, $w, $h, $cell_pos, 0, $posx, 0); |
||
823 | |||
824 | } |
||
825 | } |
||
826 | /*********************************************************************** |
||
827 | |||
828 | function printRow ( [ bool $setAsHeader = false ] ) |
||
829 | ------------------------------------------------------------------------ |
||
830 | Description: |
||
831 | |||
832 | This function indicates the end of the current row. |
||
833 | Parameters: |
||
834 | setAsHeader (optional) |
||
835 | Optional. When it is set as true, it sets the current row as the header |
||
836 | for the table; this means that the current row will be printed as the first |
||
837 | row of the table (table header) on every page that the table splits on. |
||
838 | Remark: 1. In order to work, the table attribute split-row should set as true. |
||
839 | 2. Just the first row where this parameter is set as true will be |
||
840 | used as header any other will printed as a normal row. |
||
841 | Return values |
||
842 | Void |
||
843 | Note: |
||
844 | |||
845 | This function will print the current row as far as the following holds: |
||
846 | total_rowspan=0 |
||
847 | where total_rowspan is set as |
||
848 | total_rowspan=max(total_rowspan, max(rowspan of cell in the current row))-1; |
||
849 | ***********************************************************************/ |
||
850 | |||
851 | public function printRow($setAsHeader=false){ |
||
941 | } |
||
942 | /*********************************************************************** |
||
943 | |||
944 | function endTable( [int $bottomMargin=2]) |
||
945 | ------------------------------------------ |
||
946 | Description: |
||
947 | Unset all the data members of the easyTable object |
||
948 | Parameters: |
||
949 | bottomMargin (optional) |
||
950 | Optional. Specify the number of white lines left after |
||
951 | the last row of the table. Default 2. |
||
952 | If it is negative, the vertical position will be set before |
||
953 | the end of the table. |
||
954 | Return values |
||
955 | Void |
||
956 | ***********************************************************************/ |
||
957 | |||
958 | public function endTable($bottomMargin=2){ |
||
987 |