<?php

Goweb::loadClass('Goweb_Controller_Action_Admin');
Goweb::loadClass('Goweb_View');
Goweb::loadClass('Goweb_Form');
Goweb::loadClass('Goweb_Paginator');

/**
 * Goweb Sitemanager 5 Framework
 * @version    5.0.24
 * @category   Backoffice
 * @package    Index
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2010 (c) Goweb (http://www.goweb.pt)
*/
class Index_GenericController extends Goweb_Controller_Action_Admin {
    
    /**
     * Objecto Goweb_Admin
     * @var Goweb_Admin
    */
    protected $_admin = null;
    
    /**
     * Array com as accoes genericas
     * @var array
    */
    protected $_actions = array('list', 'add', 'edit', 'save', 'delete', 'deletelist', 'sql', 'excel', 'xml', 'treeDhtmlx', 'dhtmlxData', 'dhtmlxGrid', 'grid', 'updateSelect');
    
    /**
     * Construtor do back-office generico - Modulos Automaticos
    */
    public function init() {
        parent::init();
        if (strcmp($this->_action, 'index') == 0 && strcmp($this->_controller, 'index') ==0) return $this->_forward('list', 'cms');
        $controller = ucfirst($this->_formatName($this->_controller));
        $adminClass = $controller . '_Admin';
        $this->_request->setControllerName($controller);

        if (Goweb::isReadable($adminClass, APPLICATION_PATH)) {
            Goweb::loadClass($adminClass, APPLICATION_PATH);
            $this->_admin = new $adminClass();
            $this->_render();
        }        
    }

    /**
     * Este metodo efectua o render do modulo generico
    */
    public function _render() {
        $this->view->setViewsPath(GENERIC_VIEWS_PATH);
        
        if (!in_array($this->_action, $this->_actions)) {
            $this->_action = 'list';
        }
        
        foreach ($this->_admin->getSections() as $name => $section) {
            if ($section->getSectionListAction() == null && $section->getListAction() == null) {
                $this->_sections[] = array('title'   => $section->getTitle(),
                                           'section' => $name,
                                           'link'    => '/' . $this->_controller . '/' . ($section->getListType()) . '/section/' . $name . '/');
            }
        }
        
        $this->view->sections = $this->_sections;
        $this->view->title = $this->_admin->getTitle();        
        $this->view->controller = $this->_controller;
        $method = '_' . $this->_action;        
                 
        if ($this->_action == 'sql') {
            return $this->{$method}();
        }
        
        if ($this->_getParam('section')) {
            $sections = $this->_admin->getSections();
            if(isset($sections[$this->_getParam('section')]) && $sections[$this->_getParam('section')]->getListAction() && $this->_getParam('action') && strcmp($this->_getParam('action'), 'list') === 0){
                return $this->_forward($sections[$this->_getParam('section')]->getListAction());
            }
            $this->_section = $this->_getParam('section');
            if (strcmp($this->_request->getActionName(), substr($method, 1)) === 0) {
                $this->{$method}();
            }
        } else {
            /**
             * Só correr se não existir a função chamada...
             */
            $actionName1 = lcfirst($this->_formatName($this->_request->getActionName())) . 'Action';
            $actionName2 = $this->_request->getActionName() . 'Action';
            if (!in_array($actionName1, get_class_methods($this)) && 
                        !in_array($actionName2, get_class_methods($this))){
                $this->_section = $this->_admin->getDefaultSectionName();
                $this->{$method}();
            }
        }        
    }

    /**
     * Este metodo processa a pagina inicial do modulo automatico
    */
    protected function _sectionsDashboard() {
        $this->view->output = $this->view->render('sections_dashboard.tpl');
        $this->view->action = translateAdmin('Gest&atilde;o');
        $this->view->error  = $this->_error;
        $this->view->message = $this->_message;
        $this->view->section_title = translateAdmin('In&iacute;cio');
        $this->_helper->viewRenderer->setRender('base');
    }
    
