OSDN Git Service

add plugin
[ethna/ethna.git] / extlib / Plugin / Filter / Debugtoolbar.php
1 <?php
2 // vim: foldmethod=marker
3 /**
4  *  Ethna_Plugin_Filter_DebugToolbar.php
5  *
6  *  @author     Sotaro KARASAWA <sotaro.k@gmail.com>
7  *  @package    Ether
8  */
9
10 /**
11  *  DebugToolbar Plugin Filter
12  *
13  *  @description    DebugToolbar plugin standard set
14  *  @author         Sotaro KARASAWA <sotaro.k@gmail.com>
15  *  @access         public
16  *  @package        Ethna_Plugin_Filter_DebugToolbar
17  */
18 class Ethna_Plugin_Filter_Debugtoolbar extends Ethna_Plugin_Filter
19 {
20     var $version = '1.0.0 - $Id$';
21
22     var $type_mapping = array(
23         VAR_TYPE_INT      => 'VAR_TYPE_INT',
24         VAR_TYPE_FLOAT    => 'VAR_TYPE_FLOAT',
25         VAR_TYPE_STRING   => 'VAR_TYPE_STRING',
26         VAR_TYPE_DATETIME => 'VAR_TYPE_DATETIME',
27         VAR_TYPE_BOOLEAN  => 'VAR_TYPE_BOOLEAN',
28         VAR_TYPE_FILE     => 'VAR_TYPE_FILE',
29     );
30
31     var $form_type_mapping = array(
32         FORM_TYPE_TEXT     => 'FORM_TYPE_TEXT',
33         FORM_TYPE_PASSWORD => 'FORM_TYPE_PASSWORD',
34         FORM_TYPE_TEXTAREA => 'FORM_TYPE_TEXTAREA',
35         FORM_TYPE_SELECT   => 'FORM_TYPE_SELECT',
36         FORM_TYPE_RADIO    => 'FORM_TYPE_RADIO',
37         FORM_TYPE_CHECKBOX => 'FORM_TYPE_CHECKBOX',
38         FORM_TYPE_SUBMIT   => 'FORM_TYPE_SUBMIT',
39         FORM_TYPE_FILE     => 'FORM_TYPE_FILE',
40         FORM_TYPE_BUTTON   => 'FORM_TYPE_BUTTON',
41         FORM_TYPE_HIDDEN   => 'FORM_TYPE_HIDDEN',
42     );
43
44     private $_stime;
45
46     public function __destruct() {
47     }
48
49     public function preFilter()
50     {
51         $stime = microtime(true);
52         $this->_stime = $stime;
53     }
54
55     /**
56      *  filter which will be executed at the end.
57      *
58      *  @access public
59      */
60     function postFilter()
61     {
62         if (!is_null($view = $this->ctl->getView()) && !$view->has_default_header) {
63             return null;
64         }
65
66         $this->init();
67         $this->dumpInfo();
68         $this->dumpConfig();
69         $this->dumpActionForm();
70         $this->smartyDebug();
71
72     }
73
74     function init()
75     {
76         $url = $this->ctl->getConfig()->get('url');
77         if (substr($url, -1) != '/') {
78             $url .= '/';
79         }
80
81         // {{{ CSS
82         echo '<style type="text/css">';
83         echo <<<EOF
84
85 .xdebug-var-dump {
86   background: #f0f0f0;
87   padding: 2px;
88   font-family: monospace;
89   line-height: 150%;
90 }
91
92 /* ethna debug style
93  */
94
95 /*
96 0 => string 'EMERG' (length=5)
97 1 => string 'ALERT' (length=5)
98 2 => string 'CRIT' (length=4)
99 3 => string 'ERR' (length=3)
100 4 => string 'WARNING' (length=7)
101 5 => string 'NOTICE' (length=6)
102 6 => string 'INFO' (length=4)
103 7 => string 'DEBUG' (length=5)
104 */
105 .ethna-debug-pre
106 {
107   line-height: 55%;
108   border: solid 2px #333;
109   padding: 8px;
110   margin: 10px;
111 }
112 .ethna-debug-pre-blink
113 {
114   color: #f00;
115 }
116 .ethna-debug-title ,
117 .ethna-debug-subtitle {
118   font-family: Verdana, "ヒラギノ角ゴ Pro W3", "メイリオ" !important;
119   font-size: 18px;
120   font-weight: bold;
121   line-height: 2.6em;
122 }
123
124 .ethna-debug {
125   font-family: Verdana !important;
126   position: fixed;
127   bottom: 0px;
128   left: 0px;
129   width: 100%;
130   max-height: 50%;
131   padding-top: 20px;
132   padding-bottom: 50px;
133   overflow: auto;
134   background: #ccc !important;
135   border-top: solid 3px #fff;
136   color: #333 !important;
137   display:none;
138   font-size: 12px;
139   opacity: 0.9;
140 }
141 .ethna-debug td,
142 .ethna-debug th {
143   color: #333 !important;
144 }
145 .ethna-debug div {
146   padding-left: 20px;
147 }
148
149 #ethna-debug-switch-outline {
150   background: #666;
151   color: #fff;
152   margin: 0;
153   padding: 0;
154   position: fixed;
155   bottom: 0px;
156   left: 0px;
157   font-size: 14px;
158   font-family: Verdana, "ヒラギノ角ゴ Pro W3", "メイリオ";
159   opacity: 0.8;
160 }
161 #ethna-debug-switch-outline li {
162   padding: 7px 10px 7px 22px;
163   float:left;
164   list-style:none;
165   z-index: 1000;
166 }
167 li.ethna-debug-switch {
168   /* background-position: 2px 12px; */
169   background-position: 4px 50%;
170   background-repeat: no-repeat;
171 }
172 li.ethna-debug-switch:hover {
173   background-color: #fff !important;
174   color: #333;
175 }
176
177 li#ethna-debug-switch-EthnaClose {
178   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHdSURBVDjLpZNraxpBFIb3a0ggISmmNISWXmOboKihxpgUNGWNSpvaS6RpKL3Ry//Mh1wgf6PElaCyzq67O09nVjdVlJbSDy8Lw77PmfecMwZg/I/GDw3DCo8HCkZl/RlgGA0e3Yfv7+DbAfLrW+SXOvLTG+SHV/gPbuMZRnsyIDL/OASziMxkkKkUQTJJsLaGn8/iHz6nd+8mQv87Ahg2H9Th/BxZqxEkEgSrq/iVCvLsDK9awtvfxb2zjD2ARID+lVVlbabTgWYTv1rFL5fBUtHbbeTJCb3EQ3ovCnRC6xAgzJtOE+ztheYIEkqbFaS3vY2zuIj77AmtYYDusPy8/zuvunJkDKXM7tYWTiyGWFjAqeQnAD6+7ueNx/FLpRGAru7mcoj5ebqzszil7DggeF/DX1nBN82rzPqrzbRayIsLhJqMPT2N83Sdy2GApwFqRN7jFPL0tF+10cDd3MTZ2AjNUkGCoyO6y9cRxfQowFUbpufr1ct4ZoHg+Dg067zduTmEbq4yi/UkYidDe+kaTcP4ObJIajksPd/eyx3c+N2rvPbMDPbUFPZSLKzcGjKPrbJaDsu+dQO3msfZzeGY2TCvKGYQhdSYeeJjUt21dIcjXQ7U7Kv599f4j/oF55W4g/2e3b8AAAAASUVORK5CYII=");
179   background-position: center 3px;
180   border: none;
181   text-indent: -9999px;
182 }
183 li#ethna-debug-switch-Ethna {
184   padding-right: 0;
185   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABUSURBVHjaYvz//z8DKYCJgVSA34b/YPC+zO0/DLAQo40iJzECzWZkZMRqw4dyd5x++I8XIPuBZCdBPQ10FZFhiM8P1AmlQaiB5FBiISkhAQFAgAEA1FBb2xYZTGEAAAAASUVORK5CYII=");
186   /* background-image: url(../images/ethna-debug-switch-Ethna.png); */
187 }
188 #ethna-debug-switch-Timer {
189   background-image: url("data:image/png;base64,");
190 }
191 #ethna-debug-switch-ActionForm {
192   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAZdJREFUeNqcUz2LwkAQfdFFEAQRRU1zrXYWgiCineX1Xi+50srOwn8gtv4OewsRBTsR/0CKgKCFH/gRNbczR5bEeCD3IOy+nZnH28ms1u12PwHoeAOPx8PHHcex0Ol0vp03MZvNfLzdbhvifr+TEn8uxuMxLMtSXNd11Go12LbNeYPBAIZhYL/fQ8hDjayNRiMkEgkUCgVEIhE0Gg0lMJ1O2f71emWBZrPJ6263g7jdbixQrVY5mRxlMhmsVislQJxyDocDhsOhOjdNkx1wkApdZLPZlw28XC6+2Ha7hZC2tGeB+XyO9XqteDqdRrlcVg694B7Q4WKxwPl8RrFYRDQaDfTALQwIuA7y+bxKSKVSvh4Qd2cgICDvFbhCPB7/c4j+dOANLJdLbDYbxZPJJF+NIP9a0AEVTyYTnoNcLodYLIZ6vf6yB5VKhffhcPhX4Hg8ajQUpVJJWSUhbw+IUw7FyEGr1UK/3ychTciRFaFQiKfPhXfvgnJOpxOvvV6PVzmJQpMN+5LKH2++RvtJ1NS8j+g/+BFgAJmwQl7DhC7TAAAAAElFTkSuQmCC");
193 }
194 #ethna-debug-switch-Log {
195   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJxSURBVHjajJPLbxJBHMe/+wCk0gJKbW0DxERbG+qD9CAeSjzIAUNibJuY9OaFxIvnXvgnqgkJdy9cDBcS8WT0YNCaphEjjUSgLa+Wx5ZdBJZdnKEBS4uJ32Qyu/Ob32fm9xim2+0iGo0ysVgs4PF4nnSIQETXVVVFq9Vid3Z2kqFQaKNSqWSpTaPRIBKJwOv1gseJWKvVeuMukSzL6APoaLfbsFgsToZhNMFg8EWtVsvjlFicEdl4YiAzz7HkNC0BgVlbW1sNBAIvTSbTDAWfA1BHlmUH41BsIp7Ko1bchXCYQTqdYVyu+yt+v3/TbDYPIPxpAMdx6CgKfhQEvN4u4Ft6D5uLCUwV4ijiGiTDOuPz+VYFQfhJABtDAHoqR66cKUt4mxLwIXsMtlqFtlPB1YsFmEpf0ZAcmJp7CrvdPksO5IibMhSCogJfcnXE8w3sFctQGwIYMQteLoNTJIjJCOSmBJ1Odz4HNGltQvh8UMd2uggSPKxGGb+7TTRECS1SHKmaQ5NAaah9DeWAJ4ZiRYBFKcP3QAvHvIitjgWp/UVYxDTarBG8Vj+o1BCArGJ87AKeLY2jdOsIBnMBpcYvlNs5fNdL0E9O4t6EF6ZLV4bKfuYGPDx3FvBu9z0+ZT/iuF5Bq6FCEbW4bHRifmkFBoNh9A3oIsMyMIyZ8PD6c0yyDiT3t9DSyZi134RzbhnT0zO9+P8JoEba/8YJM5ZvP4Zr4VHvn+M5Umam19q03CMB1Lmf3UGXabihd0EHz/Ojq5DL5WqJROJIUZROHzBqJs58Pp+v2Wy2vwDSGGo4HH71hgj/IfJCD9xut0q//wgwALyXGwTcoR6SAAAAAElFTkSuQmCC");
196 }
197 #ethna-debug-switch-Info {
198   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAH2SURBVHjapFPPS1RRFP7uvfOQQnRsnGkR4iJkwEUFiZsBBXPllHshaJP0w6WgCP0HLURhxkD/gaBFigaSi+El0bJWYRQ0iWI9JycJdebNvNe5P971RbSaB9+99z3O953vnHseC8MQrTwJuTDG7Ifr+Yc9tE0R8oSs+bxD2CAUPmw8241iZXKmFiNA5PvJjvZibuCa09d7BfVGA4xznNUbKO99x5b7zqewxySy8o+AJPf39S7fGcmhfHCIn9XfOCUiJwGJy6kkAoR4XXqLo+qvSSliBW7cftRDmb88mBh3Pn7dR4XIEZFzAS70uf3iBQRBiNVXm9LJ1ffrS7vclDM1PppzvKNjlVlQsBACC3P3MD97l96FQs1voK3NweDATcf0CZFAPpXswKfyAWUTGpzbxioHQrs5qzeRyXTDNFnfAtnPshgxsj0z/1yfY2XIs2CKlrUCKgvjymYU+HR6wjp4UnxphLQTxmLu5EI1f675vrUpMbf4wgapHgjdF3mGHr4dK1CpHq992/eQSXWaerXIeQ9EzIGAd1iBGSzbxMLqZsmXuulLnbZpVsAQJYIggPtmW15jQU1xfJC6upLLY6NDaAZMTd95SbovTYotlVx4nvf3IMVHmbbireGck06nkUgkFPGk5uOH58F1t/8/yi39TK08fwQYAJFWzPPb9QZyAAAAAElFTkSuQmCC");
199 }
200 #ethna-debug-switch-SmartyDebug {
201   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJcSURBVHjabFJLT1NREJ7zuo8+eFRAqYoESi0aEgwJaqxRXBQTEzDGiAsNO7f+ALdsTPwFunHlygUbE6NBVBAXjUYN8rCgUIjIK1Sgpff23jOee6sJqJNZzDmZx/d9MyT3+jzsNkTCTJRFFQEQ+MfoX29EW9R28X1JdK0/XxKk7df/pwAJ1Vg4rkd7qXkY3aI3igpW0UZYSDVTGdxPc1CWPADoUuOAFmoAs66ipX/n60MMJngkSQjbydwrg+ReUijGAo3obKOb16taZ+ZyE1PDACzefD3RdEK6YC8/k84WocKfgIhOQdSliBbhnL4YfpWdvXHm5DoV7WPp8Pzi5VSq2938rPoCaD4HymUhay08YlRmMovZ2Tv9fUuxI3ZT9P3NvoX11ccT4+NcCEIIeLB90oQZzkaabIxMTn1Idq4oqKWSckfuZJKdm9NfJvXYLb2hn5oHFRz6WzhFhhqIkuyRXpV+AnCAmmL/RSN2WwnIwSeh1fdg1enWxPzYaE1T45oqUxpSBm/SgbaODln4bq+m3dw7WVyiIF2t9oJe3+M6pfjR5trowNOhSqGDFoDnL8PByMDxlkh+4q4i6W7PoLQVEiGtH8Vv94FQRxin2rsGnxxbWX4rOCwsNfZeSQH8ROl4mhJeXhy6W5MKvRegRerCH6cSo+lqzpimGVevFYBXUjPqbG6U6fmkiSBUJ9RQjtYyFTV68Gyoptvk1Jp74OE2D3nC+MZ3iyKRmKJ46Vx0ZGiQWqw9XgyUWH46S0SlurFyDtlz3qoNDxvBaizMoTotwu0S+jvGMgFlvwQYAL5QCxf9wMU0AAAAAElFTkSuQmCC");
202 }
203 #ethna-debug-switch-Config {
204   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAoJJREFUeNqkU01oE1EQnk02iTFQE7QihUKRkKTF1iU9+FdQCoWYgAcPegkIeiiIWiHgwUvpQXs1Ggo99OYlFwUhWAhYhZJWUmhMxJbYYk1LFDcmJraSv911vjQbevPgg9kZ5vu+eW9n3hM0TaP/WSI+gUCADAYDmUwmEgSBUNRoNJ5jaKjNSyuKsqRjjUaDVFWlWCy2X0BfDJ5nd5r9KxZI0Wh0BuRgMHibcznGrrD/wD6hawwHxBdcLte12dnZGYfDcYOFhkJBpnL5F3Y0IAcMHHB1nYAj+Xw+xHeZ8FSWf1BPTw+trqY2JElyAkilUhsej8dZKhWpu/s4jY+P3+P0s/n5+f0TVCoVqlarL0Oh0KTZbCZZlmlgoN+pqgrBEO/u/iZg4IALTecX+BQX6/X69Xw+v8e7bYqiSMvLy+t+f2AGhhg5YOCAC43+7+T1eh+srCS1hYU32tJSQkun09rg4NA0TwLTIMTIAQMHXGigbU2hVqsZq9UaNZsKKYrKoxRZKDYwKizEyAEDB1xoOk3kzo6xP4PExMT9WyMjl/q2t7+npqYevkBucvLx1d7eE9Li4tutcPjJXEsoCO+z2WxcP0GcC3zmDt8ZHj7bVyyWyO32SLHYOwl4ufyTdna+ELCuriN2nlSEC2x1mshdRZGbkchcSJaLfCOtFI+//prLbRIMMXLAwAEXmk4T+ZLALo+Ojj1PJtc1t7s/bLfbHyUSGQ2GGDlg4IALTesd6Y8JY7JarX6bzTZtsVhOwq+tfdMymZx2MAcOuPrmrSYKaDHRUbZjbIcA8sM6xQ9sADFP4xNf54/t21tnk9kKrG3qBdCLw20T//GCFbY9tj+sVf8KMAACOoVxz9PPRwAAAABJRU5ErkJggg==");
205 }
206
207 #ethna-debug-timewindow {
208 }
209 #ethna-debug-logwindow {
210 }
211
212 .ethna-debug-log {
213   margin: 0;
214   padding: 2px 10px;
215   color: #000;
216 }
217
218 .ethna-debug-log-EMERG {
219 }
220 .ethna-debug-log-ALERM {
221 }
222 .ethna-debug-log-CRIT {
223 }
224 .ethna-debug-log-ERR {
225   background: #ffaaaa;
226 }
227 .ethna-debug-log-WARNING {
228   background: #ffaaaa;
229 }
230 .ethna-debug-log-NOTICE {
231   background: #ffcccc;
232 }
233 .ethna-debug-log-INFO {
234   background: #ccccff;
235 }
236 .ethna-debug-log-DEBUG {
237   background: #ccc;
238 }
239
240 .ethna-debug-log-loglevel {
241   font-weight: bold;
242 }
243
244 .ethna-debug-log-loglevel-EMERG {
245   color: #f00;
246 }
247 .ethna-debug-log-loglevel-ALERM {
248   color: #f00;
249 }
250 .ethna-debug-log-loglevel-CRIT {
251   color: #f00;
252 }
253 .ethna-debug-log-loglevel-ERR {
254   color: #f00;
255 }
256 .ethna-debug-log-loglevel-WARNING {
257   color: #f00;
258 }
259 .ethna-debug-log-loglevel-NOTICE {
260   color: #f66;
261 }
262 .ethna-debug-log-loglevel-INFO {
263   color: #00f;
264 }
265 .ethna-debug-log-loglevel-DEBUG {
266 }
267
268 .ethna-debug-window {
269
270 }
271
272 .ethna-debug-table {
273   border-collapse: collapse;
274   border: solid 1px #333;
275 }
276 .ethna-debug-table th ,
277 .ethna-debug-table td {
278   padding: 3px 5px;
279   border-collapse: collapse;
280   border: solid 1px #333;
281   font-size: 12px;
282 }
283 .ethna-debug-table th {
284   background: #9c9;
285 }
286 .ethna-debug-table td.e {
287   background: #aca;
288 }
289 EOF;
290         echo '</style>';
291         // }}}
292
293         // {{{ load JavaScript
294         echo <<<EOL
295 <link rel="stylesheet" href="{$url}Debugtoolbar/css/ether.css" type="text/css" />
296 <script type="text/javascript" src="http://www.google.com/jsapi"></script>
297 <script type="text/javascript">
298     google.load("jquery", "1.3");
299 </script>
300 EOL;
301         // }}}
302
303         // {{{ jquery.cookie.plugin
304         echo <<<EOF
305 <script type="text/javascript">
306 /**
307  * Cookie plugin
308  *
309  * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
310  * Dual licensed under the MIT and GPL licenses:
311  * http://www.opensource.org/licenses/mit-license.php
312  * http://www.gnu.org/licenses/gpl.html
313  *
314  */
315
316 /**
317  * Create a cookie with the given name and value and other optional parameters.
318  *
319  * @example $.cookie('the_cookie', 'the_value');
320  * @desc Set the value of a cookie.
321  * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
322  * @desc Create a cookie with all available options.
323  * @example $.cookie('the_cookie', 'the_value');
324  * @desc Create a session cookie.
325  * @example $.cookie('the_cookie', null);
326  * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
327  *       used when the cookie was set.
328  *
329  * @param String name The name of the cookie.
330  * @param String value The value of the cookie.
331  * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
332  * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
333  *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
334  *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
335  *                             when the the browser exits.
336  * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
337  * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
338  * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
339  *                        require a secure protocol (like HTTPS).
340  * @type undefined
341  *
342  * @name $.cookie
343  * @cat Plugins/Cookie
344  * @author Klaus Hartl/klaus.hartl@stilbuero.de
345  */
346
347 /**
348  * Get the value of a cookie with the given name.
349  *
350  * @example $.cookie('the_cookie');
351  * @desc Get the value of a cookie.
352  *
353  * @param String name The name of the cookie.
354  * @return The value of the cookie.
355  * @type String
356  *
357  * @name $.cookie
358  * @cat Plugins/Cookie
359  * @author Klaus Hartl/klaus.hartl@stilbuero.de
360  */
361 jQuery.cookie = function(name, value, options) {
362     if (typeof value != 'undefined') { // name and value given, set cookie
363         options = options || {};
364         if (value === null) {
365             value = '';
366             options.expires = -1;
367         }
368         var expires = '';
369         if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
370             var date;
371             if (typeof options.expires == 'number') {
372                 date = new Date();
373                 date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
374             } else {
375                 date = options.expires;
376             }
377             expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
378         }
379         // CAUTION: Needed to parenthesize options.path and options.domain
380         // in the following expressions, otherwise they evaluate to undefined
381         // in the packed version for some reason...
382         var path = options.path ? '; path=' + (options.path) : '';
383         var domain = options.domain ? '; domain=' + (options.domain) : '';
384         var secure = options.secure ? '; secure' : '';
385         document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
386     } else { // only name given, get cookie
387         var cookieValue = null;
388         if (document.cookie && document.cookie != '') {
389             var cookies = document.cookie.split(';');
390             for (var i = 0; i < cookies.length; i++) {
391                 var cookie = jQuery.trim(cookies[i]);
392                 // Does this cookie string begin with the name we want?
393                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
394                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
395                     break;
396                 }
397             }
398         }
399         return cookieValue;
400     }
401 };
402 </script>
403 EOF;
404         // }}}
405
406         // {{{ JavaScript for Debugtoolbar
407         echo <<<EOL
408 <script type="text/javascript">
409 //jQuery.noConflict();
410 jQuery(function()
411 {
412
413     var buttonOutline = document.createElement('ul');
414     jQuery(buttonOutline).attr('id', 'ethna-debug-switch-outline');
415     jQuery('html > body').append(buttonOutline);
416
417     var buttonEthna = document.createElement('li');
418     jQuery(buttonEthna).attr('id', 'ethna-debug-switch-Ethna');
419     jQuery(buttonEthna).attr('class', 'ethna-debug-switch');
420     jQuery(buttonEthna).text("Ethna");
421     jQuery(buttonOutline).append(buttonEthna);
422
423     var state = {};
424
425     jQuery('.ethna-debug').each(function()
426     {
427         var name = jQuery(this).children('div.ethna-debug-title').text();
428         //var stateName = ^
429
430         var showMessage = ' ' + name;
431         var hideMessage = ' ' + name;
432         state[name] = false;
433
434         var targetId = jQuery(this).attr('id');
435         var buttonId = 'ethna-debug-switch-' + name;
436         var button = document.createElement('li');
437         jQuery(button).attr('id', buttonId);
438         jQuery(button).attr('class', 'ethna-debug-switch');
439         jQuery(button).text(showMessage);
440
441         jQuery(button).click(function()
442         {
443             jQuery('.ethna-debug').each(function()
444             {
445                 jQuery(this).hide();
446                 var local_name = jQuery(this).children('div.ethna-debug-title').text();
447
448                 if (name != local_name) {
449                     state[local_name] = false;
450                     jQuery.cookie(local_name, 0);
451                 }
452             });
453
454             if (!state[name]) {
455                 jQuery(this).text(hideMessage);
456                 //jQuery('#ethna-debug-logwindow').show();
457                 jQuery('#' + targetId).show();
458                 jQuery.cookie(name, 1);
459                 state[name] = true;
460             }
461             else {
462                 jQuery(this).text(showMessage);
463                 //jQuery('#ethna-debug-logwindow').hide();
464                 jQuery('#' + targetId).hide();
465                 jQuery.cookie(name, 0);
466                 state[name] = false;
467             }
468         });
469
470
471         jQuery(button).hover(function()
472         {
473             jQuery(this).css('cursor', 'pointer');
474         },
475         function()
476         {
477             jQuery(this).css('cursor', 'default');
478         });
479
480         jQuery(buttonOutline).append(button);
481
482         if (jQuery.cookie(name) == 1) {
483             jQuery('#' + targetId).show();
484             state[name] = true;
485         }
486
487         // log window coloring
488         if(jQuery('#' + targetId)
489             .is(":has('.ethna-debug-log-EMERG,.ethna-debug-log-ALERM,.ethna-debug-log-CRIT,.ethna-debug-log-ERR,.ethna-debug-log-WARNING,.ethna-debug-log-NOTICE')"))
490         {
491             jQuery(button).css('background-color', "#f00")
492                 .css('color', "#fff");
493         }
494     });
495
496
497     // close button
498     var closeButtonEthna = document.createElement('li');
499     jQuery(closeButtonEthna).attr('id', 'ethna-debug-switch-EthnaClose');
500     jQuery(closeButtonEthna).attr('class', 'ethna-debug-switch');
501     jQuery(closeButtonEthna).text("close");
502     jQuery(closeButtonEthna).click(function(e) {
503         jQuery(buttonOutline).hide();
504         return false;
505     });
506     jQuery(buttonOutline).append(closeButtonEthna);
507
508 });
509 </script>
510 EOL;
511         // }}}
512
513         // time
514         $etime = microtime(true);
515         $time   = sprintf("%.4f", $etime - $this->_stime);
516
517         echo '<div class="ethna-debug" id="ethna-debug-evwindow">';
518         echo '<div class="ethna-debug-title">' . ETHNA_VERSION
519             . ': ' . $this->controller->getCurrentActionName()  . '</div>';
520         echo "<div class=\"ethna-debug-log\">";
521         echo ETHNA_VERSION;
522         echo "</div> \n";
523         echo "<div class=\"ethna-debug-log\">";
524         echo "Ethna_Plugin_Debugtoolbar Version" . $this->version;
525         echo "</div> \n";
526
527         $time_warning_class ="";
528         if (0.5 < $time) {
529             $time_warning_class =" ethna-debug-log-WARNING";
530         }
531         elseif (2 < $time) {
532             $time_warning_class =" ethna-debug-log-ERR";
533         }
534         echo '<div class="ethna-debug-subtitle">Time Elapsed</div>';
535         echo "<div class=\"ethna-debug-log $time_warning_class\">" . "${time} sec.";
536         echo "</div> \n";
537
538         echo '<div class="ethna-debug-subtitle">Action/View/Forward</div>';
539         echo '<div id="ethna-debug-info-env" style="">';
540         $info = array(
541             'action' => $this->ctl->getCurrentActionName(),
542             'action_form' => get_class($this->ctl->getActionForm()),
543             'view' => get_class($this->ctl->getView()),
544             'forward' => (is_null($view = $this->ctl->getView())) ? "" : $view->getCurrentForwardName(),
545             'encoding' => $this->controller->getClientEncoding(),
546         );
547         self::dumpArray($info);
548         echo "</div> \n";
549         echo '</div>';
550     }
551
552     /**
553      * dump php info
554      *
555      * @access  public
556      */
557     function dumpInfo()
558     {
559         echo '<div class="ethna-debug" id="ethna-debug-infowindow">';
560         echo '<div class="ethna-debug-title">Info</div>';
561         echo "<div class=\"ethna-debug-log\">";
562
563         echo '<div class="ethna-debug-subtitle">PHPINFO</div>';
564         echo '<div class="ethna-debug-subtitle" id="ethna-debug-info-env-title"><a href="javascript:;">Environment &gt;&gt;</a></div>';
565         echo '<div id="ethna-debug-info-env" style="display:none;">';
566         echo $this->parsePHPInfo(INFO_ENVIRONMENT);
567         echo "</div> \n";
568
569         echo '<div class="ethna-debug-subtitle" id="ethna-debug-info-var-title"><a href="javascript:;">Variables &gt;&gt;</a></div>';
570         echo '<div id="ethna-debug-info-var" style="display:none;">';
571         echo $this->parsePHPInfo(INFO_VARIABLES);
572         echo "</div> \n";
573
574         echo '<div class="ethna-debug-subtitle" id="ethna-debug-info-modules-title"><a href="javascript:;">Installed Modules &gt;&gt;</a></div>';
575         echo '<div id="ethna-debug-info-modules" style="display:none;">';
576         echo $this->parsePHPInfo(INFO_MODULES);
577         //$this->dumpArray(get_loaded_extensions());
578         echo "</div> \n";
579
580         echo <<<EOF
581 <script type="text/javascript">
582 jQuery(function()
583 {
584     jQuery("#ethna-debug-info-env-title a").click(function() {
585         jQuery("#ethna-debug-info-env").toggle();
586     });
587     jQuery("#ethna-debug-info-var-title a").click(function() {
588         jQuery("#ethna-debug-info-var").toggle();
589     });
590     jQuery("#ethna-debug-info-modules-title a").click(function() {
591         jQuery("#ethna-debug-info-modules").toggle();
592     });
593 });
594 </script>
595 EOF;
596
597         echo "</div> \n";
598         echo '</div>';
599
600     }
601
602
603     function parsePHPInfo($info)
604     {
605         ob_start();
606         $phpinfo = phpinfo($info);
607         $info = ob_get_contents();
608         ob_end_clean();
609
610         $info_html = @simplexml_import_dom(DOMDOcument::loadHTML($info));
611         $body = $info_html->xpath("//body");
612         return preg_replace("/<table/", "<table class=\"ethna-debug-table ethna-debug-table-info\"", $body[0]->asXML());
613     }
614
615     /**
616      * dump action form defined values and posted values
617      *
618      * @access  public
619      */
620     function dumpActionForm()
621     {
622         $af = $this->ctl->getActionForm();
623         if ($af === null) {
624             return ;
625         }
626         echo '<div class="ethna-debug" id="ethna-debug-afwindow">';
627         echo '<div class="ethna-debug-title">ActionForm</div>';
628         echo '<div class="ethna-debug-subtitle">Posted Value</div>';
629         echo "<div class=\"ethna-debug-log\">";
630         self::dumpArray($this->ctl->getActionForm()->getArray());
631         echo "</div> \n";
632         echo '<div class="ethna-debug-subtitle">Definition</div>';
633         echo "<div class=\"ethna-debug-log\">";
634         //var_dump($this->controller->action_form->getArray());
635         self::dumpArray($this->controller->getActionForm()->getDef());
636         echo "</div> \n";
637         echo '<div class="ethna-debug-subtitle">$_GET</div>';
638         echo "<div class=\"ethna-debug-log\">";
639         //var_dump($this->controller->action_form->getArray());
640         self::dumpArray($_GET);
641         echo "</div> \n";
642         echo '<div class="ethna-debug-subtitle">$_POST</div>';
643         echo "<div class=\"ethna-debug-log\">";
644         //var_dump($this->controller->action_form->getArray());
645         self::dumpArray($_POST);
646         echo "</div> \n";
647         echo '</div>';
648     }
649
650     function dumpConfig()
651     {
652         $config = $this->controller->getConfig();
653         echo '<div class="ethna-debug" id="ethna-debug-configwindow">';
654         echo '<div class="ethna-debug-title">Config</div>';
655         echo "<div class=\"ethna-debug-log\">";
656         //var_dump($this->controller->action_form->getArray());
657         self::dumpArray($config->config);
658         echo "</div> \n";
659         echo '</div>';
660     }
661
662     function smartyDebug()
663     {
664         if (!defined('Smarty::SMARTY_VERSION')) {
665             return ;
666         }
667         $c =& Ethna_Controller::getInstance();
668         $debug_tpl = $c->getDirectory('template') . "/smarty_debug.tpl";
669
670         //if smarty2
671         //if (!file_exists($debug_tpl)) {
672         //    Ethna::raiseWarning(sprintf("Smarty debug template not found, please set %s.", $debug_tpl), E_USER_WARNING);
673         //    return null;
674         //}
675
676         require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_debug.php';
677
678         // get template directory
679         $r = $c->getRenderer();
680         $smarty = $r->engine;
681
682         $vars = Smarty_Internal_Debug::get_debug_vars($smarty);
683
684         //$smarty_original_debugging = $smarty->debugging;
685         //$smarty_original_debugtpl = $smarty->debug_tpl;
686
687         //$smarty->debugging = true;
688         //$smarty->debug_tpl = $debug_tpl;
689         //$smarty->assign('_smarty_debug_output', 'html');
690
691         echo '<div class="ethna-debug" id="ethna-debug-smartydebugwindow">';
692         echo '<div class="ethna-debug-title">SmartyDebug</div>';
693
694         echo '<div class="ethna-debug-subtitle">Smarty template vars</div>';
695         echo "<div class=\"ethna-debug-log\">";
696         foreach ($vars->tpl_vars as $k => $v) {
697             echo "$k<br />";
698             self::dumpArray($v->value);
699         }
700         echo "</div> \n";
701
702         echo '<div class="ethna-debug-subtitle">Smarty config vars</div>';
703         echo "<div class=\"ethna-debug-log\">";
704         foreach ($vars->config_vars as $k => $v) {
705             echo "$k<br />";
706             self::dumpArray($v->value);
707         }
708         echo "</div> \n";
709
710         echo "</div> \n";
711         echo '</div>';
712
713         //$smarty->debugging = $smarty_original_debugging;
714         //$smarty->debug_tpl = $smarty_original_debugtpl;
715     }
716
717     function dumpArray(&$array)
718     {
719         echo "<table class=\"ethna-debug-table\">";
720         if (is_scalar($array)) {
721             echo "<tr>\n";
722             echo "<th>Scalar</th>";
723             echo "<td>{$array}</td>";
724             echo "</tr>\n";
725         }
726         elseif (is_object($array)) {
727             echo "<tr>\n";
728             echo "<th>Object</th>";
729             echo "<td>" . get_class($array) . "</td>";
730             echo "</tr>\n";
731         }
732         else foreach ($array as $k => $v) {
733             echo "<tr>\n";
734             echo "<th>{$k}</th>";
735             if (is_array($v)) {
736                 echo "<td>";
737                 self::dumpArray($v);
738                 echo "</td>";
739             }
740             else {
741                 if (is_bool($v)) {
742                     echo "<td>" . ($v ? '<span style="color: #090;">true</span>' : '<span style="color: #900;">false</span>')  . "</td>";
743                 }
744                 else if ($k === 'type' || $k === 'form_type') {
745                     echo "<td>";
746                     if ($v === null) {
747                         echo "Undefined";
748                     }
749                     else {
750                         $key = $k . "_mapping";
751                         $ar = $this->$key;
752                         echo $ar[$v];
753                     }
754
755                     echo "</td>";
756                 }
757                 else {
758                     echo "<td>{$v}</td>";
759                 }
760             }
761             echo "</tr>\n";
762         }
763         echo "</table>\n";
764     }
765
766 }