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