Example #1
0
    public function displayDebug()
    {
        global $start_time;
        $this->display();
        $this->_memory['display'] = memory_get_usage();
        $this->_time['display'] = microtime(true);
        if (!$this->ini_get_display_errors()) {
            return;
        }
        $hr = '<hr style="color:#F5F5F5;margin:2px" />';
        $totalSize = 0;
        foreach (get_included_files() as $file) {
            $totalSize += filesize($file);
        }
        $totalQueryTime = 0;
        foreach (Db::getInstance()->queries as $data) {
            $totalQueryTime += $data['time'];
        }
        $hooktime = Hook::getHookTime();
        arsort($hooktime);
        $totalHookTime = 0;
        foreach ($hooktime as $time) {
            $totalHookTime += $time;
        }
        $hookMemoryUsage = Hook::getHookMemoryUsage();
        arsort($hookMemoryUsage);
        $totalHookMemoryUsage = 0;
        foreach ($hookMemoryUsage as $usage) {
            $totalHookMemoryUsage += $usage;
        }
        $globalSize = array();
        $totalGlobalSize = 0;
        foreach ($GLOBALS as $key => $value) {
            if ($key != 'GLOBALS') {
                $totalGlobalSize += $size = $this->sizeofvar($value);
                if ($size > 1024) {
                    $globalSize[$key] = round($size / 1024, 1);
                }
            }
        }
        arsort($globalSize);
        $cache = Cache::retrieveAll();
        $totalCacheSize = $this->sizeofvar($cache);
        echo '<br /><br />
		<div class="rte" style="text-align:left;padding:8px;float:left">
			<b>Load time</b>: ' . $this->displayLoadTimeColor($this->_time['display'] - $start_time, true) . '';
        if (self::$_footer) {
            echo '<ul>';
        }
        $last_time = $start_time;
        foreach ($this->_time as $k => $time) {
            echo '<li>' . $k . ': ' . $this->displayLoadTimeColor($time - $last_time) . '</li>';
            $last_time = $time;
        }
        echo '</ul>';
        echo '</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Hook processing</b>: ' . $this->displayLoadTimeColor($totalHookTime) . ' / ' . $this->displayMemoryColor($totalHookMemoryUsage) . '
			<ul>';
        foreach ($hooktime as $hook => $time) {
            echo '<li>' . $hook . ': ' . $this->displayLoadTimeColor($time) . ' / ' . $this->displayMemoryColor($hookMemoryUsage[$hook]) . '</li>';
        }
        echo '</ul>
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Memory peak usage</b>: ' . $this->displayMemoryColor(memory_get_peak_usage());
        if (self::$_footer) {
            echo '<ul>';
            $last_memory = 0;
            foreach ($this->_memory as $k => $memory) {
                echo '<li>' . $k . ': ' . $this->displayMemoryColor($memory - $last_memory) . '</li>';
                $last_memory = $memory;
            }
            echo '</ul>';
        }
        echo '<br /><br />
 	 	<b>Total cache size (in Cache class)</b>: ' . $this->displayMemoryColor($totalCacheSize) . '
 	 	</div>';
        echo '</div>';
        echo '
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>DB type</b>: ' . get_class(Db::getInstance()) . '
			<br /><b>SQL Queries</b>: ' . $this->displaySQLQueries(count(Db::getInstance()->queries)) . '
			<br /><b>Time spent querying</b>: ' . $this->displayLoadTimeColor($totalQueryTime) . '
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Included files</b>: ' . sizeof(get_included_files()) . '<br />
			<b>Size of included files</b>: ' . $this->displayMemoryColor($totalSize) . '
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Globals (&gt; 1 Ko only): ' . round($totalGlobalSize / 1024) . ' Ko</b>
			<ul>';
        foreach ($globalSize as $global => $size) {
            echo '<li>' . $global . ' &asymp; ' . $size . ' Ko</li>';
        }
        echo '</ul>
		</div>';
        echo '
		<div class="rte" style="text-align:left;padding:8px;clear:both;margin-top:20px">
			<ul>
				<li><a href="#stopwatch">Go to Stopwatch</a></li>
				<li><a href="#doubles">Go to Doubles</a></li>
				<li><a href="#tables">Go to Tables</a></li>
				' . (isset(ObjectModel::$debug_list) ? '<li><a href="#objectModels">Go to ObjectModels</a></li>' : '') . '
			</ul>
		</div>
		<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="stopwatch">Stopwatch (with SQL_NO_CACHE) (total = ' . count(Db::getInstance()->queries) . ')</a></h3>';
        $queries = Db::getInstance()->queries;
        uasort($queries, 'prestashop_querytime_sort');
        foreach ($queries as $data) {
            echo $hr . '<b ' . $this->getTimeColor($data['time'] * 1000) . '>' . round($data['time'] * 1000, 3) . ' ms</b> ' . $data['query'] . '<br />in ' . $data['file'] . ':' . $data['line'] . '<br />';
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                $explain = Db::getInstance()->executeS('explain ' . $data['query']);
                if (stristr($explain[0]['Extra'], 'filesort')) {
                    echo '<b ' . $this->getTimeColor($data['time'] * 1000) . '>USING FILESORT</b> - ';
                }
                $browsed_rows = 1;
                foreach ($explain as $row) {
                    $browsed_rows *= $row['rows'];
                }
                echo $this->displayRowsBrowsed($browsed_rows);
                if (stristr($data['query'], 'group by') && !preg_match('/(avg|count|min|max|group_concat|sum)\\s*\\(/i', $data['query'])) {
                    echo '<br /><b>Useless GROUP BY need to be removed</b>';
                }
            }
        }
        echo '</div>
		<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="doubles">Doubles (IDs replaced by "XX") (total = ' . count(Db::getInstance()->uniqQueries) . ')</a></h3>';
        $queries = Db::getInstance()->uniqQueries;
        arsort($queries);
        foreach ($queries as $q => $nb) {
            echo $hr . '<b ' . $this->getQueryColor($nb) . '>' . $nb . '</b> ' . $q;
        }
        echo '</div>
		<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="tables">Tables stress</a></h3>';
        $tables = Db::getInstance()->tables;
        arsort($tables);
        foreach ($tables as $table => $nb) {
            echo $hr . '<b ' . $this->getTableColor($nb) . '>' . $nb . '</b> ' . $table;
        }
        echo '</div>';
        if (isset(ObjectModel::$debug_list)) {
            echo '<div class="rte" style="text-align:left;padding:8px">
			<h3><a name="objectModels">ObjectModel instances</a></h3>';
            $list = ObjectModel::$debug_list;
            uasort($list, create_function('$a,$b', 'return (count($a) < count($b)) ? 1 : -1;'));
            $i = 0;
            foreach ($list as $class => $info) {
                echo $hr . '<b ' . $this->getObjectModelColor(count($info)) . '>' . count($info) . '</b> ';
                echo '<a href="#" onclick="$(\'#object_model_' . $i . '\').css(\'display\', $(\'#object_model_' . $i . '\').css(\'display\') == \'none\' ? \'block\' : \'none\'); return false">' . $class . '</a>';
                echo '<div id="object_model_' . $i . '" style="display: none">';
                foreach ($info as $trace) {
                    echo ltrim(str_replace(array(_PS_ROOT_DIR_, '\\'), array('', '/'), $trace['file']), '/') . ' [' . $trace['line'] . ']<br />';
                }
                echo '</div>';
                $i++;
            }
            echo '</div>';
        }
        // List of included files
        echo '<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="includedFiles">Included files</a></h3>';
        $i = 1;
        foreach (get_included_files() as $file) {
            $file = ltrim(str_replace('\\', '/', str_replace(_PS_ROOT_DIR_, '', $file)), '/');
            $file = '<b style="color: red">' . dirname($file) . '/</b><b style="color: blue">' . basename($file) . '</b>';
            echo $i . ' ' . $file . '<br />';
            $i++;
        }
        echo '</div>';
    }
