Permalink
Browse files

Added ability to config the trace file and line number (#162)

closes #114
  • Loading branch information...
1 parent 99f2f92 commit ed07955e80185874d4d244e8e5c25cd8a890e82e @thiagotalma thiagotalma committed with dynasource Nov 10, 2016
Showing with 283 additions and 10 deletions.
  1. +1 −0 CHANGELOG.md
  2. +19 −0 Module.php
  3. +21 −0 Panel.php
  4. +22 −0 README.md
  5. +113 −0 docs/guide/installation.md
  6. +92 −0 tests/PanelTest.php
  7. +8 −3 tests/bootstrap.php
  8. +3 −3 views/default/panels/db/detail.php
  9. +4 −4 views/default/panels/log/detail.php
View
@@ -21,6 +21,7 @@ Yii Framework 2 debug extension Change Log
- Enh #97: Added AJAX requests handling (bashkarev)
- Bug #61: Fixed toolbar not to be cached by using renderDynamic (dynasource)
- Bug #160: Remove height as it prevents the background from stretching, causing unreadable overlapping texts over background (dynasource)
+- Enh #162: Added ability to config the trace file and line number (thiagotalma)
2.0.6 March 17, 2016
--------------------
View
@@ -25,6 +25,8 @@
*/
class Module extends \yii\base\Module implements BootstrapInterface
{
+ const DEFAULT_IDE_TRACELINE = '<a href="ide://open?url=file://{file}&line={line}">{text}</a>';
+
/**
* @var array the list of IPs that are allowed to access this module.
* Each array element represents a single IP filter which can be either an IP address
@@ -91,6 +93,23 @@ class Module extends \yii\base\Module implements BootstrapInterface
* You may want to enable the debug logs if you want to investigate how the debug module itself works.
*/
public $enableDebugLogs = false;
+ /**
+ * @var mixed the string with placeholders to be be substituted or an anonymous function that returns the trace line string.
+ * The placeholders are {file}, {line} and {text} and the string should be as follows:
+ *
+ * `File: {file} - Line: {line} - Text: {text}`
+ *
+ * The signature of the anonymous function should be as follows:
+ *
+ * ```php
+ * function($trace, $panel) {
+ * // compute line string
+ * return $line;
+ * }
+ * ```
+ * @since 2.0.7
+ */
+ public $traceLine = self::DEFAULT_IDE_TRACELINE;
/**
* @var string Yii logo URL
View
@@ -114,4 +114,25 @@ public function getUrl($additionalParams = null)
return Url::toRoute($route);
}
+
+ /**
+ * Returns a trace line
+ * @param array $options The array with trace
+ * @return string the trace line
+ * @since 2.0.7
+ */
+ public function getTraceLine($options)
+ {
+ if (!isset($options['text'])) {
+ $options['text'] = "{$options['file']}:{$options['line']}";
+ }
+ $traceLine = $this->module->traceLine;
+ if ($traceLine === false) {
+ return $options['text'];
+ } else {
+ $options['file'] = str_replace('\\', '/', $options['file']);
+ $rawLink = $traceLine instanceof \Closure ? call_user_func($traceLine, $options, $this) : $traceLine;
+ return strtr($rawLink, ['{file}' => $options['file'], '{line}' => $options['line'], '{text}' => $options['text']]);
+ }
+ }
}
View
@@ -53,3 +53,25 @@ return [
You will see a debugger toolbar showing at the bottom of every page of your application.
You can click on the toolbar to see more detailed debug information.
+
+
+Open Files in IDE
+-----
+
+You can create a link to open files in your favorite IDE with this configuration:
+
+```php
+return [
+ 'bootstrap' => ['debug'],
+ 'modules' => [
+ 'debug' => [
+ 'class' => 'yii\debug\Module',
+ 'traceLink' => '<a href="phpstorm://open?url={file}&line={line}">{file}:{line}</a>',
+ ],
+ // ...
+ ],
+ ...
+];
+```
+
+You must make some changes to your OS, see this example: https://github.com/aik099/PhpStormProtocol
@@ -93,3 +93,116 @@ defined('YII_DEBUG') or define('YII_DEBUG', true);
> Note: Make sure to disable debug mode in production environments since it may have a significant and adverse performance
effect. Further, the debug mode may expose sensitive information to end users.
+
+### Extra configuration for opening in IDE's
+
+Wouldn't it be nice to be able to open files directly from the debug trace?
+
+Well, you can!
+With a few settings you're ready to go!
+
+
+#### Windows
+
+##### 1) Create a WScript file open_phpstorm.js:
+Create a file `C:\Program Files (x86)\JetBrains\open_phpstorm.js` (example for PhpStorm)
+with the following content:
+
+```js
+
+var settings = {
+ // Set to 'true' (without quotes) if run on Windows 64bit. Set to 'false' (without quotes) otherwise.
+ x64: true,
+
+ // Set to folder name, where PhpStorm was installed to (e.g. 'PhpStorm')
+ folder_name: 'PhpStorm 2016.2.1',
+
+ // Set to window title (only text after dash sign), that you see, when switching to running PhpStorm instance
+ window_title: 'PhpStorm 2016.2.1',
+
+ // In case your file is mapped via a network share and paths do not match.
+ // eg. /var/www will can replaced with Y:/
+ projects_basepath: '',
+ projects_path_alias: ''
+};
+
+
+// don't change anything below this line, unless you know what you're doing
+var url = WScript.Arguments(0),
+ match = /^ide:\/\/(?:.+)file:\/\/(.+)&line=(\d+)$/.exec(url),
+ project = '',
+ editor = '"C:\\' + (settings.x64 ? 'Program Files' : 'Program Files (x86)') + '\\JetBrains\\' + settings.folder_name + '\\bin\\PhpStorm.exe"';
+
+if (match) {
+
+ var shell = new ActiveXObject('WScript.Shell'),
+ file_system = new ActiveXObject('Scripting.FileSystemObject'),
+ file = decodeURIComponent(match[1]).replace(/\+/g, ' '),
+ search_path = file.replace(/\//g, '\\');
+
+ if (settings.projects_basepath != '' && settings.projects_path_alias != '') {
+ file = file.replace(new RegExp('^' + settings.projects_basepath), settings.projects_path_alias);
+ }
+
+ while (search_path.lastIndexOf('\\') != -1) {
+ search_path = search_path.substring(0, search_path.lastIndexOf('\\'));
+
+ if(file_system.FileExists(search_path+'\\.idea\\.name')) {
+ project = search_path;
+ break;
+ }
+ }
+
+ if (project != '') {
+ editor += ' "%project%"';
+ }
+
+ editor += ' --line %line% "%file%"';
+
+ var command = editor.replace(/%line%/g, match[2])
+ .replace(/%file%/g, file)
+ .replace(/%project%/g, project)
+ .replace(/\//g, '\\');
+
+ shell.Exec(command);
+ shell.AppActivate(settings.window_title);
+}
+```
+
+##### 2) Create a registry file and execute this file
+
+Create a registry file `C:\Program Files (x86)\JetBrains\open_phpstorm.reg` (example for PhpStorm)
+with the following content and make sure the paths are correct:
+
+```windows.reg
+Windows Registry Editor Version 5.00
+
+[HKEY_CLASSES_ROOT\ide]
+@="\"URL:ide Protocol\""
+"URL Protocol"=""
+
+[HKEY_CLASSES_ROOT\ide\shell\open\command]
+@="wscript \"C:\\Program Files (x86)\\JetBrains\\open_phpstorm.js\" %1"
+```
+
+Now you are able to use the ide:// protocol in your browser.
+
+When you click such a link, the IDE will automatically open the file and move the cursor to the corresponding line.
+
+##### Disable links
+IDE links for traces are created by default. You have to set the property `yii\debug\Module::traceLink` to
+ false to render a textual line only.
+
+```php
+<?php
+
+...
+'modules' => [
+ 'debug' => [
+ 'class' => 'yii\debug\Module',
+ 'traceLink' => false
+ ]
+]
+
+...
+```
View
@@ -0,0 +1,92 @@
+<?php
+
+namespace yiiunit\extensions\debug;
+
+use Yii;
+use yii\debug\Module;
+use yii\debug\Panel;
+
+class PanelTest extends TestCase
+{
+ public function testGetTraceLine_DefaultLink()
+ {
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10
+ ];
+ $panel = $this->getPanel();
+ $this->assertEquals('<a href="ide://open?url=file://file.php&line=10">file.php:10</a>', $panel->getTraceLine($traceConfig));
+ }
+
+ public function testGetTraceLine_DefaultLink_CustomText()
+ {
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10,
+ 'text' => 'custom text'
+ ];
+ $panel = $this->getPanel();
+ $this->assertEquals('<a href="ide://open?url=file://file.php&line=10">custom text</a>', $panel->getTraceLine($traceConfig));
+ }
+
+ public function testGetTraceLine_TextOnly()
+ {
+ $panel = $this->getPanel();
+ $panel->module->traceLine = false;
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10
+ ];
+ $this->assertEquals('file.php:10', $panel->getTraceLine($traceConfig));
+ }
+
+ public function testGetTraceLine_CustomLinkByString()
+ {
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10
+ ];
+ $panel = $this->getPanel();
+ $panel->module->traceLine = '<a href="phpstorm://open?url=file://file.php&line=10">my custom phpstorm protocol</a>';
+ $this->assertEquals('<a href="phpstorm://open?url=file://file.php&line=10">my custom phpstorm protocol</a>', $panel->getTraceLine($traceConfig));
+ }
+
+ public function testGetTraceLine_CustomLinkByCallback()
+ {
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10,
+ ];
+ $panel = $this->getPanel();
+ $expected = 'http://my.custom.link';
+ $panel->module->traceLine = function () use ($expected) {
+ return $expected;
+ };
+ $this->assertEquals($expected, $panel->getTraceLine($traceConfig));
+ }
+
+ public function testGetTraceLine_CustomLinkByCallback_CustomText()
+ {
+ $traceConfig = [
+ 'file' => 'file.php',
+ 'line' => 10,
+ 'text' => 'custom text'
+ ];
+ $panel = $this->getPanel();
+ $panel->module->traceLine = function () {
+ return '<a href="ide://open?url={file}&line={line}">{text}</a>';
+ };
+ $this->assertEquals('<a href="ide://open?url=file.php&line=10">custom text</a>', $panel->getTraceLine($traceConfig));
+ }
+
+ protected function setUp()
+ {
+ parent::setUp();
+ $this->mockWebApplication();
+ }
+
+ private function getPanel()
+ {
+ return new Panel(['module' => new Module('debug')]);
+ }
+}
View
@@ -8,9 +8,14 @@
$_SERVER['SCRIPT_NAME'] = '/' . __DIR__;
$_SERVER['SCRIPT_FILENAME'] = __FILE__;
-require_once(__DIR__ . '/../vendor/autoload.php');
-require_once(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
+if (is_dir(__DIR__ . '/../vendor/')) {
+ $vendorRoot = __DIR__ . '/../vendor'; //this extension has its own vendor folder
+} else {
+ $vendorRoot = __DIR__ . '/../../..'; //this extension is part of a project vendor folder
+}
+require_once($vendorRoot . '/autoload.php');
+require_once($vendorRoot . '/yiisoft/yii2/Yii.php');
Yii::setAlias('@yiiunit/extensions/debug', __DIR__);
Yii::setAlias('@yiiunit', __DIR__ . '/../tests');
-Yii::setAlias('@yii/debug', dirname(__DIR__));
+Yii::setAlias('@yii/debug', dirname(__DIR__));
@@ -57,8 +57,8 @@
if (!empty($data['trace'])) {
$query .= Html::ul($data['trace'], [
'class' => 'trace',
- 'item' => function ($trace) {
- return "<li>{$trace['file']} ({$trace['line']})</li>";
+ 'item' => function ($trace) use ($panel) {
+ return '<li>' . $panel->getTraceLine($trace) . '</li>';
},
]);
}
@@ -75,7 +75,7 @@
return $query;
},
- 'format' => 'html',
+ 'format' => 'raw',
'options' => [
'width' => '60%',
],
@@ -55,19 +55,19 @@
'category',
[
'attribute' => 'message',
- 'value' => function ($data) {
+ 'value' => function ($data) use ($panel) {
$message = Html::encode(is_string($data['message']) ? $data['message'] : VarDumper::export($data['message']));
if (!empty($data['trace'])) {
$message .= Html::ul($data['trace'], [
'class' => 'trace',
- 'item' => function ($trace) {
- return "<li>{$trace['file']} ({$trace['line']})</li>";
+ 'item' => function ($trace) use ($panel) {
+ return '<li>' . $panel->traceLink($trace) . '</li>';
}
]);
};
return $message;
},
- 'format' => 'html',
+ 'format' => 'raw',
'options' => [
'width' => '50%',
],

0 comments on commit ed07955

Please sign in to comment.