PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Concurrency / DistributedList.php
matomo / app / core / Concurrency Last commit date
LockBackend 6 years ago DistributedList.php 6 years ago Lock.php 6 years ago LockBackend.php 6 years ago
DistributedList.php
172 lines
1 <?php
2 /**
3 * Piwik - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 */
8 namespace Piwik\Concurrency;
9
10 use Piwik\Common;
11 use Piwik\Container\StaticContainer;
12 use Piwik\Option;
13 use Psr\Log\LoggerInterface;
14
15 /**
16 * Manages a simple distributed list stored in an Option. No locking occurs, so the list
17 * is not thread safe, and should only be used for use cases where atomicity is not
18 * important.
19 *
20 * The list of items is serialized and stored in an Option. Items are converted to string
21 * before being persisted, so it is not expected to unserialize objects.
22 */
23 class DistributedList
24 {
25 /**
26 * The name of the option to store the list in.
27 *
28 * @var string
29 */
30 private $optionName;
31
32 /**
33 * @var LoggerInterface
34 */
35 private $logger;
36
37 /**
38 * Constructor.
39 *
40 * @param string $optionName
41 */
42 public function __construct($optionName, LoggerInterface $logger = null)
43 {
44 $this->optionName = $optionName;
45 $this->logger = $logger ?: StaticContainer::get('Psr\Log\LoggerInterface');
46 }
47
48 /**
49 * Queries the option table and returns all items in this list.
50 *
51 * @return array
52 */
53 public function getAll()
54 {
55 $result = $this->getListOptionValue();
56
57 foreach ($result as $key => $item) {
58 // remove non-array items (unexpected state, though can happen when upgrading from an old Piwik)
59 if (is_array($item)) {
60 $this->logger->info("Found array item in DistributedList option value '{name}': {data}", array(
61 'name' => $this->optionName,
62 'data' => var_export($result, true)
63 ));
64
65 unset($result[$key]);
66 }
67 }
68
69 return $result;
70 }
71
72 /**
73 * Sets the contents of the list in the option table.
74 *
75 * @param string[] $items
76 */
77 public function setAll($items)
78 {
79 foreach ($items as $key => &$item) {
80 if (is_array($item)) {
81 throw new \InvalidArgumentException("Array item encountered in DistributedList::setAll() [ key = $key ].");
82 } else {
83 $item = (string)$item;
84 }
85 }
86
87 Option::set($this->optionName, serialize($items));
88 }
89
90 /**
91 * Adds one or more items to the list in the option table.
92 *
93 * @param string|array $item
94 */
95 public function add($item)
96 {
97 $allItems = $this->getAll();
98 if (is_array($item)) {
99 $allItems = array_merge($allItems, $item);
100 } else {
101 $allItems[] = $item;
102 }
103
104 $this->setAll($allItems);
105 }
106
107 /**
108 * Removes one or more items by value from the list in the option table.
109 *
110 * Does not preserve array keys.
111 *
112 * @param string|array $items
113 */
114 public function remove($items)
115 {
116 if (!is_array($items)) {
117 $items = array($items);
118 }
119
120 $allItems = $this->getAll();
121
122 foreach ($items as $item) {
123 $existingIndex = array_search($item, $allItems);
124 if ($existingIndex === false) {
125 return;
126 }
127
128 unset($allItems[$existingIndex]);
129 }
130
131 $this->setAll(array_values($allItems));
132 }
133
134 /**
135 * Removes one or more items by index from the list in the option table.
136 *
137 * Does not preserve array keys.
138 *
139 * @param int[]|int $indices
140 */
141 public function removeByIndex($indices)
142 {
143 if (!is_array($indices)) {
144 $indices = array($indices);
145 }
146
147 $indices = array_unique($indices);
148
149 $allItems = $this->getAll();
150 foreach ($indices as $index) {
151 unset($allItems[$index]);
152 }
153
154 $this->setAll(array_values($allItems));
155 }
156
157 protected function getListOptionValue()
158 {
159 Option::clearCachedOption($this->optionName);
160 $array = Option::get($this->optionName);
161
162 $result = array();
163 if ($array
164 && ($array = Common::safe_unserialize($array))
165 && count($array)
166 ) {
167 $result = $array;
168 }
169 return $result;
170 }
171 }
172