<?php

Goweb::loadClass('Goweb_Controller_Action');
Goweb::loadClass('Goweb_View');

/**
 * Goweb Sitemanager 5 Framework
 * @version    5.0.18
 * @category   Frontoffice
 * @package    Cms
 * @subpackage Controller
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 * 
 * A classe _Controller para o Front-Office disponibiliza
 * as accoes referentes a cada Modulo.
 *
 */
class Cms_GenericController extends Goweb_Controller_Action {

    /**
     * string dummy para o url amigável
     *
     * @var String
     */
    protected $_goString = 'go';

    /**
     * Objecto Goweb_Db_Model
     *
     * @var Goweb_Db_Model
     */
    protected $_model = null;

    /**
     * Objecto Goweb_Config_Ini
     *
     * @var Goweb_Config_Ini
     */
    protected $_moduleConfig = null;

    /**
     * Caminho da pasta onde os ficheiros alterados
     * serao guardados - cache
     *
     * @var string
     */
    protected $_cachePath = '';

    /**
     * Objecto Goweb_Session
     *
     * @var Goweb_Session
     */
    protected $_session = null;

    /**
     * Construtor da Classe
     */
    public function init() {
        $this->_cachePath = ROOT_PATH . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'cms';
        $this->_moduleConfig = new Goweb_Config(Goweb_Config_Ini::load(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.ini', 'base'));
        $this->view->setViewsPath($this->_cachePath);
        $this->_model = Goweb::getModelInstance('Cms_Model_Pagina', 'db', false);
        $this->view->titulo = $this->_request->getBaseUrl();
        $this->view->output = '';
    }

    /**
     * Acao executada se a acao chamada nao existir neste modulo
     *
     * @param string
     * @param array
     */
    public function __call($action, $arguments) {
        if('Action' == substr($action, -6)) {
            $this->_forward('index');
        } else {
            throw new Goweb_Exception("A fun&ccedil;&atilde;o n&atilde;o existe em ". get_class($this));
        }
    }

    /**
     * Acao executada se nenhuma outra acao for especificada
     */
    public function indexAction() {
        $sub = $this->_getLinkStart() . '/' . $this->_goString . '/';
        $pathInfo = str_replace($sub, '', $this->_request->getPathInfo());
        if ($pathInfo == '/') $pathInfo = '';
        if ($pathInfo && 
                ($this->_model->findBy('url', $pathInfo) || 
                $this->_model->findBy('url', substr($pathInfo, 1)))){
                    if (!$this->_model->homepage){
                        return $this->viewAction($this->_model->id);
                    }
        }
        if ($this->_model->findBy('homepage', '1')) {
            if (($this->_getLinkStart() && strlen($pathInfo) == 0 && $this->_getParam('lang')) || (strcmp($pathInfo, $this->_getLinkStart()) != 0 && 
            strcmp($pathInfo, $this->_getLinkStart() . '/') != 0) ){
                return $this->_redirect( $this->_getServerName() . $this->view->baseUrl . (goweb::registry('config')->url->rewrite || strpos($this->_request->getBaseUrl()) !== false ? '' : '/index.php') . $this->_getLinkStart());
            }
            return $this->viewAction($this->_model->id);
        }
        $this->view->setViewsPath(VIEWS_PATH);
        $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
        $this->_helper->viewRenderer->setRender('404');
    }

    /**
     * Acao de visualizacao da pagina
     *
     * @param integer
     */
    public function viewAction($id = null) {
        if (is_null($id)) {
            $id = $this->_getParam('id');
            if (!$this->_validateId($id) || !$this->_model->find($id) || $this->_model->sistema == '1' || $this->_model->activo == '0') {
                $this->view->setViewsPath(VIEWS_PATH);
                $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
                $this->_helper->viewRenderer->setRender('404');
                return false;
            }
        }

        // permiss&otilde;es
        if ($this->_model->privado > 0) {
            if (!$this->_session->logged) {
                $this->_forward('login', 'utilizadores');
                return false;
            }
            $permissaoModel = Goweb::getModelInstance('Cms_Model_Permissao', 'db', false);
            $permissaoModel->where("pagina_id=?", $this->_model->id);
            $permissaoModel->where("perfil_id=?", $this->_session->utilizador['perfil_id']);
            if ($permissaoModel->count() == 0) {
                $this->_forward('login', 'utilizadores');
                return false;
            }
        }

        if ($this->_model->redireccionar) {
            $this->_session->lastId = $this->_model->id;
            return $this->_redirect(substr($this->_model->redireccionar, 0, 1) == '/' ? $this->view->link($this->_model->redireccionar) : $this->_model->redireccionar);
        }
        
        if ($this->_getParam('id') && $this->_model->url){
            if ($this->_model->homepage) {
                if (strcmp($this->_request->getPathInfo(), $this->_getLinkStart()) != 0){
                    return $this->_redirect($this->_getLinkStart());
                }
            } else {
                return $this->_redirect($this->_getLinkStart() . '/' . $this->_goString . '/' . $this->_model->url, array('code' => 301));
            }
        }

        if ($this->_model->sistema || !$this->_model->activo) {
            $this->view->setViewsPath(VIEWS_PATH);
            $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
            $this->_helper->viewRenderer->setRender('404');
            return false;
        }

        $filename = 'cms_'. $id . '_' . Goweb::registry('session')->lang . '.tpl';
        if (!file_exists($this->_cachePath . DIRECTORY_SEPARATOR . $filename)) {
            // cria o directorio 'cache' se n&atilde;o existir
            if (!file_exists($this->_cachePath)) {
                if (!is_writable(ROOT_PATH . DIRECTORY_SEPARATOR . 'cache')) {
                    throw new Goweb_Exception("O directerio '" . ROOT_PATH . DIRECTORY_SEPARATOR . 'cache' . "' n&atilde;o tem permiss&otilde;es de escrita ou n&atilde;o existe.");
                }
                mkdir($this->_cachePath);
                chmod($this->_cachePath, 0777);
            }
            if (!is_writable($this->_cachePath)) {
                throw new Goweb_Exception("O directerio '{$this->_cachePath}' n&atilde;o tem permiss&otilde;es de escrita.");
            }
            // substitui os elementos do tipo <img /> que contenham component:
            $html = self::parseHtmlForComponents(htmlspecialchars_decode($this->_model->texto));
            // abre ficheiro para escrita
            if (!$handle = fopen($this->_cachePath . DIRECTORY_SEPARATOR . $filename, 'w')) {
                throw new Goweb_Exception("N&atilde;o foi poss&iacute;vel abrir o ficheiro '$filename'");
            }
            // grava o $html no ficheiro
            if (fwrite($handle, $html) === false) {
                throw new Goweb_Exception("N&atilde;o foi poss&iacute;vel escrever para o ficheiro '$filename'");
            }
            // fecha o ficheiro
            fclose($handle);
        }

        if ($this->_getParam('print') == '1') {
            $canal = 'print.tpl';
        } else {
            $canal = $this->_model->canal;
        }

        $this->view->id       = $this->_model->id;
        $this->view->titulo   = $this->_model->titulo_site ? $this->_model->titulo_site : $this->_model->titulo;
        $this->view->keywords = $this->_model->keywords;

        $this->_session->lastId = $this->_model->id;

        if ($canal) {
            $this->view->output = $this->view->render($filename);
            $this->view->setViewsPath(VIEWS_PATH);
            $this->_helper->viewRenderer->setNoController(true);
            $this->_helper->viewRenderer->setRender(str_replace('.' . $this->_helper->viewRenderer->getViewSuffix(), '', $canal));
        } else {
            $this->_helper->viewRenderer->setNoController(true);
            $this->_helper->viewRenderer->setRender(str_replace('.' . $this->_helper->viewRenderer->getViewSuffix(), '', $filename));
        }
    }


    /**
     * Funcao auxiliar que retorna verdadeiro quanto um certo
     * id tem filhos.
     * Serve para validar se é o ultimo nível ou não para atribuição
     * de um link.
     *      *
     * @param String $id, id a verificar
     * @return boolean
     */
    protected function _ifIsParent($id) {

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();

        $query = "SELECT * FROM " . $table . " WHERE activo = 1 ";
        $query .= " AND pai_id = ".$id;
        $query .= " AND menu = 1";
        $query .= " AND privado = 0";
        $query .= " AND sistema=0";
        $query .= " ORDER BY pai_id,ordem";

        $result = $db->fetchAll($query);

        if ($result) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * Acao para exibir o formulario de pesquisa nos conteudos do site
     */
    public function pesquisaAction() {
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        Goweb::loadClass('Form_Pesquisa', dirname(__FILE__));
        $form = new Form_Pesquisa();
        $form->render();
        $this->view->form = $form;
        $this->_helper->viewRenderer->setRender('form_search');
    }

    /**
     * Acao que mostra os resultados da pesquisa
     */
    public function resultadoPesquisaAction() {
        
        $invalidChars = array('<', '>', '"', '\'');
        $palavra = str_replace($invalidChars, '', $this->_request->palavra);

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        if (strlen($palavra) > 2) {
            $table = $this->_model->getTableName();

            $this->_model->where('(' . $table . '.privado = 0 AND ' . $table . '.sistema = 0 AND ' . $table . '.activo = 1)');
            $this->view->palavra = $palavra;
            $this->_model->where('(' . $table . '.titulo like "%' . $palavra . '%" OR ' . $table . '.texto_stripped like "%' . $palavra . '%")');

            $this->view->resultado = $this->_model->fetchAll();
            $this->view->message = null;
        } else {
            $this->view->resultado = false;
            $this->view->message = translate('Para que a pesquisa apresente resultados eficazes, introduza no m&iacute;nimo 3 caracteres.');
        }
        $moduloModel = Goweb::getModelInstance('Sistema_Model_Modulo', 'db');
        $moduloModel->where('pesquisa > ?', '0');
        $moduloModel->order('titulo');
        $this->view->modulos = $moduloModel->fetchAll();
        $this->view->modulo_pesquisa = 'Cms';
        $this->view->palavra = $palavra;

        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                        'search.tpl',
                                        'Cms',
                                        'cms-resultado-pesquisa',
                                        'Pesquisa',
            $this->_getParam('print'));
        } else {
            $this->_helper->viewRenderer->setRender('search');
        }
    }

    /**
     * Acao para exibir o mapa do site
     */
    public function mapaAction() {
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();
        if ($this->_session->logged) {
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query  = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem FROM {$table} AS pagina";
            $query .= " LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
            //            $query .= " WHERE permissao.perfil_id={$perfilId} OR (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0) ORDER BY ordem,titulo";
            $query .= " WHERE (permissao.perfil_id={$perfilId} AND pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1)";
            $query .= " OR (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0) ORDER BY ordem,titulo";
        } else {
            $query = 'SELECT id, pai_id, titulo, ordem FROM ' . $this->_model->getTableName() . ' WHERE privado=0 AND activo=1 AND sistema=0 AND menu=1 ORDER BY ordem,titulo';
        }

        $result = $db->fetchAll($query);

        if ($result) {
            $paginas = $this->_getRelated($result, $this->_getParam('pai_id'));
        } else {
            $paginas = false;
        }

        if ($this->_getParam('pai_id')) {
            $paiId = $this->_getParam('pai_id');
        } else {
            $paiId = 0;
        }

        $maxLevel = null;
        if ($this->_getParam('nivel_max')) {
            $maxLevel = $this->_getParam('nivel_max');
        }

        $filo       = array();
        $pagesLevel = array();
        $this->_menuLevelBuilder(array_reverse($paginas), $this->_paiIdsBuilder($paginas), $pagesLevel, $filo, $maxLevel, $paiId, 1);

        if (count($pagesLevel) > 0) {
            $this->view->paginas = $pagesLevel;
        } else {
            $this->view->paginas = false;
        }

        $this->view->paiId  = $this->_getParam('pai_id');
    }
    
    /**
     * Menu em lista Footer
     *
     */
    public function menuListFooterAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getListFooter($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }
    
    public function menuAccordionAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu_id = "menu_id_$pai_id";
        $this->view->menu = $this->_getAccordion($tree->getTree(), null, $pai_id, $id, 0, $parents, $pai_id);
    }
    
    
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getAccordion($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array(), $currrentId = 0){
        if (method_exists($this->_model, 'getPais')){
            $allParents = $this->_model->getPais($idSelected);
        } else {
            $allParents = array($idSelected);
        }
        if ($tree) {
            if (is_null($html)){
                $this->_accordions = array($parentId => -1);
                $html = str_pad(' ', $level) . "<ul class='accordion_root' id='vertical_container_menu_id_$parentId'>\n";
            } else {
                $this->_accordions[$currrentId] = -1;
                $html .= str_pad(' ', $level) . "<ul class='accordion_level_". $level/2 . "' id='vertical_container_menu_id_$currrentId'>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if (in_array($node->id, $allParents)){
                    $this->_accordions[$node->pai_id] = $count;
                }
                
                $count++;
                $html .= str_pad(' ', $level+1)."<li";
                if (count($node->childs) > 0) {
                    $html .= " class='parents'";
                }
                $html .= ">\n";
                $html .= str_pad(' ', $level+1)."<h3>\n";
                if (!is_null($node->url)){
                    $html .= "<a href='" . ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'>";
                } else {
                    $html .= "<a href='#nolink' onclick='return false;'>";
                }
                
                $html .= '<span>' . $node->titulo . '</span>';
                $html .= "</a>";
                $html .= "</h3>";
                $html .= "<div class='acc-section'>";
                $html .= "  <div class='acc-content'>";
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getAccordion($node->childs, $html, $parentId, $idSelected, $level, $parents, $node->id);
                    $level--;
                    $level--;
                }
                $html .= "  </div>\n";
                $html .= "</div>\n";
                $html .= str_pad(' ', $level+1)."</li>\n";
            }
            //$html .= '</div>' . "\n";
            