Example #2
0
    public function displayDebug()
    {
        global $start_time;
        $this->display();
        $this->_memory['display'] = memory_get_usage();
        $this->_mempeak['display'] = memory_get_peak_usage();
        $this->_time['display'] = microtime(true);
        if (!$this->ini_get_display_errors()) {
            return;
        }
        $memory_peak_usage = memory_get_peak_usage();
        $hr = '<hr style="color:#F5F5F5;margin:2px" />';
        $totalSize = 0;
        foreach (get_included_files() as $file) {
            $totalSize += filesize($file);
        }
        $totalQueryTime = 0;
        foreach (Db::getInstance()->queries as $data) {
            $totalQueryTime += $data['time'];
        }
        $executedModules = Hook::getExecutedModules();
        $hooktime = Hook::getHookTime();
        arsort($hooktime);
        $totalHookTime = 0;
        foreach ($hooktime as $time) {
            $totalHookTime += $time;
        }
        $hookMemoryUsage = Hook::getHookMemoryUsage();
        arsort($hookMemoryUsage);
        $totalHookMemoryUsage = 0;
        foreach ($hookMemoryUsage as $usage) {
            $totalHookMemoryUsage += $usage;
        }
        $globalSize = array();
        $totalGlobalSize = 0;
        foreach ($GLOBALS as $key => $value) {
            if ($key != 'GLOBALS') {
                $totalGlobalSize += $size = $this->sizeofvar($value);
                if ($size > 1024) {
                    $globalSize[$key] = round($size / 1024, 1);
                }
            }
        }
        arsort($globalSize);
        $cache = Cache::retrieveAll();
        $totalCacheSize = $this->sizeofvar($cache);
        echo '
		<div style="clear:both;height:20px;line-height:20px">&nbsp;</div>
		<div style="margin:50px;background-color:#FFFFFF">
		<div class="rte" style="text-align:left;padding:8px;float:left">
			<b>Load time</b>: ' . $this->displayLoadTimeColor($this->_time['display'] - $start_time, true) . '';
        if (self::$_footer) {
            echo '<ul>';
        }
        $last_time = $start_time;
        foreach ($this->_time as $k => $time) {
            echo '<li>' . $k . ': ' . $this->displayLoadTimeColor($time - $last_time) . '</li>';
            $last_time = $time;
        }
        echo '</ul>';
        echo '</div>
		
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Hook processing</b>: ' . $this->displayLoadTimeColor($totalHookTime) . ' / ' . $this->displayMemoryColor($totalHookMemoryUsage) . '<br />
			' . (int) count($executedModules) . ' methods called in ' . (int) count(array_unique($executedModules)) . ' modules
			<ul>';
        foreach ($hooktime as $hook => $time) {
            echo '<li>' . $hook . ': ' . $this->displayLoadTimeColor($time) . ' / ' . $this->displayMemoryColor($hookMemoryUsage[$hook]) . '</li>';
        }
        echo '</ul>
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Memory peak usage</b>: ' . $this->displayPeakMemoryColor($memory_peak_usage);
        if (self::$_footer) {
            echo '<ul>';
            $last_memory = 0;
            foreach ($this->_memory as $k => $memory) {
                echo '<li>' . $k . ': ' . $this->displayMemoryColor($memory - $last_memory) . ' (' . $this->displayPeakMemoryColor($this->_mempeak[$k]) . ')</li>';
                $last_memory = $memory;
            }
            echo '</ul>';
        }
        echo '<br /><br />
 	 	<b>Total cache size (in Cache class)</b>: ' . $this->displayMemoryColor($totalCacheSize) . '
 	 	</div>';
        echo '
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>DB type</b>: ' . get_class(Db::getInstance()) . '
			<br /><b>SQL Queries</b>: ' . $this->displaySQLQueries(count(Db::getInstance()->queries)) . '
			<br /><b>Time spent querying</b>: ' . $this->displayLoadTimeColor($totalQueryTime) . '
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Included files</b>: ' . sizeof(get_included_files()) . '<br />
			<b>Size of included files</b>: ' . $this->displayMemoryColor($totalSize) . '
		</div>
		<div class="rte" style="text-align:left;padding:8px;float:left;margin-left:20px">
			<b>Globals (&gt; 1 Ko only): ' . round($totalGlobalSize / 1024) . ' Ko</b>
			<ul>';
        foreach ($globalSize as $global => $size) {
            echo '<li>' . $global . ' &asymp; ' . $size . ' Ko</li>';
        }
        echo '</ul>
		</div>';
        $array_queries = array();
        $queries = Db::getInstance()->queries;
        uasort($queries, 'prestashop_querytime_sort');
        foreach ($queries as $data) {
            $query_row = array('time' => $data['time'], 'query' => $data['query'], 'location' => $data['stack'][0]['file'] . ':' . $data['stack'][0]['line'], 'filesort' => false, 'rows' => 1, 'group_by' => false, 'stack' => $data['stack']);
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                $explain = Db::getInstance()->executeS('explain ' . $data['query']);
                if (stristr($explain[0]['Extra'], 'filesort')) {
                    $query_row['filesort'] = true;
                }
                foreach ($explain as $row) {
                    $query_row['rows'] *= $row['rows'];
                }
                if (stristr($data['query'], 'group by') && !preg_match('/(avg|count|min|max|group_concat|sum)\\s*\\(/i', $data['query'])) {
                    $query_row['group_by'] = true;
                }
            }
            $array_queries[] = $query_row;
        }
        echo '
		<div class="rte" style="text-align:left;padding:8px;clear:both;margin-top:20px">
			<ul>
				<li><a href="#stopwatch">Go to Stopwatch</a></li>
				<li><a href="#doubles">Go to Doubles</a></li>
				<li><a href="#tables">Go to Tables</a></li>
				' . (isset(ObjectModel::$debug_list) ? '<li><a href="#objectModels">Go to ObjectModels</a></li>' : '') . '
				<li><a onclick="$(\'#queries_table\').toggle();" style="cursor:pointer">Display queries table</a></li>
				<li><a href="#includedFiles">Go to files</a></li>
			</ul>
		</div>
		<div id="queries_table" style="display:none;margin:4px">
			<table class="table std">
				<tr><th>Time (ms)</th><th>Rows</th><th>Query</th><th>Location</th><th>Filesort</th><th>Group By</th></tr>';
        foreach ($array_queries as &$data) {
            $data['location'] = str_replace('\\', '/', substr($data['location'], strlen(_PS_ROOT_DIR_)));
            $data['query'] = str_replace('SQL_NO_CACHE ', '', $data['query']);
            echo '<tr><td>' . round(1000 * $data['time'], 3) . '</td><td>' . $data['rows'] . '</td><td>' . $data['query'] . '</td><td>' . $data['location'] . '</td><td>' . ($data['filesort'] ? 'Yes' : '') . '</td><td>' . ($data['group_by'] ? 'Yes' : '') . '</td></tr>';
        }
        echo '
			</table>
		</div>
		<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="stopwatch">Stopwatch (with SQL_NO_CACHE) (total = ' . count(Db::getInstance()->queries) . ')</a></h3>';
        $i = 1;
        foreach ($array_queries as $data) {
            $echo_stack = '';
            array_shift($data['stack']);
            foreach ($data['stack'] as $call) {
                $echo_stack .= 'from ' . str_replace('\\', '/', substr($call['file'], strlen(_PS_ROOT_DIR_))) . ':' . $call['line'] . '<br />';
            }
            echo $hr . '<div onclick="$(\'#qbt' . $i . '\').toggle();"><b ' . $this->getTimeColor($data['time'] * 1000) . '>' . round($data['time'] * 1000, 3) . ' ms</b>
			' . htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false) . '<br />
			in ' . $data['location'] . '<br />
			<div id="qbt' . $i++ . '" style="display:none">' . $echo_stack . '</div>';
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                if ($data['filesort']) {
                    echo '<b ' . $this->getTimeColor($data['time'] * 1000) . '>USING FILESORT</b> - ';
                }
                echo $this->displayRowsBrowsed($data['rows']);
                if ($data['group_by']) {
                    echo '<br /><b>Useless GROUP BY need to be removed</b>';
                }
            }
            echo '</div>';
        }
        $queries = Db::getInstance()->uniqQueries;
        arsort($queries);
        $count = count(Db::getInstance()->uniqQueries);
        foreach ($queries as $q => &$nb) {
            if ($nb == 1) {
                $count--;
            }
        }
        if ($count) {
            echo '</div>
			<div class="rte" style="text-align:left;padding:8px">
			<h3><a name="doubles">Doubles (IDs replaced by "XX") (total = ' . $count . ')</a></h3>';
        }
        foreach ($queries as $q => $nb) {
            if ($nb > 1) {
                echo $hr . '<b ' . $this->getQueryColor($nb) . '>' . $nb . '</b> ' . $q;
            }
        }
        echo '</div>
		<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="tables">Tables stress</a></h3>';
        $tables = Db::getInstance()->tables;
        arsort($tables);
        foreach ($tables as $table => $nb) {
            echo $hr . '<b ' . $this->getTableColor($nb) . '>' . $nb . '</b> ' . $table;
        }
        echo '</div>';
        if (isset(ObjectModel::$debug_list)) {
            echo '<div class="rte" style="text-align:left;padding:8px">
			<h3><a name="objectModels">ObjectModel instances</a></h3>';
            $list = ObjectModel::$debug_list;
            uasort($list, create_function('$a,$b', 'return (count($a) < count($b)) ? 1 : -1;'));
            $i = 0;
            foreach ($list as $class => $info) {
                echo $hr . '<b ' . $this->getObjectModelColor(count($info)) . '>' . count($info) . '</b> ';
                echo '<a href="#" onclick="$(\'#object_model_' . $i . '\').css(\'display\', $(\'#object_model_' . $i . '\').css(\'display\') == \'none\' ? \'block\' : \'none\'); return false">' . $class . '</a>';
                echo '<div id="object_model_' . $i . '" style="display: none">';
                foreach ($info as $trace) {
                    echo ltrim(str_replace(array(_PS_ROOT_DIR_, '\\'), array('', '/'), $trace['file']), '/') . ' [' . $trace['line'] . ']<br />';
                }
                echo '</div>';
                $i++;
            }
            echo '</div>';
        }
        // List of included files
        echo '<div class="rte" style="text-align:left;padding:8px">
		<h3><a name="includedFiles">Included files</a></h3>';
        $i = 1;
        foreach (get_included_files() as $file) {
            $file = ltrim(str_replace('\\', '/', str_replace(_PS_ROOT_DIR_, '', $file)), '/');
            $file = '<b style="color: red">' . dirname($file) . '/</b><b style="color: blue">' . basename($file) . '</b>';
            echo $i . ' ' . $file . '<br />';
            $i++;
        }
        echo '</div>
		<div style="clear:both;height:20px;line-height:20px">&nbsp;</div>
		</div>';
    }
