source: branches/1.2/libs/Debug.php @ 1371

Revision 1371, 14.3 KB checked in by nick_ramsay, 3 years ago (diff)

[Branch 1.2] More work on system report formatting.

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 1MB
66        if (file_exists($this->log[$type]) && (filesize($this->log[$type]) > 1000000)) {
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' 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        $h->openLog('system_report', 'w');
118       
119        // convert object to text
120        $output = $this->logSystemReport($h, $report);
121        if ($output) {
122            $h->writeLog('system_report', $output);
123            $h->closeLog('system_report');
124           
125            $h->message = $h->lang['admin_maintenance_system_report_success'];
126            $h->messageType = 'green';
127        } else {
128            $h->message = $h->lang['admin_maintenance_system_report_failure'];
129            $h->messageType = 'red';
130        }
131    }
132
133    /**
134     * Get system data
135     *
136     * @param string $type 'log' or 'object'
137     * @return object
138     */
139    public function getSystemData($h)
140    {
141        // essentials:
142       
143        $report['hotaru_site_name'] = SITE_NAME;
144        $report['hotaru_baseurl'] = BASEURL;
145       
146        $report['php_version'] = phpversion();
147        $report['mysql_version'] = $h->db->get_var("SELECT VERSION() AS VE");
148        $report['hotaru_version'] = $h->version;
149       
150        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
151        $report['hotaru_version_db'] = $h->db->get_var($h->db->prepare($sql, 'hotaru_version'));
152       
153        // default permissions
154       
155        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
156        $report['hotaru_permissions'] = $h->db->get_var($h->db->prepare($sql, 'permissions'));
157       
158        // default user settings
159       
160        $sql = "SELECT miscdata_value FROM " . TABLE_MISCDATA . " WHERE miscdata_key = %s";
161        $report['hotaru_user_settings'] = $h->db->get_var($h->db->prepare($sql, 'user_settings'));
162       
163        // plugins: folder, enabled, version, order
164       
165        $sql = "SELECT plugin_folder, plugin_enabled, plugin_version, plugin_order FROM " . TABLE_PLUGINS . " ORDER BY plugin_order";
166        $plugins = $h->db->get_results($h->db->prepare($sql));
167        if ($plugins) {
168            foreach ($plugins as $plugin) {
169                $report['hotaru_plugins'][$plugin->plugin_folder]['enabled'] = $plugin->plugin_enabled;
170                $report['hotaru_plugins'][$plugin->plugin_folder]['version'] = $plugin->plugin_version;
171                $report['hotaru_plugins'][$plugin->plugin_folder]['order'] = $plugin->plugin_order;
172            }
173        }
174       
175        // plugin hooks: id, folder, hook name
176       
177        $sql = "SELECT phook_id, plugin_folder, plugin_hook FROM " . TABLE_PLUGINHOOKS;
178        $plugins = $h->db->get_results($h->db->prepare($sql));
179        if ($plugins) {
180            foreach ($plugins as $plugin) {
181                $report['hotaru_plugin_hooks'][$plugin->phook_id]['folder'] = $plugin->plugin_folder;
182                $report['hotaru_plugin_hooks'][$plugin->phook_id]['hook'] = $plugin->plugin_hook;
183            }
184        }
185
186        // plugin settings: folder, setting (can't use value because might include passwords)
187       
188        $sql = "SELECT plugin_folder, plugin_setting, plugin_value FROM " . TABLE_PLUGINSETTINGS;
189        $plugins = $h->db->get_results($h->db->prepare($sql));
190        if ($plugins) {
191            foreach ($plugins as $plugin) {
192                if (is_serialized($plugin->plugin_value)) { $plugin->plugin_value = unserialize($plugin->plugin_value); }
193                $report['hotaru_plugin_settings'][$plugin->plugin_folder][$plugin->plugin_setting] = $this->applyMaskToArrays($h, $plugin->plugin_value);
194            }
195        }
196       
197        // Settings: Name, value (excluding SMTP PASSWORD)
198       
199        $sql = "SELECT settings_name, settings_value FROM " . TABLE_SETTINGS;
200        $settings = $h->db->get_results($h->db->prepare($sql));
201        if ($settings) {
202            foreach ($settings as $setting) {
203                // mask sensitive data
204                switch ($setting->settings_name) {
205                    case 'SITE_EMAIL':
206                    case 'SMTP_HOST':
207                    case 'SMTP_PORT':
208                    case 'SMTP_USERNAME':
209                    case 'SMTP_PASSWORD':
210                        $setting->settings_value = preg_replace("/[a-zA-Z0-9]/", "*", $setting->settings_value);
211                        break;
212                }
213                $report['hotaru_settings'][$setting->settings_name] = $setting->settings_value;
214            }
215        }
216       
217        // Widgets: plugin, function, args
218       
219        $sql = "SELECT widget_plugin, widget_function, widget_args FROM " . TABLE_WIDGETS;
220        $widgets = $h->db->get_results($h->db->prepare($sql));
221        if ($widgets) {
222            foreach ($widgets as $widget) {
223                $report['hotaru_widgets'][$widget->widget_plugin]['function'] = $widget->widget_function;
224                $report['hotaru_widgets'][$widget->widget_plugin]['args'] = $widget->widget_args;
225            }
226        }
227       
228        // Counts for all tables
229       
230        foreach ( $h->db->get_col("SHOW TABLES",0) as $table_name )
231        {
232            $report['hotaru_table_count'][$table_name] = $h->db->get_var("SELECT COUNT(*) FROM " . $table_name);
233        }
234
235        return $report;
236    }
237
238
239    /**
240     * Recurse through arrays, applying * mask to all values, but not keys
241     *
242     * @param array $array
243     * @return array
244     */
245     public function applyMaskToArrays($h, $array)
246     {
247        //echo "<pre>"; print_r($array); echo "</pre>"; exit;
248        if (!is_array($array) && !is_object($array)) { return false; }
249       
250        foreach ($array as $key => $value) {
251            if (is_array($value) || is_object($value)) {
252                $array[$key] = $this->applyMaskToArrays($h, $value);
253            } else {
254                $array[$key] = preg_replace("/[a-zA-Z0-9]/", "*", $value);
255            }
256        }
257        return $array;
258    }
259
260   
261    /**
262     * Convert report object to text for logging to file
263     *
264     * @param object $report
265     */
266    public function logSystemReport($h, $report = NULL)
267    {
268        $output = "\n\n";
269
270        $output .= "Name: " . $report['hotaru_site_name'] . "\n";
271        $output .= "URL: " . $report['hotaru_baseurl'] . "\n";
272        $output .= "Hotaru version: " . $report['hotaru_version'] . "\n";
273        $output .= "Hotaru version in database: " . $report['hotaru_version_db'] . "\n";
274        $output .= "PHP version: " . $report['php_version'] . "\n";
275        $output .= "MySQL version: " . $report['mysql_version'] . "\n";
276       
277        $output .= "\n";
278       
279        $output .= "Default site permissions: \n";
280        $perms = unserialize($report['hotaru_permissions']);
281        unset($perms['options']); // don't need to display these
282        foreach ($perms as $key => $value) {
283            $output .= $key . " => (";
284            foreach ($value as $k => $v) {
285                $output .= $k . ": " . $v . ", ";
286            }
287            $output = rtrim($output, ", ");
288            $output .= ")\n";
289        }
290       
291        $output .= "\n";
292       
293        $output .= "Default user settings: \n";
294        $user_settings = unserialize($report['hotaru_user_settings']);
295        foreach ($user_settings as $key => $value) {
296            $output .= $key . " => " . $value . "\n";
297        }
298       
299        $output .= "\n";
300       
301        $output .= "Plugins: \n";
302        if (isset($report['hotaru_plugins'])) {
303            foreach ($report['hotaru_plugins'] as $key => $value) {
304                $output .= $value['order'] . ". " . $key . " v." . $value['version'] . " ";
305                if ($value['enabled']) { $output .= "[enabled] \n"; } else { $output .= "[disabled] \n"; }
306            }
307        }
308       
309        $output .= "\n";
310       
311        $output .= "Plugin Hooks: \n";
312        if (isset($report['hotaru_plugin_hooks'])) {
313            foreach ($report['hotaru_plugin_hooks'] as $key => $value) {
314                $output .= $key . ". " . $value['folder'] . " => " . $value['hook'] . " \n";
315            }
316        }
317       
318        $output .= "\n";
319
320        $output .= "Plugin Settings: \n";
321        if (isset($report['hotaru_plugin_settings'])) {
322            foreach ($report['hotaru_plugin_settings'] as $key => $value) {
323                foreach ($value as $k => $v) {
324                    if (!is_array($v)) {
325                        $output .= "\nPlugin settings for " . $key . ":\n...." . $k . " = " . $v . " \n";
326                    } else {
327                        $output .= "\nPlugin settings for " . $key . ":\n";
328                        $output = $this->outputArrays($h, $v, $output);
329                    }
330                }
331            }
332        }
333       
334        $output .= "\n";
335
336        $output .= "Hotaru Settings: \n";
337        if (isset($report['hotaru_settings'])) {
338            foreach ($report['hotaru_settings'] as $key => $value) {
339                $output .= $key . " => " . $value . " \n";
340            }
341        }
342
343        $output .= "\n";
344       
345        $output .= "Widgets: \n";
346        if (isset($report['hotaru_widgets'])) {
347            foreach ($report['hotaru_widgets'] as $key => $value) {
348                $output .= $key . " => " . $value['function'];
349                if ($value['args']) { $output .= " (args: " . $value['args'] . ")"; }
350                $output .= "\n";
351            }
352        }
353       
354        $output .= "\n";
355       
356        $output .= "Number of rows in each table: \n";
357        if (isset($report['hotaru_table_count'])) {
358            foreach ($report['hotaru_table_count'] as $key => $value) {
359                $output .= $key . " => " . $value . " \n";
360            }
361        }
362       
363        return $output;
364    }
365   
366   
367    /**
368     * Recurse through arrays, adding them to $output for display
369     *
370     * @param array $array
371     * @return array
372     */
373     public function outputArrays($h, $array = array(), $output = '')
374     {
375        if (!is_array($array) && !is_object($array)) { return $output; }
376       
377        foreach ($array as $key => $value) {
378            if (is_array($value) || is_object($array)) {
379                $output .= "..... " . $key . ":\n";
380                $output = $this->outputArrays($h, $value, $output);
381            } else {
382                $output .= "..... " . $key . ": " . $value . " \n";
383            }
384        }
385        return $output;
386    }
387}
388?>
Note: See TracBrowser for help on using the repository browser.