Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> xml, xsl и mvc (на примере), хотелось бы услышать мнение OOP-мыслящих 
:(
    Опции темы
izOne
  Дата 27.6.2005, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: 3
Всего: 4



Application:
Код

<?php
require_once('PEAR.php');
require_once('MDB2.php');
require_once('XML/XPath.php');
class Application{
    // public
    var $info = array(
        'ver'        => '0.0.1',
        'author'    => 'Alexey Pakhomov',
    );
    // private
    var $_controller = null;
    var $_transformer = null;
    var $_domXML = object;
    var $_domXSL = object;
    
    //    Constructor    
    function Application($args = null){
        $db = &MDB2::singleton(CFG_SQL_DSN);
        if(PEAR::isError($db)){
            die($db->getMessage());
        }
        $db->setFetchMode(MDB2_FETCHMODE_ASSOC);
        $db->query('SET NAMES cp1251');
        
        $this->_conroller    = &Controller::Singleton();
        $this->_transformer    = &Transformer::Singleton();
        
        $this->_domXML = new XML_Xpath();
        $this->_domXML->load(CFG_DIR_TEMPLATES.'/application.xml', 'file');
        $this->_domXSL = new XML_Xpath();
        $this->_domXSL->load(CFG_DIR_TEMPLATES.'/xhtml.xsl', 'file');
    }
    
    function & Singleton(){
        static $singleton = null;
        if(!$singleton){
            $singleton = true;
            $singleton = new Application();
        }
        return $singleton;
    }
    
    function run(){
        $this->_conroller->run();
        $this->_transformer->process($this->_domXML, $this->_domXSL);
    }

    function riseError(&$o){
        if(PEAR::isError($o)){
            $this->terminate('pearError', $o);
        }
    }

    function domAppend2Blocks(&$domElement, $position = null){
        if(is_object($domElement) AND $position != null){
            $rs = $this->_domXML->ctx->xpath_eval('//application/content/blocks[@position="'.$position.'"]');
            if(empty($rs->nodeset[0])){
                $blocks = $this->getBlock('blocks');
                $blocks->set_attribute('position', $position);
                $content = $this->_domXML->ctx->xpath_eval('//application/content');
                if(is_a($content->nodeset[0], 'domelement')){
                    $content->nodeset[0]->append_child($blocks);
                }
                $rs = $this->_domXML->ctx->xpath_eval('//application/content/blocks[@position="'.$position.'"]');
            }
            $rs->nodeset[0]->append_child($domElement);
        }
    }
    
    function & getBlock($name = 'block'){
        return $this->_domXML->xml->create_element($name);
    }
}
?>


Controller:
Код

<?php
class Controller{
    var $request = array();
    // private
    var $_db = null;
    var $_app = null;
    var $_modObect = object;
    
    function Controller(){
        $this->_db    = &MDB2::singleton();
        $this->_app = &Application::Singleton();
    }
    
    function & Singleton(){
        static $singleton = false;
        if(!$singleton){
            $singleton = true;
            $singleton =  new Controller;
        }
        return $singleton;
    }
    
    function run(){
        $tmp = split("\?", substr($_SERVER['REQUEST_URI'], 1));
        $request = split('/', $tmp[0]);
        $this->request = split('/', $tmp[0]);
        $module = $this->request[0];
        if(!defined('CMS_MODULE_INT') AND !defined('CMS_MODULE_INT') AND empty($module)){
            define('CMS_MODULE_INT', 'index');
            define('CMS_MODULE_EXT', 'index');
        }elseif(!defined("CMS_MODULE_EXT")){
       $module = $request[0];
       if(!is_dir(CFG_DIR_SYSTEM.'/modules/'.$module)){
           define('CMS_MODULE_EXT', 'articles');
       }else{
           define("CMS_MODULE_EXT", $module);
           array_shift($this->rq);
       }
        }
        if(!defined("CMS_MODULE_INT")){
       $query = $this->_db->query("SELECT `int` FROM `modules` WHERE `ext`='".CMS_MODULE_EXT."'");
       if(!PEAR::isError($query)){
                $query->fetchInto($rs);
                define("CMS_MODULE_INT", $rs['cms_int']);
            }
        }
        if($this->loadModule(CMS_MODULE_INT) == true){
            $this->loadBlocks();
            $this->_modObject->run();
        }else{
            echo 'Module ['. CMS_MODULE_INT .'] not found';
        }
    }

    // core functions
    function loadModule($module){
        if(is_file($file = CFG_DIR_SYS .'/module/'.$module.'.php')){
            require_once($file);
            $modClassName = 'module_'.$module;
            $this->_modObject = & new $modClassName();
            if(is_dir($dir = CFG_DIR_SYS .'/'.$module.'/ext')){
                $dh = dir($dir);
                while (false !== ($file = $dh->read())) {
                    if($file !== '.' AND $file !== '..'){
                        $extClassName = 'ext_'. $module .'_'. basename($file, '.php');
                        require_once($dir .'/'. $file);
                        aggregate($this->_modObject, $extClassName);
                    }
                }
                $dh->close();
            }
            return true;
        }else{
            return false; // PEAR::riseError(); // module not fond
        }    
    }
    
    function loadBlocks(){
        $sql = "
            SELECT * 
            FROM `cms_blocks` 
            WHERE 
                `for`='". CMS_MODULE_INT ."' 
                    OR 
                `for`='*' 
                    AND 
                `visible`='+' 
            ORDER BY `position`, `order`
        ";
        $query = $this->_db->query($sql);
        if(!PEAR::isError($query) AND ($rs = $query->fetchRow())){
            $position = null;
            do{
                $block = $this->_app->getBlock();
                if(preg_match('/'.$rs['regexp'].'/', $_SERVER['REQUEST_URI']) OR empty($rs['regexp'])){
                    if(!is_file($inc = CFG_DIR_SYS.'/module/'.$rs['from'].'/blocks/'.$rs['name'].'.php')) continue;
                    require_once($inc);
                    $function = 'b_'.$rs['from'].'_'.$rs['name'];
                    if(!function_exists($function)) continue;
                    $function($block);
                }
                if($position != $rs['position']){
                    $position = $rs['position'];
                }
                if(!$block->is_blank_node()){
                    $this->_app->domAppend2Blocks($block, $position); 
                }
            }while($rs = $query->fetchRow());
        }
    }
}
?>


Transformer:
Код

<?php
class Transformer{
    var $_output = string;
    var $_xmlObj = object;
    var $_xslObj = object;
    var $_xh = object;
    var $_xsl = '';//string;
    var $_xml = '';//string;
    var $_opt = array(
        'encoding' => 'utf-8'
    );
    
    function Transformer(){
        $this->_xh = xslt_create();
        xslt_set_encoding($this->_xh, 'UTF-8');
        xslt_set_base($this->_xh, 'file://D:/WebServers/home/xml/sys/templates/');
        //xslt_set_base($this->_xh, CFG_DIR_TEMPLATES);
    }
    
    function & Singleton(){
        static $singleton = false;
        if(!$singleton){
            $singleton = true;
            $singleton = new Transformer();
        }
        return $singleton;
    }
    
    function process(&$xmlObj, &$xslObj){
        if(!is_a($xmlObj, 'xml_xpath') OR !is_a($xslObj, 'xml_xpath')){
            return false;
        }
        $this->_xml = $xmlObj->xml->dump_mem();
        $this->_xsl = $xslObj->xml->dump_mem();
        return $this->transform($this->_xml, $this->_xsl);
    }
    
    function transform($xml, $xsl){
        $arg = array(
            '/_xml' => $xml,
            '/_xsl' => $xsl
        );
        if($result = xslt_process($this->_xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arg)){
            $this->_output = $result;
            // for testing 
            print $this->getOutput();
            $this->free();
        }else{
            PEAR::riseError(xslt_error($xh), __FILE__, __FUNCTION__);
        }    
    }
    
    function getOutput(){
        if(strcasecmp($this->_opt['encoding'], 'utf-8') !== 0){
            return iconv('UTF-8', $this->_opt['encoding'], $this->_output);
        }
        return $this->_output;
    }
    
    function free(){
        xslt_free($this->_xh);
    }
}
?>


Соответсвует ли это MVC?

Добавление блоков в XML происходит примерно так:
Код

<?php
// class block_index_test extends block_index extends block
function b_index_test(&$block){
    $db  = &MDB2::singleton();
    $app = &Application::Singleton();
    $query = $db->query("SELECT `id`, `title`, `intro`, `text` FROM `module_content` LIMIT 1");
    if(!PEAR::isError($query) AND $rs = $query->fetchRow()){
        do{
            $section = $app->getBlock('section');
            foreach($rs AS $k => $v){
                if(empty($v)) continue;
                $v = iconv("windows-1251", "UTF-8", $v);
                $node = $section->new_child($k);
                switch($k){
                    case ($k == 'intro' OR $k == 'text'):
                        $v = html2xhtml_utf8($v);    //dump($v);
                        $cdata = $app->_domXML->xml->create_cdata_section($v);
                        $node->append_child($cdata);
                        break;
                    default:
                        $node->set_content(strip_tags($v));    
                        break;
                }
                $section->append_child($node);
            }
            $block->append_child($section);
        }while($rs = $query->fetchRow());
    }
}
?>

--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
skalex
Дата 27.6.2005, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хороший человек
**


Профиль
Группа: Участник Клуба
Сообщений: 895
Регистрация: 2.4.2004

Репутация: 8
Всего: 23



PM   Вверх
izOne
Дата 27.6.2005, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: 3
Всего: 4



Mace
Как постоянный посетитель форума я читаю практически все темы мне интересные. Приведенная ссылка не исключение. Но там ничего не сказано о модели MVC в примении к XSLT.

Я уже многое просмотрел и перечитал по MVC. Наиболее интересный в этом плане ресурс http://www.phppatterns.com/. Так же были просмотрены MVC-framework'и для PHP, но в них я не нашел ничего новго(точнее того, что мне необходимо).
В своем большинстве они используеют обычные шаблонизаторы аля FastTemplate/Smarty/PEAR::IT и ориентированы на HTML. Мне же требуется расширяемая система которая сможет легко быть адаптирована для: html, xul, soap/rpc + поддержка i18n посредством шаблонов(gettext) + смена дизайн без изменения php-кода.

Я хочу услышать кунструктивные замечания по приведенному примеру. Я в правильном направлении копаю???

--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0694 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.