Base for a static organization website

ToolbarHelper.php 6.2KB

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