source: trunk/libs/Debug.php @ 1375

Revision 1375, 14.9 KB checked in by nick_ramsay, 3 years ago (diff)

[Trunk] Hotaru 1.1.3 [Run upgrade script]

Line 
1<?php
2/**
3 * Debugging functions
4 *
5 * PHP version 5
6 *
7 * LICENSE: Hotaru CMS is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * Hotaru CMS is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with Hotaru CMS. If not, see http://www.gnu.org/licenses/.
18 *
19 * @category  Content Management System
20 * @package   HotaruCMS
21 * @author    Nick Ramsay <admin@hotarucms.org>
22 * @copyright Copyright (c) 2009, Hotaru CMS
23 * @license   http://www.gnu.org/copyleft/gpl.html GNU General Public License
24 * @link      http://www.hotarucms.org/
25 */
26class Debug
27{
28    protected $fh = array();    // file handlers
29    protected $log = array();   // file paths
30   
31    /**
32     * Shows number of database queries and the time it takes for a page to load
33     */
34    public function showQueriesAndTime($h)
35    {
36        if ($h->isDebug) {
37       
38            $mysql_version = $h->db->get_var("SELECT VERSION() AS VE");
39           
40            echo "<p class='debug'>";
41            echo $h->lang['main_hotaru_db_queries'] . $h->db->num_queries . " | ";
42            echo $h->lang['main_hotaru_page_load_time'] . timer_stop(1) . $h->lang['main_times_secs'] . " | ";
43            echo $h->lang['main_hotaru_memory_usage'] . display_filesize(memory_get_usage()) . " | ";
44            echo $h->lang['main_hotaru_php_version'] . phpversion() . " | ";
45            echo $h->lang['main_hotaru_mysql_version'] . $mysql_version . " | ";
46            echo $h->lang['main_hotaru_hotaru_version'] . $h->version;
47            echo "</p>";
48        }
49
50        if ($h->currentUser->loggedIn) {echo "<span id='loggedIn' class='loggedIn_true'/>"; } else {"<span id='loggedIn' class='loggedIn_false'/>";}
51    }
52
53
54    /**
55     * Open file for logging
56     *
57     * @param string $type "speed", "error", etc.
58     * @param string $mode e.g. 'a' or 'w'.
59     * @link http://php.net/manual/en/function.fopen.php
60     */
61    public function openLog($type = 'debug', $mode = 'a+')
62    {
63        $this->log[$type] = CACHE . "debug_logs/" . $type . ".php";
64       
65        // delete file if over 500KB
66        if (file_exists($this->log[$type]) && (filesize($this->log[$type]) > 500000)) {
67            unlink($this->log[$type]);
68        }
69       
70        // If doesn't exist or rewriting, create a new file with die() at the top
71        if (!file_exists($this->log[$type]) || ($mode != 'a' && $mode != 'a+')) {
72            $this->fh[$type] = fopen($this->log[$type], $mode) or die("Sorry, I can't open cache/debug_logs/" . $type . ".php");
73            fwrite($this->fh[$type], "<?php die(); ?>\r\n");
74        } else {
75            // open existing file:
76            $this->fh[$type] = fopen($this->log[$type], $mode) or die("can't open file");
77        }
78    }
79   
80   
81    /**
82     * Log performance and errors
83     *
84     * @param string $type "error", "speed", etc.
85     */
86    public function writeLog($type = 'debug', $string = '')
87    {
88        if ($string) {
89            $string = date('d M Y H:i:s', time()) . " " . $string . "\n";
90            fwrite($this->fh[$type], $string);
91        }
92    }
93   
94   
95    /**
96     * Close log file
97     *
98     * @param string $type "speed", "error", etc.
99     */
100    public function closeLog($type = 'debug')
101    {
102        if (isset($this->fh[$type])) { fclose($this->fh[$type]); }
103    }
104   
105   
106    /**
107     * Generate a System Report
108     *
109     * @param string $type 'log', 'email' or 'object'
110     */
111    public function generateReport($h, $type = 'log')
112    {
113        $report = $this->getSystemData($h);
114       
115        if ($type == 'object') { return $report; }
116       
117        if ($type == 'email') {
118            $to = "admin@hotarucms.org"; // do not change!
119            $subject = "System Report from " . SITE_NAME;
120            $body = $this->logSystemReport($h, $report);
121            $h->email($to, $subject, $body);
122            $h->message = $h->lang['admin_maintenance_system_report_emailed'];
123            $h->messageType = 'green';
124            return true;
125        }
126       
127        $h->openLog('system_report', 'w');
128       
129        // convert object to text
130        $output = $this->logSystemReport($h, $report);
131        if ($output) {
132            $h->writeLog('system_report', $output);
133            $h->closeLog('system_report');
134           
135            $h->message = $h->lang['admin_maintenance_system_report_success'];
136            $h->messageType = 'green';
137            return true;
138        } else {
139            $h->message = $h->lang['admin_maintenance_system_report_failure'];
140            $h->messageType = 'red';
141            return false;
142        }
143    }
144
145    /**
146     * Get system data
147     *
148     * @param string $type 'log' or 'object'
149     * @return object
150     */
151    public function getSystemData($h)
152    {
153        // essentials:
154       
155        $report['hotaru_site_name'] = SITE_NAME;
156        $report['hotaru_baseurl'] = BASEURL;
157       
158        $report['php_version'] = phpversion();
159        $report['mysql_version'] = $h->db->get_var("SELECT VERSION() AS VE");
160        $report['hotaru_version'] = $h->version;
161        $report['php_extensions'] = get_loaded_extensions();
162       
163        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
164        $report['hotaru_version_db'] = $h->db->get_var($h->db->prepare($sql, 'hotaru_version'));
165       
166        // default permissions
167       
168        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
169        $report['hotaru_permissions'] = $h->db->get_var($h->db->prepare($sql, 'permissions'));
170       
171        // default user settings
172       
173        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
174        $report['hotaru_user_settings'] = $h->db->get_var($h->db->prepare($sql, 'user_settings'));
175       
176        // plugins: folder, enabled, version, order
177       
178        $sql = "SELECT plugin_folder, plugin_enabled, plugin_version, plugin_order FROM " . TABLE_PLUGINS . " ORDER BY plugin_order";
179        $plugins = $h->db->get_results($h->db->prepare($sql));
180        if ($plugins) {
181            foreach ($plugins as $plugin) {
182                $report['hotaru_plugins'][$plugin->plugin_folder]['enabled'] = $plugin->plugin_enabled;
183                $report['hotaru_plugins'][$plugin->plugin_folder]['version'] = $plugin->plugin_version;
184                $report['hotaru_plugins'][$plugin->plugin_folder]['order'] = $plugin->plugin_order;
185            }
186        }
187       
188        // plugin hooks: id, folder, hook name
189       
190        $sql = "SELECT phook_id, plugin_folder, plugin_hook FROM " . TABLE_PLUGINHOOKS;
191        $plugins = $h->db->get_results($h->db->prepare($sql));
192        if ($plugins) {
193            foreach ($plugins as $plugin) {
194                $report['hotaru_plugin_hooks'][$plugin->phook_id]['folder'] = $plugin->plugin_folder;
195                $report['hotaru_plugin_hooks'][$plugin->phook_id]['hook'] = $plugin->plugin_hook;
196            }
197        }
198
199        // plugin settings: folder, setting (can't use value because might include passwords)
200       
201        $sql = "SELECT plugin_folder, plugin_setting, plugin_value FROM " . TABLE_PLUGINSETTINGS;
202        $plugins = $h->db->get_results($h->db->prepare($sql));
203        if ($plugins) {
204            foreach ($plugins as $plugin) {
205                if (is_serialized($plugin->plugin_value)) { $plugin->plugin_value = unserialize($plugin->plugin_value); }
206                $report['hotaru_plugin_settings'][$plugin->plugin_folder][$plugin->plugin_setting] = $this->applyMaskToArrays($h, $plugin->plugin_value);
207            }
208        }
209       
210        // Settings: Name, value (excluding SMTP PASSWORD)
211       
212        $sql = "SELECT settings_name, settings_value FROM " . TABLE_SETTINGS;
213        $settings = $h->db->get_results($h->db->prepare($sql));
214        if ($settings) {
215            foreach ($settings as $setting) {
216                // mask sensitive data
217                switch ($setting->settings_name) {
218                    case 'SITE_EMAIL':
219                    case 'SMTP_HOST':
220                    case 'SMTP_PORT':
221                    case 'SMTP_USERNAME':
222                    case 'SMTP_PASSWORD':
223                        $setting->settings_value = preg_replace("/[a-zA-Z0-9]/", "*", $setting->settings_value);
224                        break;
225                }
226                $report['hotaru_settings'][$setting->settings_name] = $setting->settings_value;
227            }
228        }
229       
230        // Widgets: plugin, function, args
231       
232        $sql = "SELECT widget_plugin, widget_function, widget_args FROM " . TABLE_WIDGETS;
233        $widgets = $h->db->get_results($h->db->prepare($sql));
234        if ($widgets) {
235            foreach ($widgets as $widget) {
236                $report['hotaru_widgets'][$widget->widget_plugin]['function'] = $widget->widget_function;
237                $report['hotaru_widgets'][$widget->widget_plugin]['args'] = $widget->widget_args;
238            }
239        }
240       
241        // Counts for all tables
242       
243        foreach ( $h->db->get_col("SHOW TABLES",0) as $table_name )
244        {
245            $report['hotaru_table_count'][$table_name] = $h->db->get_var("SELECT COUNT(*) FROM " . $table_name);
246        }
247
248        return $report;
249    }
250
251
252    /**
253     * Recurse through arrays, applying * mask to all values, but not keys
254     *
255     * @param array $array
256     * @return array
257     */
258     public function applyMaskToArrays($h, $array)
259     {
260        //echo "<pre>"; print_r($array); echo "</pre>"; exit;
261        if (!is_array($array) && !is_object($array)) { return false; }
262       
263        foreach ($array as $key => $value) {
264            if (is_array($value) || is_object($value)) {
265                $array[$key] = $this->applyMaskToArrays($h, $value);
266            } else {
267                $array[$key] = preg_replace("/[a-zA-Z0-9]/", "*", $value);
268            }
269        }
270        return $array;
271    }
272
273   
274    /**
275     * Convert report object to text for logging to file
276     *
277     * @param object $report
278     */
279    public function logSystemReport($h, $report = NULL)
280    {
281        $output = "\n\n";
282
283        $output .= "Name: " . $report['hotaru_site_name'] . "\n";
284        $output .= "URL: " . $report['hotaru_baseurl'] . "\n";
285        $output .= "Hotaru version: " . $report['hotaru_version'] . "\n";
286        $output .= "Hotaru version in database: " . $report['hotaru_version_db'] . "\n";
287        $output .= "PHP version: " . $report['php_version'] . "\n";
288        $output .= "MySQL version: " . $report['mysql_version'] . "\n";
289        $output .= "PHP extensions: " . implode(', ', $report['php_extensions']) . "\n";
290       
291        $output .= "\n";
292       
293        $output .= "Default site permissions: \n";
294        $perms = unserialize($report['hotaru_permissions']);
295        unset($perms['options']); // don't need to display these
296        foreach ($perms as $key => $value) {
297            $output .= $key . " => (";
298            foreach ($value as $k => $v) {
299                $output .= $k . ": " . $v . ", ";
300            }
301            $output = rtrim($output, ", ");
302            $output .= ")\n";
303        }
304       
305        $output .= "\n";
306       
307        $output .= "Default user settings: \n";
308        $user_settings = unserialize($report['hotaru_user_settings']);
309        foreach ($user_settings as $key => $value) {
310            $output .= $key . " => " . $value . "\n";
311        }
312       
313        $output .= "\n";
314       
315        $output .= "Plugins: \n";
316        if (isset($report['hotaru_plugins'])) {
317            foreach ($report['hotaru_plugins'] as $key => $value) {
318                $output .= $value['order'] . ". " . $key . " v." . $value['version'] . " ";
319                if ($value['enabled']) { $output .= "[enabled] \n"; } else { $output .= "[disabled] \n"; }
320            }
321        }
322       
323        $output .= "\n";
324       
325        $output .= "Plugin Hooks: \n";
326        if (isset($report['hotaru_plugin_hooks'])) {
327            foreach ($report['hotaru_plugin_hooks'] as $key => $value) {
328                $output .= $key . ". " . $value['folder'] . " => " . $value['hook'] . " \n";
329            }
330        }
331       
332        $output .= "\n";
333
334        $output .= "Plugin Settings: \n";
335        if (isset($report['hotaru_plugin_settings'])) {
336            foreach ($report['hotaru_plugin_settings'] as $key => $value) {
337                foreach ($value as $k => $v) {
338                    if (!is_array($v)) {
339                        $output .= "\nPlugin settings for " . $key . ":\n...." . $k . " = " . $v . " \n";
340                    } else {
341                        $output .= "\nPlugin settings for " . $key . ":\n";
342                        $output = $this->outputArrays($h, $v, $output);
343                    }
344                }
345            }
346        }
347       
348        $output .= "\n";
349
350        $output .= "Hotaru Settings: \n";
351        if (isset($report['hotaru_settings'])) {
352            foreach ($report['hotaru_settings'] as $key => $value) {
353                $output .= $key . " => " . $value . " \n";
354            }
355        }
356
357        $output .= "\n";
358       
359        $output .= "Widgets: \n";
360        if (isset($report['hotaru_widgets'])) {
361            foreach ($report['hotaru_widgets'] as $key => $value) {
362                $output .= $key . " => " . $value['function'];
363                if ($value['args']) { $output .= " (args: " . $value['args'] . ")"; }
364                $output .= "\n";
365            }
366        }
367       
368        $output .= "\n";
369       
370        $output .= "Number of rows in each table: \n";
371        if (isset($report['hotaru_table_count'])) {
372            foreach ($report['hotaru_table_count'] as $key => $value) {
373                $output .= $key . " => " . $value . " \n";
374            }
375        }
376       
377        return $output;
378    }
379   
380   
381    /**
382     * Recurse through arrays, adding them to $output for display
383     *
384     * @param array $array
385     * @return array
386     */
387     public function outputArrays($h, $array = array(), $output = '')
388     {
389        if (!is_array($array) && !is_object($array)) { return $output; }
390       
391        foreach ($array as $key => $value) {
392            if (is_array($value) || is_object($array)) {
393                $output .= "..... " . $key . ":\n";
394                $output = $this->outputArrays($h, $value, $output);
395            } else {
396                $output .= "..... " . $key . ": " . $value . " \n";
397            }
398        }
399        return $output;
400    }
401}
402?>
Note: See TracBrowser for help on using the repository browser.