Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
40.38% covered (warning)
40.38%
21 / 52
CRAP
54.72% covered (warning)
54.72%
168 / 307
TElement
0.00% covered (danger)
0.00%
0 / 1
40.38% covered (warning)
40.38%
21 / 52
3428.69
54.58% covered (warning)
54.58%
167 / 306
 __construct
0.00% covered (danger)
0.00%
0 / 1
6.04
90.00% covered (success)
90.00%
9 / 10
 __set
0.00% covered (danger)
0.00%
0 / 1
6.40
77.78% covered (success)
77.78%
7 / 9
 setProperty
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 setAttribute
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getAttribute
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 getProperty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 __get
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 setQuotes
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
11 / 11
 safehtml
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 6
 removeIllegalChars
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
6 / 6
 removeIllegalCharsv2
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 10
 add
0.00% covered (danger)
0.00%
0 / 1
8.30
83.33% covered (success)
83.33%
10 / 12
 addOnTop
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
5 / 5
 getChildren
0.00% covered (danger)
0.00%
0 / 1
2.15
66.67% covered (warning)
66.67%
2 / 3
 open
0.00% covered (danger)
0.00%
0 / 1
41.88
70.00% covered (success)
70.00%
28 / 40
 close
0.00% covered (danger)
0.00%
0 / 1
16.51
64.29% covered (warning)
64.29%
9 / 14
 subShowCss
0.00% covered (danger)
0.00%
0 / 1
33.84
18.18% covered (danger)
18.18%
2 / 11
 subShowEvents
0.00% covered (danger)
0.00%
0 / 1
7.46
40.00% covered (warning)
40.00%
2 / 5
 subShowChildren
0.00% covered (danger)
0.00%
0 / 1
90
0.00% covered (danger)
0.00%
0 / 14
 show
0.00% covered (danger)
0.00%
0 / 1
13.15
73.91% covered (success)
73.91%
17 / 23
 setTagType
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getTagType
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setClass
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 getClass
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setEvent
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 8
 setEvents
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 addEvent
0.00% covered (danger)
0.00%
0 / 1
5.27
77.78% covered (success)
77.78%
7 / 9
 getEvent
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 5
 getEvents
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 clearEvents
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getIdent
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 clearChildren
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 setId
0.00% covered (danger)
0.00%
0 / 1
4.13
80.00% covered (success)
80.00%
4 / 5
 setName
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
4 / 4
 getName
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getId
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 clearCss
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getBase
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
8 / 8
 getRoot
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 setValue
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getValue
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setParentControl
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getParentControl
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 getTopMostParent
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 3
 setXY
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 5
 getRandomChars
0.00% covered (danger)
0.00%
0 / 1
12
0.00% covered (danger)
0.00%
0 / 3
 getIndexFileName
0.00% covered (danger)
0.00%
0 / 1
72
0.00% covered (danger)
0.00%
0 / 13
 addWarning
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 3
 getWarnings
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 specialChars2htmlEntities
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 4
 utf8_encode_array
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 6
 decodeUtf8
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 5
 setCss
n/a
0 / 0
5
n/a
0 / 0
 getCss
