PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/active_support/core/debug.php

https://github.com/bermi/akelos
PHP | 319 lines | 204 code | 24 blank | 91 comment | 46 complexity | 88cc212589f65d89e66d0ea03dfb1ed1 MD5 | raw file
  1. <?php
  2. class AkDebug
  3. {
  4. /**
  5. * Trace helper function for development purposes
  6. *
  7. * @access public
  8. * @static
  9. * @param string $text Helper text
  10. * @param string $line Helper line
  11. * @param string $file Helper file
  12. * @return echoes result to screen
  13. */
  14. static function trace($text = null, $line = null, $file = null, $method = null, $escape_html_entities = true) {
  15. static $counter = 0;
  16. if(AK_PRODUCTION_MODE){
  17. return;
  18. }
  19. $html_entities_function = $escape_html_entities ? 'htmlentities' : 'trim';
  20. list($default_file, $default_line, $default_method) = self::getLastFileAndLineAndMethod();
  21. $default_method = is_bool($text) || empty($text) ? 'var_dump' : $default_method;
  22. $line = is_null($line) ? $default_line : $line;
  23. $file = is_null($file) ? $default_file : $file;
  24. $method = is_null($method) ? $default_method : $method;
  25. if(AK_CLI){
  26. $text = self::dump($text, 'print_r');
  27. }elseif (!empty($text) && !is_scalar($text)){
  28. $rand = Ak::randomString();
  29. $formatted = '';
  30. $methods = array('print_r', 'var_dump', 'var_export');
  31. foreach ($methods as $method){
  32. $pre_style = 'display:none;';
  33. if(defined('AK_TRACE_DUMP_METHOD')){
  34. if(AK_TRACE_DUMP_METHOD == $method){
  35. $pre_style = '';
  36. }
  37. }elseif ($method == 'print_r'){
  38. $pre_style = '';
  39. }
  40. $element_id = $method.'_'.$rand;
  41. $formatted .= "<div style='margin:10px;'><a href='javascript:void(0);' onclick='e_$element_id = document.getElementById(\"$element_id\"); e_$element_id.style.display = (e_$element_id.style.display == \"none\"?\"block\":\"none\");' title='Set the constant AK_TRACE_DUMP_METHOD to your favourite default method'>$method</a><br />".
  42. '<pre style="'.$pre_style.'" id="'.$element_id.'">'.$html_entities_function(self::dump($text, $method)).'</pre></div>';
  43. }
  44. $text = $formatted;
  45. }elseif (is_bool($text) || empty($text)){
  46. $text = '<pre style="margin:10px;">'.$html_entities_function(self::dump($text, $default_method)).'</pre>';
  47. }elseif (is_scalar($text)){
  48. $text = '<pre style="margin:10px;">'.$html_entities_function($text).'</pre>';
  49. }
  50. if(!isset($text)){
  51. $counter++;
  52. $text = '';
  53. }else {
  54. $text = AK_CLI?'---> '.$text : ($text);
  55. }
  56. $include_file_and_line = strlen(trim($file.$line)) > 0;
  57. if($include_file_and_line){
  58. echo AK_CLI?"----------------\n$file ($line):\n $text\n----------------\n":"<div style='background-color:#fff;margin:10px;color:#000;font-family:sans-serif;border:3px solid #fc0;font-size:12px;'><div style='background-color:#ffc;padding:10px;color:#000;font-family:sans-serif;'>$file <span style='font-weight:bold'>$line</span></div>".$text."</div>\n";
  59. }else{
  60. echo AK_CLI?"----------------\n $text\n----------------\n":"<div style='background-color:#fff;margin:10px;color:#000;font-family:sans-serif;border:1px solid #ccc;font-size:12px;'>".$text."</div>\n";
  61. }
  62. }
  63. /**
  64. * Returns a string representation of one of these PHP methods var_dump, var_export, or print_r
  65. */
  66. static function dump($var, $method = null, $max_length = null) {
  67. $method = empty($method) ? (defined('AK_TRACE_DUMP_METHOD') ? AK_TRACE_DUMP_METHOD : 'var_dump') : $method;
  68. $methods = array('var_dump', 'var_export', 'print_r');
  69. if(!in_array($method, $methods)){
  70. trigger_error(Ak::t('Invalid dump method, valid options are %methods', array('%methods'=>join(", ", $methods))), E_USER_ERROR);
  71. return false;
  72. }
  73. ob_start();
  74. if(is_object($var)){
  75. !method_exists($var, '__toString') ? $method($var) : print($var);
  76. }else{
  77. $method($var);
  78. }
  79. $contents = ob_get_contents();
  80. $max_length = defined('AK_DUMP_MAX_LENGTH') ? AK_DUMP_MAX_LENGTH : 10000000;
  81. $result = $max_length ? substr($contents, 0, $max_length) : $contents;
  82. if($contents != $result){
  83. $result .= ' ...dump truncated at max length of '.$max_length.' chars define AK_DUMP_MAX_LENGTH to false or to a larger number';
  84. }
  85. ob_end_clean();
  86. return $result;
  87. }
  88. static function getLastFileAndLineAndMethod($only_app = false, $start_level = 1) {
  89. $backtrace = debug_backtrace();
  90. if(!$only_app){
  91. return array(@$backtrace[$start_level]['file'], @$backtrace[$start_level]['line'], @$backtrace[$start_level]['function']);
  92. }else{
  93. for($i = $start_level-1; $i <= count($backtrace) - 1; $i++){
  94. if(isset($backtrace[$i]["line"])){
  95. if(strstr($backtrace[$i]["file"], AK_COMPILED_VIEWS_DIR) || strstr($backtrace[$i]["file"], AkConfig::getDir('app'))){
  96. return array($backtrace[$i]["file"], $backtrace[$i]["line"], $backtrace[$i]["function"]);
  97. }
  98. }
  99. }
  100. }
  101. }
  102. static function getFileAndNumberTextForError($levels = 0) {
  103. list($file,$line,$method) = self::getLastFileAndLineAndMethod(false, $levels+1);
  104. return Ak::t('In %file line %line', array('%file' => $file, '%line' => $line));
  105. }
  106. /**
  107. * Outputs debug info given a PHP resource (vars, objects,
  108. * arrays...)
  109. *
  110. * @access public
  111. * @static
  112. * @param mixed $data Data to debug. It can be an object, array,
  113. * resource..
  114. * @return void Prints debug info.
  115. */
  116. static function debug ($data, $_functions=0) {
  117. if(!AK_DEBUG && !AK_DEV_MODE){
  118. return;
  119. }
  120. if($_functions!=0) {
  121. $sf=1;
  122. } else {
  123. $sf=0 ;
  124. }
  125. if(is_object($data) && method_exists($data, 'debug')){
  126. echo AK_CLI ?
  127. "\n------------------------------------\nEntering on ".get_class($data)." debug() method\n\n":
  128. "<hr /><h2>Entering on ".get_class($data)." debug() method</h2>";
  129. if(!empty($data->__activeRecordObject)){
  130. $data->toString(true);
  131. }
  132. $data->debug();
  133. return ;
  134. }
  135. if (isset ($data)) {
  136. if (is_array($data) || is_object($data)) {
  137. if (count ($data)) {
  138. echo AK_CLI ? "/--\n" : "<ol>\n";
  139. while (list ($key,$value) = each ($data)) {
  140. $type=gettype($value);
  141. if ($type=="array" || $type == "object") {
  142. ob_start();
  143. self::debug ($value,$sf);
  144. $lines = explode("\n",ob_get_clean()."\n");
  145. foreach ($lines as $line){
  146. echo "\t".$line."\n";
  147. }
  148. } elseif (stristr($type, "function")) {
  149. if ($sf) {
  150. AK_CLI ? printf ("\t* (%s) %s:\n",$type, $key, $value) :
  151. printf ("<li>(%s) <b>%s</b> </li>\n",$type, $key, $value);
  152. }
  153. } else {
  154. if (!$value) {
  155. $value="(none)";
  156. }
  157. AK_CLI ? printf ("\t* (%s) %s = %s\n",$type, $key, $value) :
  158. printf ("<li>(%s) <b>%s</b> = %s</li>\n",$type, $key, $value);
  159. }
  160. }
  161. echo AK_CLI ? "\n--/\n" : "</ol>fin.\n";
  162. } else {
  163. echo "(empty)";
  164. }
  165. }
  166. }
  167. }
  168. /**
  169. * Gets information about given object
  170. *
  171. * @access public
  172. * @static
  173. * @uses AkDebug::get_this_object_methods
  174. * @uses AkDebug::get_this_object_attributes
  175. * @param object &$object Object to get info from
  176. * @param boolean $include_inherited_info By setting this to true, parent Object properties
  177. * and methods will be included.
  178. * @return string html output with Object info
  179. */
  180. static function get_object_info($object, $include_inherited_info = false) {
  181. $object_name = get_class($object);
  182. $methods = $include_inherited_info ? get_class_methods($object) : self::get_this_object_methods($object);
  183. $vars = $include_inherited_info ? get_class_vars($object_name) : self::get_this_object_attributes($object);
  184. $var_desc = '';
  185. if(is_array($vars)){
  186. $var_desc = '<ul>';
  187. foreach ($vars as $varname=>$var_value){
  188. $var_desc .= "<li>$varname = $var_value (". gettype($var_value) .")</li>\n";
  189. }
  190. $var_desc .= "</ul>";
  191. }
  192. return Ak::t('Object <b>%object_name</b> information:<hr> <b>object Vars:</b><br>%var_desc <hr> <b>object Methods:</b><br><ul><li>%methods</li></ul>',array('%object_name'=>$object_name,'%var_desc'=>$var_desc,'%methods'=>join("();</li>\n<li>",$methods) .'();'));
  193. }
  194. /**
  195. * Gets selected object methods.
  196. *
  197. * WARNING: Inherited methods are not returned by this
  198. * function. You can fetch them by using PHP native function
  199. * get_class_methods
  200. *
  201. * @access public
  202. * @static
  203. * @see get_this_object_attributes
  204. * @see get_object_info
  205. * @param object &$object Object to inspect
  206. * @return array Returns an array with selected object methods. It
  207. * does not return inherited methods
  208. */
  209. static function get_this_object_methods($object) {
  210. $array1 = get_class_methods($object);
  211. if($parent_object = get_parent_class($object)){
  212. $array2 = get_class_methods($parent_object);
  213. $array3 = array_diff($array1, $array2);
  214. }else{
  215. $array3 = $array1;
  216. }
  217. return array_values((array)$array3);
  218. }
  219. /**
  220. * Get selected objects default attributes
  221. *
  222. * WARNING: Inherited attributes are not returned by this
  223. * function. You can fetch them by using PHP native function
  224. * get_class_vars
  225. *
  226. * @access public
  227. * @static
  228. * @see get_this_object_methods
  229. * @see get_object_info
  230. * @param object &$object Object to inspect
  231. * @return void Returns an array with selected object attributes.
  232. * It does not return inherited attributes
  233. */
  234. static function get_this_object_attributes($object) {
  235. $object = get_class($object);
  236. $array1 = get_class_vars($object);
  237. if($parent_object = get_parent_class($object)){
  238. $array2 = get_class_vars($parent_object);
  239. $array3 = array_diff_assoc($array1, $array2);
  240. }else{
  241. $array3 = $array1;
  242. }
  243. return (array)$array3;
  244. }
  245. static function get_constants() {
  246. $constants = get_defined_constants();
  247. $keys = array_keys($constants);
  248. foreach ($keys as $k){
  249. if(substr($k,0,3) != 'AK_'){
  250. unset($constants[$k]);
  251. }
  252. }
  253. return $constants;
  254. }
  255. /**
  256. * Add a profile message that can be displayed after executing the script
  257. *
  258. * You can add benchmark markers by calling
  259. *
  260. * AkDebug::profile('Searching for books');
  261. *
  262. * To display the results you need to call
  263. *
  264. * AkDebug::profile(true);
  265. *
  266. * You might also find handy adding this to your application controller.
  267. *
  268. * class ApplicationController extends BaseActionController
  269. * {
  270. * static function __construct(){
  271. * $this->afterFilter('_displayBenchmark');
  272. * parent::__construct();
  273. * }
  274. * static function _displayBenchmark(){
  275. * AkDebug::profile(true);
  276. * }
  277. * }
  278. *
  279. * IMPORTANT NOTE: You must define AK_ENABLE_PROFILER to true for this to work.
  280. */
  281. static function profile($message = '') {
  282. if(AK_ENABLE_PROFILER){
  283. if(!$ProfileTimer = $Timer = Ak::getStaticVar('ProfileTimer')){
  284. require_once 'Benchmark/Timer.php';
  285. $ProfileTimer = new Benchmark_Timer();
  286. $ProfileTimer->start();
  287. Ak::setStaticVar('ProfileTimer', $ProfileTimer);
  288. }elseif($message === true){
  289. $ProfileTimer->display();
  290. }else {
  291. $ProfileTimer->setMarker($message);
  292. }
  293. }
  294. }
  295. }