PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
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 months ago DistributedList.php 1 month ago Lock.php 1 month ago LockBackend.php 2 years ago
DistributedList.php
143 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik\Concurrency;
10
11 use Piwik\Common;
12 use Piwik\Container\StaticContainer;
13 use Piwik\Option;
14 use Piwik\Log\LoggerInterface;
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 * @var LoggerInterface
33 */
34 private $logger;
35 /**
36 * @param string $optionName
37 */
38 public function __construct($optionName, ?LoggerInterface $logger = null)
39 {
40 $this->optionName = $optionName;
41 $this->logger = $logger ?: StaticContainer::get(LoggerInterface::class);
42 }
43 /**
44 * Queries the option table and returns all items in this list.
45 *
46 * @return array
47 */
48 public function getAll()
49 {
50 $result = $this->getListOptionValue();
51 foreach ($result as $key => $item) {
52 // remove non-array items (unexpected state, though can happen when upgrading from an old Piwik)
53 if (is_array($item)) {
54 $this->logger->info("Found array item in DistributedList option value '{name}': {data}", array('name' => $this->optionName, 'data' => var_export($result, \true)));
55 unset($result[$key]);
56 }
57 }
58 return $result;
59 }
60 /**
61 * Sets the contents of the list in the option table.
62 *
63 * @param string[] $items
64 */
65 public function setAll($items)
66 {
67 foreach ($items as $key => &$item) {
68 if (is_array($item)) {
69 throw new \InvalidArgumentException("Array item encountered in DistributedList::setAll() [ key = {$key} ].");
70 } else {
71 $item = (string) $item;
72 }
73 }
74 Option::set($this->optionName, serialize($items));
75 }
76 /**
77 * Adds one or more items to the list in the option table.
78 *
79 * @param string|array $item
80 */
81 public function add($item)
82 {
83 $allItems = $this->getAll();
84 if (is_array($item)) {
85 $allItems = array_merge($allItems, $item);
86 } else {
87 $allItems[] = $item;
88 }
89 $this->setAll($allItems);
90 }
91 /**
92 * Removes one or more items by value from the list in the option table.
93 *
94 * Does not preserve array keys.
95 *
96 * @param string|array $items
97 */
98 public function remove($items)
99 {
100 if (!is_array($items)) {
101 $items = array($items);
102 }
103 $allItems = $this->getAll();
104 foreach ($items as $item) {
105 $existingIndex = array_search($item, $allItems);
106 if ($existingIndex === \false) {
107 return;
108 }
109 unset($allItems[$existingIndex]);
110 }
111 $this->setAll(array_values($allItems));
112 }
113 /**
114 * Removes one or more items by index from the list in the option table.
115 *
116 * Does not preserve array keys.
117 *
118 * @param int[]|int $indices
119 */
120 public function removeByIndex($indices)
121 {
122 if (!is_array($indices)) {
123 $indices = array($indices);
124 }
125 $indices = array_unique($indices);
126 $allItems = $this->getAll();
127 foreach ($indices as $index) {
128 unset($allItems[$index]);
129 }
130 $this->setAll(array_values($allItems));
131 }
132 protected function getListOptionValue()
133 {
134 Option::clearCachedOption($this->optionName);
135 $array = Option::get($this->optionName);
136 $result = array();
137 if ($array && ($array = Common::safe_unserialize($array)) && count($array)) {
138 $result = $array;
139 }
140 return $result;
141 }
142 }
143