Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Tomáš Pospíšil
tracyBars
Commits
d6ddce83
Commit
d6ddce83
authored
Jan 17, 2020
by
Tomáš Pospíšil
Browse files
Internal smarty
parent
79284701
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/BarPanel/Helper.php
View file @
d6ddce83
...
...
@@ -2,10 +2,34 @@
namespace
Praguebest\BarPanel
;
use
Nette\Utils\Strings
;
use
Tracy\Helpers
;
class
Helper
{
private
static
$genericClasses
=
[
'Db'
,
'WTObject'
,
'WTModel'
,
'Database'
,
'EPObject'
,
'EPModel'
,
'EPBase'
,
];
public
static
function
getInternalSmartyBacktrace
(
array
$backtraces
=
null
):
array
{
$filtered
=
[];
foreach
(
$backtraces
as
$backtrace
)
{
$match
=
Strings
::
match
(
$backtrace
[
'file'
],
'#.*file\.(.*\.tpl).*#'
);
if
(
$match
)
{
$filtered
[]
=
$match
[
1
];
}
}
return
$filtered
;
}
public
static
function
getBacktrace
(
array
$backtraces
=
null
):
array
{
if
(
$backtraces
===
null
)
{
...
...
@@ -13,22 +37,28 @@ class Helper
}
$lines
=
[];
$first
=
null
;
for
(
$i
=
1
,
$iMax
=
count
(
$backtraces
);
$i
<
$iMax
;
$i
++
)
{
for
(
$i
=
0
,
$iMax
=
count
(
$backtraces
);
$i
<
$iMax
;
$i
++
)
{
$isGeneric
=
false
;
$backtrace
=
$backtraces
[
$i
];
$nextBacktrace
=
$backtrace
;
if
(
array_key_exists
(
$i
+
1
,
$backtraces
))
{
$nextBacktrace
=
$backtraces
[
$i
+
1
];
}
$loc
=
''
;
if
(
isset
(
$backtrace
[
'file'
]))
{
$loc
.
=
Helpers
::
editorLink
(
$backtrace
[
'file'
],
$backtrace
[
'line'
])
.
' '
;
}
$name
=
' '
;
if
(
$nextBacktrace
!==
null
&&
isset
(
$nextBacktrace
[
'class'
]))
{
$name
.
=
$nextBacktrace
[
'class'
]
.
$nextBacktrace
[
'type'
];
}
if
(
isset
(
$backtrace
[
'class'
]))
{
$isGeneric
=
in_array
(
$backtrace
[
'class'
],
[
'Db'
,
'WTObject'
,
'WTModel'
,
'Database'
,
'EPObject'
,
'EPModel'
,
'EPBase'
],
true
);
$name
.
=
$backtrace
[
'class'
]
.
$backtrace
[
'type'
];
$isGeneric
=
in_array
(
$backtrace
[
'class'
],
self
::
$genericClasses
,
true
);
}
if
(
$
i
>
0
&&
isset
(
$
b
acktrace
[
'function'
]))
{
$name
.
=
$
b
acktrace
[
'function'
]
.
'() '
;
if
(
$
nextBacktrace
!==
null
&&
isset
(
$
nextB
acktrace
[
'function'
]))
{
$name
.
=
$
nextB
acktrace
[
'function'
]
.
'() '
;
}
$line
=
compact
(
'loc'
,
'name'
);
...
...
src/BarPanel/InternalSmartyBarPanel.php
0 → 100644
View file @
d6ddce83
<?php
namespace
Praguebest\BarPanel
;
use
Praguebest\Tools\OnOffSwitcher
;
use
Praguebest\Tools\TraceableSmarty
;
use
Smarty
;
use
SmartyException
;
use
Tracy
;
use
Tracy\Dumper
;
use
Tracy\Helpers
;
final
class
InternalSmartyBarPanel
implements
Tracy\IBarPanel
{
private
static
$maxDepth
=
8
;
private
static
$maxLength
=
512
;
public
$data
;
public
$id
=
'database'
;
/**
* @var Smarty
*/
private
$smarty
;
/**
* @var TraceableSmarty
*/
private
$currentSmarty
;
public
function
__construct
(
TraceableSmarty
$currentSmarty
,
Smarty
$smarty
)
{
$this
->
smarty
=
$smarty
;
$this
->
currentSmarty
=
$currentSmarty
;
}
/**
* Renders HTML code for custom panel.
* @return string
* @throws SmartyException
*/
public
function
getPanel
():
string
{
$this
->
assignSmarty
();
return
$this
->
smarty
->
fetch
(
dirname
(
__DIR__
)
.
'/templates/internalSmarty/smartyVars.tpl'
);
}
/**
* Renders HTML code for custom tab.
* @return string
* @throws SmartyException
*/
public
function
getTab
():
string
{
$this
->
assignSmarty
();
return
$this
->
smarty
->
fetch
(
dirname
(
__DIR__
)
.
'/templates/internalSmarty/tab.tpl'
);
}
private
function
assignSmarty
():
void
{
$variables
=
$this
->
currentSmarty
->
getAssigns
();
foreach
(
$variables
as
$name
=>
&
$assigns
)
{
foreach
(
$assigns
as
&
$assign
)
{
$assign
[
'backtrace'
]
=
array_map
(
static
function
(
$backtrace
)
{
return
Helpers
::
editorLink
(
$backtrace
);
},
$assign
[
'backtrace'
]
);
$assign
[
'first'
]
=
array_shift
(
$assign
[
'backtrace'
]);
$assign
[
'value'
]
=
Dumper
::
toHtml
(
$assign
[
'value'
],
[
Dumper
::
DEPTH
=>
self
::
$maxDepth
,
Dumper
::
TRUNCATE
=>
self
::
$maxLength
,
Dumper
::
LOCATION
=>
Dumper
::
LOCATION_CLASS
,
Dumper
::
LAZY
=>
true
,
Dumper
::
DEBUGINFO
=>
true
,
]
);
}
}
$this
->
smarty
->
assign
(
'internalVariables'
,
$variables
);
$this
->
smarty
->
assign
(
'countInternalVariables'
,
count
(
$variables
));
$this
->
smarty
->
assign
(
'profileInternalVariables'
,
OnOffSwitcher
::
shouldProfile
(
TraceableSmarty
::
INTERNAL_VARIABLES
));
}
}
src/BarPanel/Registrator.php
View file @
d6ddce83
...
...
@@ -3,6 +3,7 @@
namespace
Praguebest\BarPanel
;
use
Nette\Utils\FileSystem
;
use
Nette\Utils\Strings
;
use
Praguebest\Tools
;
use
Praguebest\Tools\WebSwitcherUrls
;
use
Smarty
;
...
...
@@ -41,7 +42,7 @@ final class Registrator
Debugger
::
$strictMode
=
true
;
Debugger
::
$maxLength
=
1024
;
Debugger
::
$maxDepth
=
5
;
Debugger
::
enable
(
"42@84.42.168.182,42@185.156.123.46"
,
realpath
(
$errorDir
),
$emailDeveloper
);
Debugger
::
enable
(
"42@84.42.168.182,42@185.156.123.46"
,
realpath
(
$errorDir
),
Strings
::
replace
(
$emailDeveloper
,
'/,;/'
,
','
)
);
return
$this
;
}
...
...
@@ -81,7 +82,7 @@ final class Registrator
return
$this
;
}
public
function
registerSmarty
(
Smarty
$smarty
):
Registrator
public
function
registerSmarty
(
Tools
\
Traceable
Smarty
$smarty
)
:
Registrator
{
$this
->
addPanel
(
__METHOD__
,
...
...
@@ -93,6 +94,18 @@ final class Registrator
return
$this
;
}
public
function
registerInternalSmarty
(
Tools
\
TraceableSmarty
$smarty
)
:
Registrator
{
$this
->
addPanel
(
__METHOD__
,
function
()
use
(
$smarty
)
{
return
new
InternalSmartyBarPanel
(
$smarty
,
$this
->
smarty
);
}
);
return
$this
;
}
private
function
addPanel
(
string
$method
,
callable
$panelCreator
):
void
{
if
(
!
array_key_exists
(
$method
,
$this
->
registeredPanels
)
&&
Debugger
::
isEnabled
())
{
...
...
src/BarPanel/SmartyBarPanel.php
View file @
d6ddce83
...
...
@@ -2,6 +2,8 @@
namespace
Praguebest\BarPanel
;
use
Praguebest\Tools\OnOffSwitcher
;
use
Praguebest\Tools\TraceableSmarty
;
use
Smarty
;
use
SmartyException
;
use
Tracy
;
...
...
@@ -21,11 +23,11 @@ final class SmartyBarPanel implements Tracy\IBarPanel
*/
private
$smarty
;
/**
* @var
PB
Smarty
* @var
Traceable
Smarty
*/
private
$currentSmarty
;
public
function
__construct
(
Smarty
$currentSmarty
,
Smarty
$smarty
)
public
function
__construct
(
Traceable
Smarty
$currentSmarty
,
Smarty
$smarty
)
{
$this
->
smarty
=
$smarty
;
$this
->
currentSmarty
=
$currentSmarty
;
...
...
@@ -57,31 +59,35 @@ final class SmartyBarPanel implements Tracy\IBarPanel
private
function
assignSmarty
():
void
{
if
(
method_exists
(
$this
->
currentSmarty
,
'getBacktraces'
))
{
$smartyBacktrace
=
[];
$smartyBacktrace
=
[];
$smartyVars
=
[];
if
(
OnOffSwitcher
::
shouldProfile
(
TraceableSmarty
::
SMARTY_VARIABLES
))
{
foreach
(
$this
->
currentSmarty
->
getBacktraces
()
as
$key
=>
$backtrace
)
{
$smartyBacktrace
[
$key
]
=
Helper
::
getBacktrace
(
$backtrace
);
}
$this
->
smarty
->
assign
(
'smartyBacktrace'
,
$smartyBacktrace
);
}
$smartyVars
=
array_map
(
static
function
(
$value
)
{
return
Dumper
::
toHtml
(
$value
,
[
Dumper
::
DEPTH
=>
self
::
$maxDepth
,
Dumper
::
TRUNCATE
=>
self
::
$maxLength
,
Dumper
::
LOCATION
=>
Dumper
::
LOCATION_CLASS
,
Dumper
::
LAZY
=>
true
,
Dumper
::
DEBUGINFO
=>
true
,
]
);
},
array_combine
(
array_keys
(
$this
->
currentSmarty
->
tpl_vars
),
array_column
(
$this
->
currentSmarty
->
tpl_vars
,
'value'
))
);
ksort
(
$smartyVars
,
SORT_STRING
|
SORT_FLAG_CASE
);
$this
->
smarty
->
assign
(
'smartyVars'
,
$smartyVars
);
$smartyVars
=
array_map
(
static
function
(
$value
)
{
return
Dumper
::
toHtml
(
$value
,
[
Dumper
::
DEPTH
=>
self
::
$maxDepth
,
Dumper
::
TRUNCATE
=>
self
::
$maxLength
,
Dumper
::
LOCATION
=>
Dumper
::
LOCATION_CLASS
,
Dumper
::
LAZY
=>
true
,
Dumper
::
DEBUGINFO
=>
true
,
]
);
},
array_combine
(
array_keys
(
$this
->
currentSmarty
->
tpl_vars
),
array_column
(
$this
->
currentSmarty
->
tpl_vars
,
'value'
))
);
ksort
(
$smartyVars
,
SORT_STRING
|
SORT_FLAG_CASE
);
}
$this
->
smarty
->
assign
(
'smartyVariables'
,
$smartyVars
);
$this
->
smarty
->
assign
(
'countSmartyVariables'
,
count
(
$smartyVars
));
$this
->
smarty
->
assign
(
'profileSmartyVariables'
,
OnOffSwitcher
::
shouldProfile
(
TraceableSmarty
::
SMARTY_VARIABLES
));
}
}
src/Tools/DBProfiler.php
View file @
d6ddce83
...
...
@@ -33,30 +33,7 @@ final class DBProfiler
private
function
initProfiling
():
void
{
if
(
session_status
()
!==
PHP_SESSION_ACTIVE
)
{
session_start
();
}
$get
=
filter_input
(
INPUT_GET
,
DBProfiler
::
PROFILE_DB
,
FILTER_VALIDATE_BOOLEAN
);
if
(
$get
===
true
||
(
$get
===
null
&&
$this
->
getFromSession
()
===
true
))
{
$this
->
setToSession
(
true
);
$this
->
profile
=
true
;
}
if
(
$get
===
false
||
(
$get
===
null
&&
$this
->
getFromSession
()
===
false
))
{
$this
->
setToSession
(
false
);
$this
->
profile
=
false
;
}
}
private
function
getFromSession
():
bool
{
$profileDB
=
$_SESSION
[
DBProfiler
::
PROFILE_DB
]
??
false
;
return
(
bool
)
$profileDB
;
}
private
function
setToSession
(
bool
$value
):
void
{
$_SESSION
[
DBProfiler
::
PROFILE_DB
]
=
$value
;
$this
->
profile
=
OnOffSwitcher
::
shouldProfile
(
DBProfiler
::
PROFILE_DB
);
}
public
static
function
getInstance
():
self
...
...
src/Tools/OnOffSwitcher.php
0 → 100644
View file @
d6ddce83
<?php
namespace
Praguebest\Tools
;
class
OnOffSwitcher
{
public
static
function
shouldProfile
(
string
$profileName
):
bool
{
if
(
session_status
()
!==
PHP_SESSION_ACTIVE
)
{
session_start
();
}
$profile
=
false
;
$get
=
filter_input
(
INPUT_GET
,
$profileName
,
FILTER_VALIDATE_BOOLEAN
);
if
(
$get
===
true
||
(
$get
===
null
&&
static
::
getFromSession
(
$profileName
)
===
true
))
{
static
::
setToSession
(
$profileName
,
true
);
$profile
=
true
;
}
if
(
$get
===
false
||
(
$get
===
null
&&
static
::
getFromSession
(
$profileName
)
===
false
))
{
static
::
setToSession
(
$profileName
,
false
);
$profile
=
false
;
}
return
$profile
;
}
private
static
function
getFromSession
(
string
$profileName
):
bool
{
$profileDB
=
$_SESSION
[
$profileName
]
??
false
;
return
(
bool
)
$profileDB
;
}
private
static
function
setToSession
(
string
$profileName
,
bool
$value
):
void
{
$_SESSION
[
$profileName
]
=
$value
;
}
}
src/Tools/TraceableInternalTemplate.php
0 → 100644
View file @
d6ddce83
<?php
namespace
Praguebest\Tools
;
class
TraceableInternalTemplate
extends
\
Smarty_Internal_Template
{
private
$assignedByScope
=
[];
/**
* @param string $varName
* @param mixed $value
* @param bool $nocache
* @param int $scope
*/
public
function
_assignInScope
(
$varName
,
$value
,
$nocache
=
false
,
$scope
=
0
)
{
parent
::
_assignInScope
(
$varName
,
$value
,
$nocache
,
$scope
);
$this
->
addAssignedByScope
(
$varName
,
$value
);
}
public
function
addAssignedByScope
(
$varName
,
$value
,
array
$backtrace
=
[])
{
$backtrace
[]
=
reset
(
$this
->
compiled
->
file_dependency
)[
0
];
if
(
$this
->
parent
instanceof
TraceableInternalTemplate
)
{
$this
->
parent
->
addAssignedByScope
(
$varName
,
$value
,
$backtrace
);
}
else
{
$this
->
assignedByScope
[
$varName
]
=
$this
->
assignedByScope
[
$varName
]
??
[];
$this
->
assignedByScope
[
$varName
][]
=
[
'value'
=>
$value
,
'backtrace'
=>
$backtrace
,
];
}
}
/**
* @param string $template
* @param mixed $cache_id
* @param mixed $compile_id
* @param int $caching
* @param int $cache_lifetime
* @param array $data
* @param int $scope
* @param bool $forceTplCache
* @param string|null $uid
* @param string|null $content_func
*/
public
function
_subTemplateRender
(
$template
,
$cache_id
,
$compile_id
,
$caching
,
$cache_lifetime
,
$data
,
$scope
,
$forceTplCache
,
$uid
=
null
,
$content_func
=
null
)
{
parent
::
_subTemplateRender
(
$template
,
$cache_id
,
$compile_id
,
$caching
,
$cache_lifetime
,
$data
,
$scope
,
$forceTplCache
,
$uid
,
$content_func
);
foreach
(
$data
as
$key
=>
$value
)
{
$this
->
addAssignedByScope
(
$key
,
$value
);
}
}
public
function
getAssigns
():
array
{
return
$this
->
assignedByScope
;
}
}
src/Tools/TraceableSmarty.php
View file @
d6ddce83
...
...
@@ -7,8 +7,30 @@ use Smarty;
class
TraceableSmarty
extends
Smarty
{
public
const
SMARTY_VARIABLES
=
'SMARTY_VARIABLES'
;
public
const
INTERNAL_VARIABLES
=
'INTERNAL_VARIABLES'
;
/** @var array */
private
$backtraces
;
private
$backtraces
=
[];
/** @var TraceableInternalTemplate[] */
private
$generatedTemplates
=
[];
private
$collectVariables
=
false
;
private
$collectBacktraces
=
false
;
/**
* TraceableSmarty constructor.
*/
public
function
__construct
()
{
parent
::
__construct
();
if
(
OnOffSwitcher
::
shouldProfile
(
TraceableSmarty
::
INTERNAL_VARIABLES
))
{
$this
->
template_class
=
TraceableInternalTemplate
::
class
;
$this
->
collectVariables
=
true
;
}
$this
->
collectBacktraces
=
OnOffSwitcher
::
shouldProfile
(
TraceableSmarty
::
SMARTY_VARIABLES
);
}
/**
* @param array|string $tpl_var
...
...
@@ -24,7 +46,9 @@ class TraceableSmarty extends Smarty
$this
->
assign
(
$var
,
$value
,
$nocache
);
}
}
else
{
$this
->
backtraces
[
$tpl_var
]
=
debug_backtrace
(
DEBUG_BACKTRACE_IGNORE_ARGS
);
if
(
$this
->
collectBacktraces
)
{
$this
->
backtraces
[
$tpl_var
]
=
debug_backtrace
(
DEBUG_BACKTRACE_IGNORE_ARGS
);
}
parent
::
assign
(
$tpl_var
,
$value
,
$nocache
);
}
...
...
@@ -32,11 +56,39 @@ class TraceableSmarty extends Smarty
return
$this
;
}
public
function
assignByRef
(
$tpl_var
,
&
$value
,
$nocache
=
false
)
{
if
(
$this
->
collectBacktraces
)
{
$this
->
backtraces
[
$tpl_var
]
=
debug_backtrace
(
DEBUG_BACKTRACE_IGNORE_ARGS
);
}
parent
::
assignByRef
(
$tpl_var
,
$value
,
$nocache
);
}
public
function
display
(
$template
=
null
,
$cache_id
=
null
,
$compile_id
=
null
,
$parent
=
null
)
{
parent
::
display
(
$template
,
$cache_id
,
$compile_id
,
$parent
);
Registrator
::
getInstance
(
$this
->
getCompileDir
(),
$this
->
getCacheDir
())
->
registerSmarty
(
$this
);
$registrator
=
Registrator
::
getInstance
(
$this
->
getCompileDir
(),
$this
->
getCacheDir
());
$registrator
->
registerSmarty
(
$this
);
$registrator
->
registerInternalSmarty
(
$this
);
}
/**
* @param string $template
* @param mixed|null $cache_id
* @param mixed|null $compile_id
* @param object|null $parent
* @param bool $do_clone
* @return Smarty_Internal_Template
*/
public
function
createTemplate
(
$template
,
$cache_id
=
null
,
$compile_id
=
null
,
$parent
=
null
,
$do_clone
=
true
)
{
$template
=
parent
::
createTemplate
(
$template
,
$cache_id
,
$compile_id
,
$parent
,
$do_clone
);
if
(
$this
->
collectVariables
)
{
$this
->
generatedTemplates
[]
=
$template
;
}
return
$template
;
}
public
function
getBacktraces
():
array
...
...
@@ -44,4 +96,19 @@ class TraceableSmarty extends Smarty
return
$this
->
backtraces
;
}
public
function
getAssigns
():
array
{
$assigns
=
[];
foreach
(
$this
->
generatedTemplates
as
$template
)
{
$assigns
[]
=
$template
->
getAssigns
();
}
$assigns
=
array_filter
(
$assigns
);
if
(
count
(
$assigns
)
>
0
)
{
$assigns
=
array_merge_recursive
(
...
$assigns
);
}
return
$assigns
;
}
}
src/templates/database/dbProfiler.tpl
View file @
d6ddce83
{
if
$count
>
0
}
<h1>
Queries:
{
$count
}
, {($time * 1000)|number_format:2} ms
</h1>
{/
if
}
{
if
$count
===
0
&&
(
$profile
===
false
||
$profile
===
null
)
}
<h1><a
href=
"?profileDB=1"
>
Turn profiling on
</a></h1>
{/
if
}
{
if
$count
>
0
}
<h1>
Queries:
{
$count
}
, {($time * 1000)|number_format:2} ms
</h1>
<div
class=
"tracy-inner"
>
<div
class=
"tracy-inner-container"
>
<table
class=
"tracy-sortable"
>
...
...
src/templates/internalSmarty/smartyVars.tpl
0 → 100644
View file @
d6ddce83
{
if
$countInternalVariables
===
0
&&
(
$profileInternalVariables
===
false
||
$profileInternalVariables
===
null
)
}
<h1><a
href=
"?INTERNAL_VARIABLES=1"
>
Turn profiling on
</a></h1>
{/
if
}
{
if
$countInternalVariables
>
0
}
<h1>
Variables:
{
$countInternalVariables
}
</h1>
<style>
#tracy-debug
pre
.tracy-dump
{
background
:
transparent
!important
;
}
</style>
<div
class=
"tracy-inner"
>
<div
class=
"tracy-inner-container"
>
<table>
{
foreach
$internalVariables
as
$name
=>
$assigns
}
{
foreach
$assigns
as
$assign
}
<tr>
{
if
$assign
@
first
}
<td
rowspan=
"
{
count
(
$assigns
)
}
"
>
{
$name
}
</td>
{/
if
}
<td>
{
$assign
[
'first'
]
nofilter
}
{
if
count
(
$assign
[
'backtrace'
])
>
0
}
<a
class=
"tracy-toggle tracy-collapsed"
data-tracy-ref=
"^tr .nette-DbConnectionPanel-trace"
></a>
<div
class=
"tracy-collapsed nette-DbConnectionPanel-trace"
>
{
foreach
$assign
[
'backtrace'
]
as
$backtrace
}
<div>
{
$backtrace
nofilter
}
</div>
{/
foreach
}
</div>
{/
if
}
</td>
<td>
{
$assign
[
'value'
]
nofilter
}
</td>
</tr>
{/
foreach
}
{/
foreach
}
</table>
</div>
</div>
<h2><a
href=
"?INTERNAL_VARIABLES=0"
>
Turn profiling off
</a></h2>
{/
if
}
src/templates/internalSmarty/tab.tpl
0 → 100644
View file @
d6ddce83
<span>
{
if
$countInternalVariables
===
0
}
<span
style=
"color: gray; text-decoration: line-through"
>
{
ldelim
}
$
{
rdelim
}
Internal variables
</span>
<span
class=
"tracy-label"
></span>
{
else
}
<span
style=
"color: cadetblue"
>
{
ldelim
}
</span>
<span
style=
"color: coral"
>
$
</span>
<span
style=
"color: cadetblue"
>
{
rdelim
}
</span>
<span
class=
"tracy-label"
>
{
$countInternalVariables
}
internal variables
</span>
{/
if
}
</span>