* @license PHP License * @package wb * @subpackage Markup */ /** * Tag converter * * Convert node to node * * @version 0.3.0 * @package wb * @subpackage Markup */ abstract class WBMarkup_Converter extends WBStdClass { const TARGET_XML = 'target_xml'; const TARGET_WXML = 'target_wxml'; const TARGET_HTML = 'target_html'; /** * List of loaded templates * * @var array */ private $tmplLoaded = array(); /** * associative array to configure converter * @var array */ protected $config = array(); /** * Associative array of convert options * @var array */ protected $option = array(); /** * document's md5 sum * @var string */ protected $md5 = 'x'; /** * template engine * @var patTemplate */ protected $tmpl; /** * template dir format */ protected $tmplDirPrototype = ''; /** * template folder * @var string */ protected $tmplDir = ''; /** * Suffix for template files * @var string */ protected $tmplSuffix = '.tmpl'; /** * Template engine's type * @var string */ protected $tmplType = 'html'; /** * user object * @var WBUser_Auth */ protected $user; /** * constructor * * start up end set temüplate dir */ public function __construct() { $clazz = explode('_', get_class($this)); array_shift($clazz); array_shift($clazz); $this->tmplDirPrototype = sprintf('Wxml/converter/%s', strtolower(implode('/', $clazz))); $this->tmplDir = $this->tmplDirPrototype; $configFile = sprintf('wxml/converter/%s', strtolower(implode('/', $clazz))); $config = WBClass::create('WBConfig'); if ($config->load( $configFile, true )) { $this->config = array_merge($this->config, $config->get()); } WBClass::load('WBUser'); $this->user = WBUser::getCurrent(); } /** * Set Option List * * @param array */ public function setOption($opt = array()) { $this->option = array_merge($this->option, $opt); } /** * set template folder * * load template from dir... * * @var string $dir */ public function setTmplDir( $dir = null ) { $this->tmplDir = $this->tmplDirPrototype; if (!empty($dir)) { $this->tmplDir .= '/' . trim($dir, '/'); } } /** * Configure Template Engine * * Set patTemplate type and template file's suffix * * @param string type either "html" or "tex" */ public function setTmplType($type) { $this->tmplType = $type; if ('tex' == $type) { $this->tmplSuffix = '.tex.tmpl'; } } /** * setup convert when started * * Inform convert whenever created or new scan was started * * @param WBMarkup_Handler $handler * @param string $content */ public function preset($handler, &$content) { $this->md5 = md5($content); } /** * reset * * @return bool true on success */ public function reset() { return true; } /** * transform Xinha Tags to XML * * @param array $node to be modified document node * @return bool true on success */ abstract public function toXml(&$node); /** * transform Xml to Wxml (html) tags * * @param array $node to be modified document node * @return bool true on success */ abstract public function toWxml(&$node); /** * transform XML to Html * * @param array $node to be modified document node * @return bool true on success */ abstract public function toHtml(&$node); /** * create tag attribute style * * implode style array to string * * @param array $style * @return string */ protected function implodeStyle($style) { $tmp = array(); foreach ($style as $k => $v) { $tmp[] = $k . ':' . $v; } return implode(';', $tmp) . ';'; } /** * extract all stype attribute to array * * * @param array $node * @return array */ protected function explodeStyle($node) { if (!isset($node['attributes']['style'])) { return array(); } $tmp = explode(';', trim($node['attributes']['style'])); $tmp = array_map('trim', $tmp); $style = array(); foreach ($tmp as $t) { $t = trim($t); if (empty($t)) { continue; } $s = array_map('trim', explode(':', $t)); if (count($s == 2)) { // remove "px" from style if (substr($s[1], -2) == 'px') { $s[1] = substr($s[1], 0, -2); } $style[$s[0]] = $s[1]; } } return $style; } /** * Get Default Attributes * * @return array */ protected function getDefaultAttributes($target = self::TARGET_XML) { switch ($target) { case self::TARGET_WXML: $atts = array( 'title' => patI18n::dgettext('wombat', 'double click to change'), 'ondblclick'=> 'return WB.Wxml.Dialog.editTag(this);' ); break; default: $atts = array(); break; } return $atts; } /** * load templates from file * * @param string $tmpl * @return bool true on success */ protected function loadTemplates($tmpl, $local = true) { if (!$this->tmpl) { $this->tmpl = WBClass::create('patTemplate'); $this->tmpl->setType($this->tmplType); if ('tex' == $this->tmplType) { $this->tmpl->setDefaultAttribute('whitespace', 'keep'); } $this->tmpl->addGlobalVars($this->config, 'config_'); // add user data and group membership if ($this->user && $this->user->isAuthenticated()) { $this->tmpl->addGlobalVars($this->user->getData(), 'user_current_'); $groups = array(); foreach ($this->user->getGroups() as $gid => $gname) { $groups[$gname] = '1'; } $this->tmpl->addGlobalVars($groups, 'user_current_group_'); } } if ($local) { $tmpl = $this->tmplDir . '/' . $tmpl; } // clear and reload template if (isset($this->tmplLoaded[$tmpl])) { ++$this->tmplLoaded[$tmpl]; $this->tmpl->clearTemplate('snippet', true); } // false on error patErrorManager::pushExpect(6000); $ret = $this->tmpl->readTemplatesFromInput($tmpl . $this->tmplSuffix); if (patErrorManager::isError($ret)) { return false; } patErrorManager::popExpect(); $this->tmplLoaded[$tmpl] = 1; return true; } /** * convert template to node * * Add vars and parse temlate and replace node's CData * * @param array $node * @param array $data */ protected function template2HtmlNode(&$node, $data) { $html = array( 'ns' => null, 'tag' => '', 'attributes' => array(), 'isEmpty' => false, 'cData' => array() ); $this->tmpl->addGlobalVars($data); $html['cData'][] = $this->tmpl->getParsedTemplate('snippet'); $this->tmpl->clearAllTemplates(); $node = $html; } }