Permalink
Browse files

Adding data format support for components.

  • Loading branch information...
1 parent 8b91ad1 commit 32363fc959ad50542cb2c6f9726621060c004d12 @zyxist zyxist committed Oct 30, 2010
View
@@ -185,6 +185,8 @@ class Opt_Class extends Opl_Class
public $defaultFormat = 'Array';
public $containerFormat = 'Container';
public $treeFormat = 'DepthTree';
+ public $componentFormat = 'Component';
+ public $blockFormat = 'Block';
/**
* The compiler object
@@ -289,14 +291,17 @@ class Opt_Class extends Opl_Class
'Objective' => 'Opt_Format_Objective',
'Global' => 'Opt_Format_Global',
'SingleArray' => 'Opt_Format_SingleArray',
+ 'SplDatastructure' => 'Opt_Format_SplDatastructure',
'StaticGenerator' => 'Opt_Format_StaticGenerator',
'RuntimeGenerator' => 'Opt_Format_RuntimeGenerator',
'System' => 'Opt_Format_System',
'SwitchEquals' => 'Opt_Format_SwitchEquals',
'SwitchContains' => 'Opt_Format_SwitchContains',
'Container' => 'Opt_Format_Container',
'DepthTree' => 'Opt_Format_DepthTree',
- 'NestedTree' => 'Opt_Format_NestedTree'
+ 'NestedTree' => 'Opt_Format_NestedTree',
+ 'Component' => 'Opt_Format_Component',
+ 'Block' => 'Opt_Format_Block'
);
/**
* The extra entities replaced by OPT
@@ -0,0 +1,96 @@
+<?php
+/*
+ * OPEN POWER LIBS <http://www.invenzzia.org>
+ *
+ * This file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE. It is also available through
+ * WWW at this URL: <http://www.invenzzia.org/license/new-bsd>
+ *
+ * Copyright (c) Invenzzia Group <http://www.invenzzia.org>
+ * and other contributors. See website for details.
+ */
+
+/**
+ * The data format for components.
+ *
+ * @author Tomasz Jędrzejewski
+ * @copyright Invenzzia Group <http://www.invenzzia.org/> and contributors.
+ * @license http://www.invenzzia.org/license/new-bsd New BSD License
+ * @package Formats
+ */
+class Opt_Format_Component extends Opt_Format_Abstract
+{
+ /**
+ * The list of supported hook types.
+ * @var array
+ */
+ protected $_supports = array(
+ 'component'
+ );
+
+ /**
+ * Build a PHP code for the specified hook name.
+ *
+ * @internal
+ * @param string $hookName The hook name
+ * @return string The output PHP code
+ */
+ protected function _build($hookName)
+ {
+ switch($hookName)
+ {
+ case 'component:init':
+ return ' '.$this->_getVar('variable').'->setView($this); ';
+ case 'component:done':
+ return '';
+ case 'component:valid':
+ return ' '.$this->_getVar('variable').' instanceof Opt_Component_Interface';
+ case 'component:build':
+ return ' '.$this->_getVar('variable').' = new '.$this->_getVar('className').'; ';
+ case 'component:datasource':
+ return ' '.$this->_getVar('variable').'->setDatasource('.$this->_getVar('datasource').'); ';
+ case 'component:event-open':
+ return ' if('.$this->_getVar('variable').'->processEvent('.$this->_getVar('eventName').')){ ';
+ case 'component:event-close':
+ return ' } ';
+ case 'component:display':
+ $attrs = $this->_getVar('attributes');
+ $subCode = '';
+ if(sizeof($attrs) > 0)
+ {
+ $subCode = 'array(';
+ foreach($attrs as $name => $value)
+ {
+ $subCode .= '\''.$name.'\' => '.$value.',';
+ }
+ $subCode .= ')';
+ }
+ return ' '.$this->_getVar('variable').'->display('.$subCode.'); ';
+ case 'component:inject-open':
+ return ' '.$this->_getVar('variable').'->setInjection(';
+ case 'component:inject-close':
+ return '); ';
+ case 'component:manage-attributes':
+ $attrs = $this->_getVar('attributes');
+ $subCode = 'array()';
+ if(sizeof($attrs) > 0)
+ {
+ $subCode = 'array(';
+ foreach($attrs as $name => $value)
+ {
+ $subCode .= '\''.$name.'\' => '.$value.',';
+ }
+ $subCode .= ')';
+ }
+
+ return ' $out = '.$this->_getVar('variable').'->manageAttributes(\''.$this->_getVar('tag').'\', '.$subCode.'); ';
+ case 'component:manage-attributes-apply':
+ return ' if(is_array($out)){ foreach($out as $name=>$value){ echo \' \'.$name.\'="\'.$value.\'"\'; } } ';
+ case 'component:set':
+ return ' '.$this->_getVar('variable').'->__set('.$this->_getVar('name').', '.$this->_getVar('value').') ';
+ case 'component:get':
+ return ' '.$this->_getVar('variable').'->__get('.$this->_getVar('name').') ';
+ }
+ } // end _build();
+
+} // end Opt_Format_Component;
@@ -84,21 +84,25 @@ public function processNode(Opt_Xml_Node $node)
'from' => array(self::REQUIRED, self::EXPRESSION, null),
'datasource' => array(self::OPTIONAL, self::EXPRESSION, null),
'template' => array(self::OPTIONAL, self::ID, null),
+ 'id' => array(self::OPTIONAL, self::STRING, null),
'__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)
);
$vars = $this->_extractAttributes($node, $params);
- $this->_stack->push($params['from']);
+ $format = $this->_compiler->getFormat('component#'.$params['id'], false, $this->_tpl->componentFormat);
+ $format->assign('variable', $params['from']);
+ $this->_stack->push(array($params['from'], $format));
- $mainCode = ' if(is_object('.$params['from'].') && '.$params['from'].' instanceof Opt_Component_Interface){ '.$params['from'].'->setView($this); ';
+ $mainCode = ' if(is_object('.$params['from'].') && '.$format->get('component:valid').'){ '.$format->get('component:init');
if($params['datasource'] !== null)
{
- $mainCode .= $params['from'].'->setDatasource('.$params['datasource'].'); ';
+ $format->assign('datasource', $params['datasource']);
+ $mainCode .= $format->get('component:datasource');
}
- $mainCode .= $this->_commonProcessing($node, $params['from'], $params, $vars);
+ $mainCode .= $this->_commonProcessing($node, $params['from'], $params, $vars, $format);
$node->addBefore(Opt_Xml_Buffer::TAG_BEFORE, $mainCode);
- $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } ');
+ $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, $format->get('component:done').' } ');
break;
case 'on-event':
if($this->_stack->count() == 0)
@@ -110,9 +114,12 @@ public function processNode(Opt_Xml_Node $node)
'name' => array(self::REQUIRED, self::EXPRESSION)
);
+ list($variable, $format) = $this->_stack->top();
+
$this->_extractAttributes($node, $tagParams);
- $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, ' if('.$this->_stack->top().'->processEvent('.$tagParams['name'].')){ ');
- $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, ' } ');
+ $format->assign('eventName', $tagParams['name']);
+ $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $format->get('component:event-open'));
+ $node->addAfter(Opt_Xml_Buffer::TAG_AFTER, $format->get('component:event-close'));
$this->_process($node);
break;
@@ -121,6 +128,7 @@ public function processNode(Opt_Xml_Node $node)
{
throw new Opt_Instruction_Exception('Component error: invalid use of "opt:display": no active component.');
}
+ list($variable, $format) = $this->_stack->top();
$node->set('hidden', false);
$node->removeChildren();
// The opt:display attributes must be packed into array and sent
@@ -132,20 +140,20 @@ public function processNode(Opt_Xml_Node $node)
'__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)
);
$vars = $this->_extractAttributes($node, $params);
- $subCode = 'array(';
- foreach($vars as $name => $value)
- {
- $subCode .= '\''.$name.'\' => '.$value.',';
- }
- $subCode .= ')';
+ $format->assign('attributes', $vars);
}
- $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $this->_stack->top().'->display('.$subCode.'); ');
+ else
+ {
+ $format->assign('attributes', array());
+ }
+ $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $format->get('component:display'));
break;
case 'inject':
if($this->_stack->count() == 0)
{
throw new Opt_Instruction_Exception('Component error: invalid use of "opt:inject": no active component.');
}
+ list($variable, $format) = $this->_stack->top();
$code = 'function() use($ctx){ ';
if($node->getAttribute('procedure') !== null)
@@ -157,7 +165,7 @@ public function processNode(Opt_Xml_Node $node)
$code .= ' $args = func_get_args(); array_unshift($args, $ctx); '.PHP_EOL;
$code .= $this->_compiler->processor('procedure')->callProcedure($params['procedure'], '$args', true).PHP_EOL;
$code .= '}'.PHP_EOL;
- $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $this->_stack->top().'->setInjection('.$code.'); ');
+ $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $format->get('component:inject-open').$code.$format->get('component:inject-close'));
}
else
{
@@ -182,8 +190,8 @@ public function processNode(Opt_Xml_Node $node)
}
$value = '$args['.($i++).']';
}
- $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $this->_stack->top().'->setInjection('.$code);
- $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, ' }); ');
+ $node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $format->get('component:inject-open').$code);
+ $node->addBefore(Opt_Xml_Buffer::TAG_AFTER, ' } '.$format->get('component:inject-close'));
$this->_compiler->processor('snippet')->useSnippet($node, $params['snippet'], $snippetArgs, false, true);
$this->_process($node);
}
@@ -223,55 +231,30 @@ public function processComponent(Opt_Xml_Element $node)
{
// Defined component processing
$params = array(
+ 'id' => array(self::OPTIONAL, self::STRING, null),
'datasource' => array(self::OPTIONAL, self::EXPRESSION, null),
'template' => array(self::OPTIONAL, self::ID, null),
'__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null)
);
$vars = $this->_extractAttributes($node, $params);
- // Get the real class name
+ // Initialize component structures
$cn = '$_component_'.($this->_unique++);
-
- $this->_stack->push($cn);
-
- $class = $this->_compiler->component($node->getXmlName());
-
- // Check, if there are any conversions that may take control over initializing
- // the component object. We are allowed to capture only particular component
- // creation or all of them.
- if((($to = $this->_compiler->convert('##component_'.$class)) != '##component_'.$class))
- {
- $attributes = 'array(';
- foreach($vars as $name => $value)
- {
- $attributes .= '\''.$name.'\' => '.$value.', ';
- }
- $attributes .= ')';
- $ccode = str_replace(array('%CLASS%', '%TAG%', '%ATTRIBUTES%'), array($class, $node->getXmlName(), $attributes), $to);
- }
- elseif((($to = $this->_compiler->convert('##component')) != '##component'))
- {
- $attributes = 'array(';
- foreach($vars as $name => $value)
- {
- $attributes .= '\''.$name.'\' => '.$value.', ';
- }
- $attributes .= ')';
- $ccode = str_replace(array('%CLASS%', '%TAG%', '%ATTRIBUTES%'), array($class, $node->getXmlName(), $attributes), $to);
- }
- else
- {
- $ccode = 'new '.$class;
- }
+ $format = $this->_compiler->getFormat('component#'.$params['id'], false, $this->_tpl->componentFormat);
+ $format->assign('variable', $cn);
+ $this->_stack->push(array($cn, $format));
// Generate the initialization code
- $mainCode = $cn.' = '.$ccode.'; '.$cn.'->setView($this); ';
+ $format->assign('className', $this->_compiler->component($node->getXmlName()));
+ $mainCode = $format->get('component:build').$format->get('component:init');
+
if($params['datasource'] !== null)
{
- $mainCode .= $cn.'->setDatasource('.$params['datasource'].'); ';
+ $format->assign('datasource', $params['datasource']);
+ $mainCode .= $format->get('component:datasource');
}
- $mainCode .= $this->_commonProcessing($node, $cn, $params, $vars);
+ $mainCode .= $this->_commonProcessing($node, $cn, $params, $vars, $format).$format->get('component:done');
$node->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $mainCode);
} // end processComponent();
@@ -305,9 +288,10 @@ public function postprocessComponent(Opt_Xml_Node $node)
* @param string $componentVariable The PHP component variable name.
* @param array $params The array of standard component attributes.
* @param array $args The array of custom component attributes.
+ * @param Opt_Format_Abstract $format The component data format.
* @return string
*/
- private function _commonProcessing(Opt_Xml_Element $node, $componentVariable, array $params, array $args)
+ private function _commonProcessing(Opt_Xml_Element $node, $componentVariable, array $params, array $args, Opt_Format_Abstract $format)
{
// Common part of the component processing
$set2 = array();
@@ -345,33 +329,29 @@ private function _commonProcessing(Opt_Xml_Element $node, $componentVariable, ar
);
$this->_extractAttributes($set, $tagParams);
- $code .= $componentVariable.'->__set('.$tagParams['name']['bare'].', '.$tagParams['value'].'); ';
+ $format->assign('name', $tagParams['name']['bare']);
+ $format->assign('value', $tagParams['value']);
+ $code .= $format->get('component:set');
}
foreach($args as $name => $value)
{
- $code .= $componentVariable.'->__set(\''.$name.'\', '.$value.'); ';
+ $format->assign('name', $name);
+ $format->assign('value', $value);
+ $code .= $format->get('component:set');
}
// opt:component-attributes
foreach($everything[1] as $wtf)
{
- $id = $wtf->getAttribute('opt:component-attributes')->getValue();
- $subCode = ' $out = '.$componentVariable.'->manageAttributes(\''.$wtf->getName().'#'.$id.'\', array(';
- // $wtf->removeAttribute('opt:component-attributes');
+ $params = array(
+ '__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null, 'str')
+ );
+ $vars = $this->_extractAttributes($wtf, $params);
+ $format->assign('tag', $wtf->getName().'#'.$wtf->getAttribute('opt:component-attributes')->getValue());
+ $format->assign('attributes', $vars);
- // foreach($wtf->getAttributes() as $attribute)
- // {
- $params = array(
- '__UNKNOWN__' => array(self::OPTIONAL, self::EXPRESSION, null, 'str')
- );
- $vars = $this->_extractAttributes($wtf, $params);
- foreach($vars as $name => $value)
- {
- $subCode .= '\''.$name.'\' => '.$value.',';
- }
- // }
$wtf->removeAttributes();
- $wtf->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $subCode.')); ');
- $wtf->addAfter(Opt_Xml_Buffer::TAG_ENDING_ATTRIBUTES, ' if(is_array($out)){ foreach($out as $name=>$value){ echo \' \'.$name.\'="\'.$value.\'"\'; } } ');
+ $wtf->addAfter(Opt_Xml_Buffer::TAG_BEFORE, $format->get('component:manage-attributes'));
+ $wtf->addAfter(Opt_Xml_Buffer::TAG_ENDING_ATTRIBUTES, $format->get('component:manage-attributes-apply'));
}
$node->set('postprocess', true);
@@ -398,7 +378,9 @@ public function processSystemVar($opt)
{
throw new Opt_Instruction_Exception('Component error: invalid use of $'.implode('.',$opt).': no active component.');
}
- return $this->_stack->top().'->'.$opt[2];
+ list($variable, $format) = $this->_stack->top();
+ $format->assign('name', $opt[2]);
+ return $format->get('component:get');
} // end processSystemVar();
/**
@@ -53,6 +53,7 @@ public static function dataProvider()
array('Component/component_nesting.txt'),
array('Component/component_template.txt'),
array('Component/component_template_missing.txt'),
+ array('Component/component_id.txt'),
);
} // end dataProvider();
Oops, something went wrong.

0 comments on commit 32363fc

Please sign in to comment.