PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / storage / class-abstractmemorystorage.php

class-abstractmemorystorage.php in DecaLog 4.4.0, at includes/storage/class-abstractmemorystorage.php

284 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Memory abstract storage engine for DecaLog.
4 *
5 * Handles all memory abstract storage features.
6 *
7 * @package Storage
8 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
9 * @since 3.4.0
10 */
11
12 namespace Decalog\Storage;
13
14 use Decalog\Plugin\Feature\EventTypes;
15 use Decalog\Plugin\Feature\Log;
16 use Decalog\System\Cache;
17 use Decalog\System\UUID;
18
19 /**
20 * Define the DecaLog memory abstract storage mechanisms.
21 *
22 * Handles all features of memory abstract storage engine for DecaLog.
23 *
24 * @package Storage
25 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
26 * @since 3.4.0
27 */
28 abstract class AbstractMemoryStorage extends AbstractStorage {
29
30 /**
31 * The pool's name, specific to the calling plugin.
32 *
33 * @since 3.4.0
34 * @var string $pool_name The pool's name.
35 */
36 protected $pool_name = DECALOG_SLUG;
37
38 /**
39 * Update bucket with current value.
40 *
41 * @return boolean The availability of this storage.
42 * @since 3.4.0
43 */
44 abstract protected function available();
45
46 /**
47 * Get the value of a global cache item.
48 *
49 * @param string $item_name Item name. Expected to not be SQL-escaped.
50 * @return mixed Value of item.
51 * @since 3.4.0
52 */
53 abstract protected function get_global( $item_name );
54
55 /**
56 * Set the value of a global cache item.
57 *
58 * You do not need to serialize values. If the value needs to be serialized, then
59 * it will be serialized before it is set.
60 *
61 * @param string $item_name Item name. Expected to not be SQL-escaped.
62 * @param mixed $value Item value. Must be serializable if non-scalar.
63 * Expected to not be SQL-escaped.
64 * @param int|string $ttl Optional. The previously defined ttl @see Cache::init() if it's a string.
65 * The ttl value in seconds if it's and integer.
66 * @return bool False if value was not set and true if value was set.
67 * @since 3.4.0
68 */
69 abstract protected function set_global( $item_name, $value, $ttl = 'default' );
70
71 /**
72 * Delete the value of a global cache item.
73 *
74 * @param string $item_name Item name. Expected to not be SQL-escaped.
75 * @return integer Number of deleted items.
76 * @since 3.4.0
77 */
78 abstract protected static function delete_global( $item_name );
79
80 /**
81 * Update bucket with current value.
82 *
83 * @param array $value The values to update or insert in the bucket.
84 * @return integer The inserted id if anny.
85 * @since 3.4.0
86 */
87 public function insert_value( $value ) {
88 if ( ! $this->available() ) {
89 return 0;
90 }
91 $log = $this->get_global( $this->bucket_name );
92 if ( ! isset( $log ) ) {
93 $log = [];
94 }
95 if ( is_array( $log ) ) {
96 $id = UUID::generate_unique_id( 32 );
97 $value['id'] = $id;
98 $log[ $id ] = $value;
99 $this->set_global( $this->bucket_name, $log, 'infinite' );
100 return 1;
101 }
102 return 0;
103 }
104
105 /**
106 * Initialize the logger.
107 *
108 * @since 3.4.0
109 */
110 public function initialize() {
111 if ( $this->available() && ! $this->get_global( $this->bucket_name ) ) {
112 $this->force_purge();
113 }
114 }
115
116 /**
117 * Update the logger.
118 *
119 * @param string $from The version from which the plugin is updated.
120 * @since 3.4.0
121 */
122 public function update( $from ) {
123
124 }
125
126 /**
127 * Finalize the logger.
128 *
129 * @since 3.4.0
130 */
131 public function finalize() {
132 $this->force_purge();
133 if ( $this->available() ) {
134 $log = Log::bootstrap( 'plugin', DECALOG_PRODUCT_SHORTNAME, DECALOG_VERSION );
135 $log->debug( sprintf( 'Logger "%s" dropped.', $this->bucket_name ) );
136 $this->delete_global( $this->bucket_name );
137 }
138 }
139
140 /**
141 * Force table purge.
142 *
143 * @since 3.4.0
144 */
145 public function force_purge() {
146 if ( $this->available() ) {
147 $this->set_global( $this->bucket_name, [], 'infinite' );
148 }
149 }
150
151 /**
152 * Rotate and purge.
153 *
154 * @var array $logger The logger definition.
155 * @return integer The number of deleted records.
156 * @since 3.4.0
157 */
158 public function cron_clean( $logger ) {
159 $count = 0;
160 if ( $this->available() ) {
161 $logs = $this->get_global( $this->bucket_name );
162 if ( isset( $logs ) && is_array( $logs ) ) {
163 if ( 0 < (int) $logger['configuration']['purge'] ) {
164 $time = time() - ( MINUTE_IN_SECONDS * HOUR_IN_SECONDS * DAY_IN_SECONDS * (int) $logger['configuration']['purge'] );
165 $l = [];
166 foreach ( $logs as $id => $log ) {
167 if ( ! array_key_exists( 'timestamp', $log ) ) {
168 $count++;
169 continue;
170 }
171 $t = strtotime( $log['timestamp'] );
172 if ( false === $t || $t < $time ) {
173 $count++;
174 continue;
175 }
176 $l[ $id ] = $log;
177 }
178 $logs = $l;
179 }
180 if ( 0 < (int) $logger['configuration']['rotate'] ) {
181 $logs = array_slice( $logs, - (int) $logger['configuration']['rotate'] );
182 }
183 $this->set_global( $this->bucket_name, array_values( $logs ), 'infinite' );
184 }
185 }
186 $log = Log::bootstrap( 'plugin', DECALOG_PRODUCT_SHORTNAME, DECALOG_VERSION );
187 if ( 0 === $count ) {
188 $log->info( sprintf( 'No old records to delete for logger "%s".', $logger['name'] ) );
189 } elseif ( 1 === $count ) {
190 $log->info( sprintf( '1 old record deleted for logger "%s".', $logger['name'] ) );
191 } else {
192 $log->info( sprintf( '%1$s old records deleted for logger "%2$s".', $count, $logger['name'] ) );
193 }
194 return $count;
195 }
196
197 /**
198 * Count logged errors.
199 *
200 * @var array $filters Optional. The filter to apply.
201 * @return integer The count of the filtered logged errors.
202 * @since 3.4.0
203 */
204 public function get_count( $filters = [] ) {
205 return count( $this->get_list( $filters ) );
206 }
207
208 /**
209 * Get list of logged errors.
210 *
211 * @param array $filters Optional. The filter to apply.
212 * @param integer $offset The offset to record.
213 * @param integer $rowcount Optional. The number of rows to return.
214 * @return array An array containing the filtered logged errors.
215 * @since 3.4.0
216 */
217 public function get_list( $filters, $offset = null, $rowcount = null ) {
218 $result = [];
219 if ( $this->available() ) {
220 $logs = $this->get_global( $this->bucket_name );
221 if ( isset( $logs ) && is_array( $logs ) ) {
222 $levels = [];
223 if ( 0 < count( $filters ) ) {
224 foreach ( $filters as $key => $filter ) {
225 if ( 'level' === $key ) {
226 foreach ( EventTypes::$levels as $str => $val ) {
227 if ( EventTypes::$levels[ $filter ] <= $val ) {
228 $levels[] = $str;
229 }
230 }
231 }
232 }
233 }
234 $l = [];
235 foreach ( $logs as $id => $log ) {
236 if ( 0 < count( $filters ) ) {
237 foreach ( $filters as $key => $filter ) {
238 if ( 'level' === $key && array_key_exists( 'level', $log ) ) {
239 if ( ! in_array( $log['level'], $levels, true ) ) {
240 continue 2;
241 }
242 } elseif ( array_key_exists( $key, $log ) ) {
243 if ( $log[ $key ] !== $filter ) {
244 continue 2;
245 }
246 }
247 }
248 }
249 if ( ! array_key_exists( 'instance', $log ) ) {
250 $log['instance'] = 'undefined';
251 }
252 $l[ $id ] = $log;
253 }
254 $logs = array_reverse( $l );
255 if ( ! is_null( $offset ) && ! is_null( $rowcount ) ) {
256 $logs = array_slice( $logs, $offset, $rowcount );
257 }
258 $result = $logs;
259 }
260 }
261 return $result;
262 }
263
264 /**
265 * Get a single logged error.
266 *
267 * @param string $id The id to record.
268 * @return array|null An array containing the logged error.
269 * @since 3.4.0
270 */
271 public function get_by_id( $id ) {
272 $logs = $this->get_list( [] );
273 if ( array_key_exists( $id, $logs ) ) {
274 $result = $logs[ $id ];
275 if ( ! array_key_exists( 'instance', $result ) ) {
276 $result['instance'] = 'undefined';
277 }
278 return $result;
279 }
280 return null;
281 }
282
283 }
284