source: extensions/AMetaData/JpegMetaData/Common/XmlData.class.php @ 4686

Last change on this file since 4686 was 4686, checked in by grum, 14 years ago

[Plugin:AMetaData] prepare the directory for a future plugin

  • Property svn:executable set to *
File size: 12.0 KB
Line 
1<?php
2/*
3 * --:: JPEG MetaDatas ::-------------------------------------------------------
4 *
5 *  Author    : Grum
6 *   email    : grum at piwigo.org
7 *   website  : http://photos.grum.fr
8 *
9 *   << May the Little SpaceFrog be with you ! >>
10 *
11 *
12 * +-----------------------------------------------------------------------+
13 * | JpegMetaData - a PHP based Jpeg Metadata manager                      |
14 * +-----------------------------------------------------------------------+
15 * | Copyright(C) 2010  Grum - http://www.grum.fr                          |
16 * +-----------------------------------------------------------------------+
17 * | This program is free software; you can redistribute it and/or modify  |
18 * | it under the terms of the GNU General Public License as published by  |
19 * | the Free Software Foundation                                          |
20 * |                                                                       |
21 * | This program is distributed in the hope that it will be useful, but   |
22 * | WITHOUT ANY WARRANTY; without even the implied warranty of            |
23 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
24 * | General Public License for more details.                              |
25 * |                                                                       |
26 * | You should have received a copy of the GNU General Public License     |
27 * | along with this program; if not, write to the Free Software           |
28 * | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
29 * | USA.                                                                  |
30 * +-----------------------------------------------------------------------+
31 *
32 *
33 * -----------------------------------------------------------------------------
34 *
35 * The XmlData class is used to read Xml data in a tree structure
36 * The class read the Xml data from a string, and build a tree made with XmlNode
37 * objects
38 *
39 * The XmlNode class is used to manage the nodes properties, like name, value,
40 * attributes, ...
41 *
42 * -----------------------------------------------------------------------------
43 *
44 * The XmlData class provides theses public functions :
45 *  - isValid
46 *  - isLoaded
47 *  - hasNodes
48 *  - getFirstNode
49 *  - getLastNode
50 *  - setXmlData
51 *
52 * The XmlNode class provides theses public functions :
53 *  - getName
54 *  - getLevel
55 *  - getValue
56 *  - setName
57 *  - setValue
58 *  - hasAttributes
59 *  - getAttributes
60 *  - getAttribute
61 *  - setAttribute
62 *  - delAttribute
63 *  - addAttribute
64 *  - hasChilds
65 *  - getChilds
66 *  - addChild
67 *  - getFirstChild
68 *  - getLastChild
69 *  - getPreviousNode
70 *  - setPreviousNode
71 *  - getNextNode
72 *  - setNextNode
73 *
74 * -----------------------------------------------------------------------------
75 */
76
77  class XmlNode
78  {
79    private $name = "";
80    private $attributes = Array();
81    private $childs = Array();
82    private $level = 0;
83    private $previousNode = null;
84    private $nextNode = null;
85    private $value=NULL;
86
87    /**
88     * the XmlNode constructor need a name for the node, and optionally the node
89     * level in the tree
90     *
91     * @param String $name              : node name
92     * @param Integer $level (optional) : node level, by default set to zero
93     */
94    function __construct($name, $level=0)
95    {
96      $this->name=$name;
97      $this->level=$level;
98    }
99
100    function __destruct()
101    {
102      unset($this->attributes);
103      unset($this->childs);
104    }
105
106    /**
107     * returns the name of the node
108     *
109     * @return String
110     */
111    public function getName()
112    {
113      return($this->name);
114    }
115
116    /**
117     * returns the level of the node
118     *
119     * @return Integer
120     */
121    public function getLevel()
122    {
123      return($this->level);
124    }
125
126    /**
127     * returns the value of the node
128     *
129     * @return the type depends of the node
130     */
131    public function getValue()
132    {
133      return($this->value);
134    }
135
136    /**
137     * set the name of the node
138     *
139     * @param String $value : the name of the node
140     * @return String
141     */
142    public function setName($value)
143    {
144      $this->name = $value;
145      return($this->name);
146    }
147
148    /**
149     * set the value of the node
150     *
151     * @param $value : the value can be of any type
152     */
153    public function setValue($value)
154    {
155      $this->value=$value;
156      return($this->value);
157    }
158
159    /**
160     * return true if the node has attributes
161     *
162     * @return Boolean
163     */
164    public function hasAttributes()
165    {
166      return(count($this->attributes)>0);
167    }
168
169    /**
170     * return an array of attributes
171     *
172     * @return Array : key = name of the attribute, value = value for attribute
173     */
174    public function getAttributes()
175    {
176      return($this->attributes);
177    }
178
179    /**
180     * return value for an attribute
181     * if the given attribute doesn't exist, return an empty string
182     *
183     * @param String $name : the attribute name
184     * @return String
185     */
186    public function getAttribute($name)
187    {
188      if(array_key_exists($name, $this->attributes))
189        return($this->attributes[$name]);
190      else
191        return("");
192    }
193
194    /**
195     * set the value for an attribute
196     * the attribute must exist, otherwise uses the addAttribute function
197     *
198     * @param String $name : the name of the attribute to set to value
199     * @param $value       : the value to set for the attribute
200     * @return Boolean : false if the attribute doesn't exist
201     */
202    public function setAttribute($name, $value)
203    {
204      if(array_key_exists($name, $this->attributes))
205      {
206        $this->attributes[$name];
207        return(true);
208      }
209      else
210        return(false);
211    }
212
213    /**
214     * add an attribute
215     * the attribute must exist, otherwise uses the addAttribute function
216
217     * @param String $name : the name of the new attribute
218     * @param $value       : the value of the new attribute
219     */
220    public function addAttribute($name, $value)
221    {
222      $this->attributes[]=Array(
223        'name'  => $name,
224        'value' => $value
225      );
226    }
227
228    /**
229     * delete an attribute
230     * return true of the attribute has been deleted, otherwise false
231
232     * @param String $name : the name the attribute to delete
233     * @return Boolean
234     */
235    public function delAttribute($name)
236    {
237      if(array_key_exists($name, $this->attributes))
238      {
239        unset($this->attributes[$name]);
240        return(true);
241      }
242      else
243      {
244        return(false);
245      }
246    }
247
248    /**
249     * returns true if the node have childs
250
251     * @return Boolean
252     */
253    public function hasChilds()
254    {
255      return(count($this->childs)>0);
256    }
257
258    /**
259     * returns an array of childs
260
261     * @return Array of XmlNode
262     */
263    public function getChilds()
264    {
265      return($this->childs);
266    }
267
268    /**
269     * add a new child (added as the last child)
270     *
271     * @param XmlNode $node : the child must be an instanciated XmlNode
272     */
273    public function addChild(XmlNode $node)
274    {
275      $this->childs[]=$node;
276    }
277
278    /**
279     * returns the first child
280     *
281     * @return XmlNode or null
282     */
283    public function getFirstChild()
284    {
285      if($this->hasChilds())
286        return($this->childs[0]);
287      else
288        return(null);
289    }
290
291    /**
292     * returns the last child
293     *
294     * @return XmlNode or null
295     */
296    public function getLastChild()
297    {
298      if($this->hasChilds())
299        return($this->childs[count($this->childs)-1]);
300      else
301        return(null);
302    }
303
304    /**
305     * set the previous node
306     *
307     * @param XmlNode $node : must be an instanciated XmlNode
308     * @return XmlNode : the previous node
309     */
310    public function setPreviousNode(XmlNode $node)
311    {
312      $this->previousNode = $node;
313      return($this->previousNode);
314    }
315
316    /**
317     * returns the previous node
318     *
319     * @return XmlNode or null
320     */
321    public function getPreviousNode()
322    {
323      return($this->previousNode);
324    }
325
326    /**
327     * set the next node
328     *
329     * @param XmlNode $node : must be an instanciated XmlNode
330     * @return XmlNode : the next node
331     */
332    public function setNextNode(XmlNode $node)
333    {
334      $this->nextNode = $node;
335      return($this->nextNode);
336    }
337
338    /**
339     * returns the next node
340     *
341     * @return XmlNode or null
342     */
343    public function getNextNode()
344    {
345      return($this->nextNode);
346    }
347
348
349  }
350
351  class XmlData
352  {
353    private $xml = "";
354    private $nodes = Array();
355    private $isValid = false;
356    private $isLoaded = false;
357
358    /**
359     * the XmlData constructor needs ans Xml string
360     *
361     * @param String $xml : an xml structure in a string
362     */
363    function __construct($xml)
364    {
365      $this->isValid = $this->setXmlData($xml);
366      $this->isLoaded = $this->hasNodes();
367    }
368
369    function __destruct()
370    {
371      unset($this->nodes);
372    }
373
374    /**
375     * returns true if the xml is valid
376     *
377     * @return Boolean
378     */
379    public function isValid()
380    {
381      return($this->isValid);
382    }
383
384    /**
385     * returns true if the xml has been successfully loaded
386     *
387     * @return Boolean
388     */
389    public function isLoaded()
390    {
391      return($this->isLoaded);
392    }
393
394    /**
395     * returns true if XmlData has nodes
396     *
397     * @return Boolean
398     */
399    public function hasNodes()
400    {
401      return(count($this->nodes)>0);
402    }
403
404    /**
405     * returns the first node of the XmlData
406     *
407     * @return XmlNode or null
408     */
409    public function getFirstNode()
410    {
411      if(count($this->nodes)>0)
412      {
413        return($this->nodes[0]);
414      }
415      else
416      {
417        return(null);
418      }
419    }
420
421    /**
422     * returns the last node of the XmlData
423     *
424     * @return XmlNode or null
425     */
426    public function getLastNode()
427    {
428      if(count($this->nodes)>0)
429      {
430        return($this->nodes[count($this->nodes)-1]);
431      }
432      else
433      {
434        return(null);
435      }
436    }
437
438    /**
439     * set the xml data
440     * return true if the xml is valid and the xml tree is built
441     *
442     * @param String $xml : an xml structure in a string
443     * @return Boolean
444     */
445    public function setXmlData($xml)
446    {
447      if(is_string($xml))
448      {
449        $this->xml=$xml;
450        return($this->buildTreeNode());
451      }
452      return(false);
453    }
454
455    /**
456     * the xml_parse_info_struct load an XML file into a one dimension array
457     * this function build a tree with XmlNode object
458     */
459    private function buildTreeNode()
460    {
461      $xmlParser = xml_parser_create();
462      xml_parser_set_option($xmlParser, XML_OPTION_CASE_FOLDING, 0);
463      xml_parser_set_option($xmlParser, XML_OPTION_SKIP_WHITE, 1);
464      $result=xml_parse_into_struct($xmlParser, $this->xml, $values);
465      xml_parser_free($xmlParser);
466
467      //an error has occured while parsing the xml structure
468      if($result===0) return(false);
469
470
471      $tree=Array();
472
473      for($i=0;$i<count($values);$i++)
474      {
475        $val=$values[$i];
476
477        switch($val['type'])
478        {
479          case "open":
480          case "complete":
481            $node=new XmlNode($val['tag'], $val['level']);
482
483            if(array_key_exists('value', $val))
484            {
485              $node->setValue($val['value']);
486            }
487
488            if(array_key_exists('attributes', $val))
489            {
490              foreach($val['attributes'] as $itemKey => $itemVal)
491              {
492                $node->addAttribute($itemKey, $itemVal);
493              }
494            }
495
496            if(count($tree)>0)
497            {
498              $parent=$tree[count($tree)-1];
499              if($parent->hasChilds())
500              {
501                $parent->getLastChild()->setNextNode($node);
502                $node->setPreviousNode($parent->getLastChild());
503              }
504              $parent->addChild($node);
505            }
506
507            if($val['type']=="open")
508            {
509              array_push($tree, $node);
510            }
511
512            $this->nodes[]=$node;
513            break;
514          case "close":
515            array_pop($tree);
516            break;
517        }
518      }
519      unset($tree);
520      return(true);
521    }
522
523  }
524
525?>
Note: See TracBrowser for help on using the repository browser.