NodeComparator.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\model;
12 
15 
16 /**
17  * NodeComparator is used to compare nodes by given criterias.
18  *
19  * The following example shows the usage:
20  *
21  * @code
22  * $nodeList = array(...); // array of Node instances
23  *
24  * // simple sort by creator attribute
25  * $comparator = new NodeComparator('creator');
26  * usort($nodeList, array($comparator, 'compare'));
27  *
28  * // more complex example with different attributes
29  * $sortCriteria = array(
30  * NodeComparator::ATTRIB_TYPE => NodeComparator::SORTTYPE_ASC,
31  * 'created' => NodeComparator::SORTTYPE_DESC
32  * );
33  * $comparator = new NodeComparator($sortCriteria);
34  * usort($nodeList, array($comparator, 'compare'));
35  * @endcode
36  *
37  * @author ingo herwig <ingo@wemove.com>
38  */
40 
41  const SORTTYPE_ASC = -1; // sort children ascending
42  const SORTTYPE_DESC = -2; // sort children descending
43  const ATTRIB_OID = -3; // sort by oid
44  const ATTRIB_TYPE = -4; // sort by type
45 
46  private $_sortCriteria;
47 
48  /**
49  * Constructor
50  * @param $sortCriteria An assoziative array of criteria - SORTTYPE constant pairs OR a single criteria string.
51  * possible criteria: NodeComparator::OID, NodeComparator::TYPE or any value/property name
52  * (e.g. array(NodeComparator::OID => NodeComparator::SORTTYPE_ASC, 'name' => NodeComparator::SORTTYPE_DESC) OR 'name')
53  * @note If criteria is only a string we will sort by this criteria with NodeComparator::SORTTYPE_ASC
54  */
55  public function __construct(array $sortCriteria) {
56  $this->_sortCriteria = $sortCriteria;
57  }
58 
59  /**
60  * Compare function for sorting Nodes by the list of criterias
61  * @param $a First Node instance
62  * @param $b First Node instance
63  * @return -1, 0 or 1 whether a is less, equal or greater than b
64  * in respect of the criteria
65  */
66  public function compare(Node $a, Node $b) {
67  // we compare for each criteria and sum the results for $a, $b
68  // afterwards we compare the sums and return -1,0,1 appropriate
69  $sumA = 0;
70  $sumB = 0;
71  $maxWeight = sizeOf($this->_sortCriteria);
72  $i = 0;
73  foreach ($this->_sortCriteria as $criteria => $sortType) {
74  $weightedValue = ($maxWeight-$i)*($maxWeight-$i);
75  $AGreaterB = 0;
76  // sort by id
77  if ($criteria == self::ATTRIB_OID) {
78  if ($a->getOID() != $b->getOID()) {
79  ($a->getOID() > $b->getOID()) ? $AGreaterB = 1 : $AGreaterB = -1;
80  }
81  }
82  // sort by type
83  else if ($criteria == self::ATTRIB_TYPE) {
84  if ($a->getType() != $b->getType()) {
85  ($a->getType() > $b->getType()) ? $AGreaterB = 1 : $AGreaterB = -1;
86  }
87  }
88  // sort by value
89  else if($a->getValue($criteria) != null || $b->getValue($criteria) != null) {
90  $aValue = strToLower($a->getValue($criteria));
91  $bValue = strToLower($b->getValue($criteria));
92  if ($aValue != $bValue) {
93  ($aValue > $bValue) ? $AGreaterB = 1 : $AGreaterB = -1;
94  }
95  }
96  // sort by property
97  else if($a->getProperty($criteria) != null || $b->getProperty($criteria) != null) {
98  $aProperty = strToLower($a->getProperty($criteria));
99  $bProperty = strToLower($b->getProperty($criteria));
100  if ($aProperty != $bProperty) {
101  ($aProperty > $bProperty) ? $AGreaterB = 1 : $AGreaterB = -1;
102  }
103  }
104  // calculate result of current criteria depending on current sorttype
105  if ($sortType == self::SORTTYPE_ASC) {
106  if ($AGreaterB == 1) { $sumA += $weightedValue; }
107  else if ($AGreaterB == -1) { $sumB += $weightedValue; }
108  }
109  else if ($sortType == self::SORTTYPE_DESC) {
110  if ($AGreaterB == 1) { $sumB += $weightedValue; }
111  else if ($AGreaterB == -1) { $sumA += $weightedValue; }
112  }
113  else {
114  throw new IllegalArgumentException("Unknown SORTTYPE.");
115  }
116  $i++;
117  }
118  if ($sumA == $sumB) { return 0; }
119  return ($sumA > $sumB) ? 1 : -1;
120  }
121 }
122 ?>
getValue($name)
Definition: Node.php:91
Node related interfaces and classes.
Definition: namespaces.php:26
NodeComparator is used to compare nodes by given criterias.
IllegalArgumentException signals an exception in method arguments.
__construct(array $sortCriteria)
Constructor.
compare(Node $a, Node $b)
Compare function for sorting Nodes by the list of criterias.
Node adds the concept of relations to PersistentObject.
Definition: Node.php:34