            $html .= str_pad(' ', $level) . "</ul>";
            if ($level === 0){
                $html .= "<script type='text/javascript'>
/* <![CDATA[ */\n";
                foreach ($this->_accordions as $accordion => $selected){
                $html .= "var vertical_container_id_" . $accordion . "=new TINY.accordion.slider('vertical_container_id_" . $accordion . "');
vertical_container_id_" . $accordion . ".init('vertical_container_menu_id_" . $accordion . "','h3',0,".$selected.",'acc-selected');\n";
                }
$html .= "
/* ]]> */" . '
</script>';
            }
        }
        return $html;
    }
    
    /**
     * Menu em lista
     *
     */
    public function menuListAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getList($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }

    /**
     * Menu em lista
     *
     */
    public function menuListDropMultiAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getListDropMulti($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }
    

    /**
     * Menu em lista
     *
     */
    public function menuListDropAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getListDrop($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }
    
    /**
     * Menu em lista
     *
     */
    public function menuList4Action(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getList4($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }

    /**
     * Menu em lista
     *
     */
    public function menuList3Action(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getList3($tree->getTree(), null, $pai_id, $id, 0, $parents);
    }
    
    
    /**
     * Menu em lista
     *
     */
    public function menuList2Action(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $this->_helper->viewRenderer->setRender('menu-list');
        $this->view->menu = '';
        if ($this->_validateId($id) && $id > 0 && !$this->_model->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_model->find($pai_id)) return false;
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        $this->view->menu = $this->_getList2($tree->getTree(), null, $pai_id, $id, 0, $parents);
        $this->view->menu .= '<script type="text/javascript">
var menu_id_' . $pai_id . '=new menu.dd("menu_id_' . $pai_id . '");
menu_id_' . $pai_id . '.init("menu_id_' . $pai_id . '","menuhover");
</script>';
    }
    
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getListFooter($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<div id='menu_id_$parentId' class='menu_list_footer'><ul>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . "<li";
                $cssClass = '';
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'child';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'top';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                $html .= "><a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                }
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= "top_link";
                }
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'drop';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= ">";
                $html .=  '<span>' . $node->titulo . '</span>';
                $html .= '</a>';
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getListFooter($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1);
                $html .= "</li>\n";
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
            if ($level == 0){
                $html .= str_pad(' ', $level) . "</div>\n";
            }
        }
        return $html;
    }
    

    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getListDrop($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<div id='menu_id_$parentId' class='dropline'>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                if ($level == 0){
                    $html .= str_pad(' ', $level) . "<ul";
                    $cssClass = '';
                    if (in_array($node->id, $parents) && $level == 0){
                        $cssClass .= 'current';
                    } else {
                        if ($level == 0){
                            $cssClass .= 'select';
                        } else {
                            $cssClass .= 'sub';
                        }
                    }
                    if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                    $html .= ">\n";
                }
                $html .= str_pad(' ', $level+1) . "<li";
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'current_sub';
                }
                if (strlen($cssClass) > 0) $html .= ' class="' . $cssClass . '"';
                
                $html .= "><a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                }
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= ">";
                $html .=  '<span>' . $node->titulo . '</span>';
                $html .= "<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->";
                if (count($node->childs) > 0 && $level == 0) {
                    $html .= str_pad(' ', $level) . "<ul";
                    $cssClass = '';
                    if (in_array($node->id, $parents)){
                        $cssClass .= 'sub_active';
                    } else {
                        $cssClass .= 'sub';
                    }
                    if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                    $html .= ">\n";
                    
                    $level++;
                    $level++;
                    $html = $this->_getListDrop($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                    $html .= str_pad(' ', $level) . "</ul>\n";
                }
                $html .= str_pad(' ', $level+1);
                if (count($node->childs) > 0) {
                    $html .= "<!--[if lte IE 6]></td></tr></table></a><![endif]--></li>\n";
                } else {
                    $html .= "</li>\n";
                }
                if ($level == 0){
                    $html .= str_pad(' ', $level) . "</ul>\n";
                }
                
                
            }
            if ($level == 0){
                $html .= str_pad(' ', $level) . "</div>\n";
            }
        }
        return $html;
    }
    

    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getListDropMulti($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul id='menu_id_$parentId' class='droplineMulti'>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . "<li";
                $cssClass = '';
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'child';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'top';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                $html .= "><a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                }
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= "top_link";
                }
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'down';
                }
                if (strlen($cssClass) > 0) $html .= ' class="' . $cssClass . '"';
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= ">";
                $html .=  '<span>' . $node->titulo . '</span>';
                $html .= "<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->";
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getListDropMulti($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1);
                if (count($node->childs) > 0) {
                    $html .= "<!--[if lte IE 6]></td></tr></table></a><![endif]--></li>\n";
                } else {
                    $html .= "</li>\n";
                }
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }
    
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getList4($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul id='menu_id_$parentId' class='pro_dropdown_2'>\n";
            } else {
                if ($level == 2){
                    $html .= str_pad(' ', $level) . "<ul class='sub'>\n";
                }else{
                    $html .= str_pad(' ', $level) . "<ul>\n";
                }
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . "<li";
                $cssClass = '';
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'child';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'top';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                $html .= "><a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                }
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= "top_link";
                }
                if (count($node->childs) > 0 && $level > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'fly';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= ">";
                if ($level == 0){
                    $html .= "<span";
                    if (count($node->childs) > 0) $html .= " class='down'";
                    $html .= ">";
                }
                $html .=  '<span>' . $node->titulo . '</span>';
                if ($level == 0) $html .=  '</span>';
                $html .= "</a>";
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getList4($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1) . "</li>\n";
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }
    
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getList3($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($level>2) return $html;
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . '
	<link rel="stylesheet" type="text/css" href="' . $this->view->baseUrl . '/media/js/sdmenu/sdmenu.css" />
	<script type="text/javascript" src="' . $this->view->baseUrl . '/media/js/sdmenu/sdmenu.js">
		/***********************************************
		* Slashdot Menu script- By DimX
		* Submitted to Dynamic Drive DHTML code library: http://www.dynamicdrive.com
		* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
		***********************************************/
	</script>
	<script type="text/javascript">
	// <![CDATA[
	var menu_id_' . $parentId . ';
	window.onload = function() {
		menu_id_' . $parentId . ' = new SDMenu("menu_id_' . $parentId . '");
		menu_id_' . $parentId . '.init();
	};
	// ]]>
	</script>';
                
                $html .= "<div style='float: left' id='menu_id_$parentId' class='sdmenu'>\n";
            } else {
                $html .= str_pad(' ', $level) . "\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                if ($level == 0){
                    $html .= str_pad(' ', $level+1) . "<div>\n<span";
                    $cssClass = '';
                    if (in_array($node->id, $parents)){
                        $cssClass .= 'selected';
                    }
                    if (strlen($cssClass)) $cssClass .= ' ';
                    if (count($node->childs) > 0) {
                        $cssClass .= 'filhos';
                    }else{
                        $cssClass .= 'semFilhos';
                    }
                    if (strlen($cssClass)) $cssClass = ' class="' . $cssClass . '"';
                    $html .= $cssClass . '>';
                }
                if ($level != 0 || count($node->childs) == 0){
                    $html .= "<a href='";
                    if (is_null($node->url)){
                        $html .= $this->view->baseUrl ."' onclick='return false;'";
                    } else {
                        $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                    }
                    //if ($level == 0) $html .= ' class="teste"';
                    $cssClass = '';
                    if (in_array($node->id, $parents)){
                       $cssClass .= 'selected';
                    }
                    if (strlen($cssClass)) $cssClass .= ' ';
                    if ($level != 0) {
                        $cssClass .= 'menuLink';
                    }
                    if (strlen($cssClass)) $cssClass = ' class="' . $cssClass . '"';
                    $html .= $cssClass;
                    if ($this->_model->colExists('popup') && $node->popup){
                        $html .= ' target="_blank"';
                    }
                    $html .= ">";
                    $html .= '<span>' . $node->titulo . '</span>' . "</a>\n";
                } else {
                    $html .= '<span>' . $node->titulo . '</span>';
                }
                if ($level == 0)
                $html .= str_pad(' ', $level) . "</span>\n";
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getList3($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                if ($level == 0)
                $html .= str_pad(' ', $level) . "</div>\n";
                
            }
            
            if ($level == 0)
            $html .= "</div>\n";
        }
        return $html;
    }
    
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getList2($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul class='dropdown-menu' id='menu_id_$parentId'>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . "<li>";
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'dropdown-menulink';
                }
                if (count($node->childs) > 0 && $level > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'sub';
                }
                if (strlen($cssClass)) $cssClass = ' class="' . $cssClass . '"';
                $html .= "<a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id)) . "'";
                }
                $html .= "$cssClass";
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= '>';
                $html .= '<span>' . $node->titulo . '</span>' . "</a>\n";
                
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getList2($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1) . "</li>\n";
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getList($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul id='menu_id_$parentId'>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . "<li";
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'child';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                $html .= "><a href='";
                if (is_null($node->url)){
                    $html .= $this->view->baseUrl ."' onclick='return false;";
                } else {
                    $html .= ($node->url ? $this->view->link('/' . $this->_goString . '/'.$node->url) : $this->view->link('/cms/view/id/' . $node->id));
                }
                $html .= "'";
                if ($this->_model->colExists('popup') && $node->popup){
                    $html .= ' target="_blank"';
                }
                $html .= ">" . '<span>' . $node->titulo . '</span>' . "</a></li>\n";
                
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getList($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }
    
    /**
     * Obter todos os pais para o id seleccionado
     *
     * @param int $pai_id
     * @return array
     */
    protected function _getAllParents($pai_id = 0){
        $parents = array();

        $parents[] = $pai_id;

        if ($this->_model->find($pai_id)){
            while ($this->_model->find($this->_model->pai_id)){
                $parents[] = $this->_model->id;
            }
        }
        return $parents;
    }

    /**
     * Acao para exibir o menu do site
     */
    public function menuAction() {
        $menu_id = $this->_getParam('menu_id');
        if (!$menu_id) {
            $menu_id = 1;
        }

        $menu_nome = 'menu_' . $menu_id;

        $idSelected = $this->_getParam('id_selected');

        // menu
        Goweb::loadClass('Goweb_Js_JSCookMenu');
        $menu = new Goweb_Js_JSCookMenu($menu_nome);

        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();
        if ($this->_session->logged) {
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query  = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem, pagina.semlink FROM {$table} AS pagina";
            $query .= " LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
            $query .= " WHERE (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND permissao.perfil_id={$perfilId}) OR (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0) ORDER BY ordem,titulo";
        } else {
            $query = "SELECT id, pai_id, titulo, ordem, semlink FROM {$table} WHERE privado=0 AND activo=1 AND sistema=0 AND menu=1 ORDER BY ordem,titulo";
        }

        $result = $db->fetchAll($query);
         
        $pai_id = 0;
        if ($this->_validateId($this->_getParam('pai_id'))) {
            if ($this->_model->find($this->_getParam('pai_id'))) {
                $pai_id = $this->_getParam('pai_id');

            }
        }

        $paginas = null;
        if (count($result) > 0) {
            foreach ($result as $pagina) {
                $menu->addNode($pagina['id'],
                $pagina['pai_id'],
                $pagina['titulo'],
                               '',
                ($pagina['semlink'] === '0') ? $this->view->link('/cms/view/id/' . $pagina['id'] . '/') : 'notLink');
            }
            $paginas = $menu->build($pai_id);
        }

        $this->view->menu_nome = $menu_nome;

        $this->view->id_selected = $idSelected;
        $this->view->paginas = $paginas;
    }

    /**
     * Acao para exibir o menu privado do site
     */
    public function menuPrivadoAction() {
        $pai_id = $this->_getParam('pai_id');

        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $ids = $this->_getIdsPaginasPerfil($this->_session->utilizador['perfil_id']);
        if ($ids) {
            $this->_model->where('id IN (' . implode(",", $ids) . ')');
        }

        $this->_model->where('pai_id = ?', $pai_id);
        $this->_model->where('activo = 1');
        $this->_model->where('menu = 1');
        $this->_model->where('sistema = 0');

        $this->_model->order('ordem');
        $result = $this->_model->fetchAll();

        $this->view->result = $result;

        $this->_helper->viewRenderer->setRender('menu_privado');
    }

    /**
     * Acao para exibir o menu de footer
     */
    public function menuFooterAction() {
        $pai_id = $this->_getParam('pai_id');
        $limit = $this->_getParam('limit');
        if (!$limit)
        $limit ="4";
        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        /**
         * Query usando a plataforma!!
         */
        $pagina=$this->_model->getTableName();


        $query="";
        if ($this->_session->logged){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query .= " (permissao.perfil_id={$perfilId} AND {$pagina}.activo=1 AND {$pagina}.sistema=0 AND {$pagina}.menu=1 AND {$pagina}.pai_id={$pai_id}) OR ";
        }
        $query .= " ({$pagina}.activo=1 AND {$pagina}.sistema=0 AND {$pagina}.menu=1 AND {$pagina}.privado=0  AND {$pagina}.pai_id={$pai_id}) ";

        $this->_model->where($query);
        if ($this->_session->logged)
        $this->_model->joinLeft("cms_permissao AS permissao", "{$pagina}.id=permissao.pagina_id");


        $this->_model->limit($limit, 0);
        $this->_model->order('ordem');
        $result = $this->_model->fetchAll();

        if ($result)
        $this->view->count = $result->count();
        $this->view->result = $result;
        $this->_helper->viewRenderer->setRender('menu_footer');
    }

    /**
     * Este menu suporta 4 niveis.
     */
    public function slideMenuAction() {
        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $this->view->id = $this->_getParam('id');

        if ($this->_getParam('subpagina')) {
            $this->view->pai_id = $this->_getParam('subpagina');
        } else {
            $this->view->pai_id = "0";
        }

        $table = $this->_model->getTableName();
        /*
         * Ter em conta os perfis de utilizador!!
         *
         */

        $sql = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem FROM {$table} as pagina LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
        $sql .= " WHERE ";
        if ($this->_session->logged){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $sql .= " (permissao.perfil_id={$perfilId} AND pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1";
            if ($this->_getParam('subpagina')) {
                $sql .= " AND pagina.pai_id IN ( " . $this->_getAllSubIds($this->_getParam('subpagina')) . " ) ";
            }
            $sql .= ") OR ";
        }
        $sql .= " (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0 ";
        if ($this->_getParam('subpagina')) {
            $sql .= " AND pagina.pai_id IN ( " . $this->_getAllSubIds($this->_getParam('subpagina')) . " ) ";
        }
        $sql .= ") ";
        $sql .= " ORDER BY pagina.pai_id, pagina.ordem";


        $config = Goweb::registry('config');
        $optionsDb = array('host'     => $config->database->host,
                           'dbname'   => $config->database->dbname,
                           'username' => $config->database->username,
                           'password' => $config->database->password);

        Goweb::loadClass('Goweb_Db');

        $adapter = Goweb_Db::factory($config->database->type, $optionsDb);
        $result  = $adapter->query($sql);

        $struct = array();

        if ($result) {
            foreach ($result as $item) {
                $struct[$item['id']] = array('id'     => $item['id'],
                                             'pai_id' => $item['pai_id'],
                                             'titulo' => $item['titulo']);
            }
        }

        $this->view->result = $struct;
        $this->_helper->viewRenderer->setRender('slide_menu');

    }

    /**
     * Este menu suporta niveis infinitos.
     * Versão 19-05-2008 by RG
     */
    public function unlimitedSlideMenuAction() {
        $this->loadJavascript('/media/js/dd_slide_menu.js');
        $this->loadCss('/media/css/dd_slide_menu.css');
        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $useLink = "/cms/view/id/";

        /**
         * mypaiId eh usado para fixar o pai_id
         */
        if(!$this->_session->mypaiId){
            if ($this->_getParam('subpagina')) {
                $this->view->pai_id = $this->_getParam('subpagina');
            } else {
                $this->view->pai_id = "0";
            }
        }

        if($this->_getParam('id_selected')) {
            $id_selected = $this->_getParam('id_selected');
        } else {
            $id_selected = 0;
        }
        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();

        $query = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem FROM {$table} as pagina LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
        $query .= " WHERE ";
        if ($this->_session->logged){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query .= " (permissao.perfil_id={$perfilId} AND pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1";
            if($this->_session->mypaiId){
                $query .= " AND pai_id = ".$this->_session->mypaiId;
            } else {
                $query .= " AND pai_id = ".$this->view->pai_id;
            }
            $query .= ") OR ";
        }
        $query .= " (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0 ";
        if($this->_session->mypaiId){
            $query .= " AND pai_id = ".$this->_session->mypaiId;
        } else {
            $query .= " AND pai_id = ".$this->view->pai_id;
        }
        $query .= ") ";
        $query .= " ORDER BY pagina.pai_id, pagina.ordem";

        $result = $db->fetchAll($query);

        $struct = '';

        if ($result) {
            $struct .= "<ul>";
            foreach ($result as $item) {
                if($id_selected > 0 && $id_selected == $item['id']){
                    $struct .= "<li id='usm_".$item['id']."'><a id='open".$item['id']."' name='usm_selected' ";
                } else {
                    $struct .= "<li id='usm_".$item['id']."'><a id='open".$item['id']."'";
                }
                if($this->_ifIsUSMParent($item['id'])){
                    $struct .= "href='#'>".$item['titulo']."</a>";
                } else {
                    $struct .= "href='".$useLink.$item['id']."'>".$item['titulo']."</a>";
                }
                $this->_getAllSubUSMIds($struct, $item['id'], $useLink, $id_selected);
            }
            $struct .= "</li></ul>";
        }

        $this->view->result = $struct;
        $this->view->rootId = $this->_getParam('subpagina');
        $this->_helper->viewRenderer->setRender('unlimited_slide_menu');

    }

    /**
     *
     * Funcao recursiva auxiliar que cria toda a estrutura em àrvore do menu
     * mediante o id do pai.
     *
     */
    protected function _getAllSubUSMIds(&$struct, $id, $useLink, $id_selected=0) {
         
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();

        $query = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem FROM {$table} as pagina LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
        $query .= " WHERE ";
        if ($this->_session->logged){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query .= " (permissao.perfil_id={$perfilId} AND pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1";
            $query .= " AND pai_id = ".$id;
            $query .= ") OR ";
        }
        $query .= " (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0 ";
        $query .= " AND pai_id = ".$id;
        $query .= ") ";
        $query .= " ORDER BY pagina.pai_id, pagina.ordem";


        $result = $db->fetchAll($query);

        if ($result) {
            $struct .= "<ul>";
            foreach ($result as $item) {
                if($id_selected > 0 && $id_selected == $item['id']){
                    $struct .= "<li id='usm_".$item['id']."'><a name='usm_selected' ";
                } else {
                    $struct .= "<li id='usm_".$item['id']."'><a ";
                }
                if($this->_ifIsUSMParent($item['id'])){
                    $struct .= "href='#'>".$item['titulo']."</a>";
                } else {
                    $struct .= "href='".$useLink.$item['id']."'>".$item['titulo']."</a>";
                }
                $this->_getAllSubUSMIds($struct, $item['id'], $useLink, $id_selected);
            }
            $struct .= "</li></ul>";
        }
        return $struct;

    }

    /**
     *
     * Funcao auxiliar que retorna verdadeiro quanto um certo
     * id tem filhos.
     * Serve para validar se é o ultimo nével ou não para atribuição
     * de um link.
     *
     */
    protected function _ifIsUSMParent($id) {
         
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');

        $db = $this->_model->getAdapter();
        $table = $this->_model->getTableName();

        $query = "SELECT pagina.id, pagina.pai_id, pagina.titulo, pagina.ordem FROM {$table} as pagina LEFT JOIN cms_permissao AS permissao ON (pagina.id=permissao.pagina_id)";
        $query .= " WHERE ";
        if ($this->_session->logged){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query .= " (permissao.perfil_id={$perfilId} AND pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1";
            $query .= " AND pai_id = ".$id;
            $query .= ") OR ";
        }
        $query .= " (pagina.activo=1 AND pagina.sistema=0 AND pagina.menu=1 AND pagina.privado=0 ";
        $query .= " AND pai_id = ".$id;
        $query .= ") ";
        $query .= " ORDER BY pagina.pai_id, pagina.ordem";


        $result = $db->fetchAll($query);

        if ($result) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * Funcao auxiliar que devolve todos os ids filhos de um determinado
     * noh.
     *
     * @param integer
     *
     * @return string
     */
    protected function _getAllSubIds($pai_id) {
        $table = $this->_model->getTableName();

        $sql = "SELECT * FROM {$table} ";
        $sql .= " WHERE privado=0 AND ";
        $sql .= "       activo=1 AND ";
        $sql .= "       sistema=0 AND ";
        $sql .= "       menu=1 ";
        $sql .= " ORDER BY pai_id, ordem";

        $config = Goweb::registry('config');
        $optionsDb = array('host'     => $config->database->host,
                           'dbname'   => $config->database->dbname,
                           'username' => $config->database->username,
                           'password' => $config->database->password);

        Goweb::loadClass('Goweb_Db');

        $adapter = Goweb_Db::factory($config->database->type, $optionsDb);
        $result  = $adapter->query($sql);

        $idsArray = array();
        $idsArray[] = $pai_id;

        if ($result) {
            foreach ($result as $item) {
                if (in_array($item['pai_id'], $idsArray)) {
                    if (!in_array($item['id'], $idsArray)) {
                        $idsArray[] = $item['id'];
                    }
                }
            }
        }

        return implode(",", $idsArray);

    }

    /**
     * Devolve as paginas que tenham o perfil_id igual ao
     * do utilizador logado
     *
     * @param int $perfil_id
     *
     * @return array | boolean
     */
    protected function _getIdsPaginasPerfil($perfil_id) {
        $permissaoModel = Goweb::getModelInstance('Cms_Model_Permissao', 'db');
        $permissaoModel->where('perfil_id = ?', $perfil_id);
        $paginas = $permissaoModel->fetchAll();

        if ($paginas) {
            $ids = array();
            foreach ($paginas as $pagina) {
                $ids[] = $pagina->pagina_id;
            }
            return $ids;
        }

        return false;
    }

    /**
     * Acao para exibir uma imagem aleatoria da pasta upload/fix
     */
    public function getFixImageAction(){
        $this->_session = Goweb::registry('session');
         
        if (!$this->_session->fixImages) {
            $this->_session->fixImages = array();
             
            $images = array();
             
            $dir = WWW_PATH . "/uploads/fix/";
             
            $dirhandle = opendir("$dir");
            while ($arquivos = readdir($dirhandle)) {
                if ($arquivos != "." && $arquivos != "..") {
                    $type = exif_imagetype($dir . $arquivos);
                    // se o tipo do ficheiro lido for uma imagem do tipo GIF, JPEG ou PNG
                    if (($type == IMAGETYPE_GIF) || ($type == IMAGETYPE_JPEG) || ($type == IMAGETYPE_PNG)) {
                        $this->_session->fixImages[] = $arquivos; // incrementa o array
                    }
                }
            }
            $rand_keys = array_rand($this->_session->fixImages, 1);
            $image = $this->_session->fixImages[$rand_keys];
        } else {
            $rand_keys = array_rand($this->_session->fixImages, 1);
            $image = $this->_session->fixImages[$rand_keys];
        }
         
        echo "<a href=\"/\"><img src=\"/uploads/fix/" . $image . "\" alt=\"Topo 4\" border=\"0\" /></a>";
    }

    /**
     * Obter o ínicio dos links, útil para costumizações
     *
     * @return string
     */
    protected function _getLinkStart(){
        $sub = '';
        if($this->_getParam('lang')){
            $sub = '/' . $this->_getParam('lang') . $sub; 
        }
        return $sub;
    }

    /**
     * Funcao recursiva para nivelar os nos do menu.
     *
     * @param array
     * @param array
     * @param string
     * @param array
     * @param integer
     *
     */
    protected function _menuLevelBuilder($paginas, $nodeWithChieldren, &$pagesLevel, &$filo, $maxLevel = null, $pai_id = 0,  $nivel = 1) {
        // preencher a pilha
        foreach ($paginas as $key => $pagina) {
            if ($pagina['pai_id'] == $pai_id) {
                $pagina['nivel'] = $nivel;
                $pagina['fathersLevel'] = $nivel - 1;
                if (in_array($pagina['id'], $nodeWithChieldren)) {
                    $pagina['hasSon'] = true;
                } else {
                    $pagina['hasSon'] = false;
                }
                if ($maxLevel) {
                    if ($pagina['nivel'] <= $maxLevel) {
                        if ($pagina['nivel'] == $maxLevel) {
                            $pagina['hasSon'] = false;
                        }
                        $filo[] = $pagina;
                    }
                } else {
                    $filo[] = $pagina;
                }

            }
        }

        // visitar o ultimo elemento
        $visited = array_pop($filo);
        if (in_array($visited['pai_id'], $nodeWithChieldren)) {
            $nivel = $visited['nivel'] + 1;
            // verifica se o elemento tem irmaos no nivel
            if ($this->_hasBrother($visited['pai_id'], $filo)) {
                $visited['hasBrother'] = true;
            } else {
                $visited['hasBrother'] = false;
            }
        }

        // se a pilha contiver elementos ou o array visited tiver elemento
        if ((count($filo) > 0) || (count($visited) > 0)) {
            // chama a funcao novamente
            if ($visited['pai_id'] != '0'){
            	$pagesLevel[] = $visited;
            }
            $this->_menuLevelBuilder($paginas, $nodeWithChieldren, $pagesLevel, $filo, $maxLevel, $visited['id'], $nivel);
        }
    }

    /**
     * Esta funcao preenche um array com todos os ids das paginas
     * que tem sub-paginas.
     *
     * @param array
     *
     * @return array
     */
    protected function _paiIdsBuilder($paginas) {
        $nodeWithChieldren = array();
        foreach ($paginas as $key => $pagina) {
            if (!in_array($pagina['pai_id'], $nodeWithChieldren) ) {
                $nodeWithChieldren[] = $pagina['pai_id'];
            }
        }
        return $nodeWithChieldren;
    }

    /**
     * Esta funcao verifica se um determinado noh tem irmaos na pilha
     *
     * @param integer
     * @param array
     *
     * @return boolean
     */
    protected function _hasBrother($pai_id, $filo) {
        $hasBrother = 0;
        foreach ($filo as $noh) {
            if ($pai_id == $noh['pai_id']) {
                $hasBrother++;
            }
        }
        return $hasBrother;
    }

    /**
     * Funcao auxiliar que relaciona os nos das arvores das paginas
     *
     * @param array
     * @param integer
     *
     * @return array | boolean
     */
    protected function _getRelated($result, $pai_id) {
        if ($pai_id > 0) {
            $ids[0]     = $pai_id;
            $paginas[0] = $pai_id;
            if ($result) {
                foreach ($result as $pagina) {
                    if (in_array($pagina['pai_id'], $ids)) {
                        $ids[] = $pagina['id'];
                        $paginas[] = array('id'     => $pagina['id'],
                                           'pai_id' => $pagina['pai_id'],
                                           'ordem'  => $pagina['ordem'],
                                           'titulo' => $pagina['titulo']);
                    }
                }
                array_shift($paginas);
                return $paginas;
            } else {
                return false;
            }
        } else {
            return $result;
        }
    }
    
    protected function _getPrivate(){
        $query="";
        $pagina = $this->_model->getTableName();
        if ($this->_session->logged && isset($this->_session->utilizador['perfil_id'])){
            $perfilId = $this->_session->utilizador['perfil_id'];
            $query .= " (permissao.perfil_id={$perfilId} AND {$pagina}.activo=1 AND {$pagina}.sistema=0 AND {$pagina}.menu=1) OR ";
        }
        $query .= " ({$pagina}.activo=1 AND {$pagina}.sistema=0 AND {$pagina}.menu=1 AND {$pagina}.privado=0) ";
        $this->_model->where($query);
        $this->_model->order('ordem'); // ordena as paginas pelo campo ordem da bd
        if ($this->_session->logged){
            $this->_model->joinLeft(array('permissao' => 'cms_permissao'), "{$pagina}.id=permissao.pagina_id");
        }
    }
    
    public function _getTree($idCol = 'id', $pidCol = 'pai_id', $nameCol = 'titulo'){
        goweb::loadClass('Goweb_Tree');
        $tree = new Goweb_Tree($idCol, $pidCol);
        $this->_getPrivate();

        // n&atilde;o carregar as chaves estrangeiras
        $this->_model->loadForeigns(false);

        $fetchCols = array($idCol, $pidCol, $nameCol, 'redireccionar', 'url', 'menu', 'semlink', 'activo');
        if ($this->_model->colExists('popup')){
            $fetchCols[] = 'popup';
        }

        $rowset = $this->_model->fetchAll($fetchCols);

        if ($rowset) {
            foreach ($rowset as $row) {
                if (!$row->menu || !$row->activo) continue;
                $node = array($idCol => $row->{$idCol},
                    $pidCol => $row->{$pidCol},
                    $nameCol => $this->view->escapeTitle($row->{$nameCol}),
                    'redireccionar' => $row->redireccionar,
                    'url' => $row->semlink ? null : ($row->url ? $row->url : ""),
                    );
                if ($this->_model->colExists('popup')){
                    $node['popup'] = $row->popup;
                }

                // adiciona o node
                $tree->addElement($node);
            }
        }
        return $tree;
    }

    /**
     * Funcao auxiliar que altera o codigo da pagina de forma que os
     * componentes nela inseridos sejam correctamente exibidos.
     *
     * @param string
     *
     * @return string
     */
    static function parseHtmlForComponents($html) {
        preg_match_all('#<img[^>]+>#', $html, $images);
        foreach ($images[0] as $image) {
            $attributes = explode(' ', $image);
            foreach ($attributes as $key => $attribute) {
                if (strpos($attribute, 'component:')) {
                    $attributeArray = explode('=', $attribute);
                    $component = trim(substr($attributeArray[1], 11), '"');
                    $html = str_replace($image, '<?php echo $this->component(\'' . $component . '\'); ?>', $html);
                }
                if (strpos($attribute, 'output:')) {
                    $html = str_replace($image, '', $html);
                }
            }
        }
        return $html;
    }

    /**
     * Esta funcao exibe um determinado componente (quando chamado directamente)
     * dentro da estrutura do site (template base).
     *
     * @param Goweb_View
     * @param string
     * @param Goweb_Db_Model
     * @param string
     * @param string
     * @param integer
     * @param boolean
     */
    static public function renderOutput($view,
        $template,
        $modulo,
        $slug,
        $titulo,
        $print = '0',
        $outputComponent = true,
        $canal = 'base.tpl') {
        $viewRenderer = Zend_Controller_Action_HelperBroker::getExistingHelper('viewRenderer');
        /**
         * A $session e' necessa'ria para quando e' chamado esta'ticamente
         * como por exemplo: Cms_Controller::renderOutput(...);
         * Pedro Pinto
         */
        $session = Goweb::registry('session');
        $view->id = $session->lastId;

        $view->titulo = $titulo;
        $view->output = $view->render($template);
        $view->setViewsPath(VIEWS_PATH);
        if ($print) $canal = 'print.tpl';
        $viewRenderer->setRender(str_replace('.' . $viewRenderer->getViewSuffix(), '', $canal));
    }
}
