174 lines
4.7KB

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