You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.5KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\debug\controllers;
  8. use Yii;
  9. use yii\web\Controller;
  10. use yii\web\NotFoundHttpException;
  11. use yii\debug\models\search\Debug;
  12. /**
  13. * Debugger controller
  14. *
  15. * @author Qiang Xue <qiang.xue@gmail.com>
  16. * @since 2.0
  17. */
  18. class DefaultController extends Controller
  19. {
  20. /**
  21. * @inheritdoc
  22. */
  23. public $layout = 'main';
  24. /**
  25. * @var \yii\debug\Module
  26. */
  27. public $module;
  28. /**
  29. * @var array the summary data (e.g. URL, time)
  30. */
  31. public $summary;
  32. /**
  33. * @inheritdoc
  34. */
  35. public function actions()
  36. {
  37. $actions = [];
  38. foreach ($this->module->panels as $panel) {
  39. $actions = array_merge($actions, $panel->actions);
  40. }
  41. return $actions;
  42. }
  43. public function actionIndex()
  44. {
  45. $searchModel = new Debug();
  46. $dataProvider = $searchModel->search($_GET, $this->getManifest());
  47. // load latest request
  48. $tags = array_keys($this->getManifest());
  49. $tag = reset($tags);
  50. $this->loadData($tag);
  51. return $this->render('index', [
  52. 'panels' => $this->module->panels,
  53. 'dataProvider' => $dataProvider,
  54. 'searchModel' => $searchModel,
  55. 'manifest' => $this->getManifest(),
  56. ]);
  57. }
  58. public function actionView($tag = null, $panel = null)
  59. {
  60. if ($tag === null) {
  61. $tags = array_keys($this->getManifest());
  62. $tag = reset($tags);
  63. }
  64. $this->loadData($tag);
  65. if (isset($this->module->panels[$panel])) {
  66. $activePanel = $this->module->panels[$panel];
  67. } else {
  68. $activePanel = $this->module->panels['request'];
  69. }
  70. return $this->render('view', [
  71. 'tag' => $tag,
  72. 'summary' => $this->summary,
  73. 'manifest' => $this->getManifest(),
  74. 'panels' => $this->module->panels,
  75. 'activePanel' => $activePanel,
  76. ]);
  77. }
  78. public function actionToolbar($tag)
  79. {
  80. $this->loadData($tag, 5);
  81. return $this->renderPartial('toolbar', [
  82. 'tag' => $tag,
  83. 'panels' => $this->module->panels,
  84. 'position' => 'bottom',
  85. ]);
  86. }
  87. public function actionDownloadMail($file)
  88. {
  89. $filePath = Yii::getAlias($this->module->panels['mail']->mailPath) . '/' . basename($file);
  90. if ((mb_strpos($file, '\\') !== false || mb_strpos($file, '/') !== false) || !is_file($filePath)) {
  91. throw new NotFoundHttpException('Mail file not found');
  92. }
  93. Yii::$app->response->sendFile($filePath);
  94. }
  95. private $_manifest;
  96. protected function getManifest($forceReload = false)
  97. {
  98. if ($this->_manifest === null || $forceReload) {
  99. if ($forceReload) {
  100. clearstatcache();
  101. }
  102. $indexFile = $this->module->dataPath . '/index.data';
  103. $content = '';
  104. $fp = @fopen($indexFile, 'r');
  105. if ($fp !== false) {
  106. @flock($fp, LOCK_SH);
  107. $content = fread($fp, filesize($indexFile));
  108. @flock($fp, LOCK_UN);
  109. fclose($fp);
  110. }
  111. if ($content !== '') {
  112. $this->_manifest = array_reverse(unserialize($content), true);
  113. } else {
  114. $this->_manifest = [];
  115. }
  116. }
  117. return $this->_manifest;
  118. }
  119. public function loadData($tag, $maxRetry = 0)
  120. {
  121. // retry loading debug data because the debug data is logged in shutdown function
  122. // which may be delayed in some environment if xdebug is enabled.
  123. // See: https://github.com/yiisoft/yii2/issues/1504
  124. for ($retry = 0; $retry <= $maxRetry; ++$retry) {
  125. $manifest = $this->getManifest($retry > 0);
  126. if (isset($manifest[$tag])) {
  127. $dataFile = $this->module->dataPath . "/$tag.data";
  128. $data = unserialize(file_get_contents($dataFile));
  129. foreach ($this->module->panels as $id => $panel) {
  130. if (isset($data[$id])) {
  131. $panel->tag = $tag;
  132. $panel->load($data[$id]);
  133. }
  134. }
  135. $this->summary = $data['summary'];
  136. return;
  137. }
  138. sleep(1);
  139. }
  140. throw new NotFoundHttpException("Unable to find debug data tagged with '$tag'.");
  141. }
  142. }