19 require_once(BASE.
"wcmf/lib/core/class.WCMFException.php");
20 require_once(BASE.
"wcmf/lib/persistence/class.PersistenceMapper.php");
21 require_once(BASE.
"wcmf/lib/model/class.Node.php");
22 require_once(BASE.
"wcmf/lib/model/class.NodeIterator.php");
23 require_once(BASE.
"wcmf/lib/visitor/class.OutputVisitor.php");
24 require_once(BASE.
"wcmf/lib/output/class.XMLOutputStrategy.php");
29 define(
"DATATYPE_DONTCARE", 0);
30 define(
"DATATYPE_ATTRIBUTE", 1);
31 define(
"DATATYPE_ELEMENT", 2);
32 define(
"DATATYPE_IGNORE", 3);
36 define(
"BUILDDEPTH_INFINITE", -1);
37 define(
"BUILDDEPTH_SINGLE", -2);
38 define(
"BUILDDEPTH_GROUPED", -3);
41 define(
"NEXTID_NODE", 2);
80 $this->_filename = $params[
'filename'];
81 $this->_doctype = $params[
'doctype'];
82 $this->_dtd = $params[
'dtd'];
90 function &
load($oid, $buildDepth)
94 $this->_curParent = null;
95 $this->_curNode = null;
96 $this->_startId = $oid;
99 $this->_buildDepth = $buildDepth;
100 $this->_curDepth = -1;
101 $this->_startDepth = -1;
102 $this->_loading =
false;
103 $this->_intransaction =
false;
106 $xml_parser = xml_parser_create();
107 xml_set_object($xml_parser,&$this);
108 xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING,
false);
109 xml_set_element_handler($xml_parser,
"parseStartTag",
"parseEndTag");
110 xml_set_character_data_handler($xml_parser,
"parseElement");
111 if (!($fp = fopen($this->_filename,
"r")))
115 while ($data = fread($fp, 4096))
116 if (!xml_parse($xml_parser, $data, feof($fp)))
117 WCMFException::throwEx(
"XML error: ".xml_error_string(xml_get_error_code($xml_parser)).
" at line ".xml_get_current_line_number($xml_parser), __FILE__, __LINE__);
119 xml_parser_free($xml_parser);
122 if ($this->_root != null)
137 $node =
new Node($type);
138 $node->setMapper($this);
144 else if ($type ==
'date')
147 else if ($type ==
'headline')
150 else if ($type ==
'textblock')
153 else if ($type ==
'image')
172 if ($this->_saveTree == null)
180 $parent = &$node->getParent();
186 $node->setOID($nextId);
188 while(!$saveIter->isEnd())
190 $currentNode = &$saveIter->getCurrentObject();
194 if ($currentNode->getOID() == $parent->getOID())
199 foreach($insertNode->getChildren() as $child)
200 $insertNode->deleteChild($child->getOID(),
true);
203 $children = $parent->getChildren();
204 if ($children[0]->getOID() == $node->getOID())
207 $currentNode->addChild($insertNode);
210 $saveIter->proceed();
221 while(!$saveIter->isEnd())
223 $currentNode = &$saveIter->getCurrentObject();
224 if ($currentNode->getOID() == $node->getOID())
227 foreach ($node->getDataTypes() as $type)
228 foreach ($node->getValueNames($type) as $valueName)
230 $currentNode->setValue($valueName, $node->getValue($valueName, $type), $type);
231 $currentNode->setValueProperties($valueName, $node->getValueProperties($valueName, $type), $type);
235 $saveIter->proceed();
253 function delete($oid, $recursive=
true)
259 if ($this->_saveTree == null)
264 while(!$saveIter->isEnd())
266 $currentNode = &$saveIter->getCurrentObject();
267 if ($currentNode->getOID() == $oid)
270 $parent = &$currentNode->getParent();
271 $parent->deleteChild($oid,
true);
274 $saveIter->proceed();
288 $saveMapper =
new NodeXMLMapper(array(
'filename' => $this->_filename));
290 $this->_intransaction =
true;
301 while(!$saveIter->isEnd())
303 $currentNode = &$saveIter->getCurrentObject();
304 foreach ($currentNode->getDataTypes() as $type)
305 foreach ($currentNode->getValueNames($type) as $valueName)
306 $currentNode->setValue($valueName, htmlspecialchars($currentNode->getValue($valueName, $type), ENT_QUOTES), $type);
307 $saveIter->proceed();
310 $xmlos =
new XMLOutputStrategy(strtolower($this->_filename), $this->_doctype, $this->_dtd);
311 $saveIter->reset($this->_saveTree);
313 $ov->startIterator($saveIter);
314 $this->_intransaction =
false;
333 if (!$this->_intransaction)
336 $insertMapper =
new NodeXMLMapper(array(
'filename' => $this->_filename));
338 unset($insertMapper);
345 while(!$iter->isEnd())
347 $currentNode = &$iter->getCurrentObject();
371 if ($attribs[
'id'] == $this->_startId || $this->_loading && $this->
isDepthValid())
375 $node->setOID($attribs[
'id']);
376 $node->setMapper($this);
377 $this->_curNode = &$node;
380 foreach($attribs as $key => $value)
381 if (strtolower($key) !=
'id')
382 $node->setValue(strtolower($key), stripslashes(stripslashes($value)),
DATATYPE_ATTRIBUTE);
384 if ($attribs[
'id'] == $this->_startId)
387 $this->_loading =
true;
389 if ($this->_prevId != -1)
390 $node->setProperty(
'parentdbid', $this->_prevId);
391 $this->_root = &$node;
393 else if ($this->_loading)
396 $node->setProperty(
'parentdbid', $this->_curParent->getOID());
397 $this->_curParent->addChild($node);
401 $this->_curParent = &$node;
404 $this->_prevId = $attribs[
'id'];
418 $this->_curParent = &$this->_curParent->getParent();
420 if (!$this->_curParent)
421 $this->_loading =
false;
431 $data = stripslashes(stripslashes(trim($data)));
432 if ($data !=
'' && $this->_loading && $this->
isDepthValid())
434 $value = $this->_curNode->getValue($this->_curNode->getType(),
DATATYPE_ELEMENT).$data;
435 $this->_curNode->setValue($this->_curNode->getType(), $value,
DATATYPE_ELEMENT);
444 return (($this->_curDepth-$this->_startDepth) <= $this->_buildDepth) || ($this->_buildDepth ==
BUILDDEPTH_INFINITE);
parseStartTag($parser, $name, $attribs)
Node is the basic component for building trees (although a Node can have one than more parents)...
NodeXMLMapper maps nodes to a xml file.
const BUILDDEPTH_INFINITE
& load($oid, $buildDepth)
This OutputStrategy outputs an object's content in a xml file using the default format.
parseElement($parser, $data)
NodeIterator is used to iterate over a tree/list build of objects using a Depth-First-Algorithm. Classes used with the NodeIterator must implement the getChildren() and getOID() methods. NodeIterator implements the 'Iterator Pattern'. The base class NodeIterator defines the interface for all specialized Iterator classes.
The OutputVisitor is used to output an object's content to different destinations and formats...
throwEx($message, $file='', $line='')
& create($type, $buildDepth)
parseEndTag($parser, $name)
PersistenceMapper is the base class for all mapper classes.