소스 검색

auto-push

Coldiary 5 년 전
부모
커밋
83e3273ea4
100개의 변경된 파일11026개의 추가작업 그리고 0개의 파일을 삭제
  1. 6
    0
      .htaccess
  2. 16
    0
      Plugin/DebugKit/.gitignore
  3. 84
    0
      Plugin/DebugKit/.jshintrc
  4. 84
    0
      Plugin/DebugKit/.travis.yml
  5. 159
    0
      Plugin/DebugKit/Console/Command/BenchmarkShell.php
  6. 93
    0
      Plugin/DebugKit/Console/Command/WhitespaceShell.php
  7. 504
    0
      Plugin/DebugKit/Controller/Component/ToolbarComponent.php
  8. 25
    0
      Plugin/DebugKit/Controller/DebugKitAppController.php
  9. 121
    0
      Plugin/DebugKit/Controller/ToolbarAccessController.php
  10. 28
    0
      Plugin/DebugKit/LICENSE.txt
  11. 227
    0
      Plugin/DebugKit/Lib/DebugKitDebugger.php
  12. 98
    0
      Plugin/DebugKit/Lib/DebugMemory.php
  13. 84
    0
      Plugin/DebugKit/Lib/DebugPanel.php
  14. 201
    0
      Plugin/DebugKit/Lib/DebugTimer.php
  15. 538
    0
      Plugin/DebugKit/Lib/FireCake.php
  16. 50
    0
      Plugin/DebugKit/Lib/Log/Engine/DebugKitLog.php
  17. 81
    0
      Plugin/DebugKit/Lib/Panel/EnvironmentPanel.php
  18. 83
    0
      Plugin/DebugKit/Lib/Panel/HistoryPanel.php
  19. 160
    0
      Plugin/DebugKit/Lib/Panel/IncludePanel.php
  20. 51
    0
      Plugin/DebugKit/Lib/Panel/LogPanel.php
  21. 41
    0
      Plugin/DebugKit/Lib/Panel/RequestPanel.php
  22. 32
    0
      Plugin/DebugKit/Lib/Panel/SessionPanel.php
  23. 64
    0
      Plugin/DebugKit/Lib/Panel/SqlLogPanel.php
  24. 36
    0
      Plugin/DebugKit/Lib/Panel/TimerPanel.php
  25. 31
    0
      Plugin/DebugKit/Lib/Panel/VariablesPanel.php
  26. 138
    0
      Plugin/DebugKit/Locale/debug_kit.pot
  27. 135
    0
      Plugin/DebugKit/Locale/eng/LC_MESSAGES/debug_kit.po
  28. 135
    0
      Plugin/DebugKit/Locale/fra/LC_MESSAGES/debug_kit.po
  29. 136
    0
      Plugin/DebugKit/Locale/lim/LC_MESSAGES/debug_kit.po
  30. 141
    0
      Plugin/DebugKit/Locale/nld/LC_MESSAGES/debug_kit.po
  31. 135
    0
      Plugin/DebugKit/Locale/spa/LC_MESSAGES/debug_kit.po
  32. 102
    0
      Plugin/DebugKit/Model/Behavior/TimedBehavior.php
  33. 24
    0
      Plugin/DebugKit/Model/DebugKitAppModel.php
  34. 56
    0
      Plugin/DebugKit/Model/ToolbarAccess.php
  35. 299
    0
      Plugin/DebugKit/README.md
  36. 40
    0
      Plugin/DebugKit/Test/Case/AllDebugKitTest.php
  37. 40
    0
      Plugin/DebugKit/Test/Case/AllDebugKitViewTest.php
  38. 40
    0
      Plugin/DebugKit/Test/Case/AllDebugKitWithoutViewTest.php
  39. 40
    0
      Plugin/DebugKit/Test/Case/AllTestsTest.php
  40. 524
    0
      Plugin/DebugKit/Test/Case/Controller/Component/ToolbarComponentTest.php
  41. 79
    0
      Plugin/DebugKit/Test/Case/DebugkitGroupTestCase.php
  42. 76
    0
      Plugin/DebugKit/Test/Case/Lib/DebugKitDebuggerTest.php
  43. 65
    0
      Plugin/DebugKit/Test/Case/Lib/DebugMemoryTest.php
  44. 169
    0
      Plugin/DebugKit/Test/Case/Lib/DebugTimerTest.php
  45. 345
    0
      Plugin/DebugKit/Test/Case/Lib/FireCakeTest.php
  46. 63
    0
      Plugin/DebugKit/Test/Case/Lib/Panel/LogPanelTest.php
  47. 59
    0
      Plugin/DebugKit/Test/Case/Lib/Panel/SqlLogPanelTest.php
  48. 89
    0
      Plugin/DebugKit/Test/Case/Model/Behavior/TimedBehaviorTest.php
  49. 69
    0
      Plugin/DebugKit/Test/Case/Model/ToolbarAccessTest.php
  50. 65
    0
      Plugin/DebugKit/Test/Case/TestFireCake.php
  51. 152
    0
      Plugin/DebugKit/Test/Case/View/Helper/FirePhpToolbarHelperTest.php
  52. 452
    0
      Plugin/DebugKit/Test/Case/View/Helper/HtmlToolbarHelperTest.php
  53. 179
    0
      Plugin/DebugKit/Test/Case/View/Helper/ToolbarHelperTest.php
  54. 63
    0
      Plugin/DebugKit/Test/test_app/Controller/DebugKitTestController.php
  55. 37
    0
      Plugin/DebugKit/Test/test_app/Lib/Panel/TestPanel.php
  56. 26
    0
      Plugin/DebugKit/Test/test_app/Plugin/DebugkitTestPlugin/Lib/Panel/PluginTestPanel.php
  57. 18
    0
      Plugin/DebugKit/Test/test_app/View/DebugKitTest/request_action_render.ctp
  58. 1
    0
      Plugin/DebugKit/VERSION.txt
  59. 59
    0
      Plugin/DebugKit/View/Elements/debug_toolbar.ctp
  60. 84
    0
      Plugin/DebugKit/View/Elements/environment_panel.ctp
  61. 32
    0
      Plugin/DebugKit/View/Elements/history_panel.ctp
  62. 34
    0
      Plugin/DebugKit/View/Elements/include_panel.ctp
  63. 41
    0
      Plugin/DebugKit/View/Elements/log_panel.ctp
  64. 50
    0
      Plugin/DebugKit/View/Elements/request_panel.ctp
  65. 20
    0
      Plugin/DebugKit/View/Elements/session_panel.ctp
  66. 80
    0
      Plugin/DebugKit/View/Elements/sql_log_panel.ctp
  67. 110
    0
      Plugin/DebugKit/View/Elements/timer_panel.ctp
  68. 23
    0
      Plugin/DebugKit/View/Elements/variables_panel.ctp
  69. 90
    0
      Plugin/DebugKit/View/Helper/DebugTimerHelper.php
  70. 106
    0
      Plugin/DebugKit/View/Helper/FirePhpToolbarHelper.php
  71. 238
    0
      Plugin/DebugKit/View/Helper/HtmlToolbarHelper.php
  72. 88
    0
      Plugin/DebugKit/View/Helper/SimpleGraphHelper.php
  73. 171
    0
      Plugin/DebugKit/View/Helper/TidyHelper.php
  74. 226
    0
      Plugin/DebugKit/View/Helper/ToolbarHelper.php
  75. 30
    0
      Plugin/DebugKit/View/ToolbarAccess/history_state.ctp
  76. 11
    0
      Plugin/DebugKit/View/ToolbarAccess/sql_explain.ctp
  77. 35
    0
      Plugin/DebugKit/composer.json
  78. 382
    0
      Plugin/DebugKit/webroot/css/debug_toolbar.css
  79. BIN
      Plugin/DebugKit/webroot/img/cake.icon.png
  80. 4
    0
      Plugin/DebugKit/webroot/js/jquery.js
  81. 936
    0
      Plugin/DebugKit/webroot/js/js_debug_toolbar.js
  82. 5
    0
      app/.htaccess
  83. 80
    0
      app/Config/Schema/db_acl.php
  84. 52
    0
      app/Config/Schema/db_acl.sql
  85. 71
    0
      app/Config/Schema/i18n.php
  86. 27
    0
      app/Config/Schema/i18n.sql
  87. 65
    0
      app/Config/Schema/sessions.php
  88. 17
    0
      app/Config/Schema/sessions.sql
  89. 57
    0
      app/Config/acl.ini.php
  90. 124
    0
      app/Config/acl.php
  91. 95
    0
      app/Config/bootstrap.php
  92. 361
    0
      app/Config/core.php
  93. 75
    0
      app/Config/database.php
  94. 82
    0
      app/Config/email.php.default
  95. 36
    0
      app/Config/routes.php
  96. 21
    0
      app/Console/Command/AppShell.php
  97. 41
    0
      app/Console/cake
  98. 30
    0
      app/Console/cake.bat
  99. 48
    0
      app/Console/cake.php
  100. 0
    0
      app/Controller/AppController.php

+ 6
- 0
.htaccess 파일 보기

1
+<IfModule mod_rewrite.c>
2
+   RewriteEngine on
3
+   RewriteRule    ^$ app/webroot/    [L]
4
+   RewriteRule    (.*) app/webroot/$1 [L]
5
+</IfModule>
6
+Options -Indexes

+ 16
- 0
Plugin/DebugKit/.gitignore 파일 보기

1
+*.diff
2
+*.err
3
+*.orig
4
+*.rej
5
+*.swo
6
+*.swp
7
+*.vi
8
+*~
9
+.DS_Store
10
+.cache
11
+.project
12
+.settings
13
+.svn
14
+errors.err
15
+tags
16
+/nbproject/

+ 84
- 0
Plugin/DebugKit/.jshintrc 파일 보기

1
+{
2
+    // JSHint Default Configuration File (as on JSHint website)
3
+    // See http://jshint.com/docs/ for more details
4
+
5
+    "maxerr"        : 500,      // {int} Maximum error before stopping
6
+
7
+    // Enforcing
8
+    "bitwise"       : true,     // true: Prohibit bitwise operators (&, |, ^, etc.)
9
+    "camelcase"     : true,     // true: Identifiers must be in camelCase
10
+    "curly"         : true,     // true: Require {} for every new block or scope
11
+    "eqeqeq"        : true,     // true: Require triple equals (===) for comparison
12
+    "forin"         : true,     // true: Require filtering for..in loops with obj.hasOwnProperty()
13
+    "immed"         : true,     // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
14
+    "indent"        : 2,        // {int} Number of spaces to use for indentation
15
+    "latedef"       : false,    // true: Require variables/functions to be defined before being used
16
+    "newcap"        : true,     // true: Require capitalization of all constructor functions e.g. `new F()`
17
+    "noarg"         : true,     // true: Prohibit use of `arguments.caller` and `arguments.callee`
18
+    "noempty"       : true,     // true: Prohibit use of empty blocks
19
+    "nonew"         : true,     // true: Prohibit use of constructors for side-effects (without assignment)
20
+    "plusplus"      : false,    // true: Prohibit use of `++` & `--`
21
+    "quotmark"      : "single", // Quotation mark consistency:
22
+                                //   false    : do nothing (default)
23
+                                //   true     : ensure whatever is used is consistent
24
+                                //   "single" : require single quotes
25
+                                //   "double" : require double quotes
26
+    "undef"         : true,     // true: Require all non-global variables to be declared (prevents global leaks)
27
+    "unused"        : true,     // true: Require all defined variables be used
28
+    "strict"        : true,     // true: Requires all functions run in ES5 Strict Mode
29
+    "trailing"      : true,     // true: Prohibit trailing whitespaces
30
+    "maxparams"     : false,    // {int} Max number of formal params allowed per function
31
+    "maxdepth"      : false,    // {int} Max depth of nested blocks (within functions)
32
+    "maxstatements" : false,    // {int} Max number statements per function
33
+    "maxcomplexity" : false,    // {int} Max cyclomatic complexity per function
34
+    "maxlen"        : 120,      // {int} Max number of characters per line
35
+
36
+    // Relaxing
37
+    "asi"           : false,    // true: Tolerate Automatic Semicolon Insertion (no semicolons)
38
+    "boss"          : false,    // true: Tolerate assignments where comparisons would be expected
39
+    "debug"         : false,    // true: Allow debugger statements e.g. browser breakpoints.
40
+    "eqnull"        : false,    // true: Tolerate use of `== null`
41
+    "es5"           : false,    // true: Allow ES5 syntax (ex: getters and setters)
42
+    "esnext"        : false,    // true: Allow ES.next (ES6) syntax (ex: `const`)
43
+    "evil"          : false,    // true: Tolerate use of `eval` and `new Function()`
44
+    "expr"          : false,    // true: Tolerate `ExpressionStatement` as Programs
45
+    "funcscope"     : false,    // true: Tolerate defining variables inside control statements"
46
+    "globalstrict"  : false,    // true: Allow global "use strict" (also enables 'strict')
47
+    "iterator"      : false,    // true: Tolerate using the `__iterator__` property
48
+    "lastsemic"     : false,    // true: Tolerate omitting a semicolon for the last statement of a 1-line block
49
+    "laxbreak"      : false,    // true: Tolerate possibly unsafe line breakings
50
+    "laxcomma"      : false,    // true: Tolerate comma-first style coding
51
+    "loopfunc"      : false,    // true: Tolerate functions being defined in loops
52
+    "multistr"      : false,    // true: Tolerate multi-line strings
53
+    "proto"         : false,    // true: Tolerate using the `__proto__` property
54
+    "scripturl"     : false,    // true: Tolerate script-targeted URLs
55
+    "smarttabs"     : false,    // true: Tolerate mixed tabs/spaces when used for alignment
56
+    "shadow"        : false,    // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
57
+    "sub"           : false,    // true: Tolerate using `[]` notation when it can still be expressed in dot notation
58
+    "supernew"      : false,    // true: Tolerate `new function () { ... };` and `new Object;`
59
+    "validthis"     : false,    // true: Tolerate using this in a non-constructor function
60
+
61
+    // Environments
62
+    "browser"       : true,     // Web Browser (window, document, etc)
63
+    "couch"         : false,    // CouchDB
64
+    "devel"         : true,     // Development/debugging (alert, confirm, etc)
65
+    "dojo"          : false,    // Dojo Toolkit
66
+    "jquery"        : false,    // jQuery
67
+    "mootools"      : false,    // MooTools
68
+    "node"          : false,    // Node.js
69
+    "nonstandard"   : false,    // Widely adopted globals (escape, unescape, etc)
70
+    "prototypejs"   : false,    // Prototype and Scriptaculous
71
+    "rhino"         : false,    // Rhino
72
+    "worker"        : false,    // Web Workers
73
+    "wsh"           : false,    // Windows Scripting Host
74
+    "yui"           : false,    // Yahoo User Interface
75
+
76
+    // Legacy
77
+    "nomen"         : false,    // true: Prohibit dangling `_` in variables
78
+    "onevar"        : false,    // true: Allow only one `var` statement per function
79
+    "passfail"      : false,    // true: Stop on first error
80
+    "white"         : true,     // true: Check against strict whitespace and indentation rules
81
+
82
+    // Custom Globals
83
+    "predef"        : [ ]       // additional predefined global variables
84
+}

+ 84
- 0
Plugin/DebugKit/.travis.yml 파일 보기

1
+language: php
2
+
3
+php:
4
+  - 5.3
5
+  - 5.4
6
+  - 5.5
7
+
8
+env:
9
+  - CAKE_VERSION=2.3.10 DB=mysql
10
+  - CAKE_VERSION=2.3.10 DB=pgsql
11
+  - CAKE_VERSION=2.4.10 DB=mysql
12
+  - CAKE_VERSION=2.4.10 DB=pgsql
13
+  - CAKE_VERSION=2.6 DB=mysql
14
+  - CAKE_VERSION=2.6 DB=pgsql
15
+
16
+install:
17
+  - git clone git://github.com/cakephp/cakephp ../cakephp && cd ../cakephp && git checkout $CAKE_VERSION
18
+  - cp -R ../debug_kit plugins/DebugKit
19
+  - chmod -R 777 ../cakephp/app/tmp
20
+  - sh -c "composer global require 'phpunit/phpunit=3.7.33'"
21
+  - sh -c "ln -s ~/.composer/vendor/phpunit/phpunit/PHPUnit ../cakephp/vendors/PHPUnit"
22
+
23
+before_script:
24
+  - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi"
25
+  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi"
26
+  - set +H
27
+  - echo "<?php
28
+    class DATABASE_CONFIG {
29
+    private \$identities = array(
30
+      'mysql' => array(
31
+        'datasource' => 'Database/Mysql',
32
+        'host' => '0.0.0.0',
33
+        'login' => 'travis'
34
+      ),
35
+      'pgsql' => array(
36
+        'datasource' => 'Database/Postgres',
37
+        'host' => '127.0.0.1',
38
+        'login' => 'postgres',
39
+        'database' => 'cakephp_test',
40
+        'schema' => array(
41
+          'default' => 'public',
42
+          'test' => 'public'
43
+        )
44
+      )
45
+    );
46
+    public \$default = array(
47
+      'persistent' => false,
48
+      'host' => '',
49
+      'login' => '',
50
+      'password' => '',
51
+      'database' => 'cakephp_test',
52
+      'prefix' => ''
53
+    );
54
+    public \$test = array(
55
+      'persistent' => false,
56
+      'host' => '',
57
+      'login' => '',
58
+      'password' => '',
59
+      'database' => 'cakephp_test',
60
+      'prefix' => ''
61
+    );
62
+    public function __construct() {
63
+      \$db = 'mysql';
64
+      if (!empty(\$_SERVER['DB'])) {
65
+        \$db = \$_SERVER['DB'];
66
+      }
67
+      foreach (array('default', 'test') as \$source) {
68
+        \$config = array_merge(\$this->{\$source}, \$this->identities[\$db]);
69
+        if (is_array(\$config['database'])) {
70
+          \$config['database'] = \$config['database'][\$source];
71
+        }
72
+        if (!empty(\$config['schema']) && is_array(\$config['schema'])) {
73
+          \$config['schema'] = \$config['schema'][\$source];
74
+        }
75
+        \$this->{\$source} = \$config;
76
+      }
77
+    }
78
+    }" > ../cakephp/app/Config/database.php
79
+
80
+script:
81
+  - ./lib/Cake/Console/cake test DebugKit AllDebugKit --stderr
82
+
83
+notifications:
84
+  email: false

+ 159
- 0
Plugin/DebugKit/Console/Command/BenchmarkShell.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.0
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('String', 'Utility');
16
+
17
+/**
18
+ * Benchmark Shell Class
19
+ *
20
+ * Provides basic benchmarking of application requests
21
+ * functionally similar to Apache AB
22
+ *
23
+ * @since         DebugKit 1.0
24
+ * @todo Print/export time detail information
25
+ * @todo Export/graphing of data to .dot format for graphviz visualization
26
+ * @todo Make calculated results round to leading significant digit position of std dev.
27
+ */
28
+class BenchmarkShell extends Shell {
29
+
30
+/**
31
+ * Main execution of shell
32
+ *
33
+ * @return void
34
+ */
35
+	public function main() {
36
+		$url = $this->args[0];
37
+		$defaults = array('t' => 100, 'n' => 10);
38
+		$options = array_merge($defaults, $this->params);
39
+		$times = array();
40
+
41
+		$this->out(String::insert(__d('debug_kit', '-> Testing :url'), compact('url')));
42
+		$this->out("");
43
+		for ($i = 0; $i < $options['n']; $i++) {
44
+			if (floor($options['t'] - array_sum($times)) <= 0 || $options['n'] <= 1) {
45
+				break;
46
+			}
47
+
48
+			$start = microtime(true);
49
+			file_get_contents($url);
50
+			$stop = microtime(true);
51
+
52
+			$times[] = $stop - $start;
53
+		}
54
+		$this->_results($times);
55
+	}
56
+
57
+/**
58
+ * Prints calculated results
59
+ *
60
+ * @param array $times Array of time values
61
+ * @return void
62
+ */
63
+	protected function _results($times) {
64
+		$duration = array_sum($times);
65
+		$requests = count($times);
66
+
67
+		$this->out(String::insert(__d('debug_kit', 'Total Requests made: :requests'), compact('requests')));
68
+		$this->out(String::insert(__d('debug_kit', 'Total Time elapsed: :duration (seconds)'), compact('duration')));
69
+
70
+		$this->out("");
71
+
72
+		$this->out(String::insert(__d('debug_kit', 'Requests/Second: :rps req/sec'), array(
73
+				'rps' => round($requests / $duration, 3)
74
+		)));
75
+
76
+		$this->out(String::insert(__d('debug_kit', 'Average request time: :average-time seconds'), array(
77
+				'average-time' => round($duration / $requests, 3)
78
+		)));
79
+
80
+		$this->out(String::insert(__d('debug_kit', 'Standard deviation of average request time: :std-dev'), array(
81
+				'std-dev' => round($this->_deviation($times, true), 3)
82
+		)));
83
+
84
+		$this->out(String::insert(__d('debug_kit', 'Longest/shortest request: :longest sec/:shortest sec'), array(
85
+				'longest' => round(max($times), 3),
86
+				'shortest' => round(min($times), 3)
87
+		)));
88
+
89
+		$this->out("");
90
+	}
91
+
92
+/**
93
+ * One-pass, numerically stable calculation of population variance.
94
+ *
95
+ * Donald E. Knuth (1998).
96
+ * The Art of Computer Programming, volume 2: Seminumerical Algorithms, 3rd edn.,
97
+ * p. 232. Boston: Addison-Wesley.
98
+ *
99
+ * @param array $times Array of values
100
+ * @param boolean $sample If true, calculates an unbiased estimate of the population
101
+ * 						  variance from a finite sample.
102
+ * @return float Variance
103
+ */
104
+	protected function _variance($times, $sample = true) {
105
+		$n = $mean = $M2 = 0;
106
+
107
+		foreach ($times as $time) {
108
+			$n += 1;
109
+			$delta = $time - $mean;
110
+			$mean = $mean + $delta / $n;
111
+			$M2 = $M2 + $delta * ($time - $mean);
112
+		}
113
+
114
+		if ($sample) {
115
+			$n -= 1;
116
+		}
117
+
118
+		return $M2 / $n;
119
+	}
120
+
121
+/**
122
+ * Calculate the standard deviation.
123
+ *
124
+ * @param array $times Array of values
125
+ * @param boolean $sample
126
+ * @return float Standard deviation
127
+ */
128
+	protected function _deviation($times, $sample = true) {
129
+		return sqrt($this->_variance($times, $sample));
130
+	}
131
+
132
+	public function getOptionParser() {
133
+		$parser = parent::getOptionParser();
134
+		$parser->description(__d('debug_kit',
135
+			'Allows you to obtain some rough benchmarking statistics' .
136
+			'about a fully qualified URL.'
137
+		))
138
+		->addArgument('url', array(
139
+			'help' => __d('debug_kit', 'The URL to request.'),
140
+			'required' => true
141
+		))
142
+		->addOption('n', array(
143
+			'default' => 10,
144
+			'help' => __d('debug_kit', 'Number of iterations to perform.')
145
+		))
146
+		->addOption('t', array(
147
+			'default' => 100,
148
+			'help' => __d('debug_kit', 'Maximum total time for all iterations, in seconds.' .
149
+				'If a single iteration takes more than the timeout, only one request will be made'
150
+			)
151
+		))
152
+		->epilog(__d('debug_kit',
153
+			'Example Use: `cake benchmark --n 10 --t 100 http://localhost/testsite`. ' .
154
+			'<info>Note:</info> this benchmark does not include browser render times.'
155
+		));
156
+		return $parser;
157
+	}
158
+}
159
+

+ 93
- 0
Plugin/DebugKit/Console/Command/WhitespaceShell.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.3
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+App::uses('Folder', 'Utility');
15
+
16
+/**
17
+ * Whitespace shell. Helps find and trim whitespace from files.
18
+ *
19
+ * Based on jperras' shell found at http://bin.cakephp.org/view/626544881
20
+ *
21
+ * @since         DebugKit 1.3
22
+ */
23
+class WhitespaceShell extends Shell {
24
+
25
+/**
26
+ * Will check files for whitespace and notify you
27
+ * of any files containing leading or trailing whitespace.
28
+ *
29
+ * @return void
30
+ */
31
+	public function main() {
32
+		$path = APP;
33
+		if (!empty($this->params['path']) && strpos($this->params['path'], '/') === 0) {
34
+			$path = $this->params['path'];
35
+		} elseif (!empty($this->params['path'])) {
36
+			$path .= $this->params['path'];
37
+		}
38
+		$folder = new Folder($path);
39
+
40
+		$r = $folder->findRecursive('.*\.php');
41
+		$this->out("Checking *.php in " . $path);
42
+		foreach ($r as $file) {
43
+			$c = file_get_contents($file);
44
+			if (preg_match('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/', $c)) {
45
+				$this->out('!!!contains leading whitespaces: ' . $this->shortPath($file));
46
+			}
47
+			if (preg_match('/\?\>[\n\r|\n\r|\n|\r|\s]+$/', $c)) {
48
+				$this->out('!!!contains trailing whitespaces: ' . $this->shortPath($file));
49
+			}
50
+		}
51
+	}
52
+
53
+/**
54
+ * Much like main() except files are modified. Be sure to have
55
+ * backups or use version control.
56
+ *
57
+ * @return void
58
+ */
59
+	public function trim() {
60
+		$path = APP;
61
+		if (!empty($this->params['path']) && strpos($this->params['path'], '/') === 0) {
62
+			$path = $this->params['path'];
63
+		} elseif (!empty($this->params['path'])) {
64
+			$path .= $this->params['path'];
65
+		}
66
+		$folder = new Folder($path);
67
+
68
+		$r = $folder->findRecursive('.*\.php');
69
+		$this->out("Checking *.php in " . $path);
70
+		foreach ($r as $file) {
71
+			$c = file_get_contents($file);
72
+			if (preg_match('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/', $c) || preg_match('/\?\>[\n\r|\n\r|\n|\r|\s]+$/', $c)) {
73
+				$this->out('trimming' . $this->shortPath($file));
74
+				$c = preg_replace('/^[\n\r|\n\r|\n|\r|\s]+\<\?php/', '<?php', $c);
75
+				$c = preg_replace('/\?\>[\n\r|\n\r|\n|\r|\s]+$/', '?>', $c);
76
+				file_put_contents($file, $c);
77
+			}
78
+		}
79
+	}
80
+
81
+/**
82
+ * get the option parser
83
+ *
84
+ * @return ConsoleOptionParser
85
+ */
86
+	public function getOptionParser() {
87
+		$parser = parent::getOptionParser();
88
+		return $parser->addOption('path', array(
89
+			'short' => 'p',
90
+			'help' => __d('cake_console', 'Absolute path or relative to APP.')
91
+		));
92
+	}
93
+}

+ 504
- 0
Plugin/DebugKit/Controller/Component/ToolbarComponent.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit DebugToolbar Component
4
+ *
5
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
+ *
7
+ * Licensed under The MIT License
8
+ * Redistributions of files must retain the above copyright notice.
9
+ *
10
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
+ * @link          http://cakephp.org CakePHP(tm) Project
12
+ * @since         DebugKit 0.1
13
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
+ */
15
+
16
+App::uses('CakeLog', 'Log');
17
+App::uses('CakeLogInterface', 'Log');
18
+App::uses('DebugTimer', 'DebugKit.Lib');
19
+App::uses('DebugMemory', 'DebugKit.Lib');
20
+App::uses('HelperCollection', 'View');
21
+App::uses('CakeEventManager', 'Event');
22
+App::uses('CakeEventListener', 'Event');
23
+
24
+/**
25
+ * Class ToolbarComponent
26
+ *
27
+ * @since         DebugKit 0.1
28
+ */
29
+class ToolbarComponent extends Component implements CakeEventListener {
30
+
31
+/**
32
+ * Settings for the Component
33
+ *
34
+ * - forceEnable - Force the toolbar to display even if debug == 0. Default = false
35
+ * - autoRun - Automatically display the toolbar. If set to false, toolbar display can be triggered by adding
36
+ *    `?debug=true` to your URL.
37
+ *
38
+ * @var array
39
+ */
40
+	public $settings = array(
41
+		'forceEnable' => false,
42
+		'autoRun' => true
43
+	);
44
+
45
+/**
46
+ * Controller instance reference
47
+ *
48
+ * @var object
49
+ */
50
+	public $controller;
51
+
52
+/**
53
+ * Components used by DebugToolbar
54
+ *
55
+ * @var array
56
+ */
57
+	public $components = array('RequestHandler', 'Session');
58
+
59
+/**
60
+ * The default panels the toolbar uses.
61
+ * which panels are used can be configured when attaching the component
62
+ *
63
+ * @var array
64
+ */
65
+	protected $_defaultPanels = array(
66
+		'DebugKit.History',
67
+		'DebugKit.Session',
68
+		'DebugKit.Request',
69
+		'DebugKit.SqlLog',
70
+		'DebugKit.Timer',
71
+		'DebugKit.Log',
72
+		'DebugKit.Variables',
73
+		'DebugKit.Environment',
74
+		'DebugKit.Include'
75
+	);
76
+
77
+/**
78
+ * Loaded panel objects.
79
+ *
80
+ * @var array
81
+ */
82
+	public $panels = array();
83
+
84
+/**
85
+ * javascript files component will be using
86
+ *
87
+ * @var array
88
+ */
89
+	public $javascript = array(
90
+		'libs' => 'DebugKit./js/js_debug_toolbar'
91
+	);
92
+
93
+/**
94
+ * CSS files component will be using
95
+ *
96
+ * @var array
97
+ */
98
+	public $css = array('DebugKit./css/debug_toolbar.css');
99
+
100
+/**
101
+ * CacheKey used for the cache file.
102
+ *
103
+ * @var string
104
+ */
105
+	public $cacheKey = 'toolbar_cache';
106
+
107
+/**
108
+ * Duration of the debug kit history cache
109
+ *
110
+ * @var string
111
+ */
112
+	public $cacheDuration = '+4 hours';
113
+
114
+/**
115
+ * Status whether component is enable or disable
116
+ *
117
+ * @var boolean
118
+ */
119
+	public $enabled = true;
120
+
121
+/**
122
+ * Constructor
123
+ *
124
+ * If debug is off the component will be disabled and not do any further time tracking
125
+ * or load the toolbar helper.
126
+ *
127
+ * @param ComponentCollection $collection
128
+ * @param array $settings
129
+ * @return \ToolbarComponent
130
+ */
131
+	public function __construct(ComponentCollection $collection, $settings = array()) {
132
+		$settings = array_merge((array)Configure::read('DebugKit'), $settings);
133
+		$panels = $this->_defaultPanels;
134
+		if (isset($settings['panels'])) {
135
+			$panels = $this->_makePanelList($settings['panels']);
136
+			unset($settings['panels']);
137
+		}
138
+		$this->controller = $collection->getController();
139
+
140
+		parent::__construct($collection, array_merge($this->settings, (array)$settings));
141
+
142
+		if (
143
+			!Configure::read('debug') &&
144
+			empty($this->settings['forceEnable'])
145
+		) {
146
+			$this->enabled = false;
147
+			return false;
148
+		}
149
+		if (
150
+			$this->settings['autoRun'] === false &&
151
+			!isset($this->controller->request->query['debug'])
152
+		) {
153
+			$this->enabled = false;
154
+			return false;
155
+		}
156
+
157
+		$this->controller->getEventManager()->attach($this);
158
+
159
+		DebugMemory::record(__d('debug_kit', 'Component initialization'));
160
+
161
+		$this->cacheKey .= $this->Session->read('Config.userAgent');
162
+		if (
163
+			in_array('DebugKit.History', $panels) ||
164
+			(isset($settings['history']) && $settings['history'] !== false)
165
+		) {
166
+			$this->_createCacheConfig();
167
+		}
168
+
169
+		$this->_loadPanels($panels, $settings);
170
+		return false;
171
+	}
172
+
173
+/**
174
+ * Register all the timing handlers for core events.
175
+ *
176
+ * @return array
177
+ */
178
+	public function implementedEvents() {
179
+		$before = function ($name) {
180
+			return function () use ($name) {
181
+				DebugTimer::start($name, $name);
182
+			};
183
+		};
184
+		$after = function ($name) {
185
+			return function () use ($name) {
186
+				DebugTimer::stop($name);
187
+			};
188
+		};
189
+
190
+		return array(
191
+			'Controller.initialize' => array(
192
+				array('priority' => 0, 'callable' => $before('Event: Controller.initialize')),
193
+				array('priority' => 999, 'callable' => $after('Event: Controller.initialize'))
194
+			),
195
+			'Controller.startup' => array(
196
+				array('priority' => 0, 'callable' => $before('Event: Controller.startup')),
197
+				array('priority' => 999, 'callable' => $after('Event: Controller.startup'))
198
+			),
199
+			'Controller.beforeRender' => array(
200
+				array('priority' => 0, 'callable' => $before('Event: Controller.beforeRender')),
201
+				array('priority' => 999, 'callable' => $after('Event: Controller.beforeRender'))
202
+			),
203
+			'Controller.shutdown' => array(
204
+				array('priority' => 0, 'callable' => $before('Event: Controller.shutdown')),
205
+				array('priority' => 999, 'callable' => $after('Event: Controller.shutdown'))
206
+			),
207
+			'View.beforeRender' => array(
208
+				array('priority' => 0, 'callable' => $before('Event: View.beforeRender')),
209
+				array('priority' => 999, 'callable' => $after('Event: View.beforeRender'))
210
+			),
211
+			'View.afterRender' => array(
212
+				array('priority' => 0, 'callable' => $before('Event: View.afterRender')),
213
+				array('priority' => 999, 'callable' => $after('Event: View.afterRender'))
214
+			),
215
+			'View.beforeLayout' => array(
216
+				array('priority' => 0, 'callable' => $before('Event: View.beforeLayout')),
217
+				array('priority' => 999, 'callable' => $after('Event: View.beforeLayout'))
218
+			),
219
+			'View.afterLayout' => array(
220
+				array('priority' => 0, 'callable' => $before('Event: View.afterLayout')),
221
+				array('priority' => 999, 'callable' => $after('Event: View.afterLayout'))
222
+			),
223
+		);
224
+	}
225
+
226
+/**
227
+ * Initialize callback.
228
+ * If automatically disabled, tell component collection about the state.
229
+ *
230
+ * @param Controller $controller
231
+ * @return boolean
232
+ */
233
+	public function initialize(Controller $controller) {
234
+		if (!$this->enabled) {
235
+			$this->_Collection->disable('Toolbar');
236
+		}
237
+	}
238
+
239
+/**
240
+ * Go through user panels and remove default panels as indicated.
241
+ *
242
+ * @param array $userPanels The list of panels ther user has added removed.
243
+ * @return array Array of panels to use.
244
+ */
245
+	protected function _makePanelList($userPanels) {
246
+		$panels = $this->_defaultPanels;
247
+		foreach ($userPanels as $key => $value) {
248
+			if (is_numeric($key)) {
249
+				$panels[] = $value;
250
+			}
251
+			if (is_string($key) && $value === false) {
252
+				$index = array_search($key, $panels);
253
+				if ($index !== false) {
254
+					unset($panels[$index]);
255
+				}
256
+				// Compatibility for when panels were not
257
+				// required to have a plugin prefix.
258
+				$alternate = 'DebugKit.' . ucfirst($key);
259
+				$index = array_search($alternate, $panels);
260
+				if ($index !== false) {
261
+					unset($panels[$index]);
262
+				}
263
+			}
264
+		}
265
+		return $panels;
266
+	}
267
+
268
+/**
269
+ * Component Startup
270
+ *
271
+ * @param Controller $controller
272
+ * @return boolean
273
+ */
274
+	public function startup(Controller $controller) {
275
+		$panels = array_keys($this->panels);
276
+		foreach ($panels as $panelName) {
277
+			$this->panels[$panelName]->startup($controller);
278
+		}
279
+		DebugTimer::start(
280
+			'controllerAction',
281
+			__d('debug_kit', 'Controller action')
282
+		);
283
+		DebugMemory::record(
284
+			__d('debug_kit', 'Controller action start')
285
+		);
286
+	}
287
+
288
+/**
289
+ * beforeRedirect callback
290
+ *
291
+ * @param Controller $controller
292
+ * @param $url
293
+ * @param null $status
294
+ * @param boolean $exit
295
+ * @return void
296
+ */
297
+	public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
298
+		if (!class_exists('DebugTimer')) {
299
+			return null;
300
+		}
301
+		DebugTimer::stop('controllerAction');
302
+		DebugTimer::start(
303
+			'processToolbar',
304
+			__d('debug_kit', 'Processing toolbar state')
305
+		);
306
+		$vars = $this->_gatherVars($controller);
307
+		$this->_saveState($controller, $vars);
308
+		DebugTimer::stop('processToolbar');
309
+	}
310
+
311
+/**
312
+ * beforeRender callback
313
+ *
314
+ * Calls beforeRender on all the panels and set the aggregate to the controller.
315
+ *
316
+ * @param Controller $controller
317
+ * @return void
318
+ */
319
+	public function beforeRender(Controller $controller) {
320
+		if (!class_exists('DebugTimer')) {
321
+			return null;
322
+		}
323
+		DebugTimer::stop('controllerAction');
324
+
325
+		DebugTimer::start(
326
+			'processToolbar',
327
+			__d('debug_kit', 'Processing toolbar data')
328
+		);
329
+		$vars = $this->_gatherVars($controller);
330
+		$this->_saveState($controller, $vars);
331
+
332
+		$this->javascript = array_unique(array_merge($this->javascript, $vars['javascript']));
333
+		$this->css = array_unique(array_merge($this->css, $vars['css']));
334
+		unset($vars['javascript'], $vars['css']);
335
+
336
+		$controller->set(array(
337
+			'debugToolbarPanels' => $vars,
338
+			'debugToolbarJavascript' => $this->javascript,
339
+			'debugToolbarCss' => $this->css
340
+		));
341
+
342
+		$isHtml = (
343
+			!isset($controller->request->params['ext']) ||
344
+			$controller->request->params['ext'] === 'html'
345
+		);
346
+
347
+		if (!$controller->request->is('ajax') && $isHtml) {
348
+			$format = 'Html';
349
+		} else {
350
+			$format = 'FirePhp';
351
+		}
352
+
353
+		$controller->helpers[] = 'DebugKit.DebugTimer';
354
+		$controller->helpers['DebugKit.Toolbar'] = array(
355
+			'output' => sprintf('DebugKit.%sToolbar', $format),
356
+			'cacheKey' => $this->cacheKey,
357
+			'cacheConfig' => 'debug_kit',
358
+			'forceEnable' => $this->settings['forceEnable'],
359
+		);
360
+
361
+		DebugTimer::stop('processToolbar');
362
+		DebugMemory::record(__d('debug_kit', 'Controller render start'));
363
+	}
364
+
365
+/**
366
+ * Load a toolbar state from cache
367
+ *
368
+ * @param integer $key
369
+ * @return array
370
+ */
371
+	public function loadState($key) {
372
+		$history = Cache::read($this->cacheKey, 'debug_kit');
373
+		if (isset($history[$key])) {
374
+			return $history[$key];
375
+		}
376
+		return array();
377
+	}
378
+
379
+/**
380
+ * Create the cache config for the history
381
+ *
382
+ * @return void
383
+ */
384
+	protected function _createCacheConfig() {
385
+		if (Configure::read('Cache.disable') === true || Cache::config('debug_kit')) {
386
+			return;
387
+		}
388
+		$cache = array(
389
+		    'duration' => $this->cacheDuration,
390
+		    'engine' => 'File',
391
+		    'path' => CACHE
392
+		);
393
+		if (isset($this->settings['cache'])) {
394
+			$cache = array_merge($cache, $this->settings['cache']);
395
+		}
396
+		Cache::config('debug_kit', $cache);
397
+	}
398
+
399
+/**
400
+ * collects the panel contents
401
+ *
402
+ * @param Controller $controller
403
+ * @return array Array of all panel beforeRender()
404
+ */
405
+	protected function _gatherVars(Controller $controller) {
406
+		$vars = array('javascript' => array(), 'css' => array());
407
+		$panels = array_keys($this->panels);
408
+
409
+		foreach ($panels as $panelName) {
410
+			$panel = $this->panels[$panelName];
411
+			$panelName = Inflector::underscore($panelName);
412
+			$vars[$panelName]['content'] = $panel->beforeRender($controller);
413
+			$elementName = Inflector::underscore($panelName) . '_panel';
414
+			if (isset($panel->elementName)) {
415
+				$elementName = $panel->elementName;
416
+			}
417
+			$vars[$panelName]['elementName'] = $elementName;
418
+			$vars[$panelName]['plugin'] = $panel->plugin;
419
+			$vars[$panelName]['title'] = $panel->title;
420
+			$vars[$panelName]['disableTimer'] = true;
421
+
422
+			if (!empty($panel->javascript)) {
423
+				$vars['javascript'] = array_merge($vars['javascript'], (array)$panel->javascript);
424
+			}
425
+			if (!empty($panel->css)) {
426
+				$vars['css'] = array_merge($vars['css'], (array)$panel->css);
427
+			}
428
+		}
429
+		return $vars;
430
+	}
431
+
432
+/**
433
+ * Load Panels used in the debug toolbar
434
+ *
435
+ * @param $panels
436
+ * @param $settings
437
+ * @return void
438
+ */
439
+	protected function _loadPanels($panels, $settings) {
440
+		foreach ($panels as $panel) {
441
+			$className = ucfirst($panel) . 'Panel';
442
+			list($plugin, $className) = pluginSplit($className, true);
443
+
444
+			App::uses($className, $plugin . 'Panel');
445
+			if (!class_exists($className)) {
446
+				trigger_error(__d('debug_kit', 'Could not load DebugToolbar panel %s', $panel), E_USER_WARNING);
447
+				continue;
448
+			}
449
+			$panelObj = new $className($settings);
450
+			if ($panelObj instanceof DebugPanel) {
451
+				list(, $panel) = pluginSplit($panel);
452
+				$this->panels[Inflector::underscore($panel)] = $panelObj;
453
+			}
454
+		}
455
+	}
456
+
457
+/**
458
+ * Save the current state of the toolbar varibles to the cache file.
459
+ *
460
+ * @param \Controller|object $controller Controller instance
461
+ * @param array $vars Vars to save.
462
+ * @return void
463
+ */
464
+	protected function _saveState(Controller $controller, $vars) {
465
+		$config = Cache::config('debug_kit');
466
+		if (empty($config) || !isset($this->panels['history'])) {
467
+			return;
468
+		}
469
+		$history = Cache::read($this->cacheKey, 'debug_kit');
470
+		if (empty($history)) {
471
+			$history = array();
472
+		}
473
+		if (count($history) == $this->panels['history']->history) {
474
+			array_pop($history);
475
+		}
476
+
477
+		if (isset($vars['variables']['content'])) {
478
+			// Remove unserializable native objects.
479
+			array_walk_recursive($vars['variables']['content'], function (&$item) {
480
+				if (
481
+					$item instanceof Closure ||
482
+					$item instanceof PDO ||
483
+					$item instanceof SimpleXmlElement
484
+				) {
485
+					$item = 'Unserializable object - ' . get_class($item);
486
+				} elseif ($item instanceof Exception) {
487
+					$item = sprintf(
488
+						'Unserializable object - %s. Error: %s in %s, line %s',
489
+						get_class($item),
490
+						$item,
491
+						$item->getMessage(),
492
+						$item->getFile(),
493
+						$item->getLine()
494
+					);
495
+				}
496
+				return $item;
497
+			});
498
+		}
499
+		unset($vars['history']);
500
+		array_unshift($history, $vars);
501
+		Cache::write($this->cacheKey, $history, 'debug_kit');
502
+	}
503
+
504
+}

+ 25
- 0
Plugin/DebugKit/Controller/DebugKitAppController.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Controller', 'Controller');
16
+App::uses('AppController', 'Controller');
17
+
18
+/**
19
+ * Class DebugKitAppController
20
+ *
21
+ * @since         DebugKit 0.1
22
+ */
23
+class DebugKitAppController extends AppController {
24
+
25
+}

+ 121
- 0
Plugin/DebugKit/Controller/ToolbarAccessController.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Security', 'Utility');
16
+App::uses('DebugKitAppController', 'DebugKit.Controller');
17
+
18
+/**
19
+ * DebugKit ToolbarAccess Controller
20
+ *
21
+ * Allows retrieval of information from the debugKit internals.
22
+ *
23
+ * @since         DebugKit 1.1
24
+ */
25
+class ToolbarAccessController extends DebugKitAppController {
26
+
27
+/**
28
+ * name
29
+ *
30
+ * @var string
31
+ */
32
+	public $name = 'ToolbarAccess';
33
+
34
+/**
35
+ * Helpers
36
+ *
37
+ * @var array
38
+ */
39
+	public $helpers = array(
40
+		'DebugKit.Toolbar' => array('output' => 'DebugKit.HtmlToolbar'),
41
+		'Js', 'Number', 'DebugKit.SimpleGraph'
42
+	);
43
+
44
+/**
45
+ * Components
46
+ *
47
+ * @var array
48
+ */
49
+	public $components = array('RequestHandler', 'DebugKit.Toolbar');
50
+
51
+/**
52
+ * Uses
53
+ *
54
+ * @var array
55
+ */
56
+	public $uses = array('DebugKit.ToolbarAccess');
57
+
58
+/**
59
+ * beforeFilter callback
60
+ *
61
+ * @return void
62
+ */
63
+	public function beforeFilter() {
64
+		parent::beforeFilter();
65
+		if (isset($this->Toolbar)) {
66
+			$this->Components->disable('Toolbar');
67
+		}
68
+		$this->helpers['DebugKit.Toolbar']['cacheKey'] = $this->Toolbar->cacheKey;
69
+		$this->helpers['DebugKit.Toolbar']['cacheConfig'] = 'debug_kit';
70
+
71
+		if (isset($this->Auth) && method_exists($this->Auth, 'mapActions')) {
72
+			$this->Auth->mapActions(array(
73
+				'read' => array('history_state', 'sql_explain')
74
+			));
75
+		}
76
+	}
77
+
78
+/**
79
+ * Get a stored history state from the toolbar cache.
80
+ *
81
+ * @param null $key
82
+ * @return void
83
+ */
84
+	public function history_state($key = null) {
85
+		if (Configure::read('debug') == 0) {
86
+			return $this->redirect($this->referer());
87
+		}
88
+		$oldState = $this->Toolbar->loadState($key);
89
+		$this->set('toolbarState', $oldState);
90
+		$this->set('debugKitInHistoryMode', true);
91
+		$this->viewClass = null;
92
+		$this->layout = null;
93
+	}
94
+
95
+/**
96
+ * Run SQL explain/profiling on queries. Checks the hash + the hashed queries,
97
+ * if there is mismatch a 404 will be rendered. If debug == 0 a 404 will also be
98
+ * rendered. No explain will be run if a 404 is made.
99
+ *
100
+ * @throws BadRequestException
101
+ * @return void
102
+ */
103
+	public function sql_explain() {
104
+		if (
105
+			!$this->request->is('post') ||
106
+			empty($this->request->data['log']['sql']) ||
107
+			empty($this->request->data['log']['ds']) ||
108
+			empty($this->request->data['log']['hash']) ||
109
+			Configure::read('debug') == 0
110
+		) {
111
+			throw new BadRequestException('Invalid parameters');
112
+		}
113
+		$hash = Security::hash($this->request->data['log']['sql'] . $this->request->data['log']['ds'], 'sha1', true);
114
+		if ($hash !== $this->request->data['log']['hash']) {
115
+			throw new BadRequestException('Invalid parameters');
116
+		}
117
+		$result = $this->ToolbarAccess->explainQuery($this->request->data['log']['ds'], $this->request->data['log']['sql']);
118
+		$this->set(compact('result'));
119
+	}
120
+
121
+}

+ 28
- 0
Plugin/DebugKit/LICENSE.txt 파일 보기

1
+The MIT License
2
+
3
+CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org)
4
+Copyright (c) 2005-2015, Cake Software Foundation, Inc.
5
+
6
+Permission is hereby granted, free of charge, to any person obtaining a
7
+copy of this software and associated documentation files (the "Software"),
8
+to deal in the Software without restriction, including without limitation
9
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+and/or sell copies of the Software, and to permit persons to whom the
11
+Software is furnished to do so, subject to the following conditions:
12
+
13
+The above copyright notice and this permission notice shall be included in
14
+all copies or substantial portions of the Software.
15
+
16
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+DEALINGS IN THE SOFTWARE.
23
+
24
+Cake Software Foundation, Inc.
25
+1785 E. Sahara Avenue,
26
+Suite 490-204
27
+Las Vegas, Nevada 89104,
28
+United States of America.

+ 227
- 0
Plugin/DebugKit/Lib/DebugKitDebugger.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Debugger', 'Utility');
16
+App::uses('FireCake', 'DebugKit.Lib');
17
+App::uses('DebugTimer', 'DebugKit.Lib');
18
+App::uses('DebugMemory', 'DebugKit.Lib');
19
+
20
+/**
21
+ * DebugKit Temporary Debugger Class
22
+ *
23
+ * Provides the future features that are planned. Yet not implemented in the 1.2 code base
24
+ *
25
+ * This file will not be needed in future version of CakePHP.
26
+ *
27
+ * @since         DebugKit 0.1
28
+ */
29
+class DebugKitDebugger extends Debugger {
30
+
31
+/**
32
+ * destruct method
33
+ *
34
+ * Allow timer info to be displayed if the code dies or is being debugged before rendering the view
35
+ * Cheat and use the debug log class for formatting
36
+ *
37
+ * @return void
38
+ */
39
+	public function __destruct() {
40
+		$timers = DebugTimer::getAll();
41
+		if (Configure::read('debug') < 2 || count($timers) > 0) {
42
+			return;
43
+		}
44
+		$timers = array_values($timers);
45
+		$end = end($timers);
46
+		echo '<table class="cake-sql-log"><tbody>';
47
+		echo '<caption>Debug timer info</caption>';
48
+		echo '<tr><th>Message</th><th>Start Time (ms)</th><th>End Time (ms)</th><th>Duration (ms)</th></tr>';
49
+		$i = 0;
50
+		foreach ($timers as $timer) {
51
+			$indent = 0;
52
+			for ($j = 0; $j < $i; $j++) {
53
+				if (($timers[$j]['end']) > ($timer['start']) && ($timers[$j]['end']) > ($timer['end'])) {
54
+					$indent++;
55
+				}
56
+			}
57
+			$indent = str_repeat(' &raquo; ', $indent);
58
+
59
+			extract($timer);
60
+			$start = round($start * 1000, 0);
61
+			$end = round($end * 1000, 0);
62
+			$time = round($time * 1000, 0);
63
+			echo "<tr><td>{$indent}$message</td><td>$start</td><td>$end</td><td>$time</td></tr>";
64
+			$i++;
65
+		}
66
+		echo '</tbody></table>';
67
+	}
68
+
69
+/**
70
+ * Start an benchmarking timer.
71
+ *
72
+ * @param string $name The name of the timer to start.
73
+ * @param string $message A message for your timer
74
+ * @return boolean true
75
+ * @deprecated use DebugTimer::start()
76
+ */
77
+	public static function startTimer($name = null, $message = null) {
78
+		return DebugTimer::start($name, $message);
79
+	}
80
+
81
+/**
82
+ * Stop a benchmarking timer.
83
+ *
84
+ * $name should be the same as the $name used in startTimer().
85
+ *
86
+ * @param string $name The name of the timer to end.
87
+ * @return boolean true if timer was ended, false if timer was not started.
88
+ * @deprecated use DebugTimer::stop()
89
+ */
90
+	public static function stopTimer($name = null) {
91
+		return DebugTimer::stop($name);
92
+	}
93
+
94
+/**
95
+ * Get all timers that have been started and stopped.
96
+ * Calculates elapsed time for each timer. If clear is true, will delete existing timers
97
+ *
98
+ * @param boolean $clear false
99
+ * @return array
100
+ * @deprecated use DebugTimer::getAll()
101
+ */
102
+	public static function getTimers($clear = false) {
103
+		return DebugTimer::getAll($clear);
104
+	}
105
+
106
+/**
107
+ * Clear all existing timers
108
+ *
109
+ * @return boolean true
110
+ * @deprecated use DebugTimer::clear()
111
+ */
112
+	public static function clearTimers() {
113
+		return DebugTimer::clear();
114
+	}
115
+
116
+/**
117
+ * Get the difference in time between the timer start and timer end.
118
+ *
119
+ * @param $name string the name of the timer you want elapsed time for.
120
+ * @param $precision int the number of decimal places to return, defaults to 5.
121
+ * @return float number of seconds elapsed for timer name, 0 on missing key
122
+ * @deprecated use DebugTimer::elapsedTime()
123
+ */
124
+	public static function elapsedTime($name = 'default', $precision = 5) {
125
+		return DebugTimer::elapsedTime($name, $precision);
126
+	}
127
+
128
+/**
129
+ * Get the total execution time until this point
130
+ *
131
+ * @return float elapsed time in seconds since script start.
132
+ * @deprecated use DebugTimer::requestTime()
133
+ */
134
+	public static function requestTime() {
135
+		return DebugTimer::requestTime();
136
+	}
137
+
138
+/**
139
+ * get the time the current request started.
140
+ *
141
+ * @return float time of request start
142
+ * @deprecated use DebugTimer::requestStartTime()
143
+ */
144
+	public static function requestStartTime() {
145
+		return DebugTimer::requestStartTime();
146
+	}
147
+
148
+/**
149
+ * get current memory usage
150
+ *
151
+ * @return integer number of bytes ram currently in use. 0 if memory_get_usage() is not available.
152
+ * @deprecated Use DebugMemory::getCurrent() instead.
153
+ */
154
+	public static function getMemoryUse() {
155
+		return DebugMemory::getCurrent();
156
+	}
157
+
158
+/**
159
+ * Get peak memory use
160
+ *
161
+ * @return integer peak memory use (in bytes). Returns 0 if memory_get_peak_usage() is not available
162
+ * @deprecated Use DebugMemory::getPeak() instead.
163
+ */
164
+	public static function getPeakMemoryUse() {
165
+		return DebugMemory::getPeak();
166
+	}
167
+
168
+/**
169
+ * Stores a memory point in the internal tracker.
170
+ * Takes a optional message name which can be used to identify the memory point.
171
+ * If no message is supplied a debug_backtrace will be done to identifty the memory point.
172
+ * If you don't have memory_get_xx methods this will not work.
173
+ *
174
+ * @param string $message Message to identify this memory point.
175
+ * @return boolean
176
+ * @deprecated Use DebugMemory::getAll() instead.
177
+ */
178
+	public static function setMemoryPoint($message = null) {
179
+		return DebugMemory::record($message);
180
+	}
181
+
182
+/**
183
+ * Get all the stored memory points
184
+ *
185
+ * @param boolean $clear Whether you want to clear the memory points as well. Defaults to false.
186
+ * @return array Array of memory marks stored so far.
187
+ * @deprecated Use DebugMemory::getAll() instead.
188
+ */
189
+	public static function getMemoryPoints($clear = false) {
190
+		return DebugMemory::getAll($clear);
191
+	}
192
+
193
+/**
194
+ * Clear out any existing memory points
195
+ *
196
+ * @return void
197
+ * @deprecated Use DebugMemory::clear() instead.
198
+ */
199
+	public static function clearMemoryPoints() {
200
+		DebugMemory::clear();
201
+	}
202
+
203
+/**
204
+ * Create a FirePHP error message
205
+ *
206
+ * @param array $data Data of the error
207
+ * @param array $links  Links for the error
208
+ * @return void
209
+ */
210
+	public static function fireError($data, $links) {
211
+		$name = $data['error'] . ' - ' . $data['description'];
212
+		$message = "{$data['error']} {$data['code']} {$data['description']} on line: {$data['line']} in file: {$data['file']}";
213
+		FireCake::group($name);
214
+		FireCake::error($message, $name);
215
+		if (isset($data['context'])) {
216
+			FireCake::log($data['context'], 'Context');
217
+		}
218
+		if (isset($data['trace'])) {
219
+			FireCake::log(preg_split('/[\r\n]+/', $data['trace']), 'Trace');
220
+		}
221
+		FireCake::groupEnd();
222
+	}
223
+
224
+}
225
+
226
+DebugKitDebugger::getInstance('DebugKitDebugger');
227
+Debugger::addFormat('fb', array('callback' => 'DebugKitDebugger::fireError'));

+ 98
- 0
Plugin/DebugKit/Lib/DebugMemory.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 2.0
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Debugger', 'Utility');
16
+
17
+/**
18
+ * Contains methods for Profiling memory usage.
19
+ *
20
+ */
21
+class DebugMemory {
22
+
23
+/**
24
+ * An array of recorded memory use points.
25
+ *
26
+ * @var array
27
+ */
28
+	protected static $_points = array();
29
+
30
+/**
31
+ * Get current memory usage
32
+ *
33
+ * @return integer number of bytes ram currently in use. 0 if memory_get_usage() is not available.
34
+ */
35
+	public static function getCurrent() {
36
+		return memory_get_usage();
37
+	}
38
+
39
+/**
40
+ * Get peak memory use
41
+ *
42
+ * @return integer peak memory use (in bytes). Returns 0 if memory_get_peak_usage() is not available
43
+ */
44
+	public static function getPeak() {
45
+		return memory_get_peak_usage();
46
+	}
47
+
48
+/**
49
+ * Stores a memory point in the internal tracker.
50
+ * Takes a optional message name which can be used to identify the memory point.
51
+ * If no message is supplied a debug_backtrace will be done to identify the memory point.
52
+ *
53
+ * @param string $message Message to identify this memory point.
54
+ * @return boolean
55
+ */
56
+	public static function record($message = null) {
57
+		$memoryUse = self::getCurrent();
58
+		if (!$message) {
59
+			$named = false;
60
+			$trace = debug_backtrace();
61
+			$message = Debugger::trimpath($trace[0]['file']) . ' line ' . $trace[0]['line'];
62
+		}
63
+		if (isset(self::$_points[$message])) {
64
+			$originalMessage = $message;
65
+			$i = 1;
66
+			while (isset(self::$_points[$message])) {
67
+				$i++;
68
+				$message = $originalMessage . ' #' . $i;
69
+			}
70
+		}
71
+		self::$_points[$message] = $memoryUse;
72
+		return true;
73
+	}
74
+
75
+/**
76
+ * Get all the stored memory points
77
+ *
78
+ * @param boolean $clear Whether you want to clear the memory points as well. Defaults to false.
79
+ * @return array Array of memory marks stored so far.
80
+ */
81
+	public static function getAll($clear = false) {
82
+		$marks = self::$_points;
83
+		if ($clear) {
84
+			self::$_points = array();
85
+		}
86
+		return $marks;
87
+	}
88
+
89
+/**
90
+ * Clear out any existing memory points
91
+ *
92
+ * @return void
93
+ */
94
+	public static function clear() {
95
+		self::$_points = array();
96
+	}
97
+
98
+}

+ 84
- 0
Plugin/DebugKit/Lib/DebugPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+/**
16
+ * Base class for debug panels.
17
+ *
18
+ * @since         DebugKit 0.1
19
+ */
20
+class DebugPanel {
21
+
22
+/**
23
+ * Defines which plugin this panel is from so the element can be located.
24
+ *
25
+ * @var string
26
+ */
27
+	public $plugin = 'DebugKit';
28
+
29
+/**
30
+ * Defines the title for displaying on the toolbar. If null, the class name will be used.
31
+ * Overriding this allows you to define a custom name in the toolbar.
32
+ *
33
+ * @var string
34
+ */
35
+	public $title = null;
36
+
37
+/**
38
+ * Panel's css files
39
+ *
40
+ * @var array
41
+ */
42
+	public $css = array();
43
+
44
+/**
45
+ * Panel's javascript files
46
+ *
47
+ * @var array
48
+ */
49
+	public $javascript = array();
50
+
51
+/**
52
+ * Provide a custom element name for this panel. If null, the underscored version of the class
53
+ * name will be used.
54
+ *
55
+ * @var string
56
+ */
57
+	public $elementName = null;
58
+
59
+/**
60
+ * Empty constructor
61
+ */
62
+	public function __construct() {
63
+	}
64
+
65
+/**
66
+ * startup the panel
67
+ *
68
+ * Pull information from the controller / request
69
+ *
70
+ * @param \Controller|object $controller Controller reference.
71
+ * @return void
72
+ */
73
+	public function startup(Controller $controller) {
74
+	}
75
+
76
+/**
77
+ * Prepare output vars before Controller Rendering.
78
+ *
79
+ * @param \Controller|object $controller Controller reference.
80
+ * @return void
81
+ */
82
+	public function beforeRender(Controller $controller) {
83
+	}
84
+}

+ 201
- 0
Plugin/DebugKit/Lib/DebugTimer.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Debugger', 'Utility');
16
+
17
+/**
18
+ * Contains methods for Profiling and creating timers.
19
+ *
20
+ */
21
+class DebugTimer {
22
+
23
+/**
24
+ * Internal timers array
25
+ *
26
+ * @var array
27
+ */
28
+	protected static $_timers = array();
29
+
30
+/**
31
+ * Start an benchmarking timer.
32
+ *
33
+ * @param string $name The name of the timer to start.
34
+ * @param string $message A message for your timer
35
+ * @return boolean Always true
36
+ */
37
+	public static function start($name = null, $message = null) {
38
+		$start = microtime(true);
39
+
40
+		if (!$name) {
41
+			$named = false;
42
+			$calledFrom = debug_backtrace();
43
+			$_name = $name = Debugger::trimpath($calledFrom[0]['file']) . ' line ' . $calledFrom[0]['line'];
44
+		} else {
45
+			$named = true;
46
+		}
47
+
48
+		if (!$message) {
49
+			$message = $name;
50
+		}
51
+
52
+		$_name = $name;
53
+		$i = 1;
54
+		while (isset(self::$_timers[$name])) {
55
+			$i++;
56
+			$name = $_name . ' #' . $i;
57
+		}
58
+
59
+		if ($i > 1) {
60
+			$message .= ' #' . $i;
61
+		}
62
+
63
+		self::$_timers[$name] = array(
64
+			'start' => $start,
65
+			'message' => $message,
66
+			'named' => $named
67
+		);
68
+		return true;
69
+	}
70
+
71
+/**
72
+ * Stop a benchmarking timer.
73
+ *
74
+ * $name should be the same as the $name used in startTimer().
75
+ *
76
+ * @param string $name The name of the timer to end.
77
+ * @return boolean true if timer was ended, false if timer was not started.
78
+ */
79
+	public static function stop($name = null) {
80
+		$end = microtime(true);
81
+		if (!$name) {
82
+			$names = array_reverse(array_keys(self::$_timers));
83
+			foreach ($names as $name) {
84
+				if (!empty(self::$_timers[$name]['end'])) {
85
+					continue;
86
+				}
87
+				if (empty(self::$_timers[$name]['named'])) {
88
+					break;
89
+				}
90
+			}
91
+		} else {
92
+			$i = 1;
93
+			$_name = $name;
94
+			while (isset(self::$_timers[$name])) {
95
+				if (empty(self::$_timers[$name]['end'])) {
96
+					break;
97
+				}
98
+				$i++;
99
+				$name = $_name . ' #' . $i;
100
+			}
101
+		}
102
+		if (!isset(self::$_timers[$name])) {
103
+			return false;
104
+		}
105
+		self::$_timers[$name]['end'] = $end;
106
+		return true;
107
+	}
108
+
109
+/**
110
+ * Get all timers that have been started and stopped.
111
+ * Calculates elapsed time for each timer. If clear is true, will delete existing timers
112
+ *
113
+ * @param boolean $clear false
114
+ * @return array
115
+ */
116
+	public static function getAll($clear = false) {
117
+		$start = self::requestStartTime();
118
+		$now = microtime(true);
119
+
120
+		$times = array();
121
+		if (!empty(self::$_timers)) {
122
+			$firstTimer = reset(self::$_timers);
123
+			$_end = $firstTimer['start'];
124
+		} else {
125
+			$_end = $now;
126
+		}
127
+		$times['Core Processing (Derived from $_SERVER["REQUEST_TIME"])'] = array(
128
+			'message' => __d('debug_kit', 'Core Processing (Derived from $_SERVER["REQUEST_TIME"])'),
129
+			'start' => 0,
130
+			'end' => $_end - $start,
131
+			'time' => round($_end - $start, 6),
132
+			'named' => null
133
+		);
134
+		foreach (self::$_timers as $name => $timer) {
135
+			if (!isset($timer['end'])) {
136
+				$timer['end'] = $now;
137
+			}
138
+			$times[$name] = array_merge($timer, array(
139
+				'start' => $timer['start'] - $start,
140
+				'end' => $timer['end'] - $start,
141
+				'time' => self::elapsedTime($name)
142
+			));
143
+		}
144
+		if ($clear) {
145
+			self::$_timers = array();
146
+		}
147
+		return $times;
148
+	}
149
+
150
+/**
151
+ * Clear all existing timers
152
+ *
153
+ * @return boolean true
154
+ */
155
+	public static function clear() {
156
+		self::$_timers = array();
157
+		return true;
158
+	}
159
+
160
+/**
161
+ * Get the difference in time between the timer start and timer end.
162
+ *
163
+ * @param $name string the name of the timer you want elapsed time for.
164
+ * @param $precision int the number of decimal places to return, defaults to 5.
165
+ * @return float number of seconds elapsed for timer name, 0 on missing key
166
+ */
167
+	public static function elapsedTime($name = 'default', $precision = 5) {
168
+		if (!isset(self::$_timers[$name]['start']) || !isset(self::$_timers[$name]['end'])) {
169
+			return 0;
170
+		}
171
+		return round(self::$_timers[$name]['end'] - self::$_timers[$name]['start'], $precision);
172
+	}
173
+
174
+/**
175
+ * Get the total execution time until this point
176
+ *
177
+ * @return float elapsed time in seconds since script start.
178
+ */
179
+	public static function requestTime() {
180
+		$start = self::requestStartTime();
181
+		$now = microtime(true);
182
+		return ($now - $start);
183
+	}
184
+
185
+/**
186
+ * get the time the current request started.
187
+ *
188
+ * @return float time of request start
189
+ */
190
+	public static function requestStartTime() {
191
+		if (defined('TIME_START')) {
192
+			$startTime = TIME_START;
193
+		} elseif (isset($GLOBALS['TIME_START'])) {
194
+			$startTime = $GLOBALS['TIME_START'];
195
+		} else {
196
+			$startTime = env('REQUEST_TIME');
197
+		}
198
+		return $startTime;
199
+	}
200
+
201
+}

+ 538
- 0
Plugin/DebugKit/Lib/FireCake.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('Debugger', 'Utility');
16
+
17
+if (!function_exists('firecake')) {
18
+
19
+/**
20
+ * Procedural version of FireCake::log()
21
+ *
22
+ * @param $message
23
+ * @param null $label
24
+ */
25
+	function firecake($message, $label = null) {
26
+		FireCake::fb($message, $label, 'log');
27
+	}
28
+
29
+}
30
+
31
+/**
32
+ * FirePHP Class for CakePHP
33
+ *
34
+ * Provides most of the functionality offered by FirePHPCore
35
+ * Interoperates with FirePHP extension for Firefox
36
+ *
37
+ * For more information see: http://www.firephp.org/
38
+ *
39
+ */
40
+class FireCake {
41
+
42
+/**
43
+ * Options for FireCake.
44
+ *
45
+ * @see _defaultOptions and setOptions();
46
+ * @var string
47
+ */
48
+	public $options = array();
49
+
50
+/**
51
+ * Default Options used in CakeFirePhp
52
+ *
53
+ * @var string
54
+ */
55
+	protected $_defaultOptions = array(
56
+		'maxObjectDepth' => 10,
57
+		'maxArrayDepth' => 20,
58
+		'useNativeJsonEncode' => true,
59
+		'includeLineNumbers' => true,
60
+	);
61
+
62
+/**
63
+ * Message Levels for messages sent via FirePHP
64
+ *
65
+ * @var array
66
+ */
67
+	protected $_levels = array(
68
+		'log' => 'LOG',
69
+		'info' => 'INFO',
70
+		'warn' => 'WARN',
71
+		'error' => 'ERROR',
72
+		'dump' => 'DUMP',
73
+		'trace' => 'TRACE',
74
+		'exception' => 'EXCEPTION',
75
+		'table' => 'TABLE',
76
+		'groupStart' => 'GROUP_START',
77
+		'groupEnd' => 'GROUP_END',
78
+	);
79
+
80
+/**
81
+ * Version number for X-Wf-1-Plugin-1 HTML header
82
+ *
83
+ * @var string
84
+ */
85
+	protected $_version = '0.2.1';
86
+
87
+/**
88
+ * internal messageIndex counter
89
+ *
90
+ * @var integer
91
+ */
92
+	protected $_messageIndex = 1;
93
+
94
+/**
95
+ * stack of objects encoded by stringEncode()
96
+ *
97
+ * @var array
98
+ */
99
+	protected $_encodedObjects = array();
100
+
101
+/**
102
+ * methodIndex to include in tracebacks when using includeLineNumbers
103
+ *
104
+ * @var array
105
+ */
106
+	protected $_methodIndex = array('info', 'log', 'warn', 'error', 'table', 'trace');
107
+
108
+/**
109
+ * FireCake output status
110
+ *
111
+ * @var boolean
112
+ */
113
+	protected $_enabled = true;
114
+
115
+/**
116
+ * get Instance of the singleton
117
+ *
118
+ * @param string $class Class instance to store in the singleton. Used with subclasses and Tests.
119
+ * @return FireCake
120
+ */
121
+	public static function getInstance($class = null) {
122
+		static $instance = array();
123
+		if (!empty($class)) {
124
+			if (!$instance || strtolower($class) !== strtolower(get_class($instance[0]))) {
125
+				$instance[0] = new $class();
126
+				$instance[0]->setOptions();
127
+			}
128
+		}
129
+		if (!isset($instance[0]) || !$instance[0]) {
130
+			$instance[0] = new FireCake();
131
+			$instance[0]->setOptions();
132
+		}
133
+		return $instance[0];
134
+	}
135
+
136
+/**
137
+ * setOptions
138
+ *
139
+ * @param array $options Array of options to set.
140
+ * @return void
141
+ */
142
+	public static function setOptions($options = array()) {
143
+		$_this = FireCake::getInstance();
144
+		if (empty($_this->options)) {
145
+			$_this->options = array_merge($_this->_defaultOptions, $options);
146
+		} else {
147
+			$_this->options = array_merge($_this->options, $options);
148
+		}
149
+	}
150
+
151
+/**
152
+ * Return boolean based on presence of FirePHP extension
153
+ *
154
+ * @return boolean
155
+ */
156
+	public static function detectClientExtension() {
157
+		$ua = FireCake::getUserAgent();
158
+		if (preg_match('/\sFirePHP\/([\.|\d]*)\s?/si', $ua, $match) && version_compare($match[1], '0.0.6', '>=')) {
159
+			return true;
160
+		}
161
+		if (env('HTTP_X_FIREPHP_VERSION') && version_compare(env('HTTP_X_FIREPHP_VERSION'), '0.6', '>=')) {
162
+			return true;
163
+		}
164
+		return false;
165
+	}
166
+
167
+/**
168
+ * Get the Current UserAgent
169
+ *
170
+ * @return string UserAgent string of active client connection
171
+ */
172
+	public static function getUserAgent() {
173
+		return env('HTTP_USER_AGENT');
174
+	}
175
+
176
+/**
177
+ * Disable FireCake output
178
+ * All subsequent output calls will not be run.
179
+ *
180
+ * @return void
181
+ */
182
+	public static function disable() {
183
+		$_this = FireCake::getInstance();
184
+		$_this->_enabled = false;
185
+	}
186
+
187
+/**
188
+ * Enable FireCake output
189
+ *
190
+ * @return void
191
+ */
192
+	public static function enable() {
193
+		$_this = FireCake::getInstance();
194
+		$_this->_enabled = true;
195
+	}
196
+
197
+/**
198
+ * Convenience wrapper for LOG messages
199
+ *
200
+ * @param string $message Message to log
201
+ * @param string $label Label for message (optional)
202
+ * @return void
203
+ */
204
+	public static function log($message, $label = null) {
205
+		FireCake::fb($message, $label, 'log');
206
+	}
207
+
208
+/**
209
+ * Convenience wrapper for WARN messages
210
+ *
211
+ * @param string $message Message to log
212
+ * @param string $label Label for message (optional)
213
+ * @return void
214
+ */
215
+	public static function warn($message, $label = null) {
216
+		FireCake::fb($message, $label, 'warn');
217
+	}
218
+
219
+/**
220
+ * Convenience wrapper for INFO messages
221
+ *
222
+ * @param string $message Message to log
223
+ * @param string $label Label for message (optional)
224
+ * @return void
225
+ */
226
+	public static function info($message, $label = null) {
227
+		FireCake::fb($message, $label, 'info');
228
+	}
229
+
230
+/**
231
+ * Convenience wrapper for ERROR messages
232
+ *
233
+ * @param string $message Message to log
234
+ * @param string $label Label for message (optional)
235
+ * @return void
236
+ */
237
+	public static function error($message, $label = null) {
238
+		FireCake::fb($message, $label, 'error');
239
+	}
240
+
241
+/**
242
+ * Convenience wrapper for TABLE messages
243
+ *
244
+ * @param string $label Label for message (optional)
245
+ * @param string $message Message to log
246
+ * @return void
247
+ */
248
+	public static function table($label, $message) {
249
+		FireCake::fb($message, $label, 'table');
250
+	}
251
+
252
+/**
253
+ * Convenience wrapper for DUMP messages
254
+ *
255
+ * @param string $label Unique label for message
256
+ * @param string $message Message to log
257
+ * @return void
258
+ */
259
+	public static function dump($label, $message) {
260
+		FireCake::fb($message, $label, 'dump');
261
+	}
262
+
263
+/**
264
+ * Convenience wrapper for TRACE messages
265
+ *
266
+ * @param string $label Label for message (optional)
267
+ * @return void
268
+ */
269
+	public static function trace($label) {
270
+		FireCake::fb($label, 'trace');
271
+	}
272
+
273
+/**
274
+ * Convenience wrapper for GROUP messages
275
+ * Messages following the group call will be nested in a group block
276
+ *
277
+ * @param string $label Label for group (optional)
278
+ * @return void
279
+ */
280
+	public static function group($label) {
281
+		FireCake::fb(null, $label, 'groupStart');
282
+	}
283
+
284
+/**
285
+ * Convenience wrapper for GROUPEND messages
286
+ * Closes a group block
287
+ *
288
+ * @internal param string $label Label for group (optional)
289
+ * @return void
290
+ */
291
+	public static function groupEnd() {
292
+		FireCake::fb(null, null, 'groupEnd');
293
+	}
294
+
295
+/**
296
+ * fb - Send messages with FireCake to FirePHP
297
+ *
298
+ * Much like FirePHP's fb() this method can be called with various parameter counts
299
+ * fb($message) - Just send a message defaults to LOG type
300
+ * fb($message, $type) - Send a message with a specific type
301
+ * fb($message, $label, $type) - Send a message with a custom label and type.
302
+ *
303
+ * @param mixed $message Message to output. For other parameters see usage above.
304
+ * @return boolean Success
305
+ */
306
+	public static function fb($message) {
307
+		$_this = FireCake::getInstance();
308
+
309
+		if (headers_sent($filename, $linenum)) {
310
+			trigger_error(__d('debug_kit', 'Headers already sent in %s on line %s. Cannot send log data to FirePHP.', $filename, $linenum), E_USER_WARNING);
311
+			return false;
312
+		}
313
+		if (!$_this->_enabled || !$_this->detectClientExtension()) {
314
+			return false;
315
+		}
316
+
317
+		$args = func_get_args();
318
+		$type = $label = null;
319
+		switch (count($args)) {
320
+			case 1:
321
+				$type = $_this->_levels['log'];
322
+				break;
323
+			case 2:
324
+				$type = $args[1];
325
+				break;
326
+			case 3:
327
+				$type = $args[2];
328
+				$label = $args[1];
329
+				break;
330
+			default:
331
+				trigger_error(__d('debug_kit', 'Incorrect parameter count for FireCake::fb()'), E_USER_WARNING);
332
+				return false;
333
+		}
334
+		if (isset($_this->_levels[$type])) {
335
+			$type = $_this->_levels[$type];
336
+		} else {
337
+			$type = $_this->_levels['log'];
338
+		}
339
+
340
+		$meta = array();
341
+		$skipFinalObjectEncode = false;
342
+		if ($type == $_this->_levels['trace']) {
343
+			$trace = debug_backtrace();
344
+			if (!$trace) {
345
+				return false;
346
+			}
347
+			$message = FireCake::_parseTrace($trace, $args[0]);
348
+			$skipFinalObjectEncode = true;
349
+		}
350
+
351
+		if ($_this->options['includeLineNumbers']) {
352
+			if (!isset($meta['file']) || !isset($meta['line'])) {
353
+				$trace = debug_backtrace();
354
+				for ($i = 0, $len = count($trace); $i < $len; $i++) {
355
+					$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
356
+					$selfCall = ($keySet &&
357
+						strtolower($trace[$i]['class']) === 'firecake' &&
358
+						in_array($trace[$i]['function'], $_this->_methodIndex)
359
+					);
360
+					if ($selfCall) {
361
+						$meta['File'] = isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '';
362
+						$meta['Line'] = isset($trace[$i]['line']) ? $trace[$i]['line'] : '';
363
+						break;
364
+					}
365
+				}
366
+			}
367
+		}
368
+
369
+		$structureIndex = 1;
370
+		if ($type == $_this->_levels['dump']) {
371
+			$structureIndex = 2;
372
+			$_this->_sendHeader('X-Wf-1-Structure-2', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/Dump/0.1');
373
+		} else {
374
+			$_this->_sendHeader('X-Wf-1-Structure-1', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
375
+		}
376
+
377
+		$_this->_sendHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
378
+		$_this->_sendHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/' . $_this->_version);
379
+		if ($type == $_this->_levels['groupStart']) {
380
+			$meta['Collapsed'] = 'true';
381
+		}
382
+		if ($type == $_this->_levels['dump']) {
383
+			$dump = FireCake::jsonEncode($message);
384
+			$msg = '{"' . $label . '":' . $dump . '}';
385
+		} else {
386
+			$meta['Type'] = $type;
387
+			if ($label !== null) {
388
+				$meta['Label'] = $label;
389
+			}
390
+			$msg = '[' . $_this->jsonEncode($meta) . ',' . $_this->jsonEncode($message, $skipFinalObjectEncode) . ']';
391
+		}
392
+
393
+		$lines = explode("\n", chunk_split($msg, 5000, "\n"));
394
+
395
+		foreach ($lines as $i => $line) {
396
+			if (empty($line)) {
397
+				continue;
398
+			}
399
+			$header = 'X-Wf-1-' . $structureIndex . '-1-' . $_this->_messageIndex;
400
+			if (count($lines) > 2) {
401
+				$first = ($i == 0) ? strlen($msg) : '';
402
+				$end = ($i < count($lines) - 2) ? '\\' : '';
403
+				$message = $first . '|' . $line . '|' . $end;
404
+				$_this->_sendHeader($header, $message);
405
+			} else {
406
+				$_this->_sendHeader($header, strlen($line) . '|' . $line . '|');
407
+			}
408
+			$_this->_messageIndex++;
409
+			if ($_this->_messageIndex > 99999) {
410
+				trigger_error(__d('debug_kit', 'Maximum number (99,999) of messages reached!'), E_USER_WARNING);
411
+			}
412
+		}
413
+		$_this->_sendHeader('X-Wf-1-Index', $_this->_messageIndex - 1);
414
+		return true;
415
+	}
416
+
417
+/**
418
+ * Parse a debug backtrace
419
+ *
420
+ * @param array $trace Debug backtrace output
421
+ * @param $messageName
422
+ * @return array
423
+ */
424
+	protected static function _parseTrace($trace, $messageName) {
425
+		$message = array();
426
+		for ($i = 0, $len = count($trace); $i < $len; $i++) {
427
+			$keySet = (isset($trace[$i]['class']) && isset($trace[$i]['function']));
428
+			$selfCall = ($keySet && $trace[$i]['class'] === 'FireCake');
429
+			if (!$selfCall) {
430
+				$message = array(
431
+					'Class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : '',
432
+					'Type' => isset($trace[$i]['type']) ? $trace[$i]['type'] : '',
433
+					'Function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : '',
434
+					'Message' => $messageName,
435
+					'File' => isset($trace[$i]['file']) ? Debugger::trimPath($trace[$i]['file']) : '',
436
+					'Line' => isset($trace[$i]['line']) ? $trace[$i]['line'] : '',
437
+					'Args' => isset($trace[$i]['args']) ? FireCake::stringEncode($trace[$i]['args']) : '',
438
+					'Trace' => FireCake::_escapeTrace(array_splice($trace, $i + 1))
439
+				);
440
+				break;
441
+			}
442
+		}
443
+		return $message;
444
+	}
445
+
446
+/**
447
+ * Fix a trace for use in output
448
+ *
449
+ * @param mixed $trace Trace to fix
450
+ * @return string
451
+ */
452
+	protected static function _escapeTrace($trace) {
453
+		for ($i = 0, $len = count($trace); $i < $len; $i++) {
454
+			if (isset($trace[$i]['file'])) {
455
+				$trace[$i]['file'] = Debugger::trimPath($trace[$i]['file']);
456
+			}
457
+			if (isset($trace[$i]['args'])) {
458
+				$trace[$i]['args'] = FireCake::stringEncode($trace[$i]['args']);
459
+			}
460
+		}
461
+		return $trace;
462
+	}
463
+
464
+/**
465
+ * Encode non string objects to string.
466
+ * Filter out recursion, so no errors are raised by json_encode or $javascript->object()
467
+ *
468
+ * @param mixed $object Object or variable to encode to string.
469
+ * @param integer $objectDepth Current Depth in object chains.
470
+ * @param integer $arrayDepth Current Depth in array chains.
471
+ * @return string|Object
472
+ */
473
+	public static function stringEncode($object, $objectDepth = 1, $arrayDepth = 1) {
474
+		$_this = FireCake::getInstance();
475
+		$return = array();
476
+		if (is_resource($object)) {
477
+			return '** ' . (string)$object . '**';
478
+		}
479
+		if (is_object($object)) {
480
+			if ($objectDepth == $_this->options['maxObjectDepth']) {
481
+				return '** Max Object Depth (' . $_this->options['maxObjectDepth'] . ') **';
482
+			}
483
+			foreach ($_this->_encodedObjects as $encoded) {
484
+				if ($encoded === $object) {
485
+					return '** Recursion (' . get_class($object) . ') **';
486
+				}
487
+			}
488
+			$_this->_encodedObjects[] = $object;
489
+
490
+			$return['__className'] = $class = get_class($object);
491
+			$properties = get_object_vars($object);
492
+			foreach ($properties as $name => $property) {
493
+				$return[$name] = FireCake::stringEncode($property, 1, $objectDepth + 1);
494
+			}
495
+			array_pop($_this->_encodedObjects);
496
+		}
497
+		if (is_array($object)) {
498
+			if ($arrayDepth == $_this->options['maxArrayDepth']) {
499
+				return '** Max Array Depth (' . $_this->options['maxArrayDepth'] . ') **';
500
+			}
501
+			foreach ($object as $key => $value) {
502
+				$return[$key] = FireCake::stringEncode($value, 1, $arrayDepth + 1);
503
+			}
504
+		}
505
+		if (is_string($object) || is_numeric($object) || is_bool($object) || $object === null) {
506
+			return $object;
507
+		}
508
+		return $return;
509
+	}
510
+
511
+/**
512
+ * Encode an object into JSON
513
+ *
514
+ * @param mixed $object Object or array to json encode
515
+ * @param boolean $skipEncode
516
+ * @internal param bool $doIt
517
+ * @static
518
+ * @return string
519
+ */
520
+	public static function jsonEncode($object, $skipEncode = false) {
521
+		$_this = FireCake::getInstance();
522
+		if (!$skipEncode) {
523
+			$object = FireCake::stringEncode($object);
524
+		}
525
+		return json_encode($object);
526
+	}
527
+
528
+/**
529
+ * Send Headers - write headers.
530
+ *
531
+ * @param $name
532
+ * @param $value
533
+ * @return void
534
+ */
535
+	protected function _sendHeader($name, $value) {
536
+		header($name . ': ' . $value);
537
+	}
538
+}

+ 50
- 0
Plugin/DebugKit/Lib/Log/Engine/DebugKitLog.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+/**
15
+ * A CakeLog listener which saves having to munge files or other configured loggers.
16
+ *
17
+ */
18
+class DebugKitLog implements CakeLogInterface {
19
+
20
+/**
21
+ * logs
22
+ *
23
+ * @var array
24
+ */
25
+	public $logs = array();
26
+
27
+/**
28
+ * Makes the reverse link needed to get the logs later.
29
+ *
30
+ * @param $options
31
+ * @return \DebugKitLog
32
+ */
33
+	public function __construct($options) {
34
+		$options['panel']->logger = $this;
35
+	}
36
+
37
+/**
38
+ * Captures log messages in memory
39
+ *
40
+ * @param $type
41
+ * @param $message
42
+ * @return void
43
+ */
44
+	public function write($type, $message) {
45
+		if (!isset($this->logs[$type])) {
46
+			$this->logs[$type] = array();
47
+		}
48
+		$this->logs[$type][] = array(date('Y-m-d H:i:s'), (string)$message);
49
+	}
50
+}

+ 81
- 0
Plugin/DebugKit/Lib/Panel/EnvironmentPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ *
13
+ */
14
+
15
+App::uses('DebugPanel', 'DebugKit.Lib');
16
+
17
+/**
18
+ * Provides information about your PHP and CakePHP environment to assist with debugging.
19
+ *
20
+ */
21
+class EnvironmentPanel extends DebugPanel {
22
+
23
+/**
24
+ * beforeRender - Get necessary data about environment to pass back to controller
25
+ *
26
+ * @param Controller $controller
27
+ * @return array
28
+ */
29
+	public function beforeRender(Controller $controller) {
30
+		parent::beforeRender($controller);
31
+
32
+		$return = array();
33
+
34
+		// PHP Data
35
+		$phpVer = phpversion();
36
+		$return['php'] = array_merge(array('PHP_VERSION' => $phpVer), $_SERVER);
37
+		unset($return['php']['argv']);
38
+
39
+		// CakePHP Data
40
+		$return['cake'] = array(
41
+			'APP' => APP,
42
+			'APP_DIR' => APP_DIR,
43
+			'APPLIBS' => APPLIBS,
44
+			'CACHE' => CACHE,
45
+			'CAKE' => CAKE,
46
+			'CAKE_CORE_INCLUDE_PATH' => CAKE_CORE_INCLUDE_PATH,
47
+			'CORE_PATH' => CORE_PATH,
48
+			'CAKE_VERSION' => Configure::version(),
49
+			'CSS' => CSS,
50
+			'CSS_URL' => CSS_URL,
51
+			'DS' => DS,
52
+			'FULL_BASE_URL' => FULL_BASE_URL,
53
+			'IMAGES' => IMAGES,
54
+			'IMAGES_URL' => IMAGES_URL,
55
+			'JS' => JS,
56
+			'JS_URL' => JS_URL,
57
+			'LOGS' => LOGS,
58
+			'ROOT' => ROOT,
59
+			'TESTS' => TESTS,
60
+			'TMP' => TMP,
61
+			'VENDORS' => VENDORS,
62
+			'WEBROOT_DIR' => WEBROOT_DIR,
63
+			'WWW_ROOT' => WWW_ROOT
64
+		);
65
+
66
+		$cakeConstants = array_fill_keys(
67
+			array(
68
+				'DS', 'ROOT', 'FULL_BASE_URL', 'TIME_START', 'SECOND', 'MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH', 'YEAR',
69
+				'LOG_ERROR', 'FULL_BASE_URL'
70
+			), ''
71
+		);
72
+		$var = get_defined_constants(true);
73
+		$return['app'] = array_diff_key($var['user'], $return['cake'], $cakeConstants);
74
+
75
+		if (isset($var['hidef'])) {
76
+			$return['hidef'] = $var['hidef'];
77
+		}
78
+
79
+		return $return;
80
+	}
81
+}

+ 83
- 0
Plugin/DebugKit/Lib/Panel/HistoryPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on previous requests.
18
+ *
19
+ */
20
+class HistoryPanel extends DebugPanel {
21
+
22
+/**
23
+ * Number of history elements to keep
24
+ *
25
+ * @var string
26
+ */
27
+	public $history = 5;
28
+
29
+/**
30
+ * Constructor
31
+ *
32
+ * @param array $settings Array of settings.
33
+ * @return \HistoryPanel
34
+ */
35
+	public function __construct($settings) {
36
+		if (isset($settings['history'])) {
37
+			$this->history = $settings['history'];
38
+		}
39
+	}
40
+
41
+/**
42
+ * beforeRender callback function
43
+ *
44
+ * @param Controller $controller
45
+ * @return array contents for panel
46
+ */
47
+	public function beforeRender(Controller $controller) {
48
+		$cacheKey = $controller->Toolbar->cacheKey;
49
+		$toolbarHistory = Cache::read($cacheKey, 'debug_kit');
50
+		$historyStates = array();
51
+		if (is_array($toolbarHistory) && !empty($toolbarHistory)) {
52
+			$prefix = array();
53
+			if (!empty($controller->request->params['prefix'])) {
54
+				$prefix[$controller->request->params['prefix']] = false;
55
+			}
56
+			foreach ($toolbarHistory as $i => $state) {
57
+				if (!isset($state['request']['content']['url'])) {
58
+					continue;
59
+				}
60
+				$title = $state['request']['content']['url'];
61
+				$query = @$state['request']['content']['query'];
62
+				if (isset($query['url'])) {
63
+					unset($query['url']);
64
+				}
65
+				if (!empty($query)) {
66
+					$title .= '?' . urldecode(http_build_query($query));
67
+				}
68
+				$historyStates[] = array(
69
+					'title' => $title,
70
+					'url' => array_merge($prefix, array(
71
+						'plugin' => 'debug_kit',
72
+						'controller' => 'toolbar_access',
73
+						'action' => 'history_state',
74
+						$i + 1))
75
+				);
76
+			}
77
+		}
78
+		if (count($historyStates) >= $this->history) {
79
+			array_pop($historyStates);
80
+		}
81
+		return $historyStates;
82
+	}
83
+}

+ 160
- 0
Plugin/DebugKit/Lib/Panel/IncludePanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides a list of included files for the current request
18
+ *
19
+ */
20
+class IncludePanel extends DebugPanel {
21
+
22
+/**
23
+ * The list of plugins within the application
24
+ *
25
+ * @var <type>
26
+ */
27
+	protected $_pluginPaths = array();
28
+
29
+/**
30
+ * File Types
31
+ *
32
+ * @var array
33
+ */
34
+	protected $_fileTypes = array(
35
+		'Cache', 'Config', 'Configure', 'Console', 'Component', 'Controller',
36
+		'Behavior', 'Datasource', 'Model', 'Plugin', 'Test', 'View', 'Utility',
37
+		'Network', 'Routing', 'I18n', 'Log', 'Error'
38
+	);
39
+
40
+/**
41
+ * Get a list of plugins on construct for later use
42
+ */
43
+	public function __construct() {
44
+		foreach (CakePlugin::loaded() as $plugin) {
45
+			$this->_pluginPaths[$plugin] = CakePlugin::path($plugin);
46
+		}
47
+
48
+		parent::__construct();
49
+	}
50
+
51
+/**
52
+ * Get a list of files that were included and split them out into the various parts of the app
53
+ *
54
+ * @param Controller $controller
55
+ * @return array
56
+ */
57
+	public function beforeRender(Controller $controller) {
58
+		$return = array('core' => array(), 'app' => array(), 'plugins' => array());
59
+
60
+		foreach (get_included_files() as $file) {
61
+			$pluginName = $this->_isPluginFile($file);
62
+
63
+			if ($pluginName) {
64
+				$return['plugins'][$pluginName][$this->_getFileType($file)][] = $this->_niceFileName($file, $pluginName);
65
+			} elseif ($this->_isAppFile($file)) {
66
+				$return['app'][$this->_getFileType($file)][] = $this->_niceFileName($file, 'app');
67
+			} elseif ($this->_isCoreFile($file)) {
68
+				$return['core'][$this->_getFileType($file)][] = $this->_niceFileName($file, 'core');
69
+			}
70
+		}
71
+
72
+		$return['paths'] = $this->_includePaths();
73
+
74
+		ksort($return['core']);
75
+		ksort($return['plugins']);
76
+		ksort($return['app']);
77
+		return $return;
78
+	}
79
+
80
+/**
81
+ * Get the possible include paths
82
+ * @return array
83
+ */
84
+	protected function _includePaths() {
85
+		$paths = array_flip(array_merge(explode(PATH_SEPARATOR, get_include_path()), array(CAKE)));
86
+
87
+		unset($paths['.']);
88
+		return array_flip($paths);
89
+	}
90
+
91
+/**
92
+ * Check if a path is part of cake core
93
+ * @param string $file
94
+ * @return boolean
95
+ */
96
+	protected function _isCoreFile($file) {
97
+		return strstr($file, CAKE);
98
+	}
99
+
100
+/**
101
+ * Check if a path is from APP but not a plugin
102
+ * @param string $file
103
+ * @return boolean
104
+ */
105
+	protected function _isAppFile($file) {
106
+		return strstr($file, APP);
107
+	}
108
+
109
+/**
110
+ * Check if a path is from a plugin
111
+ * @param string $file
112
+ * @return boolean
113
+ */
114
+	protected function _isPluginFile($file) {
115
+		foreach ($this->_pluginPaths as $plugin => $path) {
116
+			if (strstr($file, $path)) {
117
+				return $plugin;
118
+			}
119
+		}
120
+
121
+		return false;
122
+	}
123
+
124
+/**
125
+ * Replace the path with APP, CORE or the plugin name
126
+ * @param string $file
127
+ * @param string
128
+ *  - app for app files
129
+ *  - core for core files
130
+ *  - PluginName for the name of a plugin
131
+ * @return boolean
132
+ */
133
+	protected function _niceFileName($file, $type) {
134
+		switch ($type) {
135
+			case 'app':
136
+				return str_replace(APP, 'APP/', $file);
137
+
138
+			case 'core':
139
+				return str_replace(CAKE, 'CORE/', $file);
140
+
141
+			default:
142
+				return str_replace($this->_pluginPaths[$type], $type . '/', $file);
143
+		}
144
+	}
145
+
146
+/**
147
+ * Get the type of file (model, controller etc)
148
+ * @param string $file
149
+ * @return string
150
+ */
151
+	protected function _getFileType($file) {
152
+		foreach ($this->_fileTypes as $type) {
153
+			if (stripos($file, '/' . $type . '/') !== false) {
154
+				return $type;
155
+			}
156
+		}
157
+
158
+		return 'Other';
159
+	}
160
+}

+ 51
- 0
Plugin/DebugKit/Lib/Panel/LogPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Log Panel - Reads log entries made this request.
18
+ *
19
+ */
20
+class LogPanel extends DebugPanel {
21
+
22
+/**
23
+ * Constructor - sets up the log listener.
24
+ *
25
+ * @return \LogPanel
26
+ */
27
+	public function __construct() {
28
+		parent::__construct();
29
+		$existing = CakeLog::configured();
30
+		if (empty($existing)) {
31
+			CakeLog::config('default', array(
32
+				'engine' => 'FileLog'
33
+			));
34
+		}
35
+		CakeLog::config('debug_kit_log_panel', array(
36
+			'engine' => 'DebugKit.DebugKitLog',
37
+			'panel' => $this
38
+		));
39
+	}
40
+
41
+/**
42
+ * beforeRender Callback
43
+ *
44
+ * @param Controller $controller
45
+ * @return array
46
+ */
47
+	public function beforeRender(Controller $controller) {
48
+		$logger = $this->logger;
49
+		return $logger;
50
+	}
51
+}

+ 41
- 0
Plugin/DebugKit/Lib/Panel/RequestPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on the Current request params.
18
+ *
19
+ */
20
+class RequestPanel extends DebugPanel {
21
+
22
+/**
23
+ * beforeRender callback - grabs request params
24
+ *
25
+ * @param Controller $controller
26
+ * @return array
27
+ */
28
+	public function beforeRender(Controller $controller) {
29
+		$out = array();
30
+		$out['params'] = $controller->request->params;
31
+		$out['url'] = $controller->request->url;
32
+		$out['query'] = $controller->request->query;
33
+		$out['data'] = $controller->request->data;
34
+		if (isset($controller->Cookie)) {
35
+			$out['cookie'] = $controller->Cookie->read();
36
+		}
37
+		$out['get'] = $_GET;
38
+		$out['currentRoute'] = Router::currentRoute();
39
+		return $out;
40
+	}
41
+}

+ 32
- 0
Plugin/DebugKit/Lib/Panel/SessionPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on the Session contents.
18
+ *
19
+ */
20
+class SessionPanel extends DebugPanel {
21
+
22
+/**
23
+ * beforeRender callback
24
+ *
25
+ * @param \Controller|object $controller
26
+ * @return array
27
+ */
28
+	public function beforeRender(Controller $controller) {
29
+		$sessions = $controller->Toolbar->Session->read();
30
+		return $sessions;
31
+	}
32
+}

+ 64
- 0
Plugin/DebugKit/Lib/Panel/SqlLogPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on the SQL logs and provides links to an ajax explain interface.
18
+ *
19
+ */
20
+class SqlLogPanel extends DebugPanel {
21
+
22
+/**
23
+ * Minimum number of Rows Per Millisecond that must be returned by a query before an explain
24
+ * is done.
25
+ *
26
+ * @var integer
27
+ */
28
+	public $slowRate = 20;
29
+
30
+/**
31
+ * Gets the connection names that should have logs + dumps generated.
32
+ *
33
+ * @param \Controller|string $controller
34
+ * @return array
35
+ */
36
+	public function beforeRender(Controller $controller) {
37
+		if (!class_exists('ConnectionManager')) {
38
+			return array();
39
+		}
40
+		$connections = array();
41
+
42
+		$dbConfigs = ConnectionManager::sourceList();
43
+		foreach ($dbConfigs as $configName) {
44
+			$driver = null;
45
+			$db = ConnectionManager::getDataSource($configName);
46
+			if (
47
+				(empty($db->config['driver']) && empty($db->config['datasource'])) ||
48
+				!method_exists($db, 'getLog')
49
+			) {
50
+				continue;
51
+			}
52
+			if (isset($db->config['datasource'])) {
53
+				$driver = $db->config['datasource'];
54
+			}
55
+			$explain = false;
56
+			$isExplainable = (preg_match('/(Mysql|Postgres)$/', $driver));
57
+			if ($isExplainable) {
58
+				$explain = true;
59
+			}
60
+			$connections[$configName] = $explain;
61
+		}
62
+		return array('connections' => $connections, 'threshold' => $this->slowRate);
63
+	}
64
+}

+ 36
- 0
Plugin/DebugKit/Lib/Panel/TimerPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on all timers used in a request.
18
+ *
19
+ */
20
+class TimerPanel extends DebugPanel {
21
+
22
+/**
23
+ * startup - add in necessary helpers
24
+ *
25
+ * @param Controller $controller
26
+ * @return void
27
+ */
28
+	public function startup(Controller $controller) {
29
+		if (!in_array('Number', array_keys(HelperCollection::normalizeObjectArray($controller->helpers)))) {
30
+			$controller->helpers[] = 'Number';
31
+		}
32
+		if (!in_array('SimpleGraph', array_keys(HelperCollection::normalizeObjectArray($controller->helpers)))) {
33
+			$controller->helpers[] = 'DebugKit.SimpleGraph';
34
+		}
35
+	}
36
+}

+ 31
- 0
Plugin/DebugKit/Lib/Panel/VariablesPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('DebugPanel', 'DebugKit.Lib');
15
+
16
+/**
17
+ * Provides debug information on the View variables.
18
+ *
19
+ */
20
+class VariablesPanel extends DebugPanel {
21
+
22
+/**
23
+ * beforeRender callback
24
+ *
25
+ * @param Controller $controller
26
+ * @return array
27
+ */
28
+	public function beforeRender(Controller $controller) {
29
+		return array_merge($controller->viewVars, array('$request->data' => $controller->request->data));
30
+	}
31
+}

+ 138
- 0
Plugin/DebugKit/Locale/debug_kit.pot 파일 보기

1
+# LANGUAGE translation of Debug Kit Application
2
+# Copyright 2008 Andy Dawson <andydawson76@yahoo.co.uk>
3
+# No version information was available in the source files.
4
+#
5
+#, fuzzy
6
+msgid ""
7
+msgstr ""
8
+"Project-Id-Version: debug_kit-\n"
9
+"POT-Creation-Date: 2009-05-27 09:47+0200\n"
10
+"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
11
+"Last-Translator: Andy Dawson <andydawson76@yahoo.co.uk>\n"
12
+"Language-Team:\n"
13
+"MIME-Version: 1.0\n"
14
+"Content-Type: text/plain; charset=utf-8\n"
15
+"Content-Transfer-Encoding: 8bit\n"
16
+"X-Poedit-Basepath: ../../../\n"
17
+
18
+#: controllers/components/toolbar.php:91
19
+msgid "Component initialization and startup"
20
+msgstr ""
21
+
22
+#: controllers/components/toolbar.php:140
23
+msgid "Controller Action"
24
+msgstr ""
25
+
26
+#: controllers/components/toolbar.php:167
27
+msgid "Render Controller Action"
28
+msgstr ""
29
+
30
+#: controllers/components/toolbar.php:231
31
+msgid "Could not load DebugToolbar panel %s"
32
+msgstr ""
33
+
34
+#: views/elements/debug_toolbar.ctp:25
35
+msgid "There are no active panels. You must enable a panel to see its output."
36
+msgstr ""
37
+
38
+#: views/elements/history_panel.ctp:21
39
+msgid "Request History"
40
+msgstr ""
41
+
42
+#: views/elements/history_panel.ctp:23
43
+msgid "No previous requests logged."
44
+msgstr ""
45
+
46
+#: views/elements/history_panel.ctp:25
47
+msgid "previous requests available"
48
+msgstr ""
49
+
50
+#: views/elements/history_panel.ctp:27
51
+msgid "Restore to current request"
52
+msgstr ""
53
+
54
+#: views/elements/log_panel.ctp:21
55
+msgid "Logs"
56
+msgstr ""
57
+
58
+#: views/elements/log_panel.ctp:28
59
+msgid "Time"
60
+msgstr ""
61
+
62
+#: views/elements/log_panel.ctp:28
63
+#: views/elements/timer_panel.ctp:54
64
+msgid "Message"
65
+msgstr ""
66
+
67
+#: views/elements/log_panel.ctp:37
68
+msgid "There were no log entries made this request"
69
+msgstr ""
70
+
71
+#: views/elements/request_panel.ctp:21
72
+msgid "Request"
73
+msgstr ""
74
+
75
+#: views/elements/request_panel.ctp:35
76
+msgid "Current Route"
77
+msgstr ""
78
+
79
+#: views/elements/session_panel.ctp:21
80
+msgid "Session"
81
+msgstr ""
82
+
83
+#: views/elements/sql_log_panel.ctp:21
84
+msgid "Sql Logs"
85
+msgstr ""
86
+
87
+#: views/elements/sql_log_panel.ctp:31
88
+msgid "toggle (%s) query explains for %s"
89
+msgstr ""
90
+
91
+#: views/elements/sql_log_panel.ctp:39
92
+msgid "No slow queries!, or your database does not support EXPLAIN"
93
+msgstr ""
94
+
95
+#: views/elements/sql_log_panel.ctp:44
96
+msgid "No active database connections"
97
+msgstr ""
98
+
99
+#: views/elements/timer_panel.ctp:33
100
+msgid "Memory"
101
+msgstr ""
102
+
103
+#: views/elements/timer_panel.ctp:35
104
+msgid "Current Memory Use"
105
+msgstr ""
106
+
107
+#: views/elements/timer_panel.ctp:39
108
+msgid "Peak Memory Use"
109
+msgstr ""
110
+
111
+#: views/elements/timer_panel.ctp:43
112
+msgid "Timers"
113
+msgstr ""
114
+
115
+#: views/elements/timer_panel.ctp:45
116
+msgid "%s (ms)"
117
+msgstr ""
118
+
119
+#: views/elements/timer_panel.ctp:46
120
+msgid "Total Request Time:"
121
+msgstr ""
122
+
123
+#: views/elements/timer_panel.ctp:54
124
+msgid "Time in ms"
125
+msgstr ""
126
+
127
+#: views/elements/timer_panel.ctp:54
128
+msgid "Graph"
129
+msgstr ""
130
+
131
+#: views/elements/variables_panel.ctp:21
132
+msgid "View Variables"
133
+msgstr ""
134
+
135
+#: views/helpers/simple_graph.php:79
136
+msgid "Starting %sms into the request, taking %sms"
137
+msgstr ""
138
+

+ 135
- 0
Plugin/DebugKit/Locale/eng/LC_MESSAGES/debug_kit.po 파일 보기

1
+# LANGUAGE translation of CakePHP Application
2
+# Copyright YEAR NAME <EMAIL@ADDRESS>
3
+# No version information was available in the source files.
4
+#
5
+#, fuzzy
6
+msgid   ""
7
+msgstr  "Project-Id-Version: PROJECT VERSION\n"
8
+        "POT-Creation-Date: 2009-05-27 09:47+0200\n"
9
+        "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
10
+        "Last-Translator: NAME <EMAIL@ADDRESS>\n"
11
+        "Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
12
+        "MIME-Version: 1.0\n"
13
+        "Content-Type: text/plain; charset=UTF-8\n"
14
+        "Content-Transfer-Encoding: 8bit\n"
15
+        "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
16
+
17
+#: controllers/components/toolbar.php:91
18
+msgid   "Component initialization and startup"
19
+msgstr  ""
20
+
21
+#: controllers/components/toolbar.php:140
22
+msgid   "Controller Action"
23
+msgstr  ""
24
+
25
+#: controllers/components/toolbar.php:167
26
+msgid   "Render Controller Action"
27
+msgstr  ""
28
+
29
+#: controllers/components/toolbar.php:231
30
+msgid   "Could not load DebugToolbar panel %s"
31
+msgstr  ""
32
+
33
+#: views/elements/debug_toolbar.ctp:25
34
+msgid   "There are no active panels. You must enable a panel to see its output."
35
+msgstr  ""
36
+
37
+#: views/elements/history_panel.ctp:21
38
+msgid   "Request History"
39
+msgstr  ""
40
+
41
+#: views/elements/history_panel.ctp:23
42
+msgid   "No previous requests logged."
43
+msgstr  ""
44
+
45
+#: views/elements/history_panel.ctp:25
46
+msgid   "previous requests available"
47
+msgstr  ""
48
+
49
+#: views/elements/history_panel.ctp:27
50
+msgid   "Restore to current request"
51
+msgstr  ""
52
+
53
+#: views/elements/log_panel.ctp:21
54
+msgid   "Logs"
55
+msgstr  ""
56
+
57
+#: views/elements/log_panel.ctp:28
58
+msgid   "Time"
59
+msgstr  ""
60
+
61
+#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54
62
+msgid   "Message"
63
+msgstr  ""
64
+
65
+#: views/elements/log_panel.ctp:37
66
+msgid   "There were no log entries made this request"
67
+msgstr  ""
68
+
69
+#: views/elements/request_panel.ctp:21
70
+msgid   "Request"
71
+msgstr  ""
72
+
73
+#: views/elements/request_panel.ctp:35
74
+msgid   "Current Route"
75
+msgstr  ""
76
+
77
+#: views/elements/session_panel.ctp:21
78
+msgid   "Session"
79
+msgstr  ""
80
+
81
+#: views/elements/sql_log_panel.ctp:21
82
+msgid   "Sql Logs"
83
+msgstr  ""
84
+
85
+#: views/elements/sql_log_panel.ctp:31
86
+msgid   "toggle (%s) query explains for %s"
87
+msgstr  ""
88
+
89
+#: views/elements/sql_log_panel.ctp:39
90
+msgid   "No slow queries!, or your database does not support EXPLAIN"
91
+msgstr  ""
92
+
93
+#: views/elements/sql_log_panel.ctp:44
94
+msgid   "No active database connections"
95
+msgstr  ""
96
+
97
+#: views/elements/timer_panel.ctp:33
98
+msgid   "Memory"
99
+msgstr  ""
100
+
101
+#: views/elements/timer_panel.ctp:35
102
+msgid   "Current Memory Use"
103
+msgstr  ""
104
+
105
+#: views/elements/timer_panel.ctp:39
106
+msgid   "Peak Memory Use"
107
+msgstr  ""
108
+
109
+#: views/elements/timer_panel.ctp:43
110
+msgid   "Timers"
111
+msgstr  ""
112
+
113
+#: views/elements/timer_panel.ctp:45
114
+msgid   "%s (ms)"
115
+msgstr  ""
116
+
117
+#: views/elements/timer_panel.ctp:46
118
+msgid   "Total Request Time:"
119
+msgstr  ""
120
+
121
+#: views/elements/timer_panel.ctp:54
122
+msgid   "Time in ms"
123
+msgstr  ""
124
+
125
+#: views/elements/timer_panel.ctp:54
126
+msgid   "Graph"
127
+msgstr  ""
128
+
129
+#: views/elements/variables_panel.ctp:21
130
+msgid   "View Variables"
131
+msgstr  ""
132
+
133
+#: views/helpers/simple_graph.php:79
134
+msgid   "Starting %sms into the request, taking %sms"
135
+msgstr  ""

+ 135
- 0
Plugin/DebugKit/Locale/fra/LC_MESSAGES/debug_kit.po 파일 보기

1
+# LANGUAGE translation of CakePHP Application
2
+# Copyright YEAR NAME <EMAIL@ADDRESS>
3
+# No version information was available in the source files.
4
+#
5
+#, fuzzy
6
+msgid   ""
7
+msgstr  "Project-Id-Version: PROJECT VERSION\n"
8
+        "POT-Creation-Date: 2013-06-04 12:00+0200\n"
9
+        "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
10
+        "Last-Translator: cake17 <gvmail76-inscription@yahoo.fr>\n"
11
+        "Language-Team: \n"
12
+        "MIME-Version: 1.0\n"
13
+        "Content-Type: text/plain; charset=UTF-8\n"
14
+        "Content-Transfer-Encoding: 8bit\n"
15
+        "Plural-Forms: nplurals=2; plural=n>1;\n"
16
+
17
+#: controllers/components/toolbar.php:91
18
+msgid   "Component initialization and startup"
19
+msgstr  "Initialisation du component et démarrage"
20
+
21
+#: controllers/components/toolbar.php:140
22
+msgid   "Controller Action"
23
+msgstr  "Action du Controller"
24
+
25
+#: controllers/components/toolbar.php:167
26
+msgid   "Render Controller Action"
27
+msgstr  "Rendu de l'Action du Controller"
28
+
29
+#: controllers/components/toolbar.php:231
30
+msgid   "Could not load DebugToolbar panel %s"
31
+msgstr  "Ne peut charger le panel %s de DebugToolbar"
32
+
33
+#: views/elements/debug_toolbar.ctp:25
34
+msgid   "There are no active panels. You must enable a panel to see its output."
35
+msgstr  "Il n'y a pas de panels actifs. Vous devez activer le panel pour voir sa sortie."
36
+
37
+#: views/elements/history_panel.ctp:21
38
+msgid   "Request History"
39
+msgstr  "Historique des Requêtes"
40
+
41
+#: views/elements/history_panel.ctp:23
42
+msgid   "No previous requests logged."
43
+msgstr  "Pas de demandes antérieures enregistrées."
44
+
45
+#: views/elements/history_panel.ctp:25
46
+msgid   "previous requests available"
47
+msgstr  "Des requêtes antérieures sont disponibles"
48
+
49
+#: views/elements/history_panel.ctp:27
50
+msgid   "Restore to current request"
51
+msgstr  "Restaure la requête actuelle"
52
+
53
+#: views/elements/log_panel.ctp:21
54
+msgid   "Logs"
55
+msgstr  "Logs"
56
+
57
+#: views/elements/log_panel.ctp:28
58
+msgid   "Time"
59
+msgstr  "Date"
60
+
61
+#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54
62
+msgid   "Message"
63
+msgstr  "Message"
64
+
65
+#: views/elements/log_panel.ctp:37
66
+msgid   "There were no log entries made this request"
67
+msgstr  "Il n'y avait pas d'entrées de log faîtes pour cette requête"
68
+
69
+#: views/elements/request_panel.ctp:21
70
+msgid   "Request"
71
+msgstr  "Requête"
72
+
73
+#: views/elements/request_panel.ctp:35
74
+msgid   "Current Route"
75
+msgstr  "Route actuelle"
76
+
77
+#: views/elements/session_panel.ctp:21
78
+msgid   "Session"
79
+msgstr  "Session"
80
+
81
+#: views/elements/sql_log_panel.ctp:21
82
+msgid   "Sql Logs"
83
+msgstr  "Logs Sql"
84
+
85
+#: views/elements/sql_log_panel.ctp:31
86
+msgid   "toggle (%s) query explains for %s"
87
+msgstr  "bascule (%s) requêtes expliquées pour %s"
88
+
89
+#: views/elements/sql_log_panel.ctp:39
90
+msgid   "No slow queries!, or your database does not support EXPLAIN"
91
+msgstr  "Pas de requêtes lentes!, ou votre base de données ne supporte pas EXPLAIN"
92
+
93
+#: views/elements/sql_log_panel.ctp:44
94
+msgid   "No active database connections"
95
+msgstr  "Pas de connections actives de la base de données"
96
+
97
+#: views/elements/timer_panel.ctp:33
98
+msgid   "Memory"
99
+msgstr  "Mémoire"
100
+
101
+#: views/elements/timer_panel.ctp:35
102
+msgid   "Current Memory Use"
103
+msgstr  "Utilisation de la Mémoire Actuelle"
104
+
105
+#: views/elements/timer_panel.ctp:39
106
+msgid   "Peak Memory Use"
107
+msgstr  "Utilisation de la Mémoire au niveau maximum"
108
+
109
+#: views/elements/timer_panel.ctp:43
110
+msgid   "Timers"
111
+msgstr  "Timers"
112
+
113
+#: views/elements/timer_panel.ctp:45
114
+msgid   "%s (ms)"
115
+msgstr  "%s (ms)"
116
+
117
+#: views/elements/timer_panel.ctp:46
118
+msgid   "Total Request Time:"
119
+msgstr  "Total du Temps de Requête"
120
+
121
+#: views/elements/timer_panel.ctp:54
122
+msgid   "Time in ms"
123
+msgstr  "Temps en ms"
124
+
125
+#: views/elements/timer_panel.ctp:54
126
+msgid   "Graph"
127
+msgstr  "Graph"
128
+
129
+#: views/elements/variables_panel.ctp:21
130
+msgid   "View Variables"
131
+msgstr  "Variables du View"
132
+
133
+#: views/helpers/simple_graph.php:79
134
+msgid   "Starting %sms into the request, taking %sms"
135
+msgstr  "Début en %sms de la requête, et prend %sms"

+ 136
- 0
Plugin/DebugKit/Locale/lim/LC_MESSAGES/debug_kit.po 파일 보기

1
+# LANGUAGE translation of Debug Kit Application
2
+# Copyright 2008 Andy Dawson <andydawson76@yahoo.co.uk>
3
+# No version information was available in the source files.
4
+#
5
+msgid ""
6
+msgstr ""
7
+"Project-Id-Version: debug_kit-\n"
8
+"POT-Creation-Date: 2009-05-27 09:47+0200\n"
9
+"PO-Revision-Date: 2009-05-27 09:47+0200\n"
10
+"Last-Translator: Automatically generated\n"
11
+"Language-Team:none\n"
12
+"MIME-Version: 1.0\n"
13
+"Content-Type: text/plain; charset=UTF-8\n"
14
+"Content-Transfer-Encoding: 8bit\n"
15
+"X-Poedit-Basepath: ../../../\n"
16
+"Language: lim\n"
17
+
18
+#: controllers/components/toolbar.php:91
19
+msgid "Component initialization and startup"
20
+msgstr ""
21
+
22
+#: controllers/components/toolbar.php:140
23
+msgid "Controller Action"
24
+msgstr ""
25
+
26
+#: controllers/components/toolbar.php:167
27
+msgid "Render Controller Action"
28
+msgstr ""
29
+
30
+#: controllers/components/toolbar.php:231
31
+msgid "Could not load DebugToolbar panel %s"
32
+msgstr ""
33
+
34
+#: views/elements/debug_toolbar.ctp:25
35
+msgid "There are no active panels. You must enable a panel to see its output."
36
+msgstr ""
37
+
38
+#: views/elements/history_panel.ctp:21
39
+msgid "Request History"
40
+msgstr ""
41
+
42
+#: views/elements/history_panel.ctp:23
43
+msgid "No previous requests logged."
44
+msgstr ""
45
+
46
+#: views/elements/history_panel.ctp:25
47
+msgid "previous requests available"
48
+msgstr ""
49
+
50
+#: views/elements/history_panel.ctp:27
51
+msgid "Restore to current request"
52
+msgstr ""
53
+
54
+#: views/elements/log_panel.ctp:21
55
+msgid "Logs"
56
+msgstr ""
57
+
58
+#: views/elements/log_panel.ctp:28
59
+msgid "Time"
60
+msgstr ""
61
+
62
+#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54
63
+msgid "Message"
64
+msgstr ""
65
+
66
+#: views/elements/log_panel.ctp:37
67
+msgid "There were no log entries made this request"
68
+msgstr ""
69
+
70
+#: views/elements/request_panel.ctp:21
71
+msgid "Request"
72
+msgstr ""
73
+
74
+#: views/elements/request_panel.ctp:35
75
+msgid "Current Route"
76
+msgstr ""
77
+
78
+#: views/elements/session_panel.ctp:21
79
+msgid "Session"
80
+msgstr ""
81
+
82
+#: views/elements/sql_log_panel.ctp:21
83
+msgid "Sql Logs"
84
+msgstr ""
85
+
86
+#: views/elements/sql_log_panel.ctp:31
87
+msgid "toggle (%s) query explains for %s"
88
+msgstr ""
89
+
90
+#: views/elements/sql_log_panel.ctp:39
91
+msgid "No slow queries!, or your database does not support EXPLAIN"
92
+msgstr ""
93
+
94
+#: views/elements/sql_log_panel.ctp:44
95
+msgid "No active database connections"
96
+msgstr ""
97
+
98
+#: views/elements/timer_panel.ctp:33
99
+msgid "Memory"
100
+msgstr ""
101
+
102
+#: views/elements/timer_panel.ctp:35
103
+msgid "Current Memory Use"
104
+msgstr ""
105
+
106
+#: views/elements/timer_panel.ctp:39
107
+msgid "Peak Memory Use"
108
+msgstr ""
109
+
110
+#: views/elements/timer_panel.ctp:43
111
+msgid "Timers"
112
+msgstr ""
113
+
114
+#: views/elements/timer_panel.ctp:45
115
+msgid "%s (ms)"
116
+msgstr ""
117
+
118
+#: views/elements/timer_panel.ctp:46
119
+msgid "Total Request Time:"
120
+msgstr ""
121
+
122
+#: views/elements/timer_panel.ctp:54
123
+msgid "Time in ms"
124
+msgstr ""
125
+
126
+#: views/elements/timer_panel.ctp:54
127
+msgid "Graph"
128
+msgstr ""
129
+
130
+#: views/elements/variables_panel.ctp:21
131
+msgid "View Variables"
132
+msgstr ""
133
+
134
+#: views/helpers/simple_graph.php:79
135
+msgid "Starting %sms into the request, taking %sms"
136
+msgstr ""

+ 141
- 0
Plugin/DebugKit/Locale/nld/LC_MESSAGES/debug_kit.po 파일 보기

1
+# LANGUAGE translation of Debug Kit Application
2
+# Copyright 2008 Andy Dawson <andydawson76@yahoo.co.uk>
3
+# No version information was available in the source files.
4
+#
5
+msgid ""
6
+msgstr ""
7
+"Project-Id-Version: debug_kit-\n"
8
+"POT-Creation-Date: 2009-05-27 09:47+0200\n"
9
+"PO-Revision-Date: 2014-07-17 17:04+0200\n"
10
+"Last-Translator: Marlin Cremers <m.cremers@cvo-technologies.com>\n"
11
+"Language-Team: \n"
12
+"Language: nld\n"
13
+"MIME-Version: 1.0\n"
14
+"Content-Type: text/plain; charset=utf-8\n"
15
+"Content-Transfer-Encoding: 8bit\n"
16
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
17
+"X-Generator: Weblate 1.9\n"
18
+"X-Poedit-Basepath: ../../../\n"
19
+
20
+#: controllers/components/toolbar.php:91
21
+msgid "Component initialization and startup"
22
+msgstr "Component initializatie en opstarten"
23
+
24
+#: controllers/components/toolbar.php:140
25
+msgid "Controller Action"
26
+msgstr "Controller Actie"
27
+
28
+#: controllers/components/toolbar.php:167
29
+msgid "Render Controller Action"
30
+msgstr "Produceer Controller Actie"
31
+
32
+#: controllers/components/toolbar.php:231
33
+msgid "Could not load DebugToolbar panel %s"
34
+msgstr "Kon DebugToolbar paneel %s niet laden"
35
+
36
+#: views/elements/debug_toolbar.ctp:25
37
+msgid "There are no active panels. You must enable a panel to see its output."
38
+msgstr ""
39
+"Er zijn geen actieve panelen. Je moet een paneel aanzetten om de uitvoer te "
40
+"zien."
41
+
42
+#: views/elements/history_panel.ctp:21
43
+msgid "Request History"
44
+msgstr "Aanvraag Geschiedenis"
45
+
46
+#: views/elements/history_panel.ctp:23
47
+msgid "No previous requests logged."
48
+msgstr "Geen vorige aanvragen gelogged."
49
+
50
+#: views/elements/history_panel.ctp:25
51
+msgid "previous requests available"
52
+msgstr "vorige aanvraag beschikbaar"
53
+
54
+#: views/elements/history_panel.ctp:27
55
+msgid "Restore to current request"
56
+msgstr "Herstel naar actuele aanvraag"
57
+
58
+#: views/elements/log_panel.ctp:21
59
+msgid "Logs"
60
+msgstr "Logs"
61
+
62
+#: views/elements/log_panel.ctp:28
63
+msgid "Time"
64
+msgstr "Tijd"
65
+
66
+#: views/elements/log_panel.ctp:28
67
+#: views/elements/timer_panel.ctp:54
68
+msgid "Message"
69
+msgstr "Bericht"
70
+
71
+#: views/elements/log_panel.ctp:37
72
+msgid "There were no log entries made this request"
73
+msgstr "Er zijn geen log vermeldingen gemaakt in deze aanvraag"
74
+
75
+#: views/elements/request_panel.ctp:21
76
+msgid "Request"
77
+msgstr "Aanvraag"
78
+
79
+#: views/elements/request_panel.ctp:35
80
+msgid "Current Route"
81
+msgstr "Huide Route"
82
+
83
+#: views/elements/session_panel.ctp:21
84
+msgid "Session"
85
+msgstr "Sessie"
86
+
87
+#: views/elements/sql_log_panel.ctp:21
88
+msgid "Sql Logs"
89
+msgstr "Sql Logs"
90
+
91
+#: views/elements/sql_log_panel.ctp:31
92
+msgid "toggle (%s) query explains for %s"
93
+msgstr "schakel (%s) aanvraag uitleg voor %s"
94
+
95
+#: views/elements/sql_log_panel.ctp:39
96
+msgid "No slow queries!, or your database does not support EXPLAIN"
97
+msgstr "Geen langzame vragen!, of je database ondersteund geen EXPLAIN"
98
+
99
+#: views/elements/sql_log_panel.ctp:44
100
+msgid "No active database connections"
101
+msgstr "Geen actieve database verbindingen"
102
+
103
+#: views/elements/timer_panel.ctp:33
104
+msgid "Memory"
105
+msgstr "Geheugen"
106
+
107
+#: views/elements/timer_panel.ctp:35
108
+msgid "Current Memory Use"
109
+msgstr "Actueel Geheugen Gebruik"
110
+
111
+#: views/elements/timer_panel.ctp:39
112
+msgid "Peak Memory Use"
113
+msgstr "Hoogste Geheugen Gebruik"
114
+
115
+#: views/elements/timer_panel.ctp:43
116
+msgid "Timers"
117
+msgstr "Timers"
118
+
119
+#: views/elements/timer_panel.ctp:45
120
+msgid "%s (ms)"
121
+msgstr "%s (ms)"
122
+
123
+#: views/elements/timer_panel.ctp:46
124
+msgid "Total Request Time:"
125
+msgstr "Totale Aanvraag Tijd:"
126
+
127
+#: views/elements/timer_panel.ctp:54
128
+msgid "Time in ms"
129
+msgstr "Tijd in ms"
130
+
131
+#: views/elements/timer_panel.ctp:54
132
+msgid "Graph"
133
+msgstr "Diagram"
134
+
135
+#: views/elements/variables_panel.ctp:21
136
+msgid "View Variables"
137
+msgstr "View Variabelen"
138
+
139
+#: views/helpers/simple_graph.php:79
140
+msgid "Starting %sms into the request, taking %sms"
141
+msgstr "Starten %sms in de aanvraag, neemt %sms"

+ 135
- 0
Plugin/DebugKit/Locale/spa/LC_MESSAGES/debug_kit.po 파일 보기

1
+# LANGUAGE translation of CakePHP Application
2
+# Copyright YEAR NAME <EMAIL@ADDRESS>
3
+# No version information was available in the source files.
4
+#
5
+#, fuzzy
6
+msgid   ""
7
+msgstr  "Project-Id-Version: PROJECT VERSION\n"
8
+        "POT-Creation-Date: 2009-05-27 09:47+0200\n"
9
+        "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n"
10
+        "Last-Translator: NAME <EMAIL@ADDRESS>\n"
11
+        "Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
12
+        "MIME-Version: 1.0\n"
13
+        "Content-Type: text/plain; charset=UTF-8\n"
14
+        "Content-Transfer-Encoding: 8bit\n"
15
+        "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
16
+
17
+#: controllers/components/toolbar.php:91
18
+msgid   "Component initialization and startup"
19
+msgstr  ""
20
+
21
+#: controllers/components/toolbar.php:140
22
+msgid   "Controller Action"
23
+msgstr  ""
24
+
25
+#: controllers/components/toolbar.php:167
26
+msgid   "Render Controller Action"
27
+msgstr  ""
28
+
29
+#: controllers/components/toolbar.php:231
30
+msgid   "Could not load DebugToolbar panel %s"
31
+msgstr  ""
32
+
33
+#: views/elements/debug_toolbar.ctp:25
34
+msgid   "There are no active panels. You must enable a panel to see its output."
35
+msgstr  ""
36
+
37
+#: views/elements/history_panel.ctp:21
38
+msgid   "Request History"
39
+msgstr  ""
40
+
41
+#: views/elements/history_panel.ctp:23
42
+msgid   "No previous requests logged."
43
+msgstr  ""
44
+
45
+#: views/elements/history_panel.ctp:25
46
+msgid   "previous requests available"
47
+msgstr  ""
48
+
49
+#: views/elements/history_panel.ctp:27
50
+msgid   "Restore to current request"
51
+msgstr  ""
52
+
53
+#: views/elements/log_panel.ctp:21
54
+msgid   "Logs"
55
+msgstr  ""
56
+
57
+#: views/elements/log_panel.ctp:28
58
+msgid   "Time"
59
+msgstr  ""
60
+
61
+#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54
62
+msgid   "Message"
63
+msgstr  ""
64
+
65
+#: views/elements/log_panel.ctp:37
66
+msgid   "There were no log entries made this request"
67
+msgstr  ""
68
+
69
+#: views/elements/request_panel.ctp:21
70
+msgid   "Request"
71
+msgstr  ""
72
+
73
+#: views/elements/request_panel.ctp:35
74
+msgid   "Current Route"
75
+msgstr  ""
76
+
77
+#: views/elements/session_panel.ctp:21
78
+msgid   "Session"
79
+msgstr  ""
80
+
81
+#: views/elements/sql_log_panel.ctp:21
82
+msgid   "Sql Logs"
83
+msgstr  ""
84
+
85
+#: views/elements/sql_log_panel.ctp:31
86
+msgid   "toggle (%s) query explains for %s"
87
+msgstr  ""
88
+
89
+#: views/elements/sql_log_panel.ctp:39
90
+msgid   "No slow queries!, or your database does not support EXPLAIN"
91
+msgstr  ""
92
+
93
+#: views/elements/sql_log_panel.ctp:44
94
+msgid   "No active database connections"
95
+msgstr  ""
96
+
97
+#: views/elements/timer_panel.ctp:33
98
+msgid   "Memory"
99
+msgstr  ""
100
+
101
+#: views/elements/timer_panel.ctp:35
102
+msgid   "Current Memory Use"
103
+msgstr  ""
104
+
105
+#: views/elements/timer_panel.ctp:39
106
+msgid   "Peak Memory Use"
107
+msgstr  ""
108
+
109
+#: views/elements/timer_panel.ctp:43
110
+msgid   "Timers"
111
+msgstr  ""
112
+
113
+#: views/elements/timer_panel.ctp:45
114
+msgid   "%s (ms)"
115
+msgstr  ""
116
+
117
+#: views/elements/timer_panel.ctp:46
118
+msgid   "Total Request Time:"
119
+msgstr  ""
120
+
121
+#: views/elements/timer_panel.ctp:54
122
+msgid   "Time in ms"
123
+msgstr  ""
124
+
125
+#: views/elements/timer_panel.ctp:54
126
+msgid   "Graph"
127
+msgstr  ""
128
+
129
+#: views/elements/variables_panel.ctp:21
130
+msgid   "View Variables"
131
+msgstr  ""
132
+
133
+#: views/helpers/simple_graph.php:79
134
+msgid   "Starting %sms into the request, taking %sms"
135
+msgstr  ""

+ 102
- 0
Plugin/DebugKit/Model/Behavior/TimedBehavior.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.3
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('DebugKitDebugger', 'DebugKit.Lib');
16
+
17
+/**
18
+ * Class TimedBehavior
19
+ *
20
+ * @since         DebugKit 1.3
21
+ */
22
+class TimedBehavior extends ModelBehavior {
23
+
24
+/**
25
+ * Behavior settings
26
+ *
27
+ * @var array
28
+ */
29
+	public $settings = array();
30
+
31
+/**
32
+ * Default setting values
33
+ *
34
+ * @var array
35
+ */
36
+	protected $_defaults = array();
37
+
38
+/**
39
+ * Setup the behavior and import required classes.
40
+ *
41
+ * @param \Model|object $Model Model using the behavior
42
+ * @param array $settings Settings to override for model.
43
+ * @return void
44
+ */
45
+	public function setup(Model $Model, $settings = null) {
46
+		if (is_array($settings)) {
47
+			$this->settings[$Model->alias] = array_merge($this->_defaults, $settings);
48
+		} else {
49
+			$this->settings[$Model->alias] = $this->_defaults;
50
+		}
51
+	}
52
+
53
+/**
54
+ * beforeFind, starts a timer for a find operation.
55
+ *
56
+ * @param Model $Model
57
+ * @param array $queryData Array of query data (not modified)
58
+ * @return boolean true
59
+ */
60
+	public function beforeFind(Model $Model, $queryData) {
61
+		DebugKitDebugger::startTimer($Model->alias . '_find', $Model->alias . '->find()');
62
+		return true;
63
+	}
64
+
65
+/**
66
+ * afterFind, stops a timer for a find operation.
67
+ *
68
+ * @param Model $Model
69
+ * @param array $results Array of results
70
+ * @param $primary
71
+ * @return boolean true.
72
+ */
73
+	public function afterFind(Model $Model, $results, $primary = false) {
74
+		DebugKitDebugger::stopTimer($Model->alias . '_find');
75
+		return true;
76
+	}
77
+
78
+/**
79
+ * beforeSave, starts a time before a save is initiated.
80
+ *
81
+ * @param Model $Model
82
+ * @param array $options
83
+ * @return boolean true
84
+ */
85
+	public function beforeSave(Model $Model, $options = array()) {
86
+		DebugKitDebugger::startTimer($Model->alias . '_save', $Model->alias . '->save()');
87
+		return true;
88
+	}
89
+
90
+/**
91
+ * afterSave, stop the timer started from a save.
92
+ *
93
+ * @param \Model $Model
94
+ * @param string $created
95
+ * @return boolean Always true
96
+ */
97
+	public function afterSave(Model $Model, $created, $options = array()) {
98
+		DebugKitDebugger::stopTimer($Model->alias . '_save');
99
+		return true;
100
+	}
101
+
102
+}

+ 24
- 0
Plugin/DebugKit/Model/DebugKitAppModel.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('AppModel', 'Model');
16
+
17
+/**
18
+ * Class DebugKitAppModel
19
+ *
20
+ * @since         DebugKit 0.1
21
+ */
22
+class DebugKitAppModel extends AppModel {
23
+
24
+}

+ 56
- 0
Plugin/DebugKit/Model/ToolbarAccess.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.3
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('ConnectionManager', 'Model');
16
+
17
+/**
18
+ * Class ToolbarAccess
19
+ *
20
+ * Contains logic for accessing DebugKit specific information.
21
+ */
22
+class ToolbarAccess extends Object {
23
+
24
+/**
25
+ * Runs an explain on a query if the connection supports EXPLAIN.
26
+ * currently only PostgreSQL and MySQL are supported.
27
+ *
28
+ * @param string $connection Connection name
29
+ * @param string $query SQL query to explain / find query plan for.
30
+ * @return array Array of explain information or empty array if connection is unsupported.
31
+ */
32
+	public function explainQuery($connection, $query) {
33
+		$db = ConnectionManager::getDataSource($connection);
34
+		$datasource = $db->config['datasource'];
35
+
36
+		$return = array();
37
+		if (preg_match('/(Mysql|Postgres)$/', $datasource)) {
38
+			$explained = $db->query('EXPLAIN ' . $query);
39
+			if (preg_match('/Postgres$/', $datasource)) {
40
+				$queryPlan = array();
41
+				foreach ($explained as $postgreValue) {
42
+					$queryPlan[] = array($postgreValue[0]['QUERY PLAN']);
43
+				}
44
+				$return = array_merge(array(array('')), $queryPlan);
45
+			} else {
46
+				$keys = array_keys($explained[0][0]);
47
+				foreach ($explained as $mysqlValue) {
48
+					$queryPlan[] = array_values($mysqlValue[0]);
49
+				}
50
+				$return = array_merge(array($keys), $queryPlan);
51
+			}
52
+		}
53
+		return $return;
54
+	}
55
+
56
+}

+ 299
- 0
Plugin/DebugKit/README.md 파일 보기

1
+# CakePHP DebugKit [![Build Status](https://secure.travis-ci.org/cakephp/debug_kit.png?branch=master)](http://travis-ci.org/cakephp/debug_kit)
2
+
3
+DebugKit provides a debugging toolbar and enhanced debugging tools for CakePHP applications.
4
+
5
+## Requirements
6
+
7
+The master branch has the following requirements:
8
+
9
+* CakePHP 2.2.0 or greater.
10
+* PHP 5.3.0 or greater.
11
+
12
+## Installation
13
+
14
+_[Using [Composer](http://getcomposer.org/)]_
15
+
16
+Add the plugin to your project's `composer.json` - something like this:
17
+
18
+```javascript
19
+{
20
+  "require": {
21
+    "cakephp/debug_kit": "2.2.*"
22
+  }
23
+}
24
+```
25
+
26
+Because this plugin has the type `cakephp-plugin` set in it's own `composer.json`, composer knows to install it inside your `/Plugin` directory, rather than in the usual vendors file. It is recommended that you add `/Plugin/DebugKit` to your .gitignore file. (Why? [read this](http://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md).)
27
+
28
+> Consider using "require-dev" if you only want to include DebugKit for your development environment.
29
+
30
+_[Manual]_
31
+
32
+* Download the [DebugKit archive](https://github.com/cakephp/debug_kit/zipball/2.2).
33
+* Unzip that download.
34
+* Rename the resulting folder to `DebugKit`
35
+* Then copy this folder into `app/Plugin/`
36
+
37
+_[GIT Submodule]_
38
+
39
+In your app directory type:
40
+
41
+```bash
42
+git submodule add --branch 2.2 git://github.com/cakephp/debug_kit.git Plugin/DebugKit
43
+git submodule init
44
+git submodule update
45
+```
46
+
47
+_[GIT Clone]_
48
+
49
+In your plugin directory type
50
+
51
+```bash
52
+git clone --single-branch --branch 2.2 git://github.com/cakephp/debug_kit.git DebugKit
53
+```
54
+
55
+### Enable plugin
56
+
57
+* In 2.x you need to enable the plugin your `app/Config/bootstrap.php` file. If you are already using `CakePlugin::loadAll();`, then the following is not necessary.:
58
+```php
59
+    CakePlugin::load('DebugKit');
60
+```
61
+* Include the toolbar component in your `app/Controller/AppController.php`:
62
+```php
63
+class AppController extends Controller {
64
+         public $components = array('DebugKit.Toolbar');
65
+}
66
+```
67
+* Set `Configure::write('debug', 1);` in `app/Config/core.php`.
68
+* Make sure to remove the 'sql_dump' element from your layout (usually
69
+  `app/View/Layouts/default.ctp`), if you want to experience the awesome that is
70
+  the DebugKit SQL log.
71
+
72
+## Reporting Issues
73
+
74
+If you have a problem with DebugKit please open an issue on [GitHub](https://github.com/cakephp/debug_kit/issues).
75
+
76
+## Contributing
77
+
78
+If you'd like to contribute to DebugKit, check out the
79
+[roadmap](https://github.com/cakephp/debug_kit/wiki/roadmap) for any
80
+planned features. You can [fork](https://help.github.com/articles/fork-a-repo)
81
+the project, add features, and send [pull
82
+requests](https://help.github.com/articles/using-pull-requests) or open
83
+[issues](https://github.com/cakephp/debug_kit/issues).
84
+
85
+## Versions
86
+
87
+DebugKit has several releases, each compatible with different releases of
88
+CakePHP. Use the appropriate version by downloading a tag, or checking out the
89
+correct branch.
90
+
91
+* `1.0, 1.1, 1.2` are compatible with CakePHP 1.2.x. These releases of DebugKit
92
+  will not work with CakePHP 1.3. You can also use the `1.2-branch` for the mos
93
+  recent updates and bugfixes.
94
+* `1.3.0` is compatible with CakePHP 1.3.x only. It will not work with CakePHP
95
+  1.2. You can also use the `1.3` branch to get the most recent updates and
96
+  bugfixes.
97
+* `2.0.0` is compatible with CakePHP 2.0.x only. It will not work with previous
98
+  CakePHP versions.
99
+* `2.2.0` is compatible with CakePHP 2.2.0 and greater. It will not work with
100
+  older versions of CakePHP as this release uses new API's available in 2.2.
101
+  You can also use the `master` branch to get the most recent updates.
102
+* `2.2.x` are compatible with CakePHP 2.2.0 and greater. It is a necessary
103
+  upgrade for people using CakePHP 2.4 as the naming conventions around loggers
104
+  changed in that release.
105
+
106
+# Documentation
107
+
108
+## Toolbar Panels
109
+
110
+The DebugKit Toolbar is comprised of several panels, which are shown by clicking the
111
+CakePHP icon in the upper right-hand corner of your browser after DebugKit has been
112
+installed and loaded. Each panel is comprised of a panel class and view element.
113
+Typically, a panel handles the collection and display of a single type of information
114
+such as Logs or Request information. You can choose to panels from the toolbar or add
115
+your own custom panels.
116
+
117
+### Built-in Panels
118
+
119
+There are several built-in panels, they are:
120
+
121
+ * **History** Allows access to previous request information, useful when
122
+   debugging actions with redirects.
123
+ * **Request** Displays information about the current request, GET, POST, Cake
124
+   Parameters, Current Route information and Cookies if the `CookieComponent`
125
+   is in you controller's components.
126
+ * **Session** Display the information currently in the Session.
127
+ * **Timer** Display any timers that were set during the request see
128
+   `DebugKitDebugger` for more information. Also displays
129
+   memory use at component callbacks as well as peak memory used.
130
+ * **Sql Logs** Displays sql logs for each database connection.
131
+ * **Log** Display any entries made to the log files this request.
132
+ * **Variables** Display View variables set in controller.
133
+ * **Environment** Display environment variables related to PHP + CakePHP.
134
+
135
+## Configuration
136
+
137
+The toolbar has a few configuration settings. Settings are passed in the component declaration like normal component configuration.
138
+
139
+```php
140
+public $components = array(
141
+    'DebugKit.Toolbar' => array(/* array of settings */)
142
+);
143
+```
144
+
145
+### Configuring Panels
146
+
147
+You can customize the toolbar to show your custom panels or hide any built-in panel when adding it toolbar to your components.
148
+```php
149
+public $components = array('DebugKit.Toolbar' => array(
150
+    'panels' => array('MyCustom', 'timer'=>false)
151
+    )
152
+);
153
+```
154
+
155
+Would display your custom panel and all built-in panels except the 'Timer' panel.
156
+
157
+#### Controlling Panels
158
+
159
+Using the panels key you can specify which panels you want to load, as well as the order in which you want the panels loaded.
160
+```php
161
+public $components = array(
162
+        'DebugKit.Toolbar' => array('panels' => array('MyCustom', 'timer' => false))
163
+);
164
+```
165
+
166
+Would add your custom panel `MyCustomPanel` to the toolbar and exclude the default `Timer` panel. In addition to choosing which panels you want, you can pass options into the `__construct` of the panels. For example the built-in `History` panel uses the `history` key to set the number of historical requests to track.
167
+```php
168
+public $components = array(
169
+        'DebugKit.Toolbar' => array('history' => 10)
170
+);
171
+```
172
+
173
+Would load the `History` panel and set its history level to 10. The `panels` key is not passed to the Panel constructor.
174
+
175
+#### forceEnable
176
+
177
+The `forceEnable` setting is new in DebugKit 1.1. It allows you to force the toolbar to display regardless of the value of `Configure::read('debug');`. This is useful when profiling an application with debug kit as you can enable the toolbar even when running the application in production mode.
178
+
179
+#### autoRun
180
+
181
+autoRun is a new configuration setting for DebugKit 1.2. It allows you to control whether or not the toolbar is displayed automatically or whether you would like to use a query string parameter to enable it. Set this configuration key to false to use query string parameter toggling of the toolbar.
182
+```php
183
+public $components = array(
184
+    'DebugKit.Toolbar' => array('autoRun' => false)
185
+);
186
+```
187
+
188
+When visiting a page you can add `?debug=true` to the url and the toolbar will be visible. Otherwise it will stay hidden and not execute.
189
+
190
+## Developing Your Own Panels
191
+
192
+You can create your own custom panels for DebugKit to help in debugging your applications.
193
+
194
+### Panel Classes
195
+
196
+Panel Classes simply need to be placed in`Panel` directory inside a `Lib` path. The filename should match the classname, so the class `MyCustomPanel` would be expected to have a filename of `app/Lib/Panel/MyCustomPanel.php`.
197
+```php
198
+
199
+App::uses('DebugPanel', 'DebugKit.Lib');
200
+
201
+/**
202
+ * My Custom Panel
203
+ */
204
+class MyCustomPanel extends DebugPanel {
205
+        ...
206
+}
207
+```
208
+See also the example `Test/test_app/Plugin/DebugkitTestPlugin/Lib/Panel/PluginTestPanel.php`.
209
+
210
+Notice that custom panels are required to subclass the `DebugPanel` class. Panels can define the
211
+`css` and `javascript` properties to include additional CSS or javascript on the page. Both
212
+properties should be an array.
213
+```php
214
+class MyCustomPanel extends DebugPanel {
215
+        public $javascript = array(
216
+                '/my_plugin/js/custom_panel.js'
217
+        );
218
+}
219
+```
220
+
221
+### Callbacks
222
+
223
+Panel objects have 2 callbacks, that allow them to hook into and introspect on the current request.
224
+```php
225
+startup(Controller $controller)
226
+```
227
+
228
+Each panel's `startup()` method is called during component `startup()` process. `$controller` is a reference to the current controller object.
229
+```php
230
+beforeRender(Controller $controller)
231
+```
232
+
233
+Much like `startup()` `beforeRender()` is called during the Component beforeRender() process. Again `$controller` is a reference to the current controller. Normally at this point you could do additional introspection on the controller. The return of a panels `beforeRender()` is automatically passed to the View by the Toolbar Component. Therefore, under normal use you do not need to explicitly set variables to the controller.
234
+
235
+#### Example of beforeRender Callback
236
+```php
237
+/**
238
+ * beforeRender callback - grabs request params
239
+ *
240
+ * @return array
241
+ */
242
+ public function beforeRender(Controller $controller) {
243
+     return $controller->params;
244
+ }
245
+```
246
+
247
+This would return cake's internal params array. The return of a panel's `beforeRender()` is available in you Panel element as `$content`
248
+
249
+### Panel Elements
250
+
251
+Each Panel is expected to have a view element that renders the content from the panel. The element name must be the underscored inflection of the class name. For example `SessionPanel` has an element named `session_panel.ctp`, and sqllogPanel has an element named `sqllog_panel.ctp`. These elements should be located in the root of your `View/Elements` directory.
252
+
253
+#### Custom Titles and Elements
254
+
255
+Panels should pick up their title and element name by convention. However, if you need to choose a custom element name or title, there are properties to allow that configuration.
256
+
257
+- `$title` - Set a custom title for use in the toolbar. This title will be used as the panels button.
258
+- `$elementName` - Set a custom element name to be used to render the panel.
259
+
260
+### Panels as Cake Plugins
261
+
262
+Panels provided by [Cake Plugins](http://book.cakephp.org/2.0/en/plugins.html) work almost entirely the same as other plugins, with one minor difference:  You must set `public $plugin` to be the name of the plugin directory, so that the panel's Elements can be located at render time.
263
+```php
264
+class MyCustomPanel extends DebugPanel {
265
+    public $plugin = 'MyPlugin';
266
+        ...
267
+}
268
+```
269
+
270
+To use a plugin panel, use the common CakePHP dot notation for plugins.
271
+```php
272
+public $components = array('DebugKit.Toolbar' => array(
273
+    'panels' => array('MyPlugin.MyCustom')
274
+));
275
+```
276
+The above would load all the default panels as well as the custom panel from `MyPlugin`.
277
+
278
+## Cache Engine
279
+
280
+By default, DebugKit uses File as the engine for internal caching, but if you want to use another cache engine you can customize it by simply adding a cache key inside the components config array.
281
+```php
282
+public $components = array('DebugKit.Toolbar' => array(
283
+        'cache' => array('engine' => 'Memcache', 'servers' => array('127.0.0.1:11211'))
284
+        )
285
+);
286
+```
287
+
288
+You can use any cache engine supported by CakePHP, the same way you set in both core.php and bootstrap.php files with the Cache::config() method.
289
+
290
+## Viewing the Toolbar for AJAX Requests
291
+
292
+When doing AJAX requests, you will not be able to see an HTML version of the toolbar. However, if you have a browser extension that supports FirePHP, you can view
293
+the toolbar in your browser:
294
+
295
+- [FirePHP 4 chrome](https://chrome.google.com/webstore/detail/firephp4chrome/gpgbmonepdpnacijbbdijfbecmgoojma)
296
+- [FirePHP for chrome](https://chrome.google.com/webstore/detail/firephp-for-chrome/goajlbdffkligccnfgibeilhdnnpaead)
297
+- [FirePHP for firefox](https://addons.mozilla.org/en-US/firefox/addon/firephp/)
298
+
299
+Once you have installed the correct extension, you should see the toolbar data output on each AJAX request.

+ 40
- 0
Plugin/DebugKit/Test/Case/AllDebugKitTest.php 파일 보기

1
+<?php
2
+/**
3
+ * View Group Test for DebugKit
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+require_once dirname(__FILE__) . DS . 'DebugkitGroupTestCase.php';
20
+
21
+/**
22
+ * DebugKitViewTestSuite class
23
+ *
24
+ * @since         DebugKit 1.0
25
+ */
26
+class AllDebugKitTest extends DebugKitGroupTestCase {
27
+
28
+/**
29
+ * Assemble Test Suite
30
+ *
31
+ * @return PHPUnit_Framework_TestSuite the instance of PHPUnit_Framework_TestSuite
32
+ */
33
+	public static function suite() {
34
+		$suite = new self;
35
+		$files = $suite->getTestFiles();
36
+		$suite->addTestFiles($files);
37
+
38
+		return $suite;
39
+	}
40
+}

+ 40
- 0
Plugin/DebugKit/Test/Case/AllDebugKitViewTest.php 파일 보기

1
+<?php
2
+/**
3
+ * View Group Test for DebugKit
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+require_once dirname(__FILE__) . DS . 'DebugkitGroupTestCase.php';
20
+
21
+/**
22
+ * DebugKitViewTestSuite class
23
+ *
24
+ * @since         DebugKit 1.0
25
+ */
26
+class AllDebugKitViewTest extends DebugkitGroupTestCase {
27
+
28
+/**
29
+ * Assemble Test Suite
30
+ *
31
+ * @return PHPUnit_Framework_TestSuite the instance of PHPUnit_Framework_TestSuite
32
+ */
33
+	public static function suite() {
34
+		$suite = new self;
35
+		$files = $suite->getTestFiles('View');
36
+		$suite->addTestFiles($files);
37
+
38
+		return $suite;
39
+	}
40
+}

+ 40
- 0
Plugin/DebugKit/Test/Case/AllDebugKitWithoutViewTest.php 파일 보기

1
+<?php
2
+/**
3
+ * View Group Test for DebugKit
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+require_once dirname(__FILE__) . DS . 'DebugkitGroupTestCase.php';
20
+
21
+/**
22
+ * DebugKitViewTestSuite class
23
+ *
24
+ * @since         DebugKit 1.0
25
+ */
26
+class AllDebugKitWithoutViewTest extends DebugkitGroupTestCase {
27
+
28
+/**
29
+ * Assemble Test Suite
30
+ *
31
+ * @return PHPUnit_Framework_TestSuite the instance of PHPUnit_Framework_TestSuite
32
+ */
33
+	public static function suite() {
34
+		$suite = new self;
35
+		$files = $suite->getTestFiles(null, 'View');
36
+		$suite->addTestFiles($files);
37
+
38
+		return $suite;
39
+	}
40
+}

+ 40
- 0
Plugin/DebugKit/Test/Case/AllTestsTest.php 파일 보기

1
+<?php
2
+/**
3
+ * AllTestsTest For DebugKit
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+require_once dirname(__FILE__) . DS . 'DebugkitGroupTestCase.php';
20
+
21
+/**
22
+ * AllTestsTest class
23
+ *
24
+ * @since         DebugKit 1.0
25
+ */
26
+class AllTestsTest extends DebugkitGroupTestCase {
27
+
28
+/**
29
+ * Assemble Test Suite
30
+ *
31
+ * @return PHPUnit_Framework_TestSuite the instance of PHPUnit_Framework_TestSuite
32
+ */
33
+	public static function suite() {
34
+		$suite = new self;
35
+		$files = $suite->getTestFiles();
36
+		$suite->addTestFiles($files);
37
+
38
+		return $suite;
39
+	}
40
+}

+ 524
- 0
Plugin/DebugKit/Test/Case/Controller/Component/ToolbarComponentTest.php 파일 보기

1
+<?php
2
+/**
3
+ * PHP 5
4
+ *
5
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
+ *
8
+ * Licensed under The MIT License
9
+ * Redistributions of files must retain the above copyright notice.
10
+ *
11
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
+ * @link          http://cakephp.org CakePHP(tm) Project
13
+ * @since         DebugKit 2.1
14
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
15
+ */
16
+
17
+App::uses('Router', 'Routing');
18
+App::uses('Controller', 'Controller');
19
+App::uses('AppController', 'Controller');
20
+App::uses('Component', 'Controller');
21
+App::uses('ToolbarComponent', 'DebugKit.Controller/Component');
22
+App::uses('DebugMemory', 'DebugKit.Lib');
23
+App::uses('DebugTimer', 'DebugKit.Lib');
24
+
25
+/**
26
+ * Class TestToolbarComponent
27
+ *
28
+ * @since         DebugKit 2.1
29
+ */
30
+class TestToolbarComponent extends ToolbarComponent {
31
+
32
+	/**
33
+	 * Load Panels of Toolbar
34
+	 *
35
+	 * @param $panels
36
+	 * @param array $settings
37
+	 */
38
+	public function loadPanels($panels, $settings = array()) {
39
+		$this->_loadPanels($panels, $settings);
40
+	}
41
+}
42
+
43
+/**
44
+ * ToolbarComponentTestCase Test case
45
+ *
46
+ */
47
+class ToolbarComponentTestCase extends CakeTestCase {
48
+
49
+/**
50
+ * fixtures
51
+ *
52
+ * @var array
53
+ */
54
+	public $fixtures = array('core.article');
55
+
56
+/**
57
+ * url for test
58
+ *
59
+ * @var string
60
+ */
61
+	public $url;
62
+
63
+/**
64
+ * Start test callback
65
+ *
66
+ * @return void
67
+ */
68
+	public function setUp() {
69
+		parent::setUp();
70
+
71
+		Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
72
+		$this->_server = $_SERVER;
73
+		$this->_get = $_GET;
74
+		$this->_paths = array();
75
+		$this->_paths['plugins'] = App::path('plugins');
76
+		$this->_paths['views'] = App::path('views');
77
+		$this->_paths['vendors'] = App::path('vendors');
78
+		$this->_paths['controllers'] = App::path('controllers');
79
+		Configure::write('Cache.disable', false);
80
+
81
+		$this->url = '/';
82
+	}
83
+
84
+/**
85
+ * endTest
86
+ *
87
+ * @return void
88
+ */
89
+	public function tearDown() {
90
+		$_SERVER = $this->_server;
91
+		$_GET = $this->_get;
92
+
93
+		parent::tearDown();
94
+
95
+		App::build(array(
96
+			'plugins' => $this->_paths['plugins'],
97
+			'views' => $this->_paths['views'],
98
+			'controllers' => $this->_paths['controllers'],
99
+			'vendors' => $this->_paths['vendors']
100
+		), true);
101
+		Configure::write('Cache.disable', true);
102
+
103
+		unset($this->Controller);
104
+		ClassRegistry::flush();
105
+		if (class_exists('DebugMemory')) {
106
+			DebugMemory::clear();
107
+		}
108
+		if (class_exists('DebugTimer')) {
109
+			DebugTimer::clear();
110
+		}
111
+		Router::reload();
112
+	}
113
+
114
+/**
115
+ * loading test controller
116
+ *
117
+ * @param array $settings
118
+ * @return Controller
119
+ */
120
+	protected function _loadController($settings = array()) {
121
+		$request = new CakeRequest($this->url);
122
+		$request->addParams(Router::parse($this->url));
123
+		$this->Controller = new Controller($request);
124
+		$this->Controller->uses = null;
125
+		$this->Controller->components = array('Toolbar' => $settings + array('className' => 'TestToolbar'));
126
+		$this->Controller->constructClasses();
127
+		$this->Controller->Components->trigger('initialize', array($this->Controller));
128
+		return $this->Controller;
129
+	}
130
+
131
+/**
132
+ * test Loading of panel classes
133
+ *
134
+ * @return void
135
+ */
136
+	public function testLoadPanels() {
137
+		$this->_loadController();
138
+
139
+		$this->Controller->Toolbar->loadPanels(array('session', 'request'));
140
+		$this->assertInstanceOf('SessionPanel', $this->Controller->Toolbar->panels['session']);
141
+		$this->assertInstanceOf('RequestPanel', $this->Controller->Toolbar->panels['request']);
142
+
143
+		$this->Controller->Toolbar->loadPanels(array('history'), array('history' => 10));
144
+		$this->assertEquals($this->Controller->Toolbar->panels['history']->history, 10);
145
+	}
146
+
147
+/**
148
+ * Test exceptions on bad panel names
149
+ *
150
+ * @expectedException PHPUnit_Framework_Error
151
+ * @return void
152
+ */
153
+	public function testLoadPanelsError() {
154
+		$this->Controller->Toolbar->loadPanels(array('randomNonExisting', 'request'));
155
+	}
156
+
157
+/**
158
+ * test Loading of panel classes from a plugin
159
+ *
160
+ * @return void
161
+ */
162
+	public function testLoadPluginPanels() {
163
+		$debugKitPath = App::pluginPath('DebugKit');
164
+		$noDir = (empty($debugKitPath) || !file_exists($debugKitPath));
165
+		if ($noDir) {
166
+			$this->markTestAsSkipped('Could not find DebugKit in plugin paths');
167
+		}
168
+
169
+		App::build(array(
170
+			'Plugin' => array($debugKitPath . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS)
171
+		));
172
+
173
+		CakePlugin::load('DebugkitTestPlugin');
174
+		$this->_loadController();
175
+		$this->Controller->Toolbar->loadPanels(array('DebugkitTestPlugin.PluginTest'));
176
+		$this->assertInstanceOf(
177
+			'PluginTestPanel',
178
+			$this->Controller->Toolbar->panels['plugin_test']
179
+		);
180
+	}
181
+
182
+/**
183
+ * test loading of vendor panels from test_app folder
184
+ *
185
+ * @return void
186
+ */
187
+	public function testLibPanels() {
188
+		$debugKitPath = App::pluginPath('DebugKit');
189
+		$noDir = (empty($debugKitPath) || !file_exists($debugKitPath));
190
+		if ($noDir) {
191
+			$this->markTestAsSkipped('Could not find DebugKit in plugin paths');
192
+		}
193
+
194
+		App::build(array(
195
+			'Lib' => array($debugKitPath . 'Test' . DS . 'test_app' . DS . 'Lib' . DS)
196
+		));
197
+		$this->_loadController(array(
198
+			'panels' => array('test'),
199
+			'className' => 'DebugKit.Toolbar',
200
+		));
201
+		$this->assertTrue(isset($this->Controller->Toolbar->panels['test']));
202
+		$this->assertInstanceOf('TestPanel', $this->Controller->Toolbar->panels['test']);
203
+	}
204
+
205
+/**
206
+ * test construct
207
+ *
208
+ * @return void
209
+ */
210
+	public function testConstruct() {
211
+		$this->_loadController();
212
+
213
+		$this->assertFalse(empty($this->Controller->Toolbar->panels));
214
+
215
+		$memory = DebugMemory::getAll();
216
+		$this->assertTrue(isset($memory['Component initialization']));
217
+
218
+		$events = $this->Controller->getEventManager();
219
+		$this->assertNotEmpty($events->listeners('Controller.initialize'));
220
+		$this->assertNotEmpty($events->listeners('Controller.startup'));
221
+		$this->assertNotEmpty($events->listeners('Controller.beforeRender'));
222
+		$this->assertNotEmpty($events->listeners('Controller.shutdown'));
223
+		$this->assertNotEmpty($events->listeners('View.beforeRender'));
224
+		$this->assertNotEmpty($events->listeners('View.afterRender'));
225
+		$this->assertNotEmpty($events->listeners('View.beforeLayout'));
226
+		$this->assertNotEmpty($events->listeners('View.afterLayout'));
227
+	}
228
+
229
+/**
230
+ * test initialize w/ custom panels and defaults
231
+ *
232
+ * @return void
233
+ */
234
+	public function testInitializeCustomPanelsWithDefaults() {
235
+		$this->_loadController(array(
236
+			'panels' => array('test'),
237
+		));
238
+
239
+		$expected = array(
240
+			'history', 'session', 'request', 'sql_log', 'timer',
241
+			'log', 'variables', 'environment', 'include', 'test'
242
+		);
243
+		$this->assertEquals($expected, array_keys($this->Controller->Toolbar->panels));
244
+	}
245
+
246
+/**
247
+ * test syntax for removing panels
248
+ *
249
+ * @return void
250
+ */
251
+	public function testInitializeRemovingPanels() {
252
+		$this->_loadController(array(
253
+			'panels' => array(
254
+				'session' => false,
255
+				'history' => false,
256
+			)
257
+		));
258
+
259
+		$expected = array('request', 'sql_log', 'timer', 'log', 'variables', 'environment', 'include');
260
+		$this->assertEquals($expected, array_keys($this->Controller->Toolbar->panels));
261
+	}
262
+
263
+/**
264
+ * ensure that Toolbar is not enabled when debug == 0 on initialize
265
+ *
266
+ * @return void
267
+ */
268
+	public function testDebugDisableOnInitialize() {
269
+		$_debug = Configure::read('debug');
270
+		Configure::write('debug', 0);
271
+		$this->_loadController();
272
+		Configure::write('debug', $_debug);
273
+
274
+		$this->assertFalse($this->Controller->Components->enabled('Toolbar'));
275
+	}
276
+
277
+/**
278
+ * test that passing in forceEnable will enable the toolbar even if debug = 0
279
+ *
280
+ * @return void
281
+ */
282
+	public function testForceEnable() {
283
+		$_debug = Configure::read('debug');
284
+		Configure::write('debug', 0);
285
+		$this->_loadController(array(
286
+			'forceEnable' => true,
287
+		));
288
+		Configure::write('debug', $_debug);
289
+
290
+		$this->assertTrue($this->Controller->Components->enabled('Toolbar'));
291
+	}
292
+
293
+/**
294
+ * Test disabling autoRunning of toolbar
295
+ *
296
+ * @return void
297
+ */
298
+	public function testAutoRunSettingFalse() {
299
+		$this->_loadController(array(
300
+			'autoRun' => false,
301
+		));
302
+		$this->assertFalse($this->Controller->Components->enabled('Toolbar'));
303
+	}
304
+
305
+/**
306
+ * test autorun = false with query string param
307
+ *
308
+ * @return void
309
+ */
310
+	public function testAutoRunSettingWithQueryString() {
311
+		$this->url = '/?debug=1';
312
+		$_GET['debug'] = 1;
313
+		$this->_loadController(array(
314
+			'autoRun' => false,
315
+		));
316
+		$this->assertTrue($this->Controller->Components->enabled('Toolbar'));
317
+	}
318
+
319
+/**
320
+ * test startup
321
+ *
322
+ * @return void
323
+ */
324
+	public function testStartup() {
325
+		$this->_loadController(array(
326
+			'panels' => array('timer'),
327
+		));
328
+		$MockPanel = $this->getMock('DebugPanel');
329
+		$MockPanel->expects($this->once())->method('startup');
330
+		$this->Controller->Toolbar->panels['timer'] = $MockPanel;
331
+
332
+		$this->Controller->Toolbar->startup($this->Controller);
333
+
334
+		$timers = DebugTimer::getAll();
335
+		$this->assertTrue(isset($timers['controllerAction']));
336
+		$memory = DebugMemory::getAll();
337
+		$this->assertTrue(isset($memory['Controller action start']));
338
+	}
339
+
340
+/**
341
+ * Test that cache config generation works.
342
+ *
343
+ * @return void
344
+ */
345
+	public function testCacheConfigGeneration() {
346
+		$this->_loadController();
347
+		$this->Controller->Components->trigger('startup', array($this->Controller));
348
+
349
+		$results = Cache::config('debug_kit');
350
+		$this->assertTrue(is_array($results));
351
+	}
352
+
353
+/**
354
+ * test state saving of toolbar
355
+ *
356
+ * @return void
357
+ */
358
+	public function testStateSaving() {
359
+		$this->_loadController();
360
+		$configName = 'debug_kit';
361
+		$this->Controller->Toolbar->cacheKey = 'toolbar_history';
362
+
363
+		$this->Controller->Components->trigger('startup', array($this->Controller));
364
+		$this->Controller->set('test', 'testing');
365
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
366
+
367
+		$result = Cache::read('toolbar_history', $configName);
368
+		$this->assertEquals($result[0]['variables']['content']['test'], 'testing');
369
+		Cache::delete('toolbar_history', $configName);
370
+	}
371
+
372
+/**
373
+ * Test Before Render callback
374
+ *
375
+ * @return void
376
+ */
377
+	public function testBeforeRender() {
378
+		$this->_loadController(array(
379
+			'panels' => array('timer', 'session'),
380
+		));
381
+		$MockPanel = $this->getMock('DebugPanel');
382
+		$MockPanel->expects($this->once())->method('beforeRender');
383
+		$this->Controller->Toolbar->panels['timer'] = $MockPanel;
384
+		$this->Controller->Toolbar->beforeRender($this->Controller);
385
+
386
+		$this->assertTrue(isset($this->Controller->helpers['DebugKit.Toolbar']));
387
+		$this->assertEquals($this->Controller->helpers['DebugKit.Toolbar']['output'], 'DebugKit.HtmlToolbar');
388
+		$this->assertEquals($this->Controller->helpers['DebugKit.Toolbar']['cacheConfig'], 'debug_kit');
389
+		$this->assertTrue(isset($this->Controller->helpers['DebugKit.Toolbar']['cacheKey']));
390
+
391
+		$this->assertTrue(isset($this->Controller->viewVars['debugToolbarPanels']));
392
+		$vars = $this->Controller->viewVars['debugToolbarPanels'];
393
+
394
+		$expected = array(
395
+			'plugin' => 'DebugKit',
396
+			'elementName' => 'session_panel',
397
+			'content' => $this->Controller->Toolbar->Session->read(),
398
+			'disableTimer' => true,
399
+			'title' => ''
400
+		);
401
+		$this->assertEquals($expected, $vars['session']);
402
+
403
+		$memory = DebugMemory::getAll();
404
+		$this->assertTrue(isset($memory['Controller render start']));
405
+	}
406
+
407
+/**
408
+ * test that vars are gathered and state is saved on beforeRedirect
409
+ *
410
+ * @return void
411
+ */
412
+	public function testBeforeRedirect() {
413
+		$this->_loadController(array(
414
+			'panels' => array('session', 'history'),
415
+		));
416
+
417
+		$configName = 'debug_kit';
418
+		$this->Controller->Toolbar->cacheKey = 'toolbar_history';
419
+		Cache::delete('toolbar_history', $configName);
420
+
421
+		DebugTimer::start('controllerAction', 'testing beforeRedirect');
422
+		$MockPanel = $this->getMock('DebugPanel');
423
+		$MockPanel->expects($this->once())->method('beforeRender');
424
+		$this->Controller->Toolbar->panels['session'] = $MockPanel;
425
+		$this->Controller->Toolbar->beforeRedirect($this->Controller, '/another/url');
426
+
427
+		$result = Cache::read('toolbar_history', $configName);
428
+		$this->assertTrue(isset($result[0]['session']));
429
+		$this->assertFalse(isset($result[0]['history']));
430
+
431
+		$timers = DebugTimer::getAll();
432
+		$this->assertTrue(isset($timers['controllerAction']));
433
+	}
434
+
435
+/**
436
+ * test that loading state (accessing cache) works.
437
+ *
438
+ * @return void
439
+ */
440
+	public function testLoadState() {
441
+		$this->_loadController();
442
+		$this->Controller->Toolbar->cacheKey = 'toolbar_history';
443
+
444
+		$data = array(0 => array('my data'));
445
+		Cache::write('toolbar_history', $data, 'debug_kit');
446
+		$result = $this->Controller->Toolbar->loadState(0);
447
+		$this->assertEquals($result, $data[0]);
448
+	}
449
+
450
+/**
451
+ * Test that history state urls set prefix = null and admin = null so generated urls do not
452
+ * adopt these params.
453
+ *
454
+ * @return void
455
+ */
456
+	public function testHistoryUrlGenerationWithPrefixes() {
457
+		$this->url = '/debugkit_url_with_prefixes_test';
458
+		Router::connect($this->url, array(
459
+			'controller' => 'posts',
460
+			'action' => 'edit',
461
+			'admin' => 1,
462
+			'prefix' => 'admin',
463
+			'plugin' => 'cms',
464
+		));
465
+		$this->_loadController();
466
+		$this->Controller->Toolbar->cacheKey = 'url_test';
467
+		$this->Controller->Components->trigger('startup', array($this->Controller));
468
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
469
+
470
+		$result = $this->Controller->Toolbar->panels['history']->beforeRender($this->Controller);
471
+		$expected = array(
472
+			'plugin' => 'debug_kit',
473
+			'controller' => 'toolbar_access',
474
+			'action' => 'history_state',
475
+			0 => 1,
476
+			'admin' => false,
477
+		);
478
+		$this->assertEquals($result[0]['url'], $expected);
479
+		Cache::delete('url_test', 'debug_kit');
480
+	}
481
+
482
+/**
483
+ * Test that the FireCake toolbar is used on AJAX requests
484
+ *
485
+ * @return void
486
+ */
487
+	public function testAjaxToolbar() {
488
+		$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest';
489
+		$this->_loadController();
490
+		$this->Controller->Components->trigger('startup', array($this->Controller));
491
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
492
+		$this->assertEquals($this->Controller->helpers['DebugKit.Toolbar']['output'], 'DebugKit.FirePhpToolbar');
493
+	}
494
+
495
+/**
496
+ * Test that the toolbar does not interfere with requestAction
497
+ *
498
+ * @return void
499
+ */
500
+	public function testNoRequestActionInterference() {
501
+		$debugKitPath = App::pluginPath('DebugKit');
502
+		$noDir = (empty($debugKitPath) || !file_exists($debugKitPath));
503
+		if ($noDir) {
504
+			$this->markTestAsSkipped('Could not find DebugKit in plugin paths');
505
+		}
506
+
507
+		App::build(array(
508
+			'Controller' => $debugKitPath . 'Test' . DS . 'test_app' . DS . 'Controller' . DS,
509
+			'View' => array(
510
+				$debugKitPath . 'Test' . DS . 'test_app' . DS . 'View' . DS,
511
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'View' . DS
512
+			),
513
+			'plugins' => $this->_paths['plugins']
514
+		));
515
+		Router::reload();
516
+		$this->_loadController();
517
+
518
+		$result = $this->Controller->requestAction('/debug_kit_test/request_action_return', array('return'));
519
+		$this->assertEquals($result, 'I am some value from requestAction.');
520
+
521
+		$result = $this->Controller->requestAction('/debug_kit_test/request_action_render', array('return'));
522
+		$this->assertEquals($result, 'I have been rendered.');
523
+	}
524
+}

+ 79
- 0
Plugin/DebugKit/Test/Case/DebugkitGroupTestCase.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit Group Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+
18
+/**
19
+ * Class DebugKitGroupTestCase
20
+ *
21
+ */
22
+class DebugKitGroupTestCase extends PHPUnit_Framework_TestSuite {
23
+
24
+/**
25
+ * Constructor
26
+ */
27
+	public function __construct() {
28
+		$label = Inflector::humanize(Inflector::underscore(get_class($this)));
29
+		parent::__construct($label);
30
+	}
31
+
32
+/**
33
+ * Get Test Files
34
+ *
35
+ * @param null $directory
36
+ * @param null $excludes
37
+ * @return array
38
+ */
39
+	public static function getTestFiles($directory = null, $excludes = null) {
40
+		if (is_array($directory)) {
41
+			$files = array();
42
+			foreach ($directory as $d) {
43
+				$files = array_merge($files, self::getTestFiles($d, $excludes));
44
+			}
45
+			return array_unique($files);
46
+		}
47
+
48
+		if ($excludes !== null) {
49
+			$excludes = self::getTestFiles((array)$excludes);
50
+		}
51
+		if ($directory === null || $directory !== realpath($directory)) {
52
+			$basePath = App::pluginPath('DebugKit') . 'Test' . DS . 'Case' . DS;
53
+			$directory = str_replace(DS . DS, DS, $basePath . $directory);
54
+		}
55
+
56
+		$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory));
57
+
58
+		$files = array();
59
+		while ($it->valid()) {
60
+
61
+			if (!$it->isDot()) {
62
+				$file = $it->key();
63
+
64
+				if (
65
+					preg_match('|Test\.php$|', $file) &&
66
+					$file !== __FILE__ &&
67
+					!preg_match('|^All.+?\.php$|', basename($file)) &&
68
+					($excludes === null || !in_array($file, $excludes))
69
+				) {
70
+					$files[] = $file;
71
+				}
72
+			}
73
+
74
+			$it->next();
75
+		}
76
+
77
+		return $files;
78
+	}
79
+}

+ 76
- 0
Plugin/DebugKit/Test/Case/Lib/DebugKitDebuggerTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit Debugger Test Case File
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         debug_kit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+
19
+App::uses('DebugKitDebugger', 'DebugKit.Lib');
20
+require_once CakePlugin::path('DebugKit') . 'Test' . DS . 'Case' . DS . 'TestFireCake.php';
21
+
22
+/**
23
+ * Test case for the DebugKitDebugger
24
+ *
25
+ * @since         debug_kit 0.1
26
+ */
27
+class DebugKitDebuggerTest extends CakeTestCase {
28
+
29
+/**
30
+ * setUp method
31
+ *
32
+ * @return void
33
+ */
34
+	public function setUp() {
35
+		parent::setUp();
36
+		Configure::write('log', false);
37
+		$this->firecake = FireCake::getInstance('TestFireCake');
38
+		TestFireCake::reset();
39
+	}
40
+
41
+/**
42
+ * tearDown method
43
+ *
44
+ * @return void
45
+ */
46
+	public function tearDown() {
47
+		parent::tearDown();
48
+		Configure::write('log', true);
49
+		DebugKitDebugger::clearTimers();
50
+		TestFireCake::reset();
51
+	}
52
+
53
+/**
54
+ * test output switch to firePHP
55
+ *
56
+ * @return void
57
+ */
58
+	public function testOutput() {
59
+		Debugger::getInstance('DebugKitDebugger');
60
+		Debugger::addFormat('fb', array('callback' => 'DebugKitDebugger::fireError'));
61
+		Debugger::outputAs('fb');
62
+
63
+		set_error_handler('ErrorHandler::handleError');
64
+		$foo .= '';
65
+		restore_error_handler();
66
+
67
+		$result = $this->firecake->sentHeaders;
68
+
69
+		$this->assertRegExp('/GROUP_START/', $result['X-Wf-1-1-1-1']);
70
+		$this->assertRegExp('/ERROR/', $result['X-Wf-1-1-1-2']);
71
+		$this->assertRegExp('/GROUP_END/', $result['X-Wf-1-1-1-5']);
72
+
73
+		Debugger::getInstance('Debugger');
74
+		Debugger::outputAs('html');
75
+	}
76
+}

+ 65
- 0
Plugin/DebugKit/Test/Case/Lib/DebugMemoryTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit Debug Memory Test Cases
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
+ **/
17
+
18
+App::uses('DebugMemory', 'DebugKit.Lib');
19
+
20
+/**
21
+ * Class DebugMemoryTest
22
+ *
23
+ */
24
+class DebugMemoryTest extends CakeTestCase {
25
+
26
+/**
27
+ * test memory usage
28
+ *
29
+ * @return void
30
+ */
31
+	public function testMemoryUsage() {
32
+		$result = DebugMemory::getCurrent();
33
+		$this->assertTrue(is_int($result));
34
+
35
+		$result = DebugMemory::getPeak();
36
+		$this->assertTrue(is_int($result));
37
+	}
38
+
39
+/**
40
+ * test making memory use markers.
41
+ *
42
+ * @return void
43
+ */
44
+	public function testMemorySettingAndGetting() {
45
+		DebugMemory::clear();
46
+		$result = DebugMemory::record('test marker');
47
+		$this->assertTrue($result);
48
+
49
+		$result = DebugMemory::getAll(true);
50
+		$this->assertEquals(count($result), 1);
51
+		$this->assertTrue(isset($result['test marker']));
52
+		$this->assertTrue(is_numeric($result['test marker']));
53
+
54
+		$result = DebugMemory::getAll();
55
+		$this->assertTrue(empty($result));
56
+
57
+		DebugMemory::record('test marker');
58
+		DebugMemory::record('test marker');
59
+		$result = DebugMemory::getAll();
60
+
61
+		$this->assertEquals(count($result), 2);
62
+		$this->assertTrue(isset($result['test marker']));
63
+		$this->assertTrue(isset($result['test marker #2']));
64
+	}
65
+}

+ 169
- 0
Plugin/DebugKit/Test/Case/Lib/DebugTimerTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugTimer Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         debug_kit 2.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('DebugTimer', 'DebugKit.Lib');
20
+
21
+/**
22
+ * Class DebugTimerTest
23
+ *
24
+ * @since         debug_kit 2.0
25
+ */
26
+class DebugTimerTest extends CakeTestCase {
27
+
28
+/**
29
+ * tearDown method
30
+ *
31
+ * @return void
32
+ */
33
+	public function tearDown() {
34
+		DebugTimer::clear();
35
+	}
36
+
37
+/**
38
+ * Start Timer test
39
+ *
40
+ * @return void
41
+ */
42
+	public function testTimers() {
43
+		$this->assertTrue(DebugTimer::start('test1', 'this is my first test'));
44
+		usleep(5000);
45
+		$this->assertTrue(DebugTimer::stop('test1'));
46
+		$elapsed = DebugTimer::elapsedTime('test1');
47
+		$this->assertTrue($elapsed > 0.0050);
48
+
49
+		$this->assertTrue(DebugTimer::start('test2', 'this is my second test'));
50
+		sleep(1);
51
+		$this->assertTrue(DebugTimer::stop('test2'));
52
+		$elapsed = DebugTimer::elapsedTime('test2');
53
+		$expected = stripos(PHP_OS, 'win') === false ? 0.999: 0.95; // Windows timer's precision is bad
54
+		$this->assertTrue($elapsed >= $expected);
55
+
56
+		DebugTimer::start('test3');
57
+		$this->assertIdentical(DebugTimer::elapsedTime('test3'), 0);
58
+		$this->assertFalse(DebugTimer::stop('wrong'));
59
+	}
60
+
61
+/**
62
+ * test timers with no names.
63
+ *
64
+ * @return void
65
+ */
66
+	public function testAnonymousTimers() {
67
+		$this->assertTrue(DebugTimer::start());
68
+		usleep(2000);
69
+		$this->assertTrue(DebugTimer::stop());
70
+		$timers = DebugTimer::getAll();
71
+
72
+		$this->assertEquals(2, count($timers));
73
+		end($timers);
74
+		$key = key($timers);
75
+		$lineNo = __LINE__ - 8;
76
+
77
+		$file = Debugger::trimPath(__FILE__);
78
+		$expected = $file . ' line ' . $lineNo;
79
+		$this->assertEquals($expected, $key);
80
+
81
+		$timer = $timers[$expected];
82
+		$this->assertTrue($timer['time'] > 0.0020);
83
+		$this->assertEquals($expected, $timers[$expected]['message']);
84
+	}
85
+
86
+/**
87
+ * Assert that nested anonymous timers don't get mixed up.
88
+ *
89
+ * @return void
90
+ */
91
+	public function testNestedAnonymousTimers() {
92
+		$this->assertTrue(DebugTimer::start());
93
+		usleep(100);
94
+		$this->assertTrue(DebugTimer::start());
95
+		usleep(100);
96
+		$this->assertTrue(DebugTimer::stop());
97
+		$this->assertTrue(DebugTimer::stop());
98
+
99
+		$timers = DebugTimer::getAll();
100
+		$this->assertEquals(3, count($timers), 'incorrect number of timers %s');
101
+		$firstTimerLine = __LINE__ - 9;
102
+		$secondTimerLine = __LINE__ - 8;
103
+		$file = Debugger::trimPath(__FILE__);
104
+
105
+		$this->assertTrue(isset($timers[$file . ' line ' . $firstTimerLine]), 'first timer is not set %s');
106
+		$this->assertTrue(isset($timers[$file . ' line ' . $secondTimerLine]), 'second timer is not set %s');
107
+
108
+		$firstTimer = $timers[$file . ' line ' . $firstTimerLine];
109
+		$secondTimer = $timers[$file . ' line ' . $secondTimerLine];
110
+		$this->assertTrue($firstTimer['time'] > $secondTimer['time']);
111
+	}
112
+
113
+/**
114
+ * test that calling start with the same name does not overwrite previous timers
115
+ * and instead adds new ones.
116
+ *
117
+ * @return void
118
+ */
119
+	public function testRepeatTimers() {
120
+		DebugTimer::start('my timer', 'This is the first call');
121
+		usleep(100);
122
+		DebugTimer::start('my timer', 'This is the second call');
123
+		usleep(100);
124
+
125
+		DebugTimer::stop('my timer');
126
+		DebugTimer::stop('my timer');
127
+
128
+		$timers = DebugTimer::getAll();
129
+		$this->assertEquals(3, count($timers), 'wrong timer count %s');
130
+
131
+		$this->assertTrue(isset($timers['my timer']));
132
+		$this->assertTrue(isset($timers['my timer #2']));
133
+
134
+		$this->assertTrue($timers['my timer']['time'] > $timers['my timer #2']['time'], 'timer 2 is longer? %s');
135
+		$this->assertEquals('This is the first call', $timers['my timer']['message']);
136
+		$this->assertEquals('This is the second call #2', $timers['my timer #2']['message']);
137
+	}
138
+
139
+/**
140
+ * testRequestTime
141
+ *
142
+ * @return void
143
+ */
144
+	public function testRequestTime() {
145
+		$result1 = DebugTimer::requestTime();
146
+		usleep(50);
147
+		$result2 = DebugTimer::requestTime();
148
+		$this->assertTrue($result1 < $result2);
149
+	}
150
+
151
+/**
152
+ * test getting all the set timers.
153
+ *
154
+ * @return void
155
+ */
156
+	public function testGetTimers() {
157
+		DebugTimer::start('test1', 'this is my first test');
158
+		DebugTimer::stop('test1');
159
+		usleep(50);
160
+		DebugTimer::start('test2');
161
+		DebugTimer::stop('test2');
162
+		$timers = DebugTimer::getAll();
163
+
164
+		$this->assertEquals(3, count($timers));
165
+		$this->assertTrue(is_float($timers['test1']['time']));
166
+		$this->assertTrue(isset($timers['test1']['message']));
167
+		$this->assertTrue(isset($timers['test2']['message']));
168
+	}
169
+}

+ 345
- 0
Plugin/DebugKit/Test/Case/Lib/FireCakeTest.php 파일 보기

1
+<?php
2
+/**
3
+ * CakeFirePHP Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+
19
+App::uses('FireCake', 'DebugKit.Lib');
20
+require_once CakePlugin::path('DebugKit') . 'Test' . DS . 'Case' . DS . 'TestFireCake.php';
21
+
22
+/**
23
+ * Test Case For FireCake
24
+ *
25
+ * @since         DebugKit 0.1
26
+ */
27
+class FireCakeTestCase extends CakeTestCase {
28
+
29
+/**
30
+ * setup test
31
+ *
32
+ * Fill FireCake with TestFireCake instance.
33
+ *
34
+ * @return void
35
+ */
36
+	public function setUp() {
37
+		$this->firecake = FireCake::getInstance('TestFireCake');
38
+		TestFireCake::reset();
39
+	}
40
+
41
+/**
42
+ * Reset the FireCake counters and headers.
43
+ *
44
+ * @return void
45
+ */
46
+	public function tearDown() {
47
+		TestFireCake::reset();
48
+	}
49
+
50
+/**
51
+ * Test getInstance cheat.
52
+ *
53
+ * If this fails the rest of the test is going to fail too.
54
+ *
55
+ * @return void
56
+ */
57
+	public function testGetInstanceOverride() {
58
+		$instance = FireCake::getInstance();
59
+		$instance2 = FireCake::getInstance();
60
+		$this->assertReference($instance, $instance2);
61
+		$this->assertIsA($instance, 'FireCake');
62
+		$this->assertIsA($instance, 'TestFireCake', 'Stored instance is not a copy of TestFireCake, test case is broken.');
63
+	}
64
+
65
+/**
66
+ * Test setOptions
67
+ *
68
+ * @return void
69
+ */
70
+	public function testSetOptions() {
71
+		FireCake::setOptions(array('includeLineNumbers' => false));
72
+		$this->assertEquals($this->firecake->options['includeLineNumbers'], false);
73
+	}
74
+
75
+/**
76
+ * Test Log()
77
+ *
78
+ * @return void
79
+ */
80
+	public function testLog() {
81
+		FireCake::setOptions(array('includeLineNumbers' => false));
82
+		FireCake::log('Testing');
83
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
84
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
85
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
86
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
87
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '26|[{"Type":"LOG"},"Testing"]|');
88
+
89
+		FireCake::log('Testing', 'log-info');
90
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"LOG","Label":"log-info"},"Testing"]|');
91
+	}
92
+
93
+/**
94
+ * Test info()
95
+ *
96
+ * @return void
97
+ */
98
+	public function testInfo() {
99
+		FireCake::setOptions(array('includeLineNumbers' => false));
100
+		FireCake::info('I have information');
101
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
102
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
103
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
104
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
105
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '38|[{"Type":"INFO"},"I have information"]|');
106
+
107
+		FireCake::info('I have information', 'info-label');
108
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '59|[{"Type":"INFO","Label":"info-label"},"I have information"]|');
109
+	}
110
+
111
+/**
112
+ * Test info()
113
+ *
114
+ * @return void
115
+ */
116
+	public function testWarn() {
117
+		FireCake::setOptions(array('includeLineNumbers' => false));
118
+		FireCake::warn('A Warning');
119
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
120
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
121
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
122
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
123
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"WARN"},"A Warning"]|');
124
+
125
+		FireCake::warn('A Warning', 'Bzzz');
126
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '44|[{"Type":"WARN","Label":"Bzzz"},"A Warning"]|');
127
+	}
128
+
129
+/**
130
+ * Test error()
131
+ *
132
+ * @return void
133
+ */
134
+	public function testError() {
135
+		FireCake::setOptions(array('includeLineNumbers' => false));
136
+		FireCake::error('An error');
137
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
138
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
139
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
140
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 1);
141
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '29|[{"Type":"ERROR"},"An error"]|');
142
+
143
+		FireCake::error('An error', 'wonky');
144
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '45|[{"Type":"ERROR","Label":"wonky"},"An error"]|');
145
+	}
146
+
147
+/**
148
+ * Test dump()
149
+ *
150
+ * @return void
151
+ */
152
+	public function testDump() {
153
+		FireCake::dump('mydump', array('one' => 1, 'two' => 2));
154
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-2-1-1'], '28|{"mydump":{"one":1,"two":2}}|');
155
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-2']));
156
+	}
157
+
158
+/**
159
+ * Test table() generation
160
+ *
161
+ * @return void
162
+ */
163
+	public function testTable() {
164
+		$table[] = array('Col 1 Heading','Col 2 Heading');
165
+		$table[] = array('Row 1 Col 1','Row 1 Col 2');
166
+		$table[] = array('Row 2 Col 1','Row 2 Col 2');
167
+		$table[] = array('Row 3 Col 1','Row 3 Col 2');
168
+		FireCake::table('myTrace', $table);
169
+		$expected = '162|[{"Type":"TABLE","Label":"myTrace"},[["Col 1 Heading","Col 2 Heading"],["Row 1 Col 1","Row 1 Col 2"],["Row 2 Col 1","Row 2 Col 2"],["Row 3 Col 1","Row 3 Col 2"]]]|';
170
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], $expected);
171
+	}
172
+
173
+/**
174
+ * TestStringEncoding
175
+ *
176
+ * @return void
177
+ */
178
+	public function testStringEncode() {
179
+		$vars = array(1,2,3);
180
+		$result = $this->firecake->stringEncode($vars);
181
+		$this->assertEquals($result, array(1,2,3));
182
+
183
+		$this->firecake->setOptions(array('maxArrayDepth' => 3));
184
+		$deep = array(1 => array(2 => array(3)));
185
+		$result = $this->firecake->stringEncode($deep);
186
+		$this->assertEquals($result, array(1 => array(2 => '** Max Array Depth (3) **')));
187
+	}
188
+
189
+/**
190
+ * Test object encoding
191
+ *
192
+ * @return void
193
+ */
194
+	public function testStringEncodeObjects() {
195
+		$obj = FireCake::getInstance();
196
+		$result = $this->firecake->stringEncode($obj);
197
+
198
+		$this->assertTrue(is_array($result));
199
+		$this->assertEquals($result['_defaultOptions']['useNativeJsonEncode'], true);
200
+		$this->assertEquals($result['_encodedObjects'][0], '** Recursion (TestFireCake) **');
201
+	}
202
+
203
+/**
204
+ * Test trace()
205
+ *
206
+ * @return void
207
+ */
208
+	public function testTrace() {
209
+		FireCake::trace('myTrace');
210
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-Protocol-1']));
211
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Plugin-1']));
212
+		$this->assertTrue(isset($this->firecake->sentHeaders['X-Wf-1-Structure-1']));
213
+		$dump = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
214
+		$this->assertPattern('/"Message":"myTrace"/', $dump);
215
+		$this->assertPattern('/"Trace":\[/', $dump);
216
+	}
217
+
218
+/**
219
+ * Test enabling and disabling of FireCake output
220
+ *
221
+ * @return void
222
+ */
223
+	public function testEnableDisable() {
224
+		FireCake::disable();
225
+		FireCake::trace('myTrace');
226
+		$this->assertTrue(empty($this->firecake->sentHeaders));
227
+
228
+		FireCake::enable();
229
+		FireCake::trace('myTrace');
230
+		$this->assertFalse(empty($this->firecake->sentHeaders));
231
+	}
232
+
233
+/**
234
+ * Test correct line continuation markers on multi line headers.
235
+ *
236
+ * @return void
237
+ */
238
+	public function testMultiLineOutput() {
239
+		FireCake::trace('myTrace');
240
+		$this->assertGreaterThan(1, $this->firecake->sentHeaders['X-Wf-1-Index']);
241
+		$header = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
242
+		$this->assertEquals(substr($header, -2), '|\\');
243
+
244
+		$endIndex = $this->firecake->sentHeaders['X-Wf-1-Index'];
245
+		$header = $this->firecake->sentHeaders['X-Wf-1-1-1-' . $endIndex];
246
+		$this->assertEquals(substr($header, -1), '|');
247
+	}
248
+
249
+/**
250
+ * Test inclusion of line numbers
251
+ *
252
+ * @return void
253
+ */
254
+	public function testIncludeLineNumbers() {
255
+		FireCake::setOptions(array('includeLineNumbers' => true));
256
+		FireCake::info('Testing');
257
+		$result = $this->firecake->sentHeaders['X-Wf-1-1-1-1'];
258
+		$this->assertPattern('/"File"\:".*FireCakeTest.php/', $result);
259
+		$this->assertPattern('/"Line"\:\d+/', $result);
260
+	}
261
+
262
+/**
263
+ * Test Group messages
264
+ *
265
+ * @return void
266
+ */
267
+	public function testGroup() {
268
+		FireCake::setOptions(array('includeLineNumbers' => false));
269
+		FireCake::group('test');
270
+		FireCake::info('my info');
271
+		FireCake::groupEnd();
272
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '63|[{"Collapsed":"true","Type":"GROUP_START","Label":"test"},null]|');
273
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '27|[{"Type":"GROUP_END"},null]|');
274
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
275
+	}
276
+
277
+/**
278
+ * Test fb() parameter parsing
279
+ *
280
+ * @return void
281
+ */
282
+	public function testFbParameterParsing() {
283
+		FireCake::setOptions(array('includeLineNumbers' => false));
284
+		FireCake::fb('Test');
285
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '23|[{"Type":"LOG"},"Test"]|');
286
+
287
+		FireCake::fb('Test', 'warn');
288
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-2'], '24|[{"Type":"WARN"},"Test"]|');
289
+
290
+		FireCake::fb('Test', 'Custom label', 'warn');
291
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-3'], '47|[{"Type":"WARN","Label":"Custom label"},"Test"]|');
292
+
293
+		$this->expectError('PHPUnit_Framework_Error');
294
+		$this->assertFalse(FireCake::fb('Test', 'Custom label', 'warn', 'more parameters'));
295
+
296
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-Index'], 3);
297
+	}
298
+
299
+/**
300
+ * Test defaulting to log if incorrect message type is used
301
+ *
302
+ * @return void
303
+ */
304
+	public function testIncorrectMessageType() {
305
+		FireCake::setOptions(array('includeLineNumbers' => false));
306
+		FireCake::fb('Hello World', 'foobared');
307
+		$this->assertEquals($this->firecake->sentHeaders['X-Wf-1-1-1-1'], '30|[{"Type":"LOG"},"Hello World"]|');
308
+	}
309
+
310
+/**
311
+ * Test DetectClientExtension.
312
+ *
313
+ * @return void
314
+ */
315
+	public function testDetectClientExtension() {
316
+		$back = env('HTTP_USER_AGENT');
317
+		$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.2.1';
318
+		$this->assertTrue(FireCake::detectClientExtension());
319
+
320
+		$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 FirePHP/0.0.4';
321
+		$this->assertFalse(FireCake::detectClientExtension());
322
+
323
+		$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4';
324
+		$this->assertFalse(FireCake::detectClientExtension());
325
+		$_SERVER['HTTP_USER_AGENT'] = $back;
326
+	}
327
+
328
+/**
329
+ * Test of Non Native JSON encoding.
330
+ *
331
+ * @return void
332
+ */
333
+	public function testNonNativeEncoding() {
334
+		FireCake::setOptions(array('useNativeJsonEncode' => false));
335
+		$json = FireCake::jsonEncode(array('one' => 1, 'two' => 2));
336
+		$this->assertEquals($json, '{"one":1,"two":2}');
337
+
338
+		$json = FireCake::jsonEncode(array(1,2,3));
339
+		$this->assertEquals($json, '[1,2,3]');
340
+
341
+		$json = FireCake::jsonEncode(FireCake::getInstance());
342
+		$this->assertPattern('/"options"\:\{"maxObjectDepth"\:\d*,/', $json);
343
+	}
344
+
345
+}

+ 63
- 0
Plugin/DebugKit/Test/Case/Lib/Panel/LogPanelTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit Log Panel Test Cases
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
+ **/
17
+
18
+App::uses('LogPanel', 'DebugKit.Lib/Panel');
19
+App::uses('Controller', 'Controller');
20
+
21
+/**
22
+ * Class LogPanelTest
23
+ *
24
+ */
25
+class LogPanelTest extends CakeTestCase {
26
+
27
+/**
28
+ * set up
29
+ *
30
+ * @return void
31
+ */
32
+	public function setUp() {
33
+		parent::setUp();
34
+		$this->panel = new LogPanel();
35
+	}
36
+
37
+/**
38
+ * Test that logging configs are created.
39
+ *
40
+ * @return void
41
+ */
42
+	public function testConstructor() {
43
+		$result = CakeLog::configured();
44
+		$this->assertContains('debug_kit_log_panel', $result);
45
+		$this->assertTrue(count($result) > 1, 'Default loggers were not added.');
46
+	}
47
+
48
+/**
49
+ * testBeforeRender
50
+ *
51
+ * @return void
52
+ */
53
+	public function testBeforeRender() {
54
+		$controller = new Controller();
55
+
56
+		CakeLog::write('error', 'Test');
57
+
58
+		$result = $this->panel->beforeRender($controller);
59
+		$this->assertInstanceOf('DebugKitLog', $result);
60
+		$this->assertTrue(isset($result->logs));
61
+		$this->assertCount(1, $result->logs['error']);
62
+	}
63
+}

+ 59
- 0
Plugin/DebugKit/Test/Case/Lib/Panel/SqlLogPanelTest.php 파일 보기

1
+<?php
2
+/**
3
+ * SqlLogPanelTest
4
+ *
5
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
6
+ *
7
+ * Licensed under The MIT License
8
+ * Redistributions of files must retain the above copyright notice.
9
+ *
10
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
+ * @link          http://cakephp.org CakePHP(tm) Project
12
+ * @since         DebugKit 2.1
13
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
14
+ */
15
+
16
+App::uses('SqlLogPanel', 'DebugKit.Lib/Panel');
17
+App::uses('Model', 'Model');
18
+App::uses('Controller', 'Controller');
19
+
20
+/**
21
+ * Class SqlLogPanelTest
22
+ *
23
+ * @since         DebugKit 2.1
24
+ */
25
+class SqlLogPanelTest extends CakeTestCase {
26
+
27
+/**
28
+ * fixtures.
29
+ *
30
+ * @var array
31
+ */
32
+	public $fixtures = array('core.article');
33
+
34
+/**
35
+ * Setup
36
+ *
37
+ * @return void
38
+ */
39
+	public function setUp() {
40
+		parent::setUp();
41
+		$this->panel = new SqlLogPanel();
42
+	}
43
+
44
+/**
45
+ * test the parsing of source list.
46
+ *
47
+ * @return void
48
+ */
49
+	public function testBeforeRender() {
50
+		$Article = ClassRegistry::init('Article');
51
+		$Article->find('first', array('conditions' => array('Article.id' => 1)));
52
+
53
+		$controller = new Controller();
54
+		$result = $this->panel->beforeRender($controller);
55
+
56
+		$this->assertTrue(isset($result['connections'][$Article->useDbConfig]));
57
+		$this->assertTrue(isset($result['threshold']));
58
+	}
59
+}

+ 89
- 0
Plugin/DebugKit/Test/Case/Model/Behavior/TimedBehaviorTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit TimedBehavior Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.3
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('DebugKitDebugger', 'DebugKit.Lib');
20
+
21
+/**
22
+ * Class TimedBehaviorTestCase
23
+ *
24
+ * @since         DebugKit 1.3
25
+ */
26
+class TimedBehaviorTestCase extends CakeTestCase {
27
+
28
+/**
29
+ * Fixtures
30
+ *
31
+ * @var array
32
+ */
33
+	public $fixtures = array('core.article');
34
+
35
+/**
36
+ * Start Test callback
37
+ *
38
+ * @return void
39
+ */
40
+	public function setUp() {
41
+		parent::setUp();
42
+		$this->Article = ClassRegistry::init('Article');
43
+		$this->Article->Behaviors->attach('DebugKit.Timed');
44
+	}
45
+
46
+/**
47
+ * End a test
48
+ *
49
+ * @return void
50
+ */
51
+	public function tearDown() {
52
+		parent::tearDown();
53
+		unset($this->Article);
54
+		ClassRegistry::flush();
55
+		DebugKitDebugger::clearTimers();
56
+	}
57
+
58
+/**
59
+ * Test find timers
60
+ *
61
+ * @return void
62
+ */
63
+	public function testFindTimers() {
64
+		$timers = DebugKitDebugger::getTimers(false);
65
+		$this->assertEquals(count($timers), 1);
66
+
67
+		$this->Article->find('all');
68
+		$result = DebugKitDebugger::getTimers(false);
69
+		$this->assertEquals(count($result), 2);
70
+
71
+		$this->Article->find('all');
72
+		$result = DebugKitDebugger::getTimers(false);
73
+		$this->assertEquals(count($result), 3);
74
+	}
75
+
76
+/**
77
+ * Test save timers
78
+ *
79
+ * @return void
80
+ */
81
+	public function testSaveTimers() {
82
+		$timers = DebugKitDebugger::getTimers(false);
83
+		$this->assertEquals(count($timers), 1);
84
+
85
+		$this->Article->save(array('user_id' => 1, 'title' => 'test', 'body' => 'test'));
86
+		$result = DebugKitDebugger::getTimers(false);
87
+		$this->assertEquals(count($result), 2);
88
+	}
89
+}

+ 69
- 0
Plugin/DebugKit/Test/Case/Model/ToolbarAccessTest.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit ToolbarAccess Model Test case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.3
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+
19
+App::uses('ToolbarAccess', 'DebugKit.Model');
20
+
21
+/**
22
+ * Test case for ToolbarAccess model
23
+ *
24
+ * @since         DebugKit 1.3
25
+ */
26
+class ToolbarAccessTestCase extends CakeTestCase {
27
+
28
+/**
29
+ * Included fixtures
30
+ *
31
+ * @var array
32
+ */
33
+	public $fixtures = array('core.post');
34
+
35
+/**
36
+ * setUp method
37
+ *
38
+ * @return void
39
+ */
40
+	public function setUp() {
41
+		parent::setUp();
42
+		$this->Model = new ToolbarAccess();
43
+	}
44
+
45
+/**
46
+ * tearDown
47
+ *
48
+ * @return void
49
+ */
50
+	public function tearDown() {
51
+		parent::tearDown();
52
+		unset($this->Model);
53
+	}
54
+
55
+/**
56
+ * test that explain query returns arrays of query information.
57
+ *
58
+ * @return void
59
+ */
60
+	public function testExplainQuery() {
61
+		$Post = new CakeTestModel(array('table' => 'posts', 'alias' => 'Post'));
62
+		$db = $Post->getDataSource();
63
+		$sql = 'SELECT * FROM ' . $db->fullTableName('posts') . ';';
64
+		$result = $this->Model->explainQuery($Post->useDbConfig, $sql);
65
+
66
+		$this->assertTrue(is_array($result));
67
+		$this->assertFalse(empty($result));
68
+	}
69
+}

+ 65
- 0
Plugin/DebugKit/Test/Case/TestFireCake.php 파일 보기

1
+<?php
2
+/**
3
+ * Common test objects used in DebugKit tests
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('FireCake', 'DebugKit.Lib');
20
+
21
+/**
22
+ * TestFireCake class allows for testing of FireCake
23
+ *
24
+ * @since         DebugKit 0.1
25
+ */
26
+class TestFireCake extends FireCake {
27
+
28
+/**
29
+ * Headers that were sent
30
+ *
31
+ * @var array
32
+ */
33
+	public $sentHeaders = array();
34
+
35
+/**
36
+ * Send header
37
+ *
38
+ * @param $name
39
+ * @param $value
40
+ */
41
+	protected function _sendHeader($name, $value) {
42
+		$_this = FireCake::getInstance();
43
+		$_this->sentHeaders[$name] = $value;
44
+	}
45
+
46
+/**
47
+ * Skip client detection as headers are not being sent.
48
+ *
49
+ * @return boolean Always true
50
+ */
51
+	public static function detectClientExtension() {
52
+		return true;
53
+	}
54
+
55
+/**
56
+ * Reset FireCake
57
+ *
58
+ * @return void
59
+ */
60
+	public static function reset() {
61
+		$_this = FireCake::getInstance();
62
+		$_this->sentHeaders = array();
63
+		$_this->_messageIndex = 1;
64
+	}
65
+}

+ 152
- 0
Plugin/DebugKit/Test/Case/View/Helper/FirePhpToolbarHelperTest.php 파일 보기

1
+<?php
2
+/**
3
+ * Toolbar Abstract Helper Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+
19
+$path = CakePlugin::path('DebugKit');
20
+
21
+App::uses('View', 'View');
22
+App::uses('Controller', 'Controller');
23
+App::uses('CakeResponse', 'Network');
24
+App::uses('Router', 'Routing');
25
+App::uses('ToolbarHelper', 'DebugKit.View/Helper');
26
+App::uses('FirePhpToolbarHelper', 'DebugKit.View/Helper');
27
+
28
+require_once $path . 'Test' . DS . 'Case' . DS . 'TestFireCake.php';
29
+
30
+/**
31
+ * Class FirePhpToolbarHelperTestCase
32
+ *
33
+ * @since         DebugKit 0.1
34
+ */
35
+class FirePhpToolbarHelperTestCase extends CakeTestCase {
36
+
37
+/**
38
+ * setUp
39
+ *
40
+ * @return void
41
+ **/
42
+	public function setUp() {
43
+		parent::setUp();
44
+
45
+		Router::connect('/:controller/:action');
46
+		Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
47
+		Router::parse('/');
48
+
49
+		$this->Controller = new Controller($this->getMock('CakeRequest'), new CakeResponse());
50
+		$this->View = new View($this->Controller);
51
+		$this->Toolbar = new ToolbarHelper($this->View, array('output' => 'DebugKit.FirePhpToolbar'));
52
+		$this->Toolbar->FirePhpToolbar = new FirePhpToolbarHelper($this->View);
53
+
54
+		$this->firecake = FireCake::getInstance('TestFireCake');
55
+		TestFireCake::reset();
56
+	}
57
+
58
+/**
59
+ * Start test - switch view paths
60
+ *
61
+ * @return void
62
+ **/
63
+	public static function setupBeforeClass() {
64
+		App::build(array(
65
+			'View' => array(
66
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'View' . DS,
67
+				APP . 'Plugin' . DS . 'DebugKit' . DS . 'View' . DS,
68
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'View' . DS
69
+		)), true);
70
+	}
71
+
72
+/**
73
+ * End Test
74
+ *
75
+ * @return void
76
+ */
77
+	public static function tearDownAfterClass() {
78
+		App::build();
79
+	}
80
+
81
+/**
82
+ * TearDown
83
+ *
84
+ * @return void
85
+ */
86
+	public function tearDown() {
87
+		parent::tearDown();
88
+		unset($this->Toolbar, $this->Controller);
89
+		TestFireCake::reset();
90
+	}
91
+
92
+/**
93
+ * Test neat array (dump)creation
94
+ *
95
+ * @return void
96
+ */
97
+	public function testMakeNeatArray() {
98
+		$this->Toolbar->makeNeatArray(array(1,2,3));
99
+		$result = $this->firecake->sentHeaders;
100
+		$this->assertTrue(isset($result['X-Wf-1-1-1-1']));
101
+		$this->assertRegexp('/\[1,2,3\]/', $result['X-Wf-1-1-1-1']);
102
+	}
103
+
104
+/**
105
+ * Test afterlayout element rendering
106
+ *
107
+ * @return void
108
+ */
109
+	public function testAfterLayout() {
110
+		$this->Controller->viewPath = 'Posts';
111
+		$request = new CakeRequest('/posts/index');
112
+		$request->addParams(Router::parse($request->url));
113
+		$request->addPaths(array(
114
+			'webroot' => '/',
115
+			'base' => '/',
116
+			'here' => '/posts/index',
117
+		));
118
+		$this->Controller->setRequest($request);
119
+		$this->Controller->layout = 'default';
120
+		$this->Controller->uses = null;
121
+		$this->Controller->components = array('DebugKit.Toolbar');
122
+		$this->Controller->constructClasses();
123
+		$this->Controller->Components->trigger('startup', array($this->Controller));
124
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
125
+		$result = $this->Controller->render();
126
+		$this->assertNotRegExp('/debug-toolbar/', (string)$result);
127
+		$result = $this->firecake->sentHeaders;
128
+		$this->assertTrue(is_array($result));
129
+	}
130
+
131
+/**
132
+ * test starting a panel
133
+ *
134
+ * @return void
135
+ **/
136
+	public function testPanelStart() {
137
+		$this->Toolbar->panelStart('My Panel', 'my_panel');
138
+		$result = $this->firecake->sentHeaders;
139
+		$this->assertPattern('/GROUP_START.+My Panel/', $result['X-Wf-1-1-1-1']);
140
+	}
141
+
142
+/**
143
+ * test ending a panel
144
+ *
145
+ * @return void
146
+ **/
147
+	public function testPanelEnd() {
148
+		$this->Toolbar->panelEnd();
149
+		$result = $this->firecake->sentHeaders;
150
+		$this->assertPattern('/GROUP_END/', $result['X-Wf-1-1-1-1']);
151
+	}
152
+}

+ 452
- 0
Plugin/DebugKit/Test/Case/View/Helper/HtmlToolbarHelperTest.php 파일 보기

1
+<?php
2
+/**
3
+ * Toolbar HTML Helper Test Case
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('View', 'View');
20
+App::uses('Controller', 'Controller');
21
+App::uses('Router', 'Routing');
22
+App::uses('CakeResponse', 'Network');
23
+App::uses('ToolbarHelper', 'DebugKit.View/Helper');
24
+App::uses('HtmlToolbarHelper', 'DebugKit.View/Helper');
25
+App::uses('HtmlHelper', 'View/Helper');
26
+App::uses('FormHelper', 'View/Helper');
27
+
28
+/**
29
+ * Class HtmlToolbarHelperTestCase
30
+ *
31
+ * @since         DebugKit 0.1
32
+ */
33
+class HtmlToolbarHelperTestCase extends CakeTestCase {
34
+
35
+/**
36
+ * Setup Test Case
37
+ */
38
+	public static function setupBeforeClass() {
39
+		App::build(array(
40
+			'View' => array(
41
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'View' . DS,
42
+				APP . 'Plugin' . DS . 'DebugKit' . DS . 'View' . DS,
43
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'View' . DS
44
+			)
45
+		), true);
46
+	}
47
+
48
+/**
49
+ * Tear Down Test Case
50
+ */
51
+	public static function tearDownAfterClass() {
52
+		App::build();
53
+	}
54
+
55
+/**
56
+ * Setup
57
+ *
58
+ * @return void
59
+ */
60
+	public function setUp() {
61
+		parent::setUp();
62
+
63
+		Router::connect('/:controller/:action');
64
+
65
+		$request = new CakeRequest();
66
+		$request->addParams(array('controller' => 'pages', 'action' => 'display'));
67
+
68
+		$this->Controller = new Controller($request, new CakeResponse());
69
+		$this->View = new View($this->Controller);
70
+		$this->Toolbar = new ToolbarHelper($this->View, array('output' => 'DebugKit.HtmlToolbar'));
71
+		$this->Toolbar->HtmlToolbar = new HtmlToolbarHelper($this->View);
72
+		$this->Toolbar->HtmlToolbar->Html = new HtmlHelper($this->View);
73
+		$this->Toolbar->HtmlToolbar->Form = new FormHelper($this->View);
74
+	}
75
+
76
+/**
77
+ * Tear Down
78
+ *
79
+ * @return void
80
+ */
81
+	public function tearDown() {
82
+		parent::tearDown();
83
+		unset($this->Toolbar, $this->Controller);
84
+	}
85
+
86
+/**
87
+ * Test makeNeatArray with basic types.
88
+ *
89
+ * @return void
90
+ */
91
+	public function testMakeNeatArrayBasic() {
92
+		$in = false;
93
+		$result = $this->Toolbar->makeNeatArray($in);
94
+		$expected = array(
95
+			'ul' => array('class' => 'neat-array depth-0'),
96
+			'<li', '<strong', '0' , '/strong', '(false)', '/li',
97
+			'/ul'
98
+		);
99
+		$this->assertTags($result, $expected);
100
+
101
+		$in = null;
102
+		$result = $this->Toolbar->makeNeatArray($in);
103
+		$expected = array(
104
+			'ul' => array('class' => 'neat-array depth-0'),
105
+			'<li', '<strong', '0' , '/strong', '(null)', '/li',
106
+			'/ul'
107
+		);
108
+		$this->assertTags($result, $expected);
109
+
110
+		$in = true;
111
+		$result = $this->Toolbar->makeNeatArray($in);
112
+		$expected = array(
113
+			'ul' => array('class' => 'neat-array depth-0'),
114
+			'<li', '<strong', '0' , '/strong', '(true)', '/li',
115
+			'/ul'
116
+		);
117
+		$this->assertTags($result, $expected);
118
+
119
+		$in = array();
120
+		$result = $this->Toolbar->makeNeatArray($in);
121
+		$expected = array(
122
+			'ul' => array('class' => 'neat-array depth-0'),
123
+			'<li', '<strong', '0' , '/strong', '(empty)', '/li',
124
+			'/ul'
125
+		);
126
+		$this->assertTags($result, $expected);
127
+	}
128
+
129
+/**
130
+ * Test that cyclic references can be printed.
131
+ *
132
+ * @return void
133
+ */
134
+	public function testMakeNeatArrayCyclicObjects() {
135
+		$a = new StdClass;
136
+		$b = new StdClass;
137
+		$a->child = $b;
138
+		$b->parent = $a;
139
+
140
+		$in = array('obj' => $a);
141
+		$result = $this->Toolbar->makeNeatArray($in);
142
+		$expected = array(
143
+			array('ul' => array('class' => 'neat-array depth-0')),
144
+			'<li', '<strong', 'obj', '/strong', '(object)',
145
+			array('ul' => array('class' => 'neat-array depth-1')),
146
+			'<li', '<strong', 'child', '/strong', '(object)',
147
+			array('ul' => array('class' => 'neat-array depth-2')),
148
+			'<li', '<strong', 'parent', '/strong',
149
+			'(object) - recursion',
150
+			'/li',
151
+			'/ul',
152
+			'/li',
153
+			'/ul',
154
+			'/li',
155
+			'/ul'
156
+		);
157
+		$this->assertTags($result, $expected);
158
+	}
159
+
160
+/**
161
+ * Test Neat Array formatting
162
+ *
163
+ * @return void
164
+ */
165
+	public function testMakeNeatArray() {
166
+		$in = array('key' => 'value');
167
+		$result = $this->Toolbar->makeNeatArray($in);
168
+		$expected = array(
169
+			'ul' => array('class' => 'neat-array depth-0'),
170
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
171
+			'/ul'
172
+		);
173
+		$this->assertTags($result, $expected);
174
+
175
+		$in = array('key' => null);
176
+		$result = $this->Toolbar->makeNeatArray($in);
177
+		$expected = array(
178
+			'ul' => array('class' => 'neat-array depth-0'),
179
+			'<li', '<strong', 'key', '/strong', '(null)', '/li',
180
+			'/ul'
181
+		);
182
+		$this->assertTags($result, $expected);
183
+
184
+		$in = array('key' => 'value', 'foo' => 'bar');
185
+		$result = $this->Toolbar->makeNeatArray($in);
186
+		$expected = array(
187
+			'ul' => array('class' => 'neat-array depth-0'),
188
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
189
+			'<li', '<strong', 'foo', '/strong', 'bar', '/li',
190
+			'/ul'
191
+		);
192
+		$this->assertTags($result, $expected);
193
+
194
+		$in = array(
195
+			'key' => 'value',
196
+			'foo' => array(
197
+				'this' => 'deep',
198
+				'another' => 'value'
199
+			)
200
+		);
201
+		$result = $this->Toolbar->makeNeatArray($in);
202
+		$expected = array(
203
+			'ul' => array('class' => 'neat-array depth-0'),
204
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
205
+			'<li', '<strong', 'foo', '/strong',
206
+				'(array)',
207
+				array('ul' => array('class' => 'neat-array depth-1')),
208
+				'<li', '<strong', 'this', '/strong', 'deep', '/li',
209
+				'<li', '<strong', 'another', '/strong', 'value', '/li',
210
+				'/ul',
211
+			'/li',
212
+			'/ul'
213
+		);
214
+		$this->assertTags($result, $expected);
215
+
216
+		$in = array(
217
+			'key' => 'value',
218
+			'foo' => array(
219
+				'this' => 'deep',
220
+				'another' => 'value'
221
+			),
222
+			'lotr' => array(
223
+				'gandalf' => 'wizard',
224
+				'bilbo' => 'hobbit'
225
+			)
226
+		);
227
+		$result = $this->Toolbar->makeNeatArray($in, 1);
228
+		$expected = array(
229
+			'ul' => array('class' => 'neat-array depth-0 expanded'),
230
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
231
+			'<li', '<strong', 'foo', '/strong',
232
+				'(array)',
233
+				array('ul' => array('class' => 'neat-array depth-1')),
234
+				'<li', '<strong', 'this', '/strong', 'deep', '/li',
235
+				'<li', '<strong', 'another', '/strong', 'value', '/li',
236
+				'/ul',
237
+			'/li',
238
+			'<li', '<strong', 'lotr', '/strong',
239
+				'(array)',
240
+				array('ul' => array('class' => 'neat-array depth-1')),
241
+				'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
242
+				'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
243
+				'/ul',
244
+			'/li',
245
+			'/ul'
246
+		);
247
+		$this->assertTags($result, $expected);
248
+
249
+		$result = $this->Toolbar->makeNeatArray($in, 2);
250
+		$expected = array(
251
+			'ul' => array('class' => 'neat-array depth-0 expanded'),
252
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
253
+			'<li', '<strong', 'foo', '/strong',
254
+				'(array)',
255
+				array('ul' => array('class' => 'neat-array depth-1 expanded')),
256
+				'<li', '<strong', 'this', '/strong', 'deep', '/li',
257
+				'<li', '<strong', 'another', '/strong', 'value', '/li',
258
+				'/ul',
259
+			'/li',
260
+			'<li', '<strong', 'lotr', '/strong',
261
+				'(array)',
262
+				array('ul' => array('class' => 'neat-array depth-1 expanded')),
263
+				'<li', '<strong', 'gandalf', '/strong', 'wizard', '/li',
264
+				'<li', '<strong', 'bilbo', '/strong', 'hobbit', '/li',
265
+				'/ul',
266
+			'/li',
267
+			'/ul'
268
+		);
269
+		$this->assertTags($result, $expected);
270
+
271
+		$in = array('key' => 'value', 'array' => array());
272
+		$result = $this->Toolbar->makeNeatArray($in);
273
+		$expected = array(
274
+			'ul' => array('class' => 'neat-array depth-0'),
275
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
276
+			'<li', '<strong', 'array', '/strong', '(empty)', '/li',
277
+			'/ul'
278
+		);
279
+		$this->assertTags($result, $expected);
280
+	}
281
+
282
+/**
283
+ * Test makeNeatArray with object inputs.
284
+ *
285
+ * @return void
286
+ */
287
+	public function testMakeNeatArrayObjects() {
288
+		$in = new StdClass();
289
+		$in->key = 'value';
290
+		$in->nested = new StdClass();
291
+		$in->nested->name = 'mark';
292
+
293
+		$result = $this->Toolbar->makeNeatArray($in);
294
+		$expected = array(
295
+			array('ul' => array('class' => 'neat-array depth-0')),
296
+			'<li', '<strong', 'key', '/strong', 'value', '/li',
297
+			'<li', '<strong', 'nested', '/strong',
298
+			'(object)',
299
+			array('ul' => array('class' => 'neat-array depth-1')),
300
+			'<li', '<strong', 'name', '/strong', 'mark', '/li',
301
+			'/ul',
302
+			'/li',
303
+			'/ul'
304
+		);
305
+		$this->assertTags($result, $expected);
306
+	}
307
+
308
+/**
309
+ * Test injection of toolbar
310
+ *
311
+ * @return void
312
+ */
313
+	public function testInjectToolbar() {
314
+		$this->Controller->viewPath = 'Posts';
315
+		$request = new CakeRequest('/posts/index');
316
+		$request->addParams(Router::parse($request->url));
317
+		$request->addPaths(array(
318
+			'webroot' => '/',
319
+			'base' => '/',
320
+			'here' => '/posts/index',
321
+		));
322
+		$this->Controller->setRequest($request);
323
+		$this->Controller->helpers = array('Html', 'Js', 'Session', 'DebugKit.Toolbar');
324
+		$this->Controller->layout = 'default';
325
+		$this->Controller->uses = null;
326
+		$this->Controller->components = array('DebugKit.Toolbar');
327
+		$this->Controller->constructClasses();
328
+		$this->Controller->Components->trigger('startup', array($this->Controller));
329
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
330
+		$result = $this->Controller->render();
331
+		$result = str_replace(array("\n", "\r"), '', $result);
332
+		$this->assertPattern('#<div id\="debug-kit-toolbar">.+</div>.*</body>#', $result);
333
+	}
334
+
335
+/**
336
+ * test injection of javascript
337
+ *
338
+ * @return void
339
+ */
340
+	public function testJavascriptInjection() {
341
+		$this->Controller->viewPath = 'Posts';
342
+		$this->Controller->uses = null;
343
+		$request = new CakeRequest('/posts/index');
344
+		$request->addParams(Router::parse($request->url));
345
+		$request->addPaths(array(
346
+			'webroot' => '/',
347
+			'base' => '/',
348
+			'here' => '/posts/index',
349
+		));
350
+		$this->Controller->setRequest($request);
351
+		$this->Controller->helpers = array('Js', 'Html', 'Session');
352
+		$this->Controller->components = array('DebugKit.Toolbar');
353
+		$this->Controller->layout = 'default';
354
+		$this->Controller->constructClasses();
355
+		$this->Controller->Components->trigger('startup', array($this->Controller));
356
+		$this->Controller->Components->trigger('beforeRender', array($this->Controller));
357
+		$result = $this->Controller->render();
358
+		$result = str_replace(array("\n", "\r"), '', $result);
359
+		$this->assertPattern('#<script\s*type="text/javascript"\s*src="/debug_kit/js/js_debug_toolbar.js(?:\?\d*?)?"\s*>\s?</script>#', $result);
360
+	}
361
+
362
+/**
363
+ * test message creation
364
+ *
365
+ * @return void
366
+ */
367
+	public function testMessage() {
368
+		$result = $this->Toolbar->message('test', 'one, two');
369
+		$expected = array(
370
+			'<p',
371
+				'<strong', 'test', '/strong',
372
+				' one, two',
373
+			'/p',
374
+		);
375
+		$this->assertTags($result, $expected);
376
+	}
377
+
378
+/**
379
+ * Test Table generation
380
+ *
381
+ * @return void
382
+ */
383
+	public function testTable() {
384
+		$rows = array(
385
+			array(1,2),
386
+			array(3,4),
387
+		);
388
+		$result = $this->Toolbar->table($rows);
389
+		$expected = array(
390
+			'table' => array('class' => 'debug-table'),
391
+			array('tr' => array('class' => 'odd')),
392
+			'<td', '1', '/td',
393
+			'<td', '2', '/td',
394
+			'/tr',
395
+			array('tr' => array('class' => 'even')),
396
+			'<td', '3', '/td',
397
+			'<td', '4', '/td',
398
+			'/tr',
399
+			'/table'
400
+		);
401
+		$this->assertTags($result, $expected);
402
+	}
403
+
404
+/**
405
+ * test starting a panel
406
+ *
407
+ * @return void
408
+ */
409
+	public function testStartPanel() {
410
+		$result = $this->Toolbar->panelStart('My Panel', 'my_panel');
411
+		$expected = array(
412
+			'a' => array('href' => '#my_panel'),
413
+			'My Panel',
414
+			'/a'
415
+		);
416
+		$this->assertTags($result, $expected);
417
+	}
418
+
419
+/**
420
+ * test ending a panel
421
+ *
422
+ * @return void
423
+ */
424
+	public function testPanelEnd() {
425
+		$result = $this->Toolbar->panelEnd();
426
+		$this->assertNull($result);
427
+	}
428
+
429
+/**
430
+ * Test generating links for query explains.
431
+ *
432
+ * @return void
433
+ */
434
+	public function testExplainLink() {
435
+		$sql = 'SELECT * FROM tasks';
436
+		$result = $this->Toolbar->explainLink($sql, 'default');
437
+		$expected = array(
438
+			'form' => array('action' => '/debug_kit/toolbar_access/sql_explain', 'method' => 'post',
439
+				'accept-charset' => 'utf-8', 'id'),
440
+			array('div' => array('style' => 'display:none;')),
441
+			array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
442
+			'/div',
443
+			array('input' => array('type' => 'hidden', 'id', 'name' => 'data[log][ds]', 'value' => 'default')),
444
+			array('input' => array('type' => 'hidden', 'id', 'name' => 'data[log][sql]', 'value' => $sql)),
445
+			array('input' => array('type' => 'hidden', 'id', 'name' => 'data[log][hash]', 'value')),
446
+			array('input' => array('class' => 'sql-explain-link', 'type' => 'submit', 'value' => 'Explain')),
447
+			'/form',
448
+		);
449
+		$this->assertTags($result, $expected);
450
+	}
451
+
452
+}

+ 179
- 0
Plugin/DebugKit/Test/Case/View/Helper/ToolbarHelperTest.php 파일 보기

1
+<?php
2
+/**
3
+ * Toolbar facade tests.
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('View', 'View');
20
+App::uses('Controller', 'Controller');
21
+App::uses('Helper', 'View');
22
+App::uses('ToolbarHelper', 'DebugKit.View/Helper');
23
+App::uses('ConnectionManager', 'Manager');
24
+
25
+/**
26
+ * Class MockBackendHelper
27
+ *
28
+ * @since         DebugKit 0.1
29
+ */
30
+class MockBackendHelper extends Helper {
31
+}
32
+
33
+/**
34
+ * Class ToolbarHelperTestCase
35
+ *
36
+ */
37
+class ToolbarHelperTestCase extends CakeTestCase {
38
+
39
+/**
40
+ * Fixtures
41
+ *
42
+ * @var array
43
+ */
44
+	public $fixtures = array('core.post');
45
+
46
+/**
47
+ * setUp
48
+ *
49
+ * @return void
50
+ */
51
+	public function setUp() {
52
+		parent::setUp();
53
+		$db = ConnectionManager::getDatasource('test');
54
+		$db->fullDebug = true;
55
+
56
+		Configure::write('Cache.disable', false);
57
+		Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
58
+		Router::parse('/');
59
+
60
+		$this->Controller = new Controller(null);
61
+		$this->View = new View($this->Controller);
62
+		$this->Toolbar = new ToolbarHelper($this->View, array(
63
+			'output' => 'MockBackendHelper',
64
+			'cacheKey' => 'debug_kit_toolbar_test_case',
65
+			'cacheConfig' => 'default'
66
+		));
67
+		$this->Toolbar->MockBackend = $this->getMock('Helper', array('testMethod'), array($this->View));
68
+
69
+		$this->_viewPaths = App::path('views');
70
+		App::build(array(
71
+			'View' => array(
72
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'View' . DS,
73
+				APP . 'Plugin' . DS . 'DebugKit' . DS . 'View' . DS,
74
+				CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'View' . DS
75
+		)), true);
76
+	}
77
+
78
+/**
79
+ * tearDown
80
+ *
81
+ * @return void
82
+ */
83
+	public function tearDown() {
84
+		parent::tearDown();
85
+		Cache::delete('debug_kit_toolbar_test_case', 'default');
86
+		unset($this->Toolbar, $this->Controller);
87
+	}
88
+
89
+/**
90
+ * test cache writing for views.
91
+ *
92
+ * @return void
93
+ */
94
+	public function testCacheWrite() {
95
+		$result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
96
+		$this->assertTrue($result);
97
+	}
98
+
99
+/**
100
+ * Ensure that the cache writing only affects the
101
+ * top most level of the history stack. As this is where the current request is stored.
102
+ *
103
+ * @return void
104
+ */
105
+	public function testOnlyWritingToFirstElement() {
106
+		$values = array(
107
+			array('test' => array('content' => array('first', 'values'))),
108
+			array('test' => array('content' => array('second', 'values'))),
109
+		);
110
+		Cache::write('debug_kit_toolbar_test_case', $values, 'default');
111
+		$this->Toolbar->writeCache('test', array('new', 'values'));
112
+
113
+		$result = $this->Toolbar->readCache('test');
114
+		$this->assertEquals($result, array('new', 'values'));
115
+
116
+		$result = $this->Toolbar->readCache('test', 1);
117
+		$this->assertEquals($result, array('second', 'values'));
118
+	}
119
+
120
+/**
121
+ * test cache reading for views
122
+ *
123
+ * @return void
124
+ */
125
+	public function testCacheRead() {
126
+		$result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
127
+		$this->assertTrue($result, 'Cache write failed %s');
128
+
129
+		$result = $this->Toolbar->readCache('test');
130
+		$this->assertEquals($result, array('stuff', 'to', 'cache'), 'Cache value is wrong %s');
131
+
132
+		$result = $this->Toolbar->writeCache('test', array('new', 'stuff'));
133
+		$this->assertTrue($result, 'Cache write failed %s');
134
+
135
+		$result = $this->Toolbar->readCache('test');
136
+		$this->assertEquals($result, array('new', 'stuff'), 'Cache value is wrong %s');
137
+	}
138
+
139
+/**
140
+ * Test that reading/writing doesn't work with no cache config.
141
+ *
142
+ * @return void
143
+ */
144
+	public function testNoCacheConfigPresent() {
145
+		$this->Toolbar = new ToolbarHelper($this->View, array('output' => 'MockBackendHelper'));
146
+
147
+		$result = $this->Toolbar->writeCache('test', array('stuff', 'to', 'cache'));
148
+		$this->assertFalse($result, 'Writing to cache succeeded with no cache config %s');
149
+
150
+		$result = $this->Toolbar->readCache('test');
151
+		$this->assertFalse($result, 'Reading cache succeeded with no cache config %s');
152
+	}
153
+
154
+/**
155
+ * ensure that getQueryLogs works and writes to the cache so the history panel will
156
+ * work.
157
+ *
158
+ * @return void
159
+ */
160
+	public function testGetQueryLogs() {
161
+		$model = new CakeTestModel(array('table' => 'posts', 'alias' => 'Post'));
162
+		$model->find('all');
163
+		$model->find('first');
164
+
165
+		$result = $this->Toolbar->getQueryLogs($model->useDbConfig, array('cache' => false));
166
+		$this->assertTrue(is_array($result));
167
+		$this->assertTrue(count($result) >= 2, 'Should be more than 2 queries in the log %s');
168
+		$this->assertTrue(isset($result['queries'][0]['actions']));
169
+
170
+		$model->find('first');
171
+		Cache::delete('debug_kit_toolbar_test_case', 'default');
172
+		$result = $this->Toolbar->getQueryLogs($model->useDbConfig, array('cache' => true));
173
+
174
+		$cached = $this->Toolbar->readCache('sql_log');
175
+		$this->assertTrue(isset($cached[$model->useDbConfig]));
176
+		$this->assertEquals($cached[$model->useDbConfig]['queries'][0], $result['queries'][0]);
177
+	}
178
+
179
+}

+ 63
- 0
Plugin/DebugKit/Test/test_app/Controller/DebugKitTestController.php 파일 보기

1
+<?php
2
+/**
3
+ * DebugKit TestController of test_app
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+
19
+/**
20
+ * Class DebugKitTestController
21
+ *
22
+ * @since         DebugKit 0.1
23
+ */
24
+class DebugKitTestController extends Controller {
25
+
26
+/**
27
+ * Mame of the Controller
28
+ *
29
+ * @var string
30
+ */
31
+	public $name = 'DebugKitTest';
32
+
33
+/**
34
+ * Uses no Models
35
+ *
36
+ * @var array
37
+ */
38
+	public $uses = array();
39
+
40
+/**
41
+ * Uses only DebugKit Toolbar Component
42
+ *
43
+ * @var array
44
+ */
45
+	public $components = array('DebugKit.Toolbar');
46
+
47
+/**
48
+ * Return Request Action Value
49
+ *
50
+ * @return string
51
+ */
52
+	public function request_action_return() {
53
+		$this->autoRender = false;
54
+		return 'I am some value from requestAction.';
55
+	}
56
+
57
+/**
58
+ * Render Request Action
59
+ */
60
+	public function request_action_render() {
61
+		$this->set('test', 'I have been rendered.');
62
+	}
63
+}

+ 37
- 0
Plugin/DebugKit/Test/test_app/Lib/Panel/TestPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * Test Panel of test_app
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+App::uses('DebugPanel', 'DebugKit.Lib');
20
+
21
+/**
22
+ * Class TestPanel
23
+ *
24
+ * @since         DebugKit 0.1
25
+ */
26
+class TestPanel extends DebugPanel {
27
+
28
+/**
29
+ * Startup
30
+ *
31
+ * @param Controller $controller
32
+ */
33
+	public function startup(Controller $controller) {
34
+		$controller->testPanel = true;
35
+	}
36
+
37
+}

+ 26
- 0
Plugin/DebugKit/Test/test_app/Plugin/DebugkitTestPlugin/Lib/Panel/PluginTestPanel.php 파일 보기

1
+<?php
2
+/**
3
+ * Test Panel of test_app
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+
18
+App::uses('DebugPanel', 'DebugKit.Lib');
19
+
20
+/**
21
+ * Class PluginTestPanel
22
+ *
23
+ */
24
+
25
+class PluginTestPanel extends DebugPanel {
26
+}

+ 18
- 0
Plugin/DebugKit/Test/test_app/View/DebugKitTest/request_action_render.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Request Action Render template
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
16
+ */
17
+?>
18
+<?php echo $test; ?>

+ 1
- 0
Plugin/DebugKit/VERSION.txt 파일 보기

1
+2.2.6

+ 59
- 0
Plugin/DebugKit/View/Elements/debug_toolbar.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Debug Toolbar Element
4
+ *
5
+ * Renders all of the other panel elements.
6
+ *
7
+ * PHP 5
8
+ *
9
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
+ *
12
+ * Licensed under The MIT License
13
+ * Redistributions of files must retain the above copyright notice.
14
+ *
15
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
16
+ * @link          http://cakephp.org CakePHP(tm) Project
17
+ * @since         DebugKit 0.1
18
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
+ */
20
+?>
21
+<div id="debug-kit-toolbar">
22
+	<?php if (empty($debugToolbarPanels)) :?>
23
+		<p class="warning"><?php echo __d('debug_kit', 'There are no active panels. You must enable a panel to see its output.'); ?></p>
24
+	<?php else: ?>
25
+		<ul id="panel-tabs">
26
+			<li class="panel-tab icon">
27
+				<a href="#hide" id="hide-toolbar">
28
+					<?php echo $this->Html->image('/debug_kit/img/cake.icon.png', array('alt' => 'CakePHP')); ?>
29
+				</a>
30
+			</li>
31
+		<?php foreach ($debugToolbarPanels as $panelName => $panelInfo): ?>
32
+			<?php $panelUnderscore = Inflector::underscore($panelName);?>
33
+			<li class="panel-tab">
34
+			<?php
35
+				$title = (empty($panelInfo['title'])) ? Inflector::humanize($panelUnderscore) : $panelInfo['title'];
36
+				echo $this->Toolbar->panelStart($title, $panelUnderscore);
37
+			?>
38
+				<div class="panel-content" id="<?php echo $panelUnderscore ?>-tab">
39
+					<a href="#" class="panel-toggle ui-control ui-button">+</a>
40
+					<div class="panel-resize-region">
41
+						<div class="panel-content-data">
42
+							<?php
43
+								echo $this->element($panelInfo['elementName'], $panelInfo, array(
44
+									'plugin' => (empty($panelInfo['plugin'])) ? null : Inflector::camelize($panelInfo['plugin'])
45
+								));
46
+							?>
47
+						</div>
48
+						<div class="panel-content-data panel-history" id="<?php echo $panelUnderscore; ?>-history">
49
+							<!-- content here -->
50
+						</div>
51
+					</div>
52
+					<div class="panel-resize-handle ui-control">====</div>
53
+				</div>
54
+			<?php $this->Toolbar->panelEnd(); ?>
55
+			</li>
56
+		<?php endforeach; ?>
57
+		</ul>
58
+	<?php endif; ?>
59
+</div>

+ 84
- 0
Plugin/DebugKit/View/Elements/environment_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Environment Panel Element
4
+ *
5
+ * Shows information about the current app environment
6
+ *
7
+ * PHP 5
8
+ *
9
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
+ *
12
+ * Licensed under The MIT License
13
+ * Redistributions of files must retain the above copyright notice.
14
+ *
15
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
16
+ * @link          http://cakephp.org CakePHP(tm) Project
17
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
18
+ */
19
+?>
20
+<h2><?php echo __d('debug_kit', 'App Constants'); ?></h2>
21
+<?php
22
+	if (!empty($content['app'])) {
23
+		$cakeRows = array();
24
+		foreach ($content['app'] as $key => $val) {
25
+			$cakeRows[] = array(
26
+				$key,
27
+				$val
28
+			);
29
+		}
30
+		$headers = array('Constant', 'Value');
31
+		echo $this->Toolbar->table($cakeRows, $headers, array('title' => 'Application Environment Vars'));
32
+	} else {
33
+		echo "No application environment available.";
34
+	} ?>
35
+
36
+<h2><?php echo __d('debug_kit', 'CakePHP Constants'); ?></h2>
37
+<?php
38
+	if (!empty($content['cake'])) {
39
+		$cakeRows = array();
40
+		foreach ($content['cake'] as $key => $val) {
41
+			$cakeRows[] = array(
42
+				h($key),
43
+				h($val)
44
+			);
45
+		}
46
+		$headers = array('Constant', 'Value');
47
+		echo $this->Toolbar->table($cakeRows, $headers, array('title' => 'CakePHP Environment Vars'));
48
+	} else {
49
+		echo "CakePHP environment unavailable.";
50
+	} ?>
51
+
52
+<h2><?php echo __d('debug_kit', 'PHP Environment');?></h2>
53
+<?php
54
+	$headers = array('Environment Variable', 'Value');
55
+
56
+	if (!empty($content['php'])) {
57
+		$phpRows = array();
58
+		foreach ($content['php'] as $key => $val) {
59
+			$phpRows[] = array(
60
+				h(Inflector::humanize(strtolower($key))),
61
+				h($val)
62
+			);
63
+		}
64
+		echo $this->Toolbar->table($phpRows, $headers, array('title' => 'CakePHP Environment Vars'));
65
+	} else {
66
+		echo "PHP environment unavailable.";
67
+	}
68
+
69
+	if (isset($content['hidef'])) {
70
+		echo '<h2>' . __d('debug_kit', 'Hidef Environment') . '</h2>';
71
+		if (!empty($content['hidef'])) {
72
+			$cakeRows = array();
73
+			foreach ($content['hidef'] as $key => $val) {
74
+				$cakeRows[] = array(
75
+					h($key),
76
+					h($val)
77
+				);
78
+			}
79
+			$headers = array('Constant', 'Value');
80
+			echo $this->Toolbar->table($cakeRows, $headers, array('title' => 'Hidef Environment Vars'));
81
+		} else {
82
+			echo "No Hidef environment available.";
83
+		}
84
+	}

+ 32
- 0
Plugin/DebugKit/View/Elements/history_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * View Variables Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+?>
19
+<h2> <?php echo __d('debug_kit', 'Request History'); ?></h2>
20
+<?php if (empty($content)): ?>
21
+	<p class="warning"><?php echo __d('debug_kit', 'No previous requests logged.'); ?></p>
22
+<?php else: ?>
23
+	<?php echo count($content); ?> <?php echo __d('debug_kit', 'previous requests available') ?>
24
+	<ul class="history-list">
25
+		<li><?php echo $this->Html->link(__d('debug_kit', 'Restore to current request'),
26
+			'#', array('class' => 'history-link', 'id' => 'history-restore-current')); ?>
27
+		</li>
28
+		<?php foreach ($content as $previous): ?>
29
+			<li><?php echo $this->Html->link($previous['title'], $previous['url'], array('class' => 'history-link')); ?></li>
30
+		<?php endforeach; ?>
31
+	</ul>
32
+<?php endif;

+ 34
- 0
Plugin/DebugKit/View/Elements/include_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Included Files Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 2.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ **/
18
+?>
19
+<h2> <?php echo __d('debug_kit', 'Included Files'); ?></h2>
20
+
21
+<h4>Include Paths</h4>
22
+<?php
23
+	foreach ($content['paths'] as $i => $path) {
24
+		if (strstr($path, CAKE)) {
25
+			$content['paths'][$i] = '-> ' . $path;
26
+			break;
27
+		}
28
+	}
29
+	echo $this->Toolbar->makeNeatArray(array_filter($content['paths']));
30
+	unset($content['paths']);
31
+?>
32
+
33
+<h4>Included Files</h4>
34
+<?php echo $this->Toolbar->makeNeatArray($content);

+ 41
- 0
Plugin/DebugKit/View/Elements/log_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Log Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+?>
19
+<h2><?php echo __d('debug_kit', 'Logs') ?></h2>
20
+<div class="code-table">
21
+<?php if ($content instanceof DebugKitLog): ?>
22
+	<?php foreach ($content->logs as $logName => $logs): ?>
23
+		<h3><?php echo $logName ?></h3>
24
+		<?php
25
+			$len = count($logs);
26
+			if ($len > 0):
27
+				$headers = array(__d('debug_kit', 'Time'), __d('debug_kit', 'Message'));
28
+				$rows = array();
29
+				for ($i = 0; $i < $len; $i++):
30
+					$rows[] = array(
31
+						$logs[$i][0], h($logs[$i][1])
32
+					);
33
+				endfor;
34
+				echo $this->Toolbar->table($rows, $headers, array('title' => $logName));
35
+			endif; ?>
36
+	<?php endforeach; ?>
37
+	<?php if (empty($content->logs)): ?>
38
+		<p class="info"><?php echo __d('debug_kit', 'There were no log entries made this request'); ?></p>
39
+	<?php endif; ?>
40
+<?php endif; ?>
41
+</div>

+ 50
- 0
Plugin/DebugKit/View/Elements/request_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Request Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+?>
19
+<h2> <?php echo __d('debug_kit', 'Request'); ?></h2>
20
+
21
+<h4>Cake Params</h4>
22
+<?php echo $this->Toolbar->makeNeatArray($content['params']); ?>
23
+
24
+<h4>Post data</h4>
25
+<?php
26
+if (empty($content['data'])):
27
+	echo '<p class="info">' . __d('debug_kit', 'No post data.') . '</p>';
28
+else:
29
+	echo $this->Toolbar->makeNeatArray($content['data']);
30
+endif;
31
+?>
32
+
33
+<h4>Query string</h4>
34
+<?php
35
+if (empty($content['query'])):
36
+	echo '<p class="info">' . __d('debug_kit', 'No querystring data.') . '</p>';
37
+else:
38
+	echo $this->Toolbar->makeNeatArray($content['query']);
39
+endif;
40
+?>
41
+
42
+<h4>Cookie</h4>
43
+<?php if (isset($content['cookie'])): ?>
44
+	<?php echo $this->Toolbar->makeNeatArray($content['cookie']); ?>
45
+<?php else: ?>
46
+	<p class="info">To view Cookies, add CookieComponent to Controller</p>
47
+<?php endif; ?>
48
+
49
+<h4><?php echo __d('debug_kit', 'Current Route') ?></h4>
50
+<?php echo $this->Toolbar->makeNeatArray($content['currentRoute']);

+ 20
- 0
Plugin/DebugKit/View/Elements/session_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Session Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+?>
19
+<h2><?php echo __d('debug_kit', 'Session'); ?></h2>
20
+<?php echo $this->Toolbar->makeNeatArray($content);

+ 80
- 0
Plugin/DebugKit/View/Elements/sql_log_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * SQL Log Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+$headers = array('Query', 'Affected', 'Num. rows', 'Took (ms)', 'Actions');
20
+if (isset($debugKitInHistoryMode)) {
21
+	$content = $this->Toolbar->readCache('sql_log', $this->request->params['pass'][0]);
22
+}
23
+?>
24
+<h2><?php echo __d('debug_kit', 'Sql Logs')?></h2>
25
+<?php if (!empty($content)) : ?>
26
+	<?php foreach ($content['connections'] as $dbName => $explain): ?>
27
+	<div class="sql-log-panel-query-log">
28
+		<h4><?php echo $dbName ?></h4>
29
+		<?php
30
+			if (!isset($debugKitInHistoryMode)):
31
+				$queryLog = $this->Toolbar->getQueryLogs($dbName, array(
32
+					'explain' => $explain, 'threshold' => $content['threshold']
33
+				));
34
+			else:
35
+				$queryLog = $content[$dbName];
36
+			endif;
37
+			if (empty($queryLog['queries'])):
38
+				if (Configure::read('debug') < 2):
39
+					echo ' ' . __d('debug_kit', 'No query logs when debug < 2.');
40
+				else:
41
+					echo ' ' . __d('debug_kit', 'No query logs.');
42
+				endif;
43
+			else:
44
+				$hashes = array();
45
+				$duplicate = 0;
46
+				foreach ($queryLog['queries'] as $key => $val) {
47
+					$hash = sha1($val['query']);
48
+					if (!isset($hashes[$hash]) || $hashes[$hash] !== $val['affected']) {
49
+						$hashes[$hash] = $val['affected'];
50
+						continue;
51
+					}
52
+					$duplicate++;
53
+
54
+					$queryLog['queries'][$key]['query'] = '<span class="alert-duplicate">' . $val['query'] . '</span>';
55
+				}
56
+
57
+				echo '<h5>';
58
+				echo __d(
59
+					'debug_kit',
60
+					'Total Time: %s ms <br />Total Queries: %s queries',
61
+					$queryLog['time'],
62
+					$queryLog['count']
63
+				);
64
+				echo '</h5>';
65
+				echo $this->Toolbar->table($queryLog['queries'], $headers, array('title' => 'SQL Log ' . $dbName));
66
+				if ($duplicate) {
67
+					echo '<p class="alert alert-warning">' . __d('debug_kit', '%s duplicate queries run.', $duplicate) . '</p>';
68
+				}
69
+			?>
70
+		<h4><?php echo __d('debug_kit', 'Query Explain:'); ?></h4>
71
+		<div id="sql-log-explain-<?php echo $dbName ?>">
72
+			<a id="debug-kit-explain-<?php echo $dbName ?>"> </a>
73
+			<p><?php echo __d('debug_kit', 'Click an "Explain" link above, to see the query explanation.'); ?></p>
74
+		</div>
75
+		<?php endif; ?>
76
+	</div>
77
+	<?php endforeach; ?>
78
+<?php else:
79
+	echo $this->Toolbar->message('Warning', __d('debug_kit', 'No active database connections'));
80
+endif;

+ 110
- 0
Plugin/DebugKit/View/Elements/timer_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Timer Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+$this->Number = $this->Helpers->load('Number');
20
+$this->SimpleGraph = $this->Helpers->load('DebugKit.SimpleGraph');
21
+
22
+if (!isset($debugKitInHistoryMode)):
23
+	$timers = DebugTimer::getAll(true);
24
+	$currentMemory = DebugKitDebugger::getMemoryUse();
25
+	$peakMemory = DebugKitDebugger::getPeakMemoryUse();
26
+	$requestTime = DebugTimer::requestTime();
27
+else:
28
+	$content = $this->Toolbar->readCache('timer', $this->request->params['pass'][0]);
29
+	if (is_array($content)):
30
+		extract($content);
31
+	endif;
32
+endif;
33
+?>
34
+<div class="debug-info">
35
+	<h2><?php echo __d('debug_kit', 'Memory'); ?></h2>
36
+	<div class="peak-mem-use">
37
+	<?php
38
+		echo $this->Toolbar->message(__d('debug_kit', 'Peak Memory Use'), $this->Number->toReadableSize($peakMemory)); ?>
39
+	</div>
40
+
41
+	<?php
42
+	$headers = array(__d('debug_kit', 'Message'), __d('debug_kit', 'Memory use'));
43
+	$memoryPoints = DebugKitDebugger::getMemoryPoints();
44
+
45
+	$rows = array();
46
+	foreach ($memoryPoints as $key => $value):
47
+		$rows[] = array($key, $this->Number->toReadableSize($value));
48
+	endforeach;
49
+
50
+	echo $this->Toolbar->table($rows, $headers);
51
+	?>
52
+</div>
53
+
54
+<div class="debug-info debug-timers">
55
+	<h2><?php echo __d('debug_kit', 'Timers'); ?></h2>
56
+	<div class="request-time">
57
+		<?php $totalTime = __d('debug_kit', '%s (ms)', $this->Number->precision($requestTime * 1000, 0)); ?>
58
+		<?php echo $this->Toolbar->message(__d('debug_kit', 'Total Request Time:'), $totalTime)?>
59
+	</div>
60
+<?php
61
+$rows = array();
62
+$end = end($timers);
63
+$maxTime = $end['end'];
64
+
65
+$headers = array(
66
+	__d('debug_kit', 'Message'),
67
+	__d('debug_kit', 'Time in ms'),
68
+	__d('debug_kit', 'Graph')
69
+);
70
+
71
+$i = 0;
72
+$values = array_values($timers);
73
+
74
+foreach ($timers as $timerName => $timeInfo):
75
+	$indent = 0;
76
+	for ($j = 0; $j < $i; $j++) {
77
+		if (($values[$j]['end'] > $timeInfo['start']) && ($values[$j]['end']) > ($timeInfo['end'])) {
78
+			$indent++;
79
+		}
80
+	}
81
+	$indent = str_repeat(' &raquo; ', $indent);
82
+	$rows[] = array(
83
+		$indent . $timeInfo['message'],
84
+		$this->Number->precision($timeInfo['time'] * 1000, 2),
85
+		$this->SimpleGraph->bar(
86
+			$this->Number->precision($timeInfo['time'] * 1000, 2),
87
+			$this->Number->precision($timeInfo['start'] * 1000, 2),
88
+			array(
89
+				'max' => $maxTime * 1000,
90
+				'requestTime' => $requestTime * 1000,
91
+			)
92
+		)
93
+	);
94
+	$i++;
95
+endforeach;
96
+
97
+if (strtolower($this->Toolbar->getName()) === 'firephptoolbar'):
98
+	for ($i = 0, $len = count($rows); $i < $len; $i++):
99
+		unset($rows[$i][2]);
100
+	endfor;
101
+	unset($headers[2]);
102
+endif;
103
+
104
+echo $this->Toolbar->table($rows, $headers, array('title' => 'Timers'));
105
+
106
+if (!isset($debugKitInHistoryMode)):
107
+	$this->Toolbar->writeCache('timer', compact('timers', 'currentMemory', 'peakMemory', 'requestTime'));
108
+endif;
109
+?>
110
+</div>

+ 23
- 0
Plugin/DebugKit/View/Elements/variables_panel.ctp 파일 보기

1
+<?php
2
+/**
3
+ * View Variables Panel Element
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 0.1
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+?>
19
+<h2> <?php echo __d('debug_kit', 'View Variables'); ?></h2>
20
+<?php
21
+$content['$this->validationErrors'] = $this->validationErrors;
22
+$content['Loaded Helpers'] = $this->Helpers->attached();
23
+echo $this->Toolbar->makeNeatArray($content);

+ 90
- 0
Plugin/DebugKit/View/Helper/DebugTimerHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 2.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('DebugTimer', 'DebugKit.Lib');
16
+App::uses('DebugMemory', 'DebugKit.Lib');
17
+App::uses('Helper', 'View');
18
+
19
+/**
20
+ * Class DebugTimerHelper
21
+ *
22
+ * Tracks time and memory usage while rendering view.
23
+ *
24
+ */
25
+class DebugTimerHelper extends Helper {
26
+
27
+/**
28
+ * Set to true when rendering is complete.
29
+ * Used to not add timers for rendering the toolbar.
30
+ *
31
+ * @var boolean
32
+ */
33
+	protected $_renderComplete = false;
34
+
35
+/**
36
+ * Constructor
37
+ *
38
+ * @param View $View
39
+ * @param array $settings
40
+ */
41
+	public function __construct(View $View, $settings = array()) {
42
+		parent::__construct($View, $settings);
43
+		DebugTimer::start(
44
+			'viewRender',
45
+			__d('debug_kit', 'Rendering View')
46
+		);
47
+	}
48
+
49
+/**
50
+ * Sets a timer point before rendering a file.
51
+ *
52
+ * @param string $viewFile The view being rendered
53
+ */
54
+	public function beforeRenderFile($viewFile) {
55
+		if ($this->_renderComplete) {
56
+			return;
57
+		}
58
+		DebugTimer::start(
59
+			'render_' . basename($viewFile),
60
+			__d('debug_kit', 'Rendering %s',
61
+			Debugger::trimPath($viewFile))
62
+		);
63
+	}
64
+
65
+/**
66
+ * Stops the timer point before rendering a file.
67
+ *
68
+ * @param string $viewFile The view being rendered
69
+ * @param string $content The contents of the view.
70
+ */
71
+	public function afterRenderFile($viewFile, $content) {
72
+		if ($this->_renderComplete) {
73
+			return;
74
+		}
75
+		DebugTimer::stop('render_' . basename($viewFile));
76
+	}
77
+
78
+/**
79
+ * Stop timers for rendering.
80
+ *
81
+ * @param string $layoutFile
82
+ */
83
+	public function afterLayout($layoutFile) {
84
+		DebugTimer::stop('viewRender');
85
+		DebugTimer::stop('controllerRender');
86
+		DebugMemory::record(__d('debug_kit', 'View render complete'));
87
+		$this->_renderComplete = true;
88
+	}
89
+
90
+}

+ 106
- 0
Plugin/DebugKit/View/Helper/FirePhpToolbarHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('ToolbarHelper', 'DebugKit.View/Helper');
16
+App::uses('FireCake', 'DebugKit.Lib');
17
+
18
+/**
19
+ * FirePHP Toolbar Helper
20
+ *
21
+ * Injects the toolbar elements into non-HTML layouts via FireCake.
22
+ *
23
+ */
24
+class FirePhpToolbarHelper extends ToolbarHelper {
25
+
26
+/**
27
+ * settings property
28
+ *
29
+ * @var array
30
+ */
31
+	public $settings = array('format' => 'firePHP', 'forceEnable' => false);
32
+
33
+/**
34
+ * send method
35
+ *
36
+ * @return void
37
+ */
38
+	public function send() {
39
+		$view = $this->_View;
40
+		$view->element('debug_toolbar', array('disableTimer' => true), array('plugin' => 'DebugKit'));
41
+	}
42
+
43
+/**
44
+ * makeNeatArray.
45
+ *
46
+ * wraps FireCake::dump() allowing panel elements to continue functioning
47
+ *
48
+ * @param string $values
49
+ * @return void
50
+ */
51
+	public function makeNeatArray($values) {
52
+		FireCake::info($values);
53
+	}
54
+
55
+/**
56
+ * Create a simple message
57
+ *
58
+ * @param string $label Label of message
59
+ * @param string $message Message content
60
+ * @return void
61
+ */
62
+	public function message($label, $message) {
63
+		FireCake::log($message, $label);
64
+	}
65
+
66
+/**
67
+ * Generate a table with FireCake
68
+ *
69
+ * @param array $rows Rows to print
70
+ * @param array $headers Headers for table
71
+ * @param array $options Additional options and params
72
+ * @return void
73
+ */
74
+	public function table($rows, $headers, $options = array()) {
75
+		$title = $headers[0];
76
+		if (isset($options['title'])) {
77
+			$title = $options['title'];
78
+		}
79
+		foreach ($rows as $i => $row) {
80
+			$rows[$i] = array_values($row);
81
+		}
82
+		array_unshift($rows, $headers);
83
+		FireCake::table($title, $rows);
84
+	}
85
+
86
+/**
87
+ * Start a panel which is a 'Group' in FirePHP
88
+ *
89
+ * @param $title
90
+ * @param $anchor
91
+ * @return void
92
+ */
93
+	public function panelStart($title, $anchor) {
94
+		FireCake::group($title);
95
+	}
96
+
97
+/**
98
+ * End a panel (Group)
99
+ *
100
+ * @return void
101
+ */
102
+	public function panelEnd() {
103
+		FireCake::groupEnd();
104
+	}
105
+
106
+}

+ 238
- 0
Plugin/DebugKit/View/Helper/HtmlToolbarHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('ToolbarHelper', 'DebugKit.View/Helper');
16
+App::uses('Security', 'Utility');
17
+
18
+/**
19
+ * Html Toolbar Helper
20
+ *
21
+ * Injects the toolbar elements into HTML layouts.
22
+ * Contains helper methods for
23
+ *
24
+ * @since         DebugKit 0.1
25
+ */
26
+class HtmlToolbarHelper extends ToolbarHelper {
27
+
28
+/**
29
+ * helpers property
30
+ *
31
+ * @var array
32
+ */
33
+	public $helpers = array('Html', 'Form');
34
+
35
+/**
36
+ * settings property
37
+ *
38
+ * @var array
39
+ */
40
+	public $settings = array('format' => 'html', 'forceEnable' => false);
41
+
42
+/**
43
+ * Recursively goes through an array and makes neat HTML out of it.
44
+ *
45
+ * @param mixed $values Array to make pretty.
46
+ * @param integer $openDepth Depth to add open class
47
+ * @param integer $currentDepth current depth.
48
+ * @param boolean $doubleEncode
49
+ * @return string
50
+ */
51
+	public function makeNeatArray($values, $openDepth = 0, $currentDepth = 0, $doubleEncode = false) {
52
+		static $printedObjects = null;
53
+		if ($currentDepth === 0) {
54
+			$printedObjects = new SplObjectStorage();
55
+		}
56
+		$className = "neat-array depth-$currentDepth";
57
+		if ($openDepth > $currentDepth) {
58
+			$className .= ' expanded';
59
+		}
60
+		$nextDepth = $currentDepth + 1;
61
+		$out = "<ul class=\"$className\">";
62
+		if (!is_array($values)) {
63
+			if (is_bool($values)) {
64
+				$values = array($values);
65
+			}
66
+			if ($values === null) {
67
+				$values = array(null);
68
+			}
69
+		}
70
+		if (empty($values)) {
71
+			$values[] = '(empty)';
72
+		}
73
+		foreach ($values as $key => $value) {
74
+			$out .= '<li><strong>' . h($key, $doubleEncode) . '</strong>';
75
+			if (is_array($value) && count($value) > 0) {
76
+				$out .= '(array)';
77
+			} elseif (is_object($value)) {
78
+				$out .= '(object)';
79
+			}
80
+			if ($value === null) {
81
+				$value = '(null)';
82
+			}
83
+			if ($value === false) {
84
+				$value = '(false)';
85
+			}
86
+			if ($value === true) {
87
+				$value = '(true)';
88
+			}
89
+			if (empty($value) && $value != 0) {
90
+				$value = '(empty)';
91
+			}
92
+			if ($value instanceof Closure) {
93
+				$value = 'function';
94
+			}
95
+
96
+			$isObject = is_object($value);
97
+			if ($isObject && $printedObjects->contains($value)) {
98
+				$isObject = false;
99
+				$value = ' - recursion';
100
+			}
101
+
102
+			if ($isObject) {
103
+				$printedObjects->attach($value);
104
+			}
105
+
106
+			if (
107
+				(
108
+				$value instanceof ArrayAccess ||
109
+				$value instanceof Iterator ||
110
+				is_array($value) ||
111
+				$isObject
112
+				) && !empty($value)
113
+			) {
114
+				$out .= $this->makeNeatArray($value, $openDepth, $nextDepth, $doubleEncode);
115
+			} else {
116
+				$out .= h($value, $doubleEncode);
117
+			}
118
+			$out .= '</li>';
119
+		}
120
+		$out .= '</ul>';
121
+		return $out;
122
+	}
123
+
124
+/**
125
+ * Create an HTML message
126
+ *
127
+ * @param string $label label content
128
+ * @param string $message message content
129
+ * @return string
130
+ */
131
+	public function message($label, $message) {
132
+		return sprintf('<p><strong>%s</strong> %s</p>', $label, $message);
133
+	}
134
+
135
+/**
136
+ * Start a panel.
137
+ * Make a link and anchor.
138
+ *
139
+ * @param $title
140
+ * @param $anchor
141
+ * @return string
142
+ */
143
+	public function panelStart($title, $anchor) {
144
+		$link = $this->Html->link($title, '#' . $anchor);
145
+		return $link;
146
+	}
147
+
148
+/**
149
+ * Create a table.
150
+ *
151
+ * @param array $rows Rows to make.
152
+ * @param array $headers Optional header row.
153
+ * @return string
154
+ */
155
+	public function table($rows, $headers = array()) {
156
+		$out = '<table class="debug-table">';
157
+		if (!empty($headers)) {
158
+			$out .= $this->Html->tableHeaders($headers);
159
+		}
160
+		$out .= $this->Html->tableCells($rows, array('class' => 'odd'), array('class' => 'even'), false, false);
161
+		$out .= '</table>';
162
+		return $out;
163
+	}
164
+
165
+/**
166
+ * Send method
167
+ *
168
+ * @return void
169
+ */
170
+	public function send() {
171
+		if (!$this->settings['forceEnable'] && Configure::read('debug') == 0) {
172
+			return;
173
+		}
174
+		$view = $this->_View;
175
+		$head = '';
176
+		if (isset($view->viewVars['debugToolbarCss']) && !empty($view->viewVars['debugToolbarCss'])) {
177
+			$head .= $this->Html->css($view->viewVars['debugToolbarCss']);
178
+		}
179
+
180
+		$js = sprintf('window.DEBUGKIT_JQUERY_URL = "%s";', $this->webroot('/debug_kit/js/jquery.js'));
181
+		$head .= $this->Html->scriptBlock($js);
182
+
183
+		if (isset($view->viewVars['debugToolbarJavascript'])) {
184
+			foreach ($view->viewVars['debugToolbarJavascript'] as $script) {
185
+				if ($script) {
186
+					$head .= $this->Html->script($script);
187
+				}
188
+			}
189
+		}
190
+		$search = '</head>';
191
+		$pos = strpos($view->output, $search);
192
+		if ($pos !== false) {
193
+			$view->output = substr_replace($view->output, $head . "\n</head>", $pos, strlen($search));
194
+		}
195
+		$toolbar = $view->element('debug_toolbar', array('disableTimer' => true), array('plugin' => 'DebugKit'));
196
+		$search = '</body>';
197
+		$pos = strrpos($view->output, $search);
198
+		if ($pos !== false) {
199
+			$view->output = substr_replace($view->output, $toolbar . "\n</body>", $pos, strlen($search));
200
+		}
201
+	}
202
+
203
+/**
204
+ * Generates a SQL explain link for a given query
205
+ *
206
+ * @param string $sql SQL query string you want an explain link for.
207
+ * @param $connection
208
+ * @return string Rendered Html link or '' if the query is not a select/describe
209
+ */
210
+	public function explainLink($sql, $connection) {
211
+		if (!preg_match('/^[\s()]*SELECT/i', $sql)) {
212
+			return '';
213
+		}
214
+		$sql = str_replace(array("\n", "\t"), ' ', $sql);
215
+		$hash = Security::hash($sql . $connection, 'sha1', true);
216
+		$url = array(
217
+			'plugin' => 'debug_kit',
218
+			'controller' => 'toolbar_access',
219
+			'action' => 'sql_explain'
220
+		);
221
+		foreach (Router::prefixes() as $prefix) {
222
+			$url[$prefix] = false;
223
+		}
224
+		$this->explainLinkUid = (isset($this->explainLinkUid) ? $this->explainLinkUid + 1 : 0);
225
+		$uid = $this->explainLinkUid . '_' . rand(0, 10000);
226
+		$form = $this->Form->create('log', array('url' => $url, 'id' => "logForm{$uid}"));
227
+		$form .= $this->Form->hidden('log.ds', array('id' => "logDs{$uid}", 'value' => $connection));
228
+		$form .= $this->Form->hidden('log.sql', array('id' => "logSql{$uid}", 'value' => $sql));
229
+		$form .= $this->Form->hidden('log.hash', array('id' => "logHash{$uid}", 'value' => $hash));
230
+		$form .= $this->Form->submit(__d('debug_kit', 'Explain'), array(
231
+			'div' => false,
232
+			'class' => 'sql-explain-link'
233
+		));
234
+		$form .= $this->Form->end();
235
+		return $form;
236
+	}
237
+
238
+}

+ 88
- 0
Plugin/DebugKit/View/Helper/SimpleGraphHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 1.0
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('AppHelper', 'View/Helper');
16
+App::uses('HtmlHelper', 'View/Helper');
17
+
18
+/**
19
+ * Class SimpleGraphHelper
20
+ *
21
+ * Allows creation and display of extremely simple graphing elements
22
+ *
23
+ * @since         DebugKit 1.0
24
+ */
25
+class SimpleGraphHelper extends AppHelper {
26
+
27
+/**
28
+ * Helpers
29
+ *
30
+ * @var array
31
+ */
32
+	public $helpers = array('Html');
33
+
34
+/**
35
+ * Default settings to be applied to each Simple Graph
36
+ *
37
+ * Allowed options:
38
+ *
39
+ * - max => (int) Maximum value in the graphs
40
+ * - width => (int)
41
+ * - valueType => string (value, percentage)
42
+ * - style => array
43
+ *
44
+ * @var array
45
+ */
46
+	protected $_defaultSettings = array(
47
+		'max' => 100,
48
+		'width' => 350,
49
+		'valueType' => 'value',
50
+	);
51
+
52
+/**
53
+ * bar method
54
+ *
55
+ * @param $value Value to be graphed
56
+ * @param $offset how much indentation
57
+ * @param array|\Graph $options Graph options
58
+ * @return string Html graph
59
+ */
60
+	public function bar($value, $offset, $options = array()) {
61
+		$settings = array_merge($this->_defaultSettings, $options);
62
+		extract($settings);
63
+
64
+		$graphValue = ($value / $max) * $width;
65
+		$graphValue = max(round($graphValue), 1);
66
+
67
+		if ($valueType === 'percentage') {
68
+			$graphOffset = 0;
69
+		} else {
70
+			$graphOffset = ($offset / $max) * $width;
71
+			$graphOffset = round($graphOffset);
72
+		}
73
+		return $this->Html->div(
74
+			'debug-kit-graph-bar',
75
+				$this->Html->div(
76
+					'debug-kit-graph-bar-value',
77
+					' ',
78
+					array(
79
+						'style' => "margin-left: {$graphOffset}px; width: {$graphValue}px",
80
+						'title' => __d('debug_kit', "Starting %sms into the request, taking %sms", $offset, $value),
81
+					)
82
+				),
83
+			array('style' => "width: {$width}px;"),
84
+			false
85
+		);
86
+	}
87
+
88
+}

+ 171
- 0
Plugin/DebugKit/View/Helper/TidyHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4
+ *
5
+ * Licensed under The MIT License
6
+ * Redistributions of files must retain the above copyright notice.
7
+ *
8
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ * @link          http://cakephp.org CakePHP(tm) Project
10
+ * @since         v 1.0 (22-Jun-2009)
11
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
+ */
13
+
14
+App::uses('File', 'Utility');
15
+
16
+/**
17
+ * TidyHelper class
18
+ *
19
+ * Passes html through tidy on the command line, and reports markup errors
20
+ *
21
+ * @uses          AppHelper
22
+ * @since         v 1.0 (22-Jun-2009)
23
+ */
24
+class TidyHelper extends AppHelper {
25
+
26
+/**
27
+ * helpers property
28
+ *
29
+ * @var array
30
+ */
31
+	public $helpers = array('DebugKit.Toolbar');
32
+
33
+/**
34
+ * results property
35
+ *
36
+ * @var mixed null
37
+ */
38
+	public $results = null;
39
+
40
+/**
41
+ * Return a nested array of errors for the passed html string
42
+ * Fudge the markup slightly so that the tag which is invalid is highlighted
43
+ *
44
+ * @param string $html ''
45
+ * @param string $out ''
46
+ * @return array
47
+ */
48
+	public function process($html = '', &$out = '') {
49
+		$errors = $this->tidyErrors($html, $out);
50
+
51
+		if (!$errors) {
52
+			return array();
53
+		}
54
+		$result = array('Error' => array(), 'Warning' => array(), 'Misc' => array());
55
+		$errors = explode("\n", $errors);
56
+		$markup = explode("\n", $out);
57
+		foreach ($errors as $error) {
58
+			preg_match('@line (\d+) column (\d+) - (\w+): (.*)@', $error, $matches);
59
+			if ($matches) {
60
+				list($original, $line, $column, $type, $message) = $matches;
61
+				$line = $line - 1;
62
+
63
+				$string = '</strong>';
64
+				if (isset($markup[$line - 1])) {
65
+					$string .= h($markup[$line - 1]);
66
+				}
67
+				$string .= '<strong>' . h(@$markup[$line]) . '</strong>';
68
+				if (isset($markup[$line + 1])) {
69
+					$string .= h($markup[$line + 1]);
70
+				}
71
+				$string .= '</strong>';
72
+
73
+				$result[$type][$string][] = h($message);
74
+			} elseif ($error) {
75
+				$message = $error;
76
+				$result['Misc'][h($message)][] = h($message);
77
+			}
78
+		}
79
+		$this->results = $result;
80
+		return $result;
81
+	}
82
+
83
+/**
84
+ * report method
85
+ *
86
+ * Call process if a string is passed, or no prior results exist - and return the results using
87
+ * the toolbar helper to generate a nested navigatable array
88
+ *
89
+ * @param mixed $html null
90
+ * @return string
91
+ */
92
+	public function report($html = null) {
93
+		if ($html) {
94
+			$this->process($html);
95
+		} elseif ($this->results === null) {
96
+			$this->process($this->_View->output);
97
+		}
98
+		if (!$this->results) {
99
+			return '<p>' . __d('debug_kit', 'No markup errors found') . '</p>';
100
+		}
101
+		foreach ($this->results as &$results) {
102
+			foreach ($results as $type => &$messages) {
103
+				foreach ($messages as &$message) {
104
+					$message = html_entity_decode($message, ENT_COMPAT, Configure::read('App.encoding'));
105
+				}
106
+			}
107
+		}
108
+		return $this->Toolbar->makeNeatArray(array_filter($this->results), 0, 0, false);
109
+	}
110
+
111
+/**
112
+ * Run the html string through tidy, and return the (raw) errors. pass back a reference to the
113
+ * normalized string so that the error messages can be linked to the line that caused them.
114
+ *
115
+ * @param string $in ''
116
+ * @param string $out ''
117
+ * @return string
118
+ */
119
+	public function tidyErrors($in = '', &$out = '') {
120
+		$out = preg_replace('@>\s*<@s', ">\n<", $in);
121
+
122
+		// direct access? windows etc
123
+		if (function_exists('tidy_parse_string')) {
124
+			$tidy = tidy_parse_string($out, array(), 'UTF8');
125
+			$tidy->cleanRepair();
126
+			$errors = $tidy->errorBuffer . "\n";
127
+			return $errors;
128
+		}
129
+
130
+		// cli
131
+		$File = new File(rtrim(TMP, DS) . DS . rand() . '.html', true);
132
+		$File->write($out);
133
+		$path = $File->pwd();
134
+		$errors = $path . '.err';
135
+		$this->_exec("tidy -eq -utf8 -f $errors $path");
136
+		$File->delete();
137
+
138
+		if (!file_exists($errors)) {
139
+			return '';
140
+		}
141
+		$Error = new File($errors);
142
+		$errors = $Error->read();
143
+		$Error->delete();
144
+		return $errors;
145
+	}
146
+
147
+/**
148
+ * exec method
149
+ *
150
+ * @param mixed $cmd
151
+ * @param mixed $out null
152
+ * @return boolean True if successful
153
+ */
154
+	protected function _exec($cmd, &$out = null) {
155
+		if (DS === '/') {
156
+			$_out = exec($cmd . ' 2>&1', $out, $return);
157
+		} else {
158
+			$_out = exec($cmd, $out, $return);
159
+		}
160
+
161
+		if (Configure::read('debug')) {
162
+			$source = Debugger::trace(array('depth' => 1, 'start' => 2)) . "\n";
163
+			//CakeLog::write('system_calls_' . date('Y-m-d'), "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
164
+			//CakeLog::write('system_calls', "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
165
+		}
166
+		if ($return) {
167
+			return false;
168
+		}
169
+		return $_out ? $_out : true;
170
+	}
171
+}

+ 226
- 0
Plugin/DebugKit/View/Helper/ToolbarHelper.php 파일 보기

1
+<?php
2
+/**
3
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
4
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
5
+ *
6
+ * Licensed under The MIT License
7
+ * Redistributions of files must retain the above copyright notice.
8
+ *
9
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
10
+ * @link          http://cakephp.org CakePHP(tm) Project
11
+ * @since         DebugKit 0.1
12
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
13
+ */
14
+
15
+App::uses('DebugKitDebugger', 'DebugKit.Lib');
16
+App::uses('AppHelper', 'View/Helper');
17
+App::uses('ConnectionManager', 'Model');
18
+
19
+/**
20
+ * Provides Base methods for content specific debug toolbar helpers.
21
+ * Acts as a facade for other toolbars helpers as well.
22
+ *
23
+ * @since         DebugKit 0.1
24
+ */
25
+class ToolbarHelper extends AppHelper {
26
+
27
+/**
28
+ * settings property to be overloaded. Subclasses should specify a format
29
+ *
30
+ * @var array
31
+ */
32
+	public $settings = array();
33
+
34
+/**
35
+ * flag for whether or not cache is enabled.
36
+ *
37
+ * @var boolean
38
+ */
39
+	protected $_cacheEnabled = false;
40
+
41
+/**
42
+ * Construct the helper and make the backend helper.
43
+ *
44
+ * @param $View
45
+ * @param array|string $options
46
+ * @return \ToolbarHelper
47
+ */
48
+	public function __construct($View, $options = array()) {
49
+		$this->_myName = strtolower(get_class($this));
50
+		$this->settings = array_merge($this->settings, $options);
51
+
52
+		if ($this->_myName !== 'toolbarhelper') {
53
+			parent::__construct($View, $options);
54
+			return;
55
+		}
56
+
57
+		if (!isset($options['output'])) {
58
+			$options['output'] = 'DebugKit.HtmlToolbar';
59
+		}
60
+		$className = $options['output'];
61
+		if (strpos($options['output'], '.') !== false) {
62
+			list($plugin, $className) = explode('.', $options['output']);
63
+		}
64
+		$this->_backEndClassName = $className;
65
+		$this->helpers[$options['output']] = $options;
66
+		if (isset($options['cacheKey']) && isset($options['cacheConfig'])) {
67
+			$this->_cacheKey = $options['cacheKey'];
68
+			$this->_cacheConfig = $options['cacheConfig'];
69
+			$this->_cacheEnabled = true;
70
+		}
71
+
72
+		parent::__construct($View, $options);
73
+	}
74
+
75
+/**
76
+ * afterLayout callback
77
+ *
78
+ * @param string $layoutFile
79
+ * @return void
80
+ */
81
+	public function afterLayout($layoutFile) {
82
+		if (!$this->request->is('requested')) {
83
+			$this->send();
84
+		}
85
+	}
86
+
87
+/**
88
+ * Get the name of the backend Helper
89
+ * used to conditionally trigger toolbar output
90
+ *
91
+ * @return string
92
+ */
93
+	public function getName() {
94
+		return $this->_backEndClassName;
95
+	}
96
+
97
+/**
98
+ * call__
99
+ *
100
+ * Allows method calls on backend helper
101
+ *
102
+ * @param string $method
103
+ * @param mixed $params
104
+ * @return mixed|void
105
+ */
106
+	public function __call($method, $params) {
107
+		if (method_exists($this->{$this->_backEndClassName}, $method)) {
108
+			return $this->{$this->_backEndClassName}->dispatchMethod($method, $params);
109
+		}
110
+	}
111
+
112
+/**
113
+ * Allows for writing to panel cache from view.
114
+ * Some panels generate all variables in the view by
115
+ * necessity ie. Timer. Using this method, will allow you to replace in full
116
+ * the content for a panel.
117
+ *
118
+ * @param string $name Name of the panel you are replacing.
119
+ * @param string $content Content to write to the panel.
120
+ * @return boolean Success of write.
121
+ */
122
+	public function writeCache($name, $content) {
123
+		if (!$this->_cacheEnabled) {
124
+			return false;
125
+		}
126
+		$existing = (array)Cache::read($this->_cacheKey, $this->_cacheConfig);
127
+		$existing[0][$name]['content'] = $content;
128
+		return Cache::write($this->_cacheKey, $existing, $this->_cacheConfig);
129
+	}
130
+
131
+/**
132
+ * Read the toolbar
133
+ *
134
+ * @param string $name Name of the panel you want cached data for
135
+ * @param integer $index
136
+ * @return mixed Boolean false on failure, array of data otherwise.
137
+ */
138
+	public function readCache($name, $index = 0) {
139
+		if (!$this->_cacheEnabled) {
140
+			return false;
141
+		}
142
+		$existing = (array)Cache::read($this->_cacheKey, $this->_cacheConfig);
143
+		if (!isset($existing[$index][$name]['content'])) {
144
+			return false;
145
+		}
146
+		return $existing[$index][$name]['content'];
147
+	}
148
+
149
+/**
150
+ * Gets the query logs for the given connection names.
151
+ *
152
+ * ### Options
153
+ *
154
+ * - explain - Whether explain links should be generated for this connection.
155
+ * - cache - Whether the toolbar_state Cache should be updated.
156
+ * - threshold - The threshold at which a visual 'maybe slow' flag should be added.
157
+ *   results with rows/ms lower than $threshold will be marked.
158
+ *
159
+ * @param string $connection Connection name to get logs for.
160
+ * @param array $options Options for the query log retrieval.
161
+ * @return array Array of data to be converted into a table.
162
+ */
163
+	public function getQueryLogs($connection, $options = array()) {
164
+		$options += array('explain' => false, 'cache' => true, 'threshold' => 20);
165
+		$db = ConnectionManager::getDataSource($connection);
166
+
167
+		if (!method_exists($db, 'getLog')) {
168
+			return array();
169
+		}
170
+
171
+		$log = $db->getLog();
172
+
173
+		$out = array(
174
+			'queries' => array(),
175
+			'count' => $log['count'],
176
+			'time' => $log['time']
177
+		);
178
+		foreach ($log['log'] as $i => $query) {
179
+			$query += array('query' => null);
180
+			$isSlow = (
181
+				$query['took'] > 0 &&
182
+				$query['numRows'] / $query['took'] != 1 &&
183
+				$query['numRows'] / $query['took'] <= $options['threshold']
184
+			);
185
+			$query['actions'] = '';
186
+			$isHtml = ($this->getName() === 'HtmlToolbar');
187
+			if ($isSlow && $isHtml) {
188
+				$query['actions'] = sprintf(
189
+					'<span class="slow-query">%s</span>',
190
+					__d('debug_kit', 'maybe slow')
191
+				);
192
+			} elseif ($isSlow) {
193
+				$query['actions'] = '*';
194
+			}
195
+			if ($options['explain'] && $isHtml) {
196
+				$query['actions'] .= $this->explainLink($query['query'], $connection);
197
+			}
198
+			if ($isHtml) {
199
+				$query['query'] = h($query['query']);
200
+				if (!empty($query['params']) && is_array($query['params'])) {
201
+					$bindParam = $bindType = null;
202
+					if (preg_match('/.+ :.+/', $query['query'])) {
203
+						$bindType = true;
204
+					}
205
+					foreach ($query['params'] as $bindKey => $bindVal) {
206
+						if ($bindType === true) {
207
+							$bindParam .= h($bindKey) . " => " . h($bindVal) . ", ";
208
+						} else {
209
+							$bindParam .= h($bindVal) . ", ";
210
+						}
211
+					}
212
+					$query['query'] .= " [ " . rtrim($bindParam, ', ') . " ]";
213
+				}
214
+			}
215
+			unset($query['params']);
216
+			$out['queries'][] = $query;
217
+		}
218
+		if ($options['cache']) {
219
+			$existing = $this->readCache('sql_log');
220
+			$existing[$connection] = $out;
221
+			$this->writeCache('sql_log', $existing);
222
+		}
223
+		return $out;
224
+	}
225
+
226
+}

+ 30
- 0
Plugin/DebugKit/View/ToolbarAccess/history_state.ctp 파일 보기

1
+<?php
2
+/**
3
+ * Toolbar history state view.
4
+ *
5
+ * PHP 5
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @since         DebugKit 1.0
16
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
+ */
18
+
19
+$panels = array();
20
+foreach ($toolbarState as $panelName => $panel) {
21
+	if (!empty($panel) && !empty($panel['elementName'])) {
22
+		$panels[$panelName] = $this->element($panel['elementName'], array(
23
+			'content' => $panel['content']
24
+		), array(
25
+			'plugin' => Inflector::camelize($panel['plugin'])
26
+		));
27
+	}
28
+}
29
+echo json_encode($panels);
30
+Configure::write('debug', 0);

+ 11
- 0
Plugin/DebugKit/View/ToolbarAccess/sql_explain.ctp 파일 보기

1
+<table class="sql-log-query-explain debug-table">
2
+<?php
3
+$headers = array_shift($result);
4
+
5
+echo $this->Html->tableHeaders($headers);
6
+echo $this->Html->tableCells($result);
7
+?>
8
+</table>
9
+<?php
10
+// Consume and toss out the timers
11
+$timers = DebugKitDebugger::getTimers(true);

+ 35
- 0
Plugin/DebugKit/composer.json 파일 보기

1
+{
2
+    "name": "cakephp/debug_kit",
3
+    "description": "CakePHP Debug Kit",
4
+    "type": "cakephp-plugin",
5
+    "keywords": ["cakephp", "debug", "kit"],
6
+    "homepage": "https://github.com/cakephp/debug_kit",
7
+    "license": "MIT",
8
+    "authors": [
9
+        {
10
+            "name": "Mark Story",
11
+            "homepage": "http://mark-story.com",
12
+            "role": "Author"
13
+        },
14
+        {
15
+            "name": "CakePHP Community",
16
+            "homepage": "https://github.com/cakephp/debug_kit/graphs/contributors"
17
+        }
18
+    ],
19
+    "support": {
20
+        "issues": "https://github.com/cakephp/debug_kit/issues",
21
+        "forum": "http://stackoverflow.com/tags/cakephp",
22
+        "irc": "irc://irc.freenode.org/cakephp",
23
+        "source": "https://github.com/cakephp/debug_kit"
24
+    },
25
+    "require": {
26
+        "php": ">=5.3.0",
27
+        "composer/installers": "*"
28
+    },
29
+    "extra": {
30
+        "branch-alias": {
31
+            "dev-master": "2.2.x-dev"
32
+        },
33
+        "installer-name": "DebugKit"
34
+    }
35
+}

+ 382
- 0
Plugin/DebugKit/webroot/css/debug_toolbar.css 파일 보기

1
+/* @override http://localhost/mark_story/site/debug_kit/css/debug_toolbar.css */
2
+#debug-kit-toolbar {
3
+	position: fixed;
4
+	top: 0;
5
+	right:0px;
6
+	width: 100%;
7
+	height: 1%;
8
+	overflow: visible;
9
+	z-index:10000;
10
+	font-family: helvetica, arial, sans-serif;
11
+	font-size: 12px;
12
+	direction: ltr;
13
+}
14
+#debug-kit-toolbar img {
15
+	border:0;
16
+	outline:0;
17
+}
18
+
19
+/* panel tabs */
20
+#debug-kit-toolbar #panel-tabs {
21
+	float: right;
22
+	list-style: none;
23
+	margin: 0;
24
+	padding: 0;
25
+	box-shadow: 0 5px 6px rgba(0, 0, 0, 0.5);
26
+	border-radius: 8px 0 0 8px;
27
+}
28
+#debug-kit-toolbar .panel-tab {
29
+	clear: none;
30
+	float: left;
31
+	margin: 0;
32
+	padding: 0;
33
+	list-style: none;
34
+}
35
+#debug-kit-toolbar .panel-tab > a {
36
+	float: left;
37
+	clear: none;
38
+	background: #efefef;
39
+	background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#cacaca));
40
+	background: -moz-linear-gradient(top, #efefef, #cacaca);
41
+	color: #222;
42
+	padding: 6px;
43
+	border-right: 1px solid #ccc;
44
+	border-bottom: 1px solid #aaa;
45
+	font-size: 12px;
46
+	line-height: 16px;
47
+	margin: 0;
48
+	display: block;
49
+	text-decoration:none;
50
+	text-shadow:1px 1px #eee;
51
+	-moz-text-shadow:1px 1px #eee;
52
+	-webkit-text-shadow:1px 1px #eee;
53
+}
54
+#debug-kit-toolbar .panel-tab .active {
55
+	background: #fff;
56
+	background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#fff));
57
+	background: -moz-linear-gradient(top, #f5f5f5, #fff);
58
+}
59
+#debug-kit-toolbar .panel-tab > a:hover {
60
+	background: #fff;
61
+	background: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#fff));
62
+	background: -moz-linear-gradient(top, #f5f5f5, #fff);
63
+	text-decoration:underline;
64
+}
65
+#debug-kit-toolbar .panel-tab.icon a {
66
+	padding: 4px;
67
+}
68
+#debug-kit-toolbar .panel-tab a.edit-value {
69
+	float: none;
70
+	display: inline;
71
+}
72
+
73
+#debug-kit-toolbar .panel-tab.icon a {
74
+	border-radius: 8px 0 0 8px;
75
+}
76
+#debug-kit-toolbar .panel-tab.icon img {
77
+	display:block;
78
+}
79
+
80
+/* panel content */
81
+#debug-kit-toolbar .panel-content {
82
+	position: absolute;
83
+	text-align: left;
84
+	width: auto;
85
+	top:28px;
86
+	right:0px;
87
+	background: #fff;
88
+	color: #000;
89
+	width:100%;
90
+	box-shadow:0px 5px 6px rgba(0, 0, 0, 0.5);
91
+	height: 200px;
92
+	overflow: hidden;
93
+}
94
+
95
+#debug-kit-toolbar .panel-resize-region {
96
+	padding:15px;
97
+	position: absolute;
98
+	top: 0;
99
+	bottom: 14px;
100
+	left: 0;
101
+	right: 0;
102
+	overflow: auto;
103
+}
104
+
105
+#debug-kit-toolbar .ui-control {
106
+	background:#ccc;
107
+	background: -webkit-gradient(linear, left top, left bottom, from(#d6d6d6), to(#c2c2c2));
108
+	background: -moz-linear-gradient(top, #d6d6d6, #c2c2c2);
109
+	text-align:center;
110
+	border-top:1px solid #afafaf;
111
+	border-bottom:1px solid #7c7c7c;
112
+	color:#666;
113
+	text-shadow: 1px 1px #eee;
114
+	-webkit-text-shadow: 1px 1px #eee;
115
+	-moz-text-shadow: 1px 1px #eee;
116
+}
117
+#debug-kit-toolbar .ui-button {
118
+	border-radius: 5px;
119
+}
120
+#debug-kit-toolbar .ui-button:hover {
121
+	text-decoration: none;
122
+	background:#ccc;
123
+	background: -webkit-gradient(linear, left top, left bottom, from(#c2c2c2), to(#d6d6d6));
124
+	background: -moz-linear-gradient(top, #c2c2c2, #d6d6d6);
125
+}
126
+#debug-kit-toolbar .panel-resize-handle {
127
+	cursor: row-resize;
128
+	height:14px;
129
+	line-height: 14px;
130
+	position: absolute;
131
+	bottom: 0;
132
+	left: 0;
133
+	right: 0;
134
+}
135
+#debug-kit-toolbar .panel-toggle {
136
+	float: right;
137
+	display: block;
138
+	width: 16px;
139
+	height: 16px;
140
+	font-size: 16px;
141
+	line-height: 14px;
142
+	border-left: 1px solid #afafaf;
143
+	border-right: 1px solid #7c7c7c;
144
+	text-decoration: none;
145
+	margin: 10px 20px 0 0;
146
+	z-index: 999;
147
+	position: relative;
148
+}
149
+
150
+/* Hide panel content by default */
151
+#debug-kit-toolbar .panel-content {
152
+	display: none;
153
+}
154
+#debug-kit-toolbar .panel-content p {
155
+	margin: 1em 0;
156
+}
157
+#debug-kit-toolbar .panel-content h2 {
158
+	padding: 0;
159
+	margin-top:0;
160
+}
161
+#debug-kit-toolbar .panel-content h3 {
162
+	padding: 0;
163
+	margin-top: 1em;
164
+}
165
+#debug-kit-toolbar .panel-content .info {
166
+	padding: 4px;
167
+	border-top: 1px dashed #6c6cff;
168
+	border-bottom: 1px dashed #6c6cff;
169
+}
170
+#debug-kit-toolbar h1,
171
+#debug-kit-toolbar h2,
172
+#debug-kit-toolbar h3,
173
+#debug-kit-toolbar h4,
174
+#debug-kit-toolbar h5,
175
+#debug-kit-toolbar th {
176
+	color: #5d1717;
177
+	font-family: Arial, sans-serif;
178
+	margin-bottom:0.6em;
179
+	background:none;
180
+}
181
+#debug-kit-toolbar h1 {
182
+	font-size: 18px;
183
+}
184
+#debug-kit-toolbar h2 {
185
+	font-size: 16px;
186
+}
187
+#debug-kit-toolbar h4 {
188
+	font-size: 14px;
189
+}
190
+
191
+
192
+/* panel tables */
193
+#debug-kit-toolbar .debug-table {
194
+	width: 100%;
195
+	border: 1px solid #eee;
196
+	border-left: 0;
197
+	clear:both;
198
+	margin-bottom: 20px;
199
+	border-spacing: 0;
200
+}
201
+#debug-kit-toolbar .debug-table td,
202
+#debug-kit-toolbar .debug-table th {
203
+	text-align: left;
204
+	border: 0;
205
+	border-left: 1px solid #eee;
206
+	padding: 3px;
207
+	margin: 0;
208
+}
209
+#debug-kit-toolbar table.debug-table th {
210
+	border-bottom: 1px solid #bbb;
211
+	border-left: 1px solid #bbb;
212
+	background: -webkit-linear-gradient(top, #d4d4d4, #c1c1c1);
213
+	background: -moz-linear-gradient(top, #d4d4d4, #c1c1c1);
214
+	color: #222;
215
+	font-weight: bold;
216
+	line-height: 16px;
217
+}
218
+#debug-kit-toolbar .debug-table tr:nth-child(2n) td {
219
+	background: #f6f6f6;
220
+}
221
+#debug-kit-toolbar .debug-timers .debug-table td:nth-child(2),
222
+#debug-kit-toolbar .debug-timers .debug-table th:nth-child(2) {
223
+	text-align:right;
224
+}
225
+
226
+/** code tables **/
227
+#debug-kit-toolbar .code-table td {
228
+	white-space: pre;
229
+	font-family: monaco, Consolas, "courier new", courier, monospaced;
230
+}
231
+#debug-kit-toolbar .code-table td:first-child {
232
+	width: 15%;
233
+}
234
+#debug-kit-toolbar .code-table td:last-child {
235
+	width: 80%;
236
+}
237
+#debug-kit-toolbar .panel-content.request {
238
+	display: block;
239
+}
240
+
241
+/** Neat Array styles **/
242
+#debug-kit-toolbar .neat-array,
243
+#debug-kit-toolbar .neat-array li {
244
+	list-style:none;
245
+	list-style-image:none;
246
+}
247
+#debug-kit-toolbar .neat-array {
248
+	padding: 1px 2px 1px 20px;
249
+	background: #CE9E23;
250
+	list-style: none;
251
+	margin: 0 0 1em 0;
252
+}
253
+#debug-kit-toolbar .neat-array .neat-array {
254
+	padding: 0 0 0 20px;
255
+	margin: 0;
256
+	border-top:1px solid #CE9E23;
257
+}
258
+#debug-kit-toolbar .neat-array li {
259
+	background: #FEF6E5;
260
+	border-top: 1px solid #CE9E23;
261
+	border-bottom: 1px solid #CE9E23;
262
+	margin: 0;
263
+	line-height: 1.5em;
264
+}
265
+#debug-kit-toolbar .neat-array li:hover {
266
+	background: #fff;
267
+}
268
+#debug-kit-toolbar .neat-array li strong {
269
+	padding: 0 8px;
270
+	font-weight: bold;
271
+}
272
+
273
+
274
+/* expandable sections */
275
+#debug-kit-toolbar .neat-array li.expandable {
276
+	cursor: pointer;
277
+}
278
+#debug-kit-toolbar .neat-array .expanded {
279
+	border-bottom:0;
280
+}
281
+#debug-kit-toolbar .neat-array li.expandable.expanded > strong:before {
282
+	content: 'v ';
283
+}
284
+#debug-kit-toolbar .neat-array li.expandable.collapsed > strong:before,
285
+#debug-kit-toolbar .neat-array li.expandable.expanded .expandable.collapsed > strong:before {
286
+	content: '> ';
287
+}
288
+#debug-kit-toolbar .neat-array li {
289
+	cursor: default;
290
+}
291
+
292
+#debug-kit-toolbar .debug-kit-graph-bar,
293
+#debug-kit-toolbar .debug-kit-graph-bar-value {
294
+	margin: 0;
295
+	padding: 0;
296
+	border: none;
297
+	overflow: hidden;
298
+	height: 10px;
299
+}
300
+#debug-kit-toolbar .debug-kit-graph-bar {
301
+	background: #ddd;
302
+	padding: 2px;
303
+	border-radius: 2px;
304
+	height: 12px;
305
+}
306
+#debug-kit-toolbar .debug-kit-graph-bar-value {
307
+	background: -webkit-linear-gradient(top, #77D124, #4B9406);
308
+	background: -moz-linear-gradient(top, #77D124, #4B9406);
309
+	border-radius: 3px;
310
+	border: 1px solid #4B9406;
311
+}
312
+
313
+/* Sql Log */
314
+#sqllog-tab td,
315
+#sqllog-tab .slow-query-container p {
316
+	font-family: Monaco, 'Consolas', "Courier New", Courier, monospaced;
317
+}
318
+#debug-kit-toolbar #sqllog-tab a.show-slow {
319
+	display:block;
320
+	margin: 3px;
321
+	float:none;
322
+}
323
+#sqllog-tab .slow-query-container p {
324
+	display:block;
325
+	clear:both;
326
+	margin: 20px 0 5px;
327
+}
328
+#debug-kit-toolbar #sqllog-tab .panel-content-data a {
329
+	background: none;
330
+	border:none;
331
+}
332
+#sqllog-tab .slow-query {
333
+	background:#e79302;
334
+	font-size:9px;
335
+	color:#fff;
336
+	padding: 2px;
337
+	white-space:nowrap;
338
+}
339
+#sqllog-tab input[type=submit] {
340
+	border: 0;
341
+	background: transparent;
342
+	cursor: pointer;
343
+	font-size: 12px;
344
+	font-family: Monaco, 'Consolas', "Courier New", Courier, monospaced;
345
+}
346
+#sqllog-tab input[type=submit]:hover {
347
+	color: darkred;
348
+}
349
+#debug-kit-toolbar .alert-duplicate {
350
+	color: red;
351
+}
352
+
353
+/* previous panels */
354
+#debug-kit-toolbar .panel-history {
355
+	display: none;
356
+	background:#eeffff;
357
+}
358
+#debug-kit-toolbar #history-tab ul {
359
+	margin: 20px 0 0 20px;
360
+}
361
+#debug-kit-toolbar #history-tab li {
362
+	margin: 0 0 5px 0;
363
+}
364
+#debug-kit-toolbar #history-tab .panel-content-data a {
365
+	float: none;
366
+	display:block;
367
+}
368
+#debug-kit-toolbar #history-tab a.active {
369
+	background: #FEF6E5;
370
+}
371
+#debug-kit-toolbar #history-tab a.loading:after {
372
+	content : ' Loading...';
373
+	font-style:italic;
374
+}
375
+
376
+/* Minimized mode */
377
+#debug-kit-toolbar.minimized {
378
+	opacity: 0.75;
379
+}
380
+#debug-kit-toolbar.minimized:hover {
381
+	opacity: inherit;
382
+}

BIN
Plugin/DebugKit/webroot/img/cake.icon.png 파일 보기


+ 4
- 0
Plugin/DebugKit/webroot/js/jquery.js
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 936
- 0
Plugin/DebugKit/webroot/js/js_debug_toolbar.js 파일 보기

1
+/**
2
+ * Debug Toolbar Javascript.
3
+ *
4
+ * Creates the DEBUGKIT namespace and provides methods for extending
5
+ * and enhancing the Html toolbar. Includes library agnostic Event, Element,
6
+ * Cookie and Request wrappers.
7
+ *
8
+ *
9
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
11
+ *
12
+ * Licensed under The MIT License
13
+ * Redistributions of files must retain the above copyright notice.
14
+ *
15
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
16
+ * @link          http://cakephp.org CakePHP(tm) Project
17
+ * @since         DebugKit 0.1
18
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
+ */
20
+
21
+/* jshint jquery: true */
22
+
23
+var DEBUGKIT = function () {
24
+	var undef;
25
+	return {
26
+		module: function (newmodule) {
27
+			if (this[newmodule] === undef) {
28
+				this[newmodule] = {};
29
+				return this[newmodule];
30
+			}
31
+			return this[newmodule];
32
+		}
33
+	};
34
+}();
35
+
36
+(function () {
37
+	function versionGTE(a, b) {
38
+		var len = Math.min(a.length, b.length);
39
+		for (var i = 0; i < len; i++) {
40
+			a[i] = parseInt(a[i], 10);
41
+			b[i] = parseInt(b[i], 10);
42
+			if (a[i] > b[i]) {
43
+				return true;
44
+			}
45
+			if (a[i] < b[i]) {
46
+				return false;
47
+			}
48
+		}
49
+		return true;
50
+	}
51
+
52
+	function versionWithin(version, min, max) {
53
+		version = version.split('.');
54
+		min = min.split('.');
55
+		max = max.split('.');
56
+		return versionGTE(version, min) && versionGTE(max, version);
57
+	}
58
+
59
+	function initOnReady() {
60
+		DEBUGKIT.$(document).ready(function () {
61
+			DEBUGKIT.registerModules(DEBUGKIT.$);
62
+			DEBUGKIT.loader.init();
63
+		});
64
+	}
65
+
66
+	// Push checking for jQuery at the end of the stack.
67
+	// This will catch JS included at the bottom of a page.
68
+	setTimeout(function() {
69
+		// Look for existing jQuery that matches the requirements.
70
+		if (window.jQuery && versionWithin(jQuery.fn.jquery, "1.8", "2.1")) {
71
+			DEBUGKIT.$ = window.jQuery;
72
+			initOnReady();
73
+		} else {
74
+			var req = new XMLHttpRequest();
75
+			req.onload = function () {
76
+				eval(this.responseText);
77
+				// Restore both $ and jQuery to the original values.
78
+				DEBUGKIT.$ = jQuery.noConflict(true);
79
+				initOnReady();
80
+			};
81
+			req.open('get', window.DEBUGKIT_JQUERY_URL, true);
82
+			req.send();
83
+		}
84
+	}, 0);
85
+})();
86
+
87
+DEBUGKIT.loader = function () {
88
+	return {
89
+		// List of methods to run on startup.
90
+		_startup: [],
91
+
92
+		// Register a new method to be run on dom ready.
93
+		register: function (method) {
94
+			this._startup.push(method);
95
+		},
96
+
97
+		init: function () {
98
+			for (var i = 0, callback; callback = this._startup[i]; i++) {
99
+				callback.init();
100
+			}
101
+		}
102
+	};
103
+}();
104
+
105
+
106
+DEBUGKIT.registerModules = function($) {
107
+
108
+
109
+DEBUGKIT.module('sqlLog');
110
+DEBUGKIT.sqlLog = function () {
111
+
112
+	return {
113
+		init : function () {
114
+			var sqlPanel = $('#sql_log-tab');
115
+			var buttons = sqlPanel.find('input');
116
+
117
+			// Button handling code for explain links.
118
+			// Performs XHR request to get explain query.
119
+			var handleButton = function (event) {
120
+				event.preventDefault();
121
+				var form = $(this.form),
122
+					data = form.serialize(),
123
+					dbName = form.find('input[name*=ds]').val() || 'default';
124
+
125
+				var fetch = $.ajax({
126
+					url: this.form.action,
127
+					data: data,
128
+					type: 'POST',
129
+					success : function (response) {
130
+						$('#sql-log-explain-' + dbName).html(response);
131
+					},
132
+					error : function () {
133
+						alert('Could not fetch EXPLAIN for query.');
134
+					}
135
+				});
136
+			};
137
+
138
+			buttons.filter('.sql-explain-link').on('click', handleButton);
139
+		}
140
+	};
141
+}();
142
+DEBUGKIT.loader.register(DEBUGKIT.sqlLog);
143
+
144
+//
145
+// NOTE DEBUGKIT.Util.Element is Deprecated.
146
+//
147
+// Util module and Element utility class.
148
+DEBUGKIT.module('Util');
149
+DEBUGKIT.Util.Element = {
150
+
151
+	// Test if an element is a name node.
152
+	nodeName: function (element, name) {
153
+		return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();
154
+	},
155
+
156
+	// Return a boolean if the element has the classname
157
+	hasClass: function (element, className) {
158
+		if (!element.className) {
159
+			return false;
160
+		}
161
+		return element.className.indexOf(className) > -1;
162
+	},
163
+
164
+	addClass: function (element, className) {
165
+		if (!element.className) {
166
+			element.className = className;
167
+			return;
168
+		}
169
+		element.className = element.className.replace(/^(.*)$/, '$1 ' + className);
170
+	},
171
+
172
+	removeClass: function (element, className) {
173
+		if (DEBUGKIT.Util.isArray(element)) {
174
+			DEBUGKIT.Util.Collection.apply(element, function (element) {
175
+				DEBUGKIT.Util.Element.removeClass(element, className);
176
+			});
177
+		}
178
+		if (!element.className) {
179
+			return false;
180
+		}
181
+		element.className = element.className.replace(new RegExp(' ?(' + className + ') ?'), '');
182
+	},
183
+
184
+	swapClass: function (element, removeClass, addClass) {
185
+		if (!element.className) {
186
+			return false;
187
+		}
188
+		element.className = element.className.replace(removeClass, addClass);
189
+	},
190
+
191
+	show: function (element) {
192
+		element.style.display = 'block';
193
+	},
194
+
195
+	hide: function (element) {
196
+		element.style.display = 'none';
197
+	},
198
+
199
+	// Go between hide() and show() depending on element.style.display
200
+	toggle: function (element) {
201
+		if (element.style.display === 'none') {
202
+			this.show(element);
203
+			return;
204
+		}
205
+		this.hide(element);
206
+	},
207
+
208
+	_walk: function (element, walk) {
209
+		var sibling = element[walk];
210
+		while (true) {
211
+			if (sibling.nodeType == 1) {
212
+				break;
213
+			}
214
+			sibling = sibling[walk];
215
+		}
216
+		return sibling;
217
+	},
218
+
219
+	getNext: function (element) {
220
+		return this._walk(element, 'nextSibling');
221
+	},
222
+
223
+	getPrevious: function (element) {
224
+		return this._walk(element, 'previousSibling');
225
+	},
226
+
227
+	// Get or set an element's height, omit value to get, add value (integer) to set.
228
+	height: function (element, value) {
229
+		// Get value
230
+		if (value === undefined) {
231
+			return parseInt(this.getStyle(element, 'height'), 10);
232
+		}
233
+		element.style.height = value + 'px';
234
+	},
235
+
236
+	// Gets the style in css format for property
237
+	getStyle: function (element, property) {
238
+		if (element.currentStyle) {
239
+			property = property.replace(/-[a-z]/g, function (match) {
240
+				return match.charAt(1).toUpperCase();
241
+			});
242
+			return element.currentStyle[property];
243
+		}
244
+		if (window.getComputedStyle) {
245
+			return document.defaultView.getComputedStyle(element, null).getPropertyValue(property);
246
+		}
247
+	}
248
+};
249
+
250
+//
251
+// NOTE DEBUGKIT.Util.Collection is Deprecated.
252
+//
253
+DEBUGKIT.Util.Collection = {
254
+	/**
255
+	 * Apply the passed function to each item in the collection.
256
+	 * The current element in the collection will be `this` in the callback
257
+	 * The callback is also passed the element and the index as arguments.
258
+	 * Optionally you can supply a binding parameter to change `this` in the callback.
259
+	 */
260
+	apply: function (collection, callback, binding) {
261
+		var name, thisVar, i = 0, len = collection.length;
262
+
263
+		if (len === undefined) {
264
+			for (name in collection) {
265
+				thisVar = (binding === undefined) ? collection[name] : binding;
266
+				callback.apply(thisVar, [collection[name], name]);
267
+			}
268
+		} else {
269
+			for (; i < len; i++) {
270
+				thisVar = (binding === undefined) ? collection[i] : binding;
271
+				callback.apply(thisVar, [collection[i], i]);
272
+			}
273
+		}
274
+	}
275
+};
276
+
277
+//
278
+// NOTE DEBUGKIT.Util.Event is Deprecated.
279
+//
280
+// Event binding
281
+DEBUGKIT.Util.Event = function () {
282
+	var _listeners = {},
283
+		_eventId = 0;
284
+
285
+	var preventDefault = function () {
286
+		this.returnValue = false;
287
+	};
288
+
289
+	var stopPropagation = function () {
290
+		this.cancelBubble = true;
291
+	};
292
+
293
+	// Fixes IE's broken event object, adds in common methods + properties.
294
+	var fixEvent = function (event) {
295
+		if (!event.preventDefault) {
296
+			event.preventDefault = preventDefault;
297
+		}
298
+		if (!event.stopPropagation) {
299
+			event.stopPropagation = stopPropagation;
300
+		}
301
+		if (!event.target) {
302
+			event.target = event.srcElement || document;
303
+		}
304
+		if (event.pageX === null && event.clientX !== null) {
305
+			var doc = document.body;
306
+			event.pageX = event.clientX + (doc.scrollLeft || 0) - (doc.clientLeft || 0);
307
+			event.pageY = event.clientY + (doc.scrollTop || 0) - (doc.clientTop || 0);
308
+		}
309
+		return event;
310
+	};
311
+
312
+	return {
313
+		// Bind an event listener of type to element, handler is your method.
314
+		addEvent: function (element, type, handler, capture) {
315
+			capture = (capture === undefined) ? false : capture;
316
+
317
+			var callback = function (event) {
318
+				event = fixEvent(event || window.event);
319
+				handler.apply(element, [event]);
320
+			};
321
+
322
+			if (element.addEventListener) {
323
+				element.addEventListener(type, callback, capture);
324
+			} else if (element.attachEvent) {
325
+				type = 'on' + type;
326
+				element.attachEvent(type, callback);
327
+			} else {
328
+				type = 'on' + type;
329
+				element[type] = callback;
330
+			}
331
+			_listeners[++_eventId] = {element: element, type: type, handler: callback};
332
+		},
333
+
334
+		// Destroy an event listener. requires the exact same function as was used for attaching
335
+		// the event.
336
+		removeEvent: function (element, type, handler) {
337
+			if (element.removeEventListener) {
338
+				element.removeEventListener(type, handler, false);
339
+			} else if (element.detachEvent) {
340
+				type = 'on' + type;
341
+				element.detachEvent(type, handler);
342
+			} else {
343
+				type = 'on' + type;
344
+				element[type] = null;
345
+			}
346
+		},
347
+
348
+		// Bind an event to the DOMContentLoaded or other similar event.
349
+		domready: function (callback) {
350
+			if (document.addEventListener) {
351
+				return document.addEventListener('DOMContentLoaded', callback, false);
352
+			}
353
+
354
+			if (document.all && !window.opera) {
355
+				// Define a "blank" external JavaScript tag
356
+				document.write(
357
+					'<script type="text/javascript" id="__domreadywatcher" defer="defer" src="javascript:void(0)"><\/script>'
358
+				);
359
+				var contentloadtag = document.getElementById('__domreadywatcher');
360
+				contentloadtag.onreadystatechange = function () {
361
+					if (this.readyState === 'complete') {
362
+						callback();
363
+					}
364
+				};
365
+				contentloadtag = null;
366
+				return;
367
+			}
368
+
369
+			if (/Webkit/i.test(navigator.userAgent)) {
370
+				var _timer = setInterval(function () {
371
+					if (/loaded|complete/.test(document.readyState)) {
372
+						clearInterval(_timer);
373
+						callback();
374
+					}
375
+				}, 10);
376
+			}
377
+		},
378
+
379
+		// Unload all the events attached by DebugKit. Fix any memory leaks.
380
+		unload: function () {
381
+			var listener;
382
+			for (var i in _listeners) {
383
+				listener = _listeners[i];
384
+				try {
385
+					this.removeEvent(listener.element, listener.type, listener.handler);
386
+				} catch (e) {}
387
+				delete _listeners[i];
388
+			}
389
+			delete _listeners;
390
+		}
391
+	};
392
+}();
393
+
394
+// Cookie utility
395
+DEBUGKIT.Util.Cookie = function () {
396
+	var cookieLife = 60;
397
+
398
+// Public methods
399
+	return {
400
+		/**
401
+		 * Write to cookie.
402
+		 *
403
+		 * @param [string] name Name of cookie to write.
404
+		 * @param [mixed] value Value to write to cookie.
405
+		 */
406
+		write: function (name, value) {
407
+			var date = new Date();
408
+			date.setTime(date.getTime() + (cookieLife * 24 * 60 * 60 * 1000));
409
+			var expires = '; expires=' + date.toGMTString();
410
+			document.cookie = name + '=' + value + expires + '; path=/';
411
+			return true;
412
+		},
413
+
414
+		/**
415
+		 * Read from the cookie.
416
+		 *
417
+		 * @param [string] name Name of cookie to read.
418
+		 */
419
+		read: function (name) {
420
+			name = name + '=';
421
+			var cookieJar = document.cookie.split(';');
422
+			var cookieJarLength = cookieJar.length;
423
+			for (var i = 0; i < cookieJarLength; i++) {
424
+				var chips = cookieJar[i];
425
+				// Trim leading spaces
426
+				while (chips.charAt(0) === ' ') {
427
+					chips = chips.substring(1, chips.length);
428
+				}
429
+				if (chips.indexOf(name) === 0) {
430
+					return chips.substring(name.length, chips.length);
431
+				}
432
+			}
433
+			return false;
434
+		},
435
+
436
+		/**
437
+		 * Delete a cookie by name.
438
+		 *
439
+		 * @param [string] name of cookie to delete.
440
+		 */
441
+		del: function (name) {
442
+			var date = new Date();
443
+			date.setFullYear(2000, 0, 1);
444
+			var expires = ' ; expires=' + date.toGMTString();
445
+			document.cookie = name + '=' + expires + '; path=/';
446
+		}
447
+	};
448
+}();
449
+
450
+//
451
+// NOTE DEBUGKIT.Util.merge is Deprecated.
452
+//
453
+
454
+/**
455
+ * Object merge takes any number of arguments and glues them together.
456
+ *
457
+ * @param [Object] one first object
458
+ * @return object
459
+ */
460
+DEBUGKIT.Util.merge = function () {
461
+	var out = {};
462
+	var argumentsLength = arguments.length;
463
+	for (var i = 0; i < argumentsLength; i++) {
464
+		var current = arguments[i];
465
+		for (var prop in current) {
466
+			if (current[prop] !== undefined) {
467
+				out[prop] = current[prop];
468
+			}
469
+		}
470
+	}
471
+	return out;
472
+};
473
+
474
+//
475
+// NOTE DEBUGKIT.Util.isArray is Deprecated.
476
+//
477
+
478
+/**
479
+ * Check if the given object is an array.
480
+ */
481
+DEBUGKIT.Util.isArray = function (test) {
482
+	return Object.prototype.toString.call(test) === '[object Array]';
483
+};
484
+
485
+//
486
+// NOTE DEBUGKIT.Util.Request is Deprecated.
487
+//
488
+// Simple wrapper for XmlHttpRequest objects.
489
+DEBUGKIT.Util.Request = function (options) {
490
+	var _defaults = {
491
+		onComplete : function () {},
492
+		onRequest : function () {},
493
+		onFail : function () {},
494
+		method : 'GET',
495
+		async : true,
496
+		headers : {
497
+			'X-Requested-With': 'XMLHttpRequest',
498
+			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
499
+		}
500
+	};
501
+
502
+	var self = this;
503
+	this.options = DEBUGKIT.Util.merge(_defaults, options);
504
+	this.options.method = this.options.method.toUpperCase();
505
+
506
+	var ajax = this.createObj();
507
+	this.transport = ajax;
508
+
509
+	// Event assignment
510
+	this.onComplete = this.options.onComplete;
511
+	this.onRequest = this.options.onRequest;
512
+	this.onFail = this.options.onFail;
513
+
514
+	this.send = function (url, data) {
515
+		if (this.options.method === 'GET' && data) {
516
+			url = url + ((url.charAt(url.length - 1) === '?') ? '&' : '?') + data; //check for ? at the end of the string
517
+			data = null;
518
+		}
519
+		// Open connection
520
+		this.transport.open(this.options.method, url, this.options.async);
521
+
522
+		// Set statechange and pass the active XHR object to it. From here it handles all status changes.
523
+		this.transport.onreadystatechange = function () {
524
+			self.onReadyStateChange.apply(self, arguments);
525
+		};
526
+		for (var key in this.options.headers) {
527
+			this.transport.setRequestHeader(key, this.options.headers[key]);
528
+		}
529
+		if (typeof data === 'object') {
530
+			data = this.serialize(data);
531
+		}
532
+		if (data) {
533
+			this.transport.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
534
+		}
535
+		this.onRequest();
536
+		this.transport.send(data);
537
+	};
538
+};
539
+
540
+DEBUGKIT.Util.Request.prototype.onReadyStateChange = function () {
541
+	if (this.transport.readyState !== 4) {
542
+		return;
543
+	}
544
+	if (this.transport.status === 200 || this.transport.status > 300 && this.transport.status < 400) {
545
+		this.response = {
546
+			xml: this.transport.responseXML,
547
+			text: this.transport.responseText
548
+		};
549
+
550
+		if (typeof this.onComplete === 'function') {
551
+			this.onComplete.apply(this, [this, this.response]);
552
+		} else {
553
+			return this.response;
554
+		}
555
+	} else if (this.transport.status > 400) {
556
+		if (typeof this.onFail === 'function') {
557
+			this.onFail.apply(this, []);
558
+		} else {
559
+			console.error('Request failed');
560
+		}
561
+	}
562
+};
563
+
564
+/**
565
+ * Creates cross-broswer XHR object used for requests.
566
+ * Tries using the standard XmlHttpRequest, then IE's wacky ActiveX Objects.
567
+ */
568
+DEBUGKIT.Util.Request.prototype.createObj = function () {
569
+	var request = null;
570
+	try {
571
+		request = new XMLHttpRequest();
572
+	} catch (MS) {
573
+		try {
574
+			request = new ActiveXObject('Msxml2.XMLHTTP');
575
+		} catch (old_MS) {
576
+			try {
577
+				request = new ActiveXObject('Microsoft.XMLHTTP');
578
+			} catch (failure) {
579
+				request = null;
580
+			}
581
+		}
582
+	}
583
+	return request;
584
+};
585
+
586
+/**
587
+ * Serializes an object literal into a querystring.
588
+ */
589
+DEBUGKIT.Util.Request.prototype.serialize = function (data) {
590
+	var out = '';
591
+	for (var name in data) {
592
+		if (data.hasOwnProperty(name)) {
593
+			out += name + '=' + data[name] + '&';
594
+		}
595
+	}
596
+	return out.substring(0, out.length - 1);
597
+};
598
+
599
+
600
+// Basic toolbar module.
601
+DEBUGKIT.toolbar = function () {
602
+	// Shortcuts
603
+	var Cookie = DEBUGKIT.Util.Cookie,
604
+		toolbarHidden = false;
605
+
606
+	return {
607
+		elements: {},
608
+		panels: {},
609
+
610
+		init: function () {
611
+			var i, element, lists, index, _this = this;
612
+
613
+			this.elements.toolbar = $('#debug-kit-toolbar');
614
+
615
+			if (this.elements.toolbar.length === 0) {
616
+				throw new Error('Toolbar not found, make sure you loaded it.');
617
+			}
618
+
619
+			this.elements.panel = $('#panel-tabs');
620
+			this.elements.panel.find('.panel-tab').each(function (i, panel) {
621
+				_this.addPanel(panel);
622
+			});
623
+
624
+			lists = this.elements.toolbar.find('.depth-0');
625
+
626
+			this.makeNeatArray(lists);
627
+			this.deactivatePanel(true);
628
+		},
629
+
630
+		// Add a panel to the toolbar
631
+		addPanel: function (tab) {
632
+			var button, content, _this = this;
633
+			var panel = {
634
+				id : false,
635
+				element : tab,
636
+				button : undefined,
637
+				content : undefined,
638
+				active : false
639
+			};
640
+			tab = $(tab);
641
+			button = tab.children('a');
642
+
643
+			panel.id = button.attr('href').replace(/^#/, '');
644
+			panel.button = button;
645
+			panel.content = tab.find('.panel-content');
646
+
647
+			if (!panel.id || panel.content.length === 0) {
648
+				return false;
649
+			}
650
+			this.makePanelDraggable(panel);
651
+			this.makePanelMinMax(panel);
652
+
653
+			button.on('click', function (event) {
654
+				event.preventDefault();
655
+				_this.togglePanel(panel.id);
656
+			});
657
+
658
+			this.panels[panel.id] = panel;
659
+			return panel.id;
660
+		},
661
+
662
+		// Find the handle element and make the panel drag resizable.
663
+		makePanelDraggable: function (panel) {
664
+
665
+			// Create a variable in the enclosing scope, for scope tricks.
666
+			var currentElement = null;
667
+
668
+			// Use the elements startHeight stored Event.pageY and current Event.pageY to
669
+			// resize the panel.
670
+			var mouseMoveHandler = function (event) {
671
+				event.preventDefault();
672
+				if (!currentElement) {
673
+					return;
674
+				}
675
+				var newHeight = currentElement.data('startHeight') + (event.pageY - currentElement.data('startY'));
676
+				currentElement.parent().height(newHeight);
677
+			};
678
+
679
+			// Handle the mouseup event, remove the other listeners so the panel
680
+			// doesn't continue to resize.
681
+			var mouseUpHandler = function (event) {
682
+				currentElement = null;
683
+				$(document).off('mousemove', mouseMoveHandler).off('mouseup', mouseUpHandler);
684
+			};
685
+
686
+			var mouseDownHandler = function (event) {
687
+				event.preventDefault();
688
+
689
+				currentElement = $(this);
690
+				currentElement.data('startY', event.pageY);
691
+				currentElement.data('startHeight', currentElement.parent().height());
692
+
693
+				// Attach to document so mouse doesn't have to stay precisely on the 'handle'.
694
+				$(document).on('mousemove', mouseMoveHandler)
695
+					.on('mouseup', mouseUpHandler);
696
+			};
697
+
698
+			panel.content.find('.panel-resize-handle').on('mousedown', mouseDownHandler);
699
+		},
700
+
701
+		// Make the maximize button work on the panels.
702
+		makePanelMinMax: function (panel) {
703
+			var _oldHeight;
704
+
705
+			var maximize = function () {
706
+				if (!_oldHeight) {
707
+					_oldHeight = this.parentNode.offsetHeight;
708
+				}
709
+				var windowHeight = window.innerHeight;
710
+				var panelHeight = windowHeight - this.parentNode.offsetTop;
711
+				$(this.parentNode).height(panelHeight);
712
+				$(this).text('-');
713
+			};
714
+
715
+			var minimize = function () {
716
+				$(this.parentNode).height(_oldHeight);
717
+				$(this).text('+');
718
+				_oldHeight = null;
719
+			};
720
+
721
+			var state = 1;
722
+			var toggle = function (event) {
723
+				event.preventDefault();
724
+				if (state === 1) {
725
+					maximize.call(this);
726
+					state = 0;
727
+				} else {
728
+					state = 1;
729
+					minimize.call(this);
730
+				}
731
+			};
732
+
733
+			panel.content.find('.panel-toggle').on('click', toggle);
734
+		},
735
+
736
+		// Toggle a panel
737
+		togglePanel: function (id) {
738
+			if (this.panels[id] && this.panels[id].active) {
739
+				this.deactivatePanel(true);
740
+			} else {
741
+				this.deactivatePanel(true);
742
+				this.activatePanel(id);
743
+			}
744
+		},
745
+
746
+		// Make a panel active.
747
+		activatePanel: function (id, unique) {
748
+			if (this.panels[id] !== undefined && !this.panels[id].active) {
749
+				var panel = this.panels[id];
750
+				if (panel.content.length > 0) {
751
+					panel.content.show();
752
+				}
753
+
754
+				var contentHeight = panel.content.find('.panel-content-data').height() + 70;
755
+				if (contentHeight <= (window.innerHeight / 2)) {
756
+					panel.content.height(contentHeight);
757
+				}
758
+
759
+				panel.button.addClass('active');
760
+				panel.active = true;
761
+				return true;
762
+			}
763
+			return false;
764
+		},
765
+
766
+		// Deactivate a panel. use true to hide all panels.
767
+		deactivatePanel: function (id) {
768
+			if (id === true) {
769
+				for (var i in this.panels) {
770
+					this.deactivatePanel(i);
771
+				}
772
+				return true;
773
+			}
774
+			if (this.panels[id] !== undefined) {
775
+				var panel = this.panels[id];
776
+				if (panel.content !== undefined) {
777
+					panel.content.hide();
778
+				}
779
+				panel.button.removeClass('active');
780
+				panel.active = false;
781
+				return true;
782
+			}
783
+			return false;
784
+		},
785
+
786
+		// Bind events for all the collapsible arrays.
787
+		makeNeatArray: function (lists) {
788
+			lists.find('ul').hide()
789
+				.parent().addClass('expandable collapsed');
790
+
791
+			lists.on('click', 'li', function (event) {
792
+				event.stopPropagation();
793
+				$(this).children('ul').toggle().toggleClass('expanded collapsed');
794
+			});
795
+		}
796
+	};
797
+}();
798
+DEBUGKIT.loader.register(DEBUGKIT.toolbar);
799
+
800
+DEBUGKIT.module('historyPanel');
801
+DEBUGKIT.historyPanel = function () {
802
+	var toolbar = DEBUGKIT.toolbar,
803
+		historyLinks;
804
+
805
+	// Private methods to handle JSON response and insertion of
806
+	// new content.
807
+	var switchHistory = function (response) {
808
+
809
+		historyLinks.removeClass('loading');
810
+
811
+		$.each(toolbar.panels, function (id, panel) {
812
+			if (panel.content === undefined || response[id] === undefined) {
813
+				return;
814
+			}
815
+
816
+			var regionDiv = panel.content.find('.panel-resize-region');
817
+			if (!regionDiv.length) {
818
+				return;
819
+			}
820
+
821
+			var regionDivs = regionDiv.children();
822
+
823
+			regionDivs.filter('div').hide();
824
+			regionDivs.filter('.panel-history').each(function (i, panelContent) {
825
+				var panelId = panelContent.id.replace('-history', '');
826
+				if (response[panelId]) {
827
+					panelContent = $(panelContent);
828
+					panelContent.html(response[panelId]);
829
+					var lists = panelContent.find('.depth-0');
830
+					toolbar.makeNeatArray(lists);
831
+				}
832
+				panelContent.show();
833
+			});
834
+		});
835
+	};
836
+
837
+	// Private method to handle restoration to current request.
838
+	var restoreCurrentState = function () {
839
+		var id, i, panelContent, tag;
840
+
841
+		historyLinks.removeClass('loading');
842
+
843
+		$.each(toolbar.panels, function (panel, id) {
844
+			if (panel.content === undefined) {
845
+				return;
846
+			}
847
+			var regionDiv = panel.content.find('.panel-resize-region');
848
+			if (!regionDiv.length) {
849
+				return;
850
+			}
851
+			var regionDivs = regionDiv.children();
852
+			regionDivs.filter('div').show()
853
+				.end()
854
+				.filter('.panel-history').hide();
855
+		});
856
+	};
857
+
858
+	function handleHistoryLink(event) {
859
+		event.preventDefault();
860
+
861
+		historyLinks.removeClass('active');
862
+		$(this).addClass('active loading');
863
+
864
+		if (this.id === 'history-restore-current') {
865
+			restoreCurrentState();
866
+			return false;
867
+		}
868
+
869
+		var xhr = $.ajax({
870
+			url: this.href,
871
+			type: 'GET',
872
+			dataType: 'json'
873
+		});
874
+		xhr.success(switchHistory).fail(function () {
875
+			alert('History retrieval failed');
876
+		});
877
+	}
878
+
879
+	return {
880
+		init : function () {
881
+			if (toolbar.panels.history === undefined) {
882
+				return;
883
+			}
884
+
885
+			historyLinks = toolbar.panels.history.content.find('.history-link');
886
+			historyLinks.on('click', handleHistoryLink);
887
+		}
888
+	};
889
+}();
890
+DEBUGKIT.loader.register(DEBUGKIT.historyPanel);
891
+
892
+//Add events + behaviors for toolbar collapser.
893
+DEBUGKIT.toolbarToggle = function () {
894
+	var toolbar = DEBUGKIT.toolbar,
895
+		Cookie = DEBUGKIT.Util.Cookie,
896
+		toolbarHidden = false;
897
+
898
+	return {
899
+		init: function () {
900
+			var button = $('#hide-toolbar'),
901
+				self = this;
902
+
903
+			button.on('click', function (event) {
904
+				event.preventDefault();
905
+				self.toggleToolbar();
906
+			});
907
+
908
+			var toolbarState = Cookie.read('toolbarDisplay');
909
+			if (toolbarState !== 'show') {
910
+				toolbarHidden = false;
911
+				this.toggleToolbar();
912
+			}
913
+		},
914
+
915
+		toggleToolbar: function () {
916
+			var display = toolbarHidden ? 'show' : 'hide';
917
+			$.each(toolbar.panels, function (i, panel) {
918
+				$(panel.element)[display]();
919
+				Cookie.write('toolbarDisplay', display);
920
+			});
921
+			toolbarHidden = !toolbarHidden;
922
+
923
+			if (toolbarHidden) {
924
+				$('#debug-kit-toolbar').addClass('minimized');
925
+			} else {
926
+				$('#debug-kit-toolbar').removeClass('minimized');
927
+			}
928
+
929
+			return false;
930
+		}
931
+	};
932
+}();
933
+DEBUGKIT.loader.register(DEBUGKIT.toolbarToggle);
934
+
935
+
936
+}; // DEBUGKIT.registerModules

+ 5
- 0
app/.htaccess 파일 보기

1
+<IfModule mod_rewrite.c>
2
+	RewriteEngine on
3
+	RewriteRule ^$ webroot/ [L]
4
+	RewriteRule (.*) webroot/$1 [L]
5
+</IfModule>

+ 80
- 0
app/Config/Schema/db_acl.php 파일 보기

1
+<?php
2
+/**
3
+ * This is Acl Schema file
4
+ *
5
+ * Use it to configure database for ACL
6
+ *
7
+ * @link          http://cakephp.org CakePHP(tm) Project
8
+ * @package       app.Config.Schema
9
+ * @since         CakePHP(tm) v 0.2.9
10
+ */
11
+
12
+/**
13
+ * Using the Schema command line utility
14
+ * cake schema run create DbAcl
15
+ */
16
+class DbAclSchema extends CakeSchema {
17
+
18
+/**
19
+ * Before event.
20
+ *
21
+ * @param array $event The event data.
22
+ * @return bool success
23
+ */
24
+	public function before($event = array()) {
25
+		return true;
26
+	}
27
+
28
+/**
29
+ * After event.
30
+ *
31
+ * @param array $event The event data.
32
+ * @return void
33
+ */
34
+	public function after($event = array()) {
35
+	}
36
+
37
+/**
38
+ * ACO - Access Control Object - Something that is wanted
39
+ */
40
+	public $acos = array(
41
+		'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
42
+		'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
43
+		'model' => array('type' => 'string', 'null' => true),
44
+		'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
45
+		'alias' => array('type' => 'string', 'null' => true),
46
+		'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
47
+		'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
48
+		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
49
+	);
50
+
51
+/**
52
+ * ARO - Access Request Object - Something that wants something
53
+ */
54
+	public $aros = array(
55
+		'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
56
+		'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
57
+		'model' => array('type' => 'string', 'null' => true),
58
+		'foreign_key' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
59
+		'alias' => array('type' => 'string', 'null' => true),
60
+		'lft' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
61
+		'rght' => array('type' => 'integer', 'null' => true, 'default' => null, 'length' => 10),
62
+		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
63
+	);
64
+
65
+/**
66
+ * Used by the Cake::Model:Permission class.
67
+ * Checks if the given $aro has access to action $action in $aco.
68
+ */
69
+	public $aros_acos = array(
70
+		'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
71
+		'aro_id' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
72
+		'aco_id' => array('type' => 'integer', 'null' => false, 'length' => 10),
73
+		'_create' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
74
+		'_read' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
75
+		'_update' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
76
+		'_delete' => array('type' => 'string', 'null' => false, 'default' => '0', 'length' => 2),
77
+		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1))
78
+	);
79
+
80
+}

+ 52
- 0
app/Config/Schema/db_acl.sql 파일 보기

1
+# $Id$
2
+#
3
+# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4
+#
5
+# Licensed under The MIT License
6
+# For full copyright and license information, please see the LICENSE.txt
7
+# Redistributions of files must retain the above copyright notice.
8
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
9
+
10
+CREATE TABLE acos (
11
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
12
+  parent_id INTEGER(10) DEFAULT NULL,
13
+  model VARCHAR(255) DEFAULT '',
14
+  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
15
+  alias VARCHAR(255) DEFAULT '',
16
+  lft INTEGER(10) DEFAULT NULL,
17
+  rght INTEGER(10) DEFAULT NULL,
18
+  PRIMARY KEY  (id)
19
+);
20
+
21
+CREATE TABLE aros_acos (
22
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
23
+  aro_id INTEGER(10) UNSIGNED NOT NULL,
24
+  aco_id INTEGER(10) UNSIGNED NOT NULL,
25
+  _create CHAR(2) NOT NULL DEFAULT 0,
26
+  _read CHAR(2) NOT NULL DEFAULT 0,
27
+  _update CHAR(2) NOT NULL DEFAULT 0,
28
+  _delete CHAR(2) NOT NULL DEFAULT 0,
29
+  PRIMARY KEY(id)
30
+);
31
+
32
+CREATE TABLE aros (
33
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
34
+  parent_id INTEGER(10) DEFAULT NULL,
35
+  model VARCHAR(255) DEFAULT '',
36
+  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
37
+  alias VARCHAR(255) DEFAULT '',
38
+  lft INTEGER(10) DEFAULT NULL,
39
+  rght INTEGER(10) DEFAULT NULL,
40
+  PRIMARY KEY  (id)
41
+);
42
+
43
+/* this indexes will improve acl perfomance */
44
+CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`);
45
+
46
+CREATE INDEX idx_acos_alias ON `acos` (`alias`);
47
+
48
+CREATE INDEX idx_aros_lft_rght ON `aros` (`lft`, `rght`);
49
+
50
+CREATE INDEX idx_aros_alias ON `aros` (`alias`);
51
+
52
+CREATE INDEX idx_aco_id ON `aros_acos` (`aco_id`);

+ 71
- 0
app/Config/Schema/i18n.php 파일 보기

1
+<?php
2
+/**
3
+ * This is i18n Schema file
4
+ *
5
+ * Use it to configure database for i18n
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * For full copyright and license information, please see the LICENSE.txt
12
+ * Redistributions of files must retain the above copyright notice.
13
+ *
14
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
+ * @link          http://cakephp.org CakePHP(tm) Project
16
+ * @package       app.Config.Schema
17
+ * @since         CakePHP(tm) v 0.2.9
18
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
+ */
20
+
21
+/**
22
+ * Using the Schema command line utility
23
+ *
24
+ * Use it to configure database for i18n
25
+ *
26
+ * cake schema run create i18n
27
+ */
28
+class I18nSchema extends CakeSchema {
29
+
30
+/**
31
+ * The name property
32
+ *
33
+ * @var string
34
+ */
35
+	public $name = 'i18n';
36
+
37
+/**
38
+ * Before callback.
39
+ *
40
+ * @param array $event Schema object properties
41
+ * @return bool Should process continue
42
+ */
43
+	public function before($event = array()) {
44
+		return true;
45
+	}
46
+
47
+/**
48
+ * After callback.
49
+ *
50
+ * @param array $event Schema object properties
51
+ * @return void
52
+ */
53
+	public function after($event = array()) {
54
+	}
55
+
56
+/**
57
+ * The i18n table definition
58
+ *
59
+ * @var array
60
+ */
61
+	public $i18n = array(
62
+		'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'length' => 10, 'key' => 'primary'),
63
+		'locale' => array('type' => 'string', 'null' => false, 'length' => 6, 'key' => 'index'),
64
+		'model' => array('type' => 'string', 'null' => false, 'key' => 'index'),
65
+		'foreign_key' => array('type' => 'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
66
+		'field' => array('type' => 'string', 'null' => false, 'key' => 'index'),
67
+		'content' => array('type' => 'text', 'null' => true, 'default' => null),
68
+		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0))
69
+	);
70
+
71
+}

+ 27
- 0
app/Config/Schema/i18n.sql 파일 보기

1
+# $Id$
2
+#
3
+# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4
+#
5
+# Licensed under The MIT License
6
+# For full copyright and license information, please see the LICENSE.txt
7
+# Redistributions of files must retain the above copyright notice.
8
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
9
+
10
+CREATE TABLE i18n (
11
+	id int(10) NOT NULL auto_increment,
12
+	locale varchar(6) NOT NULL,
13
+	model varchar(255) NOT NULL,
14
+	foreign_key int(10) NOT NULL,
15
+	field varchar(255) NOT NULL,
16
+	content mediumtext,
17
+	PRIMARY KEY	(id),
18
+#	UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
19
+#	INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
20
+#	INDEX I18N_LOCALE_MODEL(locale, model),
21
+#	INDEX I18N_FIELD(model, foreign_key, field),
22
+#	INDEX I18N_ROW(model, foreign_key),
23
+	INDEX locale (locale),
24
+	INDEX model (model),
25
+	INDEX row_id (foreign_key),
26
+	INDEX field (field)
27
+);

+ 65
- 0
app/Config/Schema/sessions.php 파일 보기

1
+<?php
2
+/**
3
+ * This is Sessions Schema file
4
+ *
5
+ * Use it to configure database for Sessions
6
+ *
7
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
+ *
10
+ * Licensed under The MIT License
11
+ * For full copyright and license information, please see the LICENSE.txt
12
+ * Redistributions of files must retain the above copyright notice.
13
+ *
14
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
+ * @link          http://cakephp.org CakePHP(tm) Project
16
+ * @package       app.Config.Schema
17
+ * @since         CakePHP(tm) v 0.2.9
18
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
+ */
20
+
21
+/**
22
+ * Using the Schema command line utility
23
+ * cake schema run create Sessions
24
+ */
25
+class SessionsSchema extends CakeSchema {
26
+
27
+/**
28
+ * Name property
29
+ *
30
+ * @var string
31
+ */
32
+	public $name = 'Sessions';
33
+
34
+/**
35
+ * Before callback.
36
+ *
37
+ * @param array $event Schema object properties
38
+ * @return bool Should process continue
39
+ */
40
+	public function before($event = array()) {
41
+		return true;
42
+	}
43
+
44
+/**
45
+ * After callback.
46
+ *
47
+ * @param array $event Schema object properties
48
+ * @return void
49
+ */
50
+	public function after($event = array()) {
51
+	}
52
+
53
+/**
54
+ * The cake_sessions table definition
55
+ *
56
+ * @var array
57
+ */
58
+	public $cake_sessions = array(
59
+		'id' => array('type' => 'string', 'null' => false, 'key' => 'primary'),
60
+		'data' => array('type' => 'text', 'null' => true, 'default' => null),
61
+		'expires' => array('type' => 'integer', 'null' => true, 'default' => null),
62
+		'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
63
+	);
64
+
65
+}

+ 17
- 0
app/Config/Schema/sessions.sql 파일 보기

1
+# $Id$
2
+#
3
+# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4
+#								1785 E. Sahara Avenue, Suite 490-204
5
+#								Las Vegas, Nevada 89104
6
+#
7
+# Licensed under The MIT License
8
+# For full copyright and license information, please see the LICENSE.txt
9
+# Redistributions of files must retain the above copyright notice.
10
+# MIT License (http://www.opensource.org/licenses/mit-license.php)
11
+
12
+CREATE TABLE cake_sessions (
13
+  id varchar(255) NOT NULL default '',
14
+  data text,
15
+  expires int(11) default NULL,
16
+  PRIMARY KEY  (id)
17
+);

+ 57
- 0
app/Config/acl.ini.php 파일 보기

1
+;<?php exit() ?>
2
+;/**
3
+; * ACL Configuration
4
+; *
5
+; * @link          http://cakephp.org CakePHP(tm) Project
6
+; * @package       app.Config
7
+; * @since         CakePHP(tm) v 0.10.0.1076
8
+; */
9
+
10
+; acl.ini.php - CakePHP ACL Configuration
11
+; ---------------------------------------------------------------------
12
+; Use this file to specify user permissions.
13
+; aco = access control object (something in your application)
14
+; aro = access request object (something requesting access)
15
+;
16
+; User records are added as follows:
17
+;
18
+; [uid]
19
+; groups = group1, group2, group3
20
+; allow = aco1, aco2, aco3
21
+; deny = aco4, aco5, aco6
22
+;
23
+; Group records are added in a similar manner:
24
+;
25
+; [gid]
26
+; allow = aco1, aco2, aco3
27
+; deny = aco4, aco5, aco6
28
+;
29
+; The allow, deny, and groups sections are all optional.
30
+; NOTE: groups names *cannot* ever be the same as usernames!
31
+;
32
+; ACL permissions are checked in the following order:
33
+; 1. Check for user denies (and DENY if specified)
34
+; 2. Check for user allows (and ALLOW if specified)
35
+; 3. Gather user's groups
36
+; 4. Check group denies (and DENY if specified)
37
+; 5. Check group allows (and ALLOW if specified)
38
+; 6. If no aro, aco, or group information is found, DENY
39
+;
40
+; ---------------------------------------------------------------------
41
+
42
+;-------------------------------------
43
+;Users
44
+;-------------------------------------
45
+
46
+[username-goes-here]
47
+groups = group1, group2
48
+deny = aco1, aco2
49
+allow = aco3, aco4
50
+
51
+;-------------------------------------
52
+;Groups
53
+;-------------------------------------
54
+
55
+[groupname-goes-here]
56
+deny = aco5, aco6
57
+allow = aco7, aco8

+ 124
- 0
app/Config/acl.php 파일 보기

1
+<?php
2
+/**
3
+ * This is the PHP base ACL configuration file.
4
+ *
5
+ * Use it to configure access control of your CakePHP application.
6
+ *
7
+ * @link          http://cakephp.org CakePHP(tm) Project
8
+ * @package       app.Config
9
+ * @since         CakePHP(tm) v 2.1
10
+ */
11
+
12
+/**
13
+ * Example
14
+ * -------
15
+ *
16
+ * Assumptions:
17
+ *
18
+ * 1. In your application you created a User model with the following properties:
19
+ *    username, group_id, password, email, firstname, lastname and so on.
20
+ * 2. You configured AuthComponent to authorize actions via
21
+ *    $this->Auth->authorize = array('Actions' => array('actionPath' => 'controllers/'),...)
22
+ *
23
+ * Now, when a user (i.e. jeff) authenticates successfully and requests a controller action (i.e. /invoices/delete)
24
+ * that is not allowed by default (e.g. via $this->Auth->allow('edit') in the Invoices controller) then AuthComponent
25
+ * will ask the configured ACL interface if access is granted. Under the assumptions 1. and 2. this will be
26
+ * done via a call to Acl->check() with
27
+ *
28
+ *    array('User' => array('username' => 'jeff', 'group_id' => 4, ...))
29
+ *
30
+ * as ARO and
31
+ *
32
+ *    '/controllers/invoices/delete'
33
+ *
34
+ * as ACO.
35
+ *
36
+ * If the configured map looks like
37
+ *
38
+ *    $config['map'] = array(
39
+ *       'User' => 'User/username',
40
+ *       'Role' => 'User/group_id',
41
+ *    );
42
+ *
43
+ * then PhpAcl will lookup if we defined a role like User/jeff. If that role is not found, PhpAcl will try to
44
+ * find a definition for Role/4. If the definition isn't found then a default role (Role/default) will be used to
45
+ * check rules for the given ACO. The search can be expanded by defining aliases in the alias configuration.
46
+ * E.g. if you want to use a more readable name than Role/4 in your definitions you can define an alias like
47
+ *
48
+ *    $config['alias'] = array(
49
+ *       'Role/4' => 'Role/editor',
50
+ *    );
51
+ *
52
+ * In the roles configuration you can define roles on the lhs and inherited roles on the rhs:
53
+ *
54
+ *    $config['roles'] = array(
55
+ *       'Role/admin' => null,
56
+ *       'Role/accountant' => null,
57
+ *       'Role/editor' => null,
58
+ *       'Role/manager' => 'Role/editor, Role/accountant',
59
+ *       'User/jeff' => 'Role/manager',
60
+ *    );
61
+ *
62
+ * In this example manager inherits all rules from editor and accountant. Role/admin doesn't inherit from any role.
63
+ * Lets define some rules:
64
+ *
65
+ *    $config['rules'] = array(
66
+ *       'allow' => array(
67
+ *       	'*' => 'Role/admin',
68
+ *       	'controllers/users/(dashboard|profile)' => 'Role/default',
69
+ *       	'controllers/invoices/*' => 'Role/accountant',
70
+ *       	'controllers/articles/*' => 'Role/editor',
71
+ *       	'controllers/users/*'  => 'Role/manager',
72
+ *       	'controllers/invoices/delete'  => 'Role/manager',
73
+ *       ),
74
+ *       'deny' => array(
75
+ *       	'controllers/invoices/delete' => 'Role/accountant, User/jeff',
76
+ *       	'controllers/articles/(delete|publish)' => 'Role/editor',
77
+ *       ),
78
+ *    );
79
+ *
80
+ * Ok, so as jeff inherits from Role/manager he's matched every rule that references User/jeff, Role/manager,
81
+ * Role/editor, Role/accountant and Role/default. However, for jeff, rules for User/jeff are more specific than
82
+ * rules for Role/manager, rules for Role/manager are more specific than rules for Role/editor and so on.
83
+ * This is important when allow and deny rules match for a role. E.g. Role/accountant is allowed
84
+ * controllers/invoices/* but at the same time controllers/invoices/delete is denied. But there is a more
85
+ * specific rule defined for Role/manager which is allowed controllers/invoices/delete. However, the most specific
86
+ * rule denies access to the delete action explicitly for User/jeff, so he'll be denied access to the resource.
87
+ *
88
+ * If we would remove the role definition for User/jeff, then jeff would be granted access as he would be resolved
89
+ * to Role/manager and Role/manager has an allow rule.
90
+ */
91
+
92
+/**
93
+ * The role map defines how to resolve the user record from your application
94
+ * to the roles you defined in the roles configuration.
95
+ */
96
+$config['map'] = array(
97
+	'User' => 'User/username',
98
+	'Role' => 'User/group_id',
99
+);
100
+
101
+/**
102
+ * define aliases to map your model information to
103
+ * the roles defined in your role configuration.
104
+ */
105
+$config['alias'] = array(
106
+	'Role/4' => 'Role/editor',
107
+);
108
+
109
+/**
110
+ * role configuration
111
+ */
112
+$config['roles'] = array(
113
+	'Role/admin' => null,
114
+);
115
+
116
+/**
117
+ * rule configuration
118
+ */
119
+$config['rules'] = array(
120
+	'allow' => array(
121
+		'*' => 'Role/admin',
122
+	),
123
+	'deny' => array(),
124
+);

+ 95
- 0
app/Config/bootstrap.php 파일 보기

1
+<?php
2
+/**
3
+ * This file is loaded automatically by the app/webroot/index.php file after core.php
4
+ *
5
+ * This file should load/create any application wide configuration settings, such as
6
+ * Caching, Logging, loading additional configuration files.
7
+ *
8
+ * You should also use this file to include any files that provide global functions/constants
9
+ * that your application uses.
10
+ *
11
+ * @link          http://cakephp.org CakePHP(tm) Project
12
+ * @package       app.Config
13
+ * @since         CakePHP(tm) v 0.10.8.2117
14
+ */
15
+
16
+// Setup a 'default' cache configuration for use in the application.
17
+Cache::config('default', array('engine' => 'File'));
18
+
19
+/**
20
+ * The settings below can be used to set additional paths to models, views and controllers.
21
+ *
22
+ * App::build(array(
23
+ *     'Model'                     => array('/path/to/models/', '/next/path/to/models/'),
24
+ *     'Model/Behavior'            => array('/path/to/behaviors/', '/next/path/to/behaviors/'),
25
+ *     'Model/Datasource'          => array('/path/to/datasources/', '/next/path/to/datasources/'),
26
+ *     'Model/Datasource/Database' => array('/path/to/databases/', '/next/path/to/database/'),
27
+ *     'Model/Datasource/Session'  => array('/path/to/sessions/', '/next/path/to/sessions/'),
28
+ *     'Controller'                => array('/path/to/controllers/', '/next/path/to/controllers/'),
29
+ *     'Controller/Component'      => array('/path/to/components/', '/next/path/to/components/'),
30
+ *     'Controller/Component/Auth' => array('/path/to/auths/', '/next/path/to/auths/'),
31
+ *     'Controller/Component/Acl'  => array('/path/to/acls/', '/next/path/to/acls/'),
32
+ *     'View'                      => array('/path/to/views/', '/next/path/to/views/'),
33
+ *     'View/Helper'               => array('/path/to/helpers/', '/next/path/to/helpers/'),
34
+ *     'Console'                   => array('/path/to/consoles/', '/next/path/to/consoles/'),
35
+ *     'Console/Command'           => array('/path/to/commands/', '/next/path/to/commands/'),
36
+ *     'Console/Command/Task'      => array('/path/to/tasks/', '/next/path/to/tasks/'),
37
+ *     'Lib'                       => array('/path/to/libs/', '/next/path/to/libs/'),
38
+ *     'Locale'                    => array('/path/to/locales/', '/next/path/to/locales/'),
39
+ *     'Vendor'                    => array('/path/to/vendors/', '/next/path/to/vendors/'),
40
+ *     'Plugin'                    => array('/path/to/plugins/', '/next/path/to/plugins/'),
41
+ * ));
42
+ */
43
+
44
+/**
45
+ * Custom Inflector rules can be set to correctly pluralize or singularize table, model, controller names or whatever other
46
+ * string is passed to the inflection functions
47
+ *
48
+ * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
49
+ * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
50
+ */
51
+
52
+/**
53
+ * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
54
+ * Uncomment one of the lines below, as you need. Make sure you read the documentation on CakePlugin to use more
55
+ * advanced ways of loading plugins
56
+ *
57
+ * CakePlugin::loadAll(); // Loads all plugins at once
58
+ * CakePlugin::load('DebugKit'); // Loads a single plugin named DebugKit
59
+ */
60
+
61
+/**
62
+ * You can attach event listeners to the request lifecycle as Dispatcher Filter . By default CakePHP bundles two filters:
63
+ *
64
+ * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
65
+ * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers
66
+ *
67
+ * Feel free to remove or add filters as you see fit for your application. A few examples:
68
+ *
69
+ * Configure::write('Dispatcher.filters', array(
70
+ *		'MyCacheFilter', //  will use MyCacheFilter class from the Routing/Filter package in your app.
71
+ *		'MyPlugin.MyFilter', // will use MyFilter class from the Routing/Filter package in MyPlugin plugin.
72
+ * 		array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // A valid PHP callback type to be called on beforeDispatch
73
+ *		array('callable' => $anotherMethod, 'on' => 'after'), // A valid PHP callback type to be called on afterDispatch
74
+ *
75
+ * ));
76
+ */
77
+Configure::write('Dispatcher.filters', array(
78
+	'AssetDispatcher',
79
+	'CacheDispatcher'
80
+));
81
+
82
+/**
83
+ * Configures default file logging options
84
+ */
85
+App::uses('CakeLog', 'Log');
86
+CakeLog::config('debug', array(
87
+	'engine' => 'File',
88
+	'types' => array('notice', 'info', 'debug'),
89
+	'file' => 'debug',
90
+));
91
+CakeLog::config('error', array(
92
+	'engine' => 'File',
93
+	'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
94
+	'file' => 'error',
95
+));

+ 361
- 0
app/Config/core.php 파일 보기

1
+<?php
2
+/**
3
+ * This is core configuration file.
4
+ *
5
+ * Use it to configure core behavior of Cake.
6
+ *
7
+ * @link          http://cakephp.org CakePHP(tm) Project
8
+ * @package       app.Config
9
+ * @since         CakePHP(tm) v 0.2.9
10
+ */
11
+
12
+/**
13
+ * CakePHP Debug Level:
14
+ *
15
+ * Production Mode:
16
+ * 	0: No error messages, errors, or warnings shown. Flash messages redirect.
17
+ *
18
+ * Development Mode:
19
+ * 	1: Errors and warnings shown, model caches refreshed, flash messages halted.
20
+ * 	2: As in 1, but also with full debug messages and SQL output.
21
+ *
22
+ * In production mode, flash messages redirect after a time interval.
23
+ * In development mode, you need to click the flash message to continue.
24
+ */
25
+	Configure::write('debug', 2);
26
+
27
+/**
28
+ * Configure the Error handler used to handle errors for your application. By default
29
+ * ErrorHandler::handleError() is used. It will display errors using Debugger, when debug > 0
30
+ * and log errors with CakeLog when debug = 0.
31
+ *
32
+ * Options:
33
+ *
34
+ * - `handler` - callback - The callback to handle errors. You can set this to any callable type,
35
+ *   including anonymous functions.
36
+ *   Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class
37
+ * - `level` - integer - The level of errors you are interested in capturing.
38
+ * - `trace` - boolean - Include stack traces for errors in log files.
39
+ *
40
+ * @see ErrorHandler for more information on error handling and configuration.
41
+ */
42
+	Configure::write('Error', array(
43
+		'handler' => 'ErrorHandler::handleError',
44
+		'level' => E_ALL & ~E_DEPRECATED,
45
+		'trace' => true
46
+	));
47
+
48
+/**
49
+ * Configure the Exception handler used for uncaught exceptions. By default,
50
+ * ErrorHandler::handleException() is used. It will display a HTML page for the exception, and
51
+ * while debug > 0, framework errors like Missing Controller will be displayed. When debug = 0,
52
+ * framework errors will be coerced into generic HTTP errors.
53
+ *
54
+ * Options:
55
+ *
56
+ * - `handler` - callback - The callback to handle exceptions. You can set this to any callback type,
57
+ *   including anonymous functions.
58
+ *   Make sure you add App::uses('MyHandler', 'Error'); when using a custom handler class
59
+ * - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
60
+ *   should place the file for that class in app/Lib/Error. This class needs to implement a render method.
61
+ * - `log` - boolean - Should Exceptions be logged?
62
+ * - `skipLog` - array - list of exceptions to skip for logging. Exceptions that
63
+ *   extend one of the listed exceptions will also be skipped for logging.
64
+ *   Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')`
65
+ *
66
+ * @see ErrorHandler for more information on exception handling and configuration.
67
+ */
68
+	Configure::write('Exception', array(
69
+		'handler' => 'ErrorHandler::handleException',
70
+		'renderer' => 'ExceptionRenderer',
71
+		'log' => true
72
+	));
73
+
74
+/**
75
+ * Application wide charset encoding
76
+ */
77
+	Configure::write('App.encoding', 'UTF-8');
78
+
79
+/**
80
+ * To configure CakePHP *not* to use mod_rewrite and to
81
+ * use CakePHP pretty URLs, remove these .htaccess
82
+ * files:
83
+ *
84
+ * /.htaccess
85
+ * /app/.htaccess
86
+ * /app/webroot/.htaccess
87
+ *
88
+ * And uncomment the App.baseUrl below. But keep in mind
89
+ * that plugin assets such as images, CSS and JavaScript files
90
+ * will not work without URL rewriting!
91
+ * To work around this issue you should either symlink or copy
92
+ * the plugin assets into you app's webroot directory. This is
93
+ * recommended even when you are using mod_rewrite. Handling static
94
+ * assets through the Dispatcher is incredibly inefficient and
95
+ * included primarily as a development convenience - and
96
+ * thus not recommended for production applications.
97
+ */
98
+	//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
99
+
100
+/**
101
+ * To configure CakePHP to use a particular domain URL
102
+ * for any URL generation inside the application, set the following
103
+ * configuration variable to the http(s) address to your domain. This
104
+ * will override the automatic detection of full base URL and can be
105
+ * useful when generating links from the CLI (e.g. sending emails)
106
+ */
107
+	//Configure::write('App.fullBaseUrl', 'http://example.com');
108
+
109
+/**
110
+ * Web path to the public images directory under webroot.
111
+ * If not set defaults to 'img/'
112
+ */
113
+	//Configure::write('App.imageBaseUrl', 'img/');
114
+
115
+/**
116
+ * Web path to the CSS files directory under webroot.
117
+ * If not set defaults to 'css/'
118
+ */
119
+	//Configure::write('App.cssBaseUrl', 'css/');
120
+
121
+/**
122
+ * Web path to the js files directory under webroot.
123
+ * If not set defaults to 'js/'
124
+ */
125
+	//Configure::write('App.jsBaseUrl', 'js/');
126
+
127
+/**
128
+ * Uncomment the define below to use CakePHP prefix routes.
129
+ *
130
+ * The value of the define determines the names of the routes
131
+ * and their associated controller actions:
132
+ *
133
+ * Set to an array of prefixes you want to use in your application. Use for
134
+ * admin or other prefixed routes.
135
+ *
136
+ * 	Routing.prefixes = array('admin', 'manager');
137
+ *
138
+ * Enables:
139
+ *	`admin_index()` and `/admin/controller/index`
140
+ *	`manager_index()` and `/manager/controller/index`
141
+ */
142
+	//Configure::write('Routing.prefixes', array('admin'));
143
+
144
+/**
145
+ * Turn off all caching application-wide.
146
+ */
147
+	//Configure::write('Cache.disable', true);
148
+
149
+/**
150
+ * Enable cache checking.
151
+ *
152
+ * If set to true, for view caching you must still use the controller
153
+ * public $cacheAction inside your controllers to define caching settings.
154
+ * You can either set it controller-wide by setting public $cacheAction = true,
155
+ * or in each action using $this->cacheAction = true.
156
+ */
157
+	//Configure::write('Cache.check', true);
158
+
159
+/**
160
+ * Enable cache view prefixes.
161
+ *
162
+ * If set it will be prepended to the cache name for view file caching. This is
163
+ * helpful if you deploy the same application via multiple subdomains and languages,
164
+ * for instance. Each version can then have its own view cache namespace.
165
+ * Note: The final cache file name will then be `prefix_cachefilename`.
166
+ */
167
+	//Configure::write('Cache.viewPrefix', 'prefix');
168
+
169
+/**
170
+ * Session configuration.
171
+ *
172
+ * Contains an array of settings to use for session configuration. The defaults key is
173
+ * used to define a default preset to use for sessions, any settings declared here will override
174
+ * the settings of the default config.
175
+ *
176
+ * ## Options
177
+ *
178
+ * - `Session.cookie` - The name of the cookie to use. Defaults to 'CAKEPHP'
179
+ * - `Session.timeout` - The number of minutes you want sessions to live for. This timeout is handled by CakePHP
180
+ * - `Session.cookieTimeout` - The number of minutes you want session cookies to live for.
181
+ * - `Session.checkAgent` - Do you want the user agent to be checked when starting sessions? You might want to set the
182
+ *    value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAX
183
+ * - `Session.defaults` - The default configuration set to use as a basis for your session.
184
+ *    There are four builtins: php, cake, cache, database.
185
+ * - `Session.handler` - Can be used to enable a custom session handler. Expects an array of callables,
186
+ *    that can be used with `session_save_handler`. Using this option will automatically add `session.save_handler`
187
+ *    to the ini array.
188
+ * - `Session.autoRegenerate` - Enabling this setting, turns on automatic renewal of sessions, and
189
+ *    sessionids that change frequently. See CakeSession::$requestCountdown.
190
+ * - `Session.ini` - An associative array of additional ini values to set.
191
+ *
192
+ * The built in defaults are:
193
+ *
194
+ * - 'php' - Uses settings defined in your php.ini.
195
+ * - 'cake' - Saves session files in CakePHP's /tmp directory.
196
+ * - 'database' - Uses CakePHP's database sessions.
197
+ * - 'cache' - Use the Cache class to save sessions.
198
+ *
199
+ * To define a custom session handler, save it at /app/Model/Datasource/Session/<name>.php.
200
+ * Make sure the class implements `CakeSessionHandlerInterface` and set Session.handler to <name>
201
+ *
202
+ * To use database sessions, run the app/Config/Schema/sessions.php schema using
203
+ * the cake shell command: cake schema create Sessions
204
+ */
205
+	Configure::write('Session', array(
206
+		'defaults' => 'php'
207
+	));
208
+
209
+/**
210
+ * A random string used in security hashing methods.
211
+ */	Configure::write('Security.salt', '2caa4a6de2fa8d7f4ebb8275bde4f5cd8c5206ce');
212
+
213
+/**
214
+ * A random numeric string (digits only) used to encrypt/decrypt strings.
215
+ */	Configure::write('Security.cipherSeed', '643931383032396535353539323061');
216
+
217
+/**
218
+ * Apply timestamps with the last modified time to static assets (js, css, images).
219
+ * Will append a query string parameter containing the time the file was modified. This is
220
+ * useful for invalidating browser caches.
221
+ *
222
+ * Set to `true` to apply timestamps when debug > 0. Set to 'force' to always enable
223
+ * timestamping regardless of debug value.
224
+ */
225
+	//Configure::write('Asset.timestamp', true);
226
+
227
+/**
228
+ * Compress CSS output by removing comments, whitespace, repeating tags, etc.
229
+ * This requires a/var/cache directory to be writable by the web server for caching.
230
+ * and /vendors/csspp/csspp.php
231
+ *
232
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
233
+ */
234
+	//Configure::write('Asset.filter.css', 'css.php');
235
+
236
+/**
237
+ * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
238
+ * output, and setting the config below to the name of the script.
239
+ *
240
+ * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JsHelper::link().
241
+ */
242
+	//Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
243
+
244
+/**
245
+ * The class name and database used in CakePHP's
246
+ * access control lists.
247
+ */
248
+	Configure::write('Acl.classname', 'DbAcl');
249
+	Configure::write('Acl.database', 'default');
250
+
251
+/**
252
+ * Uncomment this line and correct your server timezone to fix
253
+ * any date & time related errors.
254
+ */
255
+	//date_default_timezone_set('UTC');
256
+
257
+/**
258
+ * Cache Engine Configuration
259
+ * Default settings provided below
260
+ *
261
+ * File storage engine.
262
+ *
263
+ * 	 Cache::config('default', array(
264
+ *		'engine' => 'File', //[required]
265
+ *		'duration' => 3600, //[optional]
266
+ *		'probability' => 100, //[optional]
267
+ * 		'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
268
+ * 		'prefix' => 'cake_', //[optional]  prefix every cache file with this string
269
+ * 		'lock' => false, //[optional]  use file locking
270
+ * 		'serialize' => true, //[optional]
271
+ * 		'mask' => 0664, //[optional]
272
+ *	));
273
+ *
274
+ * APC (http://pecl.php.net/package/APC)
275
+ *
276
+ * 	 Cache::config('default', array(
277
+ *		'engine' => 'Apc', //[required]
278
+ *		'duration' => 3600, //[optional]
279
+ *		'probability' => 100, //[optional]
280
+ * 		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional]  prefix every cache file with this string
281
+ *	));
282
+ *
283
+ * Xcache (http://xcache.lighttpd.net/)
284
+ *
285
+ * 	 Cache::config('default', array(
286
+ *		'engine' => 'Xcache', //[required]
287
+ *		'duration' => 3600, //[optional]
288
+ *		'probability' => 100, //[optional]
289
+ *		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
290
+ *		'user' => 'user', //user from xcache.admin.user settings
291
+ *		'password' => 'password', //plaintext password (xcache.admin.pass)
292
+ *	));
293
+ *
294
+ * Memcache (http://www.danga.com/memcached/)
295
+ *
296
+ * 	 Cache::config('default', array(
297
+ *		'engine' => 'Memcache', //[required]
298
+ *		'duration' => 3600, //[optional]
299
+ *		'probability' => 100, //[optional]
300
+ * 		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional]  prefix every cache file with this string
301
+ * 		'servers' => array(
302
+ * 			'127.0.0.1:11211' // localhost, default port 11211
303
+ * 		), //[optional]
304
+ * 		'persistent' => true, // [optional] set this to false for non-persistent connections
305
+ * 		'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
306
+ *	));
307
+ *
308
+ *  Wincache (http://php.net/wincache)
309
+ *
310
+ * 	 Cache::config('default', array(
311
+ *		'engine' => 'Wincache', //[required]
312
+ *		'duration' => 3600, //[optional]
313
+ *		'probability' => 100, //[optional]
314
+ *		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional]  prefix every cache file with this string
315
+ *	));
316
+ */
317
+
318
+/**
319
+ * Configure the cache handlers that CakePHP will use for internal
320
+ * metadata like class maps, and model schema.
321
+ *
322
+ * By default File is used, but for improved performance you should use APC.
323
+ *
324
+ * Note: 'default' and other application caches should be configured in app/Config/bootstrap.php.
325
+ *       Please check the comments in bootstrap.php for more info on the cache engines available
326
+ *       and their settings.
327
+ */
328
+$engine = 'File';
329
+
330
+// In development mode, caches should expire quickly.
331
+$duration = '+999 days';
332
+if (Configure::read('debug') > 0) {
333
+	$duration = '+10 seconds';
334
+}
335
+
336
+// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
337
+$prefix = 'app_';
338
+
339
+/**
340
+ * Configure the cache used for general framework caching. Path information,
341
+ * object listings, and translation cache files are stored with this configuration.
342
+ */
343
+Cache::config('_cake_core_', array(
344
+	'engine' => $engine,
345
+	'prefix' => $prefix . 'cake_core_',
346
+	'path' => CACHE . 'persistent' . DS,
347
+	'serialize' => ($engine === 'File'),
348
+	'duration' => $duration
349
+));
350
+
351
+/**
352
+ * Configure the cache for model and datasource caches. This cache configuration
353
+ * is used to store schema descriptions, and table listings in connections.
354
+ */
355
+Cache::config('_cake_model_', array(
356
+	'engine' => $engine,
357
+	'prefix' => $prefix . 'cake_model_',
358
+	'path' => CACHE . 'models' . DS,
359
+	'serialize' => ($engine === 'File'),
360
+	'duration' => $duration
361
+));

+ 75
- 0
app/Config/database.php 파일 보기

1
+<?php
2
+/**
3
+ * @link          http://cakephp.org CakePHP(tm) Project
4
+ * @package       app.Config
5
+ * @since         CakePHP(tm) v 0.2.9
6
+ */
7
+
8
+/**
9
+ * Database configuration class.
10
+ * You can specify multiple configurations for production, development and testing.
11
+ *
12
+ * datasource => The name of a supported datasource; valid options are as follows:
13
+ *  Database/Mysql - MySQL 4 & 5,
14
+ *  Database/Sqlite - SQLite (PHP5 only),
15
+ *  Database/Postgres - PostgreSQL 7 and higher,
16
+ *  Database/Sqlserver - Microsoft SQL Server 2005 and higher
17
+ *
18
+ * You can add custom database datasources (or override existing datasources) by adding the
19
+ * appropriate file to app/Model/Datasource/Database. Datasources should be named 'MyDatasource.php',
20
+ *
21
+ *
22
+ * persistent => true / false
23
+ * Determines whether or not the database should use a persistent connection
24
+ *
25
+ * host =>
26
+ * the host you connect to the database. To add a socket or port number, use 'port' => #
27
+ *
28
+ * prefix =>
29
+ * Uses the given prefix for all the tables in this database. This setting can be overridden
30
+ * on a per-table basis with the Model::$tablePrefix property.
31
+ *
32
+ * schema =>
33
+ * For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use
34
+ * the connected user's default schema (typically 'dbo').
35
+ *
36
+ * encoding =>
37
+ * For MySQL, Postgres specifies the character encoding to use when connecting to the
38
+ * database. Uses database default not specified.
39
+ *
40
+ * unix_socket =>
41
+ * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
42
+ *
43
+ * settings =>
44
+ * Array of key/value pairs, on connection it executes SET statements for each pair
45
+ * For MySQL : http://dev.mysql.com/doc/refman/5.6/en/set-statement.html
46
+ * For Postgres : http://www.postgresql.org/docs/9.2/static/sql-set.html
47
+ * For Sql Server : http://msdn.microsoft.com/en-us/library/ms190356.aspx
48
+ *
49
+ * flags =>
50
+ * A key/value array of driver specific connection options.
51
+ */
52
+class DATABASE_CONFIG {
53
+
54
+	public $default = array(
55
+		'datasource' => 'Database/Mysql',
56
+		'persistent' => false,
57
+		'host' => 'localhost',
58
+		'login' => 'root',
59
+		'password' => 'password',
60
+		'database' => 'vitrine',
61
+		'prefix' => '',
62
+		'encoding' => 'utf8',
63
+	);
64
+
65
+	public $test = array(
66
+		'datasource' => 'Database/Mysql',
67
+		'persistent' => false,
68
+		'host' => 'localhost',
69
+		'login' => 'user',
70
+		'password' => 'password',
71
+		'database' => 'test_database_name',
72
+		'prefix' => '',
73
+		//'encoding' => 'utf8',
74
+	);
75
+}

+ 82
- 0
app/Config/email.php.default 파일 보기

1
+<?php
2
+/**
3
+ * This is email configuration file.
4
+ *
5
+ * Use it to configure email transports of Cake.
6
+ *
7
+ * @link          http://cakephp.org CakePHP(tm) Project
8
+ * @package       app.Config
9
+ * @since         CakePHP(tm) v 2.0.0
10
+ */
11
+
12
+/**
13
+ * Email configuration class.
14
+ * You can specify multiple configurations for production, development and testing.
15
+ *
16
+ * transport => The name of a supported transport; valid options are as follows:
17
+ *		Mail		- Send using PHP mail function
18
+ *		Smtp		- Send using SMTP
19
+ *		Debug		- Do not send the email, just return the result
20
+ *
21
+ * You can add custom transports (or override existing transports) by adding the
22
+ * appropriate file to app/Network/Email. Transports should be named 'YourTransport.php',
23
+ * where 'Your' is the name of the transport.
24
+ *
25
+ * from =>
26
+ * The origin email. See CakeEmail::from() about the valid values
27
+ */
28
+class EmailConfig {
29
+
30
+	public $default = array(
31
+		'transport' => 'Mail',
32
+		'from' => 'you@localhost',
33
+		//'charset' => 'utf-8',
34
+		//'headerCharset' => 'utf-8',
35
+	);
36
+
37
+	public $smtp = array(
38
+		'transport' => 'Smtp',
39
+		'from' => array('site@localhost' => 'My Site'),
40
+		'host' => 'localhost',
41
+		'port' => 25,
42
+		'timeout' => 30,
43
+		'username' => 'user',
44
+		'password' => 'secret',
45
+		'client' => null,
46
+		'log' => false,
47
+		//'charset' => 'utf-8',
48
+		//'headerCharset' => 'utf-8',
49
+	);
50
+
51
+	public $fast = array(
52
+		'from' => 'you@localhost',
53
+		'sender' => null,
54
+		'to' => null,
55
+		'cc' => null,
56
+		'bcc' => null,
57
+		'replyTo' => null,
58
+		'readReceipt' => null,
59
+		'returnPath' => null,
60
+		'messageId' => true,
61
+		'subject' => null,
62
+		'message' => null,
63
+		'headers' => null,
64
+		'viewRender' => null,
65
+		'template' => false,
66
+		'layout' => false,
67
+		'viewVars' => null,
68
+		'attachments' => null,
69
+		'emailFormat' => null,
70
+		'transport' => 'Smtp',
71
+		'host' => 'localhost',
72
+		'port' => 25,
73
+		'timeout' => 30,
74
+		'username' => 'user',
75
+		'password' => 'secret',
76
+		'client' => null,
77
+		'log' => true,
78
+		//'charset' => 'utf-8',
79
+		//'headerCharset' => 'utf-8',
80
+	);
81
+
82
+}

+ 36
- 0
app/Config/routes.php 파일 보기

1
+<?php
2
+/**
3
+ * Routes configuration
4
+ *
5
+ * In this file, you set up routes to your controllers and their actions.
6
+ * Routes are very important mechanism that allows you to freely connect
7
+ * different URLs to chosen controllers and their actions (functions).
8
+ *
9
+ * @link          http://cakephp.org CakePHP(tm) Project
10
+ * @package       app.Config
11
+ * @since         CakePHP(tm) v 0.2.9
12
+ */
13
+
14
+/**
15
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
16
+ * its action called 'display', and we pass a param to select the view file
17
+ * to use (in this case, /app/View/Pages/home.ctp)...
18
+ */
19
+	Router::connect('/', array('controller' => 'pages', 'action' => 'home'));
20
+	Router::connect('/:action', array('controller' => 'pages', 'action' => 'default'));
21
+/**
22
+ * ...and connect the rest of 'Pages' controller's URLs.
23
+ */
24
+	//Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
25
+
26
+/**
27
+ * Load all plugin routes. See the CakePlugin documentation on
28
+ * how to customize the loading of plugin routes.
29
+ */
30
+	CakePlugin::routes();
31
+
32
+/**
33
+ * Load the CakePHP default routes. Only remove this if you do not want to use
34
+ * the built-in default routes.
35
+ */
36
+	require CAKE . 'Config' . DS . 'routes.php';

+ 21
- 0
app/Console/Command/AppShell.php 파일 보기

1
+<?php
2
+/**
3
+ * AppShell file
4
+ *
5
+ * @link          http://cakephp.org CakePHP(tm) Project
6
+ * @since         CakePHP(tm) v 2.0
7
+ */
8
+
9
+App::uses('Shell', 'Console');
10
+
11
+/**
12
+ * Application Shell
13
+ *
14
+ * Add your application-wide methods in the class below, your shells
15
+ * will inherit them.
16
+ *
17
+ * @package       app.Console.Command
18
+ */
19
+class AppShell extends Shell {
20
+
21
+}

+ 41
- 0
app/Console/cake 파일 보기

1
+#!/usr/bin/env bash
2
+################################################################################
3
+#
4
+# Bake is a shell script for running CakePHP bake script
5
+#
6
+# CakePHP(tm) :  Rapid Development Framework (http://cakephp.org)
7
+# Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
8
+#
9
+# Licensed under The MIT License
10
+# For full copyright and license information, please see the LICENSE.txt
11
+# Redistributions of files must retain the above copyright notice.
12
+#
13
+# @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+# @link          http://cakephp.org CakePHP(tm) Project
15
+# @package       app.Console
16
+# @since         CakePHP(tm) v 1.2.0.5012
17
+# @license       http://www.opensource.org/licenses/mit-license.php MIT License
18
+#
19
+################################################################################
20
+
21
+# Canonicalize by following every symlink of the given name recursively
22
+canonicalize() {
23
+	NAME="$1"
24
+	if [ -f "$NAME" ]
25
+	then
26
+		DIR=$(dirname -- "$NAME")
27
+		NAME=$(cd -P "$DIR" && pwd -P)/$(basename -- "$NAME")
28
+	fi
29
+	while [ -h "$NAME" ]; do
30
+		DIR=$(dirname -- "$NAME")
31
+		SYM=$(readlink "$NAME")
32
+		NAME=$(cd "$DIR" && cd $(dirname -- "$SYM") && pwd)/$(basename -- "$SYM")
33
+	done
34
+	echo "$NAME"
35
+}
36
+
37
+CONSOLE=$(dirname -- "$(canonicalize "$0")")
38
+APP=$(dirname "$CONSOLE")
39
+
40
+exec php -q "$CONSOLE"/cake.php -working "$APP" "$@"
41
+exit

+ 30
- 0
app/Console/cake.bat 파일 보기

1
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2
+::
3
+:: Bake is a shell script for running CakePHP bake script
4
+::
5
+:: CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6
+:: Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
+::
8
+:: Licensed under The MIT License
9
+:: Redistributions of files must retain the above copyright notice.
10
+::
11
+:: @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
12
+:: @link          http://cakephp.org CakePHP(tm) Project
13
+:: @package       app.Console
14
+:: @since         CakePHP(tm) v 2.0
15
+::
16
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
17
+
18
+:: In order for this script to work as intended, the cake\console\ folder must be in your PATH
19
+
20
+@echo.
21
+@echo off
22
+
23
+SET app=%0
24
+SET lib=%~dp0
25
+
26
+php -q "%lib%cake.php" -working "%CD% " %*
27
+
28
+echo.
29
+
30
+exit /B %ERRORLEVEL%

+ 48
- 0
app/Console/cake.php 파일 보기

1
+#!/usr/bin/php -q
2
+<?php
3
+/**
4
+ * Command-line code generation utility to automate programmer chores.
5
+ *
6
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
7
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
8
+ *
9
+ * Licensed under The MIT License
10
+ * For full copyright and license information, please see the LICENSE.txt
11
+ * Redistributions of files must retain the above copyright notice.
12
+ *
13
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
14
+ * @link          http://cakephp.org CakePHP(tm) Project
15
+ * @package       app.Console
16
+ * @since         CakePHP(tm) v 2.0
17
+ */
18
+
19
+if (!defined('DS')) {
20
+	define('DS', DIRECTORY_SEPARATOR);
21
+}
22
+
23
+$dispatcher = 'Cake' . DS . 'Console' . DS . 'ShellDispatcher.php';
24
+
25
+if (function_exists('ini_set')) {
26
+	$root = dirname(dirname(dirname(__FILE__)));
27
+	$appDir = basename(dirname(dirname(__FILE__)));
28
+	$install = $root . DS . 'lib';
29
+	$composerInstall = $root . DS . $appDir . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib';
30
+
31
+	// the following lines differ from its sibling
32
+	// /app/Console/cake.php
33
+	if (file_exists($composerInstall . DS . $dispatcher)) {
34
+		$install = $composerInstall;
35
+	} elseif (!file_exists($install . DS . $dispatcher)) {
36
+		$install = $root . PATH_SEPARATOR .  DS . 'home' . DS . 'kod3' . DS . 'work' . DS . 'vitrine' . DS . 'vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib';
37
+	}
38
+
39
+	ini_set('include_path', $install . PATH_SEPARATOR . ini_get('include_path'));
40
+	unset($root, $appDir, $install, $composerInstall);
41
+}
42
+
43
+if (!include $dispatcher) {
44
+	trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
45
+}
46
+unset($dispatcher);
47
+
48
+return ShellDispatcher::run($argv);

+ 0
- 0
app/Controller/AppController.php 파일 보기


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.