n/a
0 / 0
3
n/a
0 / 0
1<?php
2/*
3 * Formdin Framework
4 * Copyright (C) 2012 Ministério do Planejamento
5 * Criado por Luís Eugênio Barbosa
6 * Essa versão é um Fork https://github.com/bjverde/formDin
7 *
8 * ----------------------------------------------------------------------------
9 * This file is part of Formdin Framework.
10 *
11 * Formdin Framework is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License version 3
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License version 3
21 * along with this program; if not,  see <http://www.gnu.org/licenses/>
22 * or write to the Free Software Foundation, Inc., 51 Franklin Street,
23 * Fifth Floor, Boston, MA  02110-1301, USA.
24 * ----------------------------------------------------------------------------
25 * Este arquivo é parte do Framework Formdin.
26 *
27 * O Framework Formdin é um software livre; você pode redistribuí-lo e/ou
28 * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
29 * do Software Livre (FSF).
30 *
31 * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
32 * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
33 * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
34 * para maiores detalhes.
35 *
36 * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
37 * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/>
38 * ou escreva para a Fundação do Software Livre (FSF) Inc.,
39 * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
40 */
41
42//error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
43$GLOBALS[ 'teste' ] = true; // deixar as quebras de linha e a identação do html
44
45/**
46 * Esta classe representa qualquer elemento HTML criado atraves de tag de abertura e fechamento
47 * Ex: <input> <br> <p> <h1> etc...
48 *
49 * Estrutura básica
50 * <tagType class="" style="">x y z</tagType>
51 */
52class TElement
53{
54    /**
55     * Armazenar o caminho do diretório base/
56     * @var string
57     */
58    
59    static public $base;
60    /**
61     * Controla a identacao do html gerado
62     *
63     * @var integer $depth
64     */
65    static private $depth;
66    /**
67     * Array com as mensagens de advertências encontradas durante o processamento
68     *
69     * @var array $warnings
70     */
71    static public $warnings;
72    //   $this->depth++;
73    /**
74     * Tipo da tag que sera criada. Ex: div, table, span
75     *
76     * @var string $tagType
77     */
78    private $tagType;
79    /**
80     * Valores que serão inseridos na tag de abertura
81     * ex: style, class, size, maxlength etc..
82     *
83     * @var array $properties
84     */
85    private $properties;
86    /**
87     * Conteudo que será exibido entre a tag de abertura e fechamento
88     *
89     * @var array $children
90     */
91    private $children;
92    /**
93     * Array de propriedades css que formarao a propriedade style da tag html
94     * Ex: style="top:10px;"
95     *
96     * @var array $css
97     */
98    protected $css;
99    /**
100     * Array de eventos javascript que serão atribuidos a tag html
101     * Ex: addEvent("onClick","fazerAlgo()");
102     *
103     * @var array $events
104     */
105    private $events;
106    /**
107     * Armazena o Id do objeto pai
108     *
109     */
110    private $parentControl;
111    
112    /**
113     * Funcao construtora da classe.
114     * Recebe como parametro o tipo de tag html que sera gerada
115     * Ex: div, span, input ...
116     *
117     * @var string tagType - name tag html
118     */
119    public function __construct( $strTagType = null )
120    {
121        // evitar que um modulo seja executado diretamente da URL sem ter sido
122        // chamado pelo controller
123        if ( !defined( 'FORMDIN' ) )
124        {
125            //die();
126        }
127        $strTagType = is_null( $strTagType ) ? 'span' : $strTagType;
128        $this->tagType = $this->removeIllegalChars( strtolower( $strTagType ) );
129        
130        //$this->setCss('font-family','Arial,Helvetica, Geneva, Sans-Serif');
131        //$this->setCss('font-size','12px');
132        if ( is_null( self::$depth ) ) {
133            if ( $this->tagType == 'doctype' ) {
134                self::$depth = -1;
135            }else {
136                self::$depth = 0;
137            }
138        }
139        
140        if ( is_null( self::$base ) ) {
141            $this->getBase();
142        }
143    }
144    /**
145     * define uma propriedade da tag. Equivalente ao metodo setProperty()
146     *
147     * @param string $property
148     * @param mixed $value
149     */
150    public function __set( $property, $value )
151    {
152        if ( is_object( $value ) )
153        {
154            return $this;
155        }
156        
157        if ( isset( $this->properties[ $property ] ) && is_object( $this->properties[ $property ] ) )
158        {
159            $this->properties[ strtolower( $property )]->$property = $value;
160        }
161        else
162        {
163            // todas as propriedades terao nomes em caixa baixa
164            $property = strtolower( $property );
165
166            // id e name nao podem ter caracteres da lingua portuguesa
167            if ( $property == 'id' || $property == 'name' )
168            {
169                $property = $this->removeIllegalChars( $property );
170            }
171            $this->properties[ $property ] = $value;
172        }
173        return $this;
174    }
175    /**
176     * Mesmo que setAttribute(). Define uma propriedade e um valor para a tag html de abertura
177     * Ex: setProperty('name','xxx'); gera: <tag name="xxx">
178     *
179     * @param string $name
180     * @param mixed $value
181     */
182    public function setProperty( $strProperty, $strValue )
183    {
184        $strProperty = $this->removeIllegalChars( $strProperty,'-' );
185        if( strtolower($strProperty) == 'id')
186        {
187            $strValue = $this->removeIllegalChars($strValue);
188        }
189        $this->$strProperty = $strValue;
190        return $this;
191    }
192    /**
193     * Mesmo que setProperty. Define um atributo e o seu valor para a tag html de abertura
194     * Ex: setAttribute('name','myDiv'); gera: <tag name="myDiv">
195     *
196     * @param string $name
197     * @param mixed $value
198     */
199    public function setAttribute( $strProperty, $strValue = null )
200    {
201        return $this->setProperty( $strProperty, $strValue );
202    }
203    /**
204     * Retorna o valor definido para uma propriedade
205     * o mesmo que getProperty()
206     *
207     * @param mixed $strProperty
208     */
209    public function getAttribute( $strProperty = null )
210    {
211        return $this->getProperty( $strProperty );
212    }
213    /**
214     * Retorna o valor definido para uma propriedade
215     *
216     * @param string $property
217     * @return string
218     */
219    public function getProperty( $strProperty )
220    {
221        $strProperty = strtolower( $strProperty );
222        return $this->$strProperty;
223    }
224    /**
225     * Retorna o valor definido para uma propriedade
226     *
227     * @param string $property
228     * @return string
229     */
230    public function __get( $strProperty )
231    {
232        if ( isset( $this->properties[ $strProperty ] ) )
233        {
234            return $this->properties[ $strProperty ];
235        }
236        return null;
237    }
238    
239    //---------------------------------------------------------------------
240    /**
241     * Faz o tratamento das aspas duplas e simples para evitar erro de sintaxe
242     *
243     * @param string $str
244     * @return string
245     */
246    private function setQuotes( $str )
247    {
248        $str = str_replace( '( "', "('", $str );
249        $str = str_replace( '("', "('", $str );
250        $str = str_replace( '")', "')", $str );
251        $str = str_replace( '" )', "')", $str );
252        //$str=str_replace('"','“' ,$str);
253        $str = str_replace( '"', "'", $str );
254        //$str=str_replace('"',"\'\'" ,$str);
255        
256        //$str=str_replace("(''","('\'" ,$str);
257        //$str=str_replace("'')","\'')" ,$str);
258        
259        $str = str_replace( "\\\'')", "\\'')", $str );
260        
261        $str = str_replace( "\\'\\'+", "'+", $str );
262        $str = str_replace( "+\\'\\'", "+'", $str );
263        
264        $str = str_replace( "\\'\\' +", "'+", $str );
265        $str = str_replace( " +\\'\\'", "+'", $str );
266        //$str=str_replace("","" ,$str);
267        return $str;
268    }
269    
270    //----------------------------------------------------------------------
271    /**
272     * Transforma as tags html para o simbolo correspondente
273     *
274     * @param string $s
275     * @return string
276     */
277    public function safehtml( $s )
278    {
279        $s = str_replace( "&", "&amp;", $s );
280        $s = str_replace( "<", "&lt;", $s );
281        $s = str_replace( ">", "&gt;", $s );
282        $s = str_replace( "'", "&apos;", $s );
283        $s = str_replace( "\"", "&quot;", $s );
284        return $s;
285    }
286    /**
287     * Remove os caracteres invalidos para criacao de nomes de funcoes e variaveis
288     * Para não excluir algum caractere especifico, utilize o parametro $strExcept
289     * ex: removeIllegalChars($teste,'[]');
290     * @param string $word
291     * @param string $strExcept
292     * @return string
293     */
294    public function removeIllegalChars( $word=null, $strExcept = null )
295    {
296        if( is_null($word) || trim($word) == '' )
297        {
298            return null;
299        }
300        if ( isset( $strExcept ) )
301        {
302            $strExcept = str_replace( array( '[', ']', '^' ), array( '\\[', '\\]', '\\^' ), $strExcept );
303        }
304        return $word = @preg_replace( "/[^a-zA-Z0-9_" . $strExcept . "]/", "",
305            strtr( $word, "áàãâéêíóôõúüçÁÀÃÂÉÊÍÓÔÕÚÜÇ ", "aaaaeeiooouucAAAAEEIOOOUUC_" ) );
306        
307        
308    }
309
310    public function removeIllegalCharsv2( $word=null, $strExcept = null )
311    {
312        if( is_null($word) || trim($word) == '' ){
313            return null;
314        }
315        if ( isset( $strExcept ) ){
316            $search  = array( '[', ']', '^' );
317            $replace = array( '\\[', '\\]', '\\^' );
318            $strExcept = str_replace( $search, $replace, $strExcept );
319        }
320        $pattern="/[^a-zA-Z0-9_" . $strExcept . "]/";
321        $subject=strtr( $word, "áàãâéêíóôõúüçÁÀÃÂÉÊÍÓÔÕÚÜÇ ", "aaaaeeiooouucAAAAEEIOOOUUC_" );
322        $word   =preg_replace( $pattern, "",$subject );
323        return $word;
324    }
325    
326    /**
327     * Adiciona conteudo dentro da tag. Pode ser um texto ou outro objeto da classe Element
328     *
329     * @param mixed $child
330     */
331    public function add( $child, $boolLF = true )
332    {
333        if ( is_array( $child ) ) {
334            foreach( $child as $v ) {
335                $this->add( $v, $boolLF );
336            }
337        } else {
338            if ( $child != null ) {
339                if ( $boolLF === false && !is_object( $child ) ) {
340                    $index = ( is_array( $this->children ) ? count( $this->children ) - 1 : 0 );
341                    $this->children[ $index ] .= $child;
342                } else {
343                    $this->children[ ] = $child;
344                }
345                
346                // gravar o objeto pai no objeto filho
347                if ( is_object( $child ) ) {
348                    $child->setParentControl( $this );
349                }
350                return $child;
351            }
352        }
353    }
354    
355    /**
356     * Adiciona conteudo dentro da tag antes de todos os objeto já inseridos.
357     * Pode ser um texto ou outro objeto da classe Element
358     *
359     * @param mixed $child
360     * @param mixed $boolLF
361     */
362    public function addOnTop( $child, $boolLF = true )
363    {
364        $children = $this->getChildren();
365        $this->clearChildren();
366        $this->add($child,$boolLF);
367        $this->add($children);
368    }
369    
370    // retorna o array de conteudo que sera impresso entre as tags de abertura e fechamento
371    public function getChildren($intIndex=null)
372    {
373        if( !is_null( $intIndex ))
374        {
375            return $this->children[$intIndex]; // retorna o filho selecionado
376        }
377        return $this->children; // retorna todos os filhos
378    }
379    
380    //---------------------------------------------------------------------
381    /**
382     * Abre a tag e imprime todo o seu conteudo.
383     * Se print for false, retorna o html gerado
384     * Se print for true, joga o html para o browser ( padrao )
385     *
386     * @param bool $print
387     */
388    protected function open( $print = true )
389    {
390        $result = '';
391        
392        // tags simples que nao possuem fechamento
393        if ( $this->tagType == 'br' ) {
394            //https://pt.stackoverflow.com/questions/46370/o-certo-%C3%A9-br-ou-br-ou-br
395            //HTML tag BR is <br>
396            $result .= "<{$this->tagType}>";
397        } else if( $this->tagType == 'doctype' ){
398            $result .= '<!DOCTYPE html>'. "\n";
399        } else {
400            $result = '';
401            
402            if ( $this->getTagType() )
403            {
404                $result .= "<{$this->tagType}";
405                
406                if ( is_array( $this->properties ) )
407                {
408                    foreach( $this->properties as $k => $v )
409                    {
410                        if ( !is_object( $v ) )
411                        {
412                            if ( !is_null( $v ) )
413                            {
414                                // regras de acessibilidade para div
415                                if( $k == 'name' )
416                                {
417                                    if( FormDinHelper::pregMatch('/(div|table|tr|td)/i',$this->getTagType()))
418                                        continue;
419                                }
420                                if(substr($k,0,3) != '_fl')
421                                {
422                                    if ( $k == 'nowrap' )
423                                    {
424                                        $v = ( ( $v == '' || $v == '1' ) ? 'true' : $v );
425                                        
426                                        if ( $v == 'false' )
427                                        {
428                                            $k = null;
429                                        }
430                                    }
431                                    
432                                    // tags que devem possuir unidade de medida para funcionarem em strict mode no browser
433                                    if ( preg_match( '/(width|height|top|left|font-size|padding|margin) /', $k )
434                                        && preg_match( '/[0-9]$/', $v ) )
435                                    {
436                                        $v .= 'px';
437                                    }
438                                    // atributos que não possuem medidas
439                                    if( preg_match('/(cellspacing|cellpadding)/i', $k ) ) {
440                                        $v = preg_replace('/[^0-9]/','',$v);
441                                    }
442                                    
443                                    if ( !is_null( $k ) && $k != '' ) {
444                                        if( is_string($v) || is_numeric($v) ) {
445                                            $result .= " $k=\"$v\" ";
446                                        } else {
447                                            $result .= "$k=\"".gettype($v)."\" ";
448                                        }
449                                    }
450                                }
451                            }
452                        } else {
453                            $result .= " $k=\"{$v->show(false)}\"";
454                        }
455                    }
456                }
457                
458                if ( $this->tagType == 'option' ) {
459                    $result .= ">";
460                } else {
461                    $result .= ">\n";
462                }
463            }
464        }
465        
466        if ( $result != '' ) {
467            $ident  = $this->getIdent();
468            $result = $ident.$result;
469            if ( $print ) {
470                echo $result;
471            } else {
472                return $result;
473            }
474        }
475    }
476    
477    //---------------------------------------------------------------------
478    /**
479     * fecha a tag
480     * Se print for false, retorna o html gerado
481     * Se print for true, joga o html para o browser ( padrao )
482     *
483     * @param mixed $print
484     */
485    protected function close( $print = true )
486    {
487        //print 'depth:'.self::$depth."\n";
488        // tags que nao precisam ser fechadas
489        if (   $this->tagType == ''
490            || $this->tagType == 'br'
491            || $this->tagType == 'doctype'
492            || $this->tagType == 'input'
493            || $this->tagType == 'img'
494            ){
495                return null;
496        }
497        
498        if ( $print ){
499            if ( $this->tagType == 'textarea' || $this->tagType == 'option' ){
500                echo "</{$this->tagType}>";
501            } else {
502                echo $this->getIdent() . "</{$this->tagType}>\n";
503            }
504        } else {
505            if ( $this->tagType == 'textarea' || $this->tagType == 'option' ) {
506                return "</{$this->tagType}>\n";
507            } else {
508                return $this->getIdent() . "</{$this->tagType}>\n";
509            }
510        }
511    }
512    
513    //---------------------------------------------------------------------
514    public function subShowCss()
515    {
516        // criar o estilo se tiver sido definida alguma propriedade
517        if ( is_array( $this->css ) ) {
518            $css = '';
519            
520            foreach( $this->css as $name => $value ) {
521                if ( $value ) {
522                    // tags que devem possuir unidade de medida para funcionarem em strict mode no browser
523                    if ( preg_match( '/(padding|margin|width|height|top|left|font-size)/', $name )
524                        && preg_match( '/[0-9]$/', $value ) )
525                    {
526                        $value .= 'px';
527                    }
528                }
529                $css .= $name . ':' . $value . ';';
530            }
531            
532            if ( ( string ) $css != '' ){
533                $this->style = $css;
534            }
535        }
536    }
537    
538    public function subShowEvents()
539    {
540        // adicionar os eventos definidos por setEvent()
541        if ( is_array( $this->events ) )
542        {
543            foreach( $this->events as $event => $function )
544            {
545                $actualValue = $this->$event;
546                $this->$event = $actualValue . ( ( string ) $actualValue != '' ? ';' : '' ) . $function;
547            }
548        }
549    }
550    
551    /***
552     * TODO DESCOBRIR o motivo de não conseguir  extrair para outro metodo
553     * https://github.com/bjverde/formDin/issues/177
554     * @param string $result
555     * @return string|array|NULL
556     */
557    public function subShowChildren($result)
558    {
559        if ( is_array( $this->children ) ) {
560            foreach( $this->children as $child ) {
561                if ( is_object( $child ) ) {
562                    self::$depth++;
563                    $result .= $child->show( false );
564                    self::$depth--;
565                } else {
566                    // o texto do campo textarea e option não ser identado senão aparece na tela
567                    if ( $this->tagType != 'textarea' && $this->tagType != 'option' ) {
568                        // linha de comentario
569                        $preg = preg_match('/^\/\//',ltrim( $child ) );
570                        if ( $preg && !$GLOBALS[ 'teste' ] ) {
571                            $child = "";
572                        } else {
573                            $result .= $this->getIdent( 1 ) . $child . "\n";
574                        }
575                    } else {
576                        if ( !$preg ) {
577                            $result .= $child;
578                        }
579                    }
580                }
581            }//END foreach
582        }
583        return $result;
584    }
585    
586    /**
587     * Imprime/retorna o codigo completo de abertura e fechamento da tag
588     * Se print for false, retorna o html gerado
589     * Se print for true, joga o html para o browser ( padrao )
590     *
591     * @param mixed $print
592     */
593    public function show( $print = true )
594    {
595        $this->subShowCss();
596        $this->subShowEvents();
597        $result = $this->open( $print );
598        
599        //--------- TODO DESCOBRIR o motivo de não conseguir  extrair para outro metodo
600        //--------- https://github.com/bjverde/formDin/issues/177
601        //$result = $this->subShowChildren($result);
602        if ( is_array( $this->children ) ) {
603            foreach( $this->children as $child ) {
604                if ( is_object( $child ) ) {
605                    self::$depth++;
606                    $result .= $child->show( false );
607                    self::$depth--;
608                } else {
609                    $preg = FormDinHelper::pregMatch('/^\/\//',ltrim( $child ) );
610                    // o texto do campo textarea e option não ser identado senão aparece na tela
611                    if ( $this->tagType != 'textarea' && $this->tagType != 'option' ) {
612                        // linha de comentario                        
613                        if ( $preg && !$GLOBALS[ 'teste' ] ) {
614                            $child = "";
615                        } else {
616                            $result .= $this->getIdent( 1 ) . $child . "\n";
617                        }
618                    } else {
619                        if ( !$preg ) {
620                            $result .= $child;
621                        }
622                    }
623                }
624            }//END foreach
625        }
626        //----------------------------------------------------------------------
627        
628        // tive que remover quebras e tabs para nao interferir no layout dos elementos na pagina
629        if ( !$GLOBALS[ 'teste' ] ) {
630            $result = str_replace( "\n", '', $result );
631            $result = str_replace( ESP, '', $result );
632        }
633        
634        if ( $print ) {
635            echo $result;
636        }
637        $result .= $this->close( $print );
638        return $result;
639    }
640    
641    //----------------------------------------------------------------
642    /**
643     * permite alterar o tipo de tag que será gerada. Ex. input, label, textarea, div ...
644     *
645     * $param string $newTagType
646     */
647    public function setTagType( $newTagType )
648    {
649        $this->tagType = strtolower( $newTagType );
650        return $this;
651    }
652    
653    //----------------------------------------------------------------
654    /**
655     * Retorna o tipo da tag html definda
656     * ex: html, span, div, input...
657     *
658     * @return string
659     */
660    public function getTagType()
661    {
662        return $this->tagType;
663    }
664    /**
665     * Define a classe (css) para estilizar a tag html
666     *
667     * @param string $newClass
668     */
669    public function setClass( $newClass, $boolClearCss = null )
670    {
671        $boolClearCss = $boolClearCss === false ? false : true;
672        $this->class = $newClass;
673        
674        if ( $boolClearCss )
675        {
676            $this->clearCss();
677        }
678        return $this;
679    }
680    /**
681     * Retorna a classe definida para estilizar a tag html
682     *
683     * @return string
684     */
685    public function getClass()
686    {
687        return $this->class;
688    }
689    
690    //--------------------------------------------------------------------------
691    /**
692     * Define o evento e a funcao javascript que sera executada ao ocorrer o evento
693     * Se for restritivo e a função executada retornar false, interrompe a execução dos próximos eventos se houver
694     *
695     * @param string $eventName
696     * @param string $functionJs
697     * @param boolean $boolRestrictive
698     */
699    public function setEvent( $eventName, $functionJs = null, $boolRestrictive = null )
700    {
701        $eventName = $this->removeIllegalChars( $eventName );
702        $eventName = !empty($eventName)?strtolower($eventName):$eventName;
703        //$functionJs    = $this->removeIllegalChars($functionJs);
704        $this->events[ $eventName ] = '';
705        
706        if ( ( string ) $functionJs != '' )
707        {
708            if ( ( bool ) $boolRestrictive === true )
709            {
710                $functionJs = 'if(!' . $functionJs . '){return false;}';
711            }
712            $this->addEvent( $eventName, $functionJs );
713        }
714        return $this;
715    }
716    /**
717     * Atribui um array de ventos e funções ao elemento
718     *
719     * @param array $arrEvents
720     */
721    public function setEvents( $arrEvents = null )
722    {
723        $this->events = $arrEvents;
724        return $this;
725    }
726    
727    /**
728     * Adiciona um evento na tag html. Se ja exisitir um evento com o mesmo nome, faz a concatenacao
729     * dos eventos, executando ambos em sequencia.
730     * Se for restritivo e a função executada retornar false, interrompe a execução dos próximos eventos se houver
731     *
732     * @param string $eventName
733     * @param string $functionJs
734     * @param boolean $boolRestrictive
735     */
736    public function addEvent( $eventName, $functionJs = null, $boolRestrictive = null )
737    {
738        $eventName = strtolower( $this->removeIllegalChars( $eventName ) );
739        
740        if ( isset( $this->events[ $eventName ] ) && ( string ) $this->events[ $eventName ] != '' )
741        {
742            $this->events[ $eventName ] .= ';';
743        }
744        
745        if ( ( bool ) $boolRestrictive === true )
746        {
747            $functionJs = 'if(!' . $functionJs . '){return false;}';
748        }
749        
750        if ( !isset( $this->events[ $eventName ] ) )
751        {
752            $this->events[ $eventName ] = ""; // evitar wornings do php
753        }
754        $this->events[ $eventName ] .= $this->setQuotes( $functionJs );
755        return $this;
756    }
757    /**
758     *  Retorna a função chamada pelo evento solicitado
759     *  se não existir, retorna null
760     *
761     * @param string $strEventName
762     */
763    public function getEvent( $strEventName )
764    {
765        $strEventName = strtolower( $this->removeIllegalChars( $strEventName ) );
766        $event = null;
767        if(is_array($this->events)){
768            $event = $this->events[ $strEventName ];
769        }
770        return $event;
771    }
772    /**
773     *  Retorna o array de eventos ligados ao elemento
774     *  se não existir, retorna null
775     *
776     */
777    public function getEvents()
778    {
779        return $this->events;
780    }
781    /**
782     * Remove todos os eventos definidos
783     *
784     */
785    public function clearEvents()
786    {
787        $this->events = null;
788    }
789    
790    //-------------------------------------------------------------------------------------------------
791    public function getIdent( $intDepth = 0 )
792    {
793        if ( $GLOBALS[ 'teste' ] && self::$depth > 0 ) {
794            $qtd    = self::$depth + $intDepth;
795            $result = str_repeat( ESP, $qtd );
796            return $result;
797        }
798        return null;
799    }
800    
801    //-------------------------------------------------------------------------------
802    public function clearChildren()
803    {
804        $this->children = null;
805    }
806    
807    //---------------------------------------------------------------------------------
808    public function setId( $newId )
809    {
810        // considerar os caracteres [] porque os campo check e select multi tem [] no final
811        // e a função removeillegaChars remove eles se não for informado
812        $this->id = $this->removeIllegalChars( $newId );
813        if( !is_null($newId) ){
814            // se o nome não possuir colchetes, dos campos multivalorados, igualar ao id            
815            if ( !empty($this->name) && !strpos( $this->name, '[' ) ) {
816                $this->name = $this->removeIllegalChars( $newId, '[]' );
817            }
818        }
819        return $this;
820    }
821    
822    //---------------------------------------------------------------------
823    public function setName( $newName )
824    {
825        $this->name = $this->removeIllegalChars( $newName, '[]' );
826        
827        // se o nome não possuir colchetes, dos campos multivalorados, igualar ao id
828        if ( !$this->id )
829        {
830            $this->id = $this->removeIllegalChars( $newName);
831        }
832        return $this;
833        /*
834         if( !strpos($this->name,'['))
835         {
836         $this->id    = $this->removeIllegalChars($newName);
837         }
838         */
839        
840    }
841    
842    //---------------------------------------------------------------------
843    public function getName()
844    {
845        return $this->name;
846    }
847    
848    //---------------------------------------------------------------------
849    public function getId()
850    {
851        return $this->id;
852    }
853    
854    //---------------------------------------------------------------------
855    public function clearCss()
856    {
857        $this->css = null;
858    }
859    
860    public function getBase()
861    {
862        //if((string)$this->base=="")
863        if ( is_null( self::$base ) )
864        {
865            for( $i = 0; $i < 10; $i++ )
866            {
867                $base = str_repeat( '../', $i ) . 'base/';
868                
869                if ( file_exists( $base ) )
870                {
871                    $i = 1000;
872                    //$this->base = $base;
873                    self::$base = $base;
874                    break;
875                }
876            }
877        }
878        return self::$base;
879    }
880    
881    public function getRoot()
882    {
883        $base = $this->getBase();
884        return str_replace( 'base/', '', $base );
885    }
886    
887    //----------------------------------------------------------------------------
888    public function setValue( $strNewValue = null )
889    {
890        $this->value = $strNewValue;
891        return $this;
892    }
893    
894    //----------------------------------------------------------------------------
895    public function getValue()
896    {
897        return $this->value;
898    }
899    
900    public function setParentControl( $objParent = null )
901    {
902        $this->parentControl = $objParent;
903        return $this;
904    }
905    
906    //-----------------------------------------------------------------------------
907    public function getParentControl()
908    {
909        return $this->parentControl;
910    }
911    
912    //-----------------------------------------------------------------------------
913    public function getTopMostParent()
914    {
915        if ( $this->parentControl ){
916            //$id = $this->parentControl->getId();
917            return $this->parentControl->getTopMostParent();
918        }
919        //$id = $this->getId();
920        return $this;
921    }
922    
923    //------------------------------------------------------------------------------
924    public function setXY( $mixX = null, $mixY = null )
925    {
926        if ( !is_null( $mixX ) )
927        {
928            $this->setCss( 'left', $mixX );
929        }
930        
931        if ( !is_null( $mixY ) )
932        {
933            $this->setCss( 'top', $mixY );
934        }
935        return $this;
936    }
937    
938    //---------------------------------------------------------------------------------
939    public function getRandomChars( $intSize = 5 )
940    {
941        $intSize = ( int ) $intSize == 0 ? 5 : $intSize;
942        $intSize = ( int ) $intSize > 32 ? 32 : $intSize;
943        return substr( preg_replace('/[li1]/','x',md5( microtime() ) ), 0, $intSize );
944    }
945    
946    //-----------------------------------------------------------------------------
947    public function getIndexFileName()
948    {
949        if ( defined( 'INDEX_FILE_NAME' ) )
950        {
951            return INDEX_FILE_NAME;
952        }
953        $url = $_SERVER[ 'SCRIPT_NAME' ];
954        $url = ( $url == '' ? $_SERVER[ 'REQUEST_URI' ] : $url );
955        $url = ( $url == '' ? $_SERVER[ 'SCRIPT_FILENAME' ] : $url );
956        $url = ( $url == '' ? $_SERVER[ 'SCRIPT_NAME' ] : $url );
957        $url = ( $url == '' ? $_SERVER[ 'PHP_SELF' ] : $url );
958        if ( !$url ){
959            return 'index.php';
960        }
961        if( FormDinHelper::pregMatch('/\./',$url)) {
962            $aFileParts = pathinfo( $url );
963            return $aFileParts[ 'basename' ];
964        }
965        return '';
966    }
967    
968    public function addWarning($strWarning=null)
969    {
970        if( ! is_null( $strWarning ) )
971        {
972            self::$warnings[] = $strWarning;
973        }
974    }
975    
976    public function getWarnings()
977    {
978        return self::$warnings;
979    }
980    
981    public function specialChars2htmlEntities($value = null) {
982        if (is_string($value)) {
983            $html_entities = array
984            (
985                'Á' => '&Aacute;',
986                'À' => '&Agrave;',
987                'É' => '&Eacute;',
988                'È' => '&Egrave;',
989                'Í' => '&Iacute;',
990                'Ì' => '&Igrave;',
991                'Ó' => '&Oacute;',
992                'Ò' => '&Ograve;',
993                'Ú' => '&Uacute;',
994                'Ù' => '&Ugrave;',
995                'á' => '&aacute;',
996                'à' => '&agrave;',
997                'é' => '&eacute;',
998                'è' => '&egrave;',
999                'í' => '&iacute;',
1000                'ì' => '&igrave;',
1001                'ó' => '&oacute;',
1002                'ò' => '&ograve;',
1003                'ú' => '&uacute;',
1004                'ù' => '&ugrave;',
1005                'Ä' => '&Auml;',
1006                'Â' => '&Acirc;',
1007                'Ë' => '&Euml;',
1008                'Ê' => '&Ecirc;',
1009                'Ï' => '&Iuml;',
1010                'Î' => '&Icirc;',
1011                'Ö' => '&Ouml;',
1012                'Ô' => '&Ocirc;',
1013                'Ü' => '&Uuml;',
1014                'Û' => '&Ucirc;',
1015                'ä' => '&auml;',
1016                'â' => '&acirc;',
1017                'ë' => '&euml;',
1018                'ê' => '&ecirc;',
1019                'ï' => '&iuml;',
1020                'î' => '&icirc;',
1021                'ö' => '&ouml;',
1022                'ô' => '&ocirc;',
1023                'ü' => '&uuml;',
1024                'û' => '&ucirc;',
1025                'Ã' => '&Atilde;',
1026                'å' => '&aring;',
1027                'Ñ' => '&Ntilde;',
1028                'Å' => '&Aring;',
1029                'Õ' => '&Otilde;',
1030                'Ç' => '&Ccedil;',
1031                'ã' => '&atilde;',
1032                'ç' => '&ccedil;',
1033                'ñ' => '&ntilde;',
1034                'Ý' => '&Yacute;',
1035                'õ' => '&otilde;',
1036                'ý' => '&yacute;',
1037                'Ø' => '&Oslash;',
1038                'ÿ' => '&yuml;',
1039                'ø' => '&oslash;',
1040                'Þ' => '&THORN;',
1041                'Ð' => '&ETH;',
1042                'þ' => '&thorn;',
1043                'ð' => '&eth;',
1044                'Æ' => '&AElig;',
1045                'ß' => '&szlig;',
1046                'æ' => '&aelig;'
1047            );
1048            
1049            return strtr($value, $html_entities);
1050        }
1051    }
1052    /**
1053     * aplicar utf8_encode em todos os elementos de um array com recursividade
1054     *
1055     * @param string[] $data
1056     * @return string[]
1057     */
1058    public function utf8_encode_array( $data=null )
1059    {
1060        if( is_array($data ))
1061        {
1062            foreach($data as $k=>$v)
1063            {
1064                if( is_array( $v ) )
1065                {
1066                    $data[$k] = $this->utf8_encode_array($v);
1067                }
1068                else
1069                {
1070                    $data[$k] = utf8_encode($v);
1071                }
1072            }
1073        }
1074        return $data;
1075    }
1076    
1077    public function decodeUtf8( $strValue=null )
1078    {
1079        if( is_null( $strValue ) || $strValue == '' )
1080        {
1081            return $strValue;
1082        }
1083        if( FormDinHelper::pregMatch( '/\?/', utf8_decode($strValue) ) )
1084        {
1085            return $strValue;
1086        }
1087        return utf8_decode( $strValue );
1088    }
1089    
1090    //--------------------------------------------------------------------------
1091    /**
1092     * DEPRECADED - change to setClass.
1093     *
1094     * Defines a css IN LINE property to create the style of the tag.
1095     * To set the CSS of a form use addCssFile.
1096     * The $mixProperty parameter can be an array of properties and css values.
1097     *
1098     *
1099     * Define uma propriedade do css IN LINE para criar o style da tag.
1100     * Para setar o CSS de um formulario utilize addCssFile.
1101     * O parametro $mixProperty pode ser um array de propriedades e valores de css.
1102     *
1103     * <code>
1104     *     $obj->setCss( array('color'=>'white','border'=>'1px solid red') );
1105     *     $obj->setCss('border','1px dashed blue');
1106     * </code>
1107     *
1108     * @deprecated
1109     * @codeCoverageIgnore
1110     *
1111     * @param mixed $mixProperty
1112     * @param string $newValue
1113     */
1114    public function setCss( $mixProperty, $newValue = null )
1115    {
1116        if ( is_array( $mixProperty ) ) {
1117            $this->css = $mixProperty;
1118        } else {
1119            // os nomes das propriedades serao em caixa baixa
1120            $mixProperty = isset($mixProperty)?$mixProperty:'';
1121            $mixProperty = preg_replace( '[-]', '_', $mixProperty );
1122            $mixProperty = $this->removeIllegalChars( strtolower( $mixProperty ) );
1123            $mixProperty = isset($mixProperty)?$mixProperty:'';
1124            $mixProperty = preg_replace( '[_]', '-', $mixProperty );
1125            if ( $newValue === null ) {
1126                $this->css[ $mixProperty ] = null;
1127                unset( $this->css[ $mixProperty ] );
1128            } else {
1129                $this->css[ $mixProperty ] = $newValue;
1130            }
1131        }
1132        return $this;
1133    }
1134    /**
1135     * Retorna o valor de uma propriedade css
1136     * @deprecated
1137     * @codeCoverageIgnore
1138     */
1139    public function getCss( $strProperty = null )
1140    {
1141        if ( $strProperty === null )
1142        {
1143            return $this->css;
1144        }
1145        
1146        if ( isset( $this->css[ $strProperty ] ) )
1147        {
1148            return $this->css[ $strProperty ];
1149        }
1150        return null;
1151    }
1152    
1153}
1154?>