Example #3
0
    public function displayDebug()
    {
        global $start_time;
        $this->display();
        $this->_memory['display'] = memory_get_usage();
        $this->_mempeak['display'] = memory_get_peak_usage();
        $this->_time['display'] = microtime(true);
        $memory_peak_usage = memory_get_peak_usage();
        $hr = '<hr>';
        $totalSize = 0;
        foreach (get_included_files() as $file) {
            $totalSize += filesize($file);
        }
        $totalQueryTime = 0;
        foreach (Db::getInstance()->queries as $data) {
            $totalQueryTime += $data['time'];
        }
        $executedModules = Hook::getExecutedModules();
        $hooktime = Hook::getHookTime();
        arsort($hooktime);
        $totalHookTime = 0;
        foreach ($hooktime as $time) {
            $totalHookTime += $time;
        }
        $hookMemoryUsage = Hook::getHookMemoryUsage();
        arsort($hookMemoryUsage);
        $totalHookMemoryUsage = 0;
        foreach ($hookMemoryUsage as $usage) {
            $totalHookMemoryUsage += $usage;
        }
        $globalSize = array();
        $totalGlobalSize = 0;
        foreach ($GLOBALS as $key => $value) {
            if ($key != 'GLOBALS') {
                $totalGlobalSize += $size = $this->sizeofvar($value);
                if ($size > 1024) {
                    $globalSize[$key] = round($size / 1024);
                }
            }
        }
        arsort($globalSize);
        $cache = Cache::retrieveAll();
        $totalCacheSize = $this->sizeofvar($cache);
        echo '
		<style>
			#ps_profiling{
				padding: 20px;
			}
			.ps_back-office.page-sidebar #ps_profiling{
				margin-left: 210px;
			}
			.ps_back-office.page-sidebar-closed #ps_profiling{
				margin-left: 50px;
			}
			.ps_back-office #ps_profiling{
				clear: both;
				padding: 10px;
				margin-bottom: 50px;
			}
			#ps_profiling *{
				box-sizing:border-box;
				-moz-box-sizing:border-box;
				color: #888;
			}
			#ps_profiling .ps_profiling_title{
				font-size: 20px;
				display: inline-block;
				padding-bottom: 15px;
			}
			#ps_profiling ul{
				margin: 0;
				padding: 0;
				list-style: none;
			}
			#ps_profiling hr{
				margin: 5px 0;
				padding: 0;
				border: none;
				border-bottom: solid 1px #ccc;
			}
			#ps_profiling td pre{
				padding: 6px;
				margin-right: 10px;
				border-radius: 5px;
				overflow: auto;
				display: block;
				color: #777;
				font-size: 12px;
				line-height: 1.42857;
				word-break: break-all;
				word-wrap: break-word;
				background-color: whitesmoke;
				border: 1px solid #cccccc;
				max-width: 960px;
			}
			#ps_profiling td .qbt{
				max-height: 140px;
				overflow: auto;
			}
			#ps_profiling table{
				width: 100%;
				margin-bottom: 10px;
				background-color: white;
			}
			#ps_profiling table th{
				font-weight: normal;
				border-bottom: 1px solid #999;
				color: #888;
				padding: 5px 0;
			}
			#ps_profiling table td{
				border-bottom: 1px solid #eee;
				padding: 6px;
			}

			.sortable thead th{
				cursor:pointer;
			}
			#ps_profiling table .text-right{
				text-align: right
			}
			#ps_profiling table .text-left{
				text-align: left
			}
			#ps_profiling table .text-center{
				text-align: center
			}
			#ps_profiling .ps_profiling_row{
				clear: both;
				margin-bottom: 60px;
			}
			#ps_profiling .ps_profiling_col4{
				float: left;
				padding: 0 10px;
				border-right: 1px solid #ccc;
				width: 25%;
			}
			@media (max-width: 1200px) {
				#ps_profiling .ps_profiling_col4 {
					width: 50%;
				}
			}
			@media (max-width: 600px) {
				#ps_profiling .ps_profiling_col4 {
					width: 100%;
				}
			}
			#ps_profiling .ps_profiling_col4:last-child{
				border-right: none;
			}
			#ps_profiling .ps_profiling_infobox{
				background-color: white;
				padding: 5px 10px;
				border: 1px solid #ccc;
				margin-bottom: 10px;
			}
			#ps_profiling .text-muted{
				color: #bbb;
			}
		</style>';
        echo '<div id="ps_profiling">';
        if (!empty($this->redirect_after)) {
            echo '<div class="ps_profiling_row"><div class="ps_profiling_col12"><h2>Caught redirection to <a href="' . htmlspecialchars($this->redirect_after) . '">' . htmlspecialchars($this->redirect_after) . '</a></h2></div></div>';
        }
        echo '
		<div class="ps_profiling_row">
		<div class="ps_profiling_col4">
			<div class="ps_profiling_infobox"><b>Load time</b>: ' . $this->displayLoadTimeColor($this->_time['display'] - $start_time, true) . '</div>';
        if (self::$_footer) {
            echo '<table>';
            echo '<thead><tr><th class="text-left">Execution</th><th class="text-right">Load time (ms)</th></tr><thead><tbody>';
            $last_time = $start_time;
            foreach ($this->_time as $k => $time) {
                echo '<tr><td>' . $k . '</td><td class="text-right">' . $this->displayLoadTimeColor($time - $last_time) . '</td></tr>';
                $last_time = $time;
            }
            echo '</tbody></table>';
        }
        echo '</div>
		<div class="ps_profiling_col4">
			<div class="ps_profiling_infobox"><b>Hook processing</b>: ' . $this->displayLoadTimeColor($totalHookTime) . ' ms / ' . $this->displayMemoryColor($totalHookMemoryUsage) . ' Mb<br>
			' . (int) count($executedModules) . ' methods called in ' . (int) count(array_unique($executedModules)) . ' modules</div>';
        echo '<table>';
        echo '<thead><tr><th class="text-left">Hook</th><th class="text-right">Processing</th></tr><thead><tbody>';
        foreach ($hooktime as $hook => $time) {
            echo '<tr><td>' . $hook . '</td><td class="text-right">' . $this->displayMemoryColor($hookMemoryUsage[$hook]) . ' Mb in ' . $this->displayLoadTimeColor($time) . ' ms</td></tr>';
        }
        echo '</table>
		</div>

		<div class="ps_profiling_col4">
			<div class="ps_profiling_infobox"><b>Memory peak usage</b>: ' . $this->displayPeakMemoryColor($memory_peak_usage) . ' Mb</div>';
        if (self::$_footer) {
            echo '<table>';
            echo '<thead><tr><th class="text-left">Execution</th><th class="text-right">Memory (Mb)</th><th class="text-right">Total (Mb)</th></tr><thead><tbody>';
            $last_memory = 0;
            foreach ($this->_memory as $k => $memory) {
                echo '<tr><td>' . $k . '</td><td class="text-right">' . $this->displayMemoryColor($memory - $last_memory) . '</td><td class="text-right">' . $this->displayPeakMemoryColor($this->_mempeak[$k]) . '</td></tr>';
                $last_memory = $memory;
            }
            echo '<tbody></table>';
        }
        echo '
 	 	</div>';
        $compile = array(0 => 'green">never recompile', 1 => 'orange">auto', 2 => 'red">force compile');
        echo '
		<div class="ps_profiling_col4">
			<div class="ps_profiling_infobox"><b>Total cache size in Cache class</b>: ' . $this->displayMemoryColor($totalCacheSize) . ' Mb</div>
			<div class="ps_profiling_infobox"><b>Smarty cache</b>: <span style="color:' . (Configuration::get('PS_SMARTY_CACHE') ? 'green">enabled' : 'red">disabled') . '</span></div>
			<div class="ps_profiling_infobox"><b>Smarty compilation</b>: <span style="color:' . $compile[Configuration::get('PS_SMARTY_FORCE_COMPILE')] . '</span></div>
			<div class="ps_profiling_infobox"><b>SQL Queries</b>: ' . $this->displaySQLQueries(count(Db::getInstance()->queries)) . ' in ' . $this->displayLoadTimeColor($totalQueryTime) . ' ms</div>
			<div class="ps_profiling_infobox"><b>Included files</b>: ' . sizeof(get_included_files()) . ' (' . $this->displayMemoryColor($totalSize) . ' Mb)</div>
			<div class="ps_profiling_infobox"><b>Global vars</b> : ' . $this->displayMemoryColor($totalGlobalSize) . ' Mb
				<ul>';
        foreach ($globalSize as $global => $size) {
            echo '<li>$' . $global . ' &asymp; ' . $size . 'k</li>';
        }
        echo '</ul>
			</div>
		</div>';
        $array_queries = array();
        $queries = Db::getInstance()->queries;
        uasort($queries, 'prestashop_querytime_sort');
        foreach ($queries as $data) {
            $query_row = array('time' => $data['time'], 'query' => $data['query'], 'location' => $data['stack'][0]['file'] . ':' . $data['stack'][0]['line'], 'filesort' => false, 'rows' => 1, 'group_by' => false, 'stack' => $data['stack']);
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                $explain = Db::getInstance()->executeS('explain ' . $data['query']);
                if (stristr($explain[0]['Extra'], 'filesort')) {
                    $query_row['filesort'] = true;
                }
                foreach ($explain as $row) {
                    $query_row['rows'] *= $row['rows'];
                }
                if (stristr($data['query'], 'group by') && !preg_match('/(avg|count|min|max|group_concat|sum)\\s*\\(/i', $data['query'])) {
                    $query_row['group_by'] = true;
                }
            }
            $array_queries[] = $query_row;
        }
        echo '</div>';
        echo '
		<div class="ps_profiling_row">
			<ul>
				<li><a href="#stopwatch">Stopwatch</a></li>
				<li><a href="#doubles">Doubles</a></li>
				<li><a href="#tables">Tables stress</a></li>
				' . (isset(ObjectModel::$debug_list) ? '<li><a href="#objectModels">ObjectModel instances</a></li>' : '') . '
				<li><a href="#includedFiles">Files included</a></li>
			</ul>
		</div>

		<div class="ps_profiling_row">
		<span class="ps_profiling_title"><a name="stopwatch">Stopwatch (with SQL_NO_CACHE) (total = ' . count(Db::getInstance()->queries) . ')</a></span>';
        $i = 1;
        echo '
		<script type="text/javascript" src="https://raw.githubusercontent.com/drvic10k/bootstrap-sortable/master/Scripts/bootstrap-sortable.js"></script>
		<table class="table table-striped table-condensed sortable">
			<thead>
				<tr>
					<th class="text-left col-lg-6">Query</th>
					<th class="text-left col-lg-1">Time (ms)</th>
					<th class="text-left col-lg-1">Rows</th>
					<th class="text-left col-lg-1">Filesort</th>
					<th class="text-left col-lg-1">Group By</th>
					<th class="text-left col-lg-2">Location</th>
				</tr>
			<thead>
			<tbody>';
        foreach ($array_queries as $data) {
            $echo_stack = '';
            array_shift($data['stack']);
            foreach ($data['stack'] as $call) {
                $echo_stack .= 'from ' . str_replace('\\', '/', substr($call['file'], strlen(_PS_ROOT_DIR_))) . ':' . $call['line'] . '<br />';
            }
            echo '
			<tr>
				<td><pre>' . preg_replace("/(^[\\s]*)/m", "", htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false)) . '</pre></td>
				<td><span ' . $this->getTimeColor($data['time'] * 1000) . '>' . (round($data['time'] * 1000, 1) < 0.1 ? '< 1' : round($data['time'] * 1000, 1)) . '</span></td>
				<td>' . $data['rows'] . '</td>
				<td>' . ($data['filesort'] ? '<span style="color:red">Yes</span>' : '') . '</td>
				<td>' . ($data['group_by'] ? '<span style="color:red">Yes</span>' : '') . '</td>
				<td>in ' . $data['location'] . '<br /><div class="qbt" id="qbt' . $i++ . '">' . $echo_stack . '</div></td>
			</tr>';
        }
        echo '</table>';
        $queries = Db::getInstance()->uniqQueries;
        arsort($queries);
        $count = count(Db::getInstance()->uniqQueries);
        foreach ($queries as $q => &$nb) {
            if ($nb == 1) {
                $count--;
            }
        }
        if ($count) {
            echo '</div>
			<div class="ps_profiling_row">
			<span class="ps_profiling_title"><a name="doubles">Doubles (IDs replaced by "XX") (total = ' . $count . ')</a></span>
			<table>';
        }
        foreach ($queries as $q => $nb) {
            if ($nb > 1) {
                echo '<tr><td><span ' . $this->getQueryColor($nb) . '>' . $nb . '</span> ' . $q . '</td></tr>';
            }
        }
        echo '</table></div>

		<div class="ps_profiling_row">
		<span class="ps_profiling_title"><a name="tables">Tables stress</a></span>
		<table>';
        $tables = Db::getInstance()->tables;
        arsort($tables);
        foreach ($tables as $table => $nb) {
            echo '<tr><td><span ' . $this->getTableColor($nb) . '>' . $nb . '</span> ' . $table . '</td></tr>';
        }
        echo '</table></div>';
        if (isset(ObjectModel::$debug_list)) {
            echo '<div class="ps_profiling_row">
			<span class="ps_profiling_title"><a name="objectModels">ObjectModel instances</a></span>';
            $list = ObjectModel::$debug_list;
            uasort($list, create_function('$a,$b', 'return (count($a) < count($b)) ? 1 : -1;'));
            $i = 0;
            echo '<table><thead><tr><th class="text-left">Name</th><th class="text-left">Instance</th><th class="text-left">Source</th></tr></thead><tbody>';
            foreach ($list as $class => $info) {
                echo '<tr><td>' . $class . '</td>';
                echo '<td><span ' . $this->getObjectModelColor(count($info)) . '>' . count($info) . '</span></td>';
                echo '<td><div id="object_model_' . $i . '">';
                foreach ($info as $trace) {
                    echo ltrim(str_replace(array(_PS_ROOT_DIR_, '\\'), array('', '/'), $trace['file']), '/') . ' [' . $trace['line'] . ']<br />';
                }
                echo '</div></td></tr>';
                $i++;
            }
            echo '</tbody></table></div>';
        }
        // List of included files
        echo '<div class="ps_profiling_row">
		<span class="ps_profiling_title"><a name="includedFiles">Included files</a></span>
		<table>';
        $i = 1;
        echo '<thead><tr><th class="text-left">#</th><th class="text-left">Filename</th></tr></thead><tbody>';
        foreach (get_included_files() as $file) {
            $file = ltrim(str_replace('\\', '/', str_replace(_PS_ROOT_DIR_, '', $file)), '/');
            $file = '<span class="text-muted">' . dirname($file) . '/</span><span>' . basename($file) . '</span>';
            echo '<tr><td>' . $i . '</td><td>' . $file . '</td></tr>';
            $i++;
        }
        echo '</tbody></table></div></div>';
    }
