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 | 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 +1529 -0
- FirePHPCore/FirePHP.class.php4 +1292 -0
- FirePHPCore/LICENSE +29 -0
- FirePHPCore/fb.php +261 -0
- FirePHPCore/fb.php4 +251 -0
- functions.php +24 -10
- index.php +2 -2
- languages/cms-tree-page-view-sv_SE.mo +0 -0
- languages/cms-tree-page-view.pot +61 -49
- readme.txt +12 -2
- scripts/cms_tree_page_view.js +67 -10
- scripts/jquery.hoverIntent.minified.js +9 -0
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 =
|
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 =
|
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.
|
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.
|
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-
|
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:
|
20 |
msgid "Enter title of new page"
|
21 |
msgstr ""
|
22 |
|
23 |
-
#: functions.php:
|
24 |
msgid "child pages"
|
25 |
msgstr ""
|
26 |
|
27 |
-
#: functions.php:
|
28 |
msgid "Edit page"
|
29 |
msgstr ""
|
30 |
|
31 |
-
#: functions.php:
|
32 |
msgid "View page"
|
33 |
msgstr ""
|
34 |
|
35 |
-
#: functions.php:
|
36 |
msgid "Edit"
|
37 |
msgstr ""
|
38 |
|
39 |
-
#: functions.php:
|
40 |
msgid "View"
|
41 |
msgstr ""
|
42 |
|
43 |
-
#: functions.php:
|
44 |
msgid "Add page"
|
45 |
msgstr ""
|
46 |
|
47 |
-
#: functions.php:
|
48 |
msgid "Add new page after"
|
49 |
msgstr ""
|
50 |
|
51 |
-
#: functions.php:
|
52 |
msgid "after"
|
53 |
msgstr ""
|
54 |
|
55 |
-
#: functions.php:
|
56 |
msgid "inside"
|
57 |
msgstr ""
|
58 |
|
59 |
-
#: functions.php:
|
|
|
|
|
|
|
|
|
60 |
msgid "Add new page inside"
|
61 |
msgstr ""
|
62 |
|
63 |
-
#: functions.php:
|
64 |
msgid "draft"
|
65 |
msgstr ""
|
66 |
|
67 |
-
#: functions.php:
|
68 |
msgid "future"
|
69 |
msgstr ""
|
70 |
|
71 |
-
#: functions.php:
|
72 |
msgid "protected"
|
73 |
msgstr ""
|
74 |
|
75 |
-
#: functions.php:
|
76 |
msgid "pending"
|
77 |
msgstr ""
|
78 |
|
79 |
-
#: functions.php:
|
80 |
msgid "private"
|
81 |
msgstr ""
|
82 |
|
83 |
-
#: functions.php:
|
84 |
msgid "Password protected page"
|
85 |
msgstr ""
|
86 |
|
87 |
-
#: functions.php:
|
|
|
|
|
|
|
|
|
88 |
msgid "settings"
|
89 |
msgstr ""
|
90 |
|
91 |
-
#: functions.php:
|
92 |
msgid "Select where to show a tree for pages and custom post types"
|
93 |
msgstr ""
|
94 |
|
95 |
-
#: functions.php:
|
96 |
msgid "On dashboard"
|
97 |
msgstr ""
|
98 |
|
99 |
-
#: functions.php:
|
100 |
msgid "In menu"
|
101 |
msgstr ""
|
102 |
|
103 |
-
#: functions.php:
|
104 |
msgid "Save Changes"
|
105 |
msgstr ""
|
106 |
|
107 |
-
#: functions.php:
|
108 |
msgid "No posts found."
|
109 |
msgstr ""
|
110 |
|
111 |
-
#: functions.php:
|
112 |
msgid "All"
|
113 |
msgstr ""
|
114 |
|
115 |
-
#: functions.php:
|
116 |
msgid "Public"
|
117 |
msgstr ""
|
118 |
|
119 |
-
#: functions.php:
|
120 |
msgid "Expand"
|
121 |
msgstr ""
|
122 |
|
123 |
-
#: functions.php:
|
124 |
msgid "Collapse"
|
125 |
msgstr ""
|
126 |
|
127 |
-
#: functions.php:
|
128 |
msgid "Clear search"
|
129 |
msgstr ""
|
130 |
|
131 |
-
#: functions.php:
|
132 |
msgid "Search"
|
133 |
msgstr ""
|
134 |
|
135 |
-
#: functions.php:
|
136 |
msgid "Searching..."
|
137 |
msgstr ""
|
138 |
|
139 |
-
#: functions.php:
|
140 |
msgid "Nothing found."
|
141 |
msgstr ""
|
142 |
|
143 |
-
#: functions.php:
|
144 |
msgid "Loading..."
|
145 |
msgstr ""
|
146 |
|
147 |
-
#: functions.php:
|
148 |
msgid "Search: no pages found"
|
149 |
msgstr ""
|
150 |
|
151 |
-
#: functions.php:
|
152 |
msgid "Loading tree"
|
153 |
msgstr ""
|
154 |
|
155 |
-
#: functions.php:
|
156 |
msgid "After"
|
157 |
msgstr ""
|
158 |
|
159 |
-
#: functions.php:
|
160 |
msgid "Inside"
|
161 |
msgstr ""
|
162 |
|
163 |
-
#: functions.php:
|
|
|
|
|
|
|
|
|
164 |
msgid "Last modified"
|
165 |
msgstr ""
|
166 |
|
167 |
-
#: functions.php:
|
168 |
msgid "by"
|
169 |
msgstr ""
|
170 |
|
171 |
-
#: functions.php:
|
172 |
msgid "Page ID"
|
173 |
msgstr ""
|
174 |
|
175 |
-
#: functions.php:
|
176 |
msgid "Unknown user"
|
177 |
msgstr ""
|
178 |
|
179 |
-
#: functions.php:
|
180 |
msgid "<Untitled page>"
|
181 |
msgstr ""
|
182 |
|
183 |
-
#: functions.php:
|
184 |
msgid "Comments"
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: functions.php:
|
188 |
#, php-format
|
189 |
msgid "%s pending"
|
190 |
msgstr ""
|
191 |
|
192 |
-
#: functions.php:
|
193 |
msgctxt "comment count"
|
194 |
msgid "0"
|
195 |
msgstr ""
|
196 |
|
197 |
-
#: functions.php:
|
198 |
msgctxt "comment count"
|
199 |
msgid "1"
|
200 |
msgstr ""
|
201 |
|
202 |
-
#: functions.php:
|
203 |
msgctxt "comment count"
|
204 |
msgid "%"
|
205 |
msgstr ""
|
206 |
|
207 |
-
#: functions.php:
|
208 |
msgid "Click to edit. Drag to move."
|
209 |
msgstr ""
|
210 |
|
211 |
-
#: functions.php:
|
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:
|
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
|
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 |
-
|
|
|
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
|
195 |
-
|
196 |
|
197 |
-
|
198 |
-
|
199 |
-
|
|
|
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 |
-
|
252 |
-
|
253 |
-
|
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);
|