CMS Tree Page View - Version 0.7.5

Version Description

  • fixed some notice-errors and switched some deprecated functions
  • updated swedish translation
  • fixed some strings that where untranslatable and updated POT-file (if I missed any, please let me know)
  • no longer allowed to add sub pages to a page with status draft, because if you edit the page and save it, wordpress will forget about the parent (and you will get confused)
  • started using hoverIntent for popup instead of regular mouseover, so the popups won't feel so aggressive - or no.. reverted this :(
  • when adding a page a text comes up so you know that something is going on
  • possible fix for magic fields and other plugins that deal with post columns
Download this release

Release Info

Developer eskapism
Plugin Icon wp plugin CMS Tree Page View
Version 0.7.5
Comparing to
See all releases

Code changes from version 0.7.4 to 0.7.5

FirePHPCore/FirePHP.class.php ADDED
@@ -0,0 +1,1529 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * *** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2009, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
40
+ * @author Christoph Dorn <christoph@christophdorn.com>
41
+ * @license http://www.opensource.org/licenses/bsd-license.php
42
+ * @package FirePHP
43
+ */
44
+
45
+
46
+ /**
47
+ * Sends the given data to the FirePHP Firefox Extension.
48
+ * The data can be displayed in the Firebug Console or in the
49
+ * "Server" request tab.
50
+ *
51
+ * For more information see: http://www.firephp.org/
52
+ *
53
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
54
+ * @author Christoph Dorn <christoph@christophdorn.com>
55
+ * @license http://www.opensource.org/licenses/bsd-license.php
56
+ * @package FirePHP
57
+ */
58
+ class FirePHP {
59
+
60
+ /**
61
+ * FirePHP version
62
+ *
63
+ * @var string
64
+ */
65
+ const VERSION = '0.3';
66
+
67
+ /**
68
+ * Firebug LOG level
69
+ *
70
+ * Logs a message to firebug console.
71
+ *
72
+ * @var string
73
+ */
74
+ const LOG = 'LOG';
75
+
76
+ /**
77
+ * Firebug INFO level
78
+ *
79
+ * Logs a message to firebug console and displays an info icon before the message.
80
+ *
81
+ * @var string
82
+ */
83
+ const INFO = 'INFO';
84
+
85
+ /**
86
+ * Firebug WARN level
87
+ *
88
+ * Logs a message to firebug console, displays an warning icon before the message and colors the line turquoise.
89
+ *
90
+ * @var string
91
+ */
92
+ const WARN = 'WARN';
93
+
94
+ /**
95
+ * Firebug ERROR level
96
+ *
97
+ * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count.
98
+ *
99
+ * @var string
100
+ */
101
+ const ERROR = 'ERROR';
102
+
103
+ /**
104
+ * Dumps a variable to firebug's server panel
105
+ *
106
+ * @var string
107
+ */
108
+ const DUMP = 'DUMP';
109
+
110
+ /**
111
+ * Displays a stack trace in firebug console
112
+ *
113
+ * @var string
114
+ */
115
+ const TRACE = 'TRACE';
116
+
117
+ /**
118
+ * Displays an exception in firebug console
119
+ *
120
+ * Increments the firebug error count.
121
+ *
122
+ * @var string
123
+ */
124
+ const EXCEPTION = 'EXCEPTION';
125
+
126
+ /**
127
+ * Displays an table in firebug console
128
+ *
129
+ * @var string
130
+ */
131
+ const TABLE = 'TABLE';
132
+
133
+ /**
134
+ * Starts a group in firebug console
135
+ *
136
+ * @var string
137
+ */
138
+ const GROUP_START = 'GROUP_START';
139
+
140
+ /**
141
+ * Ends a group in firebug console
142
+ *
143
+ * @var string
144
+ */
145
+ const GROUP_END = 'GROUP_END';
146
+
147
+ /**
148
+ * Singleton instance of FirePHP
149
+ *
150
+ * @var FirePHP
151
+ */
152
+ protected static $instance = null;
153
+
154
+ /**
155
+ * Flag whether we are logging from within the exception handler
156
+ *
157
+ * @var boolean
158
+ */
159
+ protected $inExceptionHandler = false;
160
+
161
+ /**
162
+ * Flag whether to throw PHP errors that have been converted to ErrorExceptions
163
+ *
164
+ * @var boolean
165
+ */
166
+ protected $throwErrorExceptions = true;
167
+
168
+ /**
169
+ * Flag whether to convert PHP assertion errors to Exceptions
170
+ *
171
+ * @var boolean
172
+ */
173
+ protected $convertAssertionErrorsToExceptions = true;
174
+
175
+ /**
176
+ * Flag whether to throw PHP assertion errors that have been converted to Exceptions
177
+ *
178
+ * @var boolean
179
+ */
180
+ protected $throwAssertionExceptions = false;
181
+
182
+ /**
183
+ * Wildfire protocol message index
184
+ *
185
+ * @var int
186
+ */
187
+ protected $messageIndex = 1;
188
+
189
+ /**
190
+ * Options for the library
191
+ *
192
+ * @var array
193
+ */
194
+ protected $options = array('maxObjectDepth' => 10,
195
+ 'maxArrayDepth' => 20,
196
+ 'useNativeJsonEncode' => true,
197
+ 'includeLineNumbers' => true);
198
+
199
+ /**
200
+ * Filters used to exclude object members when encoding
201
+ *
202
+ * @var array
203
+ */
204
+ protected $objectFilters = array();
205
+
206
+ /**
207
+ * A stack of objects used to detect recursion during object encoding
208
+ *
209
+ * @var object
210
+ */
211
+ protected $objectStack = array();
212
+
213
+ /**
214
+ * Flag to enable/disable logging
215
+ *
216
+ * @var boolean
217
+ */
218
+ protected $enabled = true;
219
+
220
+ /**
221
+ * The object constructor
222
+ */
223
+ function __construct() {
224
+ }
225
+
226
+ /**
227
+ * When the object gets serialized only include specific object members.
228
+ *
229
+ * @return array
230
+ */
231
+ public function __sleep() {
232
+ return array('options','objectFilters','enabled');
233
+ }
234
+
235
+ /**
236
+ * Gets singleton instance of FirePHP
237
+ *
238
+ * @param boolean $AutoCreate
239
+ * @return FirePHP
240
+ */
241
+ public static function getInstance($AutoCreate=false) {
242
+ if($AutoCreate===true && !self::$instance) {
243
+ self::init();
244
+ }
245
+ return self::$instance;
246
+ }
247
+
248
+ /**
249
+ * Creates FirePHP object and stores it for singleton access
250
+ *
251
+ * @return FirePHP
252
+ */
253
+ public static function init() {
254
+ return self::$instance = new self();
255
+ }
256
+
257
+ /**
258
+ * Enable and disable logging to Firebug
259
+ *
260
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
261
+ * @return void
262
+ */
263
+ public function setEnabled($Enabled) {
264
+ $this->enabled = $Enabled;
265
+ }
266
+
267
+ /**
268
+ * Check if logging is enabled
269
+ *
270
+ * @return boolean TRUE if enabled
271
+ */
272
+ public function getEnabled() {
273
+ return $this->enabled;
274
+ }
275
+
276
+ /**
277
+ * Specify a filter to be used when encoding an object
278
+ *
279
+ * Filters are used to exclude object members.
280
+ *
281
+ * @param string $Class The class name of the object
282
+ * @param array $Filter An array of members to exclude
283
+ * @return void
284
+ */
285
+ public function setObjectFilter($Class, $Filter) {
286
+ $this->objectFilters[strtolower($Class)] = $Filter;
287
+ }
288
+
289
+ /**
290
+ * Set some options for the library
291
+ *
292
+ * Options:
293
+ * - maxObjectDepth: The maximum depth to traverse objects (default: 10)
294
+ * - maxArrayDepth: The maximum depth to traverse arrays (default: 20)
295
+ * - useNativeJsonEncode: If true will use json_encode() (default: true)
296
+ * - includeLineNumbers: If true will include line numbers and filenames (default: true)
297
+ *
298
+ * @param array $Options The options to be set
299
+ * @return void
300
+ */
301
+ public function setOptions($Options) {
302
+ $this->options = array_merge($this->options,$Options);
303
+ }
304
+
305
+ /**
306
+ * Get options from the library
307
+ *
308
+ * @return array The currently set options
309
+ */
310
+ public function getOptions() {
311
+ return $this->options;
312
+ }
313
+
314
+ /**
315
+ * Register FirePHP as your error handler
316
+ *
317
+ * Will throw exceptions for each php error.
318
+ *
319
+ * @return mixed Returns a string containing the previously defined error handler (if any)
320
+ */
321
+ public function registerErrorHandler($throwErrorExceptions=true)
322
+ {
323
+ //NOTE: The following errors will not be caught by this error handler:
324
+ // E_ERROR, E_PARSE, E_CORE_ERROR,
325
+ // E_CORE_WARNING, E_COMPILE_ERROR,
326
+ // E_COMPILE_WARNING, E_STRICT
327
+
328
+ $this->throwErrorExceptions = $throwErrorExceptions;
329
+
330
+ return set_error_handler(array($this,'errorHandler'));
331
+ }
332
+
333
+ /**
334
+ * FirePHP's error handler
335
+ *
336
+ * Throws exception for each php error that will occur.
337
+ *
338
+ * @param int $errno
339
+ * @param string $errstr
340
+ * @param string $errfile
341
+ * @param int $errline
342
+ * @param array $errcontext
343
+ */
344
+ public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
345
+ {
346
+ // Don't throw exception if error reporting is switched off
347
+ if (error_reporting() == 0) {
348
+ return;
349
+ }
350
+ // Only throw exceptions for errors we are asking for
351
+ if (error_reporting() & $errno) {
352
+
353
+ $exception = new ErrorException($errstr, 0, $errno, $errfile, $errline);
354
+ if($this->throwErrorExceptions) {
355
+ throw $exception;
356
+ } else {
357
+ $this->fb($exception);
358
+ }
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Register FirePHP as your exception handler
364
+ *
365
+ * @return mixed Returns the name of the previously defined exception handler,
366
+ * or NULL on error.
367
+ * If no previous handler was defined, NULL is also returned.
368
+ */
369
+ public function registerExceptionHandler()
370
+ {
371
+ return set_exception_handler(array($this,'exceptionHandler'));
372
+ }
373
+
374
+ /**
375
+ * FirePHP's exception handler
376
+ *
377
+ * Logs all exceptions to your firebug console and then stops the script.
378
+ *
379
+ * @param Exception $Exception
380
+ * @throws Exception
381
+ */
382
+ function exceptionHandler($Exception) {
383
+
384
+ $this->inExceptionHandler = true;
385
+
386
+ header('HTTP/1.1 500 Internal Server Error');
387
+
388
+ $this->fb($Exception);
389
+
390
+ $this->inExceptionHandler = false;
391
+ }
392
+
393
+ /**
394
+ * Register FirePHP driver as your assert callback
395
+ *
396
+ * @param boolean $convertAssertionErrorsToExceptions
397
+ * @param boolean $throwAssertionExceptions
398
+ * @return mixed Returns the original setting or FALSE on errors
399
+ */
400
+ public function registerAssertionHandler($convertAssertionErrorsToExceptions=true, $throwAssertionExceptions=false)
401
+ {
402
+ $this->convertAssertionErrorsToExceptions = $convertAssertionErrorsToExceptions;
403
+ $this->throwAssertionExceptions = $throwAssertionExceptions;
404
+
405
+ if($throwAssertionExceptions && !$convertAssertionErrorsToExceptions) {
406
+ throw $this->newException('Cannot throw assertion exceptions as assertion errors are not being converted to exceptions!');
407
+ }
408
+
409
+ return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler'));
410
+ }
411
+
412
+ /**
413
+ * FirePHP's assertion handler
414
+ *
415
+ * Logs all assertions to your firebug console and then stops the script.
416
+ *
417
+ * @param string $file File source of assertion
418
+ * @param int $line Line source of assertion
419
+ * @param mixed $code Assertion code
420
+ */
421
+ public function assertionHandler($file, $line, $code)
422
+ {
423
+
424
+ if($this->convertAssertionErrorsToExceptions) {
425
+
426
+ $exception = new ErrorException('Assertion Failed - Code[ '.$code.' ]', 0, null, $file, $line);
427
+
428
+ if($this->throwAssertionExceptions) {
429
+ throw $exception;
430
+ } else {
431
+ $this->fb($exception);
432
+ }
433
+
434
+ } else {
435
+
436
+ $this->fb($code, 'Assertion Failed', FirePHP::ERROR, array('File'=>$file,'Line'=>$line));
437
+
438
+ }
439
+ }
440
+
441
+ /**
442
+ * Set custom processor url for FirePHP
443
+ *
444
+ * @param string $URL
445
+ */
446
+ public function setProcessorUrl($URL)
447
+ {
448
+ $this->setHeader('X-FirePHP-ProcessorURL', $URL);
449
+ }
450
+
451
+ /**
452
+ * Set custom renderer url for FirePHP
453
+ *
454
+ * @param string $URL
455
+ */
456
+ public function setRendererUrl($URL)
457
+ {
458
+ $this->setHeader('X-FirePHP-RendererURL', $URL);
459
+ }
460
+
461
+ /**
462
+ * Start a group for following messages.
463
+ *
464
+ * Options:
465
+ * Collapsed: [true|false]
466
+ * Color: [#RRGGBB|ColorName]
467
+ *
468
+ * @param string $Name
469
+ * @param array $Options OPTIONAL Instructions on how to log the group
470
+ * @return true
471
+ * @throws Exception
472
+ */
473
+ public function group($Name, $Options=null) {
474
+
475
+ if(!$Name) {
476
+ throw $this->newException('You must specify a label for the group!');
477
+ }
478
+
479
+ if($Options) {
480
+ if(!is_array($Options)) {
481
+ throw $this->newException('Options must be defined as an array!');
482
+ }
483
+ if(array_key_exists('Collapsed', $Options)) {
484
+ $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false';
485
+ }
486
+ }
487
+
488
+ return $this->fb(null, $Name, FirePHP::GROUP_START, $Options);
489
+ }
490
+
491
+ /**
492
+ * Ends a group you have started before
493
+ *
494
+ * @return true
495
+ * @throws Exception
496
+ */
497
+ public function groupEnd() {
498
+ return $this->fb(null, null, FirePHP::GROUP_END);
499
+ }
500
+
501
+ /**
502
+ * Log object with label to firebug console
503
+ *
504
+ * @see FirePHP::LOG
505
+ * @param mixes $Object
506
+ * @param string $Label
507
+ * @return true
508
+ * @throws Exception
509
+ */
510
+ public function log($Object, $Label=null) {
511
+ return $this->fb($Object, $Label, FirePHP::LOG);
512
+ }
513
+
514
+ /**
515
+ * Log object with label to firebug console
516
+ *
517
+ * @see FirePHP::INFO
518
+ * @param mixes $Object
519
+ * @param string $Label
520
+ * @return true
521
+ * @throws Exception
522
+ */
523
+ public function info($Object, $Label=null) {
524
+ return $this->fb($Object, $Label, FirePHP::INFO);
525
+ }
526
+
527
+ /**
528
+ * Log object with label to firebug console
529
+ *
530
+ * @see FirePHP::WARN
531
+ * @param mixes $Object
532
+ * @param string $Label
533
+ * @return true
534
+ * @throws Exception
535
+ */
536
+ public function warn($Object, $Label=null) {
537
+ return $this->fb($Object, $Label, FirePHP::WARN);
538
+ }
539
+
540
+ /**
541
+ * Log object with label to firebug console
542
+ *
543
+ * @see FirePHP::ERROR
544
+ * @param mixes $Object
545
+ * @param string $Label
546
+ * @return true
547
+ * @throws Exception
548
+ */
549
+ public function error($Object, $Label=null) {
550
+ return $this->fb($Object, $Label, FirePHP::ERROR);
551
+ }
552
+
553
+ /**
554
+ * Dumps key and variable to firebug server panel
555
+ *
556
+ * @see FirePHP::DUMP
557
+ * @param string $Key
558
+ * @param mixed $Variable
559
+ * @return true
560
+ * @throws Exception
561
+ */
562
+ public function dump($Key, $Variable) {
563
+ return $this->fb($Variable, $Key, FirePHP::DUMP);
564
+ }
565
+
566
+ /**
567
+ * Log a trace in the firebug console
568
+ *
569
+ * @see FirePHP::TRACE
570
+ * @param string $Label
571
+ * @return true
572
+ * @throws Exception
573
+ */
574
+ public function trace($Label) {
575
+ return $this->fb($Label, FirePHP::TRACE);
576
+ }
577
+
578
+ /**
579
+ * Log a table in the firebug console
580
+ *
581
+ * @see FirePHP::TABLE
582
+ * @param string $Label
583
+ * @param string $Table
584
+ * @return true
585
+ * @throws Exception
586
+ */
587
+ public function table($Label, $Table) {
588
+ return $this->fb($Table, $Label, FirePHP::TABLE);
589
+ }
590
+
591
+ /**
592
+ * Check if FirePHP is installed on client
593
+ *
594
+ * @return boolean
595
+ */
596
+ public function detectClientExtension() {
597
+ /* Check if FirePHP is installed on client */
598
+ if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) ||
599
+ !version_compare($m[1][0],'0.0.6','>=')) {
600
+ return false;
601
+ }
602
+ return true;
603
+ }
604
+
605
+ /**
606
+ * Log varible to Firebug
607
+ *
608
+ * @see http://www.firephp.org/Wiki/Reference/Fb
609
+ * @param mixed $Object The variable to be logged
610
+ * @return true Return TRUE if message was added to headers, FALSE otherwise
611
+ * @throws Exception
612
+ */
613
+ public function fb($Object) {
614
+
615
+ if(!$this->enabled) {
616
+ return false;
617
+ }
618
+
619
+ if (headers_sent($filename, $linenum)) {
620
+ // If we are logging from within the exception handler we cannot throw another exception
621
+ if($this->inExceptionHandler) {
622
+ // Simply echo the error out to the page
623
+ echo '<div style="border: 2px solid red; font-family: Arial; font-size: 12px; background-color: lightgray; padding: 5px;"><span style="color: red; font-weight: bold;">FirePHP ERROR:</span> Headers already sent in <b>'.$filename.'</b> on line <b>'.$linenum.'</b>. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.</div>';
624
+ } else {
625
+ throw $this->newException('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.');
626
+ }
627
+ }
628
+
629
+ $Type = null;
630
+ $Label = null;
631
+ $Options = array();
632
+
633
+ if(func_num_args()==1) {
634
+ } else
635
+ if(func_num_args()==2) {
636
+ switch(func_get_arg(1)) {
637
+ case self::LOG:
638
+ case self::INFO:
639
+ case self::WARN:
640
+ case self::ERROR:
641
+ case self::DUMP:
642
+ case self::TRACE:
643
+ case self::EXCEPTION:
644
+ case self::TABLE:
645
+ case self::GROUP_START:
646
+ case self::GROUP_END:
647
+ $Type = func_get_arg(1);
648
+ break;
649
+ default:
650
+ $Label = func_get_arg(1);
651
+ break;
652
+ }
653
+ } else
654
+ if(func_num_args()==3) {
655
+ $Type = func_get_arg(2);
656
+ $Label = func_get_arg(1);
657
+ } else
658
+ if(func_num_args()==4) {
659
+ $Type = func_get_arg(2);
660
+ $Label = func_get_arg(1);
661
+ $Options = func_get_arg(3);
662
+ } else {
663
+ throw $this->newException('Wrong number of arguments to fb() function!');
664
+ }
665
+
666
+
667
+ if(!$this->detectClientExtension()) {
668
+ return false;
669
+ }
670
+
671
+ $meta = array();
672
+ $skipFinalObjectEncode = false;
673
+
674
+ if($Object instanceof Exception) {
675
+
676
+ $meta['file'] = $this->_escapeTraceFile($Object->getFile());
677
+ $meta['line'] = $Object->getLine();
678
+
679
+ $trace = $Object->getTrace();
680
+ if($Object instanceof ErrorException
681
+ && isset($trace[0]['function'])
682
+ && $trace[0]['function']=='errorHandler'
683
+ && isset($trace[0]['class'])
684
+ && $trace[0]['class']=='FirePHP') {
685
+
686
+ $severity = false;
687
+ switch($Object->getSeverity()) {
688
+ case E_WARNING: $severity = 'E_WARNING'; break;
689
+ case E_NOTICE: $severity = 'E_NOTICE'; break;
690
+ case E_USER_ERROR: $severity = 'E_USER_ERROR'; break;
691
+ case E_USER_WARNING: $severity = 'E_USER_WARNING'; break;
692
+ case E_USER_NOTICE: $severity = 'E_USER_NOTICE'; break;
693
+ case E_STRICT: $severity = 'E_STRICT'; break;
694
+ case E_RECOVERABLE_ERROR: $severity = 'E_RECOVERABLE_ERROR'; break;
695
+ case E_DEPRECATED: $severity = 'E_DEPRECATED'; break;
696
+ case E_USER_DEPRECATED: $severity = 'E_USER_DEPRECATED'; break;
697
+ }
698
+
699
+ $Object = array('Class'=>get_class($Object),
700
+ 'Message'=>$severity.': '.$Object->getMessage(),
701
+ 'File'=>$this->_escapeTraceFile($Object->getFile()),
702
+ 'Line'=>$Object->getLine(),
703
+ 'Type'=>'trigger',
704
+ 'Trace'=>$this->_escapeTrace(array_splice($trace,2)));
705
+ $skipFinalObjectEncode = true;
706
+ } else {
707
+ $Object = array('Class'=>get_class($Object),
708
+ 'Message'=>$Object->getMessage(),
709
+ 'File'=>$this->_escapeTraceFile($Object->getFile()),
710
+ 'Line'=>$Object->getLine(),
711
+ 'Type'=>'throw',
712
+ 'Trace'=>$this->_escapeTrace($trace));
713
+ $skipFinalObjectEncode = true;
714
+ }
715
+ $Type = self::EXCEPTION;
716
+
717
+ } else
718
+ if($Type==self::TRACE) {
719
+
720
+ $trace = debug_backtrace();
721
+ if(!$trace) return false;
722
+ for( $i=0 ; $i<sizeof($trace) ; $i++ ) {
723
+
724
+ if(isset($trace[$i]['class'])
725
+ && isset($trace[$i]['file'])
726
+ && ($trace[$i]['class']=='FirePHP'
727
+ || $trace[$i]['class']=='FB')
728
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
729
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
730
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
731
+ } else
732
+ if(isset($trace[$i]['class'])
733
+ && isset($trace[$i+1]['file'])
734
+ && $trace[$i]['class']=='FirePHP'
735
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
736
+ /* Skip fb() */
737
+ } else
738
+ if($trace[$i]['function']=='fb'
739
+ || $trace[$i]['function']=='trace'
740
+ || $trace[$i]['function']=='send') {
741
+ $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'',
742
+ 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'',
743
+ 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'',
744
+ 'Message'=>$trace[$i]['args'][0],
745
+ 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'',
746
+ 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'',
747
+ 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'',
748
+ 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1)));
749
+
750
+ $skipFinalObjectEncode = true;
751
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
752
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
753
+ break;
754
+ }
755
+ }
756
+
757
+ } else
758
+ if($Type==self::TABLE) {
759
+
760
+ if(isset($Object[0]) && is_string($Object[0])) {
761
+ $Object[1] = $this->encodeTable($Object[1]);
762
+ } else {
763
+ $Object = $this->encodeTable($Object);
764
+ }
765
+
766
+ $skipFinalObjectEncode = true;
767
+
768
+ } else
769
+ if($Type==self::GROUP_START) {
770
+
771
+ if(!$Label) {
772
+ throw $this->newException('You must specify a label for the group!');
773
+ }
774
+
775
+ } else {
776
+ if($Type===null) {
777
+ $Type = self::LOG;
778
+ }
779
+ }
780
+
781
+ if($this->options['includeLineNumbers']) {
782
+ if(!isset($meta['file']) || !isset($meta['line'])) {
783
+
784
+ $trace = debug_backtrace();
785
+ for( $i=0 ; $trace && $i<sizeof($trace) ; $i++ ) {
786
+
787
+ if(isset($trace[$i]['class'])
788
+ && isset($trace[$i]['file'])
789
+ && ($trace[$i]['class']=='FirePHP'
790
+ || $trace[$i]['class']=='FB')
791
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
792
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
793
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
794
+ } else
795
+ if(isset($trace[$i]['class'])
796
+ && isset($trace[$i+1]['file'])
797
+ && $trace[$i]['class']=='FirePHP'
798
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
799
+ /* Skip fb() */
800
+ } else
801
+ if(isset($trace[$i]['file'])
802
+ && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') {
803
+ /* Skip FB::fb() */
804
+ } else {
805
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
806
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
807
+ break;
808
+ }
809
+ }
810
+
811
+ }
812
+ } else {
813
+ unset($meta['file']);
814
+ unset($meta['line']);
815
+ }
816
+
817
+ $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
818
+ $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.self::VERSION);
819
+
820
+ $structure_index = 1;
821
+ if($Type==self::DUMP) {
822
+ $structure_index = 2;
823
+ $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
824
+ } else {
825
+ $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
826
+ }
827
+
828
+ if($Type==self::DUMP) {
829
+ $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}';
830
+ } else {
831
+ $msg_meta = $Options;
832
+ $msg_meta['Type'] = $Type;
833
+ if($Label!==null) {
834
+ $msg_meta['Label'] = $Label;
835
+ }
836
+ if(isset($meta['file']) && !isset($msg_meta['File'])) {
837
+ $msg_meta['File'] = $meta['file'];
838
+ }
839
+ if(isset($meta['line']) && !isset($msg_meta['Line'])) {
840
+ $msg_meta['Line'] = $meta['line'];
841
+ }
842
+ $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']';
843
+ }
844
+
845
+ $parts = explode("\n",chunk_split($msg, 5000, "\n"));
846
+
847
+ for( $i=0 ; $i<count($parts) ; $i++) {
848
+
849
+ $part = $parts[$i];
850
+ if ($part) {
851
+
852
+ if(count($parts)>2) {
853
+ // Message needs to be split into multiple parts
854
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
855
+ (($i==0)?strlen($msg):'')
856
+ . '|' . $part . '|'
857
+ . (($i<count($parts)-2)?'\\':''));
858
+ } else {
859
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
860
+ strlen($part) . '|' . $part . '|');
861
+ }
862
+
863
+ $this->messageIndex++;
864
+
865
+ if ($this->messageIndex > 99999) {
866
+ throw $this->newException('Maximum number (99,999) of messages reached!');
867
+ }
868
+ }
869
+ }
870
+
871
+ $this->setHeader('X-Wf-1-Index',$this->messageIndex-1);
872
+
873
+ return true;
874
+ }
875
+
876
+ /**
877
+ * Standardizes path for windows systems.
878
+ *
879
+ * @param string $Path
880
+ * @return string
881
+ */
882
+ protected function _standardizePath($Path) {
883
+ return preg_replace('/\\\\+/','/',$Path);
884
+ }
885
+
886
+ /**
887
+ * Escape trace path for windows systems
888
+ *
889
+ * @param array $Trace
890
+ * @return array
891
+ */
892
+ protected function _escapeTrace($Trace) {
893
+ if(!$Trace) return $Trace;
894
+ for( $i=0 ; $i<sizeof($Trace) ; $i++ ) {
895
+ if(isset($Trace[$i]['file'])) {
896
+ $Trace[$i]['file'] = $this->_escapeTraceFile($Trace[$i]['file']);
897
+ }
898
+ if(isset($Trace[$i]['args'])) {
899
+ $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']);
900
+ }
901
+ }
902
+ return $Trace;
903
+ }
904
+
905
+ /**
906
+ * Escape file information of trace for windows systems
907
+ *
908
+ * @param string $File
909
+ * @return string
910
+ */
911
+ protected function _escapeTraceFile($File) {
912
+ /* Check if we have a windows filepath */
913
+ if(strpos($File,'\\')) {
914
+ /* First strip down to single \ */
915
+
916
+ $file = preg_replace('/\\\\+/','\\',$File);
917
+
918
+ return $file;
919
+ }
920
+ return $File;
921
+ }
922
+
923
+ /**
924
+ * Send header
925
+ *
926
+ * @param string $Name
927
+ * @param string_type $Value
928
+ */
929
+ protected function setHeader($Name, $Value) {
930
+ return header($Name.': '.$Value);
931
+ }
932
+
933
+ /**
934
+ * Get user agent
935
+ *
936
+ * @return string|false
937
+ */
938
+ protected function getUserAgent() {
939
+ if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
940
+ return $_SERVER['HTTP_USER_AGENT'];
941
+ }
942
+
943
+ /**
944
+ * Returns a new exception
945
+ *
946
+ * @param string $Message
947
+ * @return Exception
948
+ */
949
+ protected function newException($Message) {
950
+ return new Exception($Message);
951
+ }
952
+
953
+ /**
954
+ * Encode an object into a JSON string
955
+ *
956
+ * Uses PHP's jeson_encode() if available
957
+ *
958
+ * @param object $Object The object to be encoded
959
+ * @return string The JSON string
960
+ */
961
+ public function jsonEncode($Object, $skipObjectEncode=false)
962
+ {
963
+ if(!$skipObjectEncode) {
964
+ $Object = $this->encodeObject($Object);
965
+ }
966
+
967
+ if(function_exists('json_encode')
968
+ && $this->options['useNativeJsonEncode']!=false) {
969
+
970
+ return json_encode($Object);
971
+ } else {
972
+ return $this->json_encode($Object);
973
+ }
974
+ }
975
+
976
+ /**
977
+ * Encodes a table by encoding each row and column with encodeObject()
978
+ *
979
+ * @param array $Table The table to be encoded
980
+ * @return array
981
+ */
982
+ protected function encodeTable($Table) {
983
+
984
+ if(!$Table) return $Table;
985
+
986
+ $new_table = array();
987
+ foreach($Table as $row) {
988
+
989
+ if(is_array($row)) {
990
+ $new_row = array();
991
+
992
+ foreach($row as $item) {
993
+ $new_row[] = $this->encodeObject($item);
994
+ }
995
+
996
+ $new_table[] = $new_row;
997
+ }
998
+ }
999
+
1000
+ return $new_table;
1001
+ }
1002
+
1003
+ /**
1004
+ * Encodes an object including members with
1005
+ * protected and private visibility
1006
+ *
1007
+ * @param Object $Object The object to be encoded
1008
+ * @param int $Depth The current traversal depth
1009
+ * @return array All members of the object
1010
+ */
1011
+ protected function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1)
1012
+ {
1013
+ $return = array();
1014
+
1015
+ if (is_resource($Object)) {
1016
+
1017
+ return '** '.(string)$Object.' **';
1018
+
1019
+ } else
1020
+ if (is_object($Object)) {
1021
+
1022
+ if ($ObjectDepth > $this->options['maxObjectDepth']) {
1023
+ return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **';
1024
+ }
1025
+
1026
+ foreach ($this->objectStack as $refVal) {
1027
+ if ($refVal === $Object) {
1028
+ return '** Recursion ('.get_class($Object).') **';
1029
+ }
1030
+ }
1031
+ array_push($this->objectStack, $Object);
1032
+
1033
+ $return['__className'] = $class = get_class($Object);
1034
+ $class_lower = strtolower($class);
1035
+
1036
+ $reflectionClass = new ReflectionClass($class);
1037
+ $properties = array();
1038
+ foreach( $reflectionClass->getProperties() as $property) {
1039
+ $properties[$property->getName()] = $property;
1040
+ }
1041
+
1042
+ $members = (array)$Object;
1043
+
1044
+ foreach( $properties as $raw_name => $property ) {
1045
+
1046
+ $name = $raw_name;
1047
+ if($property->isStatic()) {
1048
+ $name = 'static:'.$name;
1049
+ }
1050
+ if($property->isPublic()) {
1051
+ $name = 'public:'.$name;
1052
+ } else
1053
+ if($property->isPrivate()) {
1054
+ $name = 'private:'.$name;
1055
+ $raw_name = "\0".$class."\0".$raw_name;
1056
+ } else
1057
+ if($property->isProtected()) {
1058
+ $name = 'protected:'.$name;
1059
+ $raw_name = "\0".'*'."\0".$raw_name;
1060
+ }
1061
+
1062
+ if(!(isset($this->objectFilters[$class_lower])
1063
+ && is_array($this->objectFilters[$class_lower])
1064
+ && in_array($raw_name,$this->objectFilters[$class_lower]))) {
1065
+
1066
+ if(array_key_exists($raw_name,$members)
1067
+ && !$property->isStatic()) {
1068
+
1069
+ $return[$name] = $this->encodeObject($members[$raw_name], $ObjectDepth + 1, 1);
1070
+
1071
+ } else {
1072
+ if(method_exists($property,'setAccessible')) {
1073
+ $property->setAccessible(true);
1074
+ $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1);
1075
+ } else
1076
+ if($property->isPublic()) {
1077
+ $return[$name] = $this->encodeObject($property->getValue($Object), $ObjectDepth + 1, 1);
1078
+ } else {
1079
+ $return[$name] = '** Need PHP 5.3 to get value **';
1080
+ }
1081
+ }
1082
+ } else {
1083
+ $return[$name] = '** Excluded by Filter **';
1084
+ }
1085
+ }
1086
+
1087
+ // Include all members that are not defined in the class
1088
+ // but exist in the object
1089
+ foreach( $members as $raw_name => $value ) {
1090
+
1091
+ $name = $raw_name;
1092
+
1093
+ if ($name{0} == "\0") {
1094
+ $parts = explode("\0", $name);
1095
+ $name = $parts[2];
1096
+ }
1097
+
1098
+ if(!isset($properties[$name])) {
1099
+ $name = 'undeclared:'.$name;
1100
+
1101
+ if(!(isset($this->objectFilters[$class_lower])
1102
+ && is_array($this->objectFilters[$class_lower])
1103
+ && in_array($raw_name,$this->objectFilters[$class_lower]))) {
1104
+
1105
+ $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1);
1106
+ } else {
1107
+ $return[$name] = '** Excluded by Filter **';
1108
+ }
1109
+ }
1110
+ }
1111
+
1112
+ array_pop($this->objectStack);
1113
+
1114
+ } elseif (is_array($Object)) {
1115
+
1116
+ if ($ArrayDepth > $this->options['maxArrayDepth']) {
1117
+ return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **';
1118
+ }
1119
+
1120
+ foreach ($Object as $key => $val) {
1121
+
1122
+ // Encoding the $GLOBALS PHP array causes an infinite loop
1123
+ // if the recursion is not reset here as it contains
1124
+ // a reference to itself. This is the only way I have come up
1125
+ // with to stop infinite recursion in this case.
1126
+ if($key=='GLOBALS'
1127
+ && is_array($val)
1128
+ && array_key_exists('GLOBALS',$val)) {
1129
+ $val['GLOBALS'] = '** Recursion (GLOBALS) **';
1130
+ }
1131
+
1132
+ $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1);
1133
+ }
1134
+ } else {
1135
+ if(self::is_utf8($Object)) {
1136
+ return $Object;
1137
+ } else {
1138
+ return utf8_encode($Object);
1139
+ }
1140
+ }
1141
+ return $return;
1142
+ }
1143
+
1144
+ /**
1145
+ * Returns true if $string is valid UTF-8 and false otherwise.
1146
+ *
1147
+ * @param mixed $str String to be tested
1148
+ * @return boolean
1149
+ */
1150
+ protected static function is_utf8($str) {
1151
+ $c=0; $b=0;
1152
+ $bits=0;
1153
+ $len=strlen($str);
1154
+ for($i=0; $i<$len; $i++){
1155
+ $c=ord($str[$i]);
1156
+ if($c > 128){
1157
+ if(($c >= 254)) return false;
1158
+ elseif($c >= 252) $bits=6;
1159
+ elseif($c >= 248) $bits=5;
1160
+ elseif($c >= 240) $bits=4;
1161
+ elseif($c >= 224) $bits=3;
1162
+ elseif($c >= 192) $bits=2;
1163
+ else return false;
1164
+ if(($i+$bits) > $len) return false;
1165
+ while($bits > 1){
1166
+ $i++;
1167
+ $b=ord($str[$i]);
1168
+ if($b < 128 || $b > 191) return false;
1169
+ $bits--;
1170
+ }
1171
+ }
1172
+ }
1173
+ return true;
1174
+ }
1175
+
1176
+ /**
1177
+ * Converts to and from JSON format.
1178
+ *
1179
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
1180
+ * format. It is easy for humans to read and write. It is easy for machines
1181
+ * to parse and generate. It is based on a subset of the JavaScript
1182
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
1183
+ * This feature can also be found in Python. JSON is a text format that is
1184
+ * completely language independent but uses conventions that are familiar
1185
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
1186
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
1187
+ * ideal data-interchange language.
1188
+ *
1189
+ * This package provides a simple encoder and decoder for JSON notation. It
1190
+ * is intended for use with client-side Javascript applications that make
1191
+ * use of HTTPRequest to perform server communication functions - data can
1192
+ * be encoded into JSON notation for use in a client-side javascript, or
1193
+ * decoded from incoming Javascript requests. JSON format is native to
1194
+ * Javascript, and can be directly eval()'ed with no further parsing
1195
+ * overhead
1196
+ *
1197
+ * All strings should be in ASCII or UTF-8 format!
1198
+ *
1199
+ * LICENSE: Redistribution and use in source and binary forms, with or
1200
+ * without modification, are permitted provided that the following
1201
+ * conditions are met: Redistributions of source code must retain the
1202
+ * above copyright notice, this list of conditions and the following
1203
+ * disclaimer. Redistributions in binary form must reproduce the above
1204
+ * copyright notice, this list of conditions and the following disclaimer
1205
+ * in the documentation and/or other materials provided with the
1206
+ * distribution.
1207
+ *
1208
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1209
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1210
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1211
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
1212
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
1213
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
1214
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1215
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1216
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1217
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1218
+ * DAMAGE.
1219
+ *
1220
+ * @category
1221
+ * @package Services_JSON
1222
+ * @author Michal Migurski <mike-json@teczno.com>
1223
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
1224
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
1225
+ * @author Christoph Dorn <christoph@christophdorn.com>
1226
+ * @copyright 2005 Michal Migurski
1227
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
1228
+ * @license http://www.opensource.org/licenses/bsd-license.php
1229
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
1230
+ */
1231
+
1232
+
1233
+ /**
1234
+ * Keep a list of objects as we descend into the array so we can detect recursion.
1235
+ */
1236
+ private $json_objectStack = array();
1237
+
1238
+
1239
+ /**
1240
+ * convert a string from one UTF-8 char to one UTF-16 char
1241
+ *
1242
+ * Normally should be handled by mb_convert_encoding, but
1243
+ * provides a slower PHP-only method for installations
1244
+ * that lack the multibye string extension.
1245
+ *
1246
+ * @param string $utf8 UTF-8 character
1247
+ * @return string UTF-16 character
1248
+ * @access private
1249
+ */
1250
+ private function json_utf82utf16($utf8)
1251
+ {
1252
+ // oh please oh please oh please oh please oh please
1253
+ if(function_exists('mb_convert_encoding')) {
1254
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
1255
+ }
1256
+
1257
+ switch(strlen($utf8)) {
1258
+ case 1:
1259
+ // this case should never be reached, because we are in ASCII range
1260
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1261
+ return $utf8;
1262
+
1263
+ case 2:
1264
+ // return a UTF-16 character from a 2-byte UTF-8 char
1265
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1266
+ return chr(0x07 & (ord($utf8{0}) >> 2))
1267
+ . chr((0xC0 & (ord($utf8{0}) << 6))
1268
+ | (0x3F & ord($utf8{1})));
1269
+
1270
+ case 3:
1271
+ // return a UTF-16 character from a 3-byte UTF-8 char
1272
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1273
+ return chr((0xF0 & (ord($utf8{0}) << 4))
1274
+ | (0x0F & (ord($utf8{1}) >> 2)))
1275
+ . chr((0xC0 & (ord($utf8{1}) << 6))
1276
+ | (0x7F & ord($utf8{2})));
1277
+ }
1278
+
1279
+ // ignoring UTF-32 for now, sorry
1280
+ return '';
1281
+ }
1282
+
1283
+ /**
1284
+ * encodes an arbitrary variable into JSON format
1285
+ *
1286
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
1287
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
1288
+ * if var is a strng, note that encode() always expects it
1289
+ * to be in ASCII or UTF-8 format!
1290
+ *
1291
+ * @return mixed JSON string representation of input var or an error if a problem occurs
1292
+ * @access public
1293
+ */
1294
+ private function json_encode($var)
1295
+ {
1296
+
1297
+ if(is_object($var)) {
1298
+ if(in_array($var,$this->json_objectStack)) {
1299
+ return '"** Recursion **"';
1300
+ }
1301
+ }
1302
+
1303
+ switch (gettype($var)) {
1304
+ case 'boolean':
1305
+ return $var ? 'true' : 'false';
1306
+
1307
+ case 'NULL':
1308
+ return 'null';
1309
+
1310
+ case 'integer':
1311
+ return (int) $var;
1312
+
1313
+ case 'double':
1314
+ case 'float':
1315
+ return (float) $var;
1316
+
1317
+ case 'string':
1318
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
1319
+ $ascii = '';
1320
+ $strlen_var = strlen($var);
1321
+
1322
+ /*
1323
+ * Iterate over every character in the string,
1324
+ * escaping with a slash or encoding to UTF-8 where necessary
1325
+ */
1326
+ for ($c = 0; $c < $strlen_var; ++$c) {
1327
+
1328
+ $ord_var_c = ord($var{$c});
1329
+
1330
+ switch (true) {
1331
+ case $ord_var_c == 0x08:
1332
+ $ascii .= '\b';
1333
+ break;
1334
+ case $ord_var_c == 0x09:
1335
+ $ascii .= '\t';
1336
+ break;
1337
+ case $ord_var_c == 0x0A:
1338
+ $ascii .= '\n';
1339
+ break;
1340
+ case $ord_var_c == 0x0C:
1341
+ $ascii .= '\f';
1342
+ break;
1343
+ case $ord_var_c == 0x0D:
1344
+ $ascii .= '\r';
1345
+ break;
1346
+
1347
+ case $ord_var_c == 0x22:
1348
+ case $ord_var_c == 0x2F:
1349
+ case $ord_var_c == 0x5C:
1350
+ // double quote, slash, slosh
1351
+ $ascii .= '\\'.$var{$c};
1352
+ break;
1353
+
1354
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
1355
+ // characters U-00000000 - U-0000007F (same as ASCII)
1356
+ $ascii .= $var{$c};
1357
+ break;
1358
+
1359
+ case (($ord_var_c & 0xE0) == 0xC0):
1360
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
1361
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1362
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
1363
+ $c += 1;
1364
+ $utf16 = $this->json_utf82utf16($char);
1365
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1366
+ break;
1367
+
1368
+ case (($ord_var_c & 0xF0) == 0xE0):
1369
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
1370
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1371
+ $char = pack('C*', $ord_var_c,
1372
+ ord($var{$c + 1}),
1373
+ ord($var{$c + 2}));
1374
+ $c += 2;
1375
+ $utf16 = $this->json_utf82utf16($char);
1376
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1377
+ break;
1378
+
1379
+ case (($ord_var_c & 0xF8) == 0xF0):
1380
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
1381
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1382
+ $char = pack('C*', $ord_var_c,
1383
+ ord($var{$c + 1}),
1384
+ ord($var{$c + 2}),
1385
+ ord($var{$c + 3}));
1386
+ $c += 3;
1387
+ $utf16 = $this->json_utf82utf16($char);
1388
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1389
+ break;
1390
+
1391
+ case (($ord_var_c & 0xFC) == 0xF8):
1392
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
1393
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1394
+ $char = pack('C*', $ord_var_c,
1395
+ ord($var{$c + 1}),
1396
+ ord($var{$c + 2}),
1397
+ ord($var{$c + 3}),
1398
+ ord($var{$c + 4}));
1399
+ $c += 4;
1400
+ $utf16 = $this->json_utf82utf16($char);
1401
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1402
+ break;
1403
+
1404
+ case (($ord_var_c & 0xFE) == 0xFC):
1405
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
1406
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1407
+ $char = pack('C*', $ord_var_c,
1408
+ ord($var{$c + 1}),
1409
+ ord($var{$c + 2}),
1410
+ ord($var{$c + 3}),
1411
+ ord($var{$c + 4}),
1412
+ ord($var{$c + 5}));
1413
+ $c += 5;
1414
+ $utf16 = $this->json_utf82utf16($char);
1415
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1416
+ break;
1417
+ }
1418
+ }
1419
+
1420
+ return '"'.$ascii.'"';
1421
+
1422
+ case 'array':
1423
+ /*
1424
+ * As per JSON spec if any array key is not an integer
1425
+ * we must treat the the whole array as an object. We
1426
+ * also try to catch a sparsely populated associative
1427
+ * array with numeric keys here because some JS engines
1428
+ * will create an array with empty indexes up to
1429
+ * max_index which can cause memory issues and because
1430
+ * the keys, which may be relevant, will be remapped
1431
+ * otherwise.
1432
+ *
1433
+ * As per the ECMA and JSON specification an object may
1434
+ * have any string as a property. Unfortunately due to
1435
+ * a hole in the ECMA specification if the key is a
1436
+ * ECMA reserved word or starts with a digit the
1437
+ * parameter is only accessible using ECMAScript's
1438
+ * bracket notation.
1439
+ */
1440
+
1441
+ // treat as a JSON object
1442
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
1443
+
1444
+ $this->json_objectStack[] = $var;
1445
+
1446
+ $properties = array_map(array($this, 'json_name_value'),
1447
+ array_keys($var),
1448
+ array_values($var));
1449
+
1450
+ array_pop($this->json_objectStack);
1451
+
1452
+ foreach($properties as $property) {
1453
+ if($property instanceof Exception) {
1454
+ return $property;
1455
+ }
1456
+ }
1457
+
1458
+ return '{' . join(',', $properties) . '}';
1459
+ }
1460
+
1461
+ $this->json_objectStack[] = $var;
1462
+
1463
+ // treat it like a regular array
1464
+ $elements = array_map(array($this, 'json_encode'), $var);
1465
+
1466
+ array_pop($this->json_objectStack);
1467
+
1468
+ foreach($elements as $element) {
1469
+ if($element instanceof Exception) {
1470
+ return $element;
1471
+ }
1472
+ }
1473
+
1474
+ return '[' . join(',', $elements) . ']';
1475
+
1476
+ case 'object':
1477
+ $vars = self::encodeObject($var);
1478
+
1479
+ $this->json_objectStack[] = $var;
1480
+
1481
+ $properties = array_map(array($this, 'json_name_value'),
1482
+ array_keys($vars),
1483
+ array_values($vars));
1484
+
1485
+ array_pop($this->json_objectStack);
1486
+
1487
+ foreach($properties as $property) {
1488
+ if($property instanceof Exception) {
1489
+ return $property;
1490
+ }
1491
+ }
1492
+
1493
+ return '{' . join(',', $properties) . '}';
1494
+
1495
+ default:
1496
+ return null;
1497
+ }
1498
+ }
1499
+
1500
+ /**
1501
+ * array-walking function for use in generating JSON-formatted name-value pairs
1502
+ *
1503
+ * @param string $name name of key to use
1504
+ * @param mixed $value reference to an array element to be encoded
1505
+ *
1506
+ * @return string JSON-formatted name-value pair, like '"name":value'
1507
+ * @access private
1508
+ */
1509
+ private function json_name_value($name, $value)
1510
+ {
1511
+ // Encoding the $GLOBALS PHP array causes an infinite loop
1512
+ // if the recursion is not reset here as it contains
1513
+ // a reference to itself. This is the only way I have come up
1514
+ // with to stop infinite recursion in this case.
1515
+ if($name=='GLOBALS'
1516
+ && is_array($value)
1517
+ && array_key_exists('GLOBALS',$value)) {
1518
+ $value['GLOBALS'] = '** Recursion **';
1519
+ }
1520
+
1521
+ $encoded_value = $this->json_encode($value);
1522
+
1523
+ if($encoded_value instanceof Exception) {
1524
+ return $encoded_value;
1525
+ }
1526
+
1527
+ return $this->json_encode(strval($name)) . ':' . $encoded_value;
1528
+ }
1529
+ }
FirePHPCore/FirePHP.class.php4 ADDED
@@ -0,0 +1,1292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * *** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2009, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * This verion of FirePHPCore is for use with PHP4. If you do not require PHP4
40
+ * compatibility, it is suggested you use FirePHPCore.class.php instead.
41
+ *
42
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
43
+ * @author Christoph Dorn <christoph@christophdorn.com>
44
+ * @author Michael Day <manveru.alma@gmail.com>
45
+ * @license http://www.opensource.org/licenses/bsd-license.php
46
+ * @package FirePHP
47
+ */
48
+
49
+ /**
50
+ * FirePHP version
51
+ *
52
+ * @var string
53
+ */
54
+ define('FirePHP_VERSION', '0.3');
55
+
56
+ /**
57
+ * Firebug LOG level
58
+ *
59
+ * Logs a message to firebug console
60
+ *
61
+ * @var string
62
+ */
63
+ define('FirePHP_LOG', 'LOG');
64
+
65
+ /**
66
+ * Firebug INFO level
67
+ *
68
+ * Logs a message to firebug console and displays an info icon before the message
69
+ *
70
+ * @var string
71
+ */
72
+ define('FirePHP_INFO', 'INFO');
73
+
74
+ /**
75
+ * Firebug WARN level
76
+ *
77
+ * Logs a message to firebug console, displays a warning icon before the message and colors the line turquoise
78
+ *
79
+ * @var string
80
+ */
81
+ define('FirePHP_WARN', 'WARN');
82
+
83
+ /**
84
+ * Firebug ERROR level
85
+ *
86
+ * Logs a message to firebug console, displays an error icon before the message and colors the line yellow. Also increments the firebug error count.
87
+ *
88
+ * @var string
89
+ */
90
+ define('FirePHP_ERROR', 'ERROR');
91
+
92
+ /**
93
+ * Dumps a variable to firebug's server panel
94
+ *
95
+ * @var string
96
+ */
97
+ define('FirePHP_DUMP', 'DUMP');
98
+
99
+ /**
100
+ * Displays a stack trace in firebug console
101
+ *
102
+ * @var string
103
+ */
104
+ define('FirePHP_TRACE', 'TRACE');
105
+
106
+ /**
107
+ * Displays a table in firebug console
108
+ *
109
+ * @var string
110
+ */
111
+ define('FirePHP_TABLE', 'TABLE');
112
+
113
+ /**
114
+ * Starts a group in firebug console
115
+ *
116
+ * @var string
117
+ */
118
+ define('FirePHP_GROUP_START', 'GROUP_START');
119
+
120
+ /**
121
+ * Ends a group in firebug console
122
+ *
123
+ * @var string
124
+ */
125
+ define('FirePHP_GROUP_END', 'GROUP_END');
126
+
127
+ /**
128
+ * Sends the given data to the FirePHP Firefox Extension.
129
+ * The data can be displayed in the Firebug Console or in the
130
+ * "Server" request tab.
131
+ *
132
+ * For more information see: http://www.firephp.org/
133
+ *
134
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
135
+ * @author Christoph Dorn <christoph@christophdorn.com>
136
+ * @author Michael Day <manveru.alma@gmail.com>
137
+ * @license http://www.opensource.org/licenses/bsd-license.php
138
+ * @package FirePHP
139
+ */
140
+ class FirePHP {
141
+ /**
142
+ * Wildfire protocol message index
143
+ *
144
+ * @var int
145
+ */
146
+ var $messageIndex = 1;
147
+
148
+ /**
149
+ * Options for the library
150
+ *
151
+ * @var array
152
+ */
153
+ var $options = array('maxObjectDepth' => 10,
154
+ 'maxArrayDepth' => 20,
155
+ 'useNativeJsonEncode' => true,
156
+ 'includeLineNumbers' => true);
157
+
158
+ /**
159
+ * Filters used to exclude object members when encoding
160
+ *
161
+ * @var array
162
+ */
163
+ var $objectFilters = array();
164
+
165
+ /**
166
+ * A stack of objects used to detect recursion during object encoding
167
+ *
168
+ * @var object
169
+ */
170
+ var $objectStack = array();
171
+
172
+ /**
173
+ * Flag to enable/disable logging
174
+ *
175
+ * @var boolean
176
+ */
177
+ var $enabled = true;
178
+
179
+ /**
180
+ * The object constructor
181
+ */
182
+ function FirePHP() {
183
+ }
184
+
185
+
186
+ /**
187
+ * When the object gets serialized only include specific object members.
188
+ *
189
+ * @return array
190
+ */
191
+ function __sleep() {
192
+ return array('options','objectFilters','enabled');
193
+ }
194
+
195
+ /**
196
+ * Gets singleton instance of FirePHP
197
+ *
198
+ * @param boolean $AutoCreate
199
+ * @return FirePHP
200
+ */
201
+ function &getInstance($AutoCreate=false) {
202
+ global $FirePHP_Instance;
203
+
204
+ if($AutoCreate===true && !$FirePHP_Instance) {
205
+ $FirePHP_Instance = new FirePHP();
206
+ }
207
+
208
+ return $FirePHP_Instance;
209
+ }
210
+
211
+ /**
212
+ * Enable and disable logging to Firebug
213
+ *
214
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
215
+ * @return void
216
+ */
217
+ function setEnabled($Enabled) {
218
+ $this->enabled = $Enabled;
219
+ }
220
+
221
+ /**
222
+ * Check if logging is enabled
223
+ *
224
+ * @return boolean TRUE if enabled
225
+ */
226
+ function getEnabled() {
227
+ return $this->enabled;
228
+ }
229
+
230
+ /**
231
+ * Specify a filter to be used when encoding an object
232
+ *
233
+ * Filters are used to exclude object members.
234
+ *
235
+ * @param string $Class The class name of the object
236
+ * @param array $Filter An array of members to exclude
237
+ * @return void
238
+ */
239
+ function setObjectFilter($Class, $Filter) {
240
+ $this->objectFilters[strtolower($Class)] = $Filter;
241
+ }
242
+
243
+ /**
244
+ * Set some options for the library
245
+ *
246
+ * Options:
247
+ * - maxObjectDepth: The maximum depth to traverse objects (default: 10)
248
+ * - maxArrayDepth: The maximum depth to traverse arrays (default: 20)
249
+ * - useNativeJsonEncode: If true will use json_encode() (default: true)
250
+ * - includeLineNumbers: If true will include line numbers and filenames (default: true)
251
+ *
252
+ * @param array $Options The options to be set
253
+ * @return void
254
+ */
255
+ function setOptions($Options) {
256
+ $this->options = array_merge($this->options,$Options);
257
+ }
258
+
259
+ /**
260
+ * Get options from the library
261
+ *
262
+ * @return array The currently set options
263
+ */
264
+ function getOptions() {
265
+ return $this->options;
266
+ }
267
+
268
+ /**
269
+ * Register FirePHP as your error handler
270
+ *
271
+ * Will use FirePHP to log each php error.
272
+ *
273
+ * @return mixed Returns a string containing the previously defined error handler (if any)
274
+ */
275
+ function registerErrorHandler()
276
+ {
277
+ //NOTE: The following errors will not be caught by this error handler:
278
+ // E_ERROR, E_PARSE, E_CORE_ERROR,
279
+ // E_CORE_WARNING, E_COMPILE_ERROR,
280
+ // E_COMPILE_WARNING, E_STRICT
281
+
282
+ return set_error_handler(array($this,'errorHandler'));
283
+ }
284
+
285
+ /**
286
+ * FirePHP's error handler
287
+ *
288
+ * Logs each php error that will occur.
289
+ *
290
+ * @param int $errno
291
+ * @param string $errstr
292
+ * @param string $errfile
293
+ * @param int $errline
294
+ * @param array $errcontext
295
+ */
296
+ function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
297
+ {
298
+ global $FirePHP_Instance;
299
+ // Don't log error if error reporting is switched off
300
+ if (error_reporting() == 0) {
301
+ return;
302
+ }
303
+ // Only log error for errors we are asking for
304
+ if (error_reporting() & $errno) {
305
+ $FirePHP_Instance->group($errstr);
306
+ $FirePHP_Instance->error("{$errfile}, line $errline");
307
+ $FirePHP_Instance->groupEnd();
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Register FirePHP driver as your assert callback
313
+ *
314
+ * @return mixed Returns the original setting
315
+ */
316
+ function registerAssertionHandler()
317
+ {
318
+ return assert_options(ASSERT_CALLBACK, array($this, 'assertionHandler'));
319
+ }
320
+
321
+ /**
322
+ * FirePHP's assertion handler
323
+ *
324
+ * Logs all assertions to your firebug console and then stops the script.
325
+ *
326
+ * @param string $file File source of assertion
327
+ * @param int $line Line source of assertion
328
+ * @param mixed $code Assertion code
329
+ */
330
+ function assertionHandler($file, $line, $code)
331
+ {
332
+ $this->fb($code, 'Assertion Failed', FirePHP_ERROR, array('File'=>$file,'Line'=>$line));
333
+ }
334
+
335
+ /**
336
+ * Set custom processor url for FirePHP
337
+ *
338
+ * @param string $URL
339
+ */
340
+ function setProcessorUrl($URL)
341
+ {
342
+ $this->setHeader('X-FirePHP-ProcessorURL', $URL);
343
+ }
344
+
345
+ /**
346
+ * Set custom renderer url for FirePHP
347
+ *
348
+ * @param string $URL
349
+ */
350
+ function setRendererUrl($URL)
351
+ {
352
+ $this->setHeader('X-FirePHP-RendererURL', $URL);
353
+ }
354
+
355
+ /**
356
+ * Start a group for following messages.
357
+ *
358
+ * Options:
359
+ * Collapsed: [true|false]
360
+ * Color: [#RRGGBB|ColorName]
361
+ *
362
+ * @param string $Name
363
+ * @param array $Options OPTIONAL Instructions on how to log the group
364
+ * @return true
365
+ * @throws Exception
366
+ */
367
+ function group($Name, $Options=null) {
368
+
369
+ if(!$Name) {
370
+ trigger_error('You must specify a label for the group!');
371
+ }
372
+
373
+ if($Options) {
374
+ if(!is_array($Options)) {
375
+ trigger_error('Options must be defined as an array!');
376
+ }
377
+ if(array_key_exists('Collapsed', $Options)) {
378
+ $Options['Collapsed'] = ($Options['Collapsed'])?'true':'false';
379
+ }
380
+ }
381
+
382
+ return $this->fb(null, $Name, FirePHP_GROUP_START, $Options);
383
+ }
384
+
385
+ /**
386
+ * Ends a group you have started before
387
+ *
388
+ * @return true
389
+ * @throws Exception
390
+ */
391
+ function groupEnd() {
392
+ return $this->fb(null, null, FirePHP_GROUP_END);
393
+ }
394
+
395
+ /**
396
+ * Log object with label to firebug console
397
+ *
398
+ * @see FirePHP::LOG
399
+ * @param mixes $Object
400
+ * @param string $Label
401
+ * @return true
402
+ * @throws Exception
403
+ */
404
+ function log($Object, $Label=null) {
405
+ return $this->fb($Object, $Label, FirePHP_LOG);
406
+ }
407
+
408
+ /**
409
+ * Log object with label to firebug console
410
+ *
411
+ * @see FirePHP::INFO
412
+ * @param mixes $Object
413
+ * @param string $Label
414
+ * @return true
415
+ * @throws Exception
416
+ */
417
+ function info($Object, $Label=null) {
418
+ return $this->fb($Object, $Label, FirePHP_INFO);
419
+ }
420
+
421
+ /**
422
+ * Log object with label to firebug console
423
+ *
424
+ * @see FirePHP::WARN
425
+ * @param mixes $Object
426
+ * @param string $Label
427
+ * @return true
428
+ * @throws Exception
429
+ */
430
+ function warn($Object, $Label=null) {
431
+ return $this->fb($Object, $Label, FirePHP_WARN);
432
+ }
433
+
434
+ /**
435
+ * Log object with label to firebug console
436
+ *
437
+ * @see FirePHP::ERROR
438
+ * @param mixes $Object
439
+ * @param string $Label
440
+ * @return true
441
+ * @throws Exception
442
+ */
443
+ function error($Object, $Label=null) {
444
+ return $this->fb($Object, $Label, FirePHP_ERROR);
445
+ }
446
+
447
+ /**
448
+ * Dumps key and variable to firebug server panel
449
+ *
450
+ * @see FirePHP::DUMP
451
+ * @param string $Key
452
+ * @param mixed $Variable
453
+ * @return true
454
+ * @throws Exception
455
+ */
456
+ function dump($Key, $Variable) {
457
+ return $this->fb($Variable, $Key, FirePHP_DUMP);
458
+ }
459
+
460
+ /**
461
+ * Log a trace in the firebug console
462
+ *
463
+ * @see FirePHP::TRACE
464
+ * @param string $Label
465
+ * @return true
466
+ * @throws Exception
467
+ */
468
+ function trace($Label) {
469
+ return $this->fb($Label, FirePHP_TRACE);
470
+ }
471
+
472
+ /**
473
+ * Log a table in the firebug console
474
+ *
475
+ * @see FirePHP::TABLE
476
+ * @param string $Label
477
+ * @param string $Table
478
+ * @return true
479
+ * @throws Exception
480
+ */
481
+ function table($Label, $Table) {
482
+ return $this->fb($Table, $Label, FirePHP_TABLE);
483
+ }
484
+
485
+ /**
486
+ * Check if FirePHP is installed on client
487
+ *
488
+ * @return boolean
489
+ */
490
+ function detectClientExtension() {
491
+ /* Check if FirePHP is installed on client */
492
+ if(!@preg_match_all('/\sFirePHP\/([\.|\d]*)\s?/si',$this->getUserAgent(),$m) ||
493
+ !version_compare($m[1][0],'0.0.6','>=')) {
494
+ return false;
495
+ }
496
+ return true;
497
+ }
498
+
499
+ /**
500
+ * Log varible to Firebug
501
+ *
502
+ * @see http://www.firephp.org/Wiki/Reference/Fb
503
+ * @param mixed $Object The variable to be logged
504
+ * @return true Return TRUE if message was added to headers, FALSE otherwise
505
+ * @throws Exception
506
+ */
507
+ function fb($Object) {
508
+
509
+ if(!$this->enabled) {
510
+ return false;
511
+ }
512
+
513
+ if (headers_sent($filename, $linenum)) {
514
+ trigger_error('Headers already sent in '.$filename.' on line '.$linenum.'. Cannot send log data to FirePHP. You must have Output Buffering enabled via ob_start() or output_buffering ini directive.');
515
+ }
516
+
517
+ $Type = null;
518
+ $Label = null;
519
+ $Options = array();
520
+
521
+ if(func_num_args()==1) {
522
+ } else
523
+ if(func_num_args()==2) {
524
+ switch(func_get_arg(1)) {
525
+ case FirePHP_LOG:
526
+ case FirePHP_INFO:
527
+ case FirePHP_WARN:
528
+ case FirePHP_ERROR:
529
+ case FirePHP_DUMP:
530
+ case FirePHP_TRACE:
531
+ case FirePHP_TABLE:
532
+ case FirePHP_GROUP_START:
533
+ case FirePHP_GROUP_END:
534
+ $Type = func_get_arg(1);
535
+ break;
536
+ default:
537
+ $Label = func_get_arg(1);
538
+ break;
539
+ }
540
+ } else
541
+ if(func_num_args()==3) {
542
+ $Type = func_get_arg(2);
543
+ $Label = func_get_arg(1);
544
+ } else
545
+ if(func_num_args()==4) {
546
+ $Type = func_get_arg(2);
547
+ $Label = func_get_arg(1);
548
+ $Options = func_get_arg(3);
549
+ } else {
550
+ trigger_error('Wrong number of arguments to fb() function!');
551
+ }
552
+
553
+
554
+ if(!$this->detectClientExtension()) {
555
+ return false;
556
+ }
557
+
558
+ $meta = array();
559
+ $skipFinalObjectEncode = false;
560
+
561
+ if($Type==FirePHP_TRACE) {
562
+
563
+ $trace = debug_backtrace();
564
+ if(!$trace) return false;
565
+ for( $i=0 ; $i<sizeof($trace) ; $i++ ) {
566
+
567
+ if(isset($trace[$i]['class'])
568
+ && isset($trace[$i]['file'])
569
+ && ($trace[$i]['class']=='FirePHP'
570
+ || $trace[$i]['class']=='FB')
571
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
572
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
573
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
574
+ } else
575
+ if(isset($trace[$i]['class'])
576
+ && isset($trace[$i+1]['file'])
577
+ && $trace[$i]['class']=='FirePHP'
578
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
579
+ /* Skip fb() */
580
+ } else
581
+ if($trace[$i]['function']=='fb'
582
+ || $trace[$i]['function']=='trace'
583
+ || $trace[$i]['function']=='send') {
584
+ $Object = array('Class'=>isset($trace[$i]['class'])?$trace[$i]['class']:'',
585
+ 'Type'=>isset($trace[$i]['type'])?$trace[$i]['type']:'',
586
+ 'Function'=>isset($trace[$i]['function'])?$trace[$i]['function']:'',
587
+ 'Message'=>$trace[$i]['args'][0],
588
+ 'File'=>isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'',
589
+ 'Line'=>isset($trace[$i]['line'])?$trace[$i]['line']:'',
590
+ 'Args'=>isset($trace[$i]['args'])?$this->encodeObject($trace[$i]['args']):'',
591
+ 'Trace'=>$this->_escapeTrace(array_splice($trace,$i+1)));
592
+
593
+ $skipFinalObjectEncode = true;
594
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
595
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
596
+ break;
597
+ }
598
+ }
599
+
600
+ } else
601
+ if($Type==FirePHP_TABLE) {
602
+
603
+ if(isset($Object[0]) && is_string($Object[0])) {
604
+ $Object[1] = $this->encodeTable($Object[1]);
605
+ } else {
606
+ $Object = $this->encodeTable($Object);
607
+ }
608
+
609
+ $skipFinalObjectEncode = true;
610
+
611
+ } else
612
+ if($Type==FirePHP_GROUP_START) {
613
+
614
+ if(!$Label) {
615
+ trigger_error('You must specify a label for the group!');
616
+ }
617
+ } else {
618
+ if($Type===null) {
619
+ $Type = FirePHP_LOG;
620
+ }
621
+ }
622
+
623
+ if($this->options['includeLineNumbers']) {
624
+ if(!isset($meta['file']) || !isset($meta['line'])) {
625
+
626
+ $trace = debug_backtrace();
627
+ for( $i=0 ; $trace && $i<sizeof($trace) ; $i++ ) {
628
+
629
+ if(isset($trace[$i]['class'])
630
+ && isset($trace[$i]['file'])
631
+ && ($trace[$i]['class']=='FirePHP'
632
+ || $trace[$i]['class']=='FB')
633
+ && (substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php'
634
+ || substr($this->_standardizePath($trace[$i]['file']),-29,29)=='FirePHPCore/FirePHP.class.php')) {
635
+ /* Skip - FB::trace(), FB::send(), $firephp->trace(), $firephp->fb() */
636
+ } else
637
+ if(isset($trace[$i]['class'])
638
+ && isset($trace[$i+1]['file'])
639
+ && $trace[$i]['class']=='FirePHP'
640
+ && substr($this->_standardizePath($trace[$i+1]['file']),-18,18)=='FirePHPCore/fb.php') {
641
+ /* Skip fb() */
642
+ } else
643
+ if(isset($trace[$i]['file'])
644
+ && substr($this->_standardizePath($trace[$i]['file']),-18,18)=='FirePHPCore/fb.php') {
645
+ /* Skip FB::fb() */
646
+ } else {
647
+ $meta['file'] = isset($trace[$i]['file'])?$this->_escapeTraceFile($trace[$i]['file']):'';
648
+ $meta['line'] = isset($trace[$i]['line'])?$trace[$i]['line']:'';
649
+ break;
650
+ }
651
+ }
652
+
653
+ }
654
+ } else {
655
+ unset($meta['file']);
656
+ unset($meta['line']);
657
+ }
658
+
659
+ $this->setHeader('X-Wf-Protocol-1','http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
660
+ $this->setHeader('X-Wf-1-Plugin-1','http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/'.FirePHP_VERSION);
661
+
662
+ $structure_index = 1;
663
+ if($Type==FirePHP_DUMP) {
664
+ $structure_index = 2;
665
+ $this->setHeader('X-Wf-1-Structure-2','http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
666
+ } else {
667
+ $this->setHeader('X-Wf-1-Structure-1','http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
668
+ }
669
+
670
+ if($Type==FirePHP_DUMP) {
671
+ $msg = '{"'.$Label.'":'.$this->jsonEncode($Object, $skipFinalObjectEncode).'}';
672
+ } else {
673
+ $msg_meta = $Options;
674
+ $msg_meta['Type'] = $Type;
675
+ if($Label!==null) {
676
+ $msg_meta['Label'] = $Label;
677
+ }
678
+ if(isset($meta['file']) && !isset($msg_meta['File'])) {
679
+ $msg_meta['File'] = $meta['file'];
680
+ }
681
+ if(isset($meta['line']) && !isset($msg_meta['Line'])) {
682
+ $msg_meta['Line'] = $meta['line'];
683
+ }
684
+ $msg = '['.$this->jsonEncode($msg_meta).','.$this->jsonEncode($Object, $skipFinalObjectEncode).']';
685
+ }
686
+
687
+ $parts = explode("\n",chunk_split($msg, 5000, "\n"));
688
+
689
+ for( $i=0 ; $i<count($parts) ; $i++) {
690
+
691
+ $part = $parts[$i];
692
+ if ($part) {
693
+
694
+ if(count($parts)>2) {
695
+ // Message needs to be split into multiple parts
696
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
697
+ (($i==0)?strlen($msg):'')
698
+ . '|' . $part . '|'
699
+ . (($i<count($parts)-2)?'\\':''));
700
+ } else {
701
+ $this->setHeader('X-Wf-1-'.$structure_index.'-'.'1-'.$this->messageIndex,
702
+ strlen($part) . '|' . $part . '|');
703
+ }
704
+
705
+ $this->messageIndex++;
706
+
707
+ if ($this->messageIndex > 99999) {
708
+ trigger_error('Maximum number (99,999) of messages reached!');
709
+ }
710
+ }
711
+ }
712
+
713
+ $this->setHeader('X-Wf-1-Index',$this->messageIndex-1);
714
+
715
+ return true;
716
+ }
717
+
718
+
719
+ /**
720
+ * Standardizes path for windows systems.
721
+ *
722
+ * @param string $Path
723
+ * @return string
724
+ */
725
+ function _standardizePath($Path) {
726
+ return preg_replace('/\\\\+/','/',$Path);
727
+ }
728
+
729
+ /**
730
+ * Escape trace path for windows systems
731
+ *
732
+ * @param array $Trace
733
+ * @return array
734
+ */
735
+ function _escapeTrace($Trace) {
736
+ if(!$Trace) return $Trace;
737
+ for( $i=0 ; $i<sizeof($Trace) ; $i++ ) {
738
+ if(isset($Trace[$i]['file'])) {
739
+ $Trace[$i]['file'] = $this->_escapeTraceFile($Trace[$i]['file']);
740
+ }
741
+ if(isset($Trace[$i]['args'])) {
742
+ $Trace[$i]['args'] = $this->encodeObject($Trace[$i]['args']);
743
+ }
744
+ }
745
+ return $Trace;
746
+ }
747
+
748
+ /**
749
+ * Escape file information of trace for windows systems
750
+ *
751
+ * @param string $File
752
+ * @return string
753
+ */
754
+ function _escapeTraceFile($File) {
755
+ /* Check if we have a windows filepath */
756
+ if(strpos($File,'\\')) {
757
+ /* First strip down to single \ */
758
+
759
+ $file = preg_replace('/\\\\+/','\\',$File);
760
+
761
+ return $file;
762
+ }
763
+ return $File;
764
+ }
765
+
766
+ /**
767
+ * Send header
768
+ *
769
+ * @param string $Name
770
+ * @param string_type $Value
771
+ */
772
+ function setHeader($Name, $Value) {
773
+ return header($Name.': '.$Value);
774
+ }
775
+
776
+ /**
777
+ * Get user agent
778
+ *
779
+ * @return string|false
780
+ */
781
+ function getUserAgent() {
782
+ if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
783
+ return $_SERVER['HTTP_USER_AGENT'];
784
+ }
785
+
786
+ /**
787
+ * Encode an object into a JSON string
788
+ *
789
+ * Uses PHP's jeson_encode() if available
790
+ *
791
+ * @param object $Object The object to be encoded
792
+ * @return string The JSON string
793
+ */
794
+ function jsonEncode($Object, $skipObjectEncode=false)
795
+ {
796
+ if(!$skipObjectEncode) {
797
+ $Object = $this->encodeObject($Object);
798
+ }
799
+
800
+ if(function_exists('json_encode')
801
+ && $this->options['useNativeJsonEncode']!=false) {
802
+
803
+ return json_encode($Object);
804
+ } else {
805
+ return $this->json_encode($Object);
806
+ }
807
+ }
808
+
809
+ /**
810
+ * Encodes a table by encoding each row and column with encodeObject()
811
+ *
812
+ * @param array $Table The table to be encoded
813
+ * @return array
814
+ */
815
+ function encodeTable($Table) {
816
+
817
+ if(!$Table) return $Table;
818
+
819
+ $new_table = array();
820
+ foreach($Table as $row) {
821
+
822
+ if(is_array($row)) {
823
+ $new_row = array();
824
+
825
+ foreach($row as $item) {
826
+ $new_row[] = $this->encodeObject($item);
827
+ }
828
+
829
+ $new_table[] = $new_row;
830
+ }
831
+ }
832
+
833
+ return $new_table;
834
+ }
835
+
836
+ /**
837
+ * Encodes an object
838
+ *
839
+ * @param Object $Object The object to be encoded
840
+ * @param int $Depth The current traversal depth
841
+ * @return array All members of the object
842
+ */
843
+ function encodeObject($Object, $ObjectDepth = 1, $ArrayDepth = 1)
844
+ {
845
+ $return = array();
846
+
847
+ if (is_resource($Object)) {
848
+
849
+ return '** '.(string)$Object.' **';
850
+
851
+ } else
852
+ if (is_object($Object)) {
853
+
854
+ if ($ObjectDepth > $this->options['maxObjectDepth']) {
855
+ return '** Max Object Depth ('.$this->options['maxObjectDepth'].') **';
856
+ }
857
+
858
+ foreach ($this->objectStack as $refVal) {
859
+ if ($refVal === $Object) {
860
+ return '** Recursion ('.get_class($Object).') **';
861
+ }
862
+ }
863
+ array_push($this->objectStack, $Object);
864
+
865
+ $return['__className'] = $class = get_class($Object);
866
+ $class_lower = strtolower($class);
867
+
868
+ $members = (array)$Object;
869
+
870
+ // Include all members that are not defined in the class
871
+ // but exist in the object
872
+ foreach( $members as $raw_name => $value ) {
873
+
874
+ $name = $raw_name;
875
+
876
+ if ($name{0} == "\0") {
877
+ $parts = explode("\0", $name);
878
+ $name = $parts[2];
879
+ }
880
+
881
+ if(!isset($properties[$name])) {
882
+ $name = 'undeclared:'.$name;
883
+
884
+ if(!(isset($this->objectFilters[$class_lower])
885
+ && is_array($this->objectFilters[$class_lower])
886
+ && in_array($raw_name,$this->objectFilters[$class_lower]))) {
887
+
888
+ $return[$name] = $this->encodeObject($value, $ObjectDepth + 1, 1);
889
+ } else {
890
+ $return[$name] = '** Excluded by Filter **';
891
+ }
892
+ }
893
+ }
894
+
895
+ array_pop($this->objectStack);
896
+
897
+ } elseif (is_array($Object)) {
898
+
899
+ if ($ArrayDepth > $this->options['maxArrayDepth']) {
900
+ return '** Max Array Depth ('.$this->options['maxArrayDepth'].') **';
901
+ }
902
+
903
+ foreach ($Object as $key => $val) {
904
+
905
+ // Encoding the $GLOBALS PHP array causes an infinite loop
906
+ // if the recursion is not reset here as it contains
907
+ // a reference to itself. This is the only way I have come up
908
+ // with to stop infinite recursion in this case.
909
+ if($key=='GLOBALS'
910
+ && is_array($val)
911
+ && array_key_exists('GLOBALS',$val)) {
912
+ $val['GLOBALS'] = '** Recursion (GLOBALS) **';
913
+ }
914
+
915
+ $return[$key] = $this->encodeObject($val, 1, $ArrayDepth + 1);
916
+ }
917
+ } else {
918
+ if($this->is_utf8($Object)) {
919
+ return $Object;
920
+ } else {
921
+ return utf8_encode($Object);
922
+ }
923
+ }
924
+ return $return;
925
+
926
+ }
927
+
928
+ /**
929
+ * Returns true if $string is valid UTF-8 and false otherwise.
930
+ *
931
+ * @param mixed $str String to be tested
932
+ * @return boolean
933
+ */
934
+ function is_utf8($str) {
935
+ $c=0; $b=0;
936
+ $bits=0;
937
+ $len=strlen($str);
938
+ for($i=0; $i<$len; $i++){
939
+ $c=ord($str[$i]);
940
+ if($c > 128){
941
+ if(($c >= 254)) return false;
942
+ elseif($c >= 252) $bits=6;
943
+ elseif($c >= 248) $bits=5;
944
+ elseif($c >= 240) $bits=4;
945
+ elseif($c >= 224) $bits=3;
946
+ elseif($c >= 192) $bits=2;
947
+ else return false;
948
+ if(($i+$bits) > $len) return false;
949
+ while($bits > 1){
950
+ $i++;
951
+ $b=ord($str[$i]);
952
+ if($b < 128 || $b > 191) return false;
953
+ $bits--;
954
+ }
955
+ }
956
+ }
957
+ return true;
958
+ }
959
+
960
+ /**
961
+ * Converts to and from JSON format.
962
+ *
963
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
964
+ * format. It is easy for humans to read and write. It is easy for machines
965
+ * to parse and generate. It is based on a subset of the JavaScript
966
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
967
+ * This feature can also be found in Python. JSON is a text format that is
968
+ * completely language independent but uses conventions that are familiar
969
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
970
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
971
+ * ideal data-interchange language.
972
+ *
973
+ * This package provides a simple encoder and decoder for JSON notation. It
974
+ * is intended for use with client-side Javascript applications that make
975
+ * use of HTTPRequest to perform server communication functions - data can
976
+ * be encoded into JSON notation for use in a client-side javascript, or
977
+ * decoded from incoming Javascript requests. JSON format is native to
978
+ * Javascript, and can be directly eval()'ed with no further parsing
979
+ * overhead
980
+ *
981
+ * All strings should be in ASCII or UTF-8 format!
982
+ *
983
+ * LICENSE: Redistribution and use in source and binary forms, with or
984
+ * without modification, are permitted provided that the following
985
+ * conditions are met: Redistributions of source code must retain the
986
+ * above copyright notice, this list of conditions and the following
987
+ * disclaimer. Redistributions in binary form must reproduce the above
988
+ * copyright notice, this list of conditions and the following disclaimer
989
+ * in the documentation and/or other materials provided with the
990
+ * distribution.
991
+ *
992
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
993
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
994
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
995
+ * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
996
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
997
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
998
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
999
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1000
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
1001
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1002
+ * DAMAGE.
1003
+ *
1004
+ * @category
1005
+ * @package Services_JSON
1006
+ * @author Michal Migurski <mike-json@teczno.com>
1007
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
1008
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
1009
+ * @author Christoph Dorn <christoph@christophdorn.com>
1010
+ * @copyright 2005 Michal Migurski
1011
+ * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $
1012
+ * @license http://www.opensource.org/licenses/bsd-license.php
1013
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
1014
+ */
1015
+
1016
+
1017
+ /**
1018
+ * Keep a list of objects as we descend into the array so we can detect recursion.
1019
+ */
1020
+ var $json_objectStack = array();
1021
+
1022
+
1023
+ /**
1024
+ * convert a string from one UTF-8 char to one UTF-16 char
1025
+ *
1026
+ * Normally should be handled by mb_convert_encoding, but
1027
+ * provides a slower PHP-only method for installations
1028
+ * that lack the multibye string extension.
1029
+ *
1030
+ * @param string $utf8 UTF-8 character
1031
+ * @return string UTF-16 character
1032
+ * @access private
1033
+ */
1034
+ function json_utf82utf16($utf8)
1035
+ {
1036
+ // oh please oh please oh please oh please oh please
1037
+ if(function_exists('mb_convert_encoding')) {
1038
+ return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
1039
+ }
1040
+
1041
+ switch(strlen($utf8)) {
1042
+ case 1:
1043
+ // this case should never be reached, because we are in ASCII range
1044
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1045
+ return $utf8;
1046
+
1047
+ case 2:
1048
+ // return a UTF-16 character from a 2-byte UTF-8 char
1049
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1050
+ return chr(0x07 & (ord($utf8{0}) >> 2))
1051
+ . chr((0xC0 & (ord($utf8{0}) << 6))
1052
+ | (0x3F & ord($utf8{1})));
1053
+
1054
+ case 3:
1055
+ // return a UTF-16 character from a 3-byte UTF-8 char
1056
+ // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1057
+ return chr((0xF0 & (ord($utf8{0}) << 4))
1058
+ | (0x0F & (ord($utf8{1}) >> 2)))
1059
+ . chr((0xC0 & (ord($utf8{1}) << 6))
1060
+ | (0x7F & ord($utf8{2})));
1061
+ }
1062
+
1063
+ // ignoring UTF-32 for now, sorry
1064
+ return '';
1065
+ }
1066
+
1067
+ /**
1068
+ * encodes an arbitrary variable into JSON format
1069
+ *
1070
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
1071
+ * see argument 1 to Services_JSON() above for array-parsing behavior.
1072
+ * if var is a strng, note that encode() always expects it
1073
+ * to be in ASCII or UTF-8 format!
1074
+ *
1075
+ * @return mixed JSON string representation of input var or an error if a problem occurs
1076
+ * @access public
1077
+ */
1078
+ function json_encode($var)
1079
+ {
1080
+
1081
+ if(is_object($var)) {
1082
+ if(in_array($var,$this->json_objectStack)) {
1083
+ return '"** Recursion **"';
1084
+ }
1085
+ }
1086
+
1087
+ switch (gettype($var)) {
1088
+ case 'boolean':
1089
+ return $var ? 'true' : 'false';
1090
+
1091
+ case 'NULL':
1092
+ return 'null';
1093
+
1094
+ case 'integer':
1095
+ return (int) $var;
1096
+
1097
+ case 'double':
1098
+ case 'float':
1099
+ return (float) $var;
1100
+
1101
+ case 'string':
1102
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
1103
+ $ascii = '';
1104
+ $strlen_var = strlen($var);
1105
+
1106
+ /*
1107
+ * Iterate over every character in the string,
1108
+ * escaping with a slash or encoding to UTF-8 where necessary
1109
+ */
1110
+ for ($c = 0; $c < $strlen_var; ++$c) {
1111
+
1112
+ $ord_var_c = ord($var{$c});
1113
+
1114
+ switch (true) {
1115
+ case $ord_var_c == 0x08:
1116
+ $ascii .= '\b';
1117
+ break;
1118
+ case $ord_var_c == 0x09:
1119
+ $ascii .= '\t';
1120
+ break;
1121
+ case $ord_var_c == 0x0A:
1122
+ $ascii .= '\n';
1123
+ break;
1124
+ case $ord_var_c == 0x0C:
1125
+ $ascii .= '\f';
1126
+ break;
1127
+ case $ord_var_c == 0x0D:
1128
+ $ascii .= '\r';
1129
+ break;
1130
+
1131
+ case $ord_var_c == 0x22:
1132
+ case $ord_var_c == 0x2F:
1133
+ case $ord_var_c == 0x5C:
1134
+ // double quote, slash, slosh
1135
+ $ascii .= '\\'.$var{$c};
1136
+ break;
1137
+
1138
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
1139
+ // characters U-00000000 - U-0000007F (same as ASCII)
1140
+ $ascii .= $var{$c};
1141
+ break;
1142
+
1143
+ case (($ord_var_c & 0xE0) == 0xC0):
1144
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
1145
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1146
+ $char = pack('C*', $ord_var_c, ord($var{$c + 1}));
1147
+ $c += 1;
1148
+ $utf16 = $this->json_utf82utf16($char);
1149
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1150
+ break;
1151
+
1152
+ case (($ord_var_c & 0xF0) == 0xE0):
1153
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
1154
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1155
+ $char = pack('C*', $ord_var_c,
1156
+ ord($var{$c + 1}),
1157
+ ord($var{$c + 2}));
1158
+ $c += 2;
1159
+ $utf16 = $this->json_utf82utf16($char);
1160
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1161
+ break;
1162
+
1163
+ case (($ord_var_c & 0xF8) == 0xF0):
1164
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
1165
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1166
+ $char = pack('C*', $ord_var_c,
1167
+ ord($var{$c + 1}),
1168
+ ord($var{$c + 2}),
1169
+ ord($var{$c + 3}));
1170
+ $c += 3;
1171
+ $utf16 = $this->json_utf82utf16($char);
1172
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1173
+ break;
1174
+
1175
+ case (($ord_var_c & 0xFC) == 0xF8):
1176
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
1177
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1178
+ $char = pack('C*', $ord_var_c,
1179
+ ord($var{$c + 1}),
1180
+ ord($var{$c + 2}),
1181
+ ord($var{$c + 3}),
1182
+ ord($var{$c + 4}));
1183
+ $c += 4;
1184
+ $utf16 = $this->json_utf82utf16($char);
1185
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1186
+ break;
1187
+
1188
+ case (($ord_var_c & 0xFE) == 0xFC):
1189
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
1190
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
1191
+ $char = pack('C*', $ord_var_c,
1192
+ ord($var{$c + 1}),
1193
+ ord($var{$c + 2}),
1194
+ ord($var{$c + 3}),
1195
+ ord($var{$c + 4}),
1196
+ ord($var{$c + 5}));
1197
+ $c += 5;
1198
+ $utf16 = $this->json_utf82utf16($char);
1199
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
1200
+ break;
1201
+ }
1202
+ }
1203
+
1204
+ return '"'.$ascii.'"';
1205
+
1206
+ case 'array':
1207
+ /*
1208
+ * As per JSON spec if any array key is not an integer
1209
+ * we must treat the the whole array as an object. We
1210
+ * also try to catch a sparsely populated associative
1211
+ * array with numeric keys here because some JS engines
1212
+ * will create an array with empty indexes up to
1213
+ * max_index which can cause memory issues and because
1214
+ * the keys, which may be relevant, will be remapped
1215
+ * otherwise.
1216
+ *
1217
+ * As per the ECMA and JSON specification an object may
1218
+ * have any string as a property. Unfortunately due to
1219
+ * a hole in the ECMA specification if the key is a
1220
+ * ECMA reserved word or starts with a digit the
1221
+ * parameter is only accessible using ECMAScript's
1222
+ * bracket notation.
1223
+ */
1224
+
1225
+ // treat as a JSON object
1226
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
1227
+
1228
+ $this->json_objectStack[] = $var;
1229
+
1230
+ $properties = array_map(array($this, 'json_name_value'),
1231
+ array_keys($var),
1232
+ array_values($var));
1233
+
1234
+ array_pop($this->json_objectStack);
1235
+
1236
+ return '{' . join(',', $properties) . '}';
1237
+ }
1238
+
1239
+ $this->json_objectStack[] = $var;
1240
+
1241
+ // treat it like a regular array
1242
+ $elements = array_map(array($this, 'json_encode'), $var);
1243
+
1244
+ array_pop($this->json_objectStack);
1245
+
1246
+ return '[' . join(',', $elements) . ']';
1247
+
1248
+ case 'object':
1249
+ $vars = FirePHP::encodeObject($var);
1250
+
1251
+ $this->json_objectStack[] = $var;
1252
+
1253
+ $properties = array_map(array($this, 'json_name_value'),
1254
+ array_keys($vars),
1255
+ array_values($vars));
1256
+
1257
+ array_pop($this->json_objectStack);
1258
+
1259
+ return '{' . join(',', $properties) . '}';
1260
+
1261
+ default:
1262
+ return null;
1263
+ }
1264
+ }
1265
+
1266
+ /**
1267
+ * array-walking function for use in generating JSON-formatted name-value pairs
1268
+ *
1269
+ * @param string $name name of key to use
1270
+ * @param mixed $value reference to an array element to be encoded
1271
+ *
1272
+ * @return string JSON-formatted name-value pair, like '"name":value'
1273
+ * @access private
1274
+ */
1275
+ function json_name_value($name, $value)
1276
+ {
1277
+ // Encoding the $GLOBALS PHP array causes an infinite loop
1278
+ // if the recursion is not reset here as it contains
1279
+ // a reference to itself. This is the only way I have come up
1280
+ // with to stop infinite recursion in this case.
1281
+ if($name=='GLOBALS'
1282
+ && is_array($value)
1283
+ && array_key_exists('GLOBALS',$value)) {
1284
+ $value['GLOBALS'] = '** Recursion **';
1285
+ }
1286
+
1287
+ $encoded_value = $this->json_encode($value);
1288
+
1289
+ return $this->json_encode(strval($name)) . ':' . $encoded_value;
1290
+ }
1291
+ }
1292
+
FirePHPCore/LICENSE ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Software License Agreement (New BSD License)
2
+
3
+ Copyright (c) 2006-2009, Christoph Dorn
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification,
7
+ are permitted provided that the following conditions are met:
8
+
9
+ * Redistributions of source code must retain the above copyright notice,
10
+ this list of conditions and the following disclaimer.
11
+
12
+ * Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ * Neither the name of Christoph Dorn nor the names of its
17
+ contributors may be used to endorse or promote products derived from this
18
+ software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FirePHPCore/fb.php ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* ***** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2009, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
40
+ * @author Christoph Dorn <christoph@christophdorn.com>
41
+ * @license http://www.opensource.org/licenses/bsd-license.php
42
+ * @package FirePHP
43
+ */
44
+
45
+ require_once dirname(__FILE__).'/FirePHP.class.php';
46
+
47
+ /**
48
+ * Sends the given data to the FirePHP Firefox Extension.
49
+ * The data can be displayed in the Firebug Console or in the
50
+ * "Server" request tab.
51
+ *
52
+ * @see http://www.firephp.org/Wiki/Reference/Fb
53
+ * @param mixed $Object
54
+ * @return true
55
+ * @throws Exception
56
+ */
57
+ function fb()
58
+ {
59
+ $instance = FirePHP::getInstance(true);
60
+
61
+ $args = func_get_args();
62
+ return call_user_func_array(array($instance,'fb'),$args);
63
+ }
64
+
65
+
66
+ class FB
67
+ {
68
+ /**
69
+ * Enable and disable logging to Firebug
70
+ *
71
+ * @see FirePHP->setEnabled()
72
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
73
+ * @return void
74
+ */
75
+ public static function setEnabled($Enabled) {
76
+ $instance = FirePHP::getInstance(true);
77
+ $instance->setEnabled($Enabled);
78
+ }
79
+
80
+ /**
81
+ * Check if logging is enabled
82
+ *
83
+ * @see FirePHP->getEnabled()
84
+ * @return boolean TRUE if enabled
85
+ */
86
+ public static function getEnabled() {
87
+ $instance = FirePHP::getInstance(true);
88
+ return $instance->getEnabled();
89
+ }
90
+
91
+ /**
92
+ * Specify a filter to be used when encoding an object
93
+ *
94
+ * Filters are used to exclude object members.
95
+ *
96
+ * @see FirePHP->setObjectFilter()
97
+ * @param string $Class The class name of the object
98
+ * @param array $Filter An array or members to exclude
99
+ * @return void
100
+ */
101
+ public static function setObjectFilter($Class, $Filter) {
102
+ $instance = FirePHP::getInstance(true);
103
+ $instance->setObjectFilter($Class, $Filter);
104
+ }
105
+
106
+ /**
107
+ * Set some options for the library
108
+ *
109
+ * @see FirePHP->setOptions()
110
+ * @param array $Options The options to be set
111
+ * @return void
112
+ */
113
+ public static function setOptions($Options) {
114
+ $instance = FirePHP::getInstance(true);
115
+ $instance->setOptions($Options);
116
+ }
117
+
118
+ /**
119
+ * Get options for the library
120
+ *
121
+ * @see FirePHP->getOptions()
122
+ * @return array The options
123
+ */
124
+ public static function getOptions() {
125
+ $instance = FirePHP::getInstance(true);
126
+ return $instance->getOptions();
127
+ }
128
+
129
+ /**
130
+ * Log object to firebug
131
+ *
132
+ * @see http://www.firephp.org/Wiki/Reference/Fb
133
+ * @param mixed $Object
134
+ * @return true
135
+ * @throws Exception
136
+ */
137
+ public static function send()
138
+ {
139
+ $instance = FirePHP::getInstance(true);
140
+ $args = func_get_args();
141
+ return call_user_func_array(array($instance,'fb'),$args);
142
+ }
143
+
144
+ /**
145
+ * Start a group for following messages
146
+ *
147
+ * Options:
148
+ * Collapsed: [true|false]
149
+ * Color: [#RRGGBB|ColorName]
150
+ *
151
+ * @param string $Name
152
+ * @param array $Options OPTIONAL Instructions on how to log the group
153
+ * @return true
154
+ */
155
+ public static function group($Name, $Options=null) {
156
+ $instance = FirePHP::getInstance(true);
157
+ return $instance->group($Name, $Options);
158
+ }
159
+
160
+ /**
161
+ * Ends a group you have started before
162
+ *
163
+ * @return true
164
+ * @throws Exception
165
+ */
166
+ public static function groupEnd() {
167
+ return self::send(null, null, FirePHP::GROUP_END);
168
+ }
169
+
170
+ /**
171
+ * Log object with label to firebug console
172
+ *
173
+ * @see FirePHP::LOG
174
+ * @param mixes $Object
175
+ * @param string $Label
176
+ * @return true
177
+ * @throws Exception
178
+ */
179
+ public static function log($Object, $Label=null) {
180
+ return self::send($Object, $Label, FirePHP::LOG);
181
+ }
182
+
183
+ /**
184
+ * Log object with label to firebug console
185
+ *
186
+ * @see FirePHP::INFO
187
+ * @param mixes $Object
188
+ * @param string $Label
189
+ * @return true
190
+ * @throws Exception
191
+ */
192
+ public static function info($Object, $Label=null) {
193
+ return self::send($Object, $Label, FirePHP::INFO);
194
+ }
195
+
196
+ /**
197
+ * Log object with label to firebug console
198
+ *
199
+ * @see FirePHP::WARN
200
+ * @param mixes $Object
201
+ * @param string $Label
202
+ * @return true
203
+ * @throws Exception
204
+ */
205
+ public static function warn($Object, $Label=null) {
206
+ return self::send($Object, $Label, FirePHP::WARN);
207
+ }
208
+
209
+ /**
210
+ * Log object with label to firebug console
211
+ *
212
+ * @see FirePHP::ERROR
213
+ * @param mixes $Object
214
+ * @param string $Label
215
+ * @return true
216
+ * @throws Exception
217
+ */
218
+ public static function error($Object, $Label=null) {
219
+ return self::send($Object, $Label, FirePHP::ERROR);
220
+ }
221
+
222
+ /**
223
+ * Dumps key and variable to firebug server panel
224
+ *
225
+ * @see FirePHP::DUMP
226
+ * @param string $Key
227
+ * @param mixed $Variable
228
+ * @return true
229
+ * @throws Exception
230
+ */
231
+ public static function dump($Key, $Variable) {
232
+ return self::send($Variable, $Key, FirePHP::DUMP);
233
+ }
234
+
235
+ /**
236
+ * Log a trace in the firebug console
237
+ *
238
+ * @see FirePHP::TRACE
239
+ * @param string $Label
240
+ * @return true
241
+ * @throws Exception
242
+ */
243
+ public static function trace($Label) {
244
+ return self::send($Label, FirePHP::TRACE);
245
+ }
246
+
247
+ /**
248
+ * Log a table in the firebug console
249
+ *
250
+ * @see FirePHP::TABLE
251
+ * @param string $Label
252
+ * @param string $Table
253
+ * @return true
254
+ * @throws Exception
255
+ */
256
+ public static function table($Label, $Table) {
257
+ return self::send($Table, $Label, FirePHP::TABLE);
258
+ }
259
+
260
+ }
261
+
FirePHPCore/fb.php4 ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /* ***** BEGIN LICENSE BLOCK *****
4
+ *
5
+ * This file is part of FirePHP (http://www.firephp.org/).
6
+ *
7
+ * Software License Agreement (New BSD License)
8
+ *
9
+ * Copyright (c) 2006-2009, Christoph Dorn
10
+ * All rights reserved.
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without modification,
13
+ * are permitted provided that the following conditions are met:
14
+ *
15
+ * * Redistributions of source code must retain the above copyright notice,
16
+ * this list of conditions and the following disclaimer.
17
+ *
18
+ * * Redistributions in binary form must reproduce the above copyright notice,
19
+ * this list of conditions and the following disclaimer in the documentation
20
+ * and/or other materials provided with the distribution.
21
+ *
22
+ * * Neither the name of Christoph Dorn nor the names of its
23
+ * contributors may be used to endorse or promote products derived from this
24
+ * software without specific prior written permission.
25
+ *
26
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
+ *
37
+ * ***** END LICENSE BLOCK *****
38
+ *
39
+ * @copyright Copyright (C) 2007-2009 Christoph Dorn
40
+ * @author Christoph Dorn <christoph@christophdorn.com>
41
+ * @author Michael Day <manveru.alma@gmail.com>
42
+ * @license http://www.opensource.org/licenses/bsd-license.php
43
+ * @package FirePHP
44
+ */
45
+
46
+ require_once dirname(__FILE__).'/FirePHP.class.php4';
47
+
48
+ /**
49
+ * Sends the given data to the FirePHP Firefox Extension.
50
+ * The data can be displayed in the Firebug Console or in the
51
+ * "Server" request tab.
52
+ *
53
+ * @see http://www.firephp.org/Wiki/Reference/Fb
54
+ * @param mixed $Object
55
+ * @return true
56
+ * @throws Exception
57
+ */
58
+ function fb()
59
+ {
60
+ $instance =& FirePHP::getInstance(true);
61
+
62
+ $args = func_get_args();
63
+ return call_user_func_array(array(&$instance,'fb'),$args);
64
+ }
65
+
66
+
67
+ class FB
68
+ {
69
+ /**
70
+ * Enable and disable logging to Firebug
71
+ *
72
+ * @see FirePHP->setEnabled()
73
+ * @param boolean $Enabled TRUE to enable, FALSE to disable
74
+ * @return void
75
+ */
76
+ function setEnabled($Enabled) {
77
+ $instance =& FirePHP::getInstance(true);
78
+ $instance->setEnabled($Enabled);
79
+ }
80
+
81
+ /**
82
+ * Check if logging is enabled
83
+ *
84
+ * @see FirePHP->getEnabled()
85
+ * @return boolean TRUE if enabled
86
+ */
87
+ function getEnabled() {
88
+ $instance =& FirePHP::getInstance(true);
89
+ return $instance->getEnabled();
90
+ }
91
+
92
+ /**
93
+ * Specify a filter to be used when encoding an object
94
+ *
95
+ * Filters are used to exclude object members.
96
+ *
97
+ * @see FirePHP->setObjectFilter()
98
+ * @param string $Class The class name of the object
99
+ * @param array $Filter An array or members to exclude
100
+ * @return void
101
+ */
102
+ function setObjectFilter($Class, $Filter) {
103
+ $instance =& FirePHP::getInstance(true);
104
+ $instance->setObjectFilter($Class, $Filter);
105
+ }
106
+
107
+ /**
108
+ * Set some options for the library
109
+ *
110
+ * @see FirePHP->setOptions()
111
+ * @param array $Options The options to be set
112
+ * @return void
113
+ */
114
+ function setOptions($Options) {
115
+ $instance =& FirePHP::getInstance(true);
116
+ $instance->setOptions($Options);
117
+ }
118
+
119
+ /**
120
+ * Get options for the library
121
+ *
122
+ * @see FirePHP->getOptions()
123
+ * @return array The options
124
+ */
125
+ function getOptions() {
126
+ $instance =& FirePHP::getInstance(true);
127
+ return $instance->getOptions();
128
+ }
129
+
130
+ /**
131
+ * Log object to firebug
132
+ *
133
+ * @see http://www.firephp.org/Wiki/Reference/Fb
134
+ * @param mixed $Object
135
+ * @return true
136
+ */
137
+ function send()
138
+ {
139
+ $instance =& FirePHP::getInstance(true);
140
+ $args = func_get_args();
141
+ return call_user_func_array(array(&$instance,'fb'),$args);
142
+ }
143
+
144
+ /**
145
+ * Start a group for following messages
146
+ *
147
+ * Options:
148
+ * Collapsed: [true|false]
149
+ * Color: [#RRGGBB|ColorName]
150
+ *
151
+ * @param string $Name
152
+ * @param array $Options OPTIONAL Instructions on how to log the group
153
+ * @return true
154
+ */
155
+ function group($Name, $Options=null) {
156
+ $instance =& FirePHP::getInstance(true);
157
+ return $instance->group($Name, $Options);
158
+ }
159
+
160
+ /**
161
+ * Ends a group you have started before
162
+ *
163
+ * @return true
164
+ */
165
+ function groupEnd() {
166
+ return FB::send(null, null, FirePHP_GROUP_END);
167
+ }
168
+
169
+ /**
170
+ * Log object with label to firebug console
171
+ *
172
+ * @see FirePHP::LOG
173
+ * @param mixes $Object
174
+ * @param string $Label
175
+ * @return true
176
+ */
177
+ function log($Object, $Label=null) {
178
+ return FB::send($Object, $Label, FirePHP_LOG);
179
+ }
180
+
181
+ /**
182
+ * Log object with label to firebug console
183
+ *
184
+ * @see FirePHP::INFO
185
+ * @param mixes $Object
186
+ * @param string $Label
187
+ * @return true
188
+ */
189
+ function info($Object, $Label=null) {
190
+ return FB::send($Object, $Label, FirePHP_INFO);
191
+ }
192
+
193
+ /**
194
+ * Log object with label to firebug console
195
+ *
196
+ * @see FirePHP::WARN
197
+ * @param mixes $Object
198
+ * @param string $Label
199
+ * @return true
200
+ */
201
+ function warn($Object, $Label=null) {
202
+ return FB::send($Object, $Label, FirePHP_WARN);
203
+ }
204
+
205
+ /**
206
+ * Log object with label to firebug console
207
+ *
208
+ * @see FirePHP::ERROR
209
+ * @param mixes $Object
210
+ * @param string $Label
211
+ * @return true
212
+ */
213
+ function error($Object, $Label=null) {
214
+ return FB::send($Object, $Label, FirePHP_ERROR);
215
+ }
216
+
217
+ /**
218
+ * Dumps key and variable to firebug server panel
219
+ *
220
+ * @see FirePHP::DUMP
221
+ * @param string $Key
222
+ * @param mixed $Variable
223
+ * @return true
224
+ */
225
+ function dump($Key, $Variable) {
226
+ return FB::send($Variable, $Key, FirePHP_DUMP);
227
+ }
228
+
229
+ /**
230
+ * Log a trace in the firebug console
231
+ *
232
+ * @see FirePHP::TRACE
233
+ * @param string $Label
234
+ * @return true
235
+ */
236
+ function trace($Label) {
237
+ return FB::send($Label, FirePHP_TRACE);
238
+ }
239
+
240
+ /**
241
+ * Log a table in the firebug console
242
+ *
243
+ * @see FirePHP::TABLE
244
+ * @param string $Label
245
+ * @param string $Table
246
+ * @return true
247
+ */
248
+ function table($Label, $Table) {
249
+ return FB::send($Table, $Label, FirePHP_TABLE);
250
+ }
251
+ }
functions.php CHANGED
@@ -41,6 +41,8 @@ function cms_tpv_admin_init() {
41
  wp_enqueue_script( "jquery-cookie", CMS_TPV_URL . "scripts/jquery.biscuit.js", array("jquery")); // renamed from cookie to fix problems with mod_security
42
  wp_enqueue_script( "jquery-jstree", CMS_TPV_URL . "scripts/jquery.jstree.js", false, CMS_TPV_VERSION);
43
  wp_enqueue_script( "jquery-alerts", CMS_TPV_URL . "scripts/jquery.alerts.js", false, CMS_TPV_VERSION);
 
 
44
  wp_enqueue_script( "cms_tree_page_view", CMS_TPV_URL . "scripts/cms_tree_page_view.js", false, CMS_TPV_VERSION);
45
 
46
  // DEBUG
@@ -58,13 +60,15 @@ function cms_tpv_admin_init() {
58
  "Add_new_page_after" => __("Add new page after", 'cms-tree-page-view'),
59
  "after" => __("after", 'cms-tree-page-view'),
60
  "inside" => __("inside", 'cms-tree-page-view'),
 
61
  "Add_new_page_inside" => __("Add new page inside", 'cms-tree-page-view'),
62
  "Status_draft" => __("draft", 'cms-tree-page-view'),
63
  "Status_future" => __("future", 'cms-tree-page-view'),
64
  "Status_password" => __("protected", 'cms-tree-page-view'), // is "protected" word better than "password" ?
65
  "Status_pending" => __("pending", 'cms-tree-page-view'),
66
  "Status_private" => __("private", 'cms-tree-page-view'),
67
- "Password_protected_page" => __("Password protected page", 'cms-tree-page-view')
 
68
  );
69
  wp_localize_script( "cms_tree_page_view", 'cmstpv_l10n', $oLocale);
70
 
@@ -72,7 +76,7 @@ function cms_tpv_admin_init() {
72
 
73
  // save settings
74
  function cms_tpv_save_settings() {
75
- if ($_POST["cms_tpv_action"] == "save_settings") {
76
  $options = array();
77
  $options["dashboard"] = (array) $_POST["post-type-dashboard"];
78
  $options["menu"] = (array) $_POST["post-type-menu"];
@@ -100,7 +104,7 @@ function cms_tpv_wp_dashboard_setup() {
100
  $options = cms_tpv_get_options();
101
  foreach ($options["dashboard"] as $one_dashboard_post_type) {
102
  $post_type_object = get_post_type_object($one_dashboard_post_type);
103
- $new_func_name = create_function('', "cms_tpv_dashboard($one_dashboard_post_type);");
104
  wp_add_dashboard_widget( "cms_tpv_dashboard_widget_{$one_dashboard_post_type}", $post_type_object->labels->name . " Tree View", $new_func_name );
105
  }
106
  }
@@ -170,7 +174,7 @@ foreach ($posts as $one_post) {
170
  <form method="post" action="options.php">
171
  <?php wp_nonce_field('update-options'); ?>
172
 
173
- <h3><?php _e("Select where to show a tree for pages and custom post types")?></h3>
174
 
175
  <?php
176
  $options = cms_tpv_get_options();
@@ -364,7 +368,9 @@ function cms_tpv_print_common_tree_stuff($post_type = "") {
364
  <div class="cms_tpv_container tree-default">
365
  <?php _e("Loading tree", 'cms-tree-page-view') ?>
366
  </div>
 
367
  <div style="clear: both;"></div>
 
368
  <div class="cms_tpv_page_actions">
369
  <p>
370
  <a href="#" title='<?php _e("Edit page", "cms-tree-page-view")?>' class='cms_tpv_action_edit'><?php _e("Edit", "cms-tree-page-view")?></a> |
@@ -374,10 +380,13 @@ function cms_tpv_print_common_tree_stuff($post_type = "") {
374
  <span class='cms_tpv_action_add_page'><?php echo $post_type_object->labels->add_new_item ?></span>
375
  <a href="#" title='<?php _e("Add new page after", "cms-tree-page-view")?>' class='cms_tpv_action_add_page_after'><?php _e("After", "cms-tree-page-view")?></a>
376
  <?php
 
377
  if ($post_type_object->hierarchical) {
378
  ?> | <a href="#" title='<?php _e("Add new page inside", "cms-tree-page-view")?>' class='cms_tpv_action_add_page_inside'><?php _e("Inside", "cms-tree-page-view")?></a><?php
379
  }
 
380
  ?>
 
381
  </p>
382
  <dl>
383
  <dt><?php _e("Last modified", "cms-tree-page-view") ?></dt>
@@ -489,7 +498,12 @@ function cms_tpv_print_childs($pageID, $view = "all", $arrOpenChilds = null, $po
489
 
490
  global $current_screen;
491
  $screen = convert_to_screen("edit");
 
 
 
492
  $posts_columns = get_column_headers($screen);
 
 
493
  unset($posts_columns["cb"], $posts_columns["title"], $posts_columns["author"], $posts_columns["categories"], $posts_columns["tags"], $posts_columns["date"]);
494
 
495
  global $post;
@@ -506,7 +520,7 @@ function cms_tpv_print_childs($pageID, $view = "all", $arrOpenChilds = null, $po
506
  $page_id = $onePage->ID;
507
 
508
  $editLink = get_edit_post_link($onePage->ID, 'notDisplay');
509
- $content = wp_specialchars($onePage->post_content);
510
  $content = str_replace(array("\n","\r"), "", $content);
511
  $hasChildren = false;
512
  $arrChildPages = cms_tpv_get_pages("parent={$onePage->ID}&view=$view&post_type=$post_type");
@@ -541,7 +555,7 @@ function cms_tpv_print_childs($pageID, $view = "all", $arrOpenChilds = null, $po
541
  if (empty($title)) {
542
  $title = __("<Untitled page>", 'cms-tree-page-view');
543
  }
544
- $title = wp_specialchars($title);
545
  #$title = html_entity_decode($title, ENT_COMPAT, "UTF-8");
546
  #$title = html_entity_decode($title, ENT_COMPAT);
547
 
@@ -656,8 +670,8 @@ function cms_tpv_get_childs() {
656
 
657
  $action = $_GET["action"];
658
  $view = $_GET["view"]; // all | public
659
- $post_type = $_GET["post_type"];
660
- $search = trim($_GET["search_string"]); // exits if we're doing a search
661
  if ($action) {
662
 
663
  if ($search) {
@@ -722,7 +736,7 @@ function cms_tpv_get_childs() {
722
 
723
  // regular get
724
 
725
- $id = $_GET["id"];
726
  $id = (int) str_replace("cms-tpv-", "", $id);
727
 
728
  $jstree_open = array();
@@ -926,7 +940,7 @@ function cms_tpv_move_page() {
926
  */
927
  function cms_tpv_show_annoying_box() {
928
  #update_option('cms_tpv_show_annoying_little_box', 1); // enable this to show box
929
- if ( "cms_tpv_remove_annoying_box" == $_GET["action"] ) {
930
  $show_box = 0;
931
  update_option('cms_tpv_show_annoying_little_box', $show_box);
932
  } else {
41
  wp_enqueue_script( "jquery-cookie", CMS_TPV_URL . "scripts/jquery.biscuit.js", array("jquery")); // renamed from cookie to fix problems with mod_security
42
  wp_enqueue_script( "jquery-jstree", CMS_TPV_URL . "scripts/jquery.jstree.js", false, CMS_TPV_VERSION);
43
  wp_enqueue_script( "jquery-alerts", CMS_TPV_URL . "scripts/jquery.alerts.js", false, CMS_TPV_VERSION);
44
+ wp_enqueue_script( "jquery-hoverintent", CMS_TPV_URL . "scripts/jquery.hoverIntent.minified.js", false, CMS_TPV_VERSION);
45
+ #wp_enqueue_script( "jquery-ui-dialog", CMS_TPV_URL . "scripts/jquery.ui.dialog.min.js", false, CMS_TPV_VERSION);
46
  wp_enqueue_script( "cms_tree_page_view", CMS_TPV_URL . "scripts/cms_tree_page_view.js", false, CMS_TPV_VERSION);
47
 
48
  // DEBUG
60
  "Add_new_page_after" => __("Add new page after", 'cms-tree-page-view'),
61
  "after" => __("after", 'cms-tree-page-view'),
62
  "inside" => __("inside", 'cms-tree-page-view'),
63
+ "Can_not_add_sub_page_when_status_is_draft" => __("Sorry, can't create a sub page to a page with status \"draft\".", 'cms-tree-page-view'),
64
  "Add_new_page_inside" => __("Add new page inside", 'cms-tree-page-view'),
65
  "Status_draft" => __("draft", 'cms-tree-page-view'),
66
  "Status_future" => __("future", 'cms-tree-page-view'),
67
  "Status_password" => __("protected", 'cms-tree-page-view'), // is "protected" word better than "password" ?
68
  "Status_pending" => __("pending", 'cms-tree-page-view'),
69
  "Status_private" => __("private", 'cms-tree-page-view'),
70
+ "Password_protected_page" => __("Password protected page", 'cms-tree-page-view'),
71
+ "Adding_page" => __("Adding page...", 'cms-tree-page-view'),
72
  );
73
  wp_localize_script( "cms_tree_page_view", 'cmstpv_l10n', $oLocale);
74
 
76
 
77
  // save settings
78
  function cms_tpv_save_settings() {
79
+ if (isset($_POST["cms_tpv_action"]) && $_POST["cms_tpv_action"] == "save_settings") {
80
  $options = array();
81
  $options["dashboard"] = (array) $_POST["post-type-dashboard"];
82
  $options["menu"] = (array) $_POST["post-type-menu"];
104
  $options = cms_tpv_get_options();
105
  foreach ($options["dashboard"] as $one_dashboard_post_type) {
106
  $post_type_object = get_post_type_object($one_dashboard_post_type);
107
+ $new_func_name = create_function('', "cms_tpv_dashboard('$one_dashboard_post_type');");
108
  wp_add_dashboard_widget( "cms_tpv_dashboard_widget_{$one_dashboard_post_type}", $post_type_object->labels->name . " Tree View", $new_func_name );
109
  }
110
  }
174
  <form method="post" action="options.php">
175
  <?php wp_nonce_field('update-options'); ?>
176
 
177
+ <h3><?php _e("Select where to show a tree for pages and custom post types", 'cms-tree-page-view')?></h3>
178
 
179
  <?php
180
  $options = cms_tpv_get_options();
368
  <div class="cms_tpv_container tree-default">
369
  <?php _e("Loading tree", 'cms-tree-page-view') ?>
370
  </div>
371
+
372
  <div style="clear: both;"></div>
373
+
374
  <div class="cms_tpv_page_actions">
375
  <p>
376
  <a href="#" title='<?php _e("Edit page", "cms-tree-page-view")?>' class='cms_tpv_action_edit'><?php _e("Edit", "cms-tree-page-view")?></a> |
380
  <span class='cms_tpv_action_add_page'><?php echo $post_type_object->labels->add_new_item ?></span>
381
  <a href="#" title='<?php _e("Add new page after", "cms-tree-page-view")?>' class='cms_tpv_action_add_page_after'><?php _e("After", "cms-tree-page-view")?></a>
382
  <?php
383
+ // if post type is hierarchical we can add pages inside
384
  if ($post_type_object->hierarchical) {
385
  ?> | <a href="#" title='<?php _e("Add new page inside", "cms-tree-page-view")?>' class='cms_tpv_action_add_page_inside'><?php _e("Inside", "cms-tree-page-view")?></a><?php
386
  }
387
+ // if post status = draft then we can not add pages inside because wordpress currently can not keep its parent if we edit the page
388
  ?>
389
+ <!-- <span class="cms_tpv_action_add_page_inside_disallowed"><?php _e("Can not create page inside of a page with draft status", "cms-tree-page-view")?></span> -->
390
  </p>
391
  <dl>
392
  <dt><?php _e("Last modified", "cms-tree-page-view") ?></dt>
498
 
499
  global $current_screen;
500
  $screen = convert_to_screen("edit");
501
+ $screen->post_type = null;
502
+
503
+ ob_start(); // some plugins, for example magic fields, return javascript and things here. we're not campatible with that, so just swallow any output
504
  $posts_columns = get_column_headers($screen);
505
+ ob_get_clean();
506
+
507
  unset($posts_columns["cb"], $posts_columns["title"], $posts_columns["author"], $posts_columns["categories"], $posts_columns["tags"], $posts_columns["date"]);
508
 
509
  global $post;
520
  $page_id = $onePage->ID;
521
 
522
  $editLink = get_edit_post_link($onePage->ID, 'notDisplay');
523
+ $content = esc_html($onePage->post_content);
524
  $content = str_replace(array("\n","\r"), "", $content);
525
  $hasChildren = false;
526
  $arrChildPages = cms_tpv_get_pages("parent={$onePage->ID}&view=$view&post_type=$post_type");
555
  if (empty($title)) {
556
  $title = __("<Untitled page>", 'cms-tree-page-view');
557
  }
558
+ $title = esc_html($title);
559
  #$title = html_entity_decode($title, ENT_COMPAT, "UTF-8");
560
  #$title = html_entity_decode($title, ENT_COMPAT);
561
 
670
 
671
  $action = $_GET["action"];
672
  $view = $_GET["view"]; // all | public
673
+ $post_type = (isset($_GET["post_type"])) ? $_GET["post_type"] : null;
674
+ $search = (isset($_GET["search_string"])) ? trim($_GET["search_string"]) : ""; // exits if we're doing a search
675
  if ($action) {
676
 
677
  if ($search) {
736
 
737
  // regular get
738
 
739
+ $id = (isset($_GET["id"])) ? $_GET["id"] : null;
740
  $id = (int) str_replace("cms-tpv-", "", $id);
741
 
742
  $jstree_open = array();
940
  */
941
  function cms_tpv_show_annoying_box() {
942
  #update_option('cms_tpv_show_annoying_little_box', 1); // enable this to show box
943
+ if ( isset($_GET["action"]) && "cms_tpv_remove_annoying_box" == $_GET["action"] ) {
944
  $show_box = 0;
945
  update_option('cms_tpv_show_annoying_little_box', $show_box);
946
  } else {
index.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: CMS Tree Page View
4
  Plugin URI: http://eskapism.se/code-playground/cms-tree-page-view/
5
  Description: Adds a CMS-like tree view of all your pages, like the view often found in a page-focused CMS. By using the tree you can edit, view, add pages and even search pages (useful if you have many pages). And with drag and drop you can rearrange the order of your pages. Page management won't get any easier than this!
6
- Version: 0.7.4
7
  Author: Pär Thernström
8
  Author URI: http://eskapism.se/
9
  License: GPL2
@@ -27,7 +27,7 @@ License: GPL2
27
 
28
  require("functions.php");
29
 
30
- define( "CMS_TPV_VERSION", "0.7.4");
31
  define( "CMS_TPV_URL", WP_PLUGIN_URL . '/cms-tree-page-view/');
32
  define( "CMS_TPV_NAME", "CMS Tree Page View");
33
 
3
  Plugin Name: CMS Tree Page View
4
  Plugin URI: http://eskapism.se/code-playground/cms-tree-page-view/
5
  Description: Adds a CMS-like tree view of all your pages, like the view often found in a page-focused CMS. By using the tree you can edit, view, add pages and even search pages (useful if you have many pages). And with drag and drop you can rearrange the order of your pages. Page management won't get any easier than this!
6
+ Version: 0.7.5
7
  Author: Pär Thernström
8
  Author URI: http://eskapism.se/
9
  License: GPL2
27
 
28
  require("functions.php");
29
 
30
+ define( "CMS_TPV_VERSION", "0.7.5");
31
  define( "CMS_TPV_URL", WP_PLUGIN_URL . '/cms-tree-page-view/');
32
  define( "CMS_TPV_NAME", "CMS Tree Page View");
33
 
languages/cms-tree-page-view-sv_SE.mo CHANGED
Binary file
languages/cms-tree-page-view.pot CHANGED
@@ -8,7 +8,7 @@ msgid ""
8
  msgstr ""
9
  "Project-Id-Version: \n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/cms-tree-page-view\n"
11
- "POT-Creation-Date: 2010-08-19 16:53+0000\n"
12
  "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,198 +16,210 @@ msgstr ""
16
  "Content-Type: text/plain; charset=utf-8\n"
17
  "Content-Transfer-Encoding: 8bit\n"
18
 
19
- #: functions.php:51
20
  msgid "Enter title of new page"
21
  msgstr ""
22
 
23
- #: functions.php:52
24
  msgid "child pages"
25
  msgstr ""
26
 
27
- #: functions.php:53 functions.php:370
28
  msgid "Edit page"
29
  msgstr ""
30
 
31
- #: functions.php:54 functions.php:371
32
  msgid "View page"
33
  msgstr ""
34
 
35
- #: functions.php:55 functions.php:370
36
  msgid "Edit"
37
  msgstr ""
38
 
39
- #: functions.php:56 functions.php:371
40
  msgid "View"
41
  msgstr ""
42
 
43
- #: functions.php:57
44
  msgid "Add page"
45
  msgstr ""
46
 
47
- #: functions.php:58 functions.php:375
48
  msgid "Add new page after"
49
  msgstr ""
50
 
51
- #: functions.php:59
52
  msgid "after"
53
  msgstr ""
54
 
55
- #: functions.php:60
56
  msgid "inside"
57
  msgstr ""
58
 
59
- #: functions.php:61 functions.php:378
 
 
 
 
60
  msgid "Add new page inside"
61
  msgstr ""
62
 
63
- #: functions.php:62
64
  msgid "draft"
65
  msgstr ""
66
 
67
- #: functions.php:63
68
  msgid "future"
69
  msgstr ""
70
 
71
- #: functions.php:64
72
  msgid "protected"
73
  msgstr ""
74
 
75
- #: functions.php:65 functions.php:572
76
  msgid "pending"
77
  msgstr ""
78
 
79
- #: functions.php:66
80
  msgid "private"
81
  msgstr ""
82
 
83
- #: functions.php:67
84
  msgid "Password protected page"
85
  msgstr ""
86
 
87
- #: functions.php:168
 
 
 
 
88
  msgid "settings"
89
  msgstr ""
90
 
91
- #: functions.php:173
92
  msgid "Select where to show a tree for pages and custom post types"
93
  msgstr ""
94
 
95
- #: functions.php:197
96
  msgid "On dashboard"
97
  msgstr ""
98
 
99
- #: functions.php:201
100
  msgid "In menu"
101
  msgstr ""
102
 
103
- #: functions.php:212
104
  msgid "Save Changes"
105
  msgstr ""
106
 
107
- #: functions.php:329
108
  msgid "No posts found."
109
  msgstr ""
110
 
111
- #: functions.php:335
112
  msgid "All"
113
  msgstr ""
114
 
115
- #: functions.php:336
116
  msgid "Public"
117
  msgstr ""
118
 
119
- #: functions.php:341
120
  msgid "Expand"
121
  msgstr ""
122
 
123
- #: functions.php:342
124
  msgid "Collapse"
125
  msgstr ""
126
 
127
- #: functions.php:350
128
  msgid "Clear search"
129
  msgstr ""
130
 
131
- #: functions.php:351
132
  msgid "Search"
133
  msgstr ""
134
 
135
- #: functions.php:352
136
  msgid "Searching..."
137
  msgstr ""
138
 
139
- #: functions.php:353
140
  msgid "Nothing found."
141
  msgstr ""
142
 
143
- #: functions.php:359
144
  msgid "Loading..."
145
  msgstr ""
146
 
147
- #: functions.php:362
148
  msgid "Search: no pages found"
149
  msgstr ""
150
 
151
- #: functions.php:365
152
  msgid "Loading tree"
153
  msgstr ""
154
 
155
- #: functions.php:375
156
  msgid "After"
157
  msgstr ""
158
 
159
- #: functions.php:378
160
  msgid "Inside"
161
  msgstr ""
162
 
163
- #: functions.php:383
 
 
 
 
164
  msgid "Last modified"
165
  msgstr ""
166
 
167
- #: functions.php:385
168
  msgid "by"
169
  msgstr ""
170
 
171
- #: functions.php:388
172
  msgid "Page ID"
173
  msgstr ""
174
 
175
- #: functions.php:537
176
  msgid "Unknown user"
177
  msgstr ""
178
 
179
- #: functions.php:542
180
  msgid "<Untitled page>"
181
  msgstr ""
182
 
183
- #: functions.php:562
184
  msgid "Comments"
185
  msgstr ""
186
 
187
- #: functions.php:569
188
  #, php-format
189
  msgid "%s pending"
190
  msgstr ""
191
 
192
- #: functions.php:579
193
  msgctxt "comment count"
194
  msgid "0"
195
  msgstr ""
196
 
197
- #: functions.php:579
198
  msgctxt "comment count"
199
  msgid "1"
200
  msgstr ""
201
 
202
- #: functions.php:579
203
  msgctxt "comment count"
204
  msgid "%"
205
  msgstr ""
206
 
207
- #: functions.php:610
208
  msgid "Click to edit. Drag to move."
209
  msgstr ""
210
 
211
- #: functions.php:761
212
  msgid "New page"
213
  msgstr ""
8
  msgstr ""
9
  "Project-Id-Version: \n"
10
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/cms-tree-page-view\n"
11
+ "POT-Creation-Date: 2010-08-28 21:55+0000\n"
12
  "PO-Revision-Date: 2010-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
16
  "Content-Type: text/plain; charset=utf-8\n"
17
  "Content-Transfer-Encoding: 8bit\n"
18
 
19
+ #: functions.php:53
20
  msgid "Enter title of new page"
21
  msgstr ""
22
 
23
+ #: functions.php:54
24
  msgid "child pages"
25
  msgstr ""
26
 
27
+ #: functions.php:55 functions.php:376
28
  msgid "Edit page"
29
  msgstr ""
30
 
31
+ #: functions.php:56 functions.php:377
32
  msgid "View page"
33
  msgstr ""
34
 
35
+ #: functions.php:57 functions.php:376
36
  msgid "Edit"
37
  msgstr ""
38
 
39
+ #: functions.php:58 functions.php:377
40
  msgid "View"
41
  msgstr ""
42
 
43
+ #: functions.php:59
44
  msgid "Add page"
45
  msgstr ""
46
 
47
+ #: functions.php:60 functions.php:381
48
  msgid "Add new page after"
49
  msgstr ""
50
 
51
+ #: functions.php:61
52
  msgid "after"
53
  msgstr ""
54
 
55
+ #: functions.php:62
56
  msgid "inside"
57
  msgstr ""
58
 
59
+ #: functions.php:63
60
+ msgid "Sorry, can't create a sub page to a page with status \"draft\"."
61
+ msgstr ""
62
+
63
+ #: functions.php:64 functions.php:385
64
  msgid "Add new page inside"
65
  msgstr ""
66
 
67
+ #: functions.php:65
68
  msgid "draft"
69
  msgstr ""
70
 
71
+ #: functions.php:66
72
  msgid "future"
73
  msgstr ""
74
 
75
+ #: functions.php:67
76
  msgid "protected"
77
  msgstr ""
78
 
79
+ #: functions.php:68 functions.php:586
80
  msgid "pending"
81
  msgstr ""
82
 
83
+ #: functions.php:69
84
  msgid "private"
85
  msgstr ""
86
 
87
+ #: functions.php:70
88
  msgid "Password protected page"
89
  msgstr ""
90
 
91
+ #: functions.php:71
92
+ msgid "Adding page..."
93
+ msgstr ""
94
+
95
+ #: functions.php:172
96
  msgid "settings"
97
  msgstr ""
98
 
99
+ #: functions.php:177
100
  msgid "Select where to show a tree for pages and custom post types"
101
  msgstr ""
102
 
103
+ #: functions.php:201
104
  msgid "On dashboard"
105
  msgstr ""
106
 
107
+ #: functions.php:205
108
  msgid "In menu"
109
  msgstr ""
110
 
111
+ #: functions.php:216
112
  msgid "Save Changes"
113
  msgstr ""
114
 
115
+ #: functions.php:333
116
  msgid "No posts found."
117
  msgstr ""
118
 
119
+ #: functions.php:339
120
  msgid "All"
121
  msgstr ""
122
 
123
+ #: functions.php:340
124
  msgid "Public"
125
  msgstr ""
126
 
127
+ #: functions.php:345
128
  msgid "Expand"
129
  msgstr ""
130
 
131
+ #: functions.php:346
132
  msgid "Collapse"
133
  msgstr ""
134
 
135
+ #: functions.php:354
136
  msgid "Clear search"
137
  msgstr ""
138
 
139
+ #: functions.php:355
140
  msgid "Search"
141
  msgstr ""
142
 
143
+ #: functions.php:356
144
  msgid "Searching..."
145
  msgstr ""
146
 
147
+ #: functions.php:357
148
  msgid "Nothing found."
149
  msgstr ""
150
 
151
+ #: functions.php:363
152
  msgid "Loading..."
153
  msgstr ""
154
 
155
+ #: functions.php:366
156
  msgid "Search: no pages found"
157
  msgstr ""
158
 
159
+ #: functions.php:369
160
  msgid "Loading tree"
161
  msgstr ""
162
 
163
+ #: functions.php:381
164
  msgid "After"
165
  msgstr ""
166
 
167
+ #: functions.php:385
168
  msgid "Inside"
169
  msgstr ""
170
 
171
+ #: functions.php:389
172
+ msgid "Can not create page inside of a page with draft status"
173
+ msgstr ""
174
+
175
+ #: functions.php:392
176
  msgid "Last modified"
177
  msgstr ""
178
 
179
+ #: functions.php:394
180
  msgid "by"
181
  msgstr ""
182
 
183
+ #: functions.php:397
184
  msgid "Page ID"
185
  msgstr ""
186
 
187
+ #: functions.php:551
188
  msgid "Unknown user"
189
  msgstr ""
190
 
191
+ #: functions.php:556
192
  msgid "<Untitled page>"
193
  msgstr ""
194
 
195
+ #: functions.php:576
196
  msgid "Comments"
197
  msgstr ""
198
 
199
+ #: functions.php:583
200
  #, php-format
201
  msgid "%s pending"
202
  msgstr ""
203
 
204
+ #: functions.php:593
205
  msgctxt "comment count"
206
  msgid "0"
207
  msgstr ""
208
 
209
+ #: functions.php:593
210
  msgctxt "comment count"
211
  msgid "1"
212
  msgstr ""
213
 
214
+ #: functions.php:593
215
  msgctxt "comment count"
216
  msgid "%"
217
  msgstr ""
218
 
219
+ #: functions.php:624
220
  msgid "Click to edit. Drag to move."
221
  msgstr ""
222
 
223
+ #: functions.php:775
224
  msgid "New page"
225
  msgstr ""
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://eskapism.se/sida/donate/
4
  Tags: page, pages, posts, custom posts, tree, cms, dashboard, overview, drag-and-drop, rearrange, management, manage, admin
5
  Requires at least: 3.0
6
  Tested up to: 3.0
7
- Stable tag: trunk
8
 
9
  Adds a CMS-like tree overview of your pages or custom posts. Rearrange the order of your pages (with drag and drop). Also edit, view, add, and search your pages.
10
 
@@ -40,6 +40,7 @@ This plugin is available in the following languages:
40
  * English
41
  * German
42
  * French
 
43
  * Russian
44
  * Belorussian
45
  * Swedish
@@ -72,12 +73,21 @@ Now the tree with the pages will be visible both on the dashboard and in the men
72
 
73
  == Changelog ==
74
 
 
 
 
 
 
 
 
 
 
75
  = 0.7.4 =
76
  - Updated POT-file, so translators may wan't to check their translations.
77
  - Added Spanish translation by Carlos Janini. Thank you!
78
 
79
  = 0.7.3 =
80
- - a page can now be moved above a page with the same menu order. moved page will get the menu order of the page that it's moved aboved, and the other page will get a menu order of previous menu order + 1. i think/hope this is finaly solved now!
81
  - using wp_update_post when moving pages (instead of sql directly). this should make this plugin work better with some cache plugins, for example DB Cache Reloaded
82
  - root of tree is added initially, without the need to run an ajax query. loading the root of the tree = super fast! child nodes that are not previosly open are still loaded with ajax, because I want to be sure that the plugin does not hang if there is a page with super-mega-lots of children.
83
 
4
  Tags: page, pages, posts, custom posts, tree, cms, dashboard, overview, drag-and-drop, rearrange, management, manage, admin
5
  Requires at least: 3.0
6
  Tested up to: 3.0
7
+ Stable tag: 0.7.4
8
 
9
  Adds a CMS-like tree overview of your pages or custom posts. Rearrange the order of your pages (with drag and drop). Also edit, view, add, and search your pages.
10
 
40
  * English
41
  * German
42
  * French
43
+ * Spanish
44
  * Russian
45
  * Belorussian
46
  * Swedish
73
 
74
  == Changelog ==
75
 
76
+ = 0.7.5 =
77
+ - fixed some notice-errors and switched some deprecated functions
78
+ - updated swedish translation
79
+ - fixed some strings that where untranslatable and updated POT-file (if I missed any, please let me know)
80
+ - no longer allowed to add sub pages to a page with status draft, because if you edit the page and save it, wordpress will forget about the parent (and you will get confused)
81
+ - started using hoverIntent for popup instead of regular mouseover, so the popups won't feel so aggressive - or no.. reverted this :(
82
+ - when adding a page a text comes up so you know that something is going on
83
+ - possible fix for magic fields and other plugins that deal with post columns
84
+
85
  = 0.7.4 =
86
  - Updated POT-file, so translators may wan't to check their translations.
87
  - Added Spanish translation by Carlos Janini. Thank you!
88
 
89
  = 0.7.3 =
90
+ - a page can now be moved above a page with the same menu order. moved page will get the menu order of the page that it's moved aboved, and the other page will get a menu order of previous menu order + 1. i think/hope this is finally solved now!
91
  - using wp_update_post when moving pages (instead of sql directly). this should make this plugin work better with some cache plugins, for example DB Cache Reloaded
92
  - root of tree is added initially, without the need to run an ajax query. loading the root of the tree = super fast! child nodes that are not previosly open are still loaded with ajax, because I want to be sure that the plugin does not hang if there is a page with super-mega-lots of children.
93
 
scripts/cms_tree_page_view.js CHANGED
@@ -1,5 +1,6 @@
1
 
2
- var cms_tpv_tree, treeOptions, div_actions;
 
3
  jQuery(function($) {
4
 
5
  cms_tpv_tree = $(".cms_tpv_container");
@@ -113,7 +114,6 @@ jQuery(function($) {
113
  });
114
 
115
 
116
-
117
  }); // end ondomready
118
 
119
 
@@ -143,6 +143,7 @@ jQuery(".cms_tpv_action_add_page_after").live("click", function() {
143
  var selected_lang = cms_tpv_get_wpml_selected_lang(this);
144
  jPrompt(cmstpv_l10n.Enter_title_of_new_page, "", "CMS Tree Page View", function(new_page_title) {
145
  if (new_page_title) {
 
146
  var pageID = $this.parents("li:first").attr("id");
147
  jQuery.post(ajaxurl, {
148
  "action": "cms_tpv_add_page",
@@ -165,8 +166,20 @@ jQuery(".cms_tpv_action_add_page_inside").live("click", function() {
165
  var $this = jQuery(this);
166
  var post_type = cms_tpv_get_post_type(this);
167
  var selected_lang = cms_tpv_get_wpml_selected_lang(this);
 
 
 
 
 
 
 
 
 
 
 
168
  jPrompt(cmstpv_l10n.Enter_title_of_new_page, "", "CMS Tree Page View", function(new_page_title) {
169
  if (new_page_title) {
 
170
  var pageID = $this.parents("li:first").attr("id");
171
  jQuery.post(ajaxurl, {
172
  "action": "cms_tpv_add_page",
@@ -191,12 +204,13 @@ function cms_tpv_is_dragging() {
191
  return eDrag.is(":visible");
192
  }
193
 
194
- // mouse over, show actions
195
- jQuery(".jstree li").live("mouseover", function(e) {
196
 
197
- $li = jQuery(this);
198
-
199
- var div_actions_for_post_type = cms_tpv_get_page_actions_div(this);
 
200
 
201
  if (cms_tpv_is_dragging() == false) {
202
 
@@ -245,12 +259,55 @@ jQuery(".jstree li").live("mouseover", function(e) {
245
  div_actions_for_post_type.show();
246
  }
247
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  });
249
  // ..and hide them again
250
  jQuery(".jstree li").live("mouseout", function() {
251
- $li = jQuery(this);
252
- $li.find("a:first").removeClass("hover");
253
- div_actions.hide();
254
  });
255
 
256
 
1
 
2
+ // @todo: add prefix to treeOptions, div_actions
3
+ var cms_tpv_tree, treeOptions, div_actions, cms_tpv_current_li_id = null;
4
  jQuery(function($) {
5
 
6
  cms_tpv_tree = $(".cms_tpv_container");
114
  });
115
 
116
 
 
117
  }); // end ondomready
118
 
119
 
143
  var selected_lang = cms_tpv_get_wpml_selected_lang(this);
144
  jPrompt(cmstpv_l10n.Enter_title_of_new_page, "", "CMS Tree Page View", function(new_page_title) {
145
  if (new_page_title) {
146
+ $this.closest(".cms_tpv_container").html(cmstpv_l10n.Adding_page);
147
  var pageID = $this.parents("li:first").attr("id");
148
  jQuery.post(ajaxurl, {
149
  "action": "cms_tpv_add_page",
166
  var $this = jQuery(this);
167
  var post_type = cms_tpv_get_post_type(this);
168
  var selected_lang = cms_tpv_get_wpml_selected_lang(this);
169
+
170
+ // check page status, because we cant add a page inside a page with status draft
171
+ // if we edit the page wordpress will forget the parent
172
+ //$li.data("jstree").permalink;
173
+ //var post_status = li.data("jstree").post_status;
174
+ var post_status = $this.closest("li").data("jstree").post_status;
175
+ if (post_status == "draft") {
176
+ jAlert(cmstpv_l10n.Can_not_add_sub_page_when_status_is_draft);
177
+ return false;
178
+ }
179
+
180
  jPrompt(cmstpv_l10n.Enter_title_of_new_page, "", "CMS Tree Page View", function(new_page_title) {
181
  if (new_page_title) {
182
+ $this.closest(".cms_tpv_container").html(cmstpv_l10n.Adding_page);
183
  var pageID = $this.parents("li:first").attr("id");
184
  jQuery.post(ajaxurl, {
185
  "action": "cms_tpv_add_page",
204
  return eDrag.is(":visible");
205
  }
206
 
207
+ // fired when mouse is over li
208
+ function cms_tpv_mouseover_li(li) {
209
 
210
+ //console.log("show actions div");
211
+ $li = jQuery(li);
212
+
213
+ var div_actions_for_post_type = cms_tpv_get_page_actions_div(li);
214
 
215
  if (cms_tpv_is_dragging() == false) {
216
 
259
  div_actions_for_post_type.show();
260
  }
261
  }
262
+
263
+ }
264
+
265
+ // fired when mouse leaves li
266
+ function cms_tpv_mouseout_li(li) {
267
+ $li = jQuery(li);
268
+ $li.find("a:first").removeClass("hover");
269
+ div_actions.hide();
270
+ }
271
+
272
+ // mouse over, show actions
273
+ // but only if the mouse not already is over the li (don't know why it fires multiple times, but it does)
274
+ // 29 August, 2010 this worked nice but it had problems with child-lis...
275
+ /*
276
+ jQuery(".jstree li").live("mouseenter", function(e) {
277
+
278
+ //console.log("mouseenter");
279
+ var $li = jQuery(this);
280
+ var li_id = $li.attr("id");
281
+
282
+ // add hoverIntent, if not prev. attached
283
+ if ($li.data("hasHoverIntent")) {
284
+ // already got it
285
+ } else {
286
+ $li.data("hasHoverIntent", true);
287
+ $li.hoverIntent(function() {
288
+ // console.log("over");
289
+ cms_tpv_mouseover_li(this);
290
+ }, function() {
291
+ console.log("out");
292
+ //cms_tpv_mouseout_li(this);
293
+ });
294
+ // lastlt trigger mouseenter again so the popup will show
295
+ $li.trigger("mouseover");
296
+ }
297
+
298
+ });
299
+ */
300
+
301
+ jQuery(".jstree li").live("mouseover", function(e) {
302
+ var $li = jQuery(this);
303
+ var li_id = $li.attr("id");
304
+ cms_tpv_mouseover_li(this);
305
  });
306
  // ..and hide them again
307
  jQuery(".jstree li").live("mouseout", function() {
308
+ //cms_tpv_current_li_id = null;
309
+ //console.log("out");
310
+ cms_tpv_mouseout_li(this);
311
  });
312
 
313
 
scripts/jquery.hoverIntent.minified.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
3
+ * <http://cherne.net/brian/resources/jquery.hoverIntent.html>
4
+ *
5
+ * @param f onMouseOver function || An object with configuration options
6
+ * @param g onMouseOut function || Nothing (use configuration options object)
7
+ * @author Brian Cherne <brian@cherne.net>
8
+ */
9
+ (function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);