Yaffs site version 1.1
[yaffs-website] / vendor / drush / drush / commands / core / watchdog.drush.inc
1 <?php
2
3 use Drush\Log\LogLevel;
4 use Drupal\Component\Utility\Unicode;
5 use Drupal\Component\Utility\Html;
6
7 /**
8  * Implementation of hook_drush_help().
9  */
10 function watchdog_drush_help($section) {
11   switch ($section)  {
12     case 'meta:watchdog:title':
13       return dt('Watchdog commands');
14     case 'meta:watchdog:summary':
15       return dt('Interact with Drupal\'s db logging system.');
16     case 'drush:watchdog-list':
17       return dt('Show available message types and severity levels. A prompt will ask for a choice to show watchdog messages.');
18     case 'drush:watchdog-show':
19       return dt('Show watchdog messages. Arguments and options can be combined to configure which messages to show.');
20     case 'drush:watchdog-delete':
21       return dt('Delete watchdog messages. Arguments or options must be provided to specify which messages to delete.');
22   }
23 }
24
25 /**
26  * Implementation of hook_drush_command().
27  */
28 function watchdog_drush_command() {
29   $items['watchdog-list'] = array(
30     'description' => 'Show available message types and severity levels. A prompt will ask for a choice to show watchdog messages.',
31     'drupal dependencies' => array('dblog'),
32     'outputformat' => array(
33       'default' => 'table',
34       'pipe-format' => 'var_export',
35       'field-labels' => array('wid' => 'ID', 'type' => 'Type', 'message' => 'Message', 'severity' => 'Severity', 'location' => 'Location', 'hostname' => 'Hostname', 'date' => 'Date', 'username' => 'Username'),
36       'fields-default' => array('wid', 'date', 'type', 'severity', 'message'),
37       'column-widths' => array('type' => 8, 'severity' => 8),
38       'output-data-type' => 'format-table',
39     ),
40     'aliases' => array('wd-list'),
41   );
42   $items['watchdog-show'] = array(
43     'description' => 'Show watchdog messages.',
44     'drupal dependencies' => array('dblog'),
45     'arguments' => array(
46       'wid' => 'Optional id of a watchdog message to show in detail. If not provided, a listing of most recent 10 messages will be displayed. Alternatively if a string is provided, watchdog messages will be filtered by it.',
47     ),
48     'options' => array(
49       'count' => 'The number of messages to show. Defaults to 10.',
50       'severity' => 'Restrict to messages of a given severity level.',
51       'type' => 'Restrict to messages of a given type.',
52       'tail' => 'Continuously show new watchdog messages until interrupted.',
53       'sleep-delay' => 'To be used in conjunction with --tail. This is the number of seconds to wait between each poll to the database. Delay is 1 second by default.',
54       'extended' => 'Return extended information about each message.',
55     ),
56     'examples' => array(
57       'drush watchdog-show' => 'Show a listing of most recent 10 messages.',
58       'drush watchdog-show 64' => 'Show in detail message with id 64.',
59       'drush watchdog-show "cron run succesful"' => 'Show a listing of most recent 10 messages containing the string "cron run succesful".',
60       'drush watchdog-show --count=46' => 'Show a listing of most recent 46 messages.',
61       'drush watchdog-show --severity=notice' => 'Show a listing of most recent 10 messages with a severity of notice.',
62       'drush watchdog-show --type=php' => 'Show a listing of most recent 10 messages of type php.',
63       'drush watchdog-show --tail --extended' => 'Show a listing of most recent 10 messages with extended information about each one and continue showing messages as they are registered in the watchdog.',
64       'drush watchdog-show --tail --sleep-delay=2' => 'Do a tail of the watchdog with a delay of two seconds between each poll to the database.',
65     ),
66     'outputformat' => array(
67       'default' => 'table',
68       'pipe-format' => 'var_export',
69       'field-labels' => array('wid' => 'ID', 'type' => 'Type', 'message' => 'Message', 'severity' => 'Severity', 'location' => 'Location', 'hostname' => 'Hostname', 'date' => 'Date', 'username' => 'Username'),
70       'fields-default' => array('wid', 'date', 'type', 'severity', 'message'),
71       'column-widths' => array('type' => 8, 'severity' => 8),
72       'output-data-type' => 'format-table',
73     ),
74     'aliases' => array('wd-show', 'ws'),
75   );
76   $items['watchdog-delete'] = array(
77     'description' => 'Delete watchdog messages.',
78     'drupal dependencies' => array('dblog'),
79     'options' => array(
80       'severity' => 'Delete messages of a given severity level.',
81       'type' => 'Delete messages of a given type.',
82     ),
83     'examples' => array(
84       'drush watchdog-delete all' => 'Delete all messages.',
85       'drush watchdog-delete 64' => 'Delete messages with id 64.',
86       'drush watchdog-delete "cron run succesful"' => 'Delete messages containing the string "cron run succesful".',
87       'drush watchdog-delete --severity=notice' => 'Delete all messages with a severity of notice.',
88       'drush watchdog-delete --type=cron' => 'Delete all messages of type cron.',
89     ),
90     'aliases' => array('wd-del', 'wd-delete'),
91   );
92   return $items;
93 }
94
95 /**
96  * Command callback.
97  */
98 function drush_core_watchdog_list() {
99   drush_include_engine('drupal', 'environment');
100
101   $options['-- types --'] = dt('== message types ==');
102   $types = drush_watchdog_message_types();
103   foreach ($types as $key => $type) {
104     $options[$key] = $type;
105   }
106   $options['-- levels --'] = dt('== severity levels ==');
107   $severities = drush_watchdog_severity_levels();
108   foreach ($severities as $key => $value) {
109     $options[$key] = "$value($key)";
110   }
111   $option = drush_choice($options, dt('Select a message type or severity level.'));
112   if ($option === FALSE) {
113     return drush_user_abort();
114   }
115   if (isset($types[$option])) {
116     drush_set_option('type', $types[$option]);
117   }
118   else {
119     drush_set_option('severity', $option - $ntypes);
120   }
121   return drush_core_watchdog_show_many();
122 }
123
124 /**
125  * Command callback.
126  */
127 function drush_core_watchdog_show($arg = NULL) {
128   drush_include_engine('drupal', 'environment');
129
130   if (is_numeric($arg)) {
131     return drush_core_watchdog_show_one($arg);
132   }
133   else {
134     return drush_core_watchdog_show_many($arg);
135   }
136 }
137
138 /**
139  * Print a watchdog message.
140  *
141  * @param $wid
142  *    The id of the message to show.
143  */
144 function drush_core_watchdog_show_one($wid) {
145   drush_set_default_outputformat('key-value-list', array('fields-default' => array('wid', 'type', 'message', 'severity', 'date'),));
146   $rsc = drush_db_select('watchdog', '*', 'wid = :wid', array(':wid' => $wid), 0, 1);
147   $result = drush_db_fetch_object($rsc);
148   if (!$result) {
149     return drush_set_error(dt('Watchdog message #!wid not found.', array('!wid' => $wid)));
150   }
151   $result = core_watchdog_format_result($result, TRUE);
152   return array($result->wid => (array)$result);
153 }
154
155 /**
156  * Print a table of watchdog messages.
157  *
158  * @param $filter
159  *   String to filter the message's text by.
160  */
161 function drush_core_watchdog_show_many($filter = NULL) {
162   $count = drush_get_option('count', 10);
163   $type = drush_get_option('type');
164   $severity = drush_get_option('severity');
165   $tail = drush_get_option('tail', FALSE);
166   $extended = drush_get_option('extended', FALSE);
167
168   $where = core_watchdog_query($type, $severity, $filter);
169   if ($where === FALSE) {
170     return drush_log(dt('Aborting.'));
171   }
172   $rsc = drush_db_select('watchdog', '*', $where['where'], $where['args'], 0, $count, 'wid', 'DESC');
173   if ($rsc === FALSE) {
174     return drush_log(dt('Aborting.'));
175   }
176   $table = array();
177   while ($result = drush_db_fetch_object($rsc)) {
178     $row = core_watchdog_format_result($result, $extended);
179     $table[$row->wid] = (array)$row;
180   }
181   if (empty($table) && !$tail) {
182     drush_log(dt('No log messages available.'), LogLevel::OK);
183     return array();
184   }
185   else {
186     drush_log(dt('Most recent !count watchdog log messages:', array('!count' => $count)));
187   }
188   if ($tail) {
189     $field_list = array('wid' => 'ID', 'date' => 'Date', 'severity' => 'Severity', 'type' => 'Type', 'message' => 'Message');
190     $table = array_reverse($table);
191     $table_rows = drush_rows_of_key_value_to_array_table($table, $field_list, array());
192     $tbl = drush_print_table($table_rows, TRUE);
193     // Reuse the table object to display each line generated while in tail mode.
194     // To make it possible some hacking is done on the object:
195     // remove the header and reset the rows on each iteration.
196     $tbl->_headers = NULL;
197     // Obtain the last wid. If the table has no rows, start at 0.
198     if (count($table_rows) > 1) {
199       $last = array_pop($table_rows);
200       $last_wid = $last[0];
201     }
202     else {
203       $last_wid = 0;
204     }
205     // Adapt the where snippet.
206     if ($where['where'] != '') {
207       $where['where'] .= ' AND ';
208     }
209     $where['where'] .= 'wid > :wid';
210     // sleep-delay
211     $sleep_delay = drush_get_option('sleep-delay', 1);
212     while (TRUE) {
213       $where['args'][':wid'] = $last_wid;
214       $table = array();
215       // Reset table rows.
216       $tbl->_data = array();
217       $rsc = drush_db_select('watchdog', '*', $where['where'], $where['args'], NULL, NULL, 'wid', 'ASC');
218       while ($result = drush_db_fetch_object($rsc)) {
219         $row = core_watchdog_format_result($result, $extended);
220         $table[] = array($row->wid, $row->date, $row->severity, $row->type, $row->message);
221         #$tbl->addRow(array($row->wid, $row->date, $row->severity, $row->type, $row->message));
222         $last_wid = $row->wid;
223       }
224       $tbl->addData($table);
225       print $tbl->_buildTable();
226       sleep($sleep_delay);
227     }
228   }
229   return $table;
230 }
231
232 /**
233  * Format a watchdog database row.
234  *
235  * @param $result
236  *   Array. A database result object.
237  * @param $extended
238  *   Boolean. Return extended message details.
239  * @return
240  *   Array. The result object with some attributes themed.
241  */
242 function core_watchdog_format_result($result, $extended = FALSE) {
243   // Severity.
244   $severities = drush_watchdog_severity_levels();
245   $result->severity = $severities[$result->severity];
246
247   // Date.
248   $result->date = format_date($result->timestamp, 'custom', 'd/M H:i');
249   unset($result->timestamp);
250
251   // Message.
252   $variables = $result->variables;
253   if (is_string($variables)) {
254     $variables = unserialize($variables);
255   }
256   if (is_array($variables)) {
257     $result->message = strtr($result->message, $variables);
258   }
259   unset($result->variables);
260   $message_length = 188;
261
262   // Print all the data available
263   if ($extended) {
264     // Possible empty values.
265     if (empty($result->link)) {
266       unset($result->link);
267     }
268     if (empty($result->referer)) {
269       unset($result->referer);
270     }
271     // Username.
272     if ($account = user_load($result->uid)) {
273       $result->username = $account->name;
274     }
275     else {
276       $result->username = dt('Anonymous');
277     }
278     unset($result->uid);
279     $message_length = PHP_INT_MAX;
280   }
281
282   if (drush_drupal_major_version() >= 8) {
283     $result->message = Unicode::truncate(strip_tags(Html::decodeEntities($result->message)), $message_length, FALSE, FALSE);
284   }
285   else {
286     $result->message = truncate_utf8(strip_tags(decode_entities($result->message)), $message_length, FALSE, FALSE);
287   }
288
289   return $result;
290 }
291
292 /**
293  * Command callback.
294  *
295  * @param $arg
296  *   The id of the message to delete or 'all'.
297  */
298 function drush_core_watchdog_delete($arg = NULL) {
299   drush_include_engine('drupal', 'environment');
300
301   if ($arg == 'all') {
302     drush_print(dt('All watchdog messages will be deleted.'));
303     if (!drush_confirm(dt('Do you really want to continue?'))) {
304       return drush_user_abort();
305     }
306     drush_db_delete('watchdog');
307     drush_log(dt('All watchdog messages have been deleted.'), LogLevel::OK);
308   }
309   else if (is_numeric($arg)) {
310     drush_print(dt('Watchdog message #!wid will be deleted.', array('!wid' => $arg)));
311     if(!drush_confirm(dt('Do you really want to continue?'))) {
312       return drush_user_abort();
313     }
314     $affected_rows = drush_db_delete('watchdog', 'wid=:wid', array(':wid' => $arg));
315     if ($affected_rows == 1) {
316       drush_log(dt('Watchdog message #!wid has been deleted.', array('!wid' => $arg)), LogLevel::OK);
317     }
318     else {
319       return drush_set_error(dt('Watchdog message #!wid does not exist.', array('!wid' => $arg)));
320     }
321   }
322   else {
323     $type = drush_get_option('type');
324     $severity = drush_get_option('severity');
325     if ((!isset($arg))&&(!isset($type))&&(!isset($severity))) {
326       return drush_set_error(dt('No options provided.'));
327     }
328     $where = core_watchdog_query($type, $severity, $arg, 'OR');
329     if ($where === FALSE) {
330       // Drush set error was already called by core_watchdog_query
331       return FALSE;
332     }
333     drush_print(dt('All messages with !where will be deleted.', array('!where' => preg_replace("/message LIKE %$arg%/", "message body containing '$arg'" , strtr($where['where'], $where['args'])))));
334     if(!drush_confirm(dt('Do you really want to continue?'))) {
335       return drush_user_abort();
336     }
337     $affected_rows = drush_db_delete('watchdog', $where['where'], $where['args']);
338     drush_log(dt('!affected_rows watchdog messages have been deleted.', array('!affected_rows' => $affected_rows)), LogLevel::OK);
339   }
340 }
341
342 /**
343  * Build a WHERE snippet based on given parameters.
344  *
345  * @param $type
346  *   String. Valid watchdog type.
347  * @param $severity
348  *   Int or String for a valid watchdog severity message.
349  * @param $filter
350  *   String. Value to filter watchdog messages by.
351  * @param $criteria
352  *   ('AND', 'OR'). Criteria for the WHERE snippet.
353  * @return
354  *   False or array with structure ('where' => string, 'args' => array())
355  */
356 function core_watchdog_query($type = NULL, $severity = NULL, $filter = NULL, $criteria = 'AND') {
357   $args = array();
358   $conditions = array();
359   if ($type) {
360     $types = drush_watchdog_message_types();
361     if (array_search($type, $types) === FALSE) {
362       $msg = "Unrecognized message type: !type.\nRecognized types are: !types.";
363       return drush_set_error('WATCHDOG_UNRECOGNIZED_TYPE', dt($msg, array('!type' => $type, '!types' => implode(', ', $types))));
364     }
365     $conditions[] = "type = :type";
366     $args[':type'] = $type;
367   }
368   if (isset($severity)) {
369     $severities = drush_watchdog_severity_levels();
370     if (isset($severities[$severity])) {
371       $level = $severity;
372     }
373     elseif (($key = array_search($severity, $severities)) !== FALSE) {
374       $level = $key;
375     }
376     else {
377       $level = FALSE;
378     }
379     if ($level === FALSE) {
380       foreach ($severities as $key => $value) {
381         $levels[] = "$value($key)";
382       }
383       $msg = "Unknown severity level: !severity.\nValid severity levels are: !levels.";
384       return drush_set_error(dt($msg, array('!severity' => $severity, '!levels' => implode(', ', $levels))));
385     }
386     $conditions[] = 'severity = :severity';
387     $args[':severity'] = $level;
388   }
389   if ($filter) {
390     $conditions[] = "message LIKE :filter";
391     $args[':filter'] = '%'.$filter.'%';
392   }
393
394   $where = implode(" $criteria ", $conditions);
395
396   return array('where' => $where, 'args' => $args);
397 }