Example #4
0
    public function displayDebug()
    {
        global $start_time;
        $this->display();
        $this->_memory['display'] = memory_get_usage();
        $this->_mempeak['display'] = memory_get_peak_usage();
        $this->_time['display'] = microtime(true);
        if (!$this->ini_get_display_errors()) {
            return;
        }
        $memory_peak_usage = memory_get_peak_usage();
        $hr = '<hr style="color:#F5F5F5;margin:2px" />';
        $totalSize = 0;
        foreach (get_included_files() as $file) {
            $totalSize += filesize($file);
        }
        $totalQueryTime = 0;
        foreach (Db::getInstance()->queries as $data) {
            $totalQueryTime += $data['time'];
        }
        $hooktime = Hook::getHookTime();
        arsort($hooktime);
        $totalHookTime = 0;
        foreach ($hooktime as $time) {
            $totalHookTime += $time;
        }
        $hookMemoryUsage = Hook::getHookMemoryUsage();
        arsort($hookMemoryUsage);
        $totalHookMemoryUsage = 0;
        foreach ($hookMemoryUsage as $usage) {
            $totalHookMemoryUsage += $usage;
        }
        $globalSize = array();
        $totalGlobalSize = 0;
        foreach ($GLOBALS as $key => $value) {
            if ($key != 'GLOBALS') {
                $totalGlobalSize += $size = $this->sizeofvar($value);
                if ($size > 1024) {
                    $globalSize[$key] = round($size / 1024, 1);
                }
            }
        }
        arsort($globalSize);
        $cache = Cache::retrieveAll();
        $totalCacheSize = $this->sizeofvar($cache);
        $output = '';
        $output .= '<link href="' . Tools::getShopDomain(true) . '/modules/debugtoolbar/views/assets/css/debugtoolbar.css" rel="stylesheet" type="text/css" media="all">';
        $output .= '	<div class="debugtoolbar">

							<div class="debugtoolbar-window">
								<div class="debugtoolbar-content-area">
		';
        /* LOAD TIME */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-load-times">';
        $output .= '					<table>
											<tr>
												<th>Name</th>
												<th>Running Time (ms)</th>
											</tr>
											<tr>
												<td class="debugtoolbar-table-first">Global Application</td>
												<td>' . $this->displayLoadTimeColor($this->_time['display'] - $start_time, true) . '</td>
											</tr>
		';
        $last_time = $start_time;
        foreach ($this->_time as $k => $time) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . ucfirst($k) . '</td>
												<td>' . $this->displayLoadTimeColor($time - $last_time, true) . '</td>
											</tr>
			';
            $last_time = $time;
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /LOAD TIME */
        /* HOOK PROCESSING */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-hook-processing">';
        $output .= '					<table>
											<tr>
												<th>Name</th>
												<th>Running Time (ms) / Memory Usage</th>
											</tr>
											<tr>
												<td class="debugtoolbar-table-first">Global Hook</td>
												<td><pre>' . $this->displayLoadTimeColor($totalHookTime) . ' / ' . $this->displayMemoryColor($totalHookMemoryUsage) . '</pre></td>
											</tr>
		';
        foreach ($hooktime as $hook => $time) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . ucfirst($hook) . '</td>
												<td><pre>' . $this->displayLoadTimeColor($time) . ' / ' . $this->displayMemoryColor($hookMemoryUsage[$hook]) . '</pre></td>
											</tr>
			';
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /HOOK PROCESSING */
        /* MEMORY PEAK USAGE */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-memory-peak-usage">';
        $output .= '					<table>
											<tr>
												<th>Name</th>
												<th>Memory Usage (Global)</th>
											</tr>
											<tr>
												<td class="debugtoolbar-table-first">Global Memory</td>
												<td><pre>' . $this->displayPeakMemoryColor($memory_peak_usage) . '</pre></td>
											</tr>
		';
        foreach ($this->_memory as $k => $memory) {
            $last_memory = 0;
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . ucfirst($k) . '</td>
												<td><pre>' . $this->displayMemoryColor($memory - $last_memory) . ' (' . $this->displayPeakMemoryColor($this->_mempeak[$k]) . ')</pre></td>
											</tr>
			';
            $last_memory = $memory;
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /MEMORY PEAK USAGE */
        /* INCLUDED FILES */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-included-files">';
        $output .= '					<table>
											<tr>
												<th>#</th>
												<th>File</th>
												<th>Size</th>
											</tr>
											<tr>
												<td class="debugtoolbar-table-first">Size global files</td>
												<td><pre>' . $this->displayMemoryColor($totalSize) . '</pre></td>
												<td>-</td>
											</tr>
		';
        $i = 1;
        foreach (get_included_files() as $file) {
            $f = ltrim(str_replace('\\', '/', str_replace(_PS_ROOT_DIR_, '', $file)), '/');
            $f = dirname($file) . '/<span style="color: #0080b0">' . basename($file) . '</span>';
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . $i . '</td>
												<td><pre>' . $f . '</pre></td>
												<td>' . FileSizeConvert(@filesize($file)) . '</td>
											</tr>
			';
            $i++;
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /INCLUDED FILES */
        /* SQL QUERIES */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-sql-queries">';
        $output .= '					<table>
											<tr>
												<th>Time</th>
												<th>Query</th>
											</tr>
		';
        $array_queries = array();
        $queries = Db::getInstance()->queries;
        uasort($queries, 'prestashop_querytime_sort');
        foreach ($queries as $data) {
            $query_row = array('time' => $data['time'], 'query' => $data['query'], 'location' => $data['file'] . ':<span style="color:#0080b0">' . $data['line'] . '</span>', 'filesort' => false, 'rows' => 1, 'group_by' => false);
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                $explain = Db::getInstance()->executeS('explain ' . $data['query']);
                if (stristr($explain[0]['Extra'], 'filesort')) {
                    $query_row['filesort'] = true;
                }
                foreach ($explain as $row) {
                    $query_row['rows'] *= $row['rows'];
                }
                if (stristr($data['query'], 'group by') && !preg_match('/(avg|count|min|max|group_concat|sum)\\s*\\(/i', $data['query'])) {
                    $query_row['group_by'] = true;
                }
            }
            $array_queries[] = $query_row;
        }
        foreach ($array_queries as $data) {
            $filestortGroup = '';
            if (preg_match('/^\\s*select\\s+/i', $data['query'])) {
                if ($data['filesort']) {
                    $filestortGroup .= '<b ' . $this->getTimeColor($data['time'] * 1000) . '>USING FILESORT</b> - ';
                }
                $filestortGroup .= $this->displayRowsBrowsed($data['rows']);
                if ($data['group_by']) {
                    $filestortGroup .= ' - <b>Useless GROUP BY need to be removed</b>';
                }
            }
            $output .= '
											<tr>
												<td class="debugtoolbar-table-title" colspan="2"><strong>Query in : </strong>' . $data['location'] . ' - ' . $filestortGroup . '</td>
											</tr>
											<tr>
												<td class="debugtoolbar-table-first"><span ' . $this->getTimeColor($data['time'] * 1000) . '>' . round($data['time'] * 1000, 3) . ' ms</span></td>
												<td><pre>' . htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
											</tr>
			';
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /SQL QUERIES */
        /* TABLES */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-sql-table">';
        $output .= '					<table>
											<tr>
												<th>Nb call</th>
												<th>Table</th>
											</tr>
		';
        $tables = Db::getInstance()->tables;
        arsort($tables);
        foreach ($tables as $table => $nb) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first"><b ' . $this->getTableColor($nb) . '>' . $nb . '</b></td>
												<td><pre>' . $table . '</pre></td>
											</tr>
			';
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /TABLES */
        /* OBJECTMODEL */
        if (isset(ObjectModel::$debug_list)) {
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-objectmodel-instance">';
            $output .= '					<table>
												<tr>
													<th>Nb call</th>
													<th>ObjectModel Instance</th>
												</tr>
			';
            $list = ObjectModel::$debug_list;
            uasort($list, create_function('$a,$b', 'return (count($a) < count($b)) ? 1 : -1;'));
            $i = 0;
            foreach ($list as $class => $info) {
                echo '';
                echo '';
                $i++;
                $output .= '
												<tr>
													<td class="debugtoolbar-table-first"><b ' . $this->getObjectModelColor(count($info)) . '>' . count($info) . '</b></td>
													<td><a href="#" onclick="$(\'#object_model_' . $i . '\').css(\'display\', $(\'#object_model_' . $i . '\').css(\'display\') == \'none\' ? \'block\' : \'none\'); return false" style="color:#0080b0">' . $class . '</a>
														<pre id="object_model_' . $i . '" style="display: none">';
                foreach ($info as $trace) {
                    $output .= ltrim(str_replace(array(_PS_ROOT_DIR_, '\\'), array('', '/'), $trace['file']), '/') . ' [' . $trace['line'] . ']<br />';
                }
                $output .= '</pre></td>
												</tr>
				';
            }
            $output .= '
											</table>
			';
            $output .= '				</div>';
        }
        /* /OBJECTMODEL */
        /* GETALLHEADERS */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-getallheader">';
        $output .= '					<table>
											<tr>
												<th>Name</th>
												<th>Value</th>
											</tr>
		';
        $getallheaders = getallheaders();
        foreach ($getallheaders as $name => $value) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . $name . '</td>
												<td><pre>' . $value . '</pre></td>
											</tr>
			';
        }
        stream_context_set_default(array('http' => array('method' => 'HEAD')));
        $url = getUrl();
        if ($get_headers = get_headers($url, 1)) {
            foreach ($get_headers as $name => $value) {
                $output .= '
												<tr>
													<td class="debugtoolbar-table-first">' . $name . '</td>
													<td><pre>' . (is_array($value) ? $value[0] : $value) . '</pre></td>
												</tr>
				';
            }
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /GETALLHEADERS */
        /* DATA */
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-getpost-data">';
        $output .= '					<table>
											<tr>
												<th>Name</th>
												<th>Value</th>
											</tr>
											<tr>
												<td class="debugtoolbar-table-title" colspan="2">Post Data</td>
											</tr>
		';
        $post = isset($_POST) ? $_POST : array();
        if (!count($post)) {
            $output .= '<tr><td colspan="2">No POST Data Found</td></tr>';
        } else {
            foreach ($post as $name => $value) {
                if (!is_array($value)) {
                    $output .= '
													<tr>
														<td class="debugtoolbar-table-first">' . $name . '</td>
														<td><pre>' . $value . '</pre></td>
													</tr>
					';
                } else {
                    $output .= '
													<tr>
														<td class="debugtoolbar-table-first">' . $name . '</td>
														<td>
					';
                    foreach ($value as $k => $v) {
                        $output .= '
															<pre>' . $k . ' : ' . $v . '</pre>
						';
                    }
                    $output .= '
														</td>
													</tr>
					';
                }
            }
        }
        $output .= '						<tr>
												<td class="debugtoolbar-table-title" colspan="2">Get Data</td>
											</tr>
		';
        $get = isset($_GET) ? $_GET : array();
        if (!count($get)) {
            $output .= '<tr><td colspan="2">No GET Data Found</td></tr>';
        } else {
            foreach ($get as $name => $value) {
                $output .= '
												<tr>
													<td class="debugtoolbar-table-first">' . $name . '</td>
													<td><pre>' . $value . '</pre></td>
												</tr>
				';
            }
        }
        $output .= '						<tr>
												<td class="debugtoolbar-table-title" colspan="2">Server Data</td>
											</tr>
		';
        $server = isset($_SERVER) ? $_SERVER : array();
        if (!count($server)) {
            $output .= '<tr><td colspan="2">No SERVER Data Found</td></tr>';
        } else {
            foreach ($server as $name => $value) {
                $output .= '
												<tr>
													<td class="debugtoolbar-table-first">' . $name . '</td>
													<td><pre>' . $value . '</pre></td>
												</tr>
				';
            }
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* /DATA */
        /* DEBUG */
        if (count($GLOBALS['debugtoolbar'])) {
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-debug">';
            $output .= '					<table>
												<tr>
													<th>Debug</th>
												</tr>
			';
            $output .= '
												<tr>
													<td colspan="2">' . $GLOBALS['debugtoolbar'] . '</td>
												</tr>
			';
            $output .= '
											</table>
			';
            $output .= '				</div>';
        }
        /* /DEBUG */
        /* PS INFOS */
        if (isset($this->context->employee->id)) {
            $ps_infos = array('version' => array('php' => phpversion(), 'server' => $_SERVER['SERVER_SOFTWARE'], 'memory_limit' => ini_get('memory_limit'), 'max_execution_time' => ini_get('max_execution_time')), 'database' => array('version' => Db::getInstance()->getVersion(), 'prefix' => _DB_PREFIX_, 'engine' => _MYSQL_ENGINE_), 'uname' => function_exists('php_uname') ? php_uname('s') . ' ' . php_uname('v') . ' ' . php_uname('m') : '', 'apache_instaweb' => Tools::apacheModExists('mod_instaweb'), 'shop' => array('ps' => _PS_VERSION_, 'url' => Tools::getHttpHost(true) . __PS_BASE_URI__, 'theme' => _THEME_NAME_), 'mail' => Configuration::get('PS_MAIL_METHOD') == 1, 'smtp' => array('server' => Configuration::get('PS_MAIL_SERVER'), 'user' => Configuration::get('PS_MAIL_USER'), 'password' => Configuration::get('PS_MAIL_PASSWD'), 'encryption' => Configuration::get('PS_MAIL_SMTP_ENCRYPTION'), 'port' => Configuration::get('PS_MAIL_SMTP_PORT')), 'user_agent' => $_SERVER['HTTP_USER_AGENT']);
            $tests = ConfigurationTest::getDefaultTests();
            $tests_op = ConfigurationTest::getDefaultTestsOp();
            $params_required_results = ConfigurationTest::check($tests);
            $params_optional_results = ConfigurationTest::check($tests_op);
            $tests_errors = array('phpversion' => 'Update your PHP version', 'upload' => 'Configure your server to allow file uploads', 'system' => 'Configure your server to allow the creation of directories and files with write permissions.', 'gd' => 'Enable the GD library on your server.', 'mysql_support' => 'Enable the MySQL support on your server.', 'config_dir' => 'Set write permissions for the "config" folder.', 'cache_dir' => 'Set write permissions for the "cache" folder.', 'sitemap' => 'Set write permissions for the "sitemap.xml" file.', 'img_dir' => 'Set write permissions for the "img" folder and subfolders.', 'log_dir' => 'Set write permissions for the "log" folder and subfolders.', 'mails_dir' => 'Set write permissions for the "mails" folder and subfolders.', 'module_dir' => 'Set write permissions for the "modules" folder and subfolders.', 'theme_lang_dir' => 'Set the write permissions for the "themes' . _THEME_NAME_ . '/lang/" folder and subfolders, recursively.', 'translations_dir' => 'Set write permissions for the "translations" folder and subfolders.', 'customizable_products_dir' => 'Set write permissions for the "upload" folder and subfolders.', 'virtual_products_dir' => 'Set write permissions for the "download" folder and subfolders.', 'fopen' => 'Allow the PHP fopen() function on your server', 'register_globals' => 'Set PHP "register_global" option to "Off"', 'gz' => 'Enable GZIP compression on your server.');
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-ps-info">';
            $output .= "\r\n\t\t\t\t\t\t\t\t\t\t\t<script type=\"text/javascript\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t\$(document).ready(function()\r\n\t\t\t\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\$.ajax({\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: 'GET',\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\turl: '" . $this->context->link->getAdminLink('AdminInformation') . "',\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata: {\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'action': 'checkFiles',\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ajax': 1\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdataType: 'json',\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsuccess: function(json)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvar tab = {\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'missing': 'Missing files',\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'updated': 'Updated files'\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (json.missing.length || json.updated.length)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$('#changedFilesDebugtoolbar').html('<div style=\"color:#ef8400;\">Changed/missing files have been detected.</div>');\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$('#changedFilesDebugtoolbar').html('<div style=\"color:#0080b0;\">No change has been detected in your files</div>');\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$.each(tab, function(key, lang)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (json[key].length)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvar html = \$('<ul>').attr('id', key+'_files');\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$(json[key]).each(function(key, file)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thtml.append(\$('<li>').html(file))\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\$('#changedFilesDebugtoolbar')\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.append(\$('<h3>').html(lang+' ('+json[key].length+')'))\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.append(html);\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\t\t\t</script>\r\n\t\t\t";
            $output .= '					<table>
												<tr>
													<th>Name</th>
													<th>Value</th>
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Server Informations</strong></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Server</td>
													<td><pre>' . htmlspecialchars($ps_infos['uname'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Logiciel Serveur</td>
													<td><pre>' . htmlspecialchars($ps_infos['version']['server'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">PHP Version</td>
													<td><pre>' . htmlspecialchars($ps_infos['version']['php'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Memory Limit</td>
													<td><pre>' . htmlspecialchars($ps_infos['version']['memory_limit'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Max Execution Time</td>
													<td><pre>' . htmlspecialchars($ps_infos['version']['max_execution_time'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Database Informations</strong></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">MySQL Version</td>
													<td><pre>' . htmlspecialchars($ps_infos['database']['version'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">MySQL Engine</td>
													<td><pre>' . htmlspecialchars($ps_infos['database']['engine'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">MySQL Prefix</td>
													<td><pre>' . htmlspecialchars($ps_infos['database']['prefix'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Store Informations</strong></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">PrestaShop Version</td>
													<td><pre>' . htmlspecialchars($ps_infos['shop']['ps'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Store Url</td>
													<td><pre>' . htmlspecialchars($ps_infos['shop']['url'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Themes Use</td>
													<td><pre>' . htmlspecialchars($ps_infos['shop']['theme'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
			';
            if (!empty($ps_infos['mail'])) {
                $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Email Setting</strong></td>
												</tr>
												<tr>
													<td colspan="2"><pre>You are using the PHP mail function.</pre></td>
												</tr>
				';
            } else {
                $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Email Setting</strong></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">SMTP Server</td>
													<td><pre>' . htmlspecialchars($ps_infos['smtp']['server'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Cryptage</td>
													<td><pre>' . htmlspecialchars($ps_infos['smtp']['encryption'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Port</td>
													<td><pre>' . htmlspecialchars($ps_infos['smtp']['port'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Login</td>
													<td><pre>' . (!empty($ps_infos['smtp']['user']) ? '<span style="color:#90bd00;font-weight:bold;">OK</span>' : '<span style="color:#ff4141;font-weight:bold;">Not defined</span>') . '</pre></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Password</td>
													<td><pre>' . (!empty($ps_infos['smtp']['password']) ? '<span style="color:#90bd00;font-weight:bold;">OK</span>' : '<span style="color:#ff4141;font-weight:bold;">Not defined</span>') . '</pre></td>
												</tr>
				';
            }
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Your information</strong></td>
												</tr>
												<tr>
													<td class="debugtoolbar-table-first">Your web browser</td>
													<td><pre>' . htmlspecialchars($ps_infos['user_agent'], ENT_NOQUOTES, 'utf-8', false) . '</pre></td>
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>Check your configuration</strong></td>
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-first">Required parameters</td>
			';
            if (!in_array('fail', $params_required_results)) {
                $output .= '
													<td><pre><span style="color:#90bd00;font-weight:bold;">OK</span></pre></td>
				';
            } else {
                $output .= '
													<td>
														<pre><span style="color:#ff4141;font-weight:bold;">Please fix the following error(s)</span></pre>
														<ul>
				';
                foreach ($params_required_results as $key => $value) {
                    if ($value == 'fail') {
                        $output .= '						<li>' . $tests_errors[$key] . '</li>';
                    }
                }
                $output .= '
														</ul>
													</td>
				';
            }
            $output .= '
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-first">Optional parameters</td>
			';
            if (!in_array('fail', $params_optional_results)) {
                $output .= '
													<td><pre><span style="color:#90bd00;font-weight:bold;">OK</span></pre></td>
				';
            } else {
                $output .= '
													<td>
														<pre><span style="color:#ff4141;font-weight:bold;">Please fix the following error(s)</span></pre>
														<ul>
				';
                foreach ($params_optional_results as $key => $value) {
                    if ($value == 'fail') {
                        $output .= '						<li>' . $key . '</li>';
                    }
                }
                $output .= '
														</ul>
													</td>
				';
            }
            $output .= '
												</tr>
			';
            $output .= '
												<tr>
													<td class="debugtoolbar-table-title" colspan="2"><strong>List of changed files</strong></td>
												</tr>
			';
            $output .= '
												<tr>
													<td colspan="2"><div id="changedFilesDebugtoolbar"><img src="../img/admin/ajax-loader.gif" /> Checking files...</div></td>
												</tr>
			';
            $output .= '
											</table>
			';
            $output .= '				</div>';
        } else {
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-ps-info">';
            $output .= '					<table>
												<tr>
													<td><pre><span style="color:#ff4141;font-weight:bold;">Not display in Front office</span></pre></td>
												</tr>
											</table>
										</div>
			';
        }
        /* /PS INFOS */
        /* SMARTY DEBUG */
        $this->context->smarty->loadPlugin('Smarty_Internal_Debug');
        // Smarty_Internal_Debug::display_debug($this->context->smarty);
        $SID = new Smarty_Internal_Debug();
        $obj = $this->context->smarty;
        $ptr = $SID::get_debug_vars($obj);
        if ($obj instanceof Smarty) {
            $smarty = clone $obj;
        } else {
            $smarty = clone $obj->smarty;
        }
        $_assigned_vars = $ptr->tpl_vars;
        ksort($_assigned_vars);
        $_config_vars = $ptr->config_vars;
        ksort($_config_vars);
        $smarty->registered_filters = array();
        $smarty->autoload_filters = array();
        $smarty->default_modifiers = array();
        $smarty->force_compile = false;
        $smarty->left_delimiter = '{';
        $smarty->right_delimiter = '}';
        $smarty->debugging = false;
        $smarty->force_compile = false;
        if ($obj instanceof Smarty_Internal_Template) {
            $template_name = $obj->source->type . ':' . $obj->source->name;
        }
        if ($obj instanceof Smarty) {
            $template_name = $SID::$template_data;
        } else {
            $template_name = null;
        }
        $execution_time = microtime(true) - $smarty->start_time;
        $assigned_vars = $_assigned_vars;
        $config_vars = $_config_vars;
        // echo 'assigned_vars<pre>'.print_r($assigned_vars['SCRIPT_NAME'], true).'</pre>';die;
        $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-smarty-debug">';
        $output .= '					<table>
											<tr>
												<th colspan="2">Smarty Debug Console  -  ' . (isset($template_name) && count($template_name) ? $template_name : 'Total Time ' . number_format($execution_time, 5, '.', '')) . '</th>
											</tr>
		';
        if (isset($template_name) && count($template_name)) {
            foreach ($template_name as $template) {
                $output .= '
											<tr>
												<td class="debugtoolbar-table-first"><font color=brown>' . $template['name'] . '</font></td>
												<td>
													<span style="font-size: 0.8em;font-style: italic;">
														' . number_format($template['compile_time'], 5, '.', '') . '
														' . number_format($template['render_time'], 5, '.', '') . '
														' . number_format($template['cache_time'], 5, '.', '') . '
													</span>
												</td>
											</tr>
				';
            }
        }
        $output .= '
											<tr>
												<td class="debugtoolbar-table-title" colspan="2"><strong>Assigned template variables</strong></td>
											</tr>
		';
        foreach ($assigned_vars as $key => $vars) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . $key . '</td>
												<td><pre>' . smarty_modifier_debug_print_var($vars) . '</pre></td>
											</tr>
			';
        }
        $output .= '
											<tr>
												<td class="debugtoolbar-table-title" colspan="2"><trong>Assigned config file variables (outer template scope)</strong></td>
											</tr>
		';
        foreach ($config_vars as $key => $vars) {
            $output .= '
											<tr>
												<td class="debugtoolbar-table-first">' . $key . '</td>
												<td><pre>' . smarty_modifier_debug_print_var($vars) . '</pre></td>
											</tr>
			';
        }
        $output .= '
										</table>
		';
        $output .= '				</div>';
        /* SMARTY DEBUG */
        /* ADMINER */
        if (isset($this->context->employee->id)) {
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-adminer">';
            $output .= '					<table>
											<tr>
												<th>Adminer</th>
											</tr>
		';
            $output .= '
											<tr>
												<td colspan="2">
												<iframe src="' . Tools::getShopDomain(true) . '/modules/debugtoolbar/tools/adminer/display.php?server=' . _DB_SERVER_ . '&username='******'&db=' . _DB_NAME_ . '" frameborder="0" height="880" width="100%" id="adminerFrame"></iframe>
													<script type="text/javascript">
														$(\'#adminerFrame\').load(function(){
															$self = $(this).contents();
															$self.find("input[name=\'auth[server]\']").val("' . _DB_SERVER_ . '");
															$self.find("input[name=\'auth[username]\']").val("' . _DB_USER_ . '");
															$self.find("input[name=\'auth[password]\']").val("' . _DB_PASSWD_ . '");
															$self.find("input[name=\'auth[db]\']").val("' . _DB_NAME_ . '");
														});
													</script>
												</td>
											</tr>
		';
            $output .= '
										</table>
		';
            $output .= '				</div>';
        } else {
            $output .= '				<div class="debugtoolbar-tab-pane debugtoolbar-table debugtoolbar-adminer">';
            $output .= '					<table>
												<tr>
													<td><pre><span style="color:#ff4141;font-weight:bold;">Not display in Front office</span></pre></td>
												</tr>
											</table>
										</div>
			';
        }
        /* /ADMINER */
        $output .= '			</div>
							</div>

							<ul id="debugtoolbar-open-tabs" class="debugtoolbar-tabs">

								<!-- LOAD TIME -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-load-times">Time <span class="debugtoolbar-count">' . $this->displayLoadTimeColor($this->_time['display'] - $start_time) . '</span></a></li>
								<!-- /LOAD TIME -->

								<!-- HOOK PROCESSING -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-hook-processing">Hook <span class="debugtoolbar-count">' . $this->displayLoadTimeColor($totalHookTime) . ' / ' . $this->displayMemoryColor($totalHookMemoryUsage) . '</span></a></li>
								<!-- /HOOK PROCESSING -->

								<!-- MEMORY PEAK USAGE -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-memory-peak-usage">Memory <span class="debugtoolbar-count">' . $this->displayPeakMemoryColor($memory_peak_usage) . '</span></a></li>
								<!-- /MEMORY PEAK USAGE -->

								<!-- INCLUDED FILES -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-included-files">Files <span class="debugtoolbar-count">' . sizeof(get_included_files()) . '</span></a></li>
								<!-- /INCLUDED FILES -->

								<!-- SQL QUERIES -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-sql-queries">Sql <span class="debugtoolbar-count">' . $this->displaySQLQueries(count(Db::getInstance()->queries)) . '</span><span class="debugtoolbar-count">' . $this->displayLoadTimeColor($totalQueryTime) . '</span></a></li>
								<!-- /SQL QUERIES -->

								<!-- TABLE -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-sql-table">Table</a></li>
								<!-- /TABLE -->

								<!-- OBJECTMODEL -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-objectmodel-instance">ObjectModel</a></li>
								<!-- /OBJECTMODEL -->

								<!-- GETALLHEADERS -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-getallheader">Header</a></li>
								<!-- /GETALLHEADERS -->

								<!-- DATA -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-getpost-data">Data</a></li>
								<!-- /DATA -->

								<!-- PS INFOS -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-ps-info">Infos</a></li>
								<!-- /PS INFOS -->

								<!-- SMARTY DEBUG -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-smarty-debug">Smarty</a></li>
								<!-- /SMARTY DEBUG -->

								<!-- ADMINER -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-adminer">Adminer</a></li>
								<!-- /ADMINER -->
		';
        if (count($GLOBALS['debugtoolbar'])) {
            $output .= '
								<!-- DEBUG -->
								<li><a class="debugtoolbar-tab" data-debugtoolbar-tab="debugtoolbar-debug">Debug</a></li>
								<!-- /DEBUG -->
			';
        }
        $output .= '			<li class="debugtoolbar-tab-right"><a id="debugtoolbar-hide" href="#">&#8614;</a></li>
								<li class="debugtoolbar-tab-right"><a id="debugtoolbar-close" href="#">&times;</a></li>
								<li class="debugtoolbar-tab-right"><a id="debugtoolbar-zoom" href="#">&#8645;</a></li>
							</ul>

							<ul id="debugtoolbar-closed-tabs" class="debugtoolbar-tabs">
								<li><a id="debugtoolbar-show" href="#">&#8612;</a></li>
							</ul>

						</div>
		';
        $output .= '<script type="text/javascript" src="' . Tools::getShopDomain(true) . '/modules/debugtoolbar/views/assets/js/debugtoolbar.js"></script>';
        echo $output;
    }