Location: PHPKode > scripts > Piragibe > piragibe/PGBRenderer.php
<?php
/**
 * A visual HTML renderer.
 * 
 * The renderer is in charge of every formatting and HTML presentation action. The same goes
 * for unformatting, of course. As HTML is the only current way of presenting information 
 * through PHP environments, a PGBHtmlRenderer as a specialisation of PGBRenderer structure 
 * has been considered unnecessary.
 * 
 * This renderer renders all HTML input field, regardless of its type, as an HTML array, thus
 * mimmicking the source data block strictly.
 * @package Piragibe
 * @author Francisco Piragibe
 * @version 1.00
 * @copyright Copyright &copy; 2006, Francisco Piragibe
 * This file is part of The PIRAGIBE Framework.
 *
 * The PIRAGIBE Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * The PIRAGIBE Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with The PIRAGIBE Framework; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
class PGBRenderer { 
 
    /**
     * @var PGBDataBlock the data block that supplies data for rendering
     */
    var $m_block;           // data block que sofrera a renderizacao
    /**
     * @var PGBNlsAgent the NLS agent that helps
     */
    var $m_nls;             // agente de internacionalizacao a usar
    /**
     * @var integer an auxiliary index, as every HTML input field is rendered as an array
     */
    var $m_idx;             // indice a gerar nos arrays HTML renderizados
 
    /**
     * Standard constructor.
     * @param PGBDataBlock $pDB the source {@link PGBDataBlock}
     */
    function PGBRenderer( $pDB = NULL ) {
        $this->m_nls = new PGBNlsAgent( 'pt' );
        $this->m_idx = 0;
        $this->setBlock( $pDB );
    }
    
    /**
     * Getter for the auxiliary index.
     * @return integer the index value
     */
    function getIndex() {
        return $this->m_idx;
    }
    
    /**
     * Increments the auxiliary index.
     */
    function incrementIndex() {
        $this->m_idx++;
    }
    
    /**
     * Setter for the auxiliary index.
     * @param integer $pIdx the new value for the index
     */
    function setIndex( $pIdx ) {
        $this->m_idx = $pIdx;
    }
    
    /**
     * Getter for the NLS agent.
     * @return PGBNlsAgent the NLS agent
     */
    function &getNlsAgent() {
        return $this->m_nls;
    }
    
    /**
     * Setter for the NLS agent.
     * @param PGBNlsAgent $pNls the NLS agent
     */
    function setNlsAgent( $pNls ) {
        if ( is_a( $pNls, 'PGBNlsAgent' ) ) {
            $this->m_nls = $pNls;
        }
    }
    
    /**
     * Getter for the source {@link PGBDataBlock}.
     * @return PGBDataBlock the data block
     */
    function &getBlock() {
        return $this->m_block;
    }
    
    /**
     * Setter for the source data block.
     * @param PGBDataBlock &$pDB the source data block
     */
    function setBlock( &$pDB ) {
        if ( is_a( $pDB, 'PGBDataBlock' ) ) {
            $this->m_block = &$pDB;
            $this->setNlsAgent( $pDB->getNlsAgent() );
        }
        else {
            $this->m_block = NULL;
        }
    }        
    
    /**
     * Reverts the formatting of the given value, using the property bag as a guide.
     * @return mixed the unformatted value
     * @param mixed $pBase the formatted value
     * @param PGBPropertyBag $pBag the property bag the will guide the process
     */
    function unformat( $pBase, $pBag = NULL ) {
        if ( is_null( $pBase ) ) {
            return NULL;
        }
        elseif ( strlen( $pBase ) == 0 ) {
            return '';
        }
        //print '<pre>' . $pBase . ' não nulo </pre>';
        $f      = 'asis';
        $tsep   = NULL;
        $dsep   = NULL;
        $w_voff = NULL;
        if ( is_a( $pBag, 'PGBPropertyBag' ) ) {
            $f      = $pBag->get( 'format' );
            $tsep   = $pBag->get( 'GroupChar' );
            $dsep   = $pBag->get( 'DecChar' );
            $w_voff = $pBag->get( 'ValueOff' );
            if ( is_null( $f ) ) {
                $f = 'asis';
            }
        }
        $tsep = $tsep ? $tsep : $this->m_nls->getThousandsSeparator();
        $dsep = $dsep ? $dsep : $this->m_nls->getDecimalsSeparator();
        if( $f == 'money' ) {
            $r = str_replace( $tsep, '', substr( $pBase, 3 ));
            if ( $dsep != '.' ) {
                $r = str_replace( $dsep, '.', $r );
            }
            //print '<pre>' . $pBase . '->' . $r . '</pre>';
            return $r;
        }
        elseif( $f == 'fixed' ) {
            $r = str_replace( $tsep, '', $pBase );
            if ( $dsep != '.' ) {
                $r = str_replace( $dsep, '.', $r );
            }
            //print '<pre>' . $pBase . '->' . $r . '</pre>';
            return $r;
        }
        else {
            $fc = NULL;
            if ( !is_null( $pBag ) ) {
                $fc = $pBag->get( 'converter' );
            }
            if ( $fc ) {
                return $fc( $pBase );
            }
            elseif ( $w_voff and !$pBase ) {
                return $w_voff;
            }
            else {
                return $pBase;
            }
        }
    }

    /**
     * Formats the given value, using the property bag as a guide.
     * @return mixed the formatted value
     * @param mixed $pBase the base value
     * @param PGBPropertyBag $pBag the property bag the will guide the process
     */
    function format( $pBase, $pBag = NULL) {
        if ( is_null( $pBase ) ) {
            return NULL;
        }
        elseif ( strlen( $pBase ) == 0 ) {
            return '';
        }
        //print '<pre>' . $pBase . ' não nulo </pre>';
        $f      = 'asis';
        $tsep   = NULL;
        $dsep   = NULL;
        if ( ! is_null( $pBag ) ) {
            $f      = $pBag->get( 'format' );
            $tsep   = $pBag->get( 'GroupChar' );
            $dsep   = $pBag->get( 'DecChar' );
            if ( is_null( $f ) ) {
                $f = 'asis';
            }
        }
        $tsep = $tsep ? $tsep : $this->m_nls->getThousandsSeparator();
        $dsep = $dsep ? $dsep : $this->m_nls->getDecimalsSeparator();
        if( $f == 'money' ) {
            $r = $this->m_nls->getCurrencySign() . number_format( strtr($pBase,',','.')+0, 2, $dsep, $tsep );
            //print '<pre>' . $pBase . '->' . $r . '</pre>';
            return $r;
        }
        elseif( $f == 'fixed' ) {
            $d = $pBag->get( 'decimals' );
            if ( is_null( $d ) ) {
                $d = 2;
            }
            $r = number_format( strtr($pBase,',','.')+0, $d, $dsep, $tsep );
            //print '<pre>' . $pBase . '->' . $r . '</pre>';
            return $r;
        }
        else {
            $fc = NULL;
            if ( !is_null( $pBag ) ) {
                $fc = $pBag->get( 'converter' );
            }
            if ( $fc ) {
                return $fc( $pBase );
            }
            else {
                return $pBase;
            }
        }
    }
    
    /**#@+
     * This is one of the valid renderers.
     */
    /**
     * Renders a field as an HTML hidden field.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function hiddentext( $p_field, $p_bag = NULL ) {
    // renderiza um PGBField como um campo escondido
        if ( is_null( $this->m_block ) ) {
            print '<input type="hidden" name="' .
                $p_field->getName() .
                '[' . $this->getIndex() . ']" value="' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '">';
        }
        else {
            print '<input type="hidden" name="__' . $this->m_block->getName() . '_' .
                $p_field->getName() .
                '[' . $this->getIndex() . ']" value="' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '">';
        }
    }
    
    /**
     * Renders a field as an HTML textbox.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function textbox( $p_field, $p_bag = NULL ) {
    // renderiza um PGBField como uma caixa de texto
        $w_maxl = $p_field->getSize();
        $w_size = 15;
        $w_ron  = false;
        if ( is_a( $p_bag, 'PGBPropertyBag' ) ) {
            $w_maxl = $p_bag->get('Maxlength');
            $w_size = $p_bag->get('Size');
            $w_ron  = $p_bag->get('ReadOnly');
        }
        if ( !$w_size ) {
            $w_size = max( 15, $w_maxl, $w_size );
        }
        if ( is_null( $this->m_block ) ) {
            print '<input type="text" name="' .
                $p_field->getName() .
                '[' . $this->getIndex() . ']" value="' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '" size="' .
                $w_size .
                '" maxlength="' .
                $w_maxl .
                '" ' .
                ($w_ron === true ? 'disabled ' : '') .
                '>';
        }
        else {
            print '<input type="text" name="__' . $this->m_block->getName() . '_' .
                $p_field->getName() .
                '[' . $this->getIndex() . ']" value="' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '" size="' .
                $w_size .
                '" maxlength="' .
                $w_maxl .
                '" ' .
                ($w_ron === true ? 'disabled ' : '') .
                '>';
        }
    }
    
    /**
     * Renders a field as an HTML text area (a multi-line textbox).
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function textarea( $p_field, $p_bag = NULL ) {
    // renderiza um PGBField como uma caixa de texto multilinha
        $w_tam = $p_field->getSize();
        $w_lin = 5;
        $w_col = 40;
        $w_ron = false;
        if ( is_a( $p_bag, 'PGBPropertyBag' ) ) {
            $w_tam = $p_bag->get('Maxlength');
            $w_lin = $p_bag->get('Rows');
            $w_col = $p_bag->get('Columns');
            $w_ron = $p_bag->get('ReadOnly');
        }
        $w_lin = $w_lin ? $w_lin : 3;
        $w_col = $w_col ? $w_col : 30;
        if ( is_null( $this->m_block ) ) {
            print '<textarea name="' . $p_field->getName() . '[' . $this->getIndex() . ']" ' .
                'rows="' . $w_lin .'" ' .
                'cols="' . $w_col . '" ' . 
                'maxlength="' . $w_tam . '" ' .
                ($w_ron === true ? 'disabled ' : '') .
                '>' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '</textarea>';
        }
        else {
            print '<textarea name="__' . $this->m_block->getName() . '_' . $p_field->getName() .  '[' . $this->getIndex() . ']" ' .
                'rows="' . $w_lin .'" ' .
                'cols="' . $w_col . '" ' . 
                'maxlength="' . $w_tam . '" ' .
                ($w_ron === true ? 'disabled ' : '') .
                '>' .
                $this->format( $p_field->getValue(), $p_bag ) .
                '</textarea>';
        }
    }
    
    /**
     * Renders a field as plain text, offering no editing capabilities.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function plaintext( $p_field, $p_bag = NULL ) {
    // renderiza um PGBField como texto
        if ( is_a( $p_bag, 'PGBPropertyBag' ) ) {
            $w_tl = $p_bag->get('translations');
            if ( is_array( $w_tl ) ) {
                print $w_tl[ $p_field->getValue() ];
            }
            else {
                print $this->format( $p_field->getValue(), $p_bag );
            }
        }
        else {
            print $this->format( $p_field->getValue(), $p_bag );
        }
        //$this->hiddentext( $p_field, $p_bag );
    }
    
    /**
     * Renders a field as an HTML radio button group.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function radiogroup( $p_field, $p_bag ) {
    // renderiza um radio group e seus botoes
        if ( ! is_a( $p_bag, 'PGBPropertyBag' ) ) {
            die;
        }
        $w_vals = $p_bag->get( 'Buttons' );
        $w_ron  = $p_bag->get( 'ReadOnly' );
        if ( ! is_array( $w_vals ) ) {
            die;
        }
        $p_name = $p_field->getName();
        $w_cont = 0;
        reset( $w_vals );
        while( list( $v, $c ) = each( $w_vals ) ) {
            if ( $w_cont > 0 ) {
                print '<br>';
            }
            $w_cont++;
            if ( is_null( $this->m_block ) ) {
                print '<input type="radio" name="' . $p_name . '[' . $this->getIndex() . ']" ';
            }
            else {
                print '<input type="radio" name="__' . $this->m_block->getName() . '_' . $p_name . '[' . $this->getIndex() . ']" ';
            }
            print 'value="' . $v . '" ';
            if ( $p_field->getValue() == $v ) {
                print 'checked ';
            }
            print ($w_ron === true ? 'disabled ' : '');
            print '>' . $c;
        }        
    }
    
    /**
     * Renders a field as an HTML checkbox field.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function checkbox( $p_field, $p_bag ) {
    // rederiza uma checkbox
        $w_von  = 'S';
        $w_ron  = false;
        $p_name = $p_field->getName();
        // obtem valores On e Off nao defaults
        if ( is_a( $p_bag, 'PGBPropertyBag' ) ) {
            if ( !is_null( $p_bag->get('ValueOn') ) ) {
                $w_von  = $p_bag->get('ValueOn');
            }
            $w_ron = $p_bag->get( 'ReadOnly' );
        }
        // rederiza
        if ( is_null( $this->m_block ) ) {
            print '<input type="checkbox" name="' . $p_name . '[' . $this->getIndex() . ']" ';
        }
        else {
            print '<input type="checkbox" name="__' . $this->m_block->getName() . '_' . $p_name . '[' . $this->getIndex() . ']" ';
        }
        print ' value="' . $w_von . '" ';
        if ( $p_field->getValue() == $w_von ) {
            print 'checked ';
        }
        print ($w_ron === true ? 'disabled ' : '');
        print '>';
    }
    
    /**
     * Renders a field as an HTML combobox.
     * @param PGBField $p_field the field to render
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function combobox( $p_field, $p_bag ) {
    // renderiza uma combo
        if ( ! is_a( $p_bag, 'PGBPropertyBag' ) ) {
            die;
        }
        $p_name     = $p_field->getName();
        $p_rs       = $p_bag->get('RowSource');
        $p_capfield = $p_bag->get('CapField');
        $p_valfield = $p_bag->get('ValField');
        $w_ron      = $p_bag->get( 'ReadOnly' );
        $p_currval  = $p_field->getValue();
        if ( is_null( $this->m_block ) ) {
            print '<select name="' . $p_name . '[' . $this->getIndex() . ']" size=1 ' . ($w_ron === true ? 'disabled ' : '') . '>';
        }
        else {
            print '<select name="__' . $this->m_block->getName() . '_' . $p_name . '[' . $this->getIndex() . ']" size=1 ' . ($w_ron === true ? 'disabled ' : '') . '>';
        }
        $ma = array(
                'sone' => array( 'pt' => 'Selecione Uma Opção',
                                 'en' => 'Please, choose one'
                                )
                );
        $oIN = new PGBNlsAgent('pt');
        $oIN->setMessageArray( $ma );
        print '<option value="">' . $oIN->getMessage('sone') . '</option>';
        if ( is_a( $p_rs, 'PGBRecordSet' ) ) {
        // se a fonte e um recordset, preenchemos a partir de seus registros
            $p_rs->firstRecord();
            while( $r = $p_rs->getCurrentRecord() ) {
                $c = $r->getFieldValue( $p_capfield );
                $v = $r->getFieldValue( $p_valfield );
                print '<option value="' . $v . '" ';
                if ( $v == $p_currval ) {
                    print 'selected';
                }
                print '>' . $c . '</option>';
                $p_rs->nextRecord();
            }
        }
        elseif ( is_array( $p_rs ) ) {
        // se a fonte e um array, trata-se de um conjunto discreto
            reset( $p_rs );
            while( list( $v, $c ) = each( $p_rs ) ) {
                print '<option value="' . $v . '" ';
                if ( $v == $p_currval ) {
                    print 'selected';
                }
                print '>' . $c . '</option>';
            }        
        }
        print '</select>';
    }
    /**#@- */
    
    /**
     * Renders a field, using the given renderer and property bag.
     * 
     * This should be called in an ordinary editing context, not in "enter query"
     * mode. If one calls it in "enter query" mode, it'll be impossible to query
     * fields rendered as plaintext.
     * @param string $p_renderer the actual rederer name
     * @param PGBField $p_field the field to be rendered
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function renderField( $p_renderer, $p_field, $p_bag = NULL ) {
    // renderiza um PGBField, de acordo com o renderizador dado
        $this->$p_renderer( $p_field, $p_bag );
    }
    
    /**
     * Renders a field in an "enter query" context.
     * 
     * This is a wrapper to renderField(). Before calling renderField(), it changes the
     * field size to 5000, the field value to an empty string and the renderer to textbox,
     * if the original renderer is plaintext. This allows for the querying of fields rendered
     * originally as plaintext, as well as the entering of long query criteria and predicates.
     * @param string $p_renderer the actual rederer name
     * @param PGBField $p_field the field to be rendered
     * @param PGBPropertyBag $p_bag the property bag that will guide the process
     */
    function renderQueryField( $p_renderer, $p_field, $p_bag = NULL ) {
    // renderiza um PGBField para query, de acordo com o renderizador dado
        $w_field = $p_field;
        $w_field->setValue( "" );
        $w_field->setSize( 5000 );
        $w_renderer = ($p_renderer === "plaintext") ? "textbox" : $p_renderer;
        $this->renderField( $w_renderer, $w_field, $p_bag );
    }
    
}
?>
Return current item: Piragibe