Permalink
Browse files

Removed Element options. Slick new interface.

  • Loading branch information...
Evoke-PHP committed Apr 9, 2012
1 parent 568d2a3 commit 06ebca8bd418e0f22d34024bb91d856d4a9cc166
@@ -4,25 +4,16 @@
/// Base class for writing XML elements.
abstract class XMLBase implements \Evoke\Core\Iface\Writer
{
- /** @property $attribsPos
- * \int The position of the attributes in the XML arrays being written.
- */
- protected $attribsPos;
/** @property $language
* \string The language of the XML being written.
*/
protected $language;
-
- /** @property $optionsPos
- * \int The position of the options in the XML arrays being written.
- */
- protected $optionsPos;
-
- /** @property $tagPos
- * \int The position of the tag in the XML arrays being written.
+
+ /** @property $pos
+ * \array The position of the tag, attribs and children in the element.
*/
- protected $tagPos;
+ protected $pos;
/** @property $XMLWriter
* The XML Writer \object
@@ -34,12 +25,12 @@
*/
public function __construct(Array $setup=array())
{
- $setup += array('Attribs_Pos' => 1,
- 'Indent' => true,
+ $setup += array('Indent' => true,
'Indent_String' => ' ',
'Language' => 'EN',
- 'Options_Pos' => 2,
- 'Tag_Pos' => 0,
+ 'Pos' => array('Attribs' => 1,
+ 'Children' => 2,
+ 'Tag' => 0),
'XMLWriter' => NULL);
if (!$setup['XMLWriter'] instanceof \XMLWriter)
@@ -48,10 +39,8 @@ public function __construct(Array $setup=array())
__METHOD__ . ' requires XMLWriter');
}
- $this->attribsPos = $setup['Attribs_Pos'];
$this->language = $setup['Language'];
- $this->optionsPos = $setup['Options_Pos'];
- $this->tagPos = $setup['Tag_Pos'];
+ $this->pos = $setup['Pos'];
$this->XMLWriter = $setup['XMLWriter'];
$this->XMLWriter->openMemory();
@@ -92,126 +81,81 @@ public function output()
/** Write XML elements into the memory buffer.
* @param xml \mixed Array accessible value for the xml to be written of the
- * form: array($tag, $attributes, $options)
+ * form: array($tag, $attributes, $children)
*
* An example of this is below with the default values that are used for the
* options array. Attributes and options are optional.
* \verbatim
* array(0 => tag,
* 1 => array('attrib_1' => '1', 'attrib_2' => '2'),
- * 2 => array('Children' => array(), // Child elements within the tag.
- * 'Finish' => true, // Whether to end the tag.
- * 'Start' => true, // Whether to start the tag.
- * 'Text' => NULL), // Text within the tag.
+ * 2 => array($child, 'text', $anotherChild)
* )
* \endverbatim
*/
public function write($xml)
{
- if (!isset($xml[$this->tagPos]))
+ if (empty($xml[$this->pos['Tag']]) ||
+ !is_string($xml[$this->pos['Tag']]))
{
throw new \InvalidArgumentException(
- __METHOD__ . ' Bad element: ' . var_export($xml, true));
+ __METHOD__ . ' bad tag: ' . var_export($xml, true));
}
- $tag = $xml[$this->tagPos];
- $attribs = array();
- $options = array('Children' => array(),
- 'Finish' => true,
- 'Start' => true,
- 'Text' => NULL);
-
- if (isset($xml[$this->attribsPos]))
+ if (isset($xml[$this->pos['Attribs']]) &&
+ !is_array($xml[$this->pos['Attribs']]))
{
- $attribs = $xml[$this->attribsPos];
+ throw new \InvalidArgumentException(
+ __METHOD__ . ' bad attributes: ' . var_export($xml, true));
}
- if (isset($xml[$this->optionsPos]))
- {
- $options = array_merge($options, $xml[$this->optionsPos]);
- }
-
- if (!empty($tag) && $options['Start'])
+ if (isset($xml[$this->pos['Children']]))
{
- $this->XMLWriter->startElement($tag);
+ if (is_string($xml[$this->pos['Children']]))
+ {
+ $xml[$this->pos['Children']]
+ = array($xml[$this->pos['Children']]);
+ }
+ elseif (!is_array($xml[$this->pos['Children']]))
+ {
+ throw new \InvalidArgumentException(
+ __METHOD__ . ' bad children: ' . var_export($xml, true));
+ }
}
+
+ $tag = $xml[$this->pos['Tag']];
+ $attribs = isset($xml[$this->pos['Attribs']]) ?
+ $xml[$this->pos['Attribs']] : array();
+ $children = isset($xml[$this->pos['Children']]) ?
+ $xml[$this->pos['Children']] : array();
+
+ $this->XMLWriter->startElement($tag);
foreach ($attribs as $attrib => $value)
{
$this->XMLWriter->writeAttribute($attrib, $value);
}
- if (isset($options['Text']))
- {
- $text = (string)($options['Text']);
-
- // If we have children insert a newline to ensure correct indentation.
- if (!empty($options['Children']))
- {
- $text .= "\n";
- }
-
- $this->XMLWriter->text($text);
- }
-
- if (!is_array($options['Children']))
- {
- throw new \RuntimeException(
- __METHOD__ . ' Children must be passed as an array not: ' .
- var_export($options['Children'], true));
- }
-
- foreach ($options['Children'] as $key => $child)
+ foreach ($children as $child)
{
- try
+ if (is_string($child))
{
- $this->write($child); // Recursively write children.
+ $this->XMLWriter->text($child);
}
- catch (\Exception $e)
+ else
{
- $msg = 'Element with Tag: ' . var_export($tag, true);
-
- if (!empty($attribs))
- {
- $msg .= ' Attribs: ' . var_export($attribs, true);
- }
-
- if (!empty($options['Text']))
- {
- $msg .= ' Text: ' . var_export($options['Text'], true);
- }
-
- $msg .= ' contains invalid child at index ' .
- var_export($key, true) . ': ';
-
- if (is_object($child))
- {
- $msg .= get_class($child);
- }
- else
- {
- $msg .= var_export($child, true);
- }
-
- throw new \RuntimeException(__METHOD__ . $msg, 0, $e);
+ $this->write($child);
}
}
- if (!empty($tag) && $options['Finish'])
+ // Some elements should always have a full end tag <div></div> rather
+ // than <div/>
+ if (preg_match('(^(div|link|script|textarea)$)i', $tag))
{
- $tagStr = strtoupper($tag);
-
- // Some elements should always have a full end tag <div></div> rather
- // than <div/>
- if ($tagStr === 'DIV' || $tagStr === 'LINK' || $tagStr === 'SCRIPT' ||
- $tagStr === 'TEXTAREA')
- {
- $this->XMLWriter->fullEndElement();
- }
- else
- {
- $this->XMLWriter->endElement();
- }
+ $this->XMLWriter->fullEndElement();
+ }
+ else
+ {
+ $this->XMLWriter->endElement();
}
}
@@ -52,22 +52,19 @@ public function set(Array $data)
return parent::set(
array('div',
array('class' => 'Admin_Header'),
- array('Children' => array(
- array(
- 'a',
- array('class' => 'Admin_Home',
- 'href' => '/admin/index.php?' .
- $this->Translator->getLanguageHTTPQuery()),
- array(
- 'Children' => array(
- array('img',
- array('src' => '/images/admin_home.png',
- 'alt' => 'Home')),
- array('span',
- array(),
- array('Text' => $this->Translator->get(
- 'Admin_Home')))))),
- $this->ElementLanguages->set($data)))));
+ array(array('a',
+ array('class' => 'Admin_Home',
+ 'href' => '/admin/index.php?' .
+ $this->Translator->getLanguageHTTPQuery()),
+ array(array(
+ 'img',
+ array('src' => '/images/admin_home.png',
+ 'alt' => 'Home')),
+ array('span',
+ array(),
+ $this->Translator->get(
+ 'Admin_Home')))),
+ $this->ElementLanguages->set($data))));
}
}
// EOF
@@ -28,30 +28,28 @@ public function __construct(Array $setup)
array('class' => 'Table_Button',
'href' => '/admin/' . strtolower($name) . '.php?' .
$setup['Translator']->getLanguageHTTPQuery()),
- array('Text' => $setup['Translator']->get(
- 'Table_' . $name, __FILE__))));
+ $setup['Translator']->get('Table_' . $name, __FILE__))));
$description = array(
array('div',
array('class' => 'Table_Description'),
- array('Text' => $setup['Translator']->get(
- 'Table_' . $name . '_Description', __FILE__))));
+ $setup['Translator']->get(
+ 'Table_' . $name . '_Description', __FILE__)));
$adminTableEntries[] =
array('div',
array('class' => 'Admin_Table_Entry'),
- array('Children' => array(
- array('div',
- array('class' => 'Table_Button_Div'),
- array('Children' => $button)),
- array('div',
- array('class' => 'Table_Description_Div'),
- array('Children' => $description)))));
+ array(array('div',
+ array('class' => 'Table_Button_Div'),
+ $button),
+ array('div',
+ array('class' => 'Table_Description_Div'),
+ $description)));
}
parent::__construct(array('div',
array('class' => 'Admin_Tables'),
- array('Children' => $adminTableEntries)));
+ $adminTableEntries));
}
}
// EOF
@@ -90,7 +90,22 @@ public function appendAttrib($attrib, $value)
}
}
- /** Set the element from the array values passed in for the element. The
+ /** Set the element from the array values passed in for the element and
+ * return the representation in a plain array. A value must be returned so
+ * that the Element object can be re-used to build more Elements.
+ *
+ * This allows it to be used in a template like this:
+ * \code
+ * array('div',
+ * array('class' => 'example'),
+ * array($Element->set($val1),
+ * $Element->set($val2)));
+ * \endcode
+ *
+ * The Element object was set twice, if it was set before the code val2
+ * would appear twice, because the object would have been modified.
+ *
+ * @param element \array The element that we are setting ourselves to.
* element should be passed in as an array with the numerical keys
* corresponding to the desired element data. By default this is:
* \verbatim
@@ -104,8 +119,10 @@ public function appendAttrib($attrib, $value)
* Atrribs passed in are merged with the default attributes from the
* construction.
*
- * Children are optional and must be passed in as an array. Strings should
- * be used for text. Array elements can provide nested Elements.
+ * Children are optional. A single text element child can be passed as a
+ * string. All other children must be passed using an array. Within the
+ * array Strings are used for text elements. All other items in the array
+ * must be array accessible (such as an Element object or plain array).
*
* Any data with a key outside of this range is ignored.
*
@@ -115,37 +132,40 @@ public function appendAttrib($attrib, $value)
*/
public function set(Array $element)
{
- $tagPos = $this->pos['Tag'];
- $attribsPos = $this->pos['Attribs'];
- $childrenPos = $this->pos['Children'];
-
// Remove the need for isset calls and default the attribs and children
// to empty arrays.
- $element += array($tagPos => NULL,
- $attribsPos => array(),
- $childrenPos => array());
+ $element += array($this->pos['Tag'] => NULL,
+ $this->pos['Attribs'] => array(),
+ $this->pos['Children'] => array());
- if (!is_string($element[$tagPos]))
+ if (!is_string($element[$this->pos['Tag']]))
{
throw new \DomainException(__METHOD__ . ' Tag must be a string.');
}
- if (!is_array($element[$attribsPos]))
+ if (!is_array($element[$this->pos['Attribs']]))
{
throw new \DomainException(
__METHOD__ . ' if attribs are supplied they must be an array');
}
- if (!is_array($element[$childrenPos]))
+ if (is_string($element[$this->pos['Children']]))
+ {
+ $element[$this->pos['Children']] =
+ array($element[$this->pos['Children']]);
+ }
+ elseif (!is_array($element[$this->pos['Children']]))
{
throw new \DomainException(
- __METHOD__ . ' if children are supplied they must be an array');
+ __METHOD__ . ' children must be supplied as an array or ' .
+ 'string (for a single child)');
}
$this->el = array(
- $tagPos => $element[$tagPos],
- $attribsPos => array_merge($this->attribs, $element[$attribsPos]),
- $childrenPos => $element[$childrenPos]);
+ $this->pos['Tag'] => $element[$this->pos['Tag']],
+ $this->pos['Attribs'] => array_merge(
+ $this->attribs, $element[$this->pos['Attribs']]),
+ $this->pos['Children'] => $element[$this->pos['Children']]);
return $this->el;
}
Oops, something went wrong.

0 comments on commit 06ebca8

Please sign in to comment.