implicit conversion of array to boolean.
1 | <?php |
||
2 | /** |
||
3 | * Elgg system log. |
||
4 | * Listens to events and writes crud events into the system log database. |
||
5 | * |
||
6 | * @package Elgg.Core |
||
7 | * @subpackage Logging |
||
8 | */ |
||
9 | |||
10 | /** |
||
11 | * Retrieve the system log based on a number of parameters. |
||
12 | * |
||
13 | * @param array $options Options |
||
14 | * |
||
15 | * @option int $limit Maximum number of responses to return. (default from settings) |
||
16 | * @option int $offset Offset of where to start. |
||
17 | * @option bool $count Return count or not |
||
18 | * @option int|array $performed_by_guid The guid(s) of the user(s) who initiated the event. |
||
19 | * @option string $event The event you are searching on. |
||
20 | * @option string $object_class The class of object it effects. |
||
21 | * @option string $object_type The type |
||
22 | * @option string $object_subtype The subtype. |
||
23 | * @option int $object_id GUID of an object |
||
24 | * @option int $created_before Lower time limit |
||
25 | * @option int $created_after Upper time limit |
||
26 | * @option string $ip_address The IP address. |
||
27 | * |
||
28 | * @return int|stdClass[] |
||
29 | */ |
||
30 | function system_log_get_log($options = null) { |
||
31 | |||
32 | 2 | if (!is_array($options)) { |
|
33 | 2 | elgg_deprecated_notice(__FUNCTION__ . ' accepts a single argument as an array of options', '3.0'); |
|
34 | |||
35 | 2 | $options = []; |
|
36 | |||
37 | 2 | $arguments = func_get_args(); |
|
38 | 2 | $arguments = array_pad($arguments, 12, null); |
|
39 | |||
40 | 2 | $options['performed_by_guid'] = $arguments[0]; |
|
41 | 2 | $options['event'] = $arguments[1]; |
|
42 | 2 | $options['object_class'] = $arguments[2]; |
|
43 | 2 | $options['object_type'] = $arguments[3]; |
|
44 | 2 | $options['object_subtype'] = $arguments[4]; |
|
45 | 2 | $options['limit'] = $arguments[5]; |
|
46 | 2 | $options['offset'] = $arguments[6]; |
|
47 | 2 | $options['count'] = $arguments[7]; |
|
48 | 2 | $options['created_before'] = $arguments[8]; |
|
49 | 2 | $options['created_after'] = $arguments[9]; |
|
50 | 2 | $options['object_id'] = $arguments[10]; |
|
51 | 2 | $options['ip_address'] = $arguments[11]; |
|
52 | } |
||
53 | |||
54 | 2 | $query = new \Elgg\SystemLog\SystemLogQuery(); |
|
55 | 2 | foreach ($options as $key => $value) { |
|
56 | 2 | $query->$key = $value; |
|
57 | } |
||
58 | |||
59 | 2 | return $query->execute(); |
|
60 | } |
||
61 | |||
62 | /** |
||
63 | * Return a specific log entry. |
||
64 | * |
||
65 | * @param int $entry_id The log entry |
||
66 | * |
||
67 | * @return stdClass|false |
||
68 | */ |
||
69 | function system_log_get_log_entry($entry_id) { |
||
70 | 1 | $entry_id = (int) $entry_id; |
|
71 | |||
72 | 1 | $qb = \Elgg\Database\Select::fromTable('system_log'); |
|
73 | 1 | $qb->select('*'); |
|
74 | 1 | $qb->where($qb->compare('id', '=', $entry_id, ELGG_VALUE_INTEGER)); |
|
75 | |||
76 | 1 | return _elgg_services()->db->getDataRow($qb); |
|
77 | } |
||
78 | |||
79 | /** |
||
80 | * Return the object referred to by a given log entry |
||
81 | * |
||
82 | * @param \stdClass|int $entry The log entry row or its ID |
||
83 | * |
||
84 | * @return mixed |
||
85 | */ |
||
86 | function system_log_get_object_from_log_entry($entry) { |
||
87 | 1 | if (is_numeric($entry)) { |
|
88 | 1 | $entry = system_log_get_log_entry($entry); |
|
89 | 1 | if (!$entry) { |
|
90 | return false; |
||
91 | } |
||
92 | } |
||
93 | |||
94 | 1 | $class = $entry->object_class; |
|
95 | 1 | $id = $entry->object_id; |
|
96 | |||
97 | 1 | if (!class_exists($class)) { |
|
98 | // failed autoload |
||
99 | return false; |
||
100 | } |
||
101 | |||
102 | $getters = [ |
||
103 | 1 | ElggAnnotation::class => 'elgg_get_annotation_from_id', |
|
104 | ElggMetadata::class => 'elgg_get_metadata_from_id', |
||
105 | ElggRelationship::class => 'get_relationship', |
||
106 | ]; |
||
107 | |||
108 | 1 | if (isset($getters[$class]) && is_callable($getters[$class])) { |
|
109 | $object = call_user_func($getters[$class], $id); |
||
110 | 1 | } else if (preg_match('~^Elgg[A-Z]~', $class)) { |
|
111 | 1 | $object = get_entity($id); |
|
112 | } else { |
||
113 | // surround with try/catch because object could be disabled |
||
114 | try { |
||
115 | $object = new $class($entry->object_id); |
||
116 | |||
117 | return $object; |
||
118 | } catch (Exception $e) { |
||
119 | } |
||
120 | } |
||
121 | |||
122 | 1 | if (!is_object($object) || get_class($object) !== $class) { |
|
123 | return false; |
||
124 | } |
||
125 | |||
126 | 1 | return $object; |
|
127 | } |
||
128 | |||
129 | /** |
||
130 | * Log a system event related to a specific object. |
||
131 | * |
||
132 | * This is called by the event system and should not be called directly. |
||
133 | * |
||
134 | * @param object $object The object you're talking about. |
||
135 | * @param string $event The event being logged |
||
136 | * |
||
137 | * @return void |
||
138 | */ |
||
139 | function system_log($object, $event) { |
||
140 | 429 | $insert = new \Elgg\SystemLog\SystemLogInsert(); |
|
141 | 429 | return $insert->insert($object, $event); |
|
142 | } |
||
143 | |||
144 | /** |
||
145 | * This function creates an archive copy of the system log. |
||
146 | * |
||
147 | * @param int $offset An offset in seconds from now to archive (useful for log rotation) |
||
148 | * |
||
149 | * @return bool |
||
150 | */ |
||
151 | function system_log_archive_log($offset = 0) { |
||
152 | 1 | $offset = (int) $offset; |
|
153 | 1 | $now = time(); // Take a snapshot of now |
|
154 | 1 | $prefix = _elgg_config()->dbprefix; |
|
155 | |||
156 | 1 | $ts = $now - $offset; |
|
157 | |||
158 | // create table |
||
159 | $query = " |
||
160 | 1 | CREATE TABLE {$prefix}system_log_$now as |
|
161 | 1 | SELECT * FROM {$prefix}system_log |
|
162 | 1 | WHERE time_created < $ts |
|
163 | "; |
||
164 | |||
165 | 1 | if (!update_data($query)) { |
|
166 | return false; |
||
167 | } |
||
168 | |||
169 | // delete |
||
170 | // Don't delete on time since we are running in a concurrent environment |
||
171 | 1 | if (delete_data("DELETE from {$prefix}system_log WHERE time_created < $ts") === false) { |
|
172 | return false; |
||
173 | } |
||
174 | |||
175 | // alter table to engine |
||
176 | 1 | if (!update_data("ALTER TABLE {$prefix}system_log_$now engine=archive")) { |
|
177 | return false; |
||
178 | } |
||
179 | |||
180 | 1 | return true; |
|
181 | } |
||
182 | |||
183 | /** |
||
184 | * Convert an interval to seconds |
||
185 | * |
||
186 | * @param string $period interval |
||
187 | * |
||
188 | * @return int |
||
189 | */ |
||
190 | function system_log_get_seconds_in_period($period) { |
||
191 | $seconds_in_day = 86400; |
||
192 | switch ($period) { |
||
193 | case 'weekly': |
||
194 | $offset = $seconds_in_day * 7; |
||
195 | break; |
||
196 | case 'yearly': |
||
197 | $offset = $seconds_in_day * 365; |
||
198 | break; |
||
199 | case 'monthly': |
||
200 | default: |
||
201 | // assume 28 days even if a month is longer. Won't cause data loss. |
||
202 | $offset = $seconds_in_day * 28; |
||
203 | } |
||
204 | |||
205 | return $offset; |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * This function deletes archived copies of the system logs that are older than specified |
||
210 | * |
||
211 | * @param int $time_of_delete An offset in seconds from now to delete log tables |
||
212 | * |
||
213 | * @return bool |
||
214 | */ |
||
215 | function system_log_browser_delete_log($time_of_delete) { |
||
216 | 1 | $dbprefix = elgg_get_config('dbprefix'); |
|
217 | 1 | $cutoff = time() - (int) $time_of_delete; |
|
218 | |||
219 | 1 | $deleted_tables = false; |
|
220 | 1 | $results = get_data("SHOW TABLES like '{$dbprefix}system_log_%'"); |
|
221 | 1 | if ($results) { |
|
0 ignored issues
–
show
|
|||
222 | 1 | foreach ($results as $result) { |
|
223 | 1 | $data = (array) $result; |
|
224 | 1 | $table_name = array_shift($data); |
|
225 | // extract log table rotation time |
||
226 | 1 | $log_time = str_replace("{$dbprefix}system_log_", '', $table_name); |
|
227 | 1 | if ($log_time < $cutoff) { |
|
228 | if (delete_data("DROP TABLE $table_name") !== false) { |
||
229 | // delete_data returns 0 when dropping a table (false for failure) |
||
230 | $deleted_tables = true; |
||
231 | } else { |
||
232 | 1 | elgg_log("Failed to delete the log table $table_name", 'ERROR'); |
|
233 | } |
||
234 | } |
||
235 | } |
||
236 | } |
||
237 | |||
238 | return $deleted_tables; |
||
239 | } |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.