    /**
     * Verifica se o nome da seccao existe
     *
     * @param string
     *
     * @return boolean
    */
    protected function _sectionExists($sectionName) {
        foreach ($this->_sections as $section) {
            if ($section['section'] == $sectionName) {
                return true;
            }
        }
        return false;
    }

    
    /**
     * Listagem generica
    */
    protected function _grid() {
        if (!$this->_sectionExists($this->_getParam('section'))) {
            $section = $this->_admin->getDefaultSection();
        } else {
            $section = $this->_admin->getSection($this->_getParam('section'));
        }

        if (!$section) {
            // return $this->_sectionsDashboard();
            $section = $this->_admin->getSection($this->_sections[0]['section']);
        }
        
        $this->_paginatorParams['rows_per_page'] = '20';
        $this->_paginatorParams['links_per_page'] = '10';
        $treeParams = $section->getTreeParams();
        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            if (!$this->_parentUrl) {
                if (!$pidValue) {
                    $pidValue = 0;
                }
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        $this->view->action  = translateAdmin('Listagem');
        $this->view->output = $this->_listGeneric($section, $this->view, true, 'grid.tpl');
        $this->view->section_title = $section->getTitle();
        $this->_helper->viewRenderer->setRender('base');
    }
    
    /**
     * Listagem generica
     */
    protected function _list() {
        if (!$this->_sectionExists($this->_getParam('section'))) {
            $section = $this->_admin->getDefaultSection();
        } else {
            $section = $this->_admin->getSection($this->_getParam('section'));
        }

        if (!$section) {
            // return $this->_sectionsDashboard();
            $section = $this->_admin->getSection($this->_sections[0]['section']);
        }
        
        $this->_paginatorParams['rows_per_page'] = '20';
        $this->_paginatorParams['links_per_page'] = '10';
        $treeParams = $section->getTreeParams();
        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            if (!$this->_parentUrl) {
                if (!$pidValue) {
                    $pidValue = 0;
                }
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        $this->view->action  = translateAdmin('Listagem');
        $this->view->output = $this->_listGeneric($section, $this->view);
        $this->view->section_title = $section->getTitle();
        $this->_helper->viewRenderer->setRender('base');
    }
    
    /**
     * Adicao Generica
    */
    protected function _add($cleanValues = false) {
        $section = $this->_admin->getSection($this->_getParam('section'));
        if (!$section) {
            // return $this->_sectionsDashboard();
            return $this->_list();
        }
        $this->view->action  = translateAdmin('Inser&ccedil;&atilde;o');
        $treeParams = $section->getTreeParams();
        $pidName = null;
        $pidValue = null;

        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);            
            if (!$this->_parentUrl) {
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        } elseif ($section->getParentIdCol()) {
            $pidName = $section->getParentIdCol();
            $pidValue = $this->_getParam($pidName);
        }

        $this->view->output = $this->_addGeneric($section, $this->view, $pidName, $pidValue, $cleanValues, false);
        $this->view->section_title = $section->getTitle();
        $this->_helper->viewRenderer->setRender('base');
    }

    /**
     * Edicao generica
    */
    protected function _edit() {
        $section = $this->_admin->getSection($this->_getParam('section'));
        if (!$section) {
            // return $this->_sectionsDashboard();
            return $this->_list();
        }
        
        $this->view->action  = translateAdmin('Edi&ccedil;&atilde;o');
        $treeParams = $section->getTreeParams();
        $pidName = null;
        $pidValue = null;
        
        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            if (!$this->_parentUrl) {
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        if (isset($this->_links)) {
            $this->view->delete_link = $this->_links['delete'] . $this->_getParam('id');
        }
        
        $this->view->output = $this->_editGeneric($section, $this->view, $pidName, $pidValue, false);
        $this->view->section_title = $section->getTitle();
        if ($this->_request->isAjax() || ($this->_getParam('type') && $this->_getParam('type') === 'frame')){
            $this->_helper->viewRenderer->setRender('base_blank');
        } else {
            $this->_helper->viewRenderer->setRender('base');
        }
    }

    /**
     * Save generico
    */
    protected function _save() {
        $section = $this->_admin->getSection($this->_getParam('section'));
        if (!$section) {
            // return $this->_sectionsDashboard();
            return $this->_list();
        }
        
        $this->view->action  = translateAdmin('Gravar');
        $pidName = null;
        $pidValue = null;
        $treeParams = $section->getTreeParams();
        if (!$treeParams) {
            if ($section->getSectionListAction()) {
                $sectionAux = $this->_admin->getSection($section->getSectionListAction());
                $treeParams = $sectionAux->getTreeParams();
                $pidName = $treeParams['nodesParams']['pid'];
                $pidValue = $this->_getParam($pidName);
                if (!$this->_parentUrl) {                
                    $this->_parentUrl = $pidName . '/' . $pidValue . '/';
                }
            }
        } else {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            if (!$this->_parentUrl) {                
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        $output = $this->_saveGeneric($section, $this->view, $pidName, $pidValue, false, false);
        
        if (is_bool($output)) {            
            if ($this->_request->submit) {
                if ($section->getListAction()){
                    return $this->_forward($section->getListAction());
                }elseif ($section->getSectionListAction()) {
                    $this->_params['section'] = $this->_section = $section->getSectionListAction();
                }
                return $this->_list();
            }
            
            if ($this->_request->submit_and_new) {              
                return $this->_add(true);
            }
            if ($this->_request->submit_and_continue) {
                $model = $section->getModel();
                if (!$this->_getParam($model->getPrimary())){
                    $this->_request->setParam($model->getPrimary(), $model->{$model->getPrimary()});
                    $this->_links['save'] .= $model->getPrimary() . '/' . $model->{$model->getPrimary()} . '/';
                }
                return $this->_edit();
            }
        }
        $this->view->output = $output;
        $this->_helper->viewRenderer->setRender('base');                
    }    
    
    /**
     * Delete Generico
    */
    protected function _delete() {
        $section = $this->_admin->getSection($this->_getParam('section'));
        if (!$section) {
            // return $this->_sectionsDashboard();
            return $this->_list();
        }
        
        $this->_paginatorParams['rows_per_page'] = '5';
        $this->_paginatorParams['links_per_page'] = '10';
        
        $this->view->action  = translateAdmin('Edi&ccedil;&atilde;o');
        $treeParams = $section->getTreeParams();
        $pidName = null;
        $pidValue = null;
        
        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            $this->_request->setParam($pidName, $pidValue);
            if (!$this->_parentUrl) {
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        $ouput = $this->_deleteGeneric($section, $this->view, $pidName, $pidValue);        
        if ($section->getListAction()){
            return $this->_forward($section->getListAction());
        }else $this->_list();
    }    

    /**
     * Delete List - Generico
    */
    protected function _deletelist() {
        $section = $this->_admin->getSection($this->_getParam('section'));
        if (!$section) {
            // return $this->_sectionsDashboard();
            return $this->_list();
        }
        
        $this->_paginatorParams['rows_per_page'] = '5';
        $this->_paginatorParams['links_per_page'] = '10';
        
        $this->view->action  = translateAdmin('Edi&ccedil;&atilde;o');
        $treeParams = $section->getTreeParams();
        $pidName = null;
        $pidValue = null;
        
        if ($treeParams) {
            $pidName = $treeParams['nodesParams']['urlId'];
            $pidValue = $this->_getParam($pidName);
            $this->_request->setParam($pidName, $pidValue);
            if (!$this->_parentUrl) {
                $this->_parentUrl = $pidName . '/' . $pidValue . '/';
            }
        }
        
        $ouput = $this->_deletelistGeneric($section, $this->view, $pidName, $pidValue);
        
        $this->_list();
    }
    
    /**
     * Devolve o sql do modulo
     *
     * @return string
    */
    protected function _sql() {
        $sql = '';
        $models = array();
        foreach ($this->_admin->getSections() as $section) {
            $model = $section->getModel();
            $sql .= $model->createTableSql();
            $models[] = get_class($model);
        }
        Goweb::dump($models, $this->_admin->getTitle() . ' SQL Models');
        echo '<pre>' . $sql . '</pre>';
    }
    
    /**
     * Formata a string para uma que seja compativel com o PHP. 
     * Substitui palavras separadas por "-", "_", ou "." por maiusculas e
     * remove todos caracteres que n&atilde;o sejam alfanemericos.
     *
     * @param   string  $unformatted
     * @return  string
    */
    protected function _formatName($unformatted) {
        $unformatted = str_replace(array('-', '_', '.'), ' ', strtolower($unformatted));
        $unformatted = preg_replace('[^a-z0-9 ]', '', $unformatted);
        return str_replace(' ', '', ucwords($unformatted));
    }
    
    // ****************************************************************** //
    // metodos de exportacao            -           metodos de exportacao //
    // ****************************************************************** //
    /**
     * Metodo de exportacao para excel
    */
    public function _excel() {
        $label     = array();
        $model     = null;
        $modelCols = array();
        $section   = null;
        $result    = false;
        
        $section = $this->_admin->getSection($this->_getParam('section'));
        
        if (!$section) {
            return $this->_sectionsDashboard();
        }
        
        $model                     = $section->getModel();
        $modelColsNames            = $model->getColsNames();
        $modelForeignColsWithAlias = $model->getForeignColsWithAliases();
        
        foreach ($modelColsNames as $campo) {
            $type = null;
            $type = $model->getCol($campo);
            $label[][$campo] = $type;
            if (in_array($campo, $modelForeignColsWithAlias)) {
                $label[][array_search($campo, $modelForeignColsWithAlias)] = $type;
            }
        }
        
        $result = $model->fetchAll();
        
        if ($result) {
            Goweb::loadClass('Goweb_Excel_Select_Excel');
            $resultArray = $this->_resultArray($label, $result);
            $excel = new Goweb_Excel_Select_Excel();
            $excel->sqlToExcel($resultArray, $model->getTableName());
            $this->_helper->viewRenderer->setNoRender();
        } else {
            $this->_list();
        }
    }

    /**
     * Metodo de exportacao para xml
    */
    public function _xml() {
        
        // vamos incluir a classe Goweb_Xml_Maker
        Goweb::loadClass('Goweb_Xml_Maker');
        
        $label     = array();
        $model     = null;
        $modelCols = array();
        $section   = null;
        $result    = false;
        
        $section = $this->_admin->getSection($this->_getParam('section'));
        
        if (!$section) {
            return $this->_sectionsDashboard();
        }
        
        $model                     = $section->getModel();
        $modelColsNames            = $model->getColsNames();
        $modelForeignColsWithAlias = $model->getForeignColsWithAliases();
        
        foreach ($modelColsNames as $campo) {
            $type = null;
            $type = $model->getCol($campo);
            $label[][$campo] = $type;
            if (in_array($campo, $modelForeignColsWithAlias)) {
                $label[][array_search($campo, $modelForeignColsWithAlias)] = $type;
            }
        }
        
        $result = $model->fetchAll();
        
        if ($result) {
            $resultArray = $this->_resultArray($label, $result);
            $this->_helper->viewRenderer->setNoRender();
        } else {
            $this->_list();
        }
        
        $array2XML = new Goweb_Xml_Maker();
        $array2XML->setArray($resultArray);
        $array2XML->saveXml(WWW_PATH . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . $this->_getParam('section') . '.xml',
                            $this->_getParam('section'));
        
        header("Cache-control: private");
        header("Content-type: application/octet-stream");
        header("Content-Length: " . filesize(WWW_PATH . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . $this->_getParam('section') . '.xml'));
        header("Content-Disposition: attachment; filename=" . $this->_getParam('section') . ".xml");
        
        if ($arq = fopen(WWW_PATH . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . $this->_getParam('section') . '.xml', 'r')) {
            fpassthru($arq);
            fclose($arq);
        }
    }

    /**
     * Metodo para o tratamento das informacoes - helper para exportacao.
    */
    protected function _resultArray($fieldsType, $result) {
        $fields = array();
        for ($i=0; $i<count($fieldsType); $i++) {
            foreach ($fieldsType[$i] as $campo => $object) {
                $fields[] = $campo;
            }
        }
        // Quantidade de linhas devolvidas pelo select
        $linReg  = count($result);
        // quantidade de colunas da tabela
        $qtdColunas = count($fields);
        $i = 0;
        $linha = array();
        foreach ($result as $row) {
            $colunas = $row->getCols();
            for($excelCol = 0; $excelCol < $qtdColunas; $excelCol++) {
                $objCol = $fieldsType[$excelCol][$fields[$excelCol]];
                if ($row->{$fields[$excelCol]} instanceof Goweb_Db_Model_Row) {
                    $linha[$i][$fields[$excelCol]] = trim($row->{$fields[$excelCol]}->__toString());
                } else {
                    $linha[$i][$fields[$excelCol]] = trim($row->{$fields[$excelCol]});
                }
            }
            $i++;
        }
        
        return $linha;
    }

    /**
     * componente dhtmlx, manipulação de dados
     *
     */
    protected function _dhtmlxData(){
        $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=' . CHARSET, true);
        $id = $this->_getParam('gr_id');
        $modelName = $this->_getParam('model');
        if (!$modelName && !$this->_getParam('section')){
            throw new Goweb_Exception($modelName . ' is not defined, can\'t continue.');
        }
        if ($this->_getParam('section')){
            $section = $this->_admin->getSection($this->_getParam('section'));
            $model = $section->getModel();
            $model->loadForeigns(false);
        } else {
            /**
             * @see Goweb_Db_Model
             */
            $model = Goweb::getModelInstance($modelName, 'db', false);
        }
        $id = $this->_getParam('gr_id');
        $result = 'error';
        if ($id && $this->_validateId($id) && $model->find($id)){
            foreach (array_keys($_GET) as $key){
                if ($model->colExists($key)){
                    $model->{$key} = $this->_request->{$key};
                }
            }
            if ($model->save()){
                $result = 'update';
            }
        }
        $output = '<data>
<action type=\'' . $result . '\' sid=\''.$id.'\' tid=\''.$id.'\'/>
</data>';
        $this->view->output = $output;
        $this->view->setViewsPath(VIEWS_PATH);
        $this->_helper->viewRenderer->setRender('vazia');
    }

    /**
     * componente dhtmlxGrid, geração de XML
     *
     */
    protected function _dhtmlxGrid(){
        $data = array();
        $modelName = $this->_getParam('model');
        if (!$modelName && !$this->_getParam('section')){
            throw new Goweb_Exception($modelName . ' is not defined, can\'t continue.');
        }
        if ($this->_getParam('section')){
            $section = $this->_admin->getSection($this->_getParam('section'));
            $model = $section->getModel();
            $model->loadForeigns(false);
            if (!$this->_links) {
                $this->_initDefaultLinks();
            }
            $this->_getPermissions($section);
        } else {
            /**
             * @see Goweb_Db_Model
             */
            $model = Goweb::getModelInstance($modelName, 'db', false);
        }

        if ($this->_getParam('cols')){
            $cols = explode(',', $this->_getParam('cols'));
        } else {
            $cols = array();
            foreach ($model->getCols() as $colName => $col){
                if ($col->getParam('show') && $col->getParam('label')){
                    $cols[] = $colName;
                }
            }
        }
        $foreigns = $model->getForeignColsWithAliases();
        $output = '<?xml version="1.0" encoding="' . CHARSET . '" ?>' . "\n";
        $output .= '<rows>' . "\n";
        $output .= str_pad('', 4, ' ') . '<head>' . "\n";
        foreach ($cols as $colName){
            $col = array_key_exists($colName, $foreigns) ? $model->getCol($foreigns[$colName]) : $model->getCol($colName);
            if ($col->getParam('show') && $col->getParam('label')){
                if ($col->getType() == 'ForeignKey'){
                    $output .= str_pad('', 8, ' ') . '<column type=\'coro\' id=\'' . (array_key_exists($colName, $foreigns) ? $foreigns[$colName] : $colName) . '\' width=\'*\'>';
                    $output .= htmlspecialchars($col->getParam('label'), ENT_QUOTES, CHARSET, false);
                    $output .= "\n";
                    $foreignModelName = $col->getParam('model');
                    $foreignModel = Goweb::getModelInstance($foreignModelName, $model->getAdapter(), false, true);

                    if ($model->isLoaded()) {
                        $this->{$colName}->value = strpos($model->{$colName}, 'a:') === 0 ? unserialize($model->{$colName}) : $model->{$colName};
                    }

                    if ($col->getParam('order')) {
                        $foreignModel->order($col->getParam('order'));
                    }

                    if ($col->getParam('where')) {
                        $foreignModel->where($col->getParam('where'));
                    }

                    $rowset = $foreignModel->fetchAll();
                    if ($rowset) {
                        $key = $foreignModel->getPrimary();
                        $label = $foreignModel->getToString();
                        if (!strlen($label)) {
                            $label = $key;
                        }
                        foreach ($rowset as $row) {
                            $output .= '<option value="' . $row->{$key} . '">';
                            $output .= '<![CDATA[' . html_entity_decode($row->{$label}, ENT_NOQUOTES, CHARSET) . ']]>';
                            $output .= '</option>' . "\n";
                        }
                    }
                } else {
                    $type = 'ro';
                    switch ($col->getType()){
                        case 'Char':
                            if (!$col->getParam('options')) $type = 'ed';
                            break;
                        case 'Text':
                            $type = 'txt';
                            break;
                        case 'Boolean':
                            $type = 'ch';
                            break;
                    }
                    $output .= str_pad('', 8, ' ') . '<column type=\'' . $type . '\'';
                    if ($type != 'ro'){
                        $output .= ' id=\'' . $colName . '\'';
                    }
                    $output .= ' width=\'*\'>';
                    $output .= '<![CDATA[' . $col->getParam('label') . ']]>';
                }
                $output .= '</column>' . "\n";
            }
        }
        if (isset($section) && !is_null($this->_links['delete']) || (isset($this->view->list_actions) && 
                is_array($this->view->list_actions) && count($this->view->list_actions) > 0)){
                    $output .= str_pad('', 8, ' ') .'<column type=\'ro\' width=\'*\'><![CDATA[' . translateAdmin('Ac&ccedil;&otilde;es') . ']]></column>' . "\n";
        }
        $output .= str_pad('', 4, ' ') . '</head>' . "\n";
        $rowset = $model->fetchAll();

        if ($rowset){
            foreach ($rowset as $row){
                $output .= str_pad('', 4, ' ') . '<row id=\'' . $row->{$model->getPrimary()} . '\'>' . "\n";
                foreach ($cols as $colName){
                    $col = array_key_exists($colName, $foreigns) ? $model->getCol($foreigns[$colName]) : $model->getCol($colName);
                    if ($colName != $model->getPrimary() && $col->getParam('show') && $col->getParam('label')){
                        $colName = array_key_exists($colName, $foreigns) ? $foreigns[$colName] : $colName;
                        $output .= str_pad('', 8, ' ') . '<cell>';
                        $value = $row->{$colName} instanceof Goweb_Db_Model_Row ? $row->{$colName}->__toString() : $row->{$colName};
                        $output .= '<![CDATA[' . $value . ']]>';
                        $output .= '</cell>' . "\n";
                    }
                }
                if (isset($section) && !is_null($this->_links['delete']) || (isset($this->view->list_actions) && 
                                is_array($this->view->list_actions) && count($this->view->list_actions) > 0)){
                    $output .= str_pad('', 8, ' ') . '<cell><![CDATA[';
                    $output .= '<a href="' . $this->view->link($this->_links['edit'] . $row->{$model->getPrimary()} . '/') . '">' . $this->view->img('/admin/media/images/icon_edit.png', array('alt' => translateAdmin('Editar'), 'border' => 0)) . '</a>';
                    if (isset($this->view->list_actions) && is_array($this->view->list_actions) && count($this->view->list_actions) > 0){
                        foreach ($this->view->list_actions as $list_action){
                            $output .= '<a href="' . $this->view->link($list_action['link'] . $row->{$model->getPrimary()} . '/') . '">' . $this->view->img($list_action['img'], array('alt' => translateAdmin($list_action['alt']), 'border' => 0)) . '</a>';
                        }
                    }
                    if (!is_null($this->_links['delete']) && (!isset($this->view->cant_delete) || (is_array($this->view->cant_delete) && !in_array($row->{$model->getPrimary()}, $this->view->cant_delete)))) {
                        $output .= '<a href="' . $this->view->link($this->_links['delete'] . $row->{$model->getPrimary()} . '/') . '" class="deletelink" onclick="javascript:return confirm(\'' . translateAdmin('Tem a certeza que deseja remover o item seleccionado') . '\');">' . $this->view->img('/admin/media/images/icon_trash.gif', array('alt' => translateAdmin('Remover'), 'border' => 0)) . '</a>';
                    }
                    $output .= ']]></cell>' . "\n";
                }
                $output .= str_pad('', 4, ' ') . '</row>' . "\n";
            }
        }

        $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=' . CHARSET);

        $output .= '</rows>' . "\n";
        $this->view->output = $output;
        $this->view->setViewsPath(VIEWS_PATH);
        $this->_helper->viewRenderer->setNoRender(false);
        $this->_helper->viewRenderer->setRender('vazia');
    }
    
    /**
     * Criação dinâmica da àrvore, componente dhtmlx
     *
     */
    protected function _treeDhtmlx(){
        $this->_helper->viewRenderer->setNoRender();
        $section = $this->_admin->getSection($this->_getParam('section'));
        if ($section->getSectionListAction()){
            $section = $this->_admin->getSection($section->getSectionListAction());
        }

        if (!$section) {
            throw new Goweb_Exception("A sec&ccedil;&atilde;o n&atilde;o existe.");
        }


        $idCat = $this->_request->id;
        if (!is_numeric($idCat)) {
            $idCat = 0;
        }
        $tree = $section->getTree();
        $treeNodesParams = $section->getTreeParams();
        $nodesParams = $treeNodesParams['nodesParams'];
        $model = $treeNodesParams['model'];
        
        // valida se foram passados os campos necessário para o node
        if (!array_key_exists('id', $nodesParams)) {
            throw new Goweb_Exception("O campo 'id' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }
        if (!array_key_exists('pid', $nodesParams)) {
            throw new Goweb_Exception("O campo 'pid' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }
        if (!array_key_exists('name', $nodesParams)) {
            throw new Goweb_Exception("O campo 'name' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }
        if (!array_key_exists('urlId', $nodesParams)) {
            throw new Goweb_Exception("O campo 'urlId' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }

        $idCol = $nodesParams['id'];
        $pidCol = $nodesParams['pid'];
        $nameCol = $nodesParams['name'];
        $model->where($model->getTableName() . '.' . $pidCol . ' = ?', $idCat);
        $rowset = $model->fetchAll();

        $data = array('id' => $idCat, 'item' => array());
        if ($idCat == 0){
            if (isset($treeNodesParams['rootNodeParams']) && $treeNodesParams['rootNodeParams']) {
                $rootNodeParams = $treeNodesParams['rootNodeParams'];
            } else {
                $rootNodeParams = $nodesParams;
            }
            $data['item'][0] = array(
                        'id' => 'root', 
                        'text' => $this->_addTreeOptions(translateAdmin('Raiz'), 0, $rootNodeParams),
                        'item' => array());
        }
        if ($rowset){
            $items = array();
            foreach ($rowset as $item){
                $childs = $model->getCountFilhos($item->{$idCol});
                $items[] = array(
                            'id' => $item->{$idCol}, 
                            'text' => $this->_addTreeOptions($item->{$nameCol}, $item->{$idCol}, $nodesParams), 
                            'child' => $childs);
            }
            if ($idCat == 0){
                $data['item'][0]['item'] = $items;
            } else {
                $data['item'] = $items;
            }
        }

        if ($this->_getParam('format') == 'xml'){
            $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=' . CHARSET, true);
            $output = '<tree id=\'' . $idCat . '\'>' . "\n";
            foreach ($data['item'] as $item){
                $output .= "<item ";
                foreach ($item as $key => $value){
                    if ($key != 'text'){
                        $output .= $key . "='" . $value . "' ";
                    } else {
                        $output .= $key . "='" . htmlspecialchars($value, ENT_QUOTES, CHARSET, false) . "' ";
                    }
                }
                $output .= '></item>' . "\n";
            }
            $output .= '</tree>' . "\n";
            $this->view->output = $output;
            $this->view->setViewsPath(VIEWS_PATH);
            $this->_helper->viewRenderer->setNoRender(false);
            $this->_helper->viewRenderer->setRender('vazia');
        } else {
            $this->_helper->json($data);
        }
    }
    
    /**
     * A magica esta aqui!
     * Este metodo encaminha a execucao para o Controller_Admin
     * definido no modulo automatico.
     *
     * @param string
     * @param array
    */
    public function __call($action, $arguments) {
        if (strcmp($this->_action, 'index') == 0 && strcmp($this->_controller, 'index') ==0) return $this->_forward('index', 'auth');
        $controller = ucfirst($this->_formatName($this->_controller));
        $adminClass = $controller . '_Admin';

        if (!Goweb::isReadable($adminClass, APPLICATION_PATH)) {
            $this->indexAction();
        }
    }
}