Completed
Push — work-fleets ( 961997...006942 )
by SuperNova.WS
06:22
created

IndexedObjectStorage::indexSet()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 5
Bugs 0 Features 1
Metric Value
cc 3
eloc 8
c 5
b 0
f 1
nc 3
nop 2
dl 0
loc 14
ccs 7
cts 7
cp 1
crap 3
rs 9.4285
1
<?php
2
/**
3
 * Created by Gorlum 17.08.2016 23:08
4
 */
5
6
namespace Common;
7
8
use \SplObjectStorage;
9
10
/**
11
 * Class IndexedObjectStorage
12
 *
13
 * Maintains per-method compatibility with SplObjectStorage
14
 * Introduces new methods:
15
 *    - check index existence
16
 *    - Get object by index
17
 *
18
 * @package Common
19
 */
20
class IndexedObjectStorage extends \SplObjectStorage {
21
22
  protected $index = array();
23
24
  /**
25
   * @param mixed $index
26
   *
27
   * @return bool
28
   */
29 1
  public function indexIsSet($index) {
30 1
    return array_key_exists($index, $this->index);
31
  }
32
33
  /**
34
   * @param mixed $index
35
   *
36
   * @return mixed|null
37
   */
38 1
  public function indexGetObject($index) {
39 1
    return $this->indexIsSet($index) ? $this->index[$index] : null;
40
  }
41
42 1
  public function offsetSet($object, $data = null) {
43 1
    $this->attach($object, $data);
44 1
  }
45
46 1
  public function offsetUnset($object) {
47 1
    $this->detach($object);
48 1
    parent::offsetUnset($object);
49 1
  }
50
51
52
  /**
53
   * Unassign index from object
54
   *
55
   * @param object $object
56
   */
57 1
  protected function indexUnset($object) {
58 1
    if (($oldData = parent::offsetGet($object)) !== null) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (offsetGet() instead of indexUnset()). Are you sure this is correct? If so, you might want to change this to $this->offsetGet().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
59 1
      unset($this->index[$oldData]);
60 1
    }
61 1
  }
62
63
  /**
64
   * Function called when index already exists
65
   *
66
   * Can be used by child object
67
   *
68
   * @param $object
69
   * @param $data
70
   *
71
   * @throws \Exception
72
   */
73 1
  protected function onObjectIndexDuplicated($object, $data) {
74 1
    throw new \Exception('Duplicate index [' . $data . '] in ' . __CLASS__);
75
  }
76
77
  /**
78
   * Function called when index is empty
79
   *
80
   * To use with child object
81
   *
82
   * @param $object
83
   *
84
   * @return bool
85
   */
86 1
  protected function onObjectIndexEmpty($object) {
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
    // Do something if index is empty
88 1
    return true;
89
  }
90
91
  /**
92
   * Function to handle assigning keys
93
   *
94
   * Primary for dealing with duplicates - child can overwrite function to handle duplicates by itself
95
   *
96
   * @param object     $object
97
   * @param mixed|null $data - null means remove index
98
   *
99
   * @return bool
100
   */
101
  // Set indexes for existing objects
102 2
  protected function indexSet($object, $data = null) {
103
    // When calling indexSet - $object already SHOULD not have index associated in this concrete implementation
104
105
    // Checking if index free. NULL index is always free
106 2
    if (isset($this->index[$data])) {
107 1
      return $this->onObjectIndexDuplicated($object, $data);
108 2
    } elseif ($data === null) {
109 1
      return $this->onObjectIndexEmpty($object);
110
    } else {
111
      // Assigning index
112 2
      $this->index[$data] = $object;
113 2
      return true;
114
    }
115
  }
116
117 1
  public function attach($object, $data = null) {
118
    // If object already in storage - removing it's index from $indexes
119 1
    if ($this->contains($object)) {
120 1
      $this->indexUnset($object);
121 1
    }
122 1
    if($this->indexSet($object, $data)) {
123
      // Attaches object only if index sets successfully
124 1
      parent::attach($object, $data);
125 1
    }
126 1
  }
127
128 1
  public function detach($object) {
129 1
    $this->indexUnset($object);
130 1
    parent::detach($object);
131 1
  }
132
133 1
  public function setInfo($data) {
134 1
    if ($this->valid()) {
135
      // Removing index from current object - if any
136 1
      $this->indexUnset($this->current());
137
      // Setting new index for current object
138 1
      $this->indexSet($this->current(), $data);
139
      // Changing object data in storage - giving to
140 1
      parent::setInfo($data);
141 1
    }
142 1
  }
143
144
145
  /**
146
   * Rebuild index
147
   */
148 2
  protected function indexRebuild() {
149 2
    $this->index = array();
150 2
    $this->rewind();
151 2
    while ($this->valid()) {
152 2
      $this->indexSet($this->current(), $this->getInfo());
153 2
      $this->next();
154 2
    }
155 1
  }
156
157 1
  public function addAll($storage) {
158
    // Adding new elements from storage
159 1
    parent::addAll($storage);
160
    // Original addAll overwrites indexes with those in input $storage - so we must refresh current indexes
161 1
    $this->indexRebuild();
162 1
  }
163
164 1
  public function removeAll($storage) {
165 1
    parent::removeAll($storage);
166 1
    $this->indexRebuild();
167 1
  }
168
169 1
  public function removeAllExcept($storage) {
170 1
    parent::removeAllExcept($storage);
171 1
    $this->indexRebuild();
172 1
  }
173
174 1
  public function unserialize($serialized) {
175
    // Unserialize DOES NOT removes existing objects AND creates object copies making duplicates
176
    // So be careful
177 1
    parent::unserialize($serialized);
178 1
    $this->indexRebuild();
179 1
  }
180
181
}
182