Version Notes
Download this release
Release Info
Developer | Justus Krapp |
Extension | Ecocode_Profiler |
Version | 1.1.0 |
Comparing to | |
See all releases |
Version 1.1.0
- app/MageDev.php +42 -0
- app/code/community/Ecocode/Profiler/Block/Bag.php +23 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Base.php +45 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Layout/Panel.php +137 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Log/Panel.php +98 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Menu.php +14 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Mysql/Panel.php +183 -0
- app/code/community/Ecocode/Profiler/Block/Collector/Translation/Panel.php +33 -0
- app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar.php +33 -0
- app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar/Menu.php +45 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/AbstractRenderer.php +31 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/BackTrace.php +36 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/Context.php +16 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/Log/LogTable.php +41 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/Mysql/QueryTable.php +43 -0
- app/code/community/Ecocode/Profiler/Block/Renderer/RendererInterface.php +9 -0
- app/code/community/Ecocode/Profiler/Block/Toolbar.php +65 -0
- app/code/community/Ecocode/Profiler/Controller/AbstractController.php +52 -0
- app/code/community/Ecocode/Profiler/Db/Statement/Pdo/Mysql.php +94 -0
- app/code/community/Ecocode/Profiler/Helper/AbstractHelper.php +17 -0
- app/code/community/Ecocode/Profiler/Helper/Code.php +200 -0
- app/code/community/Ecocode/Profiler/Helper/Context.php +104 -0
- app/code/community/Ecocode/Profiler/Helper/Data.php +191 -0
- app/code/community/Ecocode/Profiler/Helper/Renderer.php +34 -0
- app/code/community/Ecocode/Profiler/Helper/Rewrite.php +163 -0
- app/code/community/Ecocode/Profiler/Helper/Sql.php +99 -0
- app/code/community/Ecocode/Profiler/Helper/ValueExporter.php +95 -0
- app/code/community/Ecocode/Profiler/Model/AppDev.php +149 -0
- app/code/community/Ecocode/Profiler/Model/Collector/AbstractDataCollector.php +82 -0
- app/code/community/Ecocode/Profiler/Model/Collector/AjaxDataCollector.php +27 -0
- app/code/community/Ecocode/Profiler/Model/Collector/CacheDataCollector.php +146 -0
- app/code/community/Ecocode/Profiler/Model/Collector/ConfigDataCollector.php +237 -0
- app/code/community/Ecocode/Profiler/Model/Collector/ContextDataCollector.php +45 -0
- app/code/community/Ecocode/Profiler/Model/Collector/CustomerDataCollector.php +91 -0
- app/code/community/Ecocode/Profiler/Model/Collector/DataCollectorInterface.php +24 -0
- app/code/community/Ecocode/Profiler/Model/Collector/EventDataCollector.php +97 -0
- app/code/community/Ecocode/Profiler/Model/Collector/LateDataCollectorInterface.php +12 -0
- app/code/community/Ecocode/Profiler/Model/Collector/LayoutDataCollector.php +175 -0
- app/code/community/Ecocode/Profiler/Model/Collector/LogDataCollector.php +217 -0
- app/code/community/Ecocode/Profiler/Model/Collector/MemoryDataCollector.php +113 -0
- app/code/community/Ecocode/Profiler/Model/Collector/ModelDataCollector.php +228 -0
- app/code/community/Ecocode/Profiler/Model/Collector/MysqlDataCollector.php +139 -0
- app/code/community/Ecocode/Profiler/Model/Collector/RequestDataCollector.php +488 -0
- app/code/community/Ecocode/Profiler/Model/Collector/RewriteDataCollector.php +62 -0
- app/code/community/Ecocode/Profiler/Model/Collector/TimeDataCollector.php +44 -0
- app/code/community/Ecocode/Profiler/Model/Collector/TranslationDataCollector.php +91 -0
- app/code/community/Ecocode/Profiler/Model/Context.php +56 -0
- app/code/community/Ecocode/Profiler/Model/ContextInterface.php +21 -0
- app/code/community/Ecocode/Profiler/Model/Core/Cache.php +46 -0
- app/code/community/Ecocode/Profiler/Model/Core/Config.php +56 -0
- app/code/community/Ecocode/Profiler/Model/DebugLoggerInterface.php +28 -0
- app/code/community/Ecocode/Profiler/Model/Http/HeaderBag.php +322 -0
- app/code/community/Ecocode/Profiler/Model/Http/ParameterBag.php +235 -0
- app/code/community/Ecocode/Profiler/Model/Http/ResponseHeaderBag.php +240 -0
- app/code/community/Ecocode/Profiler/Model/Logger.php +79 -0
- app/code/community/Ecocode/Profiler/Model/Logger/DebugHandler.php +60 -0
- app/code/community/Ecocode/Profiler/Model/Observer.php +116 -0
- app/code/community/Ecocode/Profiler/Model/Observer/Context.php +55 -0
- app/code/community/Ecocode/Profiler/Model/Profile.php +289 -0
- app/code/community/Ecocode/Profiler/Model/Profiler.php +172 -0
- app/code/community/Ecocode/Profiler/Model/Profiler/FileStorage.php +295 -0
- app/code/community/Ecocode/Profiler/Model/Profiler/StorageInterface.php +58 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Controller/AbstractControllerTest.php +70 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/DevModeTest.php +33 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/DummyCacheBackend.php +7 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/ResponseHttp.php +10 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/CodeTest.php +55 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/ContextTest.php +136 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/DataTest.php +94 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/RewriteTest.php +124 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/SqlTest.php +56 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Helper/ValueExporterTest.php +60 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/CacheDataCollectorTest.php +89 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ConfigCollectorTest.php +51 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ContextDataCollectorTest.php +54 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/CustomerDataCollectorTest.php +54 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/EventDataCollectorTest.php +68 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/LayoutDataCollectorTest.php +221 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/LogDataCollectorTest.php +84 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/MemoryDataCollectorTest.php +71 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ModelDataCollectorTest.php +177 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/MysqlDataCollectorTest.php +23 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/RequestDataCollectorTest.php +158 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/RewriteDataCollectorTest.php +39 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/TimeDataCollectorTest.php +30 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/TranslationDataCollectorTest.php +79 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/HeaderBagTest.php +192 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/ParameterBagTest.php +181 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/ResponseHeaderBagTest.php +160 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/LoggerTest.php +87 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Observer/ContextTest.php +66 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/ObserverTest.php +163 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelResourceDbAbstractTest.php +118 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelResourceTest.php +29 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelTranslateTest.php +66 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageEavModelEntityAbstractTest.php +111 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageTest.php +43 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/Profiler/FileStorageTest.php +346 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/Model/ProfilerTest.php +58 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/bootstrap.php +54 -0
- app/code/community/Ecocode/Profiler/Tests/Dev/controllers/CacheControllerTest.php +168 -0
- app/code/community/Ecocode/Profiler/Tests/Prod/DevModeTest.php +33 -0
- app/code/community/Ecocode/Profiler/Tests/Prod/bootstrap.php +51 -0
- app/code/community/Ecocode/Profiler/Tests/TestHelper.php +91 -0
- app/code/community/Ecocode/Profiler/autoloader.php +68 -0
- app/code/community/Ecocode/Profiler/controllers/CacheController.php +71 -0
- app/code/community/Ecocode/Profiler/controllers/IndexController.php +155 -0
- app/code/community/Ecocode/Profiler/debug.php +24 -0
- app/code/community/Ecocode/Profiler/etc/config.xml +8 -0
- app/code/community/Ecocode/Profiler/etc/development.xml +139 -0
- app/code/community/Ecocode/Profiler/overwrite/Mage.php +124 -0
- app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResource.php +33 -0
- app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResourceDbAbstract.php +83 -0
- app/code/community/Ecocode/Profiler/overwrite/MageCoreModelStore.php +35 -0
- app/code/community/Ecocode/Profiler/overwrite/MageCoreModelTranslate.php +154 -0
- app/code/community/Ecocode/Profiler/overwrite/MageEavModelEntityAbstract.php +70 -0
- app/design/frontend/base/default/layout/ecocode_profiler.xml +120 -0
- app/design/frontend/base/default/template/ecocode_profiler/back-trace.phtml +24 -0
- app/design/frontend/base/default/template/ecocode_profiler/bag.phtml +33 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/ajax/toolbar.phtml +38 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/base/menu.phtml +8 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/cache/menu.phtml +8 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/cache/panel.phtml +164 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/cache/toolbar.phtml +62 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/config/menu.phtml +10 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/config/panel.phtml +151 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/config/toolbar.phtml +79 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/customer/toolbar.phtml +45 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/event/menu.phtml +17 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/event/panel.phtml +116 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/layout/menu.phtml +15 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/layout/panel.phtml +69 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/layout/toolbar.phtml +48 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/log/menu.phtml +25 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/log/panel.phtml +118 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/log/panel/log-table.phtml +130 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/log/toolbar.phtml +52 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/memory/toolbar.phtml +31 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/model/menu.phtml +20 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/model/panel.phtml +177 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/model/toolbar.phtml +48 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/menu.phtml +19 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/panel.phtml +343 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/panel/query-table.phtml +63 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/toolbar.phtml +36 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/request/menu.phtml +22 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/request/panel.phtml +163 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/request/toolbar.phtml +51 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/menu.phtml +22 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/panel.phtml +77 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/toolbar.phtml +40 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/time/toolbar.phtml +23 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/translation/menu.phtml +31 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/translation/panel.phtml +121 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/translation/panel/table.phtml +82 -0
- app/design/frontend/base/default/template/ecocode_profiler/collector/translation/toolbar.phtml +56 -0
- app/design/frontend/base/default/template/ecocode_profiler/layout.phtml +87 -0
- app/design/frontend/base/default/template/ecocode_profiler/layout/sidebar.phtml +103 -0
- app/design/frontend/base/default/template/ecocode_profiler/layout/sidebar/menu.phtml +22 -0
- app/design/frontend/base/default/template/ecocode_profiler/profiler/base.css.phtml +935 -0
- app/design/frontend/base/default/template/ecocode_profiler/profiler/base.js.phtml +464 -0
- app/design/frontend/base/default/template/ecocode_profiler/profiler/search/results.phtml +71 -0
- app/design/frontend/base/default/template/ecocode_profiler/profiler/search/summery.phtml +5 -0
- app/design/frontend/base/default/template/ecocode_profiler/profiler/summery.phtml +90 -0
- app/design/frontend/base/default/template/ecocode_profiler/renderer/context.phtml +30 -0
- app/design/frontend/base/default/template/ecocode_profiler/toolbar.css.phtml +479 -0
- app/design/frontend/base/default/template/ecocode_profiler/toolbar.phtml +75 -0
- app/design/frontend/base/default/template/ecocode_profiler/toolbar_js.phtml +81 -0
- app/etc/modules/Ecocode_Profiler.xml +9 -0
- dev.php +59 -0
- package.xml +448 -0
app/MageDev.php
ADDED
@@ -0,0 +1,42 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
define('BP', MAGENTO_ROOT);
|
5 |
+
$ds = DIRECTORY_SEPARATOR;
|
6 |
+
|
7 |
+
/** AUTOLOADER PATCH **/
|
8 |
+
if (file_exists($autoloaderPath = BP . $ds . '../vendor/autoload.php') ||
|
9 |
+
file_exists($autoloaderPath = BP . $ds . 'vendor/autoload.php')
|
10 |
+
) {
|
11 |
+
require $autoloaderPath;
|
12 |
+
}
|
13 |
+
/** AUTOLOADER PATCH **/
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
|
18 |
+
$profilerDir = implode(DIRECTORY_SEPARATOR, [MAGENTO_ROOT, 'app', 'code', 'community', 'Ecocode', 'Profiler']);
|
19 |
+
$profilerDir .= DIRECTORY_SEPARATOR;
|
20 |
+
define('PROFILER_DIR', $profilerDir);
|
21 |
+
|
22 |
+
$overwriteBasePath = $profilerDir . 'overwrite' . DIRECTORY_SEPARATOR;
|
23 |
+
|
24 |
+
require_once PROFILER_DIR . 'autoloader.php';
|
25 |
+
$autoloader = Ecocode_Profiler_Autoloader::getAutoloader();
|
26 |
+
$autoloader->register(true);
|
27 |
+
|
28 |
+
|
29 |
+
$autoloader
|
30 |
+
->addOverwrite('Mage_Core_Model_Resource', 'MageCoreModelResource.php')
|
31 |
+
->addOverwrite('Mage_Core_Model_Resource_Db_Abstract', 'MageCoreModelResourceDbAbstract.php')
|
32 |
+
->addOverwrite('Mage_Core_Model_Store', 'MageCoreModelStore.php')
|
33 |
+
->addOverwrite('Mage_Core_Model_Translate', 'MageCoreModelTranslate.php')
|
34 |
+
->addOverwrite('Mage_Eav_Model_Entity_Abstract', 'MageEavModelEntityAbstract.php');
|
35 |
+
|
36 |
+
require_once $profilerDir . 'Helper' . DIRECTORY_SEPARATOR . 'Data.php';
|
37 |
+
|
38 |
+
require_once $overwriteBasePath . 'Mage.php';
|
39 |
+
|
40 |
+
//load overwrites so we can get around the autoloader
|
41 |
+
Mage::setRoot(MAGENTO_ROOT . DIRECTORY_SEPARATOR . 'app');
|
42 |
+
|
app/code/community/Ecocode/Profiler/Block/Bag.php
ADDED
@@ -0,0 +1,23 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Bag
|
5 |
+
*
|
6 |
+
* @method getBag
|
7 |
+
*/
|
8 |
+
class Ecocode_Profiler_Block_Bag
|
9 |
+
extends Mage_Core_Block_Template
|
10 |
+
{
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->setTemplate('ecocode_profiler/bag.phtml');
|
14 |
+
parent::_construct();
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getLabels()
|
18 |
+
{
|
19 |
+
$labels = $this->getData('labels');
|
20 |
+
|
21 |
+
return $labels ? $labels : [];
|
22 |
+
}
|
23 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Base.php
ADDED
@@ -0,0 +1,45 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Base
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Base
|
7 |
+
extends Mage_Core_Block_Template
|
8 |
+
{
|
9 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface */
|
10 |
+
protected $collector;
|
11 |
+
|
12 |
+
/** @var Ecocode_Profiler_Model_Profile */
|
13 |
+
protected $profile;
|
14 |
+
|
15 |
+
public function setCollector(Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector)
|
16 |
+
{
|
17 |
+
$this->collector = $collector;
|
18 |
+
}
|
19 |
+
|
20 |
+
public function getCollector()
|
21 |
+
{
|
22 |
+
return $this->collector;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return Ecocode_Profiler_Model_Profile
|
27 |
+
*/
|
28 |
+
public function getProfile()
|
29 |
+
{
|
30 |
+
if ($this->profile === null) {
|
31 |
+
$this->profile = Mage::registry('current_profile');
|
32 |
+
}
|
33 |
+
return $this->profile;
|
34 |
+
}
|
35 |
+
|
36 |
+
public function renderBag($bag, array $data = [])
|
37 |
+
{
|
38 |
+
/** @var Ecocode_Profiler_Block_Bag $bagBlock */
|
39 |
+
$bagBlock = $this->getLayout()->createBlock('ecocode_profiler/bag');
|
40 |
+
$data['bag'] = $bag;
|
41 |
+
$bagBlock->setData($data);
|
42 |
+
|
43 |
+
return $bagBlock->toHtml();
|
44 |
+
}
|
45 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Layout/Panel.php
ADDED
@@ -0,0 +1,137 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Layout_Panel
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Layout_Panel
|
7 |
+
extends Ecocode_Profiler_Block_Collector_Base
|
8 |
+
{
|
9 |
+
protected $tree;
|
10 |
+
|
11 |
+
private static $colors = [
|
12 |
+
'block' => '#dfd',
|
13 |
+
'macro' => '#ddf',
|
14 |
+
'template' => '#ffd',
|
15 |
+
'big' => '#d44',
|
16 |
+
];
|
17 |
+
|
18 |
+
public function renderTree()
|
19 |
+
{
|
20 |
+
$html = '';
|
21 |
+
foreach ($this->getCallTree() as $node) {
|
22 |
+
$html .= $this->renderNode($node);
|
23 |
+
}
|
24 |
+
|
25 |
+
return '<pre>' . $html . '</pre>';
|
26 |
+
}
|
27 |
+
|
28 |
+
protected function renderNode($node, $prefix = '', $sibling = false)
|
29 |
+
{
|
30 |
+
if (!$node['parent_id']) {
|
31 |
+
$start = $node['name'];
|
32 |
+
} else {
|
33 |
+
if (isset($node['template'])) {
|
34 |
+
$start = $this->_formatTemplate($node, $prefix);
|
35 |
+
} else {
|
36 |
+
$start = $this->_formatBlock($node, $prefix);
|
37 |
+
}
|
38 |
+
if ($node['cacheable']) {
|
39 |
+
$start .= '<span class="label">cacheable</span>';
|
40 |
+
}
|
41 |
+
$prefix .= $sibling ? '│ ' : ' ';
|
42 |
+
}
|
43 |
+
$percent = $node['render_time_percent'] *= 100;
|
44 |
+
|
45 |
+
if (false && $node['render_time'] * 1000 < 1) {
|
46 |
+
$str = $start . "\n";
|
47 |
+
} else {
|
48 |
+
$str = sprintf("%s %s\n", $start, $this->_formatTime($node, $percent));
|
49 |
+
}
|
50 |
+
|
51 |
+
if ($node['children']) {
|
52 |
+
$nCount = count($node['children']);
|
53 |
+
$index = 0;
|
54 |
+
foreach ($node['children'] as $childNode) {
|
55 |
+
$index++;
|
56 |
+
$str .= $this->renderNode($childNode, $prefix, $index !== $nCount);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
return $str;
|
60 |
+
}
|
61 |
+
|
62 |
+
|
63 |
+
public function getCallTree()
|
64 |
+
{
|
65 |
+
if (!$this->tree) {
|
66 |
+
$this->tree = $this->createCallTree();
|
67 |
+
}
|
68 |
+
|
69 |
+
return $this->tree;
|
70 |
+
}
|
71 |
+
|
72 |
+
protected function createCallTree()
|
73 |
+
{
|
74 |
+
$tree = [];
|
75 |
+
/** @var Ecocode_Profiler_Model_Collector_LayoutDataCollector $collector */
|
76 |
+
$collector = $this->getCollector();
|
77 |
+
$totalRenderTime = $collector->getTotalRenderTime();
|
78 |
+
$nodeList = $collector->getRenderLog();
|
79 |
+
foreach ($nodeList as $id => &$node) {
|
80 |
+
$node['render_time_percent'] = $node['render_time_incl'] / $totalRenderTime;
|
81 |
+
}
|
82 |
+
foreach ($nodeList as $id => &$node) {
|
83 |
+
$nodeList[$id] = $node;
|
84 |
+
if ($node['parent_id'] === false) {
|
85 |
+
$this->resolveChildren($node, $nodeList);
|
86 |
+
$tree[$id] = $node;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
return $tree;
|
91 |
+
}
|
92 |
+
|
93 |
+
protected function resolveChildren(&$node, array $nodeList)
|
94 |
+
{
|
95 |
+
$children = [];
|
96 |
+
if (isset($node['children'])) {
|
97 |
+
foreach ($node['children'] as $childId) {
|
98 |
+
$child = $nodeList[$childId];
|
99 |
+
|
100 |
+
$this->resolveChildren($child, $nodeList);
|
101 |
+
$children[$childId] = $child;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
$node['children'] = $children;
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
protected function _formatTemplate($blockData, $prefix)
|
109 |
+
{
|
110 |
+
return sprintf(
|
111 |
+
'%sâ”” <span style="background-color: %s">%s (%s) <small>%s::%s</small></span>',
|
112 |
+
$prefix,
|
113 |
+
self::$colors['template'],
|
114 |
+
$blockData['name'],
|
115 |
+
$blockData['type'],
|
116 |
+
$blockData['class'],
|
117 |
+
$blockData['template']
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
protected function _formatBlock($blockData, $prefix)
|
122 |
+
{
|
123 |
+
return sprintf(
|
124 |
+
'%sâ”” <span style="background-color: %s">%s (%s) <small>%s</small></span>',
|
125 |
+
$prefix, self::$colors['block'],
|
126 |
+
$blockData['name'],
|
127 |
+
$blockData['type'],
|
128 |
+
$blockData['class']
|
129 |
+
);
|
130 |
+
}
|
131 |
+
|
132 |
+
protected function _formatTime($node, $percent)
|
133 |
+
{
|
134 |
+
return sprintf('<span style="color: %s">%.2fms/%.0f%% (excl. %.2fms)</span>', $percent > 20 ? self::$colors['big'] : 'auto', $node['render_time_incl'] * 1000, $percent, $node['render_time'] * 1000);
|
135 |
+
}
|
136 |
+
|
137 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Log/Panel.php
ADDED
@@ -0,0 +1,98 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Log_Panel
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Log_Panel
|
7 |
+
extends Ecocode_Profiler_Block_Collector_Base
|
8 |
+
{
|
9 |
+
protected $logTableRenderer;
|
10 |
+
protected $logGroups;
|
11 |
+
|
12 |
+
protected $priorityNames = [
|
13 |
+
Zend_Log::EMERG => 'emergency',
|
14 |
+
Zend_Log::ALERT => 'emergency',
|
15 |
+
Zend_Log::CRIT => 'critical',
|
16 |
+
Zend_Log::ERR => 'error',
|
17 |
+
Zend_Log::WARN => 'warning',
|
18 |
+
Zend_Log::NOTICE => 'notice',
|
19 |
+
Zend_Log::INFO => 'info',
|
20 |
+
Zend_Log::DEBUG => 'debug',
|
21 |
+
];
|
22 |
+
|
23 |
+
|
24 |
+
public function getLogGroups()
|
25 |
+
{
|
26 |
+
if ($this->logGroups === null) {
|
27 |
+
$logGroups = [
|
28 |
+
'deprecation' => [],
|
29 |
+
'debug' => [],
|
30 |
+
'info_and_error' => [],
|
31 |
+
'silenced' => []
|
32 |
+
];
|
33 |
+
|
34 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
35 |
+
$collector = $this->getCollector();
|
36 |
+
foreach ($collector->getLogs() as $log) {
|
37 |
+
if (isset($log['context']['level'], $log['context']['type']) && in_array($log['context']['type'], [E_DEPRECATED, E_USER_DEPRECATED])) {
|
38 |
+
$logGroups['deprecation'][] = $log;
|
39 |
+
} elseif (isset($log['context']['scream']) && $log['context']['scream'] === true) {
|
40 |
+
$logGroups['silenced'][] = $log;
|
41 |
+
} elseif ($log['priorityName'] === 'DEBUG') {
|
42 |
+
$logGroups['debug'][] = $log;
|
43 |
+
} else {
|
44 |
+
$logGroups['info_and_error'][] = $log;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
$this->logGroups = $logGroups;
|
48 |
+
}
|
49 |
+
|
50 |
+
return $this->logGroups;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function getPriorityName($level)
|
54 |
+
{
|
55 |
+
$names = $this->priorityNames;
|
56 |
+
if (isset($names[$level])) {
|
57 |
+
return $names[$level];
|
58 |
+
}
|
59 |
+
|
60 |
+
return 'unknown';
|
61 |
+
}
|
62 |
+
|
63 |
+
public function getEntryCssClass($level)
|
64 |
+
{
|
65 |
+
if ($level <= 3) {
|
66 |
+
return 'status-error';
|
67 |
+
}
|
68 |
+
if ($level <= 5) {
|
69 |
+
return 'status-warning';
|
70 |
+
}
|
71 |
+
|
72 |
+
return '';
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
public function renderLogTable($logs, $category = '', $showLevel = false, $isDeprecation = false)
|
77 |
+
{
|
78 |
+
$block = $this->getLogTableRenderer();
|
79 |
+
$block->setData([
|
80 |
+
'logs' => $logs,
|
81 |
+
'category' => $category,
|
82 |
+
'show_level' => $showLevel,
|
83 |
+
'is_deprecation' => $isDeprecation
|
84 |
+
]);
|
85 |
+
return $block->toHtml();
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return $this
|
90 |
+
*/
|
91 |
+
public function getLogTableRenderer()
|
92 |
+
{
|
93 |
+
if ($this->logTableRenderer === null) {
|
94 |
+
$this->logTableRenderer = Mage::app()->getLayout()->createBlock('ecocode_profiler/renderer_log_logTable');
|
95 |
+
}
|
96 |
+
return $this->logTableRenderer;
|
97 |
+
}
|
98 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Menu.php
ADDED
@@ -0,0 +1,14 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Menu
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Menu extends
|
7 |
+
Ecocode_Profiler_Block_Collector_Base
|
8 |
+
{
|
9 |
+
public function _construct()
|
10 |
+
{
|
11 |
+
parent::_construct();
|
12 |
+
$this->setTemplate('ecocode_profiler/collector/base/menu.phtml');
|
13 |
+
}
|
14 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Mysql/Panel.php
ADDED
@@ -0,0 +1,183 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Mysql_Panel
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Mysql_Panel
|
7 |
+
extends Ecocode_Profiler_Block_Collector_Base
|
8 |
+
{
|
9 |
+
|
10 |
+
|
11 |
+
protected $sqlHelper;
|
12 |
+
protected $queryTableRenderer;
|
13 |
+
|
14 |
+
protected $queries;
|
15 |
+
protected $identicalQueries;
|
16 |
+
protected $queriesByContext;
|
17 |
+
protected $queryCountByType;
|
18 |
+
|
19 |
+
public function _construct()
|
20 |
+
{
|
21 |
+
//ban cache usage as we dont need the cache and it causes some overhead
|
22 |
+
Mage::app()->getCacheInstance()->banUse(Mage_Core_Block_Abstract::CACHE_GROUP);
|
23 |
+
|
24 |
+
$this->setTemplate('ecocode_profiler/collector/mysql/panel.phtml');
|
25 |
+
parent::_construct();
|
26 |
+
}
|
27 |
+
|
28 |
+
public function prepareQueryData()
|
29 |
+
{
|
30 |
+
$this->queries = [];
|
31 |
+
$this->identicalQueries = [];
|
32 |
+
$this->queriesByContext = [];
|
33 |
+
$this->queryCountByType = [
|
34 |
+
'select' => 0,
|
35 |
+
'insert' => 0,
|
36 |
+
'update' => 0,
|
37 |
+
'delete' => 0
|
38 |
+
];
|
39 |
+
|
40 |
+
/** @var Ecocode_Profiler_Model_Collector_MysqlDataCollector $collector */
|
41 |
+
$collector = $this->getCollector();
|
42 |
+
|
43 |
+
foreach ($collector->getQueries() as &$queryData) {
|
44 |
+
$this->processType($queryData);
|
45 |
+
$this->preRenderQuery($queryData);
|
46 |
+
$this->processIdentical($queryData);
|
47 |
+
$this->processContext($queryData);
|
48 |
+
$this->queries[] = $queryData;
|
49 |
+
}
|
50 |
+
|
51 |
+
usort($this->queriesByContext, function ($a, $b) {
|
52 |
+
return $b['count'] - $a['count'];
|
53 |
+
});
|
54 |
+
|
55 |
+
usort($this->identicalQueries, function ($a, $b) {
|
56 |
+
return $b['count'] - $a['count'];
|
57 |
+
});
|
58 |
+
|
59 |
+
$this->identicalQueries = array_filter($this->identicalQueries, function ($item) {
|
60 |
+
return $item['count'] > 1;
|
61 |
+
});
|
62 |
+
|
63 |
+
|
64 |
+
return $this;
|
65 |
+
}
|
66 |
+
|
67 |
+
protected function processType(array &$queryData)
|
68 |
+
{
|
69 |
+
$sql = $queryData['sql'];
|
70 |
+
$type = explode(' ', $sql, 2);
|
71 |
+
$type = reset($type);
|
72 |
+
$type = strtolower($type);
|
73 |
+
|
74 |
+
if (isset($this->queryCountByType[$type])) {
|
75 |
+
$this->queryCountByType[$type]++;
|
76 |
+
}
|
77 |
+
|
78 |
+
$queryData['type'] = $type;
|
79 |
+
}
|
80 |
+
|
81 |
+
protected function processIdentical(array $queryData)
|
82 |
+
{
|
83 |
+
$queryId = md5($queryData['sql'] . implode(',', $queryData['params']));
|
84 |
+
|
85 |
+
if (!isset($this->identicalQueries[$queryId])) {
|
86 |
+
$this->identicalQueries[$queryId] = [
|
87 |
+
'id' => $queryId,
|
88 |
+
'count' => 0,
|
89 |
+
'total_time' => 0,
|
90 |
+
'query' => $queryData,
|
91 |
+
'traces' => []
|
92 |
+
];
|
93 |
+
}
|
94 |
+
$this->identicalQueries[$queryId]['count']++;
|
95 |
+
$this->identicalQueries[$queryId]['total_time'] += $queryData['time'];
|
96 |
+
$this->identicalQueries[$queryId]['traces'][] = $queryData['trace'];
|
97 |
+
}
|
98 |
+
|
99 |
+
protected function processContext(array $queryData)
|
100 |
+
{
|
101 |
+
$contextKey = $queryData['context'];
|
102 |
+
if (!isset($this->queriesByContext[$contextKey])) {
|
103 |
+
$this->queriesByContext[$contextKey] = [
|
104 |
+
'name' => $contextKey,
|
105 |
+
'count' => 0,
|
106 |
+
'total_time' => 0,
|
107 |
+
'queries' => []
|
108 |
+
];
|
109 |
+
}
|
110 |
+
|
111 |
+
$this->queriesByContext[$contextKey]['count']++;
|
112 |
+
$this->queriesByContext[$contextKey]['total_time'] += $queryData['time'];
|
113 |
+
$this->queriesByContext[$contextKey]['queries'][] = $queryData;
|
114 |
+
}
|
115 |
+
|
116 |
+
public function getIdenticalQueries()
|
117 |
+
{
|
118 |
+
if ($this->identicalQueries === null) {
|
119 |
+
$this->prepareQueryData();
|
120 |
+
}
|
121 |
+
return $this->identicalQueries;
|
122 |
+
}
|
123 |
+
|
124 |
+
public function preRenderQuery(array &$queryData)
|
125 |
+
{
|
126 |
+
$queryTableRenderer = $this->getQueryTableRenderer();
|
127 |
+
|
128 |
+
$queryData['sql_highlighted'] = $queryTableRenderer->formatQuery($queryData['sql'], true);
|
129 |
+
$queryData['sql_formatted'] = $queryTableRenderer->formatQuery($queryData['sql']);
|
130 |
+
$queryData['sql_runnable'] = $queryTableRenderer->formatQuery(
|
131 |
+
$queryTableRenderer->replaceQueryParameters($queryData['sql'], $queryData['params']),
|
132 |
+
true
|
133 |
+
);
|
134 |
+
}
|
135 |
+
|
136 |
+
public function getQueries()
|
137 |
+
{
|
138 |
+
if ($this->queries === null) {
|
139 |
+
$this->prepareQueryData();
|
140 |
+
}
|
141 |
+
return $this->queries;
|
142 |
+
}
|
143 |
+
|
144 |
+
public function getQueryCountByType()
|
145 |
+
{
|
146 |
+
if ($this->queryCountByType === null) {
|
147 |
+
$this->prepareQueryData();
|
148 |
+
$this->queryCountByType = array_filter($this->queryCountByType);
|
149 |
+
}
|
150 |
+
return $this->queryCountByType;
|
151 |
+
}
|
152 |
+
|
153 |
+
public function getByContext()
|
154 |
+
{
|
155 |
+
if ($this->queriesByContext === null) {
|
156 |
+
$this->prepareQueryData();
|
157 |
+
}
|
158 |
+
return $this->queriesByContext;
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
public function renderQueryTable($prefix, array $queries)
|
163 |
+
{
|
164 |
+
$prefix .= '-';
|
165 |
+
$block = $this->getQueryTableRenderer();
|
166 |
+
$block->setData([
|
167 |
+
'queries' => $queries,
|
168 |
+
'prefix' => $prefix
|
169 |
+
]);
|
170 |
+
return $block->toHtml();
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* @return $this
|
175 |
+
*/
|
176 |
+
public function getQueryTableRenderer()
|
177 |
+
{
|
178 |
+
if ($this->queryTableRenderer === null) {
|
179 |
+
$this->queryTableRenderer = Mage::app()->getLayout()->createBlock('ecocode_profiler/renderer_mysql_queryTable');
|
180 |
+
}
|
181 |
+
return $this->queryTableRenderer;
|
182 |
+
}
|
183 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Collector/Translation/Panel.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Collector_Translation_Panel
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Collector_Translation_Panel
|
7 |
+
extends Ecocode_Profiler_Block_Collector_Base
|
8 |
+
{
|
9 |
+
|
10 |
+
|
11 |
+
public function getMessageGroups()
|
12 |
+
{
|
13 |
+
/** @var Ecocode_Profiler_Model_Collector_TranslationDataCollector $collector */
|
14 |
+
$collector = $this->getCollector();
|
15 |
+
$statusCounts = $collector->getStateCount();
|
16 |
+
|
17 |
+
$groups = array_fill_keys(array_keys($statusCounts), []);
|
18 |
+
|
19 |
+
foreach ($collector->getTranslations() as $message) {
|
20 |
+
$groups[$message['state']][] = $message;
|
21 |
+
}
|
22 |
+
|
23 |
+
return $groups;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function renderTable(array $messages)
|
27 |
+
{
|
28 |
+
$tableBlock = $this->getLayout()->createBlock('core/template');
|
29 |
+
$tableBlock->setTemplate('ecocode_profiler/collector/translation/panel/table.phtml');
|
30 |
+
$tableBlock->setData('messages', $messages);
|
31 |
+
return $tableBlock->toHtml();
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Profiler_Sidebar
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Profiler_Sidebar
|
7 |
+
extends Mage_Core_Block_Template
|
8 |
+
{
|
9 |
+
protected $profile = null;
|
10 |
+
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->setTemplate('ecocode_profiler/layout/sidebar.phtml');
|
14 |
+
parent::_construct();
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getCollector()
|
18 |
+
{
|
19 |
+
return $this->getProfile()->getCollector(Mage::registry('current_panel'));
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return Ecocode_Profiler_Model_Profile
|
24 |
+
*/
|
25 |
+
public function getProfile()
|
26 |
+
{
|
27 |
+
if ($this->profile === null) {
|
28 |
+
$this->profile = Mage::registry('current_profile');
|
29 |
+
}
|
30 |
+
|
31 |
+
return $this->profile;
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar/Menu.php
ADDED
@@ -0,0 +1,45 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Profiler_Sidebar_Menu
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Profiler_Sidebar_Menu extends Mage_Core_Block_Template
|
7 |
+
{
|
8 |
+
protected $profile = null;
|
9 |
+
|
10 |
+
public function getMenuBlocks()
|
11 |
+
{
|
12 |
+
if (!$this->getProfile()) {
|
13 |
+
return [];
|
14 |
+
}
|
15 |
+
|
16 |
+
$blocks = [];
|
17 |
+
|
18 |
+
$collectors = $this->getProfile()->getCollectors();
|
19 |
+
foreach ($this->getSortedChildBlocks() as $name => $block) {
|
20 |
+
if (!$block instanceof Ecocode_Profiler_Block_Collector_Base) {
|
21 |
+
continue;
|
22 |
+
}
|
23 |
+
|
24 |
+
if(!isset($collectors[$name])) {
|
25 |
+
continue;
|
26 |
+
}
|
27 |
+
$block->setCollector($collectors[$name]);
|
28 |
+
$blocks[$collectors[$name]->getName()] = $block;
|
29 |
+
}
|
30 |
+
|
31 |
+
return $blocks;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return Ecocode_Profiler_Model_Profile
|
36 |
+
*/
|
37 |
+
public function getProfile()
|
38 |
+
{
|
39 |
+
if ($this->profile === null) {
|
40 |
+
$this->profile = Mage::registry('current_profile');
|
41 |
+
}
|
42 |
+
|
43 |
+
return $this->profile;
|
44 |
+
}
|
45 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/AbstractRenderer.php
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
5 |
+
*
|
6 |
+
* @method getBag
|
7 |
+
*/
|
8 |
+
class Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
9 |
+
extends Mage_Core_Block_Template
|
10 |
+
implements Ecocode_Profiler_Block_Renderer_RendererInterface
|
11 |
+
{
|
12 |
+
protected $_templateFileCache = [];
|
13 |
+
|
14 |
+
public function render(array $data = [])
|
15 |
+
{
|
16 |
+
$this->setData($data);
|
17 |
+
return $this->toHtml();
|
18 |
+
}
|
19 |
+
|
20 |
+
public function getTemplateFile()
|
21 |
+
{
|
22 |
+
$template = $this->getTemplate();
|
23 |
+
$key = $this->getArea() . '_' . $template;
|
24 |
+
|
25 |
+
if (!isset($this->_templateFileCache[$key])) {
|
26 |
+
$this->_templateFileCache[$key] = parent::getTemplateFile();
|
27 |
+
}
|
28 |
+
|
29 |
+
return $this->_templateFileCache[$key];
|
30 |
+
}
|
31 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/BackTrace.php
ADDED
@@ -0,0 +1,36 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Bag
|
5 |
+
*
|
6 |
+
* @method getBag
|
7 |
+
*/
|
8 |
+
class Ecocode_Profiler_Block_Renderer_BackTrace
|
9 |
+
extends Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
10 |
+
{
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->setTemplate('ecocode_profiler/back-trace.phtml');
|
14 |
+
parent::_construct();
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getTraceId()
|
18 |
+
{
|
19 |
+
$id = $this->getData('id');
|
20 |
+
if (!$id) {
|
21 |
+
$this->setData('id', uniqid());
|
22 |
+
}
|
23 |
+
|
24 |
+
return $id;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getTrace()
|
28 |
+
{
|
29 |
+
$trace = $this->getData('trace');
|
30 |
+
if (!$trace) {
|
31 |
+
return [];
|
32 |
+
}
|
33 |
+
|
34 |
+
return $trace;
|
35 |
+
}
|
36 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/Context.php
ADDED
@@ -0,0 +1,16 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Renderer_Context
|
5 |
+
*
|
6 |
+
* @method getBag
|
7 |
+
*/
|
8 |
+
class Ecocode_Profiler_Block_Renderer_Context
|
9 |
+
extends Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
10 |
+
{
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->setTemplate('ecocode_profiler/renderer/context.phtml');
|
14 |
+
parent::_construct();
|
15 |
+
}
|
16 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/Log/LogTable.php
ADDED
@@ -0,0 +1,41 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Renderer_Log_LogTable
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Renderer_Log_LogTable
|
7 |
+
extends Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
8 |
+
{
|
9 |
+
public function _construct()
|
10 |
+
{
|
11 |
+
$this->setTemplate('ecocode_profiler/collector/log/panel/log-table.phtml');
|
12 |
+
parent::_construct();
|
13 |
+
}
|
14 |
+
|
15 |
+
public function getCategory()
|
16 |
+
{
|
17 |
+
return isset($this->_data['category']) ? $this->_data['category'] : [];
|
18 |
+
}
|
19 |
+
|
20 |
+
public function getLogs()
|
21 |
+
{
|
22 |
+
return isset($this->_data['logs']) ? $this->_data['logs'] : [];
|
23 |
+
}
|
24 |
+
|
25 |
+
public function getShowLevel()
|
26 |
+
{
|
27 |
+
return isset($this->_data['show_level']) ? $this->_data['show_level'] : true;
|
28 |
+
}
|
29 |
+
|
30 |
+
public function isDeprecation()
|
31 |
+
{
|
32 |
+
return isset($this->_data['is_deprecation']) ? $this->_data['is_deprecation'] : false;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function isChannelDefined()
|
36 |
+
{
|
37 |
+
$logs = $this->getLogs();
|
38 |
+
$log = reset($logs);
|
39 |
+
return isset($log['channel']);
|
40 |
+
}
|
41 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/Mysql/QueryTable.php
ADDED
@@ -0,0 +1,43 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Block_Renderer_Context
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Block_Renderer_Mysql_QueryTable
|
7 |
+
extends Ecocode_Profiler_Block_Renderer_AbstractRenderer
|
8 |
+
{
|
9 |
+
protected $sqlHelper;
|
10 |
+
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->setTemplate('ecocode_profiler/collector/mysql/panel/query-table.phtml');
|
14 |
+
parent::_construct();
|
15 |
+
}
|
16 |
+
|
17 |
+
|
18 |
+
public function replaceQueryParameters($query, array $parameters)
|
19 |
+
{
|
20 |
+
return $this->getSqlHelper()->replaceQueryParameters($query, $parameters);
|
21 |
+
}
|
22 |
+
|
23 |
+
public function dumpParameters(array $parameters)
|
24 |
+
{
|
25 |
+
return $this->getSqlHelper()->dumpParameters($parameters);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function formatQuery($sql, $highlightOnly = false)
|
29 |
+
{
|
30 |
+
return $this->getSqlHelper()->formatQuery($sql, $highlightOnly);
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @return Ecocode_Profiler_Helper_Sql
|
35 |
+
*/
|
36 |
+
public function getSqlHelper()
|
37 |
+
{
|
38 |
+
if ($this->sqlHelper === null) {
|
39 |
+
$this->sqlHelper = Mage::helper('ecocode_profiler/sql');
|
40 |
+
}
|
41 |
+
return $this->sqlHelper;
|
42 |
+
}
|
43 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Renderer/RendererInterface.php
ADDED
@@ -0,0 +1,9 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Ecocode_Profiler_Block_Renderer_RendererInterface
|
5 |
+
*/
|
6 |
+
interface Ecocode_Profiler_Block_Renderer_RendererInterface
|
7 |
+
{
|
8 |
+
public function render(array $data = []);
|
9 |
+
}
|
app/code/community/Ecocode/Profiler/Block/Toolbar.php
ADDED
@@ -0,0 +1,65 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Block_Toolbar
|
4 |
+
extends Mage_Core_Block_Template
|
5 |
+
{
|
6 |
+
protected $profile = null;
|
7 |
+
protected $collectors = null;
|
8 |
+
|
9 |
+
public function _construct()
|
10 |
+
{
|
11 |
+
$this->setTemplate('ecocode_profiler/toolbar_js.phtml');
|
12 |
+
parent::_construct();
|
13 |
+
}
|
14 |
+
|
15 |
+
public function getToken()
|
16 |
+
{
|
17 |
+
if ($this->getData('token')) {
|
18 |
+
return $this->getData('token');
|
19 |
+
}
|
20 |
+
|
21 |
+
if ($this->getProfile()) {
|
22 |
+
return $this->getProfile()->getToken();
|
23 |
+
}
|
24 |
+
return false;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function getCollectors()
|
28 |
+
{
|
29 |
+
if ($this->collectors === null) {
|
30 |
+
$this->collectors = $this->getProfile()->getCollectors();
|
31 |
+
|
32 |
+
}
|
33 |
+
return $this->collectors;
|
34 |
+
}
|
35 |
+
|
36 |
+
public function getToolbarItems()
|
37 |
+
{
|
38 |
+
$blocks = [];
|
39 |
+
|
40 |
+
$layout = $this->getLayout();
|
41 |
+
foreach ($this->getCollectors() as $collector) {
|
42 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */
|
43 |
+
if (!$block = $layout->getBlock($collector->getBlockToolbarName())) {
|
44 |
+
continue;
|
45 |
+
}
|
46 |
+
$block->setCollector($collector);
|
47 |
+
$block->setData('token', $this->getToken());
|
48 |
+
$blocks[$collector->getName()] = $block;
|
49 |
+
}
|
50 |
+
|
51 |
+
return $blocks;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @return Ecocode_Profiler_Model_Profile
|
56 |
+
*/
|
57 |
+
public function getProfile()
|
58 |
+
{
|
59 |
+
if ($this->profile === null) {
|
60 |
+
$this->profile = Mage::registry('current_profile');
|
61 |
+
}
|
62 |
+
|
63 |
+
return $this->profile;
|
64 |
+
}
|
65 |
+
}
|
app/code/community/Ecocode/Profiler/Controller/AbstractController.php
ADDED
@@ -0,0 +1,52 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_AbstractController
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Controller_AbstractController
|
7 |
+
extends Mage_Core_Controller_Front_Action
|
8 |
+
{
|
9 |
+
/** @var Ecocode_Profiler_Model_Profiler */
|
10 |
+
protected $profiler;
|
11 |
+
|
12 |
+
public function preDispatch()
|
13 |
+
{
|
14 |
+
$app = $this->getApp();
|
15 |
+
//should not be needed as we do not include development.xml
|
16 |
+
//in production anyway
|
17 |
+
if (!$app instanceof Ecocode_Profiler_Model_AppDev) {
|
18 |
+
throw new \RuntimeException('You are not allowed to access this file. Check ' . basename(__FILE__) . ' for more information.');
|
19 |
+
}
|
20 |
+
|
21 |
+
/** @var Mage_Core_Model_Config $config */
|
22 |
+
$config = $app->getConfig();
|
23 |
+
|
24 |
+
//disable before/after to html observer as its quiet costly
|
25 |
+
$config->setNode('frontend/events/core_block_abstract_to_html_before/observers/ecocode_profiler_context/type', 'disabled');
|
26 |
+
$config->setNode('frontend/events/core_block_abstract_to_html_after/observers/ecocode_profiler_context/type', 'disabled');
|
27 |
+
|
28 |
+
parent::preDispatch();
|
29 |
+
return $this;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @codeCoverageIgnore
|
34 |
+
* @return Mage_Core_Model_App
|
35 |
+
*/
|
36 |
+
protected function getApp()
|
37 |
+
{
|
38 |
+
return Mage::app();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @codeCoverageIgnore
|
43 |
+
* @return Ecocode_Profiler_Model_Profiler
|
44 |
+
*/
|
45 |
+
protected function getProfiler()
|
46 |
+
{
|
47 |
+
if (!$this->profiler) {
|
48 |
+
$this->profiler = Mage::getSingleton('ecocode_profiler/profiler');
|
49 |
+
}
|
50 |
+
return $this->profiler;
|
51 |
+
}
|
52 |
+
}
|
app/code/community/Ecocode/Profiler/Db/Statement/Pdo/Mysql.php
ADDED
@@ -0,0 +1,94 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Db_Statement_Pdo_Mysql
|
5 |
+
*
|
6 |
+
*/
|
7 |
+
class Ecocode_Profiler_Db_Statement_Pdo_Mysql extends Varien_Db_Statement_Pdo_Mysql
|
8 |
+
{
|
9 |
+
protected $elapsedTime;
|
10 |
+
protected $params;
|
11 |
+
protected $result;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Executes statement with binding values to it.
|
15 |
+
* Allows transferring specific options to DB driver.
|
16 |
+
*
|
17 |
+
* @param array $params Array of values to bind to parameter placeholders.
|
18 |
+
* @return bool
|
19 |
+
* @throws Zend_Db_Statement_Exception
|
20 |
+
*/
|
21 |
+
public function _executeWithBinding(array $params)
|
22 |
+
{
|
23 |
+
$this->params = $params;
|
24 |
+
$start = microtime(true);
|
25 |
+
|
26 |
+
$this->result = parent::_executeWithBinding($params);
|
27 |
+
|
28 |
+
$this->elapsedTime = microtime(true) - $start;
|
29 |
+
$this->log();
|
30 |
+
return $this->result;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Executes a prepared statement.
|
35 |
+
*
|
36 |
+
* @param array $params OPTIONAL Values to bind to parameter placeholders.
|
37 |
+
* @return bool
|
38 |
+
* @throws Zend_Db_Statement_Exception
|
39 |
+
*/
|
40 |
+
public function _execute(array $params = null)
|
41 |
+
{
|
42 |
+
$this->params = $params;
|
43 |
+
$start = microtime(true);
|
44 |
+
|
45 |
+
$this->result = parent::_execute($params);
|
46 |
+
|
47 |
+
$this->elapsedTime = microtime(true) - $start;
|
48 |
+
$this->log();
|
49 |
+
|
50 |
+
return $this->result;
|
51 |
+
}
|
52 |
+
|
53 |
+
protected function log()
|
54 |
+
{
|
55 |
+
$this->getCollector()->logQuery($this);
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @return Ecocode_Profiler_Model_Collector_MysqlDataCollector
|
60 |
+
*/
|
61 |
+
public function getCollector()
|
62 |
+
{
|
63 |
+
return Mage::getSingleton('ecocode_profiler/collector_mysqlDataCollector');
|
64 |
+
}
|
65 |
+
|
66 |
+
public function getQueryString()
|
67 |
+
{
|
68 |
+
return $this->_stmt->queryString;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return mixed
|
73 |
+
*/
|
74 |
+
public function getElapsedTime()
|
75 |
+
{
|
76 |
+
return $this->elapsedTime;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* @return mixed
|
81 |
+
*/
|
82 |
+
public function getParams()
|
83 |
+
{
|
84 |
+
return $this->params;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @return mixed
|
89 |
+
*/
|
90 |
+
public function getResult()
|
91 |
+
{
|
92 |
+
return $this->result;
|
93 |
+
}
|
94 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/AbstractHelper.php
ADDED
@@ -0,0 +1,17 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_AbstractHelper
|
5 |
+
*/
|
6 |
+
abstract class Ecocode_Profiler_Helper_AbstractHelper
|
7 |
+
{
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return null|Ecocode_Profiler_Model_Profile
|
11 |
+
* @codeCoverageIgnore
|
12 |
+
*/
|
13 |
+
public function getCurrentProfile()
|
14 |
+
{
|
15 |
+
return Mage::registry('current_profile');
|
16 |
+
}
|
17 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/Code.php
ADDED
@@ -0,0 +1,200 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
/**
|
5 |
+
* Twig extension relate to PHP code and used by the profiler and the default exception templates.
|
6 |
+
*
|
7 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
8 |
+
*/
|
9 |
+
class Ecocode_Profiler_Helper_Code
|
10 |
+
{
|
11 |
+
private $fileLinkFormat;
|
12 |
+
private $rootDir;
|
13 |
+
private $charset;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Constructor.
|
17 |
+
* @param null $format
|
18 |
+
* @param null $rootDir
|
19 |
+
* @param null|string $charset
|
20 |
+
*/
|
21 |
+
public function __construct($format = null, $rootDir = null, $charset = 'UTF-8')
|
22 |
+
{
|
23 |
+
$this->fileLinkFormat = $format ? $format : ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format');
|
24 |
+
$this->rootDir = $rootDir ? $rootDir : str_replace('/', DIRECTORY_SEPARATOR, dirname(Mage::getRoot())) . DIRECTORY_SEPARATOR;
|
25 |
+
$this->charset = $charset;
|
26 |
+
}
|
27 |
+
|
28 |
+
public function abbrClass($class)
|
29 |
+
{
|
30 |
+
$parts = explode('\\', $class);
|
31 |
+
$short = array_pop($parts);
|
32 |
+
|
33 |
+
return sprintf('<abbr title="%s">%s</abbr>', $class, $short);
|
34 |
+
}
|
35 |
+
|
36 |
+
public function abbrMethod($method)
|
37 |
+
{
|
38 |
+
if (false !== strpos($method, '::')) {
|
39 |
+
list($class, $method) = explode('::', $method, 2);
|
40 |
+
$result = sprintf('%s::%s()', $this->abbrClass($class), $method);
|
41 |
+
} elseif ('Closure' === $method) {
|
42 |
+
$result = sprintf('<abbr title="%s">%s</abbr>', $method, $method);
|
43 |
+
} else {
|
44 |
+
$result = sprintf('<abbr title="%s">%s</abbr>()', $method, $method);
|
45 |
+
}
|
46 |
+
|
47 |
+
return $result;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Formats an array as a string.
|
52 |
+
*
|
53 |
+
* @param array $args The argument array
|
54 |
+
*
|
55 |
+
* @return string
|
56 |
+
*/
|
57 |
+
public function formatArgs($args)
|
58 |
+
{
|
59 |
+
$result = [];
|
60 |
+
foreach ($args as $key => $item) {
|
61 |
+
if ('object' === $item[0]) {
|
62 |
+
$parts = explode('\\', $item[1]);
|
63 |
+
$short = array_pop($parts);
|
64 |
+
$formattedValue = sprintf('<em>object</em>(<abbr title="%s">%s</abbr>)', $item[1], $short);
|
65 |
+
} elseif ('array' === $item[0]) {
|
66 |
+
$formattedValue = sprintf('<em>array</em>(%s)', is_array($item[1]) ? $this->formatArgs($item[1]) : $item[1]);
|
67 |
+
} elseif ('string' === $item[0]) {
|
68 |
+
$formattedValue = sprintf("'%s'", htmlspecialchars($item[1], ENT_QUOTES, $this->charset));
|
69 |
+
} elseif ('null' === $item[0]) {
|
70 |
+
$formattedValue = '<em>null</em>';
|
71 |
+
} elseif ('boolean' === $item[0]) {
|
72 |
+
$formattedValue = '<em>' . strtolower(var_export($item[1], true)) . '</em>';
|
73 |
+
} elseif ('resource' === $item[0]) {
|
74 |
+
$formattedValue = '<em>resource</em>';
|
75 |
+
} else {
|
76 |
+
$formattedValue = str_replace("\n", '', var_export(htmlspecialchars((string)$item[1], ENT_QUOTES, $this->charset), true));
|
77 |
+
}
|
78 |
+
|
79 |
+
$result[] = is_int($key) ? $formattedValue : sprintf("'%s' => %s", $key, $formattedValue);
|
80 |
+
}
|
81 |
+
|
82 |
+
return implode(', ', $result);
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Formats an array as a string.
|
87 |
+
*
|
88 |
+
* @param array $args The argument array
|
89 |
+
*
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
public function formatArgsAsText($args)
|
93 |
+
{
|
94 |
+
return strip_tags($this->formatArgs($args));
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Returns an excerpt of a code file around the given line number.
|
99 |
+
*
|
100 |
+
* @param string $file A file path
|
101 |
+
* @param int $line The selected line number
|
102 |
+
*
|
103 |
+
* @return string An HTML string
|
104 |
+
*/
|
105 |
+
public function fileExcerpt($file, $line)
|
106 |
+
{
|
107 |
+
if (is_readable($file)) {
|
108 |
+
// highlight_file could throw warnings
|
109 |
+
// see https://bugs.php.net/bug.php?id=25725
|
110 |
+
$code = @highlight_file($file, true);
|
111 |
+
// remove main code/span tags
|
112 |
+
$code = preg_replace('#^<code.*?>\s*<span.*?>(.*)</span>\s*</code>#s', '\\1', $code);
|
113 |
+
$content = preg_split('#<br />#', $code);
|
114 |
+
|
115 |
+
$lines = [];
|
116 |
+
for ($i = max($line - 3, 1), $max = min($line + 3, count($content)); $i <= $max; ++$i) {
|
117 |
+
$lines[] = '<li' . ($i == $line ? ' class="selected"' : '') . '><code>' . self::fixCodeMarkup($content[$i - 1]) . '</code></li>';
|
118 |
+
}
|
119 |
+
|
120 |
+
return '<ol start="' . max($line - 3, 1) . '">' . implode("\n", $lines) . '</ol>';
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Formats a file path.
|
126 |
+
*
|
127 |
+
* @param string $file An absolute file path
|
128 |
+
* @param int $line The line number
|
129 |
+
* @param string $text Use this text for the link rather than the file path
|
130 |
+
*
|
131 |
+
* @return string
|
132 |
+
*/
|
133 |
+
public function formatFile($file, $line, $text = null)
|
134 |
+
{
|
135 |
+
$file = trim($file);
|
136 |
+
|
137 |
+
if (null === $text) {
|
138 |
+
$text = str_replace('/', DIRECTORY_SEPARATOR, $file);
|
139 |
+
if (0 === strpos($text, $this->rootDir)) {
|
140 |
+
$text = substr($text, strlen($this->rootDir));
|
141 |
+
$text = explode(DIRECTORY_SEPARATOR, $text, 2);
|
142 |
+
$text = sprintf('<abbr title="%s%2$s">%s</abbr>%s', $this->rootDir, $text[0], isset($text[1]) ? DIRECTORY_SEPARATOR . $text[1] : '');
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
$text = "$text at line $line";
|
147 |
+
|
148 |
+
if (false !== $link = $this->getFileLink($file, $line)) {
|
149 |
+
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
|
150 |
+
|
151 |
+
return sprintf('<a href="%s" title="Click to open this file" class="file_link">%s</a>', htmlspecialchars($link, $flags, $this->charset), $text);
|
152 |
+
}
|
153 |
+
|
154 |
+
return $text;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Returns the link for a given file/line pair.
|
159 |
+
*
|
160 |
+
* @param string $file An absolute file path
|
161 |
+
* @param int $line The line number
|
162 |
+
*
|
163 |
+
* @return string A link of false
|
164 |
+
*/
|
165 |
+
public function getFileLink($file, $line)
|
166 |
+
{
|
167 |
+
if ($this->fileLinkFormat && is_file($file)) {
|
168 |
+
return strtr($this->fileLinkFormat, ['%f' => $file, '%l' => $line]);
|
169 |
+
}
|
170 |
+
|
171 |
+
return false;
|
172 |
+
}
|
173 |
+
|
174 |
+
public function formatFileFromText($text)
|
175 |
+
{
|
176 |
+
return preg_replace_callback('/in ("|")?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
|
177 |
+
return 'in ' . $this->formatFile($match[2], $match[3]);
|
178 |
+
}, $text);
|
179 |
+
}
|
180 |
+
|
181 |
+
protected static function fixCodeMarkup($line)
|
182 |
+
{
|
183 |
+
// </span> ending tag from previous line
|
184 |
+
$opening = strpos($line, '<span');
|
185 |
+
$closing = strpos($line, '</span>');
|
186 |
+
if (false !== $closing && (false === $opening || $closing < $opening)) {
|
187 |
+
$line = substr_replace($line, '', $closing, 7);
|
188 |
+
}
|
189 |
+
|
190 |
+
// missing </span> tag at the end of line
|
191 |
+
$opening = strpos($line, '<span');
|
192 |
+
$closing = strpos($line, '</span>');
|
193 |
+
if (false !== $opening && (false === $closing || $closing > $opening)) {
|
194 |
+
$line .= '</span>';
|
195 |
+
}
|
196 |
+
|
197 |
+
return $line;
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
app/code/community/Ecocode/Profiler/Helper/Context.php
ADDED
@@ -0,0 +1,104 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_Context
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Helper_Context
|
7 |
+
extends Ecocode_Profiler_Helper_AbstractHelper
|
8 |
+
{
|
9 |
+
protected $stack = [];
|
10 |
+
|
11 |
+
protected $list = [];
|
12 |
+
|
13 |
+
protected $contextRenderer;
|
14 |
+
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
$this->open(new Ecocode_Profiler_Model_Context('unknown'));
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* open a new context
|
22 |
+
*
|
23 |
+
* @param Ecocode_Profiler_Model_ContextInterface $context
|
24 |
+
*/
|
25 |
+
public function open(Ecocode_Profiler_Model_ContextInterface $context)
|
26 |
+
{
|
27 |
+
$id = $context->getId();
|
28 |
+
if ($current = $this->getCurrent()) {
|
29 |
+
$context->setParentId($current->getId());
|
30 |
+
}
|
31 |
+
|
32 |
+
$this->list[$id] = $context;
|
33 |
+
$this->stack[$id] = $context;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* close a previously opened context
|
38 |
+
*
|
39 |
+
* @param Ecocode_Profiler_Model_ContextInterface $context
|
40 |
+
* @return $this
|
41 |
+
* @throws Exception
|
42 |
+
*/
|
43 |
+
public function close(Ecocode_Profiler_Model_ContextInterface $context)
|
44 |
+
{
|
45 |
+
$id = $context->getId();
|
46 |
+
if (!isset($this->stack[$id])) {
|
47 |
+
throw new \RuntimeException('unable to close unknown context');
|
48 |
+
}
|
49 |
+
unset($this->stack[$id]);
|
50 |
+
|
51 |
+
return $this;
|
52 |
+
}
|
53 |
+
|
54 |
+
public function getList()
|
55 |
+
{
|
56 |
+
return $this->list;
|
57 |
+
}
|
58 |
+
|
59 |
+
public function getCurrent()
|
60 |
+
{
|
61 |
+
return end($this->stack);
|
62 |
+
}
|
63 |
+
|
64 |
+
public function getCurrentId()
|
65 |
+
{
|
66 |
+
$current = $this->getCurrent();
|
67 |
+
if (!$current) {
|
68 |
+
return null;
|
69 |
+
}
|
70 |
+
return $current->getId();
|
71 |
+
}
|
72 |
+
|
73 |
+
public function getStack()
|
74 |
+
{
|
75 |
+
return $this->stack;
|
76 |
+
}
|
77 |
+
|
78 |
+
|
79 |
+
public function render($prefix, $contextId)
|
80 |
+
{
|
81 |
+
$context = $this->getContextById($contextId);
|
82 |
+
return $this->getContextRenderer()
|
83 |
+
->render(['prefix' => $prefix, 'context' => $context]);
|
84 |
+
}
|
85 |
+
|
86 |
+
public function getContextById($id)
|
87 |
+
{
|
88 |
+
$profile = $this->getCurrentProfile();
|
89 |
+
return $profile->getCollector('context')->getById($id);
|
90 |
+
}
|
91 |
+
|
92 |
+
|
93 |
+
/**
|
94 |
+
* @return Ecocode_Profiler_Block_Renderer_Context
|
95 |
+
* @codeCoverageIgnore
|
96 |
+
*/
|
97 |
+
public function getContextRenderer()
|
98 |
+
{
|
99 |
+
if ($this->contextRenderer === null) {
|
100 |
+
$this->contextRenderer = Mage::app()->getLayout()->createBlock('ecocode_profiler/renderer_context');
|
101 |
+
}
|
102 |
+
return $this->contextRenderer;
|
103 |
+
}
|
104 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/Data.php
ADDED
@@ -0,0 +1,191 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_Data
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Helper_Data
|
7 |
+
{
|
8 |
+
protected static $version;
|
9 |
+
protected static $overwriteDirectory;
|
10 |
+
|
11 |
+
protected $configClassNameReflection;
|
12 |
+
protected $classNameCache;
|
13 |
+
|
14 |
+
public static function getOverwriteDir()
|
15 |
+
{
|
16 |
+
if (self::$overwriteDirectory === null) {
|
17 |
+
self::$overwriteDirectory = MAGENTO_ROOT . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
|
18 |
+
}
|
19 |
+
|
20 |
+
if (!file_exists(self::$overwriteDirectory)) {
|
21 |
+
mkdir(self::$overwriteDirectory, 0775, true);
|
22 |
+
}
|
23 |
+
|
24 |
+
return self::$overwriteDirectory;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
public static function getVersion()
|
31 |
+
{
|
32 |
+
if (self::$version === null && class_exists('Mage') && $config = Mage::getConfig()) {
|
33 |
+
//try to load from magento
|
34 |
+
$config = $config->getModuleConfig('Ecocode_Profiler');
|
35 |
+
if ($config && $config->version) {
|
36 |
+
self::$version = (string)$config->version;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
if (self::$version === null) {
|
41 |
+
//try to load it from the config directly
|
42 |
+
$configFile = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'config.xml';
|
43 |
+
$xml = file_get_contents($configFile);
|
44 |
+
preg_match('/<version>([0-9\.]+)<\/version>/', $xml, $matches);
|
45 |
+
if (!$matches) {
|
46 |
+
throw new RuntimeException('unable to determinate profiler version');
|
47 |
+
}
|
48 |
+
self::$version = $matches[1];
|
49 |
+
}
|
50 |
+
|
51 |
+
return self::$version;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @param string $fileName
|
56 |
+
* @param string $className
|
57 |
+
*/
|
58 |
+
public static function loadRenamedClass($fileName, $className)
|
59 |
+
{
|
60 |
+
|
61 |
+
$ds = DIRECTORY_SEPARATOR;
|
62 |
+
$sourceFile = MAGENTO_ROOT . $ds . 'app' . $ds . 'code' . $ds . $fileName;
|
63 |
+
$sourceMd5 = md5_file($sourceFile);
|
64 |
+
|
65 |
+
$fileName = sprintf('%s-%s-%s.php', $className, self::getVersion(), $sourceMd5);
|
66 |
+
$cacheFile = self::getOverwriteDir() . $fileName;
|
67 |
+
|
68 |
+
if (!file_exists($cacheFile)) {
|
69 |
+
$code = file_get_contents($sourceFile);
|
70 |
+
$code = preg_replace('/class ([^\s]+)/', 'class ' . $className, $code);
|
71 |
+
|
72 |
+
file_put_contents($cacheFile, $code);
|
73 |
+
}
|
74 |
+
|
75 |
+
require_once $cacheFile;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* use the config class cache to retrieve the initial class group
|
80 |
+
*
|
81 |
+
* @param string|object $className
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
public function getClassGroup($className)
|
85 |
+
{
|
86 |
+
if (is_object($className)) {
|
87 |
+
$className = get_class($className);
|
88 |
+
}
|
89 |
+
|
90 |
+
$classNames = $this->getClassNames();
|
91 |
+
if (!isset($classNames[$className])) {
|
92 |
+
$classNames = $this->getClassNames(true);
|
93 |
+
if (!isset($classNames[$className])) {
|
94 |
+
return 'unknown';
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
return $classNames[$className];
|
99 |
+
}
|
100 |
+
|
101 |
+
protected function getClassNames($reload = false)
|
102 |
+
{
|
103 |
+
if ($this->classNameCache !== null && $reload === false) {
|
104 |
+
return $this->classNameCache;
|
105 |
+
}
|
106 |
+
if ($this->configClassNameReflection === null) {
|
107 |
+
$this->configClassNameReflection = new ReflectionProperty('Mage_Core_Model_Config', '_classNameCache');
|
108 |
+
$this->configClassNameReflection->setAccessible(true);
|
109 |
+
}
|
110 |
+
|
111 |
+
$classNameCache = $this->configClassNameReflection->getValue(Mage::getConfig());
|
112 |
+
foreach ($classNameCache as $groupRoot) {
|
113 |
+
foreach ($groupRoot as $module => $classNames) {
|
114 |
+
foreach ($classNames as $class => $className) {
|
115 |
+
$this->classNameCache[$className] = $module . '/' . $class;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
return $this->classNameCache;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param string $token $token
|
125 |
+
* @param Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector
|
126 |
+
* @return string
|
127 |
+
*/
|
128 |
+
public function getCollectorUrl($token, Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector)
|
129 |
+
{
|
130 |
+
return $this->getUrl($token, $collector->getName());
|
131 |
+
}
|
132 |
+
|
133 |
+
public function getUrl($token = null, $panel = null)
|
134 |
+
{
|
135 |
+
$params = [];
|
136 |
+
if ($token) {
|
137 |
+
$params[Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER] = $token;
|
138 |
+
}
|
139 |
+
if ($panel) {
|
140 |
+
$params['panel'] = $panel;
|
141 |
+
}
|
142 |
+
|
143 |
+
return Mage::getUrl('_profiler/index/panel', $params);
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* removes all backtrace items until
|
148 |
+
* one does not match the rules defined
|
149 |
+
*
|
150 |
+
* @param array $backtrace
|
151 |
+
* @param array $ignoreCalls
|
152 |
+
* @param array $ignoreInstanceOf
|
153 |
+
* @return array
|
154 |
+
*/
|
155 |
+
public function cleanBacktrace(array $backtrace, array $ignoreCalls = [], array $ignoreInstanceOf = [])
|
156 |
+
{
|
157 |
+
$item = reset($backtrace);
|
158 |
+
while ($item && $this->_cleanBacktrace($item, $ignoreCalls, $ignoreInstanceOf)) {
|
159 |
+
array_shift($backtrace);
|
160 |
+
$item = reset($backtrace);
|
161 |
+
}
|
162 |
+
|
163 |
+
return $backtrace;
|
164 |
+
}
|
165 |
+
|
166 |
+
public function _cleanBacktrace(array $data, array $ignoreCalls = [], array $ignoreInstanceOf = [])
|
167 |
+
{
|
168 |
+
//remove if not called from a class
|
169 |
+
if (!isset($data['class'], $data['function'])) {
|
170 |
+
return true;
|
171 |
+
}
|
172 |
+
|
173 |
+
$functionIdent = $data['class'] . '::' . $data['function'];
|
174 |
+
if (in_array($functionIdent, $ignoreCalls)) {
|
175 |
+
return true;
|
176 |
+
}
|
177 |
+
|
178 |
+
if (!isset($data['object'])) {
|
179 |
+
return false;
|
180 |
+
}
|
181 |
+
|
182 |
+
foreach ($ignoreInstanceOf as $instance) {
|
183 |
+
if ($data['object'] instanceof $instance) {
|
184 |
+
return true;
|
185 |
+
}
|
186 |
+
}
|
187 |
+
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
|
191 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/Renderer.php
ADDED
@@ -0,0 +1,34 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_Renderer
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Helper_Renderer
|
7 |
+
extends Mage_Core_Helper_Abstract
|
8 |
+
{
|
9 |
+
protected $backTraceRenderer;
|
10 |
+
|
11 |
+
public function get($name)
|
12 |
+
{
|
13 |
+
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
public function renderBackTrace($id, $trace)
|
18 |
+
{
|
19 |
+
return $this->getBackTraceRenderer()
|
20 |
+
->setData(['id' => $id, 'trace' => $trace])
|
21 |
+
->toHtml();
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return Ecocode_Profiler_Block_Renderer_BackTrace
|
26 |
+
*/
|
27 |
+
public function getBackTraceRenderer()
|
28 |
+
{
|
29 |
+
if ($this->backTraceRenderer === null) {
|
30 |
+
$this->backTraceRenderer = Mage::app()->getLayout()->createBlock('ecocode_profiler/renderer_backTrace');
|
31 |
+
}
|
32 |
+
return $this->backTraceRenderer;
|
33 |
+
}
|
34 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/Rewrite.php
ADDED
@@ -0,0 +1,163 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_Rewrite
|
5 |
+
*
|
6 |
+
* taken from the awesome b98-magerun:
|
7 |
+
* https://github.com/netz98/n98-magerun/blob/master/src/N98/Magento/Command/Developer/Module/Rewrite/ConflictsCommand.php#L49-L55
|
8 |
+
*/
|
9 |
+
class Ecocode_Profiler_Helper_Rewrite
|
10 |
+
{
|
11 |
+
protected $_rewrites = null;
|
12 |
+
protected $_rewriteTypes = [
|
13 |
+
'blocks',
|
14 |
+
'helpers',
|
15 |
+
'models',
|
16 |
+
];
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @codeCoverageIgnore
|
20 |
+
* @return SimpleXMLElement
|
21 |
+
*/
|
22 |
+
public function getModules()
|
23 |
+
{
|
24 |
+
return Mage::getConfig()->getNode('modules')->children();
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @codeCoverageIgnore
|
29 |
+
* @param $moduleName
|
30 |
+
* @param $file
|
31 |
+
* @return bool|SimpleXMLElement
|
32 |
+
*/
|
33 |
+
public function getModuleConfigXml($moduleName, $file)
|
34 |
+
{
|
35 |
+
$file = Mage::getConfig()->getModuleDir('etc', $moduleName) . DIRECTORY_SEPARATOR . $file;
|
36 |
+
if (!is_readable($file)) {
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
$xml = \simplexml_load_file($file);
|
41 |
+
if (!$xml) {
|
42 |
+
return false;
|
43 |
+
}
|
44 |
+
|
45 |
+
return $xml;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Return all rewrites
|
50 |
+
*
|
51 |
+
* @return array
|
52 |
+
*/
|
53 |
+
public function loadRewrites()
|
54 |
+
{
|
55 |
+
if ($this->_rewrites === null) {
|
56 |
+
$files = ['config.xml', 'development.xml'];
|
57 |
+
$prototype = $this->_rewriteTypes;
|
58 |
+
$return = array_combine($prototype, array_fill(0, count($prototype), []));
|
59 |
+
// Load config of each module because modules can overwrite config each other. Global config is already merged
|
60 |
+
$modules = $this->getModules();
|
61 |
+
foreach ($modules as $moduleName => $moduleData) {
|
62 |
+
// Check only active modules
|
63 |
+
if (!$moduleData->is('active')) {
|
64 |
+
continue;
|
65 |
+
}
|
66 |
+
// Load config of module
|
67 |
+
foreach ($files as $file) {
|
68 |
+
$xml = $this->getModuleConfigXml($moduleName, $file);
|
69 |
+
if (!$xml) {
|
70 |
+
continue;
|
71 |
+
}
|
72 |
+
$rewriteElements = $xml->xpath('//*/*/rewrite');
|
73 |
+
foreach ($rewriteElements as $element) {
|
74 |
+
$type = \simplexml_import_dom(dom_import_simplexml($element)->parentNode->parentNode)->getName();
|
75 |
+
if (!isset($return[$type])) {
|
76 |
+
continue;
|
77 |
+
}
|
78 |
+
foreach ($element->children() as $child) {
|
79 |
+
$groupClassName = \simplexml_import_dom(dom_import_simplexml($element)->parentNode)->getName();
|
80 |
+
if (!isset($return[$type][$groupClassName . '/' . $child->getName()])) {
|
81 |
+
$return[$type][$groupClassName . '/' . $child->getName()] = [];
|
82 |
+
}
|
83 |
+
$return[$type][$groupClassName . '/' . $child->getName()][] = (string)$child;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
88 |
+
$this->_rewrites = $return;
|
89 |
+
}
|
90 |
+
|
91 |
+
return $this->_rewrites;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function getRewriteConflicts()
|
95 |
+
{
|
96 |
+
$conflicts = [];
|
97 |
+
$rewrites = $this->loadRewrites();
|
98 |
+
foreach ($rewrites as $type => $data) {
|
99 |
+
if (!is_array($data)) {
|
100 |
+
continue;
|
101 |
+
}
|
102 |
+
foreach ($data as $class => $rewriteClasses) {
|
103 |
+
if (!$this->_isInheritanceConflict($rewriteClasses)) {
|
104 |
+
continue;
|
105 |
+
}
|
106 |
+
$conflicts[] = [
|
107 |
+
'type' => $type,
|
108 |
+
'class' => $class,
|
109 |
+
'rewrites' => $rewriteClasses,
|
110 |
+
'loaded_class' => $this->_getLoadedClass($type, $class),
|
111 |
+
];
|
112 |
+
}
|
113 |
+
}
|
114 |
+
return $conflicts;
|
115 |
+
}
|
116 |
+
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Check if rewritten class has inherited the parent class.
|
120 |
+
* If yes we have no conflict. The top class can extend every core class.
|
121 |
+
* So we cannot check this.
|
122 |
+
*
|
123 |
+
* @var array $classes
|
124 |
+
* @return bool
|
125 |
+
*/
|
126 |
+
protected function _isInheritanceConflict($classes)
|
127 |
+
{
|
128 |
+
$count = count($classes);
|
129 |
+
$classes = array_reverse($classes);
|
130 |
+
for ($i = 1; $i < $count; $i++) {
|
131 |
+
try {
|
132 |
+
if (class_exists($classes[$i - 1])
|
133 |
+
&& class_exists($classes[$i])
|
134 |
+
) {
|
135 |
+
if (!is_a($classes[$i - 1], $classes[$i], true)) {
|
136 |
+
return true;
|
137 |
+
}
|
138 |
+
}
|
139 |
+
} catch (Exception $e) {
|
140 |
+
return true;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
return false;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Returns loaded class by type like models or blocks
|
148 |
+
*
|
149 |
+
* @param string $type
|
150 |
+
* @param string $class
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
protected function _getLoadedClass($type, $class)
|
154 |
+
{
|
155 |
+
switch ($type) {
|
156 |
+
case 'blocks':
|
157 |
+
return Mage::getConfig()->getBlockClassName($class);
|
158 |
+
case 'helpers':
|
159 |
+
return Mage::getConfig()->getHelperClassName($class);
|
160 |
+
}
|
161 |
+
return Mage::getConfig()->getModelClassName($class);
|
162 |
+
}
|
163 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/Sql.php
ADDED
@@ -0,0 +1,99 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Helper_Sql
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Helper_Sql extends Mage_Core_Helper_Abstract
|
7 |
+
{
|
8 |
+
protected $formattedQueriesCache = [];
|
9 |
+
|
10 |
+
public function replaceQueryParameters($query, array $parameters)
|
11 |
+
{
|
12 |
+
$i = 0;
|
13 |
+
if (!array_key_exists(0, $parameters) && array_key_exists(1, $parameters)) {
|
14 |
+
$i = 1;
|
15 |
+
}
|
16 |
+
|
17 |
+
$result = preg_replace_callback(
|
18 |
+
'/\?|((?<!:):[a-z0-9_]+)/i',
|
19 |
+
function ($matches) use ($parameters, &$i) {
|
20 |
+
$key = substr($matches[0], 1);
|
21 |
+
if (!array_key_exists($i, $parameters) && (false === $key || !array_key_exists($key, $parameters))) {
|
22 |
+
return $matches[0];
|
23 |
+
}
|
24 |
+
$value = array_key_exists($i, $parameters) ? $parameters[$i] : $parameters[$key];
|
25 |
+
$result = Mage::getSingleton('core/resource')->getConnection('default_write')->quote($value);
|
26 |
+
$i++;
|
27 |
+
return $result;
|
28 |
+
},
|
29 |
+
$query
|
30 |
+
);
|
31 |
+
return $result;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param array $parameters
|
36 |
+
* @return string
|
37 |
+
*
|
38 |
+
* @codeCoverageIgnore covered by Yaml\Dumper itself
|
39 |
+
*/
|
40 |
+
public function dumpParameters(array $parameters)
|
41 |
+
{
|
42 |
+
if (!$parameters) {
|
43 |
+
return '{}';
|
44 |
+
}
|
45 |
+
|
46 |
+
if (@!class_exists('\Symfony\Component\Yaml\Dumper')) {
|
47 |
+
return '"\Symfony\Component\Yaml\Dumper" is not installed';
|
48 |
+
}
|
49 |
+
|
50 |
+
static $dumper;
|
51 |
+
|
52 |
+
if (null === $dumper) {
|
53 |
+
$dumper = new \Symfony\Component\Yaml\Dumper();
|
54 |
+
}
|
55 |
+
|
56 |
+
return $dumper->dump($parameters);
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param $sql
|
62 |
+
* @param bool $highlightOnly
|
63 |
+
* @return string
|
64 |
+
* @codeCoverageIgnore covered by SqlFormatter itself
|
65 |
+
*/
|
66 |
+
public function formatQuery($sql, $highlightOnly = false)
|
67 |
+
{
|
68 |
+
if (@!class_exists('SqlFormatter')) {
|
69 |
+
return 'SqlFormatter is not installed';
|
70 |
+
}
|
71 |
+
|
72 |
+
$cacheKey = md5($sql . ($highlightOnly ? '1' : 0));
|
73 |
+
if (isset($this->formattedQueriesCache[$cacheKey])) {
|
74 |
+
return $this->formattedQueriesCache[$cacheKey];
|
75 |
+
}
|
76 |
+
|
77 |
+
\SqlFormatter::$cli = false;
|
78 |
+
\SqlFormatter::$pre_attributes = 'class="highlight highlight-sql"';
|
79 |
+
\SqlFormatter::$quote_attributes = 'class="string"';
|
80 |
+
\SqlFormatter::$backtick_quote_attributes = 'class="string"';
|
81 |
+
\SqlFormatter::$reserved_attributes = 'class="keyword"';
|
82 |
+
\SqlFormatter::$boundary_attributes = 'class="symbol"';
|
83 |
+
\SqlFormatter::$number_attributes = 'class="number"';
|
84 |
+
\SqlFormatter::$word_attributes = 'class="word"';
|
85 |
+
\SqlFormatter::$error_attributes = 'class="error"';
|
86 |
+
\SqlFormatter::$comment_attributes = 'class="comment"';
|
87 |
+
\SqlFormatter::$variable_attributes = 'class="variable"';
|
88 |
+
|
89 |
+
if ($highlightOnly) {
|
90 |
+
$html = \SqlFormatter::highlight($sql);
|
91 |
+
$html = preg_replace('/<pre class=".*">([^"]*+)<\/pre>/Us', '\1', $html);
|
92 |
+
} else {
|
93 |
+
$html = \SqlFormatter::format($sql);
|
94 |
+
$html = preg_replace('/<pre class="(.*)">([^"]*+)<\/pre>/Us', '<div class="\1"><pre>\2</pre></div>', $html);
|
95 |
+
}
|
96 |
+
|
97 |
+
return $this->formattedQueriesCache[$cacheKey] = $html;
|
98 |
+
}
|
99 |
+
}
|
app/code/community/Ecocode/Profiler/Helper/ValueExporter.php
ADDED
@@ -0,0 +1,95 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @author Bernhard Schussek <bschussek@gmail.com>
|
15 |
+
*/
|
16 |
+
class Ecocode_Profiler_Helper_ValueExporter
|
17 |
+
extends Mage_Core_Helper_Abstract
|
18 |
+
{
|
19 |
+
/**
|
20 |
+
* Converts a PHP value to a string.
|
21 |
+
*
|
22 |
+
* @param mixed $value The PHP value
|
23 |
+
* @param int $depth only for internal usage
|
24 |
+
* @param bool $deep only for internal usage
|
25 |
+
*
|
26 |
+
* @return string The string representation of the given value
|
27 |
+
*/
|
28 |
+
public function exportValue($value, $depth = 1, $deep = false)
|
29 |
+
{
|
30 |
+
if (is_object($value)) {
|
31 |
+
if ($value instanceof \DateTimeInterface) {
|
32 |
+
return sprintf('Object(%s) - %s', get_class($value), $value->format(\DateTime::ISO8601));
|
33 |
+
}
|
34 |
+
|
35 |
+
return sprintf('Object(%s)', get_class($value));
|
36 |
+
}
|
37 |
+
|
38 |
+
if ($value instanceof \__PHP_Incomplete_Class) {
|
39 |
+
return sprintf('__PHP_Incomplete_Class(%s)', $this->getClassNameFromIncomplete($value));
|
40 |
+
}
|
41 |
+
|
42 |
+
if (is_array($value)) {
|
43 |
+
if (empty($value)) {
|
44 |
+
return '[]';
|
45 |
+
}
|
46 |
+
|
47 |
+
$indent = str_repeat(' ', $depth);
|
48 |
+
|
49 |
+
$a = [];
|
50 |
+
foreach ($value as $k => $v) {
|
51 |
+
if (is_array($v)) {
|
52 |
+
$deep = true;
|
53 |
+
}
|
54 |
+
$a[] = sprintf('%s => %s', $k, $this->exportValue($v, $depth + 1, $deep));
|
55 |
+
}
|
56 |
+
|
57 |
+
if ($deep) {
|
58 |
+
return sprintf("[\n%s%s\n%s]", $indent, implode(sprintf(", \n%s", $indent), $a), str_repeat(' ', $depth - 1));
|
59 |
+
}
|
60 |
+
|
61 |
+
$s = sprintf('[%s]', implode(', ', $a));
|
62 |
+
|
63 |
+
if (80 > strlen($s)) {
|
64 |
+
return $s;
|
65 |
+
}
|
66 |
+
|
67 |
+
return sprintf("[\n%s%s\n]", $indent, implode(sprintf(",\n%s", $indent), $a));
|
68 |
+
}
|
69 |
+
|
70 |
+
if (is_resource($value)) {
|
71 |
+
return sprintf('Resource(%s#%d)', get_resource_type($value), $value);
|
72 |
+
}
|
73 |
+
|
74 |
+
if (null === $value) {
|
75 |
+
return 'null';
|
76 |
+
}
|
77 |
+
|
78 |
+
if (false === $value) {
|
79 |
+
return 'false';
|
80 |
+
}
|
81 |
+
|
82 |
+
if (true === $value) {
|
83 |
+
return 'true';
|
84 |
+
}
|
85 |
+
|
86 |
+
return (string)$value;
|
87 |
+
}
|
88 |
+
|
89 |
+
private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
|
90 |
+
{
|
91 |
+
$array = new \ArrayObject($value);
|
92 |
+
|
93 |
+
return $array['__PHP_Incomplete_Class_Name'];
|
94 |
+
}
|
95 |
+
}
|
app/code/community/Ecocode/Profiler/Model/AppDev.php
ADDED
@@ -0,0 +1,149 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_AppDev
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_AppDev extends Mage_Core_Model_App
|
7 |
+
{
|
8 |
+
protected $eventsFiredCount = 0;
|
9 |
+
protected $eventFiredCount = [];
|
10 |
+
protected $calledListeners = [];
|
11 |
+
|
12 |
+
protected $startTime;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Constructor
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
$this->startTime = microtime(true);
|
20 |
+
}
|
21 |
+
|
22 |
+
public function getStartTime()
|
23 |
+
{
|
24 |
+
return $this->startTime;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function _initRequest()
|
28 |
+
{
|
29 |
+
$result = parent::_initRequest();
|
30 |
+
|
31 |
+
$this->startProfiler();
|
32 |
+
|
33 |
+
return $result;
|
34 |
+
}
|
35 |
+
|
36 |
+
public function setErrorHandler($handler)
|
37 |
+
{
|
38 |
+
//DONT SET WE ARE USING THE SYMFONY DEBUG ONE
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Initialize application cache instance
|
44 |
+
*
|
45 |
+
* @param array $cacheInitOptions
|
46 |
+
* @return Mage_Core_Model_App
|
47 |
+
*/
|
48 |
+
protected function _initCache(array $cacheInitOptions = array())
|
49 |
+
{
|
50 |
+
//its to early to make use of normal rewrites as they are not yet loaded
|
51 |
+
//so just set it our self
|
52 |
+
$this->_config->setNode('global/models/core/rewrite/cache', 'Ecocode_Profiler_Model_Core_Cache');
|
53 |
+
return parent::_initCache($cacheInitOptions);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* start the profiler
|
58 |
+
*
|
59 |
+
* @return $this
|
60 |
+
*/
|
61 |
+
protected function startProfiler()
|
62 |
+
{
|
63 |
+
//to early to detect if this is the admin store
|
64 |
+
$path = $this->getRequest()->getPathInfo();
|
65 |
+
if (substr($path, 0, 10) === '/_profiler') {
|
66 |
+
return $this;
|
67 |
+
}
|
68 |
+
//this wont work if you use a custom url and we cant tell by now
|
69 |
+
//which one is configured. even if we read the local.xml manually
|
70 |
+
// it can still be set in the database, so for now 80/20 solution :)
|
71 |
+
if (substr($path, 0, 6) === '/admin') {
|
72 |
+
return $this;
|
73 |
+
}
|
74 |
+
|
75 |
+
Mage::getSingleton('ecocode_profiler/profiler')->init();
|
76 |
+
|
77 |
+
return $this;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @param $eventName
|
82 |
+
* @param $args
|
83 |
+
* @return $this
|
84 |
+
*/
|
85 |
+
public function dispatchEvent($eventName, $args)
|
86 |
+
{
|
87 |
+
if (!isset($args['debug'])) {
|
88 |
+
if (!isset($this->eventFiredCount[$eventName])) {
|
89 |
+
$this->eventFiredCount[$eventName] = 0;
|
90 |
+
}
|
91 |
+
$this->eventFiredCount[$eventName]++;
|
92 |
+
}
|
93 |
+
|
94 |
+
return parent::dispatchEvent($eventName, $args);
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* overwrite to log all listener calls
|
99 |
+
*
|
100 |
+
* @param object $object
|
101 |
+
* @param string $method
|
102 |
+
* @param Varien_Event_Observer $observer
|
103 |
+
* @return $this
|
104 |
+
*/
|
105 |
+
protected function _callObserverMethod($object, $method, $observer)
|
106 |
+
{
|
107 |
+
$eventName = $observer->getEvent()->getName();
|
108 |
+
if (!$observer->getEvent()->getData('debug')) {
|
109 |
+
$this->calledListeners[] = [
|
110 |
+
'event_name' => $eventName,
|
111 |
+
'class' => get_class($object),
|
112 |
+
'method' => $method
|
113 |
+
];
|
114 |
+
|
115 |
+
if (!method_exists($object, $method)) {
|
116 |
+
Mage::log(
|
117 |
+
sprintf(
|
118 |
+
'event "%s" tried to call a non existing method "%s" in "%s"',
|
119 |
+
$eventName,
|
120 |
+
$method,
|
121 |
+
get_class($object)
|
122 |
+
)
|
123 |
+
);
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
return parent::_callObserverMethod($object, $method, $observer);
|
128 |
+
}
|
129 |
+
|
130 |
+
public function getEvents()
|
131 |
+
{
|
132 |
+
return $this->_events;
|
133 |
+
}
|
134 |
+
|
135 |
+
public function getFiredEventCount()
|
136 |
+
{
|
137 |
+
return $this->eventsFiredCount;
|
138 |
+
}
|
139 |
+
|
140 |
+
public function getFiredEvents()
|
141 |
+
{
|
142 |
+
return $this->eventFiredCount;
|
143 |
+
}
|
144 |
+
|
145 |
+
public function getCalledListeners()
|
146 |
+
{
|
147 |
+
return $this->calledListeners;
|
148 |
+
}
|
149 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/AbstractDataCollector.php
ADDED
@@ -0,0 +1,82 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
5 |
+
*/
|
6 |
+
abstract class Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
7 |
+
implements Ecocode_Profiler_Model_Collector_DataCollectorInterface,
|
8 |
+
Serializable
|
9 |
+
{
|
10 |
+
protected $data = [];
|
11 |
+
|
12 |
+
protected $contextHelper;
|
13 |
+
|
14 |
+
|
15 |
+
public function init()
|
16 |
+
{
|
17 |
+
//fill if needed
|
18 |
+
}
|
19 |
+
|
20 |
+
public function serialize()
|
21 |
+
{
|
22 |
+
return serialize($this->data);
|
23 |
+
}
|
24 |
+
|
25 |
+
public function unserialize($data)
|
26 |
+
{
|
27 |
+
$this->data = unserialize($data);
|
28 |
+
}
|
29 |
+
|
30 |
+
public function getBlockPanelName()
|
31 |
+
{
|
32 |
+
return $this->getName() . '_panel';
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getBlockMenuName()
|
36 |
+
{
|
37 |
+
return $this->getName() . '_menu';
|
38 |
+
}
|
39 |
+
|
40 |
+
public function getBlockToolbarName()
|
41 |
+
{
|
42 |
+
return 'profiler.' . $this->getName() . '.toolbar';
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param $key
|
47 |
+
* @param null $default
|
48 |
+
* @return mixed
|
49 |
+
*/
|
50 |
+
protected function getData($key, $default = null)
|
51 |
+
{
|
52 |
+
return isset($this->data[$key]) ? $this->data[$key] : $default;
|
53 |
+
}
|
54 |
+
/**
|
55 |
+
* @return integer
|
56 |
+
*/
|
57 |
+
public function getContextId()
|
58 |
+
{
|
59 |
+
return $this->getContextHelper()->getCurrentId();
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @return Ecocode_Profiler_Helper_Context
|
64 |
+
*/
|
65 |
+
public function getContextHelper()
|
66 |
+
{
|
67 |
+
if ($this->contextHelper === null) {
|
68 |
+
$this->contextHelper = Mage::helper('ecocode_profiler/context');
|
69 |
+
}
|
70 |
+
|
71 |
+
return $this->contextHelper;
|
72 |
+
}
|
73 |
+
|
74 |
+
protected function getBacktrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT)
|
75 |
+
{
|
76 |
+
if (!function_exists('debug_backtrace')) {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
|
80 |
+
return debug_backtrace($options);
|
81 |
+
}
|
82 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/AjaxDataCollector.php
ADDED
@@ -0,0 +1,27 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_AjaxDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_AjaxDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
/**
|
10 |
+
* {@inheritdoc}
|
11 |
+
*
|
12 |
+
* @codeCoverageIgnore
|
13 |
+
*/
|
14 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
15 |
+
{
|
16 |
+
// all collecting is done client side
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @codeCoverageIgnore
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
public function getName()
|
24 |
+
{
|
25 |
+
return 'ajax';
|
26 |
+
}
|
27 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/CacheDataCollector.php
ADDED
@@ -0,0 +1,146 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_CacheDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_CacheDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* @return Mage_Core_Model_Cache
|
12 |
+
*
|
13 |
+
* @codeCoverageIgnore
|
14 |
+
*/
|
15 |
+
protected function getCacheInstance()
|
16 |
+
{
|
17 |
+
return Mage::app()->getCacheInstance();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return Zend_Cache_Core
|
22 |
+
*
|
23 |
+
* @codeCoverageIgnore
|
24 |
+
*/
|
25 |
+
protected function getCache()
|
26 |
+
{
|
27 |
+
return Mage::app()->getCache();
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* {@inheritdoc}
|
32 |
+
*/
|
33 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
34 |
+
{
|
35 |
+
$caches = [];
|
36 |
+
$cacheInstance = $this->getCacheInstance();
|
37 |
+
|
38 |
+
foreach ($cacheInstance->getTypes() as $cache) {
|
39 |
+
$caches[] = $cache->getData();
|
40 |
+
}
|
41 |
+
|
42 |
+
/** @var Zend_Cache_Core $cache */
|
43 |
+
$cache = $this->getCache();
|
44 |
+
$backend = $cache->getBackend();
|
45 |
+
|
46 |
+
$backendOptionsProperty = new ReflectionProperty('Zend_Cache_Backend', '_options');
|
47 |
+
$backendOptionsProperty->setAccessible(true);
|
48 |
+
|
49 |
+
$this->data = [
|
50 |
+
'backend_name' => get_class($backend),
|
51 |
+
'backend_options' => $backendOptionsProperty->getValue($backend),
|
52 |
+
'cache_list' => $caches,
|
53 |
+
'cache_calls' => [],
|
54 |
+
'stats' => [
|
55 |
+
'total' => 0,
|
56 |
+
'hit' => 0,
|
57 |
+
'miss' => 0,
|
58 |
+
'save' => 0,
|
59 |
+
]
|
60 |
+
];
|
61 |
+
}
|
62 |
+
|
63 |
+
public function lateCollect()
|
64 |
+
{
|
65 |
+
$this->collectCacheCallData();
|
66 |
+
}
|
67 |
+
|
68 |
+
protected function collectCacheCallData()
|
69 |
+
{
|
70 |
+
$cache = $this->getCacheInstance();
|
71 |
+
if (!$cache instanceof Ecocode_Profiler_Model_Core_Cache) {
|
72 |
+
return;
|
73 |
+
}
|
74 |
+
$cacheCalls = $cache->getLog();
|
75 |
+
$totalTime = 0;
|
76 |
+
$stats = [
|
77 |
+
'total' => count($cacheCalls),
|
78 |
+
'hit' => 0,
|
79 |
+
'miss' => 0,
|
80 |
+
'save' => 0,
|
81 |
+
];
|
82 |
+
|
83 |
+
foreach ($cacheCalls as $log) {
|
84 |
+
$totalTime += $log['time'];
|
85 |
+
switch ($log['action']) {
|
86 |
+
case 'load':
|
87 |
+
$stats[$log['hit'] ? 'hit' : 'miss']++;
|
88 |
+
break;
|
89 |
+
case 'save':
|
90 |
+
$stats['save']++;
|
91 |
+
break;
|
92 |
+
default:
|
93 |
+
break;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
$this->data['stats'] = $stats;
|
98 |
+
$this->data['total_time'] = $totalTime;
|
99 |
+
$this->data['cache_calls'] = $cache->getLog();
|
100 |
+
}
|
101 |
+
|
102 |
+
public function getBackendName()
|
103 |
+
{
|
104 |
+
return $this->getData('backend_name', 'Unknown');
|
105 |
+
}
|
106 |
+
|
107 |
+
public function getBackendOptions()
|
108 |
+
{
|
109 |
+
return $this->getData('backend_options', []);
|
110 |
+
}
|
111 |
+
|
112 |
+
public function getStats($key = null)
|
113 |
+
{
|
114 |
+
if ($key) {
|
115 |
+
return $this->data['stats'][$key];
|
116 |
+
}
|
117 |
+
|
118 |
+
return $this->data['stats'];
|
119 |
+
}
|
120 |
+
|
121 |
+
public function getTotalTime()
|
122 |
+
{
|
123 |
+
return $this->getData('total_time', 0);
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
public function getCacheList()
|
128 |
+
{
|
129 |
+
return $this->getData('cache_list', []);
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
public function getCacheCalls()
|
134 |
+
{
|
135 |
+
return $this->getData('cache_calls', []);
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @codeCoverageIgnore
|
140 |
+
* @return string
|
141 |
+
*/
|
142 |
+
public function getName()
|
143 |
+
{
|
144 |
+
return 'cache';
|
145 |
+
}
|
146 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/ConfigDataCollector.php
ADDED
@@ -0,0 +1,237 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_ConfigDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_ConfigDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
|
10 |
+
/**
|
11 |
+
* {@inheritdoc}
|
12 |
+
*/
|
13 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
14 |
+
{
|
15 |
+
$store = Mage::app()->getStore();
|
16 |
+
$website = Mage::app()->getWebsite();
|
17 |
+
|
18 |
+
$this->data = [
|
19 |
+
'store_id' => $store->getId(),
|
20 |
+
'store_name' => $store->getName(),
|
21 |
+
'store_code' => $store->getCode(),
|
22 |
+
'website_id' => $website->getId(),
|
23 |
+
'website_name' => $website->getName(),
|
24 |
+
'website_code' => $website->getCode(),
|
25 |
+
'developer_mode' => Mage::getIsDeveloperMode(),
|
26 |
+
'token' => $this->retrieveToken($response),
|
27 |
+
'magento_version' => Mage::getVersion(),
|
28 |
+
'magento_modules' => $this->collectMagentoModules(),
|
29 |
+
'php_version' => PHP_VERSION,
|
30 |
+
'xdebug_enabled' => extension_loaded('xdebug'),
|
31 |
+
'eaccel_enabled' => extension_loaded('eaccelerator') && ini_get('eaccelerator.enable'),
|
32 |
+
'apc_enabled' => extension_loaded('apc') && ini_get('apc.enabled'),
|
33 |
+
'xcache_enabled' => extension_loaded('xcache') && ini_get('xcache.cacher'),
|
34 |
+
'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'),
|
35 |
+
'zend_opcache_enabled' => extension_loaded('Zend OPcache') && ini_get('opcache.enable'),
|
36 |
+
'sapi_name' => PHP_SAPI,
|
37 |
+
];
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function collectMagentoModules()
|
42 |
+
{
|
43 |
+
/** @var Mage_Core_Model_Config_Element $modules */
|
44 |
+
$moduleList = Mage::getConfig()->getNode('modules')->children();
|
45 |
+
$modules = [];
|
46 |
+
foreach ($moduleList as $key => $node) {
|
47 |
+
$data = $node->asArray();
|
48 |
+
$data['active'] = isset($data['active']) && $data['active'] === 'true';
|
49 |
+
$modules[$key] = $data;
|
50 |
+
}
|
51 |
+
|
52 |
+
return $modules;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getMagentoVersion()
|
56 |
+
{
|
57 |
+
return $this->getData('magento_version');
|
58 |
+
}
|
59 |
+
|
60 |
+
public function getStoreId()
|
61 |
+
{
|
62 |
+
return $this->getData('store_id');
|
63 |
+
}
|
64 |
+
|
65 |
+
public function getStoreName()
|
66 |
+
{
|
67 |
+
return $this->getData('store_name');
|
68 |
+
}
|
69 |
+
|
70 |
+
public function getStoreCode()
|
71 |
+
{
|
72 |
+
return $this->getData('store_code');
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getWebsiteId()
|
76 |
+
{
|
77 |
+
return $this->getData('website_id');
|
78 |
+
}
|
79 |
+
|
80 |
+
public function getWebsiteName()
|
81 |
+
{
|
82 |
+
return $this->getData('website_name');
|
83 |
+
}
|
84 |
+
|
85 |
+
public function getWebsiteCode()
|
86 |
+
{
|
87 |
+
return $this->getData('website_code');
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Gets the token.
|
92 |
+
*
|
93 |
+
* @return string The token
|
94 |
+
*/
|
95 |
+
public function getToken()
|
96 |
+
{
|
97 |
+
return $this->getData('token');
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Gets the PHP version.
|
102 |
+
*
|
103 |
+
* @return string The PHP version
|
104 |
+
*/
|
105 |
+
public function getPhpVersion()
|
106 |
+
{
|
107 |
+
return $this->getData('php_version');
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Returns true if the developer mode is enabled.
|
112 |
+
*
|
113 |
+
* @return bool true if debug is enabled, false otherwise
|
114 |
+
*/
|
115 |
+
public function isDeveloperMode()
|
116 |
+
{
|
117 |
+
return $this->getData('developer_mode');
|
118 |
+
}
|
119 |
+
|
120 |
+
public function getMagentoModules()
|
121 |
+
{
|
122 |
+
return $this->getData('magento_modules', []);
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @param $state
|
127 |
+
* @return array
|
128 |
+
*/
|
129 |
+
public function geModulesByState($state)
|
130 |
+
{
|
131 |
+
return array_filter($this->getMagentoModules(), function ($module) use ($state) {
|
132 |
+
return $module['active'] === $state;
|
133 |
+
});
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Returns true if the XDebug is enabled.
|
138 |
+
*
|
139 |
+
* @return bool true if XDebug is enabled, false otherwise
|
140 |
+
*/
|
141 |
+
public function hasXDebug()
|
142 |
+
{
|
143 |
+
return $this->getData('xdebug_enabled');
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Returns true if EAccelerator is enabled.
|
148 |
+
*
|
149 |
+
* @return bool true if EAccelerator is enabled, false otherwise
|
150 |
+
*/
|
151 |
+
public function hasEAccelerator()
|
152 |
+
{
|
153 |
+
return $this->getData('eaccel_enabled');
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Returns true if APC is enabled.
|
158 |
+
*
|
159 |
+
* @return bool true if APC is enabled, false otherwise
|
160 |
+
*/
|
161 |
+
public function hasApc()
|
162 |
+
{
|
163 |
+
return $this->getData('apc_enabled');
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Returns true if Zend OPcache is enabled.
|
168 |
+
*
|
169 |
+
* @return bool true if Zend OPcache is enabled, false otherwise
|
170 |
+
*/
|
171 |
+
public function hasZendOpcache()
|
172 |
+
{
|
173 |
+
return $this->getData('zend_opcache_enabled');
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Returns true if XCache is enabled.
|
178 |
+
*
|
179 |
+
* @return bool true if XCache is enabled, false otherwise
|
180 |
+
*/
|
181 |
+
public function hasXCache()
|
182 |
+
{
|
183 |
+
return $this->getData('xcache_enabled');
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Returns true if WinCache is enabled.
|
188 |
+
*
|
189 |
+
* @return bool true if WinCache is enabled, false otherwise
|
190 |
+
*/
|
191 |
+
public function hasWinCache()
|
192 |
+
{
|
193 |
+
return $this->getData('wincache_enabled');
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Returns true if any accelerator is enabled.
|
198 |
+
*
|
199 |
+
* @return bool true if any accelerator is enabled, false otherwise
|
200 |
+
*/
|
201 |
+
public function hasAccelerator()
|
202 |
+
{
|
203 |
+
return $this->hasApc() || $this->hasZendOpcache() || $this->hasEAccelerator() || $this->hasXCache() || $this->hasWinCache();
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Gets the PHP SAPI name.
|
208 |
+
*
|
209 |
+
* @return string The environment
|
210 |
+
*/
|
211 |
+
public function getSapiName()
|
212 |
+
{
|
213 |
+
return $this->getData('sapi_name');
|
214 |
+
}
|
215 |
+
|
216 |
+
public function retrieveToken(Mage_Core_Controller_Response_Http $response)
|
217 |
+
{
|
218 |
+
$token = null;
|
219 |
+
foreach ($response->getHeaders() as $header) {
|
220 |
+
if ($header['name'] === 'X-Debug-Token') {
|
221 |
+
$token = $header['value'];
|
222 |
+
break;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
return $token;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* @codeCoverageIgnore
|
230 |
+
* @return string
|
231 |
+
*/
|
232 |
+
public function getName()
|
233 |
+
{
|
234 |
+
return 'config';
|
235 |
+
}
|
236 |
+
|
237 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/ContextDataCollector.php
ADDED
@@ -0,0 +1,45 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_ContextDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_ContextDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
|
11 |
+
/**
|
12 |
+
* {@inheritdoc}
|
13 |
+
*/
|
14 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
15 |
+
{
|
16 |
+
$this->data = ['list' => []];
|
17 |
+
|
18 |
+
return $this;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function lateCollect()
|
22 |
+
{
|
23 |
+
$this->data = ['list' => $this->getContextHelper()->getList()];
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getById($id)
|
27 |
+
{
|
28 |
+
if (isset($this->data['list'][$id])) {
|
29 |
+
return $this->data['list'][$id];
|
30 |
+
}
|
31 |
+
|
32 |
+
return null;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getList()
|
36 |
+
{
|
37 |
+
return $this->getData('list', []);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function getName()
|
41 |
+
{
|
42 |
+
return 'context';
|
43 |
+
}
|
44 |
+
|
45 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/CustomerDataCollector.php
ADDED
@@ -0,0 +1,91 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_CustomerDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_CustomerDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
/**
|
10 |
+
* {@inheritdoc}
|
11 |
+
*/
|
12 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
13 |
+
{
|
14 |
+
$customerHelper = $this->getCustomerHelper();
|
15 |
+
|
16 |
+
$customer = $customerHelper->getCustomer();
|
17 |
+
|
18 |
+
$group = Mage::getModel('customer/group')->load($customer->getGroupId());
|
19 |
+
$taxClass = Mage::getModel('tax/class')->load($group->getTaxClassId());
|
20 |
+
|
21 |
+
$this->data = [
|
22 |
+
'logged_in' => $customerHelper->isLoggedIn(),
|
23 |
+
'customer_email' => $customer->getEmail(),
|
24 |
+
'customer_name' => $customer->getName(),
|
25 |
+
'group_id' => $group->getId(),
|
26 |
+
'group_code' => $group->getCustomerGroupCode(),
|
27 |
+
'tax_class_id' => $taxClass->getId(),
|
28 |
+
'tax_class_name' => $taxClass->getClassName(),
|
29 |
+
'tax_class_type' => $taxClass->getClassType()
|
30 |
+
];
|
31 |
+
}
|
32 |
+
|
33 |
+
public function isLoggedIn()
|
34 |
+
{
|
35 |
+
return $this->getData('logged_in');
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getCustomerEmail()
|
39 |
+
{
|
40 |
+
return $this->getData('customer_email');
|
41 |
+
}
|
42 |
+
|
43 |
+
public function getCustomerName()
|
44 |
+
{
|
45 |
+
return $this->getData('customer_name');
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getGroupId()
|
49 |
+
{
|
50 |
+
return $this->getData('group_id');
|
51 |
+
}
|
52 |
+
|
53 |
+
public function getGroupCode()
|
54 |
+
{
|
55 |
+
return $this->getData('group_code');
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
public function getTaxClassName()
|
60 |
+
{
|
61 |
+
return $this->getData('tax_class_name');
|
62 |
+
}
|
63 |
+
|
64 |
+
public function getTaxClassId()
|
65 |
+
{
|
66 |
+
return $this->getData('tax_class_id');
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getTaxClassType()
|
70 |
+
{
|
71 |
+
return $this->getData('tax_class_type');
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @codeCoverageIgnore
|
76 |
+
* @return Mage_Customer_Helper_Data
|
77 |
+
*/
|
78 |
+
public function getCustomerHelper()
|
79 |
+
{
|
80 |
+
return Mage::helper('customer');
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* @codeCoverageIgnore
|
85 |
+
* @return string
|
86 |
+
*/
|
87 |
+
public function getName()
|
88 |
+
{
|
89 |
+
return 'customer';
|
90 |
+
}
|
91 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/DataCollectorInterface.php
ADDED
@@ -0,0 +1,24 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Ecocode_Profiler_Model_Collector_DataCollectorInterface
|
5 |
+
*/
|
6 |
+
interface Ecocode_Profiler_Model_Collector_DataCollectorInterface
|
7 |
+
{
|
8 |
+
public function init();
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @param Mage_Core_Controller_Request_Http $request
|
12 |
+
* @param Mage_Core_Controller_Response_Http $response
|
13 |
+
* @param Exception|null $exception
|
14 |
+
* @return mixed
|
15 |
+
*/
|
16 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null);
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Returns the name of the collector.
|
20 |
+
*
|
21 |
+
* @return string The collector name
|
22 |
+
*/
|
23 |
+
public function getName();
|
24 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/EventDataCollector.php
ADDED
@@ -0,0 +1,97 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_EventDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_EventDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* {@inheritdoc}
|
12 |
+
*/
|
13 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
14 |
+
{
|
15 |
+
$this->data = [
|
16 |
+
'called_listeners' => [],
|
17 |
+
'fired_events' => []
|
18 |
+
];
|
19 |
+
}
|
20 |
+
|
21 |
+
public function lateCollect()
|
22 |
+
{
|
23 |
+
$app = $this->getApp();
|
24 |
+
|
25 |
+
$this->data = [
|
26 |
+
'called_listeners' => $this->collectedCalledListeners($app),
|
27 |
+
'fired_events' => $this->collectEvents($app)
|
28 |
+
];
|
29 |
+
}
|
30 |
+
|
31 |
+
protected function collectEvents(Ecocode_Profiler_Model_AppDev $app)
|
32 |
+
{
|
33 |
+
$eventList = $app->getFiredEvents();
|
34 |
+
$events = [];
|
35 |
+
|
36 |
+
$observerList = $app->getEvents();
|
37 |
+
|
38 |
+
foreach ($eventList as $eventName => $count) {
|
39 |
+
$observers = [];
|
40 |
+
$observerCount = 0;
|
41 |
+
|
42 |
+
foreach ($observerList as $area => $list) {
|
43 |
+
if (!isset($list[$eventName]) || $list[$eventName] === false) {
|
44 |
+
continue;
|
45 |
+
}
|
46 |
+
|
47 |
+
$observers[$area] = [];
|
48 |
+
foreach ($list[$eventName] as $areaObservers) {
|
49 |
+
$observers[$area] += $areaObservers;
|
50 |
+
$observerCount += count($areaObservers);
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
$events[$eventName] = [
|
55 |
+
'name' => $eventName,
|
56 |
+
'count' => $count,
|
57 |
+
'observer' => $observers,
|
58 |
+
'observer_count' => $observerCount
|
59 |
+
];
|
60 |
+
}
|
61 |
+
|
62 |
+
return $events;
|
63 |
+
}
|
64 |
+
|
65 |
+
protected function collectedCalledListeners(Ecocode_Profiler_Model_AppDev $app)
|
66 |
+
{
|
67 |
+
return $app->getCalledListeners();
|
68 |
+
}
|
69 |
+
|
70 |
+
public function getCalledListeners()
|
71 |
+
{
|
72 |
+
return $this->getData('called_listeners', []);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function getFiredEvents()
|
76 |
+
{
|
77 |
+
return $this->getData('fired_events', []);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @codeCoverageIgnore
|
82 |
+
* @return Mage_Core_Model_App
|
83 |
+
*/
|
84 |
+
public function getApp()
|
85 |
+
{
|
86 |
+
return Mage::app();
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @codeCoverageIgnore
|
91 |
+
* @return string
|
92 |
+
*/
|
93 |
+
public function getName()
|
94 |
+
{
|
95 |
+
return 'event';
|
96 |
+
}
|
97 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/LateDataCollectorInterface.php
ADDED
@@ -0,0 +1,12 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
5 |
+
*/
|
6 |
+
interface Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Collects data as late as possible.
|
10 |
+
*/
|
11 |
+
public function lateCollect();
|
12 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/LayoutDataCollector.php
ADDED
@@ -0,0 +1,175 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Model_Collector_LayoutDataCollector
|
4 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
5 |
+
{
|
6 |
+
protected $renderLog = [];
|
7 |
+
protected $renderedBlocks = [];
|
8 |
+
protected $currentBlock;
|
9 |
+
|
10 |
+
public function beforeToHtml(Varien_Event_Observer $observer)
|
11 |
+
{
|
12 |
+
/** @var Mage_Core_Block_Abstract $block */
|
13 |
+
$block = $observer->getEvent()->getData('block');
|
14 |
+
$id = uniqid();
|
15 |
+
$block->setData('profiler_id', $id);
|
16 |
+
|
17 |
+
$data = [
|
18 |
+
'id' => $id,
|
19 |
+
'start_render' => microtime(true),
|
20 |
+
'hash' => spl_object_hash($block),
|
21 |
+
'children' => [],
|
22 |
+
'parent_id' => false,
|
23 |
+
];
|
24 |
+
|
25 |
+
if ($parentBlock = $block->getParentBlock()) {
|
26 |
+
|
27 |
+
} else if ($block instanceof Mage_Widget_Block_Interface) {
|
28 |
+
$parentBlock = $this->currentBlock;
|
29 |
+
}
|
30 |
+
|
31 |
+
if ($parentBlock && $parentId = $parentBlock->getData('profiler_id')) {
|
32 |
+
$this->renderLog[$parentId]['children'][] = $id;
|
33 |
+
$data['parent_id'] = $parentId;
|
34 |
+
}
|
35 |
+
|
36 |
+
if (!$block instanceof Mage_Widget_Block_Interface) {
|
37 |
+
$this->currentBlock = $block;
|
38 |
+
}
|
39 |
+
$this->renderLog[$id] = $data;
|
40 |
+
}
|
41 |
+
|
42 |
+
public function afterToHtml(Varien_Event_Observer $observer)
|
43 |
+
{
|
44 |
+
/** @var Mage_Core_Block_Abstract $block */
|
45 |
+
$block = $observer->getEvent()->getData('block');
|
46 |
+
$id = $block->getData('profiler_id');
|
47 |
+
$data = $this->renderLog[$id];
|
48 |
+
|
49 |
+
$data += $this->getBaseBlockData($block);
|
50 |
+
$data['stop_render'] = microtime(true);
|
51 |
+
$data['render_time_incl'] = $data['stop_render'] - $data['start_render'];
|
52 |
+
|
53 |
+
if ($block instanceof Mage_Core_Block_Template) {
|
54 |
+
$data['template'] = $block->getTemplate();
|
55 |
+
}
|
56 |
+
|
57 |
+
$this->renderedBlocks[$id] = $block;
|
58 |
+
$this->renderLog[$id] = $data;
|
59 |
+
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* {@inheritdoc}
|
65 |
+
*/
|
66 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
67 |
+
{
|
68 |
+
$outputProperties = new ReflectionProperty('Mage_Core_Model_Layout', '_output');
|
69 |
+
$outputProperties->setAccessible(true);
|
70 |
+
|
71 |
+
$layout = $this->getLayout();
|
72 |
+
$outputBlocks = [];
|
73 |
+
foreach ($outputProperties->getValue($layout) as $name => $data) {
|
74 |
+
$block = $layout->getBlock($name);
|
75 |
+
$outputBlocks[] = $block->getData('profiler_id');
|
76 |
+
}
|
77 |
+
|
78 |
+
$totalTime = 0;
|
79 |
+
foreach ($this->renderLog as &$data) {
|
80 |
+
$renderTimeExcl = $data['render_time_incl'];
|
81 |
+
foreach ($data['children'] as $childId) {
|
82 |
+
$child = $this->renderLog[$childId];
|
83 |
+
$renderTimeExcl -= $child['render_time_incl'];
|
84 |
+
}
|
85 |
+
$data['render_time'] = $renderTimeExcl;
|
86 |
+
|
87 |
+
$totalTime += $data['render_time'];
|
88 |
+
}
|
89 |
+
|
90 |
+
$renderedCount = 0;
|
91 |
+
$notRenderedBlocks = [];
|
92 |
+
foreach ($layout->getAllBlocks() as $block) {
|
93 |
+
if ($block->getData('profiler_id')) {
|
94 |
+
$renderedCount++;
|
95 |
+
} else {
|
96 |
+
$notRenderedBlocks[] = $this->getBaseBlockData($block);
|
97 |
+
}
|
98 |
+
}
|
99 |
+
$this->data = [
|
100 |
+
'handles' => $layout->getUpdate()->getHandles(),
|
101 |
+
'blocks_created_count' => count($layout->getAllBlocks()),
|
102 |
+
'blocks_rendered_count' => count($this->renderLog),
|
103 |
+
'blocks_not_rendered_count' => count($notRenderedBlocks),
|
104 |
+
'blocks_not_rendered' => $notRenderedBlocks,
|
105 |
+
'output_blocks' => $outputBlocks,
|
106 |
+
'render_log' => $this->renderLog,
|
107 |
+
'render_time' => $totalTime
|
108 |
+
|
109 |
+
];
|
110 |
+
return $this;
|
111 |
+
}
|
112 |
+
|
113 |
+
protected function getBaseBlockData(Mage_Core_Block_Abstract $block)
|
114 |
+
{
|
115 |
+
return [
|
116 |
+
'name' => $block->getNameInLayout(),
|
117 |
+
'class' => get_class($block),
|
118 |
+
'module' => $block->getModuleName(),
|
119 |
+
'type' => $block->getData('type'),
|
120 |
+
'cacheable' => $block->getCacheLifetime() !== null,
|
121 |
+
'cache_time' => $block->getCacheLifetime(),
|
122 |
+
];
|
123 |
+
}
|
124 |
+
|
125 |
+
public function getTotalRenderTime()
|
126 |
+
{
|
127 |
+
return $this->getData('render_time', 0);
|
128 |
+
}
|
129 |
+
|
130 |
+
public function getRenderLog()
|
131 |
+
{
|
132 |
+
return $this->getData('render_log', []);
|
133 |
+
}
|
134 |
+
|
135 |
+
public function getBlocksNotRendered()
|
136 |
+
{
|
137 |
+
return $this->getData('blocks_not_rendered', []);
|
138 |
+
}
|
139 |
+
|
140 |
+
public function getLayoutHandles()
|
141 |
+
{
|
142 |
+
return $this->getData('handles', []);
|
143 |
+
}
|
144 |
+
|
145 |
+
public function getBlocksCreatedCount()
|
146 |
+
{
|
147 |
+
return $this->getData('blocks_created_count', []);
|
148 |
+
}
|
149 |
+
|
150 |
+
public function getBlocksRenderedCount()
|
151 |
+
{
|
152 |
+
return $this->getData('blocks_rendered_count', 0);
|
153 |
+
}
|
154 |
+
|
155 |
+
|
156 |
+
|
157 |
+
/**
|
158 |
+
* @codeCoverageIgnore
|
159 |
+
* @return Mage_Core_Model_Layout
|
160 |
+
*/
|
161 |
+
public function getLayout()
|
162 |
+
{
|
163 |
+
return Mage::app()->getLayout();
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @codeCoverageIgnore
|
168 |
+
* @return string
|
169 |
+
*/
|
170 |
+
public function getName()
|
171 |
+
{
|
172 |
+
return 'layout';
|
173 |
+
}
|
174 |
+
|
175 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/LogDataCollector.php
ADDED
@@ -0,0 +1,217 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_LogDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_LogDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
private $errorNames = [
|
11 |
+
E_DEPRECATED => 'E_DEPRECATED',
|
12 |
+
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
|
13 |
+
E_NOTICE => 'E_NOTICE',
|
14 |
+
E_USER_NOTICE => 'E_USER_NOTICE',
|
15 |
+
E_STRICT => 'E_STRICT',
|
16 |
+
E_WARNING => 'E_WARNING',
|
17 |
+
E_USER_WARNING => 'E_USER_WARNING',
|
18 |
+
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
|
19 |
+
E_CORE_WARNING => 'E_CORE_WARNING',
|
20 |
+
E_USER_ERROR => 'E_USER_ERROR',
|
21 |
+
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
|
22 |
+
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
|
23 |
+
E_PARSE => 'E_PARSE',
|
24 |
+
E_ERROR => 'E_ERROR',
|
25 |
+
E_CORE_ERROR => 'E_CORE_ERROR',
|
26 |
+
];
|
27 |
+
|
28 |
+
protected $logger;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Ecocode_Profiler_Model_Collector_LogDataCollector constructor.
|
32 |
+
*/
|
33 |
+
public function __construct()
|
34 |
+
{
|
35 |
+
$this->logger = Mage::getLogger();
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* {@inheritdoc}
|
40 |
+
*/
|
41 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
42 |
+
{
|
43 |
+
$this->data = [
|
44 |
+
'logs' => [],
|
45 |
+
'total_count' => 0
|
46 |
+
];
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
public function lateCollect()
|
51 |
+
{
|
52 |
+
$this->data = [];
|
53 |
+
if ($this->logger) {
|
54 |
+
$this->data = $this->computeErrorsCount();
|
55 |
+
$this->data['logs'] = $this->sanitizeLogs($this->getLogger()->getLogs());
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
public function countErrors()
|
60 |
+
{
|
61 |
+
return isset($this->data['error_count']) ? $this->data['error_count'] : 0;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Gets the logs.
|
66 |
+
*
|
67 |
+
* @return array An array of logs
|
68 |
+
*/
|
69 |
+
public function getLogs()
|
70 |
+
{
|
71 |
+
return isset($this->data['logs']) ? $this->data['logs'] : [];
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getPriorities()
|
75 |
+
{
|
76 |
+
return isset($this->data['priorities']) ? $this->data['priorities'] : [];
|
77 |
+
}
|
78 |
+
|
79 |
+
public function countDeprecations()
|
80 |
+
{
|
81 |
+
return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function countScreams()
|
85 |
+
{
|
86 |
+
return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0;
|
87 |
+
}
|
88 |
+
|
89 |
+
private function sanitizeLogs($logs)
|
90 |
+
{
|
91 |
+
$errorContextById = [];
|
92 |
+
$sanitizedLogs = [];
|
93 |
+
|
94 |
+
foreach ($logs as $log) {
|
95 |
+
$context = $this->sanitizeContext($log['context']);
|
96 |
+
|
97 |
+
if (isset($context['type'], $context['file'], $context['line'], $context['level'])) {
|
98 |
+
$errorId = md5("{$context['type']}/{$context['line']}/{$context['file']}\x00{$log['message']}", true);
|
99 |
+
$silenced = !($context['type'] & $context['level']);
|
100 |
+
if (isset($this->errorNames[$context['type']])) {
|
101 |
+
$context = array_merge(['name' => $this->errorNames[$context['type']]], $context);
|
102 |
+
}
|
103 |
+
|
104 |
+
if (isset($errorContextById[$errorId])) {
|
105 |
+
if (isset($errorContextById[$errorId]['errorCount'])) {
|
106 |
+
++$errorContextById[$errorId]['errorCount'];
|
107 |
+
} else {
|
108 |
+
$errorContextById[$errorId]['errorCount'] = 2;
|
109 |
+
}
|
110 |
+
|
111 |
+
if (!$silenced && isset($errorContextById[$errorId]['scream'])) {
|
112 |
+
unset($errorContextById[$errorId]['scream']);
|
113 |
+
$errorContextById[$errorId]['level'] = $context['level'];
|
114 |
+
}
|
115 |
+
|
116 |
+
continue;
|
117 |
+
}
|
118 |
+
|
119 |
+
$errorContextById[$errorId] = &$context;
|
120 |
+
if ($silenced) {
|
121 |
+
$context['scream'] = true;
|
122 |
+
}
|
123 |
+
|
124 |
+
$log['context'] = &$context;
|
125 |
+
unset($context);
|
126 |
+
} else {
|
127 |
+
$log['context'] = $context;
|
128 |
+
}
|
129 |
+
|
130 |
+
$sanitizedLogs[] = $log;
|
131 |
+
}
|
132 |
+
|
133 |
+
return $sanitizedLogs;
|
134 |
+
}
|
135 |
+
|
136 |
+
private function sanitizeContext($context)
|
137 |
+
{
|
138 |
+
if (is_array($context)) {
|
139 |
+
foreach ($context as $key => $value) {
|
140 |
+
$context[$key] = $this->sanitizeContext($value);
|
141 |
+
}
|
142 |
+
|
143 |
+
return $context;
|
144 |
+
}
|
145 |
+
|
146 |
+
if (is_resource($context)) {
|
147 |
+
return sprintf('Resource(%s)', get_resource_type($context));
|
148 |
+
}
|
149 |
+
|
150 |
+
if (is_object($context)) {
|
151 |
+
return sprintf('Object(%s)', get_class($context));
|
152 |
+
}
|
153 |
+
|
154 |
+
return $context;
|
155 |
+
}
|
156 |
+
|
157 |
+
private function computeErrorsCount()
|
158 |
+
{
|
159 |
+
$logger = $this->getLogger();
|
160 |
+
$count = [
|
161 |
+
'total_log_count' => count($logger->getLogs()),
|
162 |
+
'error_count' => $logger->countErrors(),
|
163 |
+
'deprecation_count' => 0,
|
164 |
+
'scream_count' => 0,
|
165 |
+
'priorities' => [],
|
166 |
+
];
|
167 |
+
|
168 |
+
foreach ($logger->getLogs() as $log) {
|
169 |
+
if (isset($count['priorities'][$log['priority']])) {
|
170 |
+
++$count['priorities'][$log['priority']]['count'];
|
171 |
+
} else {
|
172 |
+
$count['priorities'][$log['priority']] = [
|
173 |
+
'count' => 1,
|
174 |
+
'name' => $log['priorityName'],
|
175 |
+
];
|
176 |
+
}
|
177 |
+
|
178 |
+
if (isset($log['context']['type'], $log['context']['level'])) {
|
179 |
+
if (E_DEPRECATED === $log['context']['type'] || E_USER_DEPRECATED === $log['context']['type']) {
|
180 |
+
++$count['deprecation_count'];
|
181 |
+
} elseif (!($log['context']['type'] & $log['context']['level'])) {
|
182 |
+
++$count['scream_count'];
|
183 |
+
}
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
ksort($count['priorities']);
|
188 |
+
|
189 |
+
return $count;
|
190 |
+
}
|
191 |
+
|
192 |
+
public function getLogCount()
|
193 |
+
{
|
194 |
+
return isset($this->data['total_log_count']) ? $this->data['total_log_count'] : 0;
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @codeCoverageIgnore
|
200 |
+
* {@inheritdoc}
|
201 |
+
*/
|
202 |
+
protected function getLogger()
|
203 |
+
{
|
204 |
+
return $this->logger;
|
205 |
+
}
|
206 |
+
|
207 |
+
|
208 |
+
/**
|
209 |
+
* @codeCoverageIgnore
|
210 |
+
* {@inheritdoc}
|
211 |
+
*/
|
212 |
+
public function getName()
|
213 |
+
{
|
214 |
+
return 'log';
|
215 |
+
}
|
216 |
+
|
217 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/MemoryDataCollector.php
ADDED
@@ -0,0 +1,113 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_MemoryDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_MemoryDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
protected function getCurrentMemoryLimit()
|
14 |
+
{
|
15 |
+
return ini_get('memory_limit');
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return int
|
20 |
+
*/
|
21 |
+
protected function getCurrentPeakMemoryUsage()
|
22 |
+
{
|
23 |
+
return memory_get_peak_usage(true);
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritdoc}
|
28 |
+
*/
|
29 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
30 |
+
{
|
31 |
+
$this->data = [
|
32 |
+
'memory' => 0,
|
33 |
+
'memory_limit' => $this->convertToBytes($this->getCurrentMemoryLimit()),
|
34 |
+
];
|
35 |
+
|
36 |
+
$this->updateMemoryUsage();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* {@inheritdoc}
|
41 |
+
*/
|
42 |
+
public function lateCollect()
|
43 |
+
{
|
44 |
+
$this->updateMemoryUsage();
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Gets the memory.
|
49 |
+
*
|
50 |
+
* @return int The memory
|
51 |
+
*/
|
52 |
+
public function getMemory()
|
53 |
+
{
|
54 |
+
return $this->data['memory'];
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Gets the PHP memory limit.
|
59 |
+
*
|
60 |
+
* @return int The memory limit
|
61 |
+
*/
|
62 |
+
public function getMemoryLimit()
|
63 |
+
{
|
64 |
+
return $this->data['memory_limit'];
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Updates the memory usage data.
|
69 |
+
*/
|
70 |
+
public function updateMemoryUsage()
|
71 |
+
{
|
72 |
+
$this->data['memory'] = $this->getCurrentPeakMemoryUsage();
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @codeCoverageIgnore
|
77 |
+
* {@inheritdoc}
|
78 |
+
*/
|
79 |
+
public function getName()
|
80 |
+
{
|
81 |
+
return 'memory';
|
82 |
+
}
|
83 |
+
|
84 |
+
private function convertToBytes($memoryLimit)
|
85 |
+
{
|
86 |
+
if ('-1' === $memoryLimit) {
|
87 |
+
return -1;
|
88 |
+
}
|
89 |
+
|
90 |
+
$memoryLimit = strtolower($memoryLimit);
|
91 |
+
$max = strtolower(ltrim($memoryLimit, '+'));
|
92 |
+
if (0 === strpos($max, '0x')) {
|
93 |
+
$max = intval($max, 16);
|
94 |
+
} elseif (0 === strpos($max, '0')) {
|
95 |
+
$max = intval($max, 8);
|
96 |
+
} else {
|
97 |
+
$max = (int)$max;
|
98 |
+
}
|
99 |
+
|
100 |
+
switch (substr($memoryLimit, -1)) {
|
101 |
+
case 't':
|
102 |
+
$max *= 1024;
|
103 |
+
case 'g':
|
104 |
+
$max *= 1024;
|
105 |
+
case 'm':
|
106 |
+
$max *= 1024;
|
107 |
+
case 'k':
|
108 |
+
$max *= 1024;
|
109 |
+
}
|
110 |
+
|
111 |
+
return $max;
|
112 |
+
}
|
113 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/ModelDataCollector.php
ADDED
@@ -0,0 +1,228 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_ModelDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_ModelDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
CONST LOAD_CALL_THRESHOLD = 20;
|
10 |
+
|
11 |
+
protected $callLog = [];
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @codeCoverageIgnore
|
15 |
+
* @return int
|
16 |
+
*/
|
17 |
+
public function getLoadCallThreshold()
|
18 |
+
{
|
19 |
+
return static::LOAD_CALL_THRESHOLD;
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* {@inheritdoc}
|
24 |
+
*/
|
25 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
26 |
+
{
|
27 |
+
$stats = [
|
28 |
+
'load' => 0,
|
29 |
+
'loop_load' => 0,
|
30 |
+
'save' => 0,
|
31 |
+
'delete' => 0,
|
32 |
+
];
|
33 |
+
|
34 |
+
$totalTime = 0;
|
35 |
+
$traceHashList = [];
|
36 |
+
|
37 |
+
foreach ($this->callLog as &$item) {
|
38 |
+
switch ($item['action']) {
|
39 |
+
case 'load':
|
40 |
+
$stats[$item['action']]++;
|
41 |
+
|
42 |
+
//try to detect load calls in loops
|
43 |
+
$traceHash = $item['trace_hash'];
|
44 |
+
if (!isset($traceHashList[$traceHash])) {
|
45 |
+
$traceHashList[$traceHash] = 0;
|
46 |
+
}
|
47 |
+
$traceHashList[$traceHash]++;
|
48 |
+
break;
|
49 |
+
case 'save':
|
50 |
+
case 'delete':
|
51 |
+
$stats[$item['action']]++;
|
52 |
+
break;
|
53 |
+
}
|
54 |
+
if (!isset($item['time'])) {
|
55 |
+
$item['time'] = null;
|
56 |
+
}
|
57 |
+
$totalTime += $item['time'];
|
58 |
+
}
|
59 |
+
|
60 |
+
$traceHashList = array_filter($traceHashList, function ($v) {
|
61 |
+
return $v > 1;
|
62 |
+
});
|
63 |
+
|
64 |
+
$stats['loop_load'] = array_sum($traceHashList);
|
65 |
+
|
66 |
+
$this->data = [
|
67 |
+
'total_time' => $totalTime,
|
68 |
+
'metrics' => $stats,
|
69 |
+
'calls' => $this->callLog
|
70 |
+
];
|
71 |
+
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getLoadLoopCalls()
|
75 |
+
{
|
76 |
+
$traceHashList = [];
|
77 |
+
|
78 |
+
foreach ($this->getCallLog() as $item) {
|
79 |
+
if ($item['action'] !== 'load') {
|
80 |
+
continue;
|
81 |
+
}
|
82 |
+
//try to detect load calls in loops
|
83 |
+
$traceHash = $item['trace_hash'];
|
84 |
+
if (!isset($traceHashList[$traceHash])) {
|
85 |
+
$item['count'] = 0;
|
86 |
+
$item['total_time'] = 0;
|
87 |
+
$traceHashList[$traceHash] = $item;
|
88 |
+
}
|
89 |
+
$traceHashList[$traceHash]['count']++;
|
90 |
+
$traceHashList[$traceHash]['total_time'] += $item['time'];
|
91 |
+
}
|
92 |
+
|
93 |
+
$traceHashList = array_filter($traceHashList, function ($v) {
|
94 |
+
return $v['count'] > 1;
|
95 |
+
});
|
96 |
+
|
97 |
+
usort($traceHashList, function ($a, $b) {
|
98 |
+
return $b['count'] - $a['count'];
|
99 |
+
});
|
100 |
+
|
101 |
+
return array_values($traceHashList);
|
102 |
+
}
|
103 |
+
|
104 |
+
|
105 |
+
public function getTotalTime()
|
106 |
+
{
|
107 |
+
|
108 |
+
return $this->getData('total_time', 0);
|
109 |
+
}
|
110 |
+
|
111 |
+
public function getCallLog()
|
112 |
+
{
|
113 |
+
|
114 |
+
return $this->getData('calls', []);
|
115 |
+
}
|
116 |
+
|
117 |
+
|
118 |
+
public function getMetric($key = null)
|
119 |
+
{
|
120 |
+
if ($key === null) {
|
121 |
+
return $this->data['metrics'];
|
122 |
+
}
|
123 |
+
|
124 |
+
return $this->data['metrics'][$key];
|
125 |
+
}
|
126 |
+
|
127 |
+
|
128 |
+
public function trackModelLoad(Varien_Event_Observer $observer)
|
129 |
+
{
|
130 |
+
$this->trackEvent('load', $observer->getEvent());
|
131 |
+
}
|
132 |
+
|
133 |
+
public function trackModelSave(Varien_Event_Observer $observer)
|
134 |
+
{
|
135 |
+
$this->trackEvent('save', $observer->getEvent());
|
136 |
+
}
|
137 |
+
|
138 |
+
public function trackModelDelete(Varien_Event_Observer $observer)
|
139 |
+
{
|
140 |
+
$this->trackEvent('delete', $observer->getEvent());
|
141 |
+
}
|
142 |
+
|
143 |
+
protected function trackEvent($action, Varien_Event $event)
|
144 |
+
{
|
145 |
+
$object = $event->getData('object');
|
146 |
+
|
147 |
+
$this->track($action, $object, $event->getData('time'));
|
148 |
+
}
|
149 |
+
|
150 |
+
protected function track($action, Varien_Object $object, $time = null)
|
151 |
+
{
|
152 |
+
$className = get_class($object);
|
153 |
+
$classGroup = $this->getHelper()->getClassGroup($className);
|
154 |
+
$trace = $this->cleanBacktrace($this->getBacktrace(DEBUG_BACKTRACE_IGNORE_ARGS));
|
155 |
+
|
156 |
+
$data = [
|
157 |
+
'action' => $action,
|
158 |
+
'class' => $className,
|
159 |
+
'class_group' => $classGroup,
|
160 |
+
'trace' => $trace,
|
161 |
+
'trace_hash' => md5(serialize($trace))
|
162 |
+
];
|
163 |
+
|
164 |
+
if ($time) {
|
165 |
+
$data['time'] = $time;
|
166 |
+
}
|
167 |
+
|
168 |
+
$this->callLog[] = $data;
|
169 |
+
}
|
170 |
+
|
171 |
+
protected function cleanBacktrace(array $backtrace)
|
172 |
+
{
|
173 |
+
$item = reset($backtrace);
|
174 |
+
while ($item && $this->shouldRemoveBacktrace($item)) {
|
175 |
+
array_shift($backtrace);
|
176 |
+
$item = reset($backtrace);
|
177 |
+
}
|
178 |
+
|
179 |
+
$backtrace = array_map(function ($item) {
|
180 |
+
unset($item['object'], $item['args'], $item['type']);
|
181 |
+
return $item;
|
182 |
+
}, $backtrace);
|
183 |
+
|
184 |
+
return $backtrace;
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
protected function shouldRemoveBacktrace($data)
|
189 |
+
{
|
190 |
+
if (!is_array($data)) {
|
191 |
+
return false;
|
192 |
+
}
|
193 |
+
|
194 |
+
if (!isset($data['class'], $data['function'])) {
|
195 |
+
return true;
|
196 |
+
}
|
197 |
+
|
198 |
+
if (!in_array($data['class'], ['Mage_Core_Model_Resource_Db_Abstract', 'Mage_Eav_Model_Entity_Abstract'])) {
|
199 |
+
return true;
|
200 |
+
}
|
201 |
+
|
202 |
+
if (!in_array($data['function'], ['load', 'delete', 'save'])) {
|
203 |
+
return true;
|
204 |
+
}
|
205 |
+
|
206 |
+
return false;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @codeCoverageIgnore
|
211 |
+
* @return Ecocode_Profiler_Helper_Data
|
212 |
+
*/
|
213 |
+
protected function getHelper()
|
214 |
+
{
|
215 |
+
return Mage::helper('ecocode_profiler');
|
216 |
+
}
|
217 |
+
|
218 |
+
|
219 |
+
/**
|
220 |
+
* @codeCoverageIgnore
|
221 |
+
* {@inheritdoc}
|
222 |
+
*/
|
223 |
+
public function getName()
|
224 |
+
{
|
225 |
+
return 'model';
|
226 |
+
}
|
227 |
+
|
228 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/MysqlDataCollector.php
ADDED
@@ -0,0 +1,139 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_MysqlDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_MysqlDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
const BACKTRACE_LIMIT = 10;
|
10 |
+
|
11 |
+
protected $ignoredFunctionCalls = [
|
12 |
+
'Mage_Core_Model_Resource_Db_Abstract::load',
|
13 |
+
'Mage_Eav_Model_Entity_Abstract::load',
|
14 |
+
'Mage_Catalog_Model_Resource_Abstract::load',
|
15 |
+
'Mage_Core_Model_Abstract::load',
|
16 |
+
'Varien_Data_Collection_Db::_fetchAll'
|
17 |
+
];
|
18 |
+
|
19 |
+
protected $ignoreInstanceOf = [
|
20 |
+
'Ecocode_Profiler_Model_Collector_MysqlDataCollector',
|
21 |
+
'Zend_Db_Statement',
|
22 |
+
'Zend_Db_Adapter_Abstract',
|
23 |
+
'Varien_Db_Statement_Pdo_Mysql'
|
24 |
+
];
|
25 |
+
|
26 |
+
protected $rawQueries = [];
|
27 |
+
protected $totalQueryTime = 0;
|
28 |
+
|
29 |
+
public function logQuery(Ecocode_Profiler_Db_Statement_Pdo_Mysql $statement)
|
30 |
+
{
|
31 |
+
$connectionName = 'unknown';
|
32 |
+
$connectionConfig = $statement->getAdapter()->getConfig();
|
33 |
+
if (isset($connectionConfig['connection_name'])) {
|
34 |
+
$connectionName = $connectionConfig['connection_name'];
|
35 |
+
}
|
36 |
+
|
37 |
+
$this->totalQueryTime += $statement->getElapsedTime();
|
38 |
+
$this->rawQueries[] = [
|
39 |
+
'sql' => $statement->getQueryString(),
|
40 |
+
'connection' => $connectionName,
|
41 |
+
'statement' => $statement,
|
42 |
+
'time' => $statement->getElapsedTime(),
|
43 |
+
'params' => $statement->getParams(),
|
44 |
+
'result' => $statement->getResult(),
|
45 |
+
'context' => $this->getContextId(),
|
46 |
+
'trace' => $this->getTrace()
|
47 |
+
];
|
48 |
+
}
|
49 |
+
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param Mage_Core_Controller_Request_Http $request
|
53 |
+
* @param Mage_Core_Controller_Response_Http $response
|
54 |
+
* @param Exception|null $exception
|
55 |
+
*
|
56 |
+
* @return void
|
57 |
+
*/
|
58 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
59 |
+
{
|
60 |
+
$this->data['nb_queries'] = count($this->rawQueries);
|
61 |
+
$this->data['total_time'] = $this->totalQueryTime;
|
62 |
+
|
63 |
+
$queries = [];
|
64 |
+
$connections = [];
|
65 |
+
|
66 |
+
foreach ($this->rawQueries as $query) {
|
67 |
+
unset($query['statement']);
|
68 |
+
$connection = $query['connection'];
|
69 |
+
if (!isset($connections[$connection])) {
|
70 |
+
$connections[$connection] = 0;
|
71 |
+
|
72 |
+
}
|
73 |
+
$connections[$connection]++;
|
74 |
+
$queries[] = $query;
|
75 |
+
}
|
76 |
+
$this->data['queries'] = $queries;
|
77 |
+
$this->data['used_connections'] = $connections;
|
78 |
+
$this->data;
|
79 |
+
}
|
80 |
+
|
81 |
+
public function getQueries()
|
82 |
+
{
|
83 |
+
return $this->data['queries'];
|
84 |
+
}
|
85 |
+
|
86 |
+
public function getConnectionData()
|
87 |
+
{
|
88 |
+
return $this->data['used_connections'];
|
89 |
+
}
|
90 |
+
|
91 |
+
public function getTotalTime()
|
92 |
+
{
|
93 |
+
return $this->data['total_time'];
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
public function getQueryCount()
|
98 |
+
{
|
99 |
+
return $this->data['nb_queries'];
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
protected function getTrace()
|
104 |
+
{
|
105 |
+
$backtrace = $this->getBacktrace();
|
106 |
+
if ($backtrace === false) {
|
107 |
+
return [];
|
108 |
+
}
|
109 |
+
|
110 |
+
$backtrace = $this->cleanBacktrace($backtrace);
|
111 |
+
|
112 |
+
$backtrace = array_slice($backtrace, 0, self::BACKTRACE_LIMIT);
|
113 |
+
$backtrace = array_map(function ($item) {
|
114 |
+
unset($item['object'], $item['args'], $item['type']);
|
115 |
+
return $item;
|
116 |
+
}, $backtrace);
|
117 |
+
|
118 |
+
return $backtrace;
|
119 |
+
}
|
120 |
+
|
121 |
+
public function cleanBacktrace(array $backtrace)
|
122 |
+
{
|
123 |
+
return Mage::helper('ecocode_profiler')
|
124 |
+
->cleanBacktrace(
|
125 |
+
$backtrace,
|
126 |
+
$this->ignoredFunctionCalls,
|
127 |
+
$this->ignoreInstanceOf
|
128 |
+
|
129 |
+
);
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* {@inheritdoc}
|
134 |
+
*/
|
135 |
+
public function getName()
|
136 |
+
{
|
137 |
+
return 'mysql';
|
138 |
+
}
|
139 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/RequestDataCollector.php
ADDED
@@ -0,0 +1,488 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_RequestDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_RequestDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
public static $statusTexts = [
|
10 |
+
100 => 'Continue',
|
11 |
+
101 => 'Switching Protocols',
|
12 |
+
102 => 'Processing', // RFC2518
|
13 |
+
200 => 'OK',
|
14 |
+
201 => 'Created',
|
15 |
+
202 => 'Accepted',
|
16 |
+
203 => 'Non-Authoritative Information',
|
17 |
+
204 => 'No Content',
|
18 |
+
205 => 'Reset Content',
|
19 |
+
206 => 'Partial Content',
|
20 |
+
207 => 'Multi-Status', // RFC4918
|
21 |
+
208 => 'Already Reported', // RFC5842
|
22 |
+
226 => 'IM Used', // RFC3229
|
23 |
+
300 => 'Multiple Choices',
|
24 |
+
301 => 'Moved Permanently',
|
25 |
+
302 => 'Found',
|
26 |
+
303 => 'See Other',
|
27 |
+
304 => 'Not Modified',
|
28 |
+
305 => 'Use Proxy',
|
29 |
+
307 => 'Temporary Redirect',
|
30 |
+
308 => 'Permanent Redirect', // RFC7238
|
31 |
+
400 => 'Bad Request',
|
32 |
+
401 => 'Unauthorized',
|
33 |
+
402 => 'Payment Required',
|
34 |
+
403 => 'Forbidden',
|
35 |
+
404 => 'Not Found',
|
36 |
+
405 => 'Method Not Allowed',
|
37 |
+
406 => 'Not Acceptable',
|
38 |
+
407 => 'Proxy Authentication Required',
|
39 |
+
408 => 'Request Timeout',
|
40 |
+
409 => 'Conflict',
|
41 |
+
410 => 'Gone',
|
42 |
+
411 => 'Length Required',
|
43 |
+
412 => 'Precondition Failed',
|
44 |
+
413 => 'Payload Too Large',
|
45 |
+
414 => 'URI Too Long',
|
46 |
+
415 => 'Unsupported Media Type',
|
47 |
+
416 => 'Range Not Satisfiable',
|
48 |
+
417 => 'Expectation Failed',
|
49 |
+
418 => 'I\'m a teapot', // RFC2324
|
50 |
+
421 => 'Misdirected Request', // RFC7540
|
51 |
+
422 => 'Unprocessable Entity', // RFC4918
|
52 |
+
423 => 'Locked', // RFC4918
|
53 |
+
424 => 'Failed Dependency', // RFC4918
|
54 |
+
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
|
55 |
+
426 => 'Upgrade Required', // RFC2817
|
56 |
+
428 => 'Precondition Required', // RFC6585
|
57 |
+
429 => 'Too Many Requests', // RFC6585
|
58 |
+
431 => 'Request Header Fields Too Large', // RFC6585
|
59 |
+
451 => 'Unavailable For Legal Reasons', // RFC7725
|
60 |
+
500 => 'Internal Server Error',
|
61 |
+
501 => 'Not Implemented',
|
62 |
+
502 => 'Bad Gateway',
|
63 |
+
503 => 'Service Unavailable',
|
64 |
+
504 => 'Gateway Timeout',
|
65 |
+
505 => 'HTTP Version Not Supported',
|
66 |
+
506 => 'Variant Also Negotiates (Experimental)', // RFC2295
|
67 |
+
507 => 'Insufficient Storage', // RFC4918
|
68 |
+
508 => 'Loop Detected', // RFC5842
|
69 |
+
510 => 'Not Extended', // RFC2774
|
70 |
+
511 => 'Network Authentication Required', // RFC6585
|
71 |
+
];
|
72 |
+
|
73 |
+
/**
|
74 |
+
* {@inheritdoc}
|
75 |
+
*/
|
76 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
77 |
+
{
|
78 |
+
$responseHeaders = $this->collectResponseHeaders($response);
|
79 |
+
// attributes are serialized and as they can be anything, they need to be converted to strings.
|
80 |
+
$requestAttributes = $this->collectRequestAttributes($request);
|
81 |
+
$requestHeaders = $this->collectRequestHeaders($request);
|
82 |
+
$requestContent = $request->getRawBody();
|
83 |
+
|
84 |
+
$sessionMetadata = [];
|
85 |
+
$sessionAttributes = [];
|
86 |
+
//@TODO get all magento session singletons to split them by namespace
|
87 |
+
$flashes = [];
|
88 |
+
|
89 |
+
/*
|
90 |
+
$session = null
|
91 |
+
if (false && $request->hasSession()) {
|
92 |
+
$session = $request->getSession();
|
93 |
+
if ($session->isStarted()) {
|
94 |
+
$sessionMetadata['Created'] = date(DATE_RFC822, $session->getMetadataBag()->getCreated());
|
95 |
+
$sessionMetadata['Last used'] = date(DATE_RFC822, $session->getMetadataBag()->getLastUsed());
|
96 |
+
$sessionMetadata['Lifetime'] = $session->getMetadataBag()->getLifetime();
|
97 |
+
$sessionAttributes = $session->all();
|
98 |
+
$flashes = $session->getFlashBag()->peekAll();
|
99 |
+
}
|
100 |
+
}*/
|
101 |
+
|
102 |
+
$statusCode = $this->detectStatusCode($response);
|
103 |
+
$statusText = isset(self::$statusTexts[$statusCode]) ? self::$statusTexts[$statusCode] : '';
|
104 |
+
|
105 |
+
|
106 |
+
$contentType = isset($responseHeaders['Content-Type']) ? $responseHeaders['Content-Type'] : 'text/html';
|
107 |
+
$this->data = [
|
108 |
+
'method' => $request->getMethod(),
|
109 |
+
'content' => $requestContent,
|
110 |
+
'content_type' => $contentType,
|
111 |
+
'status_text' => $statusText,
|
112 |
+
'status_code' => $statusCode,
|
113 |
+
'request_query' => $this->collectRequestQuery($request),
|
114 |
+
'request_request' => $this->collectRequestData($request),
|
115 |
+
'request_headers' => $requestHeaders,
|
116 |
+
'request_server' => $request->getServer(),
|
117 |
+
'request_cookies' => $request->getCookie(),
|
118 |
+
'request_attributes' => $requestAttributes,
|
119 |
+
'response_headers' => $responseHeaders,
|
120 |
+
'session_metadata' => $sessionMetadata,
|
121 |
+
'session_attributes' => $sessionAttributes,
|
122 |
+
'flashes' => $flashes,
|
123 |
+
'path_info' => $request->getPathInfo(),
|
124 |
+
'controller' => 'n/a',
|
125 |
+
//'locale' => $request->getLocale(),
|
126 |
+
];
|
127 |
+
|
128 |
+
$this->hideAuthData();
|
129 |
+
|
130 |
+
$controllerData = $this->collectControllerData();
|
131 |
+
if ($controllerData) {
|
132 |
+
$this->data['controller'] = $controllerData;
|
133 |
+
}
|
134 |
+
|
135 |
+
/*if (null !== $session && $session->isStarted()) {
|
136 |
+
if ($request->attributes->has('_redirected')) {
|
137 |
+
$this->data['redirect'] = $session->remove('sf_redirect');
|
138 |
+
}
|
139 |
+
|
140 |
+
if ($response->isRedirect()) {
|
141 |
+
$session->set('sf_redirect', [
|
142 |
+
'token' => $response->headers->get('x-debug-token'),
|
143 |
+
'route' => $request->attributes->get('_route', 'n/a'),
|
144 |
+
'method' => $request->getMethod(),
|
145 |
+
'controller' => $this->parseController($request->attributes->get('_controller')),
|
146 |
+
'status_code' => $statusCode,
|
147 |
+
'status_text' => Response::$statusTexts[(int)$statusCode],
|
148 |
+
]);
|
149 |
+
}
|
150 |
+
}*/
|
151 |
+
}
|
152 |
+
|
153 |
+
protected function hideAuthData()
|
154 |
+
{
|
155 |
+
if (isset($this->data['request_headers']['php-auth-pw'])) {
|
156 |
+
$this->data['request_headers']['php-auth-pw'] = '******';
|
157 |
+
}
|
158 |
+
|
159 |
+
if (isset($this->data['request_server']['PHP_AUTH_PW'])) {
|
160 |
+
$this->data['request_server']['PHP_AUTH_PW'] = '******';
|
161 |
+
}
|
162 |
+
|
163 |
+
if (isset($this->data['request_request']['_password'])) {
|
164 |
+
$this->data['request_request']['_password'] = '******';
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
public function getMethod()
|
169 |
+
{
|
170 |
+
return $this->data['method'];
|
171 |
+
}
|
172 |
+
|
173 |
+
public function getPathInfo()
|
174 |
+
{
|
175 |
+
return $this->data['path_info'];
|
176 |
+
}
|
177 |
+
|
178 |
+
public function getRequestRequest()
|
179 |
+
{
|
180 |
+
return new Ecocode_Profiler_Model_Http_ParameterBag($this->data['request_request']);
|
181 |
+
}
|
182 |
+
|
183 |
+
public function getRequestQuery()
|
184 |
+
{
|
185 |
+
return new Ecocode_Profiler_Model_Http_ParameterBag($this->data['request_query']);
|
186 |
+
}
|
187 |
+
|
188 |
+
public function getRequestHeaders()
|
189 |
+
{
|
190 |
+
return new Ecocode_Profiler_Model_Http_HeaderBag($this->data['request_headers']);
|
191 |
+
}
|
192 |
+
|
193 |
+
public function getRequestServer()
|
194 |
+
{
|
195 |
+
return new Ecocode_Profiler_Model_Http_ParameterBag($this->data['request_server']);
|
196 |
+
}
|
197 |
+
|
198 |
+
public function getRequestCookies()
|
199 |
+
{
|
200 |
+
return new Ecocode_Profiler_Model_Http_ParameterBag($this->data['request_cookies']);
|
201 |
+
}
|
202 |
+
|
203 |
+
public function getRequestAttributes()
|
204 |
+
{
|
205 |
+
return new Ecocode_Profiler_Model_Http_ParameterBag($this->data['request_attributes']);
|
206 |
+
}
|
207 |
+
|
208 |
+
public function getResponseHeaders()
|
209 |
+
{
|
210 |
+
return new Ecocode_Profiler_Model_Http_ResponseHeaderBag($this->data['response_headers']);
|
211 |
+
}
|
212 |
+
|
213 |
+
public function getSessionMetadata()
|
214 |
+
{
|
215 |
+
return $this->data['session_metadata'];
|
216 |
+
}
|
217 |
+
|
218 |
+
public function getSessionAttributes()
|
219 |
+
{
|
220 |
+
return $this->data['session_attributes'];
|
221 |
+
}
|
222 |
+
|
223 |
+
public function getFlashes()
|
224 |
+
{
|
225 |
+
return $this->data['flashes'];
|
226 |
+
}
|
227 |
+
|
228 |
+
public function getContent()
|
229 |
+
{
|
230 |
+
return $this->data['content'];
|
231 |
+
}
|
232 |
+
|
233 |
+
public function getContentType()
|
234 |
+
{
|
235 |
+
return $this->data['content_type'];
|
236 |
+
}
|
237 |
+
|
238 |
+
public function getStatusText()
|
239 |
+
{
|
240 |
+
return $this->data['status_text'];
|
241 |
+
}
|
242 |
+
|
243 |
+
public function getStatusCode()
|
244 |
+
{
|
245 |
+
return $this->data['status_code'];
|
246 |
+
}
|
247 |
+
|
248 |
+
public function getFormat()
|
249 |
+
{
|
250 |
+
return $this->data['format'];
|
251 |
+
}
|
252 |
+
|
253 |
+
public function getLocale()
|
254 |
+
{
|
255 |
+
return $this->data['locale'];
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Gets the route name.
|
260 |
+
*
|
261 |
+
* @return string The route
|
262 |
+
*/
|
263 |
+
public function getRoute()
|
264 |
+
{
|
265 |
+
return isset($this->data['request_attributes']['_route']) ? $this->data['request_attributes']['_route'] : '';
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* @return string
|
270 |
+
*/
|
271 |
+
public function getRequestUri()
|
272 |
+
{
|
273 |
+
return isset($this->data['request_attributes']['request_uri']) ? $this->data['request_attributes']['request_uri'] : '';
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* @return string
|
278 |
+
*/
|
279 |
+
public function getRequestString()
|
280 |
+
{
|
281 |
+
return isset($this->data['request_attributes']['request_string']) ? $this->data['request_attributes']['request_string'] : '';
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @return string
|
286 |
+
*/
|
287 |
+
public function getRouteName()
|
288 |
+
{
|
289 |
+
return isset($this->data['request_attributes']['_route_name']) ? $this->data['request_attributes']['_route_name'] : '';
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* @return string
|
294 |
+
*/
|
295 |
+
public function getModuleName()
|
296 |
+
{
|
297 |
+
return isset($this->data['request_attributes']['_module']) ? $this->data['request_attributes']['_module'] : '';
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* @return string
|
302 |
+
*/
|
303 |
+
public function getControllerName()
|
304 |
+
{
|
305 |
+
return isset($this->data['request_attributes']['_controller']) ? $this->data['request_attributes']['_controller'] : '';
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @return string
|
310 |
+
*/
|
311 |
+
public function getActionName()
|
312 |
+
{
|
313 |
+
return isset($this->data['request_attributes']['_action']) ? $this->data['request_attributes']['_action'] : '';
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Gets the route parameters.
|
318 |
+
*
|
319 |
+
* @return array The parameters
|
320 |
+
*/
|
321 |
+
public function getRouteParams()
|
322 |
+
{
|
323 |
+
return isset($this->data['request_attributes']['_route_params']) ? $this->data['request_attributes']['_route_params'] : [];
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Gets the parsed controller.
|
328 |
+
*
|
329 |
+
* @return array|string The controller as a string or array of data
|
330 |
+
* with keys 'class', 'method', 'file' and 'line'
|
331 |
+
*/
|
332 |
+
public function getController()
|
333 |
+
{
|
334 |
+
return $this->data['controller'];
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Gets the previous request attributes.
|
339 |
+
*
|
340 |
+
* @return array|bool A legacy array of data from the previous redirection response
|
341 |
+
* or false otherwise
|
342 |
+
*/
|
343 |
+
public function getRedirect()
|
344 |
+
{
|
345 |
+
return isset($this->data['redirect']) ? $this->data['redirect'] : false;
|
346 |
+
}
|
347 |
+
|
348 |
+
|
349 |
+
/**
|
350 |
+
* {@inheritdoc}
|
351 |
+
* @codeCoverageIgnore
|
352 |
+
*/
|
353 |
+
public function getName()
|
354 |
+
{
|
355 |
+
return 'request';
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Parse a controller.
|
360 |
+
*
|
361 |
+
* @param mixed $controller The controller to parse
|
362 |
+
*
|
363 |
+
* @return array|string An array of controller data or a simple string
|
364 |
+
*/
|
365 |
+
protected function parseController($controller)
|
366 |
+
{
|
367 |
+
if (is_object($controller)) {
|
368 |
+
$r = new \ReflectionClass($controller);
|
369 |
+
|
370 |
+
return [
|
371 |
+
'class' => $r->getName(),
|
372 |
+
'method' => null,
|
373 |
+
'file' => $r->getFileName(),
|
374 |
+
'line' => $r->getStartLine(),
|
375 |
+
];
|
376 |
+
}
|
377 |
+
|
378 |
+
return (string)$controller ?: 'n/a';
|
379 |
+
}
|
380 |
+
|
381 |
+
protected function detectStatusCode(Mage_Core_Controller_Response_Http $response)
|
382 |
+
{
|
383 |
+
$statusCode = $response->getHttpResponseCode();
|
384 |
+
foreach ($response->getHeaders() as $header) {
|
385 |
+
if (substr($header['name'], 0, 5) === 'Http/') {
|
386 |
+
preg_match('/^[0-9]{3}/', $header['value'], $matches);
|
387 |
+
if ($matches) {
|
388 |
+
$statusCode = (int)reset($matches);
|
389 |
+
}
|
390 |
+
|
391 |
+
break;
|
392 |
+
}
|
393 |
+
}
|
394 |
+
return $statusCode;
|
395 |
+
}
|
396 |
+
|
397 |
+
protected function collectRequestAttributes(Mage_Core_Controller_Request_Http $request)
|
398 |
+
{
|
399 |
+
//we need to use a reflection as Request->getParams() takes also get parameters into account
|
400 |
+
$class = new ReflectionClass('Mage_Core_Controller_Request_Http');
|
401 |
+
/** @var ReflectionProperty $property */
|
402 |
+
$property = $class->getProperty('_params');
|
403 |
+
$property->setAccessible(true);
|
404 |
+
|
405 |
+
$routeParams = $property->getValue($request);
|
406 |
+
|
407 |
+
$fullActionName = $request->getRequestedRouteName() . '_' .
|
408 |
+
$request->getRequestedControllerName() . '_' .
|
409 |
+
$request->getRequestedActionName();
|
410 |
+
|
411 |
+
$attributes = [
|
412 |
+
'request_string' => $request->getRequestString(),
|
413 |
+
'request_uri' => $request->getRequestUri(),
|
414 |
+
'_module' => $request->getModuleName(),
|
415 |
+
'_controller' => $request->getControllerName(),
|
416 |
+
'_action' => $request->getActionName(),
|
417 |
+
'_route' => $fullActionName,
|
418 |
+
'_route_name' => $request->getRouteName()
|
419 |
+
];
|
420 |
+
|
421 |
+
if ($routeParams) {
|
422 |
+
$attributes['_route_params'] = $routeParams;
|
423 |
+
}
|
424 |
+
|
425 |
+
|
426 |
+
return $attributes;
|
427 |
+
}
|
428 |
+
|
429 |
+
public function collectRequestHeaders(Mage_Core_Controller_Request_Http $request)
|
430 |
+
{
|
431 |
+
$headers = [];
|
432 |
+
foreach ($request->getServer() as $key => $value) {
|
433 |
+
if (substr($key, 0, 5) !== 'HTTP_') {
|
434 |
+
continue;
|
435 |
+
}
|
436 |
+
$header = str_replace(' ', '-', (str_replace('_', ' ', strtolower(substr($key, 5)))));
|
437 |
+
$headers[$header] = $value;
|
438 |
+
}
|
439 |
+
return $headers;
|
440 |
+
}
|
441 |
+
|
442 |
+
public function collectRequestQuery(Mage_Core_Controller_Request_Http $request)
|
443 |
+
{
|
444 |
+
$getData = $request->getQuery();
|
445 |
+
if ($getData === null) {
|
446 |
+
$getData = [];
|
447 |
+
}
|
448 |
+
return $getData;
|
449 |
+
}
|
450 |
+
|
451 |
+
|
452 |
+
public function collectRequestData(Mage_Core_Controller_Request_Http $request)
|
453 |
+
{
|
454 |
+
$postData = $request->getPost();
|
455 |
+
if ($postData === null) {
|
456 |
+
$postData = [];
|
457 |
+
}
|
458 |
+
return $postData;
|
459 |
+
}
|
460 |
+
|
461 |
+
protected function collectControllerData()
|
462 |
+
{
|
463 |
+
//use reflection to make sure we not init a front controller
|
464 |
+
$class = new ReflectionClass('Mage_Core_Model_App');
|
465 |
+
/** @var ReflectionProperty $property */
|
466 |
+
$property = $class->getProperty('_frontController');
|
467 |
+
$property->setAccessible(true);
|
468 |
+
|
469 |
+
$app = Mage::app();
|
470 |
+
$controller = $property->getValue($app);
|
471 |
+
if ($controller) {
|
472 |
+
return $this->parseController($controller);
|
473 |
+
}
|
474 |
+
|
475 |
+
return false;
|
476 |
+
}
|
477 |
+
|
478 |
+
public function collectResponseHeaders(Mage_Core_Controller_Response_Http $response)
|
479 |
+
{
|
480 |
+
$headers = [];
|
481 |
+
|
482 |
+
foreach ($response->getHeaders() as $headerData) {
|
483 |
+
$headers[$headerData['name']] = $headerData['value'];
|
484 |
+
}
|
485 |
+
|
486 |
+
return $headers;
|
487 |
+
}
|
488 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/RewriteDataCollector.php
ADDED
@@ -0,0 +1,62 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_RewriteDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_RewriteDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
/**
|
10 |
+
* @codeCoverageIgnore
|
11 |
+
* @return Ecocode_Profiler_Helper_Rewrite
|
12 |
+
*/
|
13 |
+
protected function getRewriteHelper()
|
14 |
+
{
|
15 |
+
return Mage::helper('ecocode_profiler/rewrite');
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* {@inheritdoc}
|
20 |
+
*/
|
21 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
22 |
+
{
|
23 |
+
$rewriteHelper = $this->getRewriteHelper();
|
24 |
+
$this->data = [
|
25 |
+
'module_rewrites' => $rewriteHelper->loadRewrites(),
|
26 |
+
'module_rewrite_conflicts' => $rewriteHelper->getRewriteConflicts(),
|
27 |
+
];
|
28 |
+
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @return array
|
33 |
+
*/
|
34 |
+
public function getModuleRewrites()
|
35 |
+
{
|
36 |
+
return $this->data['module_rewrites'];
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @return array
|
41 |
+
*/
|
42 |
+
public function getModuleRewriteConflicts()
|
43 |
+
{
|
44 |
+
return $this->data['module_rewrite_conflicts'];
|
45 |
+
}
|
46 |
+
|
47 |
+
|
48 |
+
public function getModuleRewriteConflictCount()
|
49 |
+
{
|
50 |
+
return count($this->data['module_rewrite_conflicts']);
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @codeCoverageIgnore
|
55 |
+
* @return string
|
56 |
+
*/
|
57 |
+
public function getName()
|
58 |
+
{
|
59 |
+
return 'rewrite';
|
60 |
+
}
|
61 |
+
|
62 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/TimeDataCollector.php
ADDED
@@ -0,0 +1,44 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_TimeDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_TimeDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
implements Ecocode_Profiler_Model_Collector_LateDataCollectorInterface
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* {@inheritdoc}
|
12 |
+
*/
|
13 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
14 |
+
{
|
15 |
+
$this->data = [
|
16 |
+
'total_time' => 0
|
17 |
+
];
|
18 |
+
}
|
19 |
+
|
20 |
+
public function lateCollect()
|
21 |
+
{
|
22 |
+
$startTime = Mage::app()->getStartTime();
|
23 |
+
|
24 |
+
if ($startTime) {
|
25 |
+
$this->data['total_time'] = microtime(true) - $startTime;
|
26 |
+
}
|
27 |
+
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getTotalTime()
|
32 |
+
{
|
33 |
+
return $this->data['total_time'];
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @codeCoverageIgnore
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
public function getName()
|
41 |
+
{
|
42 |
+
return 'time';
|
43 |
+
}
|
44 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Collector/TranslationDataCollector.php
ADDED
@@ -0,0 +1,91 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Collector_TranslationDataCollector
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Collector_TranslationDataCollector
|
7 |
+
extends Ecocode_Profiler_Model_Collector_AbstractDataCollector
|
8 |
+
{
|
9 |
+
protected $_currentBlock;
|
10 |
+
|
11 |
+
protected $stateCounts = [
|
12 |
+
'translated' => 0,
|
13 |
+
'missing' => 0,
|
14 |
+
'invalid' => 0,
|
15 |
+
'fallback' => 0
|
16 |
+
];
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return Mage_Core_Model_Translate
|
20 |
+
*/
|
21 |
+
protected function getTranslator()
|
22 |
+
{
|
23 |
+
return Mage::getSingleton('core/translate');
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritdoc}
|
28 |
+
*/
|
29 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response, \Exception $exception = null)
|
30 |
+
{
|
31 |
+
|
32 |
+
$this->data['state_counts'] = $this->stateCounts;
|
33 |
+
$translations = [];
|
34 |
+
|
35 |
+
foreach ($this->getTranslator()->getMessages() as $translation) {
|
36 |
+
$translationId = $translation['code'];
|
37 |
+
if (!isset($translations[$translationId])) {
|
38 |
+
$translation['count'] = 1;
|
39 |
+
$translation['parameters'] = !empty($translation['parameters']) ? [$translation['parameters']] : [];
|
40 |
+
$translation['traces'] = !empty($translation['trace']) ? [$translation['trace']] : [];
|
41 |
+
unset($translation['trace']);
|
42 |
+
$translations[$translationId] = $translation;
|
43 |
+
$this->data['state_counts'][$translation['state']]++;
|
44 |
+
} else {
|
45 |
+
if (!empty($translation['parameters'])) {
|
46 |
+
$translations[$translationId]['parameters'][] = $translation['parameters'];
|
47 |
+
}
|
48 |
+
if (!empty($translation['trace'])) {
|
49 |
+
$translations[$translationId]['traces'][] = $translation['trace'];
|
50 |
+
}
|
51 |
+
$translations[$translationId]['count']++;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
$this->data['translations'] = $translations;
|
55 |
+
$this->data['translation_count'] = count($translations);
|
56 |
+
}
|
57 |
+
|
58 |
+
public function getTranslations()
|
59 |
+
{
|
60 |
+
return $this->getData('translations', []);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function getTranslationCount()
|
64 |
+
{
|
65 |
+
return $this->getData('translation_count', 0);
|
66 |
+
}
|
67 |
+
|
68 |
+
public function getStateCount($status = null)
|
69 |
+
{
|
70 |
+
if ($status === null) {
|
71 |
+
return $this->data['state_counts'];
|
72 |
+
}
|
73 |
+
return $this->data['state_counts'][$status];
|
74 |
+
}
|
75 |
+
|
76 |
+
public function getNotOkCount()
|
77 |
+
{
|
78 |
+
return $this->getStateCount('invalid')
|
79 |
+
+ $this->getStateCount('missing')
|
80 |
+
+ $this->getStateCount('fallback');
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* {@inheritdoc}
|
85 |
+
* @codeCoverageIgnore
|
86 |
+
*/
|
87 |
+
public function getName()
|
88 |
+
{
|
89 |
+
return 'translation';
|
90 |
+
}
|
91 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Context.php
ADDED
@@ -0,0 +1,56 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Context
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Context
|
7 |
+
implements Ecocode_Profiler_Model_ContextInterface
|
8 |
+
{
|
9 |
+
protected $parentId = 0;
|
10 |
+
|
11 |
+
/** @var string */
|
12 |
+
protected $key;
|
13 |
+
|
14 |
+
/** @var string */
|
15 |
+
protected $data;
|
16 |
+
|
17 |
+
public function __construct($key, array $data = [])
|
18 |
+
{
|
19 |
+
$this->id = uniqid();
|
20 |
+
$this->key = $key;
|
21 |
+
$this->data = $data;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function getId()
|
25 |
+
{
|
26 |
+
return $this->id;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function getParentId()
|
30 |
+
{
|
31 |
+
return $this->parentId;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function setParentId($id)
|
35 |
+
{
|
36 |
+
$this->parentId = 0;
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
public function getKey()
|
41 |
+
{
|
42 |
+
return $this->key;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function addData($key, $value)
|
46 |
+
{
|
47 |
+
$this->data[$key] = $value;
|
48 |
+
|
49 |
+
return $this;
|
50 |
+
}
|
51 |
+
|
52 |
+
public function getData()
|
53 |
+
{
|
54 |
+
return $this->data;
|
55 |
+
}
|
56 |
+
}
|
app/code/community/Ecocode/Profiler/Model/ContextInterface.php
ADDED
@@ -0,0 +1,21 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Interface Ecocode_Profiler_Model_ContextInterface
|
5 |
+
*/
|
6 |
+
interface Ecocode_Profiler_Model_ContextInterface
|
7 |
+
{
|
8 |
+
|
9 |
+
public function getId();
|
10 |
+
|
11 |
+
public function getParentId();
|
12 |
+
|
13 |
+
public function setParentId($id);
|
14 |
+
|
15 |
+
public function getKey();
|
16 |
+
|
17 |
+
public function getData();
|
18 |
+
|
19 |
+
public function addData($key, $value);
|
20 |
+
|
21 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Core/Cache.php
ADDED
@@ -0,0 +1,46 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Core_Cache
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Core_Cache extends Mage_Core_Model_Cache
|
7 |
+
{
|
8 |
+
protected $log = [];
|
9 |
+
|
10 |
+
public function load($id)
|
11 |
+
{
|
12 |
+
$start = microtime(true);
|
13 |
+
$result = parent::load($id);
|
14 |
+
$execTime = microtime(true) - $start;
|
15 |
+
|
16 |
+
$this->log[] = ['action' => 'load', 'id' => $id, 'hit' => ($result !== false), 'time' => $execTime];
|
17 |
+
|
18 |
+
return $result;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function save($data, $id, $tags = [], $lifeTime = null)
|
22 |
+
{
|
23 |
+
$start = microtime(true);
|
24 |
+
$result = parent::save($data, $id, $tags, $lifeTime);
|
25 |
+
$execTime = microtime(true) - $start;
|
26 |
+
|
27 |
+
$this->log[] = ['action' => 'save', 'id' => $id, 'tags' => $tags, 'life_time' => $lifeTime, 'time' => $execTime];
|
28 |
+
return $result;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function clean($tags = [])
|
32 |
+
{
|
33 |
+
|
34 |
+
$loadTime = microtime(true);
|
35 |
+
$result = parent::clean($tags);
|
36 |
+
$execTime = microtime(true) - $loadTime;
|
37 |
+
$this->log[] = ['action' => 'clean', 'tags' => $tags, 'time' => $execTime];
|
38 |
+
|
39 |
+
return $result;
|
40 |
+
}
|
41 |
+
|
42 |
+
public function getLog()
|
43 |
+
{
|
44 |
+
return $this->log;
|
45 |
+
}
|
46 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Core/Config.php
ADDED
@@ -0,0 +1,56 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Core_Config
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Core_Config extends Mage_Core_Model_Config
|
7 |
+
{
|
8 |
+
|
9 |
+
public function loadBase()
|
10 |
+
{
|
11 |
+
parent::loadBase();
|
12 |
+
|
13 |
+
//needed as the mysql collector needs to log queries before the config is loaded!!!
|
14 |
+
$this->setNode('global/models/ecocode_profiler/class', 'Ecocode_Profiler_Model');
|
15 |
+
$this->setNode('global/helpers/ecocode_profiler/class', 'Ecocode_Profiler_Helper');
|
16 |
+
}
|
17 |
+
/**
|
18 |
+
* Load modules configuration
|
19 |
+
*
|
20 |
+
* @return Mage_Core_Model_Config
|
21 |
+
*/
|
22 |
+
public function loadModules()
|
23 |
+
{
|
24 |
+
parent::loadModules();
|
25 |
+
|
26 |
+
/* load development.xml for all modules if present */
|
27 |
+
$this->loadModulesConfiguration(['development.xml'], $this);
|
28 |
+
return $this;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function loadDb()
|
32 |
+
{
|
33 |
+
parent::loadDb();
|
34 |
+
|
35 |
+
//overwrite symlinks if needed
|
36 |
+
$this->enableSymlinks();
|
37 |
+
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function enableSymlinks()
|
42 |
+
{
|
43 |
+
$dir = $this->getModuleDir('etc', 'Ecocode_Profiler');
|
44 |
+
if (is_link($dir)) {
|
45 |
+
//due to magentos awesome "config->loadDb()" call we need to overwrite each store
|
46 |
+
//as the config gets copied over into all stores, so setting only the "default" is not enough
|
47 |
+
$this->setNode('default/dev/template/allow_symlink', true);
|
48 |
+
foreach($this->getNode('websites')->children() as $website) {
|
49 |
+
$website->setNode(Mage_Core_Block_Template::XML_PATH_TEMPLATE_ALLOW_SYMLINK, true);
|
50 |
+
}
|
51 |
+
foreach($this->getNode('stores')->children() as $store) {
|
52 |
+
$store->setNode(Mage_Core_Block_Template::XML_PATH_TEMPLATE_ALLOW_SYMLINK, true);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
app/code/community/Ecocode/Profiler/Model/DebugLoggerInterface.php
ADDED
@@ -0,0 +1,28 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
/**
|
5 |
+
* DebugLoggerInterface.
|
6 |
+
*
|
7 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
8 |
+
*/
|
9 |
+
interface Ecocode_Profiler_Model_DebugLoggerInterface
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Returns an array of logs.
|
13 |
+
*
|
14 |
+
* A log is an array with the following mandatory keys:
|
15 |
+
* timestamp, message, priority, and priorityName.
|
16 |
+
* It can also have an optional context key containing an array.
|
17 |
+
*
|
18 |
+
* @return array An array of logs
|
19 |
+
*/
|
20 |
+
public function getLogs();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Returns the number of errors.
|
24 |
+
*
|
25 |
+
* @return int The number of errors
|
26 |
+
*/
|
27 |
+
public function countErrors();
|
28 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Http/HeaderBag.php
ADDED
@@ -0,0 +1,322 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* HeaderBag is a container for HTTP headers.
|
14 |
+
*
|
15 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
16 |
+
*/
|
17 |
+
class Ecocode_Profiler_Model_Http_HeaderBag implements \IteratorAggregate, \Countable
|
18 |
+
{
|
19 |
+
protected $headers = [];
|
20 |
+
protected $cacheControl = [];
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Constructor.
|
24 |
+
*
|
25 |
+
* @param array $headers An array of HTTP headers
|
26 |
+
*/
|
27 |
+
public function __construct(array $headers = [])
|
28 |
+
{
|
29 |
+
foreach ($headers as $key => $values) {
|
30 |
+
$this->set($key, $values);
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Returns the headers as a string.
|
36 |
+
*
|
37 |
+
* @return string The headers
|
38 |
+
*/
|
39 |
+
public function __toString()
|
40 |
+
{
|
41 |
+
if (!$this->headers) {
|
42 |
+
return '';
|
43 |
+
}
|
44 |
+
|
45 |
+
$max = max(array_map('strlen', array_keys($this->headers))) + 1;
|
46 |
+
$content = '';
|
47 |
+
ksort($this->headers);
|
48 |
+
foreach ($this->headers as $name => $values) {
|
49 |
+
$name = implode('-', array_map('ucfirst', explode('-', $name)));
|
50 |
+
foreach ($values as $value) {
|
51 |
+
$content .= sprintf("%-{$max}s %s\r\n", $name . ':', $value);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
return $content;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Returns the headers.
|
60 |
+
*
|
61 |
+
* @return array An array of headers
|
62 |
+
*/
|
63 |
+
public function all()
|
64 |
+
{
|
65 |
+
return $this->headers;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Returns the parameter keys.
|
70 |
+
*
|
71 |
+
* @return array An array of parameter keys
|
72 |
+
*/
|
73 |
+
public function keys()
|
74 |
+
{
|
75 |
+
return array_keys($this->headers);
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Replaces the current HTTP headers by a new set.
|
80 |
+
*
|
81 |
+
* @param array $headers An array of HTTP headers
|
82 |
+
*/
|
83 |
+
public function replace(array $headers = [])
|
84 |
+
{
|
85 |
+
$this->headers = [];
|
86 |
+
$this->add($headers);
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Adds new headers the current HTTP headers set.
|
91 |
+
*
|
92 |
+
* @param array $headers An array of HTTP headers
|
93 |
+
*/
|
94 |
+
public function add(array $headers)
|
95 |
+
{
|
96 |
+
foreach ($headers as $key => $values) {
|
97 |
+
$this->set($key, $values);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns a header value by name.
|
103 |
+
*
|
104 |
+
* @param string $key The header name
|
105 |
+
* @param mixed $default The default value
|
106 |
+
* @param bool $first Whether to return the first value or all header values
|
107 |
+
*
|
108 |
+
* @return string|array The first header value if $first is true, an array of values otherwise
|
109 |
+
*/
|
110 |
+
public function get($key, $default = null, $first = true)
|
111 |
+
{
|
112 |
+
$key = str_replace('_', '-', strtolower($key));
|
113 |
+
|
114 |
+
if (!array_key_exists($key, $this->headers)) {
|
115 |
+
if (null === $default) {
|
116 |
+
return $first ? null : [];
|
117 |
+
}
|
118 |
+
|
119 |
+
return $first ? $default : [$default];
|
120 |
+
}
|
121 |
+
|
122 |
+
if ($first) {
|
123 |
+
return count($this->headers[$key]) ? $this->headers[$key][0] : $default;
|
124 |
+
}
|
125 |
+
|
126 |
+
return $this->headers[$key];
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Sets a header by name.
|
131 |
+
*
|
132 |
+
* @param string $key The key
|
133 |
+
* @param string|array $values The value or an array of values
|
134 |
+
* @param bool $replace Whether to replace the actual value or not (true by default)
|
135 |
+
*/
|
136 |
+
public function set($key, $values, $replace = true)
|
137 |
+
{
|
138 |
+
$key = str_replace('_', '-', strtolower($key));
|
139 |
+
|
140 |
+
$values = array_values((array)$values);
|
141 |
+
|
142 |
+
if (true === $replace || !isset($this->headers[$key])) {
|
143 |
+
$this->headers[$key] = $values;
|
144 |
+
} else {
|
145 |
+
$this->headers[$key] = array_merge($this->headers[$key], $values);
|
146 |
+
}
|
147 |
+
|
148 |
+
if ('cache-control' === $key) {
|
149 |
+
$this->cacheControl = $this->parseCacheControl($values[0]);
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Returns true if the HTTP header is defined.
|
155 |
+
*
|
156 |
+
* @param string $key The HTTP header
|
157 |
+
*
|
158 |
+
* @return bool true if the parameter exists, false otherwise
|
159 |
+
*/
|
160 |
+
public function has($key)
|
161 |
+
{
|
162 |
+
return array_key_exists(str_replace('_', '-', strtolower($key)), $this->headers);
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Returns true if the given HTTP header contains the given value.
|
167 |
+
*
|
168 |
+
* @param string $key The HTTP header name
|
169 |
+
* @param string $value The HTTP value
|
170 |
+
*
|
171 |
+
* @return bool true if the value is contained in the header, false otherwise
|
172 |
+
*/
|
173 |
+
public function contains($key, $value)
|
174 |
+
{
|
175 |
+
return in_array($value, $this->get($key, null, false));
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Removes a header.
|
180 |
+
*
|
181 |
+
* @param string $key The HTTP header name
|
182 |
+
*/
|
183 |
+
public function remove($key)
|
184 |
+
{
|
185 |
+
$key = str_replace('_', '-', strtolower($key));
|
186 |
+
|
187 |
+
unset($this->headers[$key]);
|
188 |
+
|
189 |
+
if ('cache-control' === $key) {
|
190 |
+
$this->cacheControl = [];
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Returns the HTTP header value converted to a date.
|
196 |
+
*
|
197 |
+
* @param string $key The parameter key
|
198 |
+
* @param \DateTime $default The default value
|
199 |
+
*
|
200 |
+
* @return null|\DateTime The parsed DateTime or the default value if the header does not exist
|
201 |
+
*
|
202 |
+
* @throws \RuntimeException When the HTTP header is not parseable
|
203 |
+
*/
|
204 |
+
public function getDate($key, \DateTime $default = null)
|
205 |
+
{
|
206 |
+
if (null === $value = $this->get($key)) {
|
207 |
+
return $default;
|
208 |
+
}
|
209 |
+
|
210 |
+
if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
|
211 |
+
throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
|
212 |
+
}
|
213 |
+
|
214 |
+
return $date;
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Adds a custom Cache-Control directive.
|
219 |
+
*
|
220 |
+
* @param string $key The Cache-Control directive name
|
221 |
+
* @param mixed $value The Cache-Control directive value
|
222 |
+
*/
|
223 |
+
public function addCacheControlDirective($key, $value = true)
|
224 |
+
{
|
225 |
+
$this->cacheControl[$key] = $value;
|
226 |
+
|
227 |
+
$this->set('Cache-Control', $this->getCacheControlHeader());
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Returns true if the Cache-Control directive is defined.
|
232 |
+
*
|
233 |
+
* @param string $key The Cache-Control directive
|
234 |
+
*
|
235 |
+
* @return bool true if the directive exists, false otherwise
|
236 |
+
*/
|
237 |
+
public function hasCacheControlDirective($key)
|
238 |
+
{
|
239 |
+
return array_key_exists($key, $this->cacheControl);
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Returns a Cache-Control directive value by name.
|
244 |
+
*
|
245 |
+
* @param string $key The directive name
|
246 |
+
*
|
247 |
+
* @return mixed|null The directive value if defined, null otherwise
|
248 |
+
*/
|
249 |
+
public function getCacheControlDirective($key)
|
250 |
+
{
|
251 |
+
return array_key_exists($key, $this->cacheControl) ? $this->cacheControl[$key] : null;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Removes a Cache-Control directive.
|
256 |
+
*
|
257 |
+
* @param string $key The Cache-Control directive
|
258 |
+
*/
|
259 |
+
public function removeCacheControlDirective($key)
|
260 |
+
{
|
261 |
+
unset($this->cacheControl[$key]);
|
262 |
+
|
263 |
+
$this->set('Cache-Control', $this->getCacheControlHeader());
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Returns an iterator for headers.
|
268 |
+
*
|
269 |
+
* @return \ArrayIterator An \ArrayIterator instance
|
270 |
+
*/
|
271 |
+
public function getIterator()
|
272 |
+
{
|
273 |
+
return new \ArrayIterator($this->headers);
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Returns the number of headers.
|
278 |
+
*
|
279 |
+
* @return int The number of headers
|
280 |
+
*/
|
281 |
+
public function count()
|
282 |
+
{
|
283 |
+
return count($this->headers);
|
284 |
+
}
|
285 |
+
|
286 |
+
protected function getCacheControlHeader()
|
287 |
+
{
|
288 |
+
$parts = [];
|
289 |
+
ksort($this->cacheControl);
|
290 |
+
foreach ($this->cacheControl as $key => $value) {
|
291 |
+
if (true === $value) {
|
292 |
+
$parts[] = $key;
|
293 |
+
} else {
|
294 |
+
if (preg_match('#[^a-zA-Z0-9._-]#', $value)) {
|
295 |
+
$value = '"' . $value . '"';
|
296 |
+
}
|
297 |
+
|
298 |
+
$parts[] = "$key=$value";
|
299 |
+
}
|
300 |
+
}
|
301 |
+
|
302 |
+
return implode(', ', $parts);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Parses a Cache-Control HTTP header.
|
307 |
+
*
|
308 |
+
* @param string $header The value of the Cache-Control HTTP header
|
309 |
+
*
|
310 |
+
* @return array An array representing the attribute values
|
311 |
+
*/
|
312 |
+
protected function parseCacheControl($header)
|
313 |
+
{
|
314 |
+
$cacheControl = [];
|
315 |
+
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
316 |
+
foreach ($matches as $match) {
|
317 |
+
$cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
|
318 |
+
}
|
319 |
+
|
320 |
+
return $cacheControl;
|
321 |
+
}
|
322 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Http/ParameterBag.php
ADDED
@@ -0,0 +1,235 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* This file is part of the Symfony package.
|
4 |
+
*
|
5 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
6 |
+
*
|
7 |
+
* For the full copyright and license information, please view the LICENSE
|
8 |
+
* file that was distributed with this source code.
|
9 |
+
*/
|
10 |
+
|
11 |
+
/**
|
12 |
+
* ParameterBag is a container for key/value pairs.
|
13 |
+
*
|
14 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
15 |
+
*/
|
16 |
+
class Ecocode_Profiler_Model_Http_ParameterBag implements \IteratorAggregate, \Countable
|
17 |
+
{
|
18 |
+
/**
|
19 |
+
* Parameter storage.
|
20 |
+
*
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
protected $parameters;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Constructor.
|
27 |
+
*
|
28 |
+
* @param array $parameters An array of parameters
|
29 |
+
*/
|
30 |
+
public function __construct(array $parameters = [])
|
31 |
+
{
|
32 |
+
$this->parameters = $parameters;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Returns the parameters.
|
37 |
+
*
|
38 |
+
* @return array An array of parameters
|
39 |
+
*/
|
40 |
+
public function all()
|
41 |
+
{
|
42 |
+
return $this->parameters;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Returns the parameter keys.
|
47 |
+
*
|
48 |
+
* @return array An array of parameter keys
|
49 |
+
*/
|
50 |
+
public function keys()
|
51 |
+
{
|
52 |
+
return array_keys($this->parameters);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Replaces the current parameters by a new set.
|
57 |
+
*
|
58 |
+
* @param array $parameters An array of parameters
|
59 |
+
*/
|
60 |
+
public function replace(array $parameters = [])
|
61 |
+
{
|
62 |
+
$this->parameters = $parameters;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Adds parameters.
|
67 |
+
*
|
68 |
+
* @param array $parameters An array of parameters
|
69 |
+
*/
|
70 |
+
public function add(array $parameters = [])
|
71 |
+
{
|
72 |
+
$this->parameters = array_replace($this->parameters, $parameters);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Returns a parameter by name.
|
77 |
+
*
|
78 |
+
* @param string $key The key
|
79 |
+
* @param mixed $default The default value if the parameter key does not exist
|
80 |
+
*
|
81 |
+
* @return mixed
|
82 |
+
*/
|
83 |
+
public function get($key, $default = null)
|
84 |
+
{
|
85 |
+
return array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Sets a parameter by name.
|
90 |
+
*
|
91 |
+
* @param string $key The key
|
92 |
+
* @param mixed $value The value
|
93 |
+
*/
|
94 |
+
public function set($key, $value)
|
95 |
+
{
|
96 |
+
$this->parameters[$key] = $value;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Returns true if the parameter is defined.
|
101 |
+
*
|
102 |
+
* @param string $key The key
|
103 |
+
*
|
104 |
+
* @return bool true if the parameter exists, false otherwise
|
105 |
+
*/
|
106 |
+
public function has($key)
|
107 |
+
{
|
108 |
+
return array_key_exists($key, $this->parameters);
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Removes a parameter.
|
113 |
+
*
|
114 |
+
* @param string $key The key
|
115 |
+
*/
|
116 |
+
public function remove($key)
|
117 |
+
{
|
118 |
+
unset($this->parameters[$key]);
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Returns the alphabetic characters of the parameter value.
|
123 |
+
*
|
124 |
+
* @param string $key The parameter key
|
125 |
+
* @param string $default The default value if the parameter key does not exist
|
126 |
+
*
|
127 |
+
* @return string The filtered value
|
128 |
+
*/
|
129 |
+
public function getAlpha($key, $default = '')
|
130 |
+
{
|
131 |
+
return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Returns the alphabetic characters and digits of the parameter value.
|
136 |
+
*
|
137 |
+
* @param string $key The parameter key
|
138 |
+
* @param string $default The default value if the parameter key does not exist
|
139 |
+
*
|
140 |
+
* @return string The filtered value
|
141 |
+
*/
|
142 |
+
public function getAlnum($key, $default = '')
|
143 |
+
{
|
144 |
+
return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Returns the digits of the parameter value.
|
149 |
+
*
|
150 |
+
* @param string $key The parameter key
|
151 |
+
* @param string $default The default value if the parameter key does not exist
|
152 |
+
*
|
153 |
+
* @return string The filtered value
|
154 |
+
*/
|
155 |
+
public function getDigits($key, $default = '')
|
156 |
+
{
|
157 |
+
// we need to remove - and + because they're allowed in the filter
|
158 |
+
return str_replace(['-', '+'], '', $this->filter($key, $default, FILTER_SANITIZE_NUMBER_INT));
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Returns the parameter value converted to integer.
|
163 |
+
*
|
164 |
+
* @param string $key The parameter key
|
165 |
+
* @param int $default The default value if the parameter key does not exist
|
166 |
+
*
|
167 |
+
* @return int The filtered value
|
168 |
+
*/
|
169 |
+
public function getInt($key, $default = 0)
|
170 |
+
{
|
171 |
+
return (int)$this->get($key, $default);
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Returns the parameter value converted to boolean.
|
176 |
+
*
|
177 |
+
* @param string $key The parameter key
|
178 |
+
* @param mixed $default The default value if the parameter key does not exist
|
179 |
+
*
|
180 |
+
* @return bool The filtered value
|
181 |
+
*/
|
182 |
+
public function getBoolean($key, $default = false)
|
183 |
+
{
|
184 |
+
return $this->filter($key, $default, FILTER_VALIDATE_BOOLEAN);
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Filter key.
|
189 |
+
*
|
190 |
+
* @param string $key Key
|
191 |
+
* @param mixed $default Default = null
|
192 |
+
* @param int $filter FILTER_* constant
|
193 |
+
* @param mixed $options Filter options
|
194 |
+
*
|
195 |
+
* @see http://php.net/manual/en/function.filter-var.php
|
196 |
+
*
|
197 |
+
* @return mixed
|
198 |
+
*/
|
199 |
+
public function filter($key, $default = null, $filter = FILTER_DEFAULT, $options = [])
|
200 |
+
{
|
201 |
+
$value = $this->get($key, $default);
|
202 |
+
|
203 |
+
// Always turn $options into an array - this allows filter_var option shortcuts.
|
204 |
+
if (!is_array($options) && $options) {
|
205 |
+
$options = ['flags' => $options];
|
206 |
+
}
|
207 |
+
|
208 |
+
// Add a convenience check for arrays.
|
209 |
+
if (is_array($value) && !isset($options['flags'])) {
|
210 |
+
$options['flags'] = FILTER_REQUIRE_ARRAY;
|
211 |
+
}
|
212 |
+
|
213 |
+
return filter_var($value, $filter, $options);
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Returns an iterator for parameters.
|
218 |
+
*
|
219 |
+
* @return \ArrayIterator An \ArrayIterator instance
|
220 |
+
*/
|
221 |
+
public function getIterator()
|
222 |
+
{
|
223 |
+
return new \ArrayIterator($this->parameters);
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Returns the number of parameters.
|
228 |
+
*
|
229 |
+
* @return int The number of parameters
|
230 |
+
*/
|
231 |
+
public function count()
|
232 |
+
{
|
233 |
+
return count($this->parameters);
|
234 |
+
}
|
235 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Http/ResponseHeaderBag.php
ADDED
@@ -0,0 +1,240 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* ResponseHeaderBag is a container for Response HTTP headers.
|
15 |
+
*
|
16 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
17 |
+
*/
|
18 |
+
class Ecocode_Profiler_Model_Http_ResponseHeaderBag
|
19 |
+
extends Ecocode_Profiler_Model_Http_HeaderBag
|
20 |
+
{
|
21 |
+
const COOKIES_FLAT = 'flat';
|
22 |
+
const COOKIES_ARRAY = 'array';
|
23 |
+
|
24 |
+
const DISPOSITION_ATTACHMENT = 'attachment';
|
25 |
+
const DISPOSITION_INLINE = 'inline';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
protected $computedCacheControl = [];
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var array
|
34 |
+
*/
|
35 |
+
protected $cookies = [];
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var array
|
39 |
+
*/
|
40 |
+
protected $headerNames = [];
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Constructor.
|
44 |
+
*
|
45 |
+
* @param array $headers An array of HTTP headers
|
46 |
+
*/
|
47 |
+
public function __construct(array $headers = [])
|
48 |
+
{
|
49 |
+
parent::__construct($headers);
|
50 |
+
|
51 |
+
if (!isset($this->headers['cache-control'])) {
|
52 |
+
$this->set('Cache-Control', '');
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* {@inheritdoc}
|
58 |
+
*/
|
59 |
+
public function __toString()
|
60 |
+
{
|
61 |
+
$cookies = '';
|
62 |
+
foreach ($this->getCookies() as $cookie) {
|
63 |
+
$cookies .= 'Set-Cookie: ' . $cookie . "\r\n";
|
64 |
+
}
|
65 |
+
|
66 |
+
ksort($this->headerNames);
|
67 |
+
|
68 |
+
return parent::__toString() . $cookies;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns the headers, with original capitalizations.
|
73 |
+
*
|
74 |
+
* @return array An array of headers
|
75 |
+
*/
|
76 |
+
public function allPreserveCase()
|
77 |
+
{
|
78 |
+
return array_combine($this->headerNames, $this->headers);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* {@inheritdoc}
|
83 |
+
*/
|
84 |
+
public function replace(array $headers = [])
|
85 |
+
{
|
86 |
+
$this->headerNames = [];
|
87 |
+
|
88 |
+
parent::replace($headers);
|
89 |
+
|
90 |
+
if (!isset($this->headers['cache-control'])) {
|
91 |
+
$this->set('Cache-Control', '');
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* {@inheritdoc}
|
97 |
+
*/
|
98 |
+
public function set($key, $values, $replace = true)
|
99 |
+
{
|
100 |
+
parent::set($key, $values, $replace);
|
101 |
+
|
102 |
+
$uniqueKey = str_replace('_', '-', strtolower($key));
|
103 |
+
$this->headerNames[$uniqueKey] = $key;
|
104 |
+
|
105 |
+
// ensure the cache-control header has sensible defaults
|
106 |
+
if (in_array($uniqueKey, ['cache-control', 'etag', 'last-modified', 'expires'])) {
|
107 |
+
$computed = $this->computeCacheControlValue();
|
108 |
+
$this->headers['cache-control'] = [$computed];
|
109 |
+
$this->headerNames['cache-control'] = 'Cache-Control';
|
110 |
+
$this->computedCacheControl = $this->parseCacheControl($computed);
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* {@inheritdoc}
|
116 |
+
*/
|
117 |
+
public function remove($key)
|
118 |
+
{
|
119 |
+
parent::remove($key);
|
120 |
+
|
121 |
+
$uniqueKey = str_replace('_', '-', strtolower($key));
|
122 |
+
unset($this->headerNames[$uniqueKey]);
|
123 |
+
|
124 |
+
if ('cache-control' === $uniqueKey) {
|
125 |
+
$this->computedCacheControl = [];
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Returns an array with all cookies.
|
131 |
+
*
|
132 |
+
* @param string $format
|
133 |
+
*
|
134 |
+
* @return array
|
135 |
+
*
|
136 |
+
* @throws \InvalidArgumentException When the $format is invalid
|
137 |
+
*/
|
138 |
+
public function getCookies($format = self::COOKIES_FLAT)
|
139 |
+
{
|
140 |
+
if (!in_array($format, [self::COOKIES_FLAT, self::COOKIES_ARRAY])) {
|
141 |
+
throw new \InvalidArgumentException(sprintf('Format "%s" invalid (%s).', $format, implode(', ', [self::COOKIES_FLAT, self::COOKIES_ARRAY])));
|
142 |
+
}
|
143 |
+
|
144 |
+
if (self::COOKIES_ARRAY === $format) {
|
145 |
+
return $this->cookies;
|
146 |
+
}
|
147 |
+
|
148 |
+
$flattenedCookies = [];
|
149 |
+
foreach ($this->cookies as $path) {
|
150 |
+
foreach ($path as $cookies) {
|
151 |
+
foreach ($cookies as $cookie) {
|
152 |
+
$flattenedCookies[] = $cookie;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
return $flattenedCookies;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Generates a HTTP Content-Disposition field-value.
|
162 |
+
*
|
163 |
+
* @param string $disposition One of "inline" or "attachment"
|
164 |
+
* @param string $filename A unicode string
|
165 |
+
* @param string $filenameFallback A string containing only ASCII characters that
|
166 |
+
* is semantically equivalent to $filename. If the filename is already ASCII,
|
167 |
+
* it can be omitted, or just copied from $filename
|
168 |
+
*
|
169 |
+
* @return string A string suitable for use as a Content-Disposition field-value
|
170 |
+
*
|
171 |
+
* @throws \InvalidArgumentException
|
172 |
+
*
|
173 |
+
* @see RFC 6266
|
174 |
+
*/
|
175 |
+
public function makeDisposition($disposition, $filename, $filenameFallback = '')
|
176 |
+
{
|
177 |
+
if (!in_array($disposition, [self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE])) {
|
178 |
+
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
|
179 |
+
}
|
180 |
+
|
181 |
+
if ('' == $filenameFallback) {
|
182 |
+
$filenameFallback = $filename;
|
183 |
+
}
|
184 |
+
|
185 |
+
// filenameFallback is not ASCII.
|
186 |
+
if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
|
187 |
+
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
|
188 |
+
}
|
189 |
+
|
190 |
+
// percent characters aren't safe in fallback.
|
191 |
+
if (false !== strpos($filenameFallback, '%')) {
|
192 |
+
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
|
193 |
+
}
|
194 |
+
|
195 |
+
// path separators aren't allowed in either.
|
196 |
+
if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
|
197 |
+
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
|
198 |
+
}
|
199 |
+
|
200 |
+
$output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
|
201 |
+
|
202 |
+
if ($filename !== $filenameFallback) {
|
203 |
+
$output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename));
|
204 |
+
}
|
205 |
+
|
206 |
+
return $output;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Returns the calculated value of the cache-control header.
|
211 |
+
*
|
212 |
+
* This considers several other headers and calculates or modifies the
|
213 |
+
* cache-control header to a sensible, conservative value.
|
214 |
+
*
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
protected function computeCacheControlValue()
|
218 |
+
{
|
219 |
+
if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
|
220 |
+
return 'no-cache';
|
221 |
+
}
|
222 |
+
|
223 |
+
if (!$this->cacheControl) {
|
224 |
+
// conservative by default
|
225 |
+
return 'private, must-revalidate';
|
226 |
+
}
|
227 |
+
|
228 |
+
$header = $this->getCacheControlHeader();
|
229 |
+
if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
|
230 |
+
return $header;
|
231 |
+
}
|
232 |
+
|
233 |
+
// public if s-maxage is defined, private otherwise
|
234 |
+
if (!isset($this->cacheControl['s-maxage'])) {
|
235 |
+
return $header . ', private';
|
236 |
+
}
|
237 |
+
|
238 |
+
return $header;
|
239 |
+
}
|
240 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Logger.php
ADDED
@@ -0,0 +1,79 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
use Monolog\Logger as BaseLogger;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Logger.
|
16 |
+
*
|
17 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
18 |
+
*/
|
19 |
+
class Ecocode_Profiler_Model_Logger
|
20 |
+
extends BaseLogger
|
21 |
+
implements Ecocode_Profiler_Model_DebugLoggerInterface
|
22 |
+
{
|
23 |
+
|
24 |
+
protected static $levelMap = [
|
25 |
+
Zend_Log::DEBUG => self::DEBUG,
|
26 |
+
Zend_Log::INFO => self::INFO,
|
27 |
+
Zend_Log::NOTICE => self::NOTICE,
|
28 |
+
Zend_Log::WARN => self::WARNING,
|
29 |
+
Zend_Log::ERR => self::ERROR,
|
30 |
+
Zend_Log::CRIT => self::CRITICAL,
|
31 |
+
Zend_Log::ALERT => self::ALERT,
|
32 |
+
Zend_Log::EMERG => self::EMERGENCY
|
33 |
+
];
|
34 |
+
|
35 |
+
|
36 |
+
public function mageLog($level, $message, array $context = [])
|
37 |
+
{
|
38 |
+
$level = self::$levelMap[$level];
|
39 |
+
return $this->log($level, $message, $context);
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* {@inheritdoc}
|
44 |
+
*/
|
45 |
+
public function getLogs()
|
46 |
+
{
|
47 |
+
if ($logger = $this->getDebugLogger()) {
|
48 |
+
return $logger->getLogs();
|
49 |
+
}
|
50 |
+
|
51 |
+
return [];
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* {@inheritdoc}
|
56 |
+
*/
|
57 |
+
public function countErrors()
|
58 |
+
{
|
59 |
+
if ($logger = $this->getDebugLogger()) {
|
60 |
+
return $logger->countErrors();
|
61 |
+
}
|
62 |
+
|
63 |
+
return 0;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Returns a DebugLoggerInterface instance if one is registered with this logger.
|
68 |
+
*
|
69 |
+
* @return Ecocode_Profiler_Model_DebugLoggerInterface|null A DebugLoggerInterface instance or null if none is registered
|
70 |
+
*/
|
71 |
+
private function getDebugLogger()
|
72 |
+
{
|
73 |
+
foreach ($this->handlers as $handler) {
|
74 |
+
if ($handler instanceof Ecocode_Profiler_Model_DebugLoggerInterface) {
|
75 |
+
return $handler;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Logger/DebugHandler.php
ADDED
@@ -0,0 +1,60 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
use Monolog\Logger;
|
14 |
+
use Monolog\Handler\TestHandler;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* DebugLogger.
|
18 |
+
*
|
19 |
+
* @author Jordi Boggiano <j.boggiano@seld.be>
|
20 |
+
*/
|
21 |
+
class Ecocode_Profiler_Model_Logger_DebugHandler extends TestHandler
|
22 |
+
implements Ecocode_Profiler_Model_DebugLoggerInterface
|
23 |
+
{
|
24 |
+
/**
|
25 |
+
* {@inheritdoc}
|
26 |
+
*/
|
27 |
+
public function getLogs()
|
28 |
+
{
|
29 |
+
$records = [];
|
30 |
+
foreach ($this->records as $record) {
|
31 |
+
$records[] = [
|
32 |
+
'timestamp' => $record['datetime']->getTimestamp(),
|
33 |
+
'message' => $record['message'],
|
34 |
+
'priority' => $record['level'],
|
35 |
+
'priorityName' => $record['level_name'],
|
36 |
+
'context' => $record['context'],
|
37 |
+
'channel' => isset($record['channel']) ? $record['channel'] : '',
|
38 |
+
];
|
39 |
+
}
|
40 |
+
|
41 |
+
return $records;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* {@inheritdoc}
|
46 |
+
*/
|
47 |
+
public function countErrors()
|
48 |
+
{
|
49 |
+
$cnt = 0;
|
50 |
+
$levels = [Logger::ERROR, Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY];
|
51 |
+
foreach ($levels as $level) {
|
52 |
+
if (isset($this->recordsByLevel[$level])) {
|
53 |
+
$cnt += count($this->recordsByLevel[$level]);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
return $cnt;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
app/code/community/Ecocode/Profiler/Model/Observer.php
ADDED
@@ -0,0 +1,116 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Observer
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Observer
|
7 |
+
{
|
8 |
+
/** @var Ecocode_Profiler_Model_Profiler */
|
9 |
+
protected $profiler;
|
10 |
+
|
11 |
+
protected $profiles;
|
12 |
+
|
13 |
+
public function __construct()
|
14 |
+
{
|
15 |
+
$this->profiles = new \SplObjectStorage();
|
16 |
+
}
|
17 |
+
|
18 |
+
public function controllerFrontSendResponseBefore(Varien_Event_Observer $observer)
|
19 |
+
{
|
20 |
+
if (!$this->getProfiler()->isEnabled()) {
|
21 |
+
return;
|
22 |
+
}
|
23 |
+
|
24 |
+
$event = $observer->getEvent();
|
25 |
+
/** @var Mage_Core_Controller_Varien_Front $front */
|
26 |
+
$front = $event->getData('front');
|
27 |
+
$request = $front->getRequest();
|
28 |
+
$response = $front->getResponse();
|
29 |
+
$profile = $this->getProfiler()->collect($front->getRequest(), $response);
|
30 |
+
if ($profile) {
|
31 |
+
$this->profiles[$request] = $profile;
|
32 |
+
}
|
33 |
+
|
34 |
+
$token = null;
|
35 |
+
foreach ($response->getHeaders() as $header) {
|
36 |
+
if ($header['name'] === 'X-Debug-Token') {
|
37 |
+
$token = $header['value'];
|
38 |
+
break;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
if ($token) {
|
43 |
+
$url = Mage::helper('ecocode_profiler')->getUrl($token);
|
44 |
+
$response->setHeader('X-Debug-Token-Link', $url);
|
45 |
+
}
|
46 |
+
|
47 |
+
$this->injectToolbar($response, $request, $token);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function onTerminate()
|
51 |
+
{
|
52 |
+
foreach ($this->profiles as $request) {
|
53 |
+
$this->getProfiler()->saveProfile($this->profiles[$request]);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Injects the web debug toolbar into the given Response.
|
59 |
+
*
|
60 |
+
* @param Mage_Core_Controller_Response_Http $response A Response instance
|
61 |
+
* @param Mage_Core_Controller_Request_Http $request
|
62 |
+
* @param null $token
|
63 |
+
*/
|
64 |
+
protected function injectToolbar(
|
65 |
+
Mage_Core_Controller_Response_Http $response,
|
66 |
+
Mage_Core_Controller_Request_Http $request,
|
67 |
+
$token = null
|
68 |
+
)
|
69 |
+
{
|
70 |
+
$content = $response->getBody();
|
71 |
+
$pos = strripos($content, '</body>');
|
72 |
+
|
73 |
+
if (false !== $pos) {
|
74 |
+
$layout = $this->getLayout();
|
75 |
+
/** @var Ecocode_Profiler_Block_Toolbar $toolbarBlock */
|
76 |
+
$toolbarBlock = $layout
|
77 |
+
->createBlock('ecocode_profiler/toolbar', 'profiler_toolbar')
|
78 |
+
->setData([
|
79 |
+
'token' => $token,
|
80 |
+
'request' => $request,
|
81 |
+
]);
|
82 |
+
|
83 |
+
$baseJsBlock = $layout->createBlock('core/template', 'profiler_base_js')
|
84 |
+
->setTemplate('ecocode_profiler/profiler/base.js.phtml');
|
85 |
+
|
86 |
+
$toolbarBlock->setChild('base_js', $baseJsBlock);
|
87 |
+
|
88 |
+
$toolbar = "\n" . str_replace("\n", '', $toolbarBlock->toHtml()) . "\n";
|
89 |
+
$content = substr($content, 0, $pos) . $toolbar . substr($content, $pos);
|
90 |
+
$response->setBody($content);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @codeCoverageIgnore
|
96 |
+
* @return Ecocode_Profiler_Model_Profiler
|
97 |
+
*/
|
98 |
+
protected function getProfiler()
|
99 |
+
{
|
100 |
+
if (!$this->profiler) {
|
101 |
+
$this->profiler = Mage::getSingleton('ecocode_profiler/profiler');
|
102 |
+
}
|
103 |
+
|
104 |
+
return $this->profiler;
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @codeCoverageIgnore
|
110 |
+
* @return Mage_Core_Model_Layout
|
111 |
+
*/
|
112 |
+
protected function getLayout()
|
113 |
+
{
|
114 |
+
return Mage::app()->getLayout();
|
115 |
+
}
|
116 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Observer/Context.php
ADDED
@@ -0,0 +1,55 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Observer_Context
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Observer_Context
|
7 |
+
{
|
8 |
+
protected $helper;
|
9 |
+
|
10 |
+
|
11 |
+
public function openBlockContext(Varien_Event_Observer $observer)
|
12 |
+
{
|
13 |
+
$event = $observer->getEvent();
|
14 |
+
$block = $event->getData('block');
|
15 |
+
|
16 |
+
$data = [
|
17 |
+
'class' => get_class($block),
|
18 |
+
'module' => $block->getModuleName()
|
19 |
+
];
|
20 |
+
|
21 |
+
$context = new Ecocode_Profiler_Model_Context('block::' . $block->getNameInLayout(), $data);
|
22 |
+
$block->setData('__context', $context);
|
23 |
+
|
24 |
+
$this->getHelper()
|
25 |
+
->open($context);
|
26 |
+
}
|
27 |
+
|
28 |
+
public function closeBlockContext(Varien_Event_Observer $observer)
|
29 |
+
{
|
30 |
+
$event = $observer->getEvent();
|
31 |
+
$block = $event->getData('block');
|
32 |
+
|
33 |
+
if ($context = $block->getData('__context')) {
|
34 |
+
if ($block instanceof Mage_Core_Block_Template) {
|
35 |
+
$context->addData('template', $block->getTemplate());
|
36 |
+
}
|
37 |
+
|
38 |
+
$this->getHelper()
|
39 |
+
->close($context);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @codeCoverageIgnore
|
45 |
+
* @return Ecocode_Profiler_Helper_Context
|
46 |
+
*/
|
47 |
+
public function getHelper()
|
48 |
+
{
|
49 |
+
if ($this->helper === null) {
|
50 |
+
$this->helper = Mage::helper('ecocode_profiler/context');
|
51 |
+
}
|
52 |
+
|
53 |
+
return $this->helper;
|
54 |
+
}
|
55 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Profile.php
ADDED
@@ -0,0 +1,289 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Profile.
|
5 |
+
*
|
6 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
7 |
+
*/
|
8 |
+
class Ecocode_Profiler_Model_Profile
|
9 |
+
{
|
10 |
+
protected $token;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var \Ecocode_Profiler_Model_Collector_DataCollectorInterface[]
|
14 |
+
*/
|
15 |
+
protected $collectors = array();
|
16 |
+
|
17 |
+
protected $ip;
|
18 |
+
protected $method;
|
19 |
+
protected $url;
|
20 |
+
protected $time;
|
21 |
+
protected $statusCode;
|
22 |
+
protected $collectTime;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var Ecocode_Profiler_Model_Profile
|
26 |
+
*/
|
27 |
+
protected $parent;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var Ecocode_Profiler_Model_Profile[]
|
31 |
+
*/
|
32 |
+
protected $children = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Constructor.
|
36 |
+
*
|
37 |
+
* @param string $token The token
|
38 |
+
*/
|
39 |
+
public function __construct($token)
|
40 |
+
{
|
41 |
+
$this->token = $token;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Gets the token.
|
46 |
+
*
|
47 |
+
* @return string The token
|
48 |
+
*/
|
49 |
+
public function getToken()
|
50 |
+
{
|
51 |
+
return $this->token;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Sets the parent token.
|
56 |
+
*
|
57 |
+
* @param Ecocode_Profiler_Model_Profile $parent The parent Profile
|
58 |
+
*/
|
59 |
+
public function setParent(Ecocode_Profiler_Model_Profile $parent)
|
60 |
+
{
|
61 |
+
$this->parent = $parent;
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Returns the parent profile.
|
66 |
+
*
|
67 |
+
* @return Ecocode_Profiler_Model_Profile The parent profile
|
68 |
+
*/
|
69 |
+
public function getParent()
|
70 |
+
{
|
71 |
+
return $this->parent;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Returns the parent token.
|
76 |
+
*
|
77 |
+
* @return null|string The parent token
|
78 |
+
*/
|
79 |
+
public function getParentToken()
|
80 |
+
{
|
81 |
+
return $this->parent ? $this->parent->getToken() : null;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Returns the IP.
|
86 |
+
*
|
87 |
+
* @return string The IP
|
88 |
+
*/
|
89 |
+
public function getIp()
|
90 |
+
{
|
91 |
+
return $this->ip;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Sets the IP.
|
96 |
+
*
|
97 |
+
* @param string $ip
|
98 |
+
*/
|
99 |
+
public function setIp($ip)
|
100 |
+
{
|
101 |
+
$this->ip = $ip;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Returns the request method.
|
106 |
+
*
|
107 |
+
* @return string The request method
|
108 |
+
*/
|
109 |
+
public function getMethod()
|
110 |
+
{
|
111 |
+
return $this->method;
|
112 |
+
}
|
113 |
+
|
114 |
+
public function setMethod($method)
|
115 |
+
{
|
116 |
+
$this->method = $method;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Returns the URL.
|
121 |
+
*
|
122 |
+
* @return string The URL
|
123 |
+
*/
|
124 |
+
public function getUrl()
|
125 |
+
{
|
126 |
+
return $this->url;
|
127 |
+
}
|
128 |
+
|
129 |
+
public function setUrl($url)
|
130 |
+
{
|
131 |
+
$this->url = $url;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Returns the time.
|
136 |
+
*
|
137 |
+
* @return string The time
|
138 |
+
*/
|
139 |
+
public function getTime()
|
140 |
+
{
|
141 |
+
if (null === $this->time) {
|
142 |
+
return 0;
|
143 |
+
}
|
144 |
+
|
145 |
+
return $this->time;
|
146 |
+
}
|
147 |
+
|
148 |
+
public function setTime($time)
|
149 |
+
{
|
150 |
+
$this->time = $time;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @param int $statusCode
|
155 |
+
*/
|
156 |
+
public function setStatusCode($statusCode)
|
157 |
+
{
|
158 |
+
$this->statusCode = $statusCode;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @return int
|
163 |
+
*/
|
164 |
+
public function getStatusCode()
|
165 |
+
{
|
166 |
+
return $this->statusCode;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* @return int
|
171 |
+
*/
|
172 |
+
public function getCollectTime()
|
173 |
+
{
|
174 |
+
return $this->collectTime;
|
175 |
+
}
|
176 |
+
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @param $time
|
180 |
+
* @return int
|
181 |
+
*/
|
182 |
+
public function setCollectTime($time)
|
183 |
+
{
|
184 |
+
return $this->collectTime = $time;
|
185 |
+
}
|
186 |
+
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Finds children profilers.
|
190 |
+
*
|
191 |
+
* @return Ecocode_Profiler_Model_Profile[] An array of Profile
|
192 |
+
*/
|
193 |
+
public function getChildren()
|
194 |
+
{
|
195 |
+
return $this->children;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Sets children profiler.
|
200 |
+
*
|
201 |
+
* @param Ecocode_Profiler_Model_Profile[] $children An array of Profile
|
202 |
+
*/
|
203 |
+
public function setChildren(array $children)
|
204 |
+
{
|
205 |
+
$this->children = array();
|
206 |
+
foreach ($children as $child) {
|
207 |
+
$this->addChild($child);
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Adds the child token.
|
213 |
+
*
|
214 |
+
* @param Ecocode_Profiler_Model_Profile $child The child Profile
|
215 |
+
*/
|
216 |
+
public function addChild(Ecocode_Profiler_Model_Profile $child)
|
217 |
+
{
|
218 |
+
$this->children[] = $child;
|
219 |
+
$child->setParent($this);
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Gets a Collector by name.
|
224 |
+
*
|
225 |
+
* @param string $name A collector name
|
226 |
+
*
|
227 |
+
* @return Ecocode_Profiler_Model_Collector_DataCollectorInterface A DataCollectorInterface instance
|
228 |
+
*
|
229 |
+
* @throws \InvalidArgumentException if the collector does not exist
|
230 |
+
*/
|
231 |
+
public function getCollector($name)
|
232 |
+
{
|
233 |
+
if (!isset($this->collectors[$name])) {
|
234 |
+
throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name));
|
235 |
+
}
|
236 |
+
|
237 |
+
return $this->collectors[$name];
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Gets the Collectors associated with this profile.
|
242 |
+
*
|
243 |
+
* @return Ecocode_Profiler_Model_Collector_DataCollectorInterface[]
|
244 |
+
*/
|
245 |
+
public function getCollectors()
|
246 |
+
{
|
247 |
+
return $this->collectors;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Sets the Collectors associated with this profile.
|
252 |
+
*
|
253 |
+
* @param Ecocode_Profiler_Model_Collector_DataCollectorInterface[] $collectors
|
254 |
+
*/
|
255 |
+
public function setCollectors(array $collectors)
|
256 |
+
{
|
257 |
+
$this->collectors = array();
|
258 |
+
foreach ($collectors as $collector) {
|
259 |
+
$this->addCollector($collector);
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Adds a Collector.
|
265 |
+
*
|
266 |
+
* @param Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector A Ecocode_Profiler_Model_Collector_DataCollectorInterface instance
|
267 |
+
*/
|
268 |
+
public function addCollector(Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector)
|
269 |
+
{
|
270 |
+
$this->collectors[$collector->getName()] = $collector;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Returns true if a Collector for the given name exists.
|
275 |
+
*
|
276 |
+
* @param string $name A collector name
|
277 |
+
*
|
278 |
+
* @return bool
|
279 |
+
*/
|
280 |
+
public function hasCollector($name)
|
281 |
+
{
|
282 |
+
return isset($this->collectors[$name]);
|
283 |
+
}
|
284 |
+
|
285 |
+
public function __sleep()
|
286 |
+
{
|
287 |
+
return array('token', 'parent', 'children', 'collectors', 'ip', 'method', 'url', 'time', 'statusCode', 'collectTime');
|
288 |
+
}
|
289 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Profiler.php
ADDED
@@ -0,0 +1,172 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Model_Profiler
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Model_Profiler
|
7 |
+
{
|
8 |
+
protected $storage;
|
9 |
+
|
10 |
+
protected $enabled = false;
|
11 |
+
protected $initialized = false;
|
12 |
+
protected $dataCollectors = null;
|
13 |
+
|
14 |
+
const URL_TOKEN_PARAMETER = 'eco_token';
|
15 |
+
|
16 |
+
public function __construct($storage = null)
|
17 |
+
{
|
18 |
+
if ($this->storage) {
|
19 |
+
$this->storage = $storage;
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
public function init()
|
24 |
+
{
|
25 |
+
$this->enable();
|
26 |
+
if (!$this->initialized) {
|
27 |
+
$this->initialized = true;
|
28 |
+
|
29 |
+
foreach ($this->getDataCollectors() as $dataCollector) {
|
30 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $dataCollector */
|
31 |
+
$dataCollector->init();
|
32 |
+
}
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
|
37 |
+
public function enable()
|
38 |
+
{
|
39 |
+
$this->enabled = true;
|
40 |
+
}
|
41 |
+
|
42 |
+
public function disable()
|
43 |
+
{
|
44 |
+
$this->enabled = false;
|
45 |
+
}
|
46 |
+
|
47 |
+
public function isEnabled()
|
48 |
+
{
|
49 |
+
return $this->enabled;
|
50 |
+
}
|
51 |
+
|
52 |
+
|
53 |
+
public function getDataCollectors()
|
54 |
+
{
|
55 |
+
if ($this->dataCollectors === null) {
|
56 |
+
$contextCollector = Mage::getSingleton('ecocode_profiler/collector_contextDataCollector');
|
57 |
+
$this->dataCollectors = [];
|
58 |
+
|
59 |
+
$this->dataCollectors[$contextCollector->getName()] = $contextCollector;
|
60 |
+
|
61 |
+
$collectors = Mage::getConfig()->getNode('ecocode/profiler/collectors')->asArray();
|
62 |
+
foreach ($collectors as $classGroup) {
|
63 |
+
$collector = Mage::getSingleton($classGroup);
|
64 |
+
if (!$collector instanceof Ecocode_Profiler_Model_Collector_DataCollectorInterface) {
|
65 |
+
throw new InvalidArgumentException('collector must implement "Ecocode_Profiler_Model_Collector_DataCollectorInterface"');
|
66 |
+
}
|
67 |
+
$this->dataCollectors[$collector->getName()] = $collector;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
return $this->dataCollectors;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param Mage_Core_Controller_Request_Http $request
|
76 |
+
* @param Mage_Core_Controller_Response_Http $response
|
77 |
+
* @return Ecocode_Profiler_Model_Profile|null
|
78 |
+
*/
|
79 |
+
public function collect(Mage_Core_Controller_Request_Http $request, Mage_Core_Controller_Response_Http $response)
|
80 |
+
{
|
81 |
+
if (false === $this->isEnabled()) {
|
82 |
+
return;
|
83 |
+
}
|
84 |
+
|
85 |
+
$start = microtime(true);
|
86 |
+
$profile = new Ecocode_Profiler_Model_Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
|
87 |
+
$profile->setTime(time());
|
88 |
+
$profile->setUrl($request->getRequestString() ? $request->getRequestString() : '/');
|
89 |
+
$profile->setMethod($request->getMethod());
|
90 |
+
$profile->setStatusCode($response->getHttpResponseCode());
|
91 |
+
$profile->setIp($request->getClientIp());
|
92 |
+
|
93 |
+
$response->setHeader('X-Debug-Token', $profile->getToken());
|
94 |
+
|
95 |
+
foreach ($this->getDataCollectors() as $collector) {
|
96 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */
|
97 |
+
$collector->collect($request, $response);
|
98 |
+
|
99 |
+
$profile->addCollector($collector);
|
100 |
+
}
|
101 |
+
$collectTime = microtime(true) - $start;
|
102 |
+
$profile->setCollectTime($collectTime);
|
103 |
+
|
104 |
+
return $profile;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Loads the Profile for the given token.
|
109 |
+
*
|
110 |
+
* @param string $token A token
|
111 |
+
*
|
112 |
+
* @return Ecocode_Profiler_Model_Profile A Profile instance
|
113 |
+
*/
|
114 |
+
public function loadProfile($token)
|
115 |
+
{
|
116 |
+
return $this->getStorage()->read($token);
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
public function find($ip, $url, $limit, $method, $start, $end)
|
121 |
+
{
|
122 |
+
return $this->getStorage()->find($ip, $url, $limit, $method, $this->getTimestamp($start), $this->getTimestamp($end));
|
123 |
+
}
|
124 |
+
|
125 |
+
public function saveProfile(Ecocode_Profiler_Model_Profile $profile)
|
126 |
+
{
|
127 |
+
if (false === $this->isEnabled()) {
|
128 |
+
return;
|
129 |
+
}
|
130 |
+
|
131 |
+
// late collect
|
132 |
+
foreach ($profile->getCollectors() as $collector) {
|
133 |
+
if ($collector instanceof Ecocode_Profiler_Model_Collector_LateDataCollectorInterface) {
|
134 |
+
$collector->lateCollect();
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
if (!$this->getStorage()->write($profile)) {
|
139 |
+
throw new Exception('Unable to store the profiler information.', ['configured_storage' => get_class($this->storage)]);
|
140 |
+
}
|
141 |
+
|
142 |
+
return true;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* @return Ecocode_Profiler_Model_Profiler_StorageInterface
|
147 |
+
*/
|
148 |
+
protected function getStorage()
|
149 |
+
{
|
150 |
+
if (!$this->storage) {
|
151 |
+
$baseDir = Mage::getBaseDir('var') . DS . '_profile';
|
152 |
+
$this->storage = Mage::getSingleton('ecocode_profiler/profiler_fileStorage', ['dsn' => 'file:' . $baseDir]);
|
153 |
+
}
|
154 |
+
|
155 |
+
return $this->storage;
|
156 |
+
}
|
157 |
+
|
158 |
+
private function getTimestamp($value)
|
159 |
+
{
|
160 |
+
if (null === $value || '' == $value) {
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
|
164 |
+
try {
|
165 |
+
$value = new \DateTime(is_numeric($value) ? '@' . $value : $value);
|
166 |
+
} catch (\Exception $e) {
|
167 |
+
return;
|
168 |
+
}
|
169 |
+
|
170 |
+
return $value->getTimestamp();
|
171 |
+
}
|
172 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Profiler/FileStorage.php
ADDED
@@ -0,0 +1,295 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Storage for profiler using files.
|
15 |
+
*
|
16 |
+
* @author Alexandre Salomé <alexandre.salome@gmail.com>
|
17 |
+
*/
|
18 |
+
class Ecocode_Profiler_Model_Profiler_FileStorage
|
19 |
+
implements Ecocode_Profiler_Model_Profiler_StorageInterface
|
20 |
+
{
|
21 |
+
/**
|
22 |
+
* Folder where profiler data are stored.
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $folder;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Constructs the file storage using a "dsn-like" path.
|
30 |
+
*
|
31 |
+
* Example : "file:/path/to/the/storage/folder"
|
32 |
+
*
|
33 |
+
* @param array $config
|
34 |
+
* @internal param string $dsn The DSN
|
35 |
+
*
|
36 |
+
*/
|
37 |
+
public function __construct(array $config)
|
38 |
+
{
|
39 |
+
$dsn = $config['dsn'];
|
40 |
+
if (0 !== strpos($dsn, 'file:')) {
|
41 |
+
throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn));
|
42 |
+
}
|
43 |
+
$this->folder = substr($dsn, 5);
|
44 |
+
|
45 |
+
if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) {
|
46 |
+
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder));
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* {@inheritdoc}
|
52 |
+
*/
|
53 |
+
public function find($ip, $url, $limit, $method, $start = null, $end = null, $statusCode = null)
|
54 |
+
{
|
55 |
+
$file = $this->getIndexFilename();
|
56 |
+
|
57 |
+
if (!file_exists($file)) {
|
58 |
+
return [];
|
59 |
+
}
|
60 |
+
|
61 |
+
$file = fopen($file, 'r');
|
62 |
+
fseek($file, 0, SEEK_END);
|
63 |
+
|
64 |
+
$result = [];
|
65 |
+
while (count($result) < $limit && $line = $this->readLineFromFile($file)) {
|
66 |
+
$values = str_getcsv($line);
|
67 |
+
list($csvToken, $csvIp, $csvMethod, $csvUrl, $csvTime, $csvParent, $csvStatusCode) = $values;
|
68 |
+
$csvTime = (int)$csvTime;
|
69 |
+
|
70 |
+
if ($ip && false === strpos($csvIp, $ip) || $url && false === strpos($csvUrl, $url) || $method && false === strpos($csvMethod, $method) || $statusCode && false === strpos($csvStatusCode, $statusCode)) {
|
71 |
+
continue;
|
72 |
+
}
|
73 |
+
|
74 |
+
if (!empty($start) && $csvTime < $start) {
|
75 |
+
continue;
|
76 |
+
}
|
77 |
+
|
78 |
+
if (!empty($end) && $csvTime > $end) {
|
79 |
+
continue;
|
80 |
+
}
|
81 |
+
|
82 |
+
$result[$csvToken] = [
|
83 |
+
'token' => $csvToken,
|
84 |
+
'ip' => $csvIp,
|
85 |
+
'method' => $csvMethod,
|
86 |
+
'url' => $csvUrl,
|
87 |
+
'time' => $csvTime,
|
88 |
+
'parent' => $csvParent,
|
89 |
+
'status_code' => $csvStatusCode,
|
90 |
+
];
|
91 |
+
}
|
92 |
+
|
93 |
+
fclose($file);
|
94 |
+
|
95 |
+
return array_values($result);
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* {@inheritdoc}
|
100 |
+
*/
|
101 |
+
public function purge()
|
102 |
+
{
|
103 |
+
$flags = \FilesystemIterator::SKIP_DOTS;
|
104 |
+
$iterator = new \RecursiveDirectoryIterator($this->folder, $flags);
|
105 |
+
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST);
|
106 |
+
|
107 |
+
foreach ($iterator as $file) {
|
108 |
+
if (is_file($file)) {
|
109 |
+
unlink($file);
|
110 |
+
} else {
|
111 |
+
rmdir($file);
|
112 |
+
}
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* {@inheritdoc}
|
118 |
+
*/
|
119 |
+
public function read($token)
|
120 |
+
{
|
121 |
+
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
122 |
+
return;
|
123 |
+
}
|
124 |
+
|
125 |
+
return $this->createProfileFromData($token, unserialize(file_get_contents($file)));
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* {@inheritdoc}
|
130 |
+
*
|
131 |
+
* @throws \RuntimeException
|
132 |
+
*/
|
133 |
+
public function write(Ecocode_Profiler_Model_Profile $profile)
|
134 |
+
{
|
135 |
+
$file = $this->getFilename($profile->getToken());
|
136 |
+
|
137 |
+
$profileIndexed = is_file($file);
|
138 |
+
if (!$profileIndexed) {
|
139 |
+
// Create directory
|
140 |
+
$dir = dirname($file);
|
141 |
+
if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
|
142 |
+
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir));
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
// Store profile
|
147 |
+
$data = [
|
148 |
+
'token' => $profile->getToken(),
|
149 |
+
'parent' => $profile->getParentToken(),
|
150 |
+
'children' => array_map(function (Ecocode_Profiler_Model_Profile $p) {
|
151 |
+
return $p->getToken();
|
152 |
+
}, $profile->getChildren()),
|
153 |
+
'data' => $profile->getCollectors(),
|
154 |
+
'ip' => $profile->getIp(),
|
155 |
+
'method' => $profile->getMethod(),
|
156 |
+
'url' => $profile->getUrl(),
|
157 |
+
'time' => $profile->getTime(),
|
158 |
+
'status_code' => $profile->getStatusCode(),
|
159 |
+
'collect_time' => $profile->getCollectTime(),
|
160 |
+
];
|
161 |
+
|
162 |
+
if (false === file_put_contents($file, serialize($data))) {
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
if (!$profileIndexed) {
|
167 |
+
// Add to index
|
168 |
+
if (false === $file = fopen($this->getIndexFilename(), 'a')) {
|
169 |
+
return false;
|
170 |
+
}
|
171 |
+
|
172 |
+
fputcsv($file, [
|
173 |
+
$profile->getToken(),
|
174 |
+
$profile->getIp(),
|
175 |
+
$profile->getMethod(),
|
176 |
+
$profile->getUrl(),
|
177 |
+
$profile->getTime(),
|
178 |
+
$profile->getParentToken(),
|
179 |
+
$profile->getStatusCode(),
|
180 |
+
]);
|
181 |
+
fclose($file);
|
182 |
+
}
|
183 |
+
|
184 |
+
return true;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Gets filename to store data, associated to the token.
|
189 |
+
*
|
190 |
+
* @param string $token
|
191 |
+
*
|
192 |
+
* @return string The profile filename
|
193 |
+
*/
|
194 |
+
protected function getFilename($token)
|
195 |
+
{
|
196 |
+
// Uses 4 last characters, because first are mostly the same.
|
197 |
+
$folderA = substr($token, -2, 2);
|
198 |
+
$folderB = substr($token, -4, 2);
|
199 |
+
|
200 |
+
return $this->folder . '/' . $folderA . '/' . $folderB . '/' . $token;
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Gets the index filename.
|
205 |
+
*
|
206 |
+
* @return string The index filename
|
207 |
+
*/
|
208 |
+
protected function getIndexFilename()
|
209 |
+
{
|
210 |
+
return $this->folder . '/index.csv';
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Reads a line in the file, backward.
|
215 |
+
*
|
216 |
+
* This function automatically skips the empty lines and do not include the line return in result value.
|
217 |
+
*
|
218 |
+
* @param resource $file The file resource, with the pointer placed at the end of the line to read
|
219 |
+
*
|
220 |
+
* @return mixed A string representing the line or null if beginning of file is reached
|
221 |
+
*/
|
222 |
+
protected function readLineFromFile($file)
|
223 |
+
{
|
224 |
+
$line = '';
|
225 |
+
$position = ftell($file);
|
226 |
+
|
227 |
+
if (0 === $position) {
|
228 |
+
return;
|
229 |
+
}
|
230 |
+
|
231 |
+
while (true) {
|
232 |
+
$chunkSize = min($position, 1024);
|
233 |
+
$position -= $chunkSize;
|
234 |
+
fseek($file, $position);
|
235 |
+
|
236 |
+
if (0 === $chunkSize) {
|
237 |
+
// bof reached
|
238 |
+
break;
|
239 |
+
}
|
240 |
+
|
241 |
+
$buffer = fread($file, $chunkSize);
|
242 |
+
|
243 |
+
if (false === ($upTo = strrpos($buffer, "\n"))) {
|
244 |
+
$line = $buffer . $line;
|
245 |
+
continue;
|
246 |
+
}
|
247 |
+
|
248 |
+
$position += $upTo;
|
249 |
+
$line = substr($buffer, $upTo + 1) . $line;
|
250 |
+
fseek($file, max(0, $position), SEEK_SET);
|
251 |
+
|
252 |
+
if ('' !== $line) {
|
253 |
+
break;
|
254 |
+
}
|
255 |
+
}
|
256 |
+
|
257 |
+
return '' === $line ? null : $line;
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* @param $token
|
262 |
+
* @param $data
|
263 |
+
* @param null $parent
|
264 |
+
* @return Ecocode_Profiler_Model_Profile
|
265 |
+
*/
|
266 |
+
protected function createProfileFromData($token, $data, $parent = null)
|
267 |
+
{
|
268 |
+
$profile = new Ecocode_Profiler_Model_Profile($token);
|
269 |
+
$profile->setIp($data['ip']);
|
270 |
+
$profile->setMethod($data['method']);
|
271 |
+
$profile->setUrl($data['url']);
|
272 |
+
$profile->setTime($data['time']);
|
273 |
+
$profile->setStatusCode($data['status_code']);
|
274 |
+
$profile->setCollectors($data['data']);
|
275 |
+
$profile->setCollectTime($data['collect_time']);
|
276 |
+
|
277 |
+
if (!$parent && $data['parent']) {
|
278 |
+
$parent = $this->read($data['parent']);
|
279 |
+
}
|
280 |
+
|
281 |
+
if ($parent) {
|
282 |
+
$profile->setParent($parent);
|
283 |
+
}
|
284 |
+
|
285 |
+
foreach ($data['children'] as $token) {
|
286 |
+
if (!$token || !file_exists($file = $this->getFilename($token))) {
|
287 |
+
continue;
|
288 |
+
}
|
289 |
+
|
290 |
+
$profile->addChild($this->createProfileFromData($token, unserialize(file_get_contents($file)), $profile));
|
291 |
+
}
|
292 |
+
|
293 |
+
return $profile;
|
294 |
+
}
|
295 |
+
}
|
app/code/community/Ecocode/Profiler/Model/Profiler/StorageInterface.php
ADDED
@@ -0,0 +1,58 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* ProfilerStorageInterface.
|
15 |
+
*
|
16 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
17 |
+
*/
|
18 |
+
interface Ecocode_Profiler_Model_Profiler_StorageInterface
|
19 |
+
{
|
20 |
+
/**
|
21 |
+
* Finds profiler tokens for the given criteria.
|
22 |
+
*
|
23 |
+
* @param string $ip The IP
|
24 |
+
* @param string $url The URL
|
25 |
+
* @param string $limit The maximum number of tokens to return
|
26 |
+
* @param string $method The request method
|
27 |
+
* @param int|null $start The start date to search from
|
28 |
+
* @param int|null $end The end date to search to
|
29 |
+
*
|
30 |
+
* @return array An array of tokens
|
31 |
+
*/
|
32 |
+
public function find($ip, $url, $limit, $method, $start = null, $end = null);
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Reads data associated with the given token.
|
36 |
+
*
|
37 |
+
* The method returns false if the token does not exist in the storage.
|
38 |
+
*
|
39 |
+
* @param string $token A token
|
40 |
+
*
|
41 |
+
* @return Ecocode_Profiler_Model_Profile The profile associated with token
|
42 |
+
*/
|
43 |
+
public function read($token);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Saves a Profile.
|
47 |
+
*
|
48 |
+
* @param Ecocode_Profiler_Model_Profile $profile A Profile instance
|
49 |
+
*
|
50 |
+
* @return bool Write operation successful
|
51 |
+
*/
|
52 |
+
public function write(Ecocode_Profiler_Model_Profile $profile);
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Purges all data from the database.
|
56 |
+
*/
|
57 |
+
public function purge();
|
58 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Controller/AbstractControllerTest.php
ADDED
@@ -0,0 +1,70 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_AbstractController
|
5 |
+
*/
|
6 |
+
class Ecocode_Profiler_Tests_Dev_Controller_AbstractControllerTest
|
7 |
+
extends TestHelper
|
8 |
+
{
|
9 |
+
protected function tearDown()
|
10 |
+
{
|
11 |
+
//reset mage as we did some config changes
|
12 |
+
$this->resetMage();
|
13 |
+
Mage::getConfig();
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @expectedException RuntimeException
|
19 |
+
* @expectExceptionMessageRegExp ^You are not allowed to access this file
|
20 |
+
*/
|
21 |
+
public function testAccessDenied()
|
22 |
+
{
|
23 |
+
$request = new Mage_Core_Controller_Request_Http();
|
24 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
25 |
+
$controller = $this->getMockBuilder('Ecocode_Profiler_Controller_AbstractController')
|
26 |
+
->setMethods(['getApp'])
|
27 |
+
->setConstructorArgs([$request, $response])
|
28 |
+
->getMock();
|
29 |
+
|
30 |
+
$app = new MageOriginal();
|
31 |
+
$controller->method('getApp')
|
32 |
+
->willReturn($app);
|
33 |
+
|
34 |
+
/** @var Ecocode_Profiler_Controller_AbstractController $controller */
|
35 |
+
$controller->preDispatch();
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testAccessAllow()
|
39 |
+
{
|
40 |
+
$request = new Mage_Core_Controller_Request_Http();
|
41 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
42 |
+
$controller = $this->getMockBuilder('Ecocode_Profiler_Controller_AbstractController')
|
43 |
+
->setMethods(['getApp', '_rewrite'])
|
44 |
+
->setConstructorArgs([$request, $response])
|
45 |
+
->getMock();
|
46 |
+
|
47 |
+
$app = new Ecocode_Profiler_Model_AppDev();
|
48 |
+
$app->init('', 'store');
|
49 |
+
$controller->method('getApp')
|
50 |
+
->willReturn($app);
|
51 |
+
|
52 |
+
|
53 |
+
$controller->expects($this->once())
|
54 |
+
->method('_rewrite')
|
55 |
+
->willReturn(true);
|
56 |
+
|
57 |
+
/** @var Ecocode_Profiler_Controller_AbstractController $controller */
|
58 |
+
$controller->preDispatch();
|
59 |
+
$this->assertConfigValue(
|
60 |
+
$app->getConfig(),
|
61 |
+
'disabled',
|
62 |
+
'frontend/events/core_block_abstract_to_html_before/observers/ecocode_profiler_context/type'
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
protected function assertConfigValue(Mage_Core_Model_Config $config, $expectValue, $configPath)
|
67 |
+
{
|
68 |
+
$this->assertEquals($expectValue, $config->getNode($configPath));
|
69 |
+
}
|
70 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/DevModeTest.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_DevModeTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
|
8 |
+
public function testDisabledInProduction()
|
9 |
+
{
|
10 |
+
$app = Mage::app();
|
11 |
+
|
12 |
+
$this->assertInstanceOf(
|
13 |
+
'Ecocode_Profiler_Model_AppDev',
|
14 |
+
$app
|
15 |
+
);
|
16 |
+
}
|
17 |
+
|
18 |
+
public function testCollectorsNotLoaded()
|
19 |
+
{
|
20 |
+
$app = Mage::app();
|
21 |
+
|
22 |
+
$value = $app->getConfig()->getNode('ecocode/profiler');
|
23 |
+
$this->assertNotFalse($value);
|
24 |
+
}
|
25 |
+
|
26 |
+
public function testModelsNotLoaded()
|
27 |
+
{
|
28 |
+
$app = Mage::app();
|
29 |
+
|
30 |
+
$value = $app->getConfig()->getNode('global/models/ecocode_profiler');
|
31 |
+
$this->assertNotFalse($value);
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/DummyCacheBackend.php
ADDED
@@ -0,0 +1,7 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Fixtures_DummyCacheBackend
|
4 |
+
extends Zend_Cache_Backend
|
5 |
+
{
|
6 |
+
protected $_options = ['test_option' => 0];
|
7 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/ResponseHttp.php
ADDED
@@ -0,0 +1,10 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp
|
4 |
+
extends Mage_Core_Controller_Response_Http
|
5 |
+
{
|
6 |
+
public function canSendHeaders($throw = true)
|
7 |
+
{
|
8 |
+
return true;
|
9 |
+
}
|
10 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/CodeTest.php
ADDED
@@ -0,0 +1,55 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Helper_CodeTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
/**
|
7 |
+
* @var Ecocode_Profiler_Helper_Code
|
8 |
+
*/
|
9 |
+
private $helper;
|
10 |
+
|
11 |
+
protected function setUp()
|
12 |
+
{
|
13 |
+
$this->helper = new Ecocode_Profiler_Helper_Code('txmt://open?url=file://%f&line=%l', '/root', 'UTF-8');
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testFormatFile()
|
17 |
+
{
|
18 |
+
$expected = sprintf('<a href="txmt://open?url=file://%s&line=25" title="Click to open this file" class="file_link">%s at line 25</a>', __FILE__, __FILE__);
|
19 |
+
$this->assertEquals($expected, $this->helper->formatFile(__FILE__, 25));
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @dataProvider getClassNameProvider
|
24 |
+
*/
|
25 |
+
public function testGettingClassAbbreviation($class, $abbr)
|
26 |
+
{
|
27 |
+
$this->assertEquals($this->helper->abbrClass($class), $abbr);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @dataProvider getMethodNameProvider
|
32 |
+
*/
|
33 |
+
public function testGettingMethodAbbreviation($method, $abbr)
|
34 |
+
{
|
35 |
+
$this->assertEquals($this->helper->abbrMethod($method), $abbr);
|
36 |
+
}
|
37 |
+
|
38 |
+
public function getClassNameProvider()
|
39 |
+
{
|
40 |
+
return array(
|
41 |
+
array('F\Q\N\Foo', '<abbr title="F\Q\N\Foo">Foo</abbr>'),
|
42 |
+
array('Bare', '<abbr title="Bare">Bare</abbr>'),
|
43 |
+
);
|
44 |
+
}
|
45 |
+
|
46 |
+
public function getMethodNameProvider()
|
47 |
+
{
|
48 |
+
return array(
|
49 |
+
array('F\Q\N\Foo::Method', '<abbr title="F\Q\N\Foo">Foo</abbr>::Method()'),
|
50 |
+
array('Bare::Method', '<abbr title="Bare">Bare</abbr>::Method()'),
|
51 |
+
array('Closure', '<abbr title="Closure">Closure</abbr>'),
|
52 |
+
array('Method', '<abbr title="Method">Method</abbr>()'),
|
53 |
+
);
|
54 |
+
}
|
55 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/ContextTest.php
ADDED
@@ -0,0 +1,136 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Helper_ContextTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testInit()
|
7 |
+
{
|
8 |
+
$helper = $this->getNewHelper();
|
9 |
+
|
10 |
+
$current = $helper->getCurrent();
|
11 |
+
|
12 |
+
$this->assertEquals('unknown', $current->getKey());
|
13 |
+
$this->assertEquals(0, $current->getParentId());
|
14 |
+
$this->assertCount(1, $helper->getList());
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testCurrentId()
|
18 |
+
{
|
19 |
+
$helper = $this->getNewHelper();
|
20 |
+
$current = $helper->getCurrent();
|
21 |
+
$this->assertEquals($current->getId(), $helper->getCurrentId());
|
22 |
+
$helper->close($current);
|
23 |
+
|
24 |
+
$this->assertNull($helper->getCurrentId());
|
25 |
+
}
|
26 |
+
|
27 |
+
public function testOpen()
|
28 |
+
{
|
29 |
+
$helper = $this->getNewHelper();
|
30 |
+
|
31 |
+
$context = new Ecocode_Profiler_Model_Context('test-context');
|
32 |
+
|
33 |
+
$this->assertNotEquals($context, $helper->getCurrent());
|
34 |
+
$helper->open($context);
|
35 |
+
$this->assertEquals($context, $helper->getCurrent());
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testClose()
|
39 |
+
{
|
40 |
+
$helper = $this->getNewHelper();
|
41 |
+
|
42 |
+
$context = new Ecocode_Profiler_Model_Context('test-context');
|
43 |
+
|
44 |
+
$helper->open($context);
|
45 |
+
$this->assertCount(2, $helper->getStack());
|
46 |
+
$helper->close($context);
|
47 |
+
$this->assertCount(1, $helper->getStack());
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @expectedException RuntimeException
|
52 |
+
* @expectedExceptionMessage unable to close unknown context
|
53 |
+
*/
|
54 |
+
public function testCloseInvalid()
|
55 |
+
{
|
56 |
+
$helper = $this->getNewHelper();
|
57 |
+
|
58 |
+
$context = new Ecocode_Profiler_Model_Context('test-context');
|
59 |
+
|
60 |
+
$helper->close($context);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function testStacking()
|
64 |
+
{
|
65 |
+
$helper = $this->getNewHelper();
|
66 |
+
$rootContext = $helper->getCurrent();
|
67 |
+
$context1 = new Ecocode_Profiler_Model_Context('test-context-1');
|
68 |
+
$context2 = new Ecocode_Profiler_Model_Context('test-context-2');
|
69 |
+
|
70 |
+
$helper->open($context1);
|
71 |
+
$this->assertCount(2, $helper->getStack());
|
72 |
+
$helper->open($context2);
|
73 |
+
$this->assertCount(3, $helper->getStack());
|
74 |
+
$this->assertEquals(
|
75 |
+
[$rootContext->getId(), $context1->getId(), $context2->getId()],
|
76 |
+
$this->getStackIds($helper)
|
77 |
+
);
|
78 |
+
|
79 |
+
$helper->close($context2);
|
80 |
+
$this->assertEquals(
|
81 |
+
[$rootContext->getId(), $context1->getId()],
|
82 |
+
$this->getStackIds($helper)
|
83 |
+
);
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
public function testGetContextById()
|
88 |
+
{
|
89 |
+
$helper = $this->getNewHelper();
|
90 |
+
|
91 |
+
$context = new Ecocode_Profiler_Model_Context('test-context');
|
92 |
+
$profile = new Ecocode_Profiler_Model_Profile('xxx');
|
93 |
+
$contextCollector = new Ecocode_Profiler_Model_Collector_ContextDataCollector();
|
94 |
+
|
95 |
+
$profile->addCollector($contextCollector);
|
96 |
+
$helper->open($context);
|
97 |
+
|
98 |
+
$dataProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_ContextDataCollector', 'data');
|
99 |
+
$dataProperty->setAccessible(true);
|
100 |
+
$dataProperty->setValue($contextCollector, ['list' => $helper->getList()]);
|
101 |
+
|
102 |
+
$mock = $this
|
103 |
+
->getMockBuilder('Ecocode_Profiler_Helper_Context')
|
104 |
+
->setMethods(['getCurrentProfile'])
|
105 |
+
->getMock();
|
106 |
+
|
107 |
+
$mock->method('getCurrentProfile')
|
108 |
+
->willReturn($profile);
|
109 |
+
|
110 |
+
/** @var Ecocode_Profiler_Helper_Context $loadedContext */
|
111 |
+
$loadedContext = $mock->getContextById($context->getId());
|
112 |
+
$this->assertEquals(
|
113 |
+
$context,
|
114 |
+
$loadedContext
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @return Ecocode_Profiler_Helper_Context
|
121 |
+
*/
|
122 |
+
protected function getNewHelper()
|
123 |
+
{
|
124 |
+
return new Ecocode_Profiler_Helper_Context();
|
125 |
+
}
|
126 |
+
|
127 |
+
protected function getStackIds(Ecocode_Profiler_Helper_Context $helper)
|
128 |
+
{
|
129 |
+
$ids = [];
|
130 |
+
foreach ($helper->getStack() as $context) {
|
131 |
+
/** @var Ecocode_Profiler_Model_ContextInterface $context */
|
132 |
+
$ids[] = $context->getId();
|
133 |
+
}
|
134 |
+
return $ids;
|
135 |
+
}
|
136 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/DataTest.php
ADDED
@@ -0,0 +1,94 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Helper_DataTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testGetClassGroup()
|
7 |
+
{
|
8 |
+
$classGroup = 'catalog/category';
|
9 |
+
$class = Mage::getModel($classGroup);
|
10 |
+
|
11 |
+
$helper = $this->getNewHelper();
|
12 |
+
|
13 |
+
$this->assertEquals(
|
14 |
+
$classGroup,
|
15 |
+
$helper->getClassGroup($class)
|
16 |
+
);
|
17 |
+
}
|
18 |
+
|
19 |
+
public function testUnknownGetClassGroup()
|
20 |
+
{
|
21 |
+
$classGroup = 'catalog/xxx';
|
22 |
+
$class = Mage::getModel($classGroup);
|
23 |
+
|
24 |
+
$helper = $this->getNewHelper();
|
25 |
+
|
26 |
+
$this->assertEquals(
|
27 |
+
'unknown',
|
28 |
+
$helper->getClassGroup($class)
|
29 |
+
);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function testGetCollectorUrl()
|
33 |
+
{
|
34 |
+
$helper = $this->getNewHelper();
|
35 |
+
$collector = new Ecocode_Profiler_Model_Collector_MysqlDataCollector();
|
36 |
+
$token = 'xxx';
|
37 |
+
$collectorName = $collector->getName();
|
38 |
+
|
39 |
+
$url = $helper->getCollectorUrl($token, $collector);
|
40 |
+
$url = str_replace(Mage::getBaseUrl(), '', $url);
|
41 |
+
|
42 |
+
$this->assertEquals(
|
43 |
+
sprintf('_profiler/index/panel/eco_token/%s/panel/%s/', $token, $collectorName),
|
44 |
+
$url
|
45 |
+
);
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
public function testCleanBacktraceBase()
|
50 |
+
{
|
51 |
+
$helper = $this->getNewHelper();
|
52 |
+
$backtrace = [
|
53 |
+
['test' => 'asd', 'function' => 'test'],
|
54 |
+
['class' => 'Test_Class', 'function' => 'asd'],
|
55 |
+
['class' => 'Test_Class2', 'function' => 'asd'],
|
56 |
+
];
|
57 |
+
|
58 |
+
//test empty error handling
|
59 |
+
$this->assertCount(0, $helper->cleanBacktrace([]));
|
60 |
+
|
61 |
+
$this->assertCount(2, $helper->cleanBacktrace($backtrace));
|
62 |
+
$this->assertCount(1, $helper->cleanBacktrace($backtrace, ['Test_Class::asd']));
|
63 |
+
}
|
64 |
+
|
65 |
+
public function testCleanBacktraceInstanceOf()
|
66 |
+
{
|
67 |
+
$helper = $this->getNewHelper();
|
68 |
+
$backtrace = [
|
69 |
+
['test' => 'asd', 'function' => 'test'],
|
70 |
+
['class' => 'Mage_Catalog_Model_Product', 'function' => 'asd'],
|
71 |
+
['class' => 'Ecocode_Profiler_Helper_Data', 'function' => 'asd'],
|
72 |
+
['class' => 'Mage_Catalog_Model_Product', 'function' => 'asd']
|
73 |
+
];
|
74 |
+
|
75 |
+
foreach ($backtrace as &$trace) {
|
76 |
+
if (isset($trace['class'])) {
|
77 |
+
$trace['object'] = $this->getMockBuilder($trace['class'])->disableOriginalConstructor()->getMock();
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->assertCount(3, $helper->cleanBacktrace($backtrace));
|
82 |
+
$this->assertCount(2, $helper->cleanBacktrace($backtrace, [], ['Varien_Object']));
|
83 |
+
$this->assertCount(0, $helper->cleanBacktrace($backtrace, [], ['Varien_Object', 'Ecocode_Profiler_Helper_Data']));
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @return Ecocode_Profiler_Helper_Data
|
88 |
+
*/
|
89 |
+
protected function getNewHelper()
|
90 |
+
{
|
91 |
+
return new Ecocode_Profiler_Helper_Data();
|
92 |
+
}
|
93 |
+
|
94 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/RewriteTest.php
ADDED
@@ -0,0 +1,124 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Helper_RewriteTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Magento doesn't have any conflicts out of the box, so we need to fake one
|
9 |
+
*/
|
10 |
+
public function testLoadRewrites()
|
11 |
+
{
|
12 |
+
$helperMock = $this->getMockBuilder('Ecocode_Profiler_Helper_Rewrite')
|
13 |
+
->setMethods(['getModules', 'getModuleConfigXml'])
|
14 |
+
->getMock();
|
15 |
+
|
16 |
+
$modelBaseConfig = new Mage_Core_Model_Config_Element('<data><active>true</active></data>');
|
17 |
+
$modelDisabledBaseConfig = new Mage_Core_Model_Config_Element('<data><active>false</active></data>');
|
18 |
+
$modelEtcConfig = new Mage_Core_Model_Config_Element('<config>
|
19 |
+
<global>
|
20 |
+
<models>
|
21 |
+
<core_mysql4>
|
22 |
+
<rewrite>
|
23 |
+
<session>XXX_REWRITE</session>
|
24 |
+
</rewrite>
|
25 |
+
</core_mysql4>
|
26 |
+
</models>
|
27 |
+
</global>
|
28 |
+
</config>');
|
29 |
+
|
30 |
+
$helperMock
|
31 |
+
->expects($this->any())
|
32 |
+
->method('getModules')
|
33 |
+
->will($this->returnValue([
|
34 |
+
'test' => $modelBaseConfig,
|
35 |
+
'test2' => $modelDisabledBaseConfig,
|
36 |
+
]));
|
37 |
+
|
38 |
+
$helperMock
|
39 |
+
->expects($this->at(0))
|
40 |
+
->method('getModuleConfigXml')
|
41 |
+
->willReturn(false);
|
42 |
+
|
43 |
+
$helperMock
|
44 |
+
->expects($this->at(1))
|
45 |
+
->method('getModuleConfigXml')
|
46 |
+
->with($this->equalTo('test'), $this->equalTo('config.xml'))
|
47 |
+
->will($this->returnValue($modelEtcConfig));
|
48 |
+
|
49 |
+
/** @var Ecocode_Profiler_Helper_Rewrite $helperMock */
|
50 |
+
$result = $helperMock->loadRewrites();
|
51 |
+
$this->assertEquals(5, count($result, COUNT_RECURSIVE));
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Magento doesn't have any conflicts out of the box, so we need to fake one
|
56 |
+
*/
|
57 |
+
public function testExecuteConflict()
|
58 |
+
{
|
59 |
+
$rewrites = [
|
60 |
+
'blocks' => [
|
61 |
+
'n98/mock_conflict' => [
|
62 |
+
'Mage_Customer_Block_Account',
|
63 |
+
'Mage_Tag_Block_All',
|
64 |
+
]
|
65 |
+
],
|
66 |
+
'helpers' => [
|
67 |
+
'n98/mock_conflict' => [
|
68 |
+
'Mage_Catalog_Helper_Data',
|
69 |
+
'Mage_Sales_Helper_Data',
|
70 |
+
]
|
71 |
+
],
|
72 |
+
'models' => [
|
73 |
+
'n98/mock_conflict' => [
|
74 |
+
'Mage_Catalog_Model_Product',
|
75 |
+
'Mage_Sales_Model_Order',
|
76 |
+
]
|
77 |
+
]
|
78 |
+
];
|
79 |
+
$helper = $this->getHelperWithMockLoadRewrites($rewrites);
|
80 |
+
$result = $helper->getRewriteConflicts();
|
81 |
+
$this->assertCount(3, $result);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* This is made to look like a conflict (2 rewrites for the same class) but
|
86 |
+
* because Bundle extends Catalog, it's valid. Note that we're implying
|
87 |
+
* Bundle depends on Catalog by passing it as the second value in the array.
|
88 |
+
*/
|
89 |
+
public function testExecuteConflictFalsePositive()
|
90 |
+
{
|
91 |
+
$rewrites = [
|
92 |
+
'blocks' => [
|
93 |
+
'n98/mock_conflict' => [
|
94 |
+
'Mage_Catalog_Block_Product_Price',
|
95 |
+
'Mage_Bundle_Block_Catalog_Product_Price',
|
96 |
+
]
|
97 |
+
]
|
98 |
+
];
|
99 |
+
$helper = $this->getHelperWithMockLoadRewrites($rewrites);
|
100 |
+
$result = $helper->getRewriteConflicts();
|
101 |
+
$this->assertCount(0, $result);
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Mock the ConflictsCommand and change the return value of loadRewrites()
|
106 |
+
* to the given argument
|
107 |
+
*
|
108 |
+
* @param array $return
|
109 |
+
* @return Ecocode_Profiler_Helper_Rewrite
|
110 |
+
*/
|
111 |
+
private function getHelperWithMockLoadRewrites(array $return)
|
112 |
+
{
|
113 |
+
$helperMock = $this->getMockBuilder('Ecocode_Profiler_Helper_Rewrite')
|
114 |
+
->setMethods(['loadRewrites'])
|
115 |
+
->getMock();
|
116 |
+
|
117 |
+
$helperMock
|
118 |
+
->expects($this->any())
|
119 |
+
->method('loadRewrites')
|
120 |
+
->will($this->returnValue($return));
|
121 |
+
|
122 |
+
return $helperMock;
|
123 |
+
}
|
124 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/SqlTest.php
ADDED
@@ -0,0 +1,56 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Tests_Dev_Helper_SqlTest extends \PHPUnit_Framework_TestCase
|
5 |
+
{
|
6 |
+
/**
|
7 |
+
* @var Ecocode_Profiler_Helper_Sql
|
8 |
+
*/
|
9 |
+
private $sql;
|
10 |
+
|
11 |
+
protected function setUp()
|
12 |
+
{
|
13 |
+
$this->sql = new Ecocode_Profiler_Helper_Sql();
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testReplaceQueryParametersWithPostgresCasting()
|
17 |
+
{
|
18 |
+
$query = 'a=? OR (1)::string OR b=?';
|
19 |
+
$parameters = [1, 2];
|
20 |
+
$result = $this->sql->replaceQueryParameters($query, $parameters);
|
21 |
+
$this->assertEquals('a=1 OR (1)::string OR b=2', $result);
|
22 |
+
}
|
23 |
+
|
24 |
+
public function testReplaceQueryParametersWithStartingIndexAtOne()
|
25 |
+
{
|
26 |
+
$query = 'a=? OR b=?';
|
27 |
+
$parameters = [
|
28 |
+
1 => 1,
|
29 |
+
2 => 2
|
30 |
+
];
|
31 |
+
$result = $this->sql->replaceQueryParameters($query, $parameters);
|
32 |
+
$this->assertEquals('a=1 OR b=2', $result);
|
33 |
+
}
|
34 |
+
|
35 |
+
public function testReplaceQueryParameters()
|
36 |
+
{
|
37 |
+
$query = 'a=? OR b=?';
|
38 |
+
$parameters = [
|
39 |
+
1,
|
40 |
+
2
|
41 |
+
];
|
42 |
+
$result = $this->sql->replaceQueryParameters($query, $parameters);
|
43 |
+
$this->assertEquals('a=1 OR b=2', $result);
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testReplaceQueryParametersWithNamedIndex()
|
47 |
+
{
|
48 |
+
$query = 'a=:a OR b=:b';
|
49 |
+
$parameters = [
|
50 |
+
'a' => 1,
|
51 |
+
'b' => 2
|
52 |
+
];
|
53 |
+
$result = $this->sql->replaceQueryParameters($query, $parameters);
|
54 |
+
$this->assertEquals('a=1 OR b=2', $result);
|
55 |
+
}
|
56 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Helper/ValueExporterTest.php
ADDED
@@ -0,0 +1,60 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Helper_ValueExporterTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
/**
|
7 |
+
* @var Ecocode_Profiler_Helper_ValueExporter
|
8 |
+
*/
|
9 |
+
private $valueExporter;
|
10 |
+
|
11 |
+
protected function setUp()
|
12 |
+
{
|
13 |
+
$this->valueExporter = new Ecocode_Profiler_Helper_ValueExporter();
|
14 |
+
}
|
15 |
+
|
16 |
+
public function exportValueDataProvider()
|
17 |
+
{
|
18 |
+
$stream = fopen('php://memory', 'w');
|
19 |
+
return [
|
20 |
+
[new Varien_Object(), 'Object(Varien_Object)'],
|
21 |
+
[[new Varien_Object(), new Varien_Object()], '[0 => Object(Varien_Object), 1 => Object(Varien_Object)]'],
|
22 |
+
[[1, 2], '[0 => 1, 1 => 2]'],
|
23 |
+
[[1 => ['a', 'b'], []], "[\n 1 => [\n 0 => a, \n 1 => b\n ], \n 2 => []\n]"],
|
24 |
+
[[null, true, false], '[0 => null, 1 => true, 2 => false]'],
|
25 |
+
[$stream, sprintf('Resource(stream#%d)', $stream)],
|
26 |
+
[[str_repeat('x', 100)], "[\n 0 => " . str_repeat('x', 100) . "\n]"]
|
27 |
+
];
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @dataProvider exportValueDataProvider
|
32 |
+
* @param $value
|
33 |
+
* @param $expectValue
|
34 |
+
*/
|
35 |
+
public function testExportValue($value, $expectValue)
|
36 |
+
{
|
37 |
+
$value = $this->valueExporter->exportValue($value);
|
38 |
+
$this->assertEquals($expectValue, $value);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function testDateTime()
|
42 |
+
{
|
43 |
+
$dateTime = new \DateTime('2014-06-10 07:35:40', new \DateTimeZone('UTC'));
|
44 |
+
$this->assertSame('Object(DateTime) - 2014-06-10T07:35:40+0000', $this->valueExporter->exportValue($dateTime));
|
45 |
+
}
|
46 |
+
|
47 |
+
public function testDateTimeImmutable()
|
48 |
+
{
|
49 |
+
$dateTime = new \DateTimeImmutable('2014-06-10 07:35:40', new \DateTimeZone('UTC'));
|
50 |
+
$this->assertSame('Object(DateTimeImmutable) - 2014-06-10T07:35:40+0000', $this->valueExporter->exportValue($dateTime));
|
51 |
+
}
|
52 |
+
|
53 |
+
public function testIncompleteClass()
|
54 |
+
{
|
55 |
+
$foo = new \__PHP_Incomplete_Class();
|
56 |
+
$array = new \ArrayObject($foo);
|
57 |
+
$array['__PHP_Incomplete_Class_Name'] = 'AppBundle/Foo';
|
58 |
+
$this->assertSame('__PHP_Incomplete_Class(AppBundle/Foo)', $this->valueExporter->exportValue($foo));
|
59 |
+
}
|
60 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/CacheDataCollectorTest.php
ADDED
@@ -0,0 +1,89 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_CacheDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$collector = $this->getMockedCollector();
|
10 |
+
|
11 |
+
$collector->collect(
|
12 |
+
new Mage_Core_Controller_Request_Http(),
|
13 |
+
new Mage_Core_Controller_Response_Http()
|
14 |
+
);
|
15 |
+
|
16 |
+
$expectCacheList = json_decode('[{"id":"config","cache_type":"Configuration","description":"System(config.xml, local.xml) and modules configuration files(config.xml).","tags":"CONFIG","status":1},{"id":"layout","cache_type":"Layouts","description":"Layout building instructions.","tags":"LAYOUT_GENERAL_CACHE_TAG","status":1},{"id":"block_html","cache_type":"Blocks HTML output","description":"Page blocks HTML.","tags":"BLOCK_HTML","status":1},{"id":"translate","cache_type":"Translations","description":"Translation files.","tags":"TRANSLATE","status":1},{"id":"collections","cache_type":"Collections Data","description":"Collection data files.","tags":"COLLECTION_DATA","status":1},{"id":"eav","cache_type":"EAV types and attributes","description":"Entity types declaration cache.","tags":"EAV","status":1},{"id":"config_api","cache_type":"Web Services Configuration","description":"Web Services definition files (api.xml).","tags":"CONFIG_API","status":1},{"id":"config_api2","cache_type":"Web Services Configuration","description":"Web Services definition files (api2.xml).","tags":"CONFIG_API2","status":1}]', true);
|
17 |
+
|
18 |
+
$this->assertEquals('Ecocode_Profiler_Tests_Dev_Fixtures_DummyCacheBackend', $collector->getBackendName());
|
19 |
+
$this->assertEquals(['test_option' => 1], $collector->getBackendOptions());
|
20 |
+
$this->assertEquals($expectCacheList, $collector->getCacheList());
|
21 |
+
$this->assertEmpty($collector->getCacheCalls());
|
22 |
+
}
|
23 |
+
|
24 |
+
public function testLateCollect()
|
25 |
+
{
|
26 |
+
$logs = [
|
27 |
+
['action' => 'clear', 'id' => 'unknown', 'time' => 0.001],
|
28 |
+
['action' => 'load', 'id' => 'core_cache_options1', 'hit' => true, 'time' => 0.005],
|
29 |
+
['action' => 'load', 'id' => 'core_cache_options2', 'hit' => true, 'time' => 0.005],
|
30 |
+
['action' => 'load', 'id' => 'core_cache_options_miss1', 'hit' => false, 'time' => 0.005],
|
31 |
+
['action' => 'load', 'id' => 'core_cache_options_miss2', 'hit' => false, 'time' => 0.005],
|
32 |
+
['action' => 'save', 'id' => 'config_global_admin', 'tags' => ['CONFIG'], 'life_time' => null, 'time' => 0.005],
|
33 |
+
];
|
34 |
+
|
35 |
+
$collector = $this->getMockedCollector([], $logs);
|
36 |
+
|
37 |
+
|
38 |
+
$collector->lateCollect();
|
39 |
+
|
40 |
+
$this->assertEquals([
|
41 |
+
'total' => 6,
|
42 |
+
'hit' => 2,
|
43 |
+
'miss' => 2,
|
44 |
+
'save' => 1,
|
45 |
+
], $collector->getStats());
|
46 |
+
|
47 |
+
$this->assertEquals(6, $collector->getStats('total'));
|
48 |
+
$this->assertEquals(0.026, $collector->getTotalTime());
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getMockedCollector($cacheTypes = [], $log = [])
|
52 |
+
{
|
53 |
+
$cacheBackend = new Ecocode_Profiler_Tests_Dev_Fixtures_DummyCacheBackend(['test_option' => 1]);
|
54 |
+
|
55 |
+
$cacheMock = $this->getMockBuilder('Ecocode_Profiler_Model_Core_Cache')
|
56 |
+
->setMethods(['getTypes', 'getBackend', 'getLog'])
|
57 |
+
->getMock();
|
58 |
+
|
59 |
+
$cacheTypes = $cacheTypes ? $cacheTypes : json_decode('[{"id":"config","cache_type":"Configuration","description":"System(config.xml, local.xml) and modules configuration files(config.xml).","tags":"CONFIG","status":1},{"id":"layout","cache_type":"Layouts","description":"Layout building instructions.","tags":"LAYOUT_GENERAL_CACHE_TAG","status":1},{"id":"block_html","cache_type":"Blocks HTML output","description":"Page blocks HTML.","tags":"BLOCK_HTML","status":1},{"id":"translate","cache_type":"Translations","description":"Translation files.","tags":"TRANSLATE","status":1},{"id":"collections","cache_type":"Collections Data","description":"Collection data files.","tags":"COLLECTION_DATA","status":1},{"id":"eav","cache_type":"EAV types and attributes","description":"Entity types declaration cache.","tags":"EAV","status":1},{"id":"config_api","cache_type":"Web Services Configuration","description":"Web Services definition files (api.xml).","tags":"CONFIG_API","status":1},{"id":"config_api2","cache_type":"Web Services Configuration","description":"Web Services definition files (api2.xml).","tags":"CONFIG_API2","status":1}]', true);
|
60 |
+
$collectorMock = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_CacheDataCollector')
|
61 |
+
->setMethods(['getCacheInstance', 'getCache'])
|
62 |
+
->getMock();
|
63 |
+
|
64 |
+
$types = [];
|
65 |
+
foreach ($cacheTypes as $typeData) {
|
66 |
+
$id = $typeData['id'];
|
67 |
+
$types[$id] = new Varien_Object($typeData);
|
68 |
+
}
|
69 |
+
|
70 |
+
$cacheMock
|
71 |
+
->method('getTypes')
|
72 |
+
->willReturn($types);
|
73 |
+
|
74 |
+
$cacheMock
|
75 |
+
->method('getBackend')
|
76 |
+
->willReturn($cacheBackend);
|
77 |
+
|
78 |
+
$cacheMock
|
79 |
+
->method('getLog')
|
80 |
+
->willReturn($log);
|
81 |
+
|
82 |
+
|
83 |
+
$collectorMock->method('getCacheInstance')->willReturn($cacheMock);
|
84 |
+
$collectorMock->method('getCache')->willReturn($cacheMock);
|
85 |
+
|
86 |
+
|
87 |
+
return $collectorMock;
|
88 |
+
}
|
89 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ConfigCollectorTest.php
ADDED
@@ -0,0 +1,51 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_ConfigCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$token = 'XXX';
|
10 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
11 |
+
$response->setHeader('X-Debug-Token', $token);
|
12 |
+
$collector = new Ecocode_Profiler_Model_Collector_ConfigDataCollector();
|
13 |
+
|
14 |
+
Mage::app()->setCurrentStore('admin');
|
15 |
+
$collector->collect(
|
16 |
+
new Mage_Core_Controller_Request_Http(),
|
17 |
+
$response
|
18 |
+
);
|
19 |
+
|
20 |
+
|
21 |
+
$this->assertEquals(0, $collector->getStoreId());
|
22 |
+
$this->assertEquals('admin', $collector->getStoreCode());
|
23 |
+
$this->assertEquals('Admin', $collector->getStoreName());
|
24 |
+
|
25 |
+
$this->assertEquals(0, $collector->getWebsiteId());
|
26 |
+
$this->assertEquals('admin', $collector->getWebsiteCode());
|
27 |
+
$this->assertEquals('Admin', $collector->getWebsiteName());
|
28 |
+
|
29 |
+
$this->assertEquals($token, $collector->getToken());
|
30 |
+
|
31 |
+
$this->assertFalse($collector->isDeveloperMode());
|
32 |
+
|
33 |
+
$this->assertGreaterThan(1, count($collector->getMagentoModules()));
|
34 |
+
|
35 |
+
$this->assertGreaterThan(1, count($collector->geModulesByState(true)));
|
36 |
+
|
37 |
+
$this->assertNotNull($collector->getMagentoVersion());
|
38 |
+
$this->assertNotNull($collector->getPhpVersion());
|
39 |
+
|
40 |
+
$this->assertNotNull($collector->hasXDebug());
|
41 |
+
$this->assertNotNull($collector->hasEAccelerator());
|
42 |
+
$this->assertNotNull($collector->hasApc());
|
43 |
+
$this->assertNotNull($collector->hasZendOpcache());
|
44 |
+
$this->assertNotNull($collector->hasXCache());
|
45 |
+
$this->assertNotNull($collector->hasWinCache());
|
46 |
+
$this->assertNotNull($collector->hasAccelerator());
|
47 |
+
$this->assertNotNull($collector->getSapiName());
|
48 |
+
|
49 |
+
|
50 |
+
}
|
51 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ContextDataCollectorTest.php
ADDED
@@ -0,0 +1,54 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_ContextDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$collector = new Ecocode_Profiler_Model_Collector_ContextDataCollector();
|
10 |
+
|
11 |
+
$collector->collect(
|
12 |
+
new Mage_Core_Controller_Request_Http(),
|
13 |
+
new Mage_Core_Controller_Response_Http()
|
14 |
+
);
|
15 |
+
|
16 |
+
|
17 |
+
$this->assertCount(0, $collector->getList());
|
18 |
+
}
|
19 |
+
|
20 |
+
public function testLateCollect()
|
21 |
+
{
|
22 |
+
$collector = $this->getMockedCollector();
|
23 |
+
|
24 |
+
$this->assertNull($collector->getById('xx'));
|
25 |
+
|
26 |
+
$context = new Ecocode_Profiler_Model_Context('block:test');
|
27 |
+
$collector->getContextHelper()->open($context);
|
28 |
+
|
29 |
+
|
30 |
+
$collector->lateCollect();
|
31 |
+
|
32 |
+
$this->assertCount(2, $collector->getList());
|
33 |
+
|
34 |
+
$this->assertEquals($context, $collector->getById($context->getId()));
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return Ecocode_Profiler_Model_Collector_ContextDataCollector
|
39 |
+
*/
|
40 |
+
public function getMockedCollector()
|
41 |
+
{
|
42 |
+
$collectorMock = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_ContextDataCollector')
|
43 |
+
->setMethods(['getContextHelper'])
|
44 |
+
->getMock();
|
45 |
+
|
46 |
+
$contextHelper = new Ecocode_Profiler_Helper_Context();
|
47 |
+
$collectorMock->method('getContextHelper')
|
48 |
+
->willReturn($contextHelper);
|
49 |
+
|
50 |
+
|
51 |
+
return $collectorMock;
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/CustomerDataCollectorTest.php
ADDED
@@ -0,0 +1,54 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_CustomerDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$customer = new Mage_Customer_Model_Customer();
|
10 |
+
$customer->setData([
|
11 |
+
'email' => 'test@test.com',
|
12 |
+
'firstname' => 'first',
|
13 |
+
'lastname' => 'last'
|
14 |
+
]);
|
15 |
+
|
16 |
+
$customerHelper = $this->getMockBuilder('Mage_Customer_Helper_Data')
|
17 |
+
->setMethods(['getCustomer', 'isLoggedIn'])
|
18 |
+
->getMock();
|
19 |
+
|
20 |
+
$customerHelper->method('getCustomer')
|
21 |
+
->willReturn($customer);
|
22 |
+
|
23 |
+
$customerHelper->method('isLoggedIn')
|
24 |
+
->willReturn(false);
|
25 |
+
|
26 |
+
/** @var Ecocode_Profiler_Model_Collector_CustomerDataCollector $collector */
|
27 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_CustomerDataCollector')
|
28 |
+
->setMethods(['getCustomerHelper'])
|
29 |
+
->getMock();
|
30 |
+
|
31 |
+
$collector->method('getCustomerHelper')
|
32 |
+
->willReturn($customerHelper);
|
33 |
+
|
34 |
+
$collector->collect(
|
35 |
+
new Mage_Core_Controller_Request_Http(),
|
36 |
+
new Mage_Core_Controller_Response_Http()
|
37 |
+
);
|
38 |
+
|
39 |
+
$this->assertFalse($collector->isLoggedIn());
|
40 |
+
|
41 |
+
$this->assertEquals('test@test.com', $collector->getCustomerEmail());
|
42 |
+
$this->assertEquals('first last', $collector->getCustomerName());
|
43 |
+
|
44 |
+
$this->assertEquals(1, $collector->getGroupId());
|
45 |
+
$this->assertEquals('General', $collector->getGroupCode());
|
46 |
+
|
47 |
+
|
48 |
+
$this->assertEquals('3', $collector->getTaxClassId());
|
49 |
+
$this->assertEquals('Retail Customer', $collector->getTaxClassName());
|
50 |
+
$this->assertEquals('CUSTOMER', $collector->getTaxClassType());
|
51 |
+
|
52 |
+
|
53 |
+
}
|
54 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/EventDataCollectorTest.php
ADDED
@@ -0,0 +1,68 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_EventDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$collector = new Ecocode_Profiler_Model_Collector_EventDataCollector();
|
10 |
+
|
11 |
+
$collector->collect(
|
12 |
+
new Mage_Core_Controller_Request_Http(),
|
13 |
+
new Mage_Core_Controller_Response_Http()
|
14 |
+
);
|
15 |
+
|
16 |
+
|
17 |
+
$this->assertCount(0, $collector->getCalledListeners());
|
18 |
+
$this->assertCount(0, $collector->getFiredEvents());
|
19 |
+
}
|
20 |
+
|
21 |
+
public function testLateCollect()
|
22 |
+
{
|
23 |
+
$collector = $this->getMockedCollector();
|
24 |
+
|
25 |
+
$app = new Ecocode_Profiler_Model_AppDev();
|
26 |
+
$app->init('admin', 'store');
|
27 |
+
$collector->method('getApp')
|
28 |
+
->willReturn($app);
|
29 |
+
|
30 |
+
$preDispatchData = json_decode('{"observers":{"log":{"type":"","model":"log\/visitor","method":"initByRequest","args":[]},"pagecache":{"type":"","model":"pagecache\/observer","method":"processPreDispatch","args":[]}}}', true);
|
31 |
+
$events = ['global' => ['controller_action_predispatch' => $preDispatchData]];
|
32 |
+
|
33 |
+
$app->dispatchEvent('resource_get_tablename', []);
|
34 |
+
$app->dispatchEvent('controller_action_predispatch', []);
|
35 |
+
$app->dispatchEvent('controller_action_predispatch', []);
|
36 |
+
|
37 |
+
$appEvents = new ReflectionProperty('Ecocode_Profiler_Model_AppDev', '_events');
|
38 |
+
$appEvents->setAccessible(true);
|
39 |
+
$appEvents->setValue($app, $events);
|
40 |
+
|
41 |
+
|
42 |
+
$collector->lateCollect();
|
43 |
+
|
44 |
+
$firedEvents = $collector->getFiredEvents();
|
45 |
+
$this->assertCount(0, $collector->getCalledListeners());
|
46 |
+
$this->assertCount(2, $collector->getFiredEvents());
|
47 |
+
|
48 |
+
$data = $firedEvents['controller_action_predispatch'];
|
49 |
+
$this->assertEquals(2, $data['count']);
|
50 |
+
$this->assertEquals(2, $data['observer_count']);
|
51 |
+
$this->assertCount(1, $data['observer']);
|
52 |
+
$this->assertCount(2, $data['observer']['global']);
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return Ecocode_Profiler_Model_Collector_EventDataCollector
|
58 |
+
*/
|
59 |
+
public function getMockedCollector()
|
60 |
+
{
|
61 |
+
$collectorMock = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_EventDataCollector')
|
62 |
+
->setMethods(['getApp'])
|
63 |
+
->getMock();
|
64 |
+
|
65 |
+
|
66 |
+
return $collectorMock;
|
67 |
+
}
|
68 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/LayoutDataCollectorTest.php
ADDED
@@ -0,0 +1,221 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_LayoutDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testBeforeToHtmlNoParent()
|
7 |
+
{
|
8 |
+
$start = microtime(true);
|
9 |
+
$observer = new Varien_Event_Observer();
|
10 |
+
$event = new Varien_Event();
|
11 |
+
$testBlock = new Mage_Core_Block_Template();
|
12 |
+
|
13 |
+
$observer->setData('event', $event);
|
14 |
+
$event->setData('block', $testBlock);
|
15 |
+
|
16 |
+
$collector = new Ecocode_Profiler_Model_Collector_LayoutDataCollector();
|
17 |
+
|
18 |
+
$collector->beforeToHtml($observer);
|
19 |
+
|
20 |
+
$id = $testBlock->getData('profiler_id');
|
21 |
+
$this->assertNotNull($id);
|
22 |
+
|
23 |
+
$renderLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_LayoutDataCollector', 'renderLog');
|
24 |
+
$renderLogProperty->setAccessible(true);
|
25 |
+
$log = $renderLogProperty->getValue($collector);
|
26 |
+
|
27 |
+
$this->assertTrue(isset($log[$id]));
|
28 |
+
|
29 |
+
$logEntry = $log[$id];
|
30 |
+
$this->assertFalse($logEntry['parent_id']);
|
31 |
+
$this->assertGreaterThan($start, $logEntry['start_render']);
|
32 |
+
$this->assertEquals(spl_object_hash($testBlock), $logEntry['hash']);
|
33 |
+
$this->assertCount(0, $logEntry['children']);
|
34 |
+
$this->assertFalse($logEntry['parent_id']);
|
35 |
+
}
|
36 |
+
|
37 |
+
public function testBeforeToHtmlWithParent()
|
38 |
+
{
|
39 |
+
$observer = new Varien_Event_Observer();
|
40 |
+
$event = new Varien_Event();
|
41 |
+
$childBlock = new Mage_Core_Block_Template();
|
42 |
+
$parentBlock = new Mage_Core_Block_Template();
|
43 |
+
|
44 |
+
$parentBlock->setChild('test-child', $childBlock);
|
45 |
+
|
46 |
+
$observer->setData('event', $event);
|
47 |
+
$event->setData('block', $parentBlock);
|
48 |
+
|
49 |
+
$collector = new Ecocode_Profiler_Model_Collector_LayoutDataCollector();
|
50 |
+
|
51 |
+
$collector->beforeToHtml($observer);
|
52 |
+
|
53 |
+
$event->setData('block', $childBlock);
|
54 |
+
$collector->beforeToHtml($observer);
|
55 |
+
|
56 |
+
$parentId = $parentBlock->getData('profiler_id');
|
57 |
+
$childId = $childBlock->getData('profiler_id');
|
58 |
+
|
59 |
+
$this->assertNotNull($parentId);
|
60 |
+
$this->assertNotNull($childId);
|
61 |
+
|
62 |
+
$renderLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_LayoutDataCollector', 'renderLog');
|
63 |
+
$renderLogProperty->setAccessible(true);
|
64 |
+
$log = $renderLogProperty->getValue($collector);
|
65 |
+
|
66 |
+
|
67 |
+
$this->assertCount(2, $log);
|
68 |
+
$this->assertTrue(isset($log[$parentId]));
|
69 |
+
$this->assertTrue(isset($log[$childId]));
|
70 |
+
|
71 |
+
$parentLogEntry = $log[$parentId];
|
72 |
+
$childLogEntry = $log[$childId];
|
73 |
+
|
74 |
+
$this->assertFalse($parentLogEntry['parent_id']);
|
75 |
+
$this->assertEquals($parentId, $childLogEntry['parent_id']);
|
76 |
+
|
77 |
+
$this->assertCount(1, $parentLogEntry['children']);
|
78 |
+
}
|
79 |
+
|
80 |
+
public function testBeforeToHtmlWidget()
|
81 |
+
{
|
82 |
+
$observer = new Varien_Event_Observer();
|
83 |
+
$event = new Varien_Event();
|
84 |
+
|
85 |
+
$parentBlock = new Mage_Core_Block_Template();
|
86 |
+
$widgetBlock = new Mage_Catalog_Block_Product_Widget_New();
|
87 |
+
$widgetChildBlock = new Mage_Core_Block_Template();
|
88 |
+
|
89 |
+
$widgetBlock->setChild('widget-child', $widgetChildBlock);
|
90 |
+
|
91 |
+
$observer->setData('event', $event);
|
92 |
+
|
93 |
+
|
94 |
+
$collector = new Ecocode_Profiler_Model_Collector_LayoutDataCollector();
|
95 |
+
|
96 |
+
$blocks = [$parentBlock, $widgetBlock, $widgetChildBlock];
|
97 |
+
|
98 |
+
foreach ($blocks as $block) {
|
99 |
+
$event->setData('block', $block);
|
100 |
+
$collector->beforeToHtml($observer);
|
101 |
+
}
|
102 |
+
|
103 |
+
$renderLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_LayoutDataCollector', 'renderLog');
|
104 |
+
$renderLogProperty->setAccessible(true);
|
105 |
+
$log = $renderLogProperty->getValue($collector);
|
106 |
+
|
107 |
+
|
108 |
+
$this->assertCount(3, $log);
|
109 |
+
|
110 |
+
$this->assertEquals(
|
111 |
+
$parentBlock->getData('profiler_id'),
|
112 |
+
$log[$widgetBlock->getData('profiler_id')]['parent_id']
|
113 |
+
);
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
public function testAfterToHtml()
|
118 |
+
{
|
119 |
+
$collector = new Ecocode_Profiler_Model_Collector_LayoutDataCollector();
|
120 |
+
|
121 |
+
$observer = new Varien_Event_Observer();
|
122 |
+
$event = new Varien_Event();
|
123 |
+
$testBlock = new Mage_Core_Block_Template();
|
124 |
+
|
125 |
+
$testBlock->setTemplate('test.html.php');
|
126 |
+
|
127 |
+
$observer->setData('event', $event);
|
128 |
+
$event->setData('block', $testBlock);
|
129 |
+
|
130 |
+
|
131 |
+
$collector->beforeToHtml($observer);
|
132 |
+
$collector->afterToHtml($observer);
|
133 |
+
|
134 |
+
$id = $testBlock->getData('profiler_id');
|
135 |
+
$this->assertNotNull($id);
|
136 |
+
|
137 |
+
$renderLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_LayoutDataCollector', 'renderLog');
|
138 |
+
$renderLogProperty->setAccessible(true);
|
139 |
+
$log = $renderLogProperty->getValue($collector);
|
140 |
+
|
141 |
+
$blockData = $log[$id];
|
142 |
+
|
143 |
+
|
144 |
+
$this->assertNotNull($blockData['stop_render']);
|
145 |
+
$this->assertEquals($blockData['stop_render'] - $blockData['start_render'], $blockData['render_time_incl']);
|
146 |
+
$this->assertEquals('test.html.php', $blockData['template']);
|
147 |
+
|
148 |
+
}
|
149 |
+
|
150 |
+
|
151 |
+
public function testCollect()
|
152 |
+
{
|
153 |
+
/** @var Ecocode_Profiler_Model_Collector_LayoutDataCollector $collector */
|
154 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_LayoutDataCollector')
|
155 |
+
->setMethods(['getLayout'])
|
156 |
+
->getMock();
|
157 |
+
|
158 |
+
/** @var Mage_Core_Model_Layout $layout */
|
159 |
+
$layout = new Mage_Core_Model_Layout();
|
160 |
+
|
161 |
+
$collector->method('getLayout')
|
162 |
+
->willReturn($layout);
|
163 |
+
|
164 |
+
$observer = new Varien_Event_Observer();
|
165 |
+
$event = new Varien_Event();
|
166 |
+
|
167 |
+
$childBlock = new Mage_Core_Block_Template();
|
168 |
+
$parentBlock = new Mage_Core_Block_Template();
|
169 |
+
$notRenderedBlock = new Mage_Core_Block_Template();
|
170 |
+
|
171 |
+
$layout->getUpdate()->addHandle('default');
|
172 |
+
$layout->getUpdate()->addHandle('test');
|
173 |
+
$layout->addBlock($childBlock, 'root');
|
174 |
+
$layout->addBlock($parentBlock, 'block-2');
|
175 |
+
$layout->addBlock($notRenderedBlock, 'block-3');
|
176 |
+
|
177 |
+
$layout->addOutputBlock('root');
|
178 |
+
$blocks = [$parentBlock, $childBlock];
|
179 |
+
|
180 |
+
$observer->setData('event', $event);
|
181 |
+
|
182 |
+
$parentBlock->setChild('test-child', $childBlock);
|
183 |
+
|
184 |
+
foreach ($blocks as $block) {
|
185 |
+
$event->setData('block', $block);
|
186 |
+
$collector->beforeToHtml($observer);
|
187 |
+
}
|
188 |
+
|
189 |
+
foreach (array_reverse($blocks) as $block) {
|
190 |
+
$event->setData('block', $block);
|
191 |
+
$collector->afterToHtml($observer);
|
192 |
+
}
|
193 |
+
|
194 |
+
$collector->collect(
|
195 |
+
new Mage_Core_Controller_Request_Http(),
|
196 |
+
new Mage_Core_Controller_Response_Http()
|
197 |
+
);
|
198 |
+
|
199 |
+
$this->assertCount(2, $collector->getLayoutHandles());
|
200 |
+
$this->assertEquals(3, $collector->getBlocksCreatedCount());
|
201 |
+
$this->assertEquals(2, $collector->getBlocksRenderedCount());
|
202 |
+
|
203 |
+
$blocksNotRendered = $collector->getBlocksNotRendered();
|
204 |
+
$this->assertCount(1, $blocksNotRendered);
|
205 |
+
$this->assertEquals('block-3', $blocksNotRendered[0]['name']);
|
206 |
+
$this->assertGreaterThan(0, $collector->getTotalRenderTime());
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* @return Ecocode_Profiler_Model_Collector_LayoutDataCollector
|
211 |
+
*/
|
212 |
+
public function getMockedCollector()
|
213 |
+
{
|
214 |
+
$collectorMock = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_LayoutDataCollector')
|
215 |
+
->setMethods(['getLayout'])
|
216 |
+
->getMock();
|
217 |
+
|
218 |
+
|
219 |
+
return $collectorMock;
|
220 |
+
}
|
221 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/LogDataCollectorTest.php
ADDED
@@ -0,0 +1,84 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Ecocode_Profiler_Tests_Dev_Model_Collector_LogDataCollectorTest
|
5 |
+
*
|
6 |
+
*
|
7 |
+
* @requires
|
8 |
+
*/
|
9 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_LogDataCollectorTest
|
10 |
+
extends TestHelper
|
11 |
+
{
|
12 |
+
protected function setUp()
|
13 |
+
{
|
14 |
+
|
15 |
+
}
|
16 |
+
|
17 |
+
|
18 |
+
public function testCollect()
|
19 |
+
{
|
20 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
21 |
+
$collector = new Ecocode_Profiler_Model_Collector_LogDataCollector();
|
22 |
+
|
23 |
+
|
24 |
+
$collector->collect(
|
25 |
+
new Mage_Core_Controller_Request_Http(),
|
26 |
+
new Mage_Core_Controller_Response_Http()
|
27 |
+
);
|
28 |
+
|
29 |
+
$this->assertEmpty(0, $collector->getLogs());
|
30 |
+
$this->assertEquals(0, $collector->getLogCount());
|
31 |
+
}
|
32 |
+
|
33 |
+
public function testLateCollect()
|
34 |
+
{
|
35 |
+
if (!class_exists('Monolog\Handler\TestHandler')) {
|
36 |
+
$this->markTestSkipped(
|
37 |
+
'Monolog not installed skipping.'
|
38 |
+
);
|
39 |
+
}
|
40 |
+
$logHandler = new Ecocode_Profiler_Model_Logger_DebugHandler();
|
41 |
+
$logger = new Ecocode_Profiler_Model_Logger('test', [$logHandler]);
|
42 |
+
|
43 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_LogDataCollector')
|
44 |
+
->setMethods(['getLogger'])
|
45 |
+
->getMock();
|
46 |
+
|
47 |
+
$collector->method('getLogger')
|
48 |
+
->willReturn($logger);
|
49 |
+
|
50 |
+
|
51 |
+
$logger->debug('test');
|
52 |
+
$logger->debug('test');
|
53 |
+
|
54 |
+
$context = [
|
55 |
+
"type" => 8192, "file" => "path/xxxxCategoryController.php", "line" => 43, "level" => 32767
|
56 |
+
];
|
57 |
+
//simulate 3 times same error like in a loop
|
58 |
+
$logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context);
|
59 |
+
$logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context);
|
60 |
+
$logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context);
|
61 |
+
|
62 |
+
$logger->info('another deprecation', ['level' => E_USER_ERROR, 'type' => E_USER_DEPRECATED]);
|
63 |
+
|
64 |
+
|
65 |
+
$logger->critical('Fatal Parse Error:', ['level' => E_ALL, 'type' => E_PARSE]);
|
66 |
+
|
67 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
68 |
+
$collector->lateCollect();
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
$logsByPriorities = $collector->getPriorities();
|
73 |
+
|
74 |
+
$this->assertEquals(2, $logsByPriorities[Ecocode_Profiler_Model_Logger::DEBUG]['count']);
|
75 |
+
$this->assertEquals(4, $logsByPriorities[Ecocode_Profiler_Model_Logger::INFO]['count']);
|
76 |
+
$this->assertEquals(1, $logsByPriorities[Ecocode_Profiler_Model_Logger::CRITICAL]['count']);
|
77 |
+
|
78 |
+
|
79 |
+
$this->assertEquals(0, $collector->countScreams());
|
80 |
+
$this->assertEquals(1, $collector->countErrors());
|
81 |
+
$this->assertEquals(4, $collector->countDeprecations());
|
82 |
+
|
83 |
+
}
|
84 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/MemoryDataCollectorTest.php
ADDED
@@ -0,0 +1,71 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_MemoryDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function collectDataProvider()
|
8 |
+
{
|
9 |
+
return [
|
10 |
+
['0x1DD5650000', '128134217728'], //hexa //128MB
|
11 |
+
['01672531200000', '128134217728'], //octal //128MB
|
12 |
+
['-1', -1],
|
13 |
+
['1048576K', 1073741824],
|
14 |
+
['2048M', 2147483648],
|
15 |
+
['2G', 2147483648],
|
16 |
+
['1T', 1099511627776]
|
17 |
+
];
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @dataProvider collectDataProvider
|
22 |
+
* @param $limit
|
23 |
+
* @param $expectedBytes
|
24 |
+
*/
|
25 |
+
public function testConvertToBytes($limit, $expectedBytes)
|
26 |
+
{
|
27 |
+
/** @var Ecocode_Profiler_Model_Collector_MemoryDataCollector $collector */
|
28 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_MemoryDataCollector')
|
29 |
+
->setMethods(['getCurrentMemoryLimit'])
|
30 |
+
->getMock();
|
31 |
+
|
32 |
+
|
33 |
+
$collector->method('getCurrentMemoryLimit')
|
34 |
+
->willReturn($limit);
|
35 |
+
|
36 |
+
$collector->collect(
|
37 |
+
new Mage_Core_Controller_Request_Http(),
|
38 |
+
new Mage_Core_Controller_Response_Http()
|
39 |
+
);
|
40 |
+
|
41 |
+
$this->assertEquals($expectedBytes, $collector->getMemoryLimit());
|
42 |
+
}
|
43 |
+
|
44 |
+
public function testCollect()
|
45 |
+
{
|
46 |
+
/** @var Ecocode_Profiler_Model_Collector_MemoryDataCollector $collector */
|
47 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_MemoryDataCollector')
|
48 |
+
->setMethods(['getCurrentMemoryUsage'])
|
49 |
+
->getMock();
|
50 |
+
|
51 |
+
|
52 |
+
$collector->method('getCurrentMemoryUsage')
|
53 |
+
->willReturn(100000);
|
54 |
+
|
55 |
+
|
56 |
+
$collector->collect(
|
57 |
+
new Mage_Core_Controller_Request_Http(),
|
58 |
+
new Mage_Core_Controller_Response_Http()
|
59 |
+
);
|
60 |
+
|
61 |
+
$this->assertGreaterThan(100000, $collector->getMemory());
|
62 |
+
}
|
63 |
+
|
64 |
+
public function testLateCollect()
|
65 |
+
{
|
66 |
+
$collector = new Ecocode_Profiler_Model_Collector_MemoryDataCollector();
|
67 |
+
|
68 |
+
$collector->lateCollect();
|
69 |
+
$this->assertGreaterThan(0, $collector->getMemory());
|
70 |
+
}
|
71 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ModelDataCollectorTest.php
ADDED
@@ -0,0 +1,177 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_ModelDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testCollect()
|
7 |
+
{
|
8 |
+
/** @var Ecocode_Profiler_Model_Collector_ModelDataCollector $collector */
|
9 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
10 |
+
|
11 |
+
$callLog = [
|
12 |
+
['action' => 'load', 'trace_hash' => 'hash-1', 'time' => 10],
|
13 |
+
['action' => 'load', 'trace_hash' => 'hash-2', 'time' => 10],
|
14 |
+
['action' => 'load', 'trace_hash' => 'hash-3', 'time' => 10],
|
15 |
+
['action' => 'load', 'trace_hash' => 'hash-4'],
|
16 |
+
['action' => 'load', 'trace_hash' => 'hash-1', 'time' => 10],
|
17 |
+
['action' => 'load', 'trace_hash' => 'hash-1', 'time' => 10],
|
18 |
+
['action' => 'load', 'trace_hash' => 'hash-2', 'time' => 11],
|
19 |
+
['action' => 'save', 'time' => 10],
|
20 |
+
['action' => 'delete', 'time' => 10],
|
21 |
+
];
|
22 |
+
|
23 |
+
$callLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'callLog');
|
24 |
+
$callLogProperty->setAccessible(true);
|
25 |
+
$callLogProperty->setValue($collector, $callLog);
|
26 |
+
|
27 |
+
$collector->collect(
|
28 |
+
new Mage_Core_Controller_Request_Http(),
|
29 |
+
new Mage_Core_Controller_Response_Http()
|
30 |
+
);
|
31 |
+
|
32 |
+
$this->assertEquals(81, $collector->getTotalTime());
|
33 |
+
$stats = $collector->getMetric();
|
34 |
+
$this->assertEquals(5, $collector->getMetric('loop_load'));
|
35 |
+
$this->assertEquals(7, $stats['load']);
|
36 |
+
$this->assertEquals(1, $stats['save']);
|
37 |
+
$this->assertEquals(1, $stats['delete']);
|
38 |
+
|
39 |
+
return $collector;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param Ecocode_Profiler_Model_Collector_ModelDataCollector $collector
|
44 |
+
*
|
45 |
+
* @depends testCollect
|
46 |
+
*/
|
47 |
+
public function testGetLoopCalls(Ecocode_Profiler_Model_Collector_ModelDataCollector $collector)
|
48 |
+
{
|
49 |
+
$loopCalls = $collector->getLoadLoopCalls();
|
50 |
+
|
51 |
+
$this->assertCount(2, $loopCalls);
|
52 |
+
$loopCall = reset($loopCalls);
|
53 |
+
|
54 |
+
$this->assertEquals(3, $loopCall['count']);
|
55 |
+
$this->assertEquals(30, $loopCall['total_time']);
|
56 |
+
}
|
57 |
+
|
58 |
+
public function testTrackModelLoad()
|
59 |
+
{
|
60 |
+
$model = Mage::getModel('catalog/product');
|
61 |
+
/** @var Ecocode_Profiler_Model_Collector_ModelDataCollector $collector */
|
62 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
63 |
+
|
64 |
+
|
65 |
+
$collector->trackModelLoad($this->getObserver(['object' => $model, 'time' => 100]));
|
66 |
+
|
67 |
+
$callLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'callLog');
|
68 |
+
$callLogProperty->setAccessible(true);
|
69 |
+
|
70 |
+
$callLog = $callLogProperty->getValue($collector);
|
71 |
+
|
72 |
+
$this->assertCount(1, $callLog);
|
73 |
+
|
74 |
+
$callLogItem = reset($callLog);
|
75 |
+
|
76 |
+
$this->assertEquals('load', $callLogItem['action']);
|
77 |
+
$this->assertEquals('Mage_Catalog_Model_Product', $callLogItem['class']);
|
78 |
+
$this->assertEquals('catalog/product', $callLogItem['class_group']);
|
79 |
+
$this->assertEquals('load', $callLogItem['action']);
|
80 |
+
$this->assertEquals(100, $callLogItem['time']);
|
81 |
+
$this->assertCount(0, $callLogItem['trace']);
|
82 |
+
|
83 |
+
|
84 |
+
}
|
85 |
+
|
86 |
+
public function testTrackModelDelete()
|
87 |
+
{
|
88 |
+
$model = Mage::getModel('catalog/product');
|
89 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
90 |
+
|
91 |
+
$collector->trackModelDelete($this->getObserver(['object' => $model]));
|
92 |
+
|
93 |
+
$callLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'callLog');
|
94 |
+
$callLogProperty->setAccessible(true);
|
95 |
+
|
96 |
+
$callLog = $callLogProperty->getValue($collector);
|
97 |
+
|
98 |
+
$this->assertCount(1, $callLog);
|
99 |
+
|
100 |
+
$callLogItem = reset($callLog);
|
101 |
+
|
102 |
+
$this->assertEquals('delete', $callLogItem['action']);
|
103 |
+
$this->assertCount(0, $callLogItem['trace']);
|
104 |
+
}
|
105 |
+
|
106 |
+
public function testTrackModelSave()
|
107 |
+
{
|
108 |
+
$model = Mage::getModel('catalog/product');
|
109 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
110 |
+
|
111 |
+
$collector->trackModelSave($this->getObserver(['object' => $model]));
|
112 |
+
|
113 |
+
$callLogProperty = new ReflectionProperty('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'callLog');
|
114 |
+
$callLogProperty->setAccessible(true);
|
115 |
+
|
116 |
+
$callLog = $callLogProperty->getValue($collector);
|
117 |
+
|
118 |
+
$this->assertCount(1, $callLog);
|
119 |
+
|
120 |
+
$callLogItem = reset($callLog);
|
121 |
+
|
122 |
+
$this->assertEquals('save', $callLogItem['action']);
|
123 |
+
$this->assertCount(0, $callLogItem['trace']);
|
124 |
+
}
|
125 |
+
|
126 |
+
|
127 |
+
public function testCleanBacktrace()
|
128 |
+
{
|
129 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
130 |
+
|
131 |
+
$cleanBacktraceMethod = new ReflectionMethod('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'cleanBacktrace');
|
132 |
+
$cleanBacktraceMethod->setAccessible(true);
|
133 |
+
|
134 |
+
$trace = json_decode('[{"file":"xdebug:\/\/debug-eval(1) : eval()\'d code","line":1,"function":"getBacktrace","class":"Ecocode_Profiler_Model_Collector_AbstractDataCollector","type":"->"},{"file":"xdebug:\/\/debug-eval","line":1,"function":"eval"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/Collector\/ModelDataCollector.php","line":157,"function":"track","class":"Ecocode_Profiler_Model_Collector_ModelDataCollector","type":"::"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/Collector\/ModelDataCollector.php","line":140,"function":"track","class":"Ecocode_Profiler_Model_Collector_ModelDataCollector","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/Collector\/ModelDataCollector.php","line":123,"function":"trackEvent","class":"Ecocode_Profiler_Model_Collector_ModelDataCollector","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/App.php","line":1338,"function":"trackModelLoad","class":"Ecocode_Profiler_Model_Collector_ModelDataCollector","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/AppDev.php","line":124,"function":"_callObserverMethod","class":"Mage_Core_Model_App","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/App.php","line":1317,"function":"_callObserverMethod","class":"Ecocode_Profiler_Model_AppDev","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/AppDev.php","line":91,"function":"dispatchEvent","class":"Mage_Core_Model_App","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/var\/cache\/Original_Mage_1.0.11-a6f179080788cdb98ede80fce0a470e1.php","line":456,"function":"dispatchEvent","class":"Ecocode_Profiler_Model_AppDev","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/overwrite\/Mage.php","line":102,"function":"dispatchEvent","class":"MageOriginal","type":"::"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/overwrite\/MageCoreModelResourceDbAbstract.php","line":24,"function":"dispatchDebugEvent","class":"Mage","type":"::"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Cms\/Model\/Resource\/Page.php","line":170,"function":"load","class":"Mage_Core_Model_Resource_Db_Abstract","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Abstract.php","line":225,"function":"load","class":"Mage_Cms_Model_Resource_Page","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Cms\/Model\/Page.php","line":113,"function":"load","class":"Mage_Core_Model_Abstract","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Cms\/Helper\/Page.php","line":74,"function":"load","class":"Mage_Cms_Model_Page","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Cms\/Helper\/Page.php","line":52,"function":"_renderPage","class":"Mage_Cms_Helper_Page","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Cms\/controllers\/IndexController.php","line":45,"function":"renderPage","class":"Mage_Cms_Helper_Page","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Controller\/Varien\/Action.php","line":418,"function":"indexAction","class":"Mage_Cms_IndexController","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Controller\/Varien\/Router\/Standard.php","line":250,"function":"dispatch","class":"Mage_Core_Controller_Varien_Action","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Controller\/Varien\/Front.php","line":172,"function":"match","class":"Mage_Core_Controller_Varien_Router_Standard","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/App.php","line":354,"function":"dispatch","class":"Mage_Core_Controller_Varien_Front","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/var\/cache\/Original_Mage_1.0.11-a6f179080788cdb98ede80fce0a470e1.php","line":692,"function":"run","class":"Mage_Core_Model_App","type":"->"},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/dev.php","line":68,"function":"run","class":"MageOriginal","type":"::"}]', true);
|
135 |
+
$cleanedTrace = $cleanBacktraceMethod->invoke($collector, $trace);
|
136 |
+
|
137 |
+
|
138 |
+
$firstTraceItem = reset($cleanedTrace);
|
139 |
+
$this->assertCount(12, $cleanedTrace);
|
140 |
+
$this->assertEquals('load', $firstTraceItem['function']);
|
141 |
+
$this->assertFalse(isset($firstTraceItem['object']));
|
142 |
+
$this->assertFalse(isset($firstTraceItem['args']));
|
143 |
+
$this->assertFalse(isset($firstTraceItem['type']));
|
144 |
+
}
|
145 |
+
|
146 |
+
public function shouldRemoveBacktraceProvider()
|
147 |
+
{
|
148 |
+
return [
|
149 |
+
[[], true],
|
150 |
+
[['class' => 'test'], true],
|
151 |
+
[['class' => 'Mage_Cms_Model_Resource_Page', 'function' => 'load'], true],
|
152 |
+
[['class' => 'Mage_Cms_Model_Resource_Page', 'function' => '_load'], true],
|
153 |
+
[false, false],
|
154 |
+
[['class' => 'Mage_Core_Model_Resource_Db_Abstract', 'function' => '_load'], true],
|
155 |
+
[['class' => 'Mage_Core_Model_Resource_Db_Abstract', 'function' => 'load'], false],
|
156 |
+
[['class' => 'Mage_Eav_Model_Entity_Abstract', 'function' => 'load'], false],
|
157 |
+
];
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @dataProvider shouldRemoveBacktraceProvider
|
162 |
+
*
|
163 |
+
* @param $data
|
164 |
+
* @param $expect
|
165 |
+
*/
|
166 |
+
public function testShouldRemoveBacktrace($data, $expect)
|
167 |
+
{
|
168 |
+
$collector = new Ecocode_Profiler_Model_Collector_ModelDataCollector();
|
169 |
+
|
170 |
+
$shouldRemoveBacktraceMethod = new ReflectionMethod('Ecocode_Profiler_Model_Collector_ModelDataCollector', 'shouldRemoveBacktrace');
|
171 |
+
$shouldRemoveBacktraceMethod->setAccessible(true);
|
172 |
+
|
173 |
+
$shouldRemove = $shouldRemoveBacktraceMethod->invoke($collector, $data);
|
174 |
+
|
175 |
+
$this->assertEquals($expect, $shouldRemove);
|
176 |
+
}
|
177 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/MysqlDataCollectorTest.php
ADDED
@@ -0,0 +1,23 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_MysqlDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testBackTrace()
|
8 |
+
{
|
9 |
+
$originalTrace = json_decode('[{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/Collector\/MysqlDataCollector.php","line":95,"function":"getBackTrace","class":"Ecocode_Profiler_Model_Collector_MysqlDataCollector","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Model\/Collector\/MysqlDataCollector.php","line":40,"function":"getTrace","class":"Ecocode_Profiler_Model_Collector_MysqlDataCollector","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Db\/Statement\/Pdo\/Mysql.php","line":55,"function":"logQuery","class":"Ecocode_Profiler_Model_Collector_MysqlDataCollector","object":{},"type":"->","args":[{}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/app\/code\/community\/Ecocode\/Profiler\/Db\/Statement\/Pdo\/Mysql.php","line":48,"function":"log","class":"Ecocode_Profiler_Db_Statement_Pdo_Mysql","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Zend\/Db\/Statement.php","line":291,"function":"_execute","class":"Ecocode_Profiler_Db_Statement_Pdo_Mysql","object":{},"type":"->","args":[{":path0":"",":path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/lib\/Zend\/Db\/Adapter\/Abstract.php","line":479,"function":"execute","class":"Zend_Db_Statement","object":{},"type":"->","args":[{":path0":"",":path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/lib\/Zend\/Db\/Adapter\/Pdo\/Abstract.php","line":238,"function":"query","class":"Zend_Db_Adapter_Abstract","object":{},"type":"->","args":["SELECT `core_url_rewrite`.* FROM `core_url_rewrite` WHERE (request_path IN (:path0, :path1)) AND (store_id IN(0, 1))",{":path0":"",":path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/lib\/Varien\/Db\/Adapter\/Pdo\/Mysql.php","line":428,"function":"query","class":"Zend_Db_Adapter_Pdo_Abstract","object":{},"type":"->","args":["SELECT `core_url_rewrite`.* FROM `core_url_rewrite` WHERE (request_path IN (:path0, :path1)) AND (store_id IN(0, 1))",{":path0":"",":path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/lib\/Zend\/Db\/Adapter\/Abstract.php","line":734,"function":"query","class":"Varien_Db_Adapter_Pdo_Mysql","object":{},"type":"->","args":[{},{"path0":"","path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Resource\/Url\/Rewrite.php","line":151,"function":"fetchAll","class":"Zend_Db_Adapter_Abstract","object":{},"type":"->","args":[{},{"path0":"","path1":"\/"}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite.php","line":100,"function":"loadByRequestPath","class":"Mage_Core_Model_Resource_Url_Rewrite","object":{},"type":"->","args":[{},["","\/"]]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite\/Request.php","line":139,"function":"loadByRequestPath","class":"Mage_Core_Model_Url_Rewrite","object":{},"type":"->","args":[["","\/"]]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite\/Request.php","line":116,"function":"_rewriteDb","class":"Mage_Core_Model_Url_Rewrite_Request","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Controller\/Varien\/Front.php","line":165,"function":"rewrite","class":"Mage_Core_Model_Url_Rewrite_Request","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/App.php","line":354,"function":"dispatch","class":"Mage_Core_Controller_Varien_Front","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/var\/cache\/Original_Mage_1.0.11-a6f179080788cdb98ede80fce0a470e1.php","line":692,"function":"run","class":"Mage_Core_Model_App","object":{},"type":"->","args":[{"scope_code":"","scope_type":"store","options":{"cache":{"id_prefix":"dev"},"config_model":"Ecocode_Profiler_Model_Core_Config"}}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/dev.php","line":68,"function":"run","class":"MageOriginal","type":"::","args":["","store",{"cache":{"id_prefix":"dev"},"config_model":"Ecocode_Profiler_Model_Core_Config"}]}]', true);
|
10 |
+
$expectedTrace = json_decode('[{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite.php","line":100,"function":"loadByRequestPath","class":"Mage_Core_Model_Resource_Url_Rewrite","object":{},"type":"->","args":[{},["","\/"]]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite\/Request.php","line":139,"function":"loadByRequestPath","class":"Mage_Core_Model_Url_Rewrite","object":{},"type":"->","args":[["","\/"]]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/Url\/Rewrite\/Request.php","line":116,"function":"_rewriteDb","class":"Mage_Core_Model_Url_Rewrite_Request","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Controller\/Varien\/Front.php","line":165,"function":"rewrite","class":"Mage_Core_Model_Url_Rewrite_Request","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/app\/code\/core\/Mage\/Core\/Model\/App.php","line":354,"function":"dispatch","class":"Mage_Core_Controller_Varien_Front","object":{},"type":"->","args":[]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/httpdocs\/var\/cache\/Original_Mage_1.0.11-a6f179080788cdb98ede80fce0a470e1.php","line":692,"function":"run","class":"Mage_Core_Model_App","object":{},"type":"->","args":[{"scope_code":"","scope_type":"store","options":{"cache":{"id_prefix":"dev"},"config_model":"Ecocode_Profiler_Model_Core_Config"}}]},{"file":"\/projects\/ecocode\/ecocode_profiler_test\/magento-1.8.1.0\/vendor\/ecocode\/magento_profiler\/dev.php","line":68,"function":"run","class":"MageOriginal","type":"::","args":["","store",{"cache":{"id_prefix":"dev"},"config_model":"Ecocode_Profiler_Model_Core_Config"}]}]', true);
|
11 |
+
|
12 |
+
foreach ($originalTrace as &$trace) {
|
13 |
+
if (isset($trace['class'])) {
|
14 |
+
$trace['object'] = $this->getMockBuilder($trace['class'])->disableOriginalConstructor()->getMock();
|
15 |
+
}
|
16 |
+
}
|
17 |
+
$dataCollector = new Ecocode_Profiler_Model_Collector_MysqlDataCollector();
|
18 |
+
|
19 |
+
$cleanedTrace = $dataCollector->cleanBacktrace($originalTrace);
|
20 |
+
|
21 |
+
$this->assertCount(count($expectedTrace), $cleanedTrace);
|
22 |
+
}
|
23 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/RequestDataCollectorTest.php
ADDED
@@ -0,0 +1,158 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_RequestDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testCollect()
|
7 |
+
{
|
8 |
+
$collector = new Ecocode_Profiler_Model_Collector_RequestDataCollector();
|
9 |
+
|
10 |
+
|
11 |
+
$request = $this->getMockBuilder('Mage_Core_Controller_Request_Http')
|
12 |
+
->setMethods(['getMethod', 'getServer', 'getCookie'])
|
13 |
+
->getMock();
|
14 |
+
|
15 |
+
$serverData = [
|
16 |
+
'REDIRECT_STATUS' => 200,
|
17 |
+
'HTTP_HOST' => 'profiler.test',
|
18 |
+
'HTTP_ACCEPT_ENCODING' => 'gzip, deflate, sdch',
|
19 |
+
];
|
20 |
+
$cookieData = [
|
21 |
+
'frontend' => 'session-key'
|
22 |
+
];
|
23 |
+
$request->method('getMethod')->willReturn('GET');
|
24 |
+
$request->method('getServer')->willReturn($serverData);
|
25 |
+
$request->method('getCookie')->willReturn($cookieData);
|
26 |
+
|
27 |
+
$request->setRequestUri('/dev.php/electronics.html');
|
28 |
+
$request->setBaseUrl('/dev.php');
|
29 |
+
$request->setPathInfo();
|
30 |
+
|
31 |
+
$request->setRequestUri('/dev.php/catalog/category/view/id/13');
|
32 |
+
$request->setPathInfo('catalog/category/view/id/13');
|
33 |
+
$request->setParams(['id' => '13']);
|
34 |
+
$request->setRouteName('catalog');
|
35 |
+
$request->setControllerName('category');
|
36 |
+
$request->setActionName('view');
|
37 |
+
|
38 |
+
|
39 |
+
/** @var Mage_Core_Controller_Request_Http $request */
|
40 |
+
|
41 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
42 |
+
$response->setHttpResponseCode(201);
|
43 |
+
$response->setHeader('content-Type', 'application/json');
|
44 |
+
$response->setHeader('X-DEBUG-TOKEN', 'XXX');
|
45 |
+
|
46 |
+
|
47 |
+
$collector->collect(
|
48 |
+
$request,
|
49 |
+
$response
|
50 |
+
);
|
51 |
+
|
52 |
+
$this->assertEquals('GET', $collector->getMethod());
|
53 |
+
$this->assertEquals('application/json', $collector->getContentType());
|
54 |
+
$this->assertEquals(201, $collector->getStatusCode());
|
55 |
+
$this->assertEquals(Ecocode_Profiler_Model_Collector_RequestDataCollector::$statusTexts[201], $collector->getStatusText());
|
56 |
+
$this->assertEquals(
|
57 |
+
['host' => ['profiler.test'], 'accept-encoding' => ['gzip, deflate, sdch']],
|
58 |
+
$collector->getRequestHeaders()->all()
|
59 |
+
);
|
60 |
+
|
61 |
+
$this->assertEquals(
|
62 |
+
$serverData,
|
63 |
+
$collector->getRequestServer()->all()
|
64 |
+
);
|
65 |
+
|
66 |
+
$this->assertEquals(
|
67 |
+
$cookieData,
|
68 |
+
$collector->getRequestCookies()->all()
|
69 |
+
);
|
70 |
+
|
71 |
+
$this->assertEquals('catalog/category/view/id/13', $collector->getPathInfo());
|
72 |
+
//no post data
|
73 |
+
$this->assertEmpty($collector->getRequestRequest());
|
74 |
+
|
75 |
+
//no get data
|
76 |
+
$this->assertEmpty($collector->getRequestQuery());
|
77 |
+
|
78 |
+
$this->assertCount(4, $collector->getController());
|
79 |
+
|
80 |
+
$this->assertInstanceOf('Ecocode_Profiler_Model_Http_ResponseHeaderBag', $collector->getResponseHeaders());
|
81 |
+
|
82 |
+
return $collector;
|
83 |
+
}
|
84 |
+
|
85 |
+
public function testCollectParameters()
|
86 |
+
{
|
87 |
+
$collector = new Ecocode_Profiler_Model_Collector_RequestDataCollector();
|
88 |
+
|
89 |
+
|
90 |
+
$request = $this->getMockBuilder('Mage_Core_Controller_Request_Http')
|
91 |
+
->setMethods(['getQuery', 'getPost'])
|
92 |
+
->getMock();
|
93 |
+
|
94 |
+
$request->method('getQuery')->willReturn(['q' => 'search']);
|
95 |
+
$request->method('getPost')->willReturn(['key' => 'data']);
|
96 |
+
|
97 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
98 |
+
$collector->collect($request, $response);
|
99 |
+
|
100 |
+
//no post data
|
101 |
+
$this->assertEquals(['key' => 'data'], $collector->getRequestRequest()->all());
|
102 |
+
|
103 |
+
//no get data
|
104 |
+
$this->assertEquals(['q' => 'search'], $collector->getRequestQuery()->all());
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
public function testParseController()
|
109 |
+
{
|
110 |
+
$collector = new Ecocode_Profiler_Model_Collector_RequestDataCollector();
|
111 |
+
|
112 |
+
$controller = new Mage_Core_Controller_Varien_Front();
|
113 |
+
|
114 |
+
$parseControllerMethod = new ReflectionMethod('Ecocode_Profiler_Model_Collector_RequestDataCollector', 'parseController');
|
115 |
+
$parseControllerMethod->setAccessible(true);
|
116 |
+
|
117 |
+
|
118 |
+
$controllerData = $parseControllerMethod->invoke($collector, false);
|
119 |
+
$this->assertEquals('n/a', $controllerData);
|
120 |
+
|
121 |
+
$controllerData = $parseControllerMethod->invoke($collector, $controller);
|
122 |
+
|
123 |
+
$this->assertEquals('Mage_Core_Controller_Varien_Front', $controllerData['class']);
|
124 |
+
}
|
125 |
+
|
126 |
+
public function testDetectStatusCode()
|
127 |
+
{
|
128 |
+
$collector = new Ecocode_Profiler_Model_Collector_RequestDataCollector();
|
129 |
+
|
130 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
131 |
+
$response->setHttpResponseCode(200);
|
132 |
+
|
133 |
+
$detectStatusCodeMethod = new ReflectionMethod('Ecocode_Profiler_Model_Collector_RequestDataCollector', 'detectStatusCode');
|
134 |
+
$detectStatusCodeMethod->setAccessible(true);
|
135 |
+
|
136 |
+
$this->assertEquals(200, $detectStatusCodeMethod->invoke($collector, $response));
|
137 |
+
|
138 |
+
//magento does not set the status 100% correct, sometime only the header is present
|
139 |
+
$response->setHeader('Http/1.1', '404 Not Found');
|
140 |
+
$this->assertEquals(404, $detectStatusCodeMethod->invoke($collector, $response));
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @depends testCollect
|
145 |
+
*/
|
146 |
+
public function testCollectRequestAttributes(Ecocode_Profiler_Model_Collector_RequestDataCollector $collector)
|
147 |
+
{
|
148 |
+
$this->assertInstanceOf('Ecocode_Profiler_Model_Http_ParameterBag', $collector->getRequestAttributes());
|
149 |
+
$this->assertEquals('/electronics.html', $collector->getRequestString());
|
150 |
+
$this->assertEquals('/dev.php/catalog/category/view/id/13', $collector->getRequestUri());
|
151 |
+
$this->assertEquals('catalog', $collector->getModuleName());
|
152 |
+
$this->assertEquals('category', $collector->getControllerName());
|
153 |
+
$this->assertEquals('view', $collector->getActionName());
|
154 |
+
$this->assertEquals('catalog_category_view', $collector->getRoute());
|
155 |
+
$this->assertEquals('catalog', $collector->getRouteName());
|
156 |
+
$this->assertEquals(['id' => '13'], $collector->getRouteParams());
|
157 |
+
}
|
158 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/RewriteDataCollectorTest.php
ADDED
@@ -0,0 +1,39 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_RewriteDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testCollect()
|
7 |
+
{
|
8 |
+
$rewriteHelperMock = $this->getMockBuilder('Ecocode_Profiler_Helper_Rewrite')
|
9 |
+
->setMethods(['loadRewrites', 'getRewriteConflicts'])
|
10 |
+
->getMock();
|
11 |
+
|
12 |
+
//fake a conflict and sample load rewrites
|
13 |
+
$rewrites = json_decode('{"blocks":[],"helpers":[],"models":{"core_mysql4\/session":["XXX_REWRITE"]}}', true);
|
14 |
+
$conflicts = json_decode('[{"type":"blocks","class":"n98\/mock_conflict","rewrites":["Mage_Customer_Block_Account","Mage_Tag_Block_All"],"loaded_class":"Mage_N98_Block_Mock_Conflict"}]', true);
|
15 |
+
|
16 |
+
$rewriteHelperMock->method('loadRewrites')->willReturn($rewrites);
|
17 |
+
$rewriteHelperMock->method('getRewriteConflicts')->willReturn($conflicts);
|
18 |
+
|
19 |
+
/** @var Ecocode_Profiler_Model_Collector_RewriteDataCollector $collector */
|
20 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_RewriteDataCollector')
|
21 |
+
->setMethods(['getRewriteHelper'])
|
22 |
+
->getMock();
|
23 |
+
|
24 |
+
|
25 |
+
$collector->method('getRewriteHelper')->willReturn($rewriteHelperMock);
|
26 |
+
|
27 |
+
$collector->collect(
|
28 |
+
new Mage_Core_Controller_Request_Http(),
|
29 |
+
new Mage_Core_Controller_Response_Http()
|
30 |
+
);
|
31 |
+
|
32 |
+
$rewrites = $collector->getModuleRewrites();
|
33 |
+
$this->assertCount(0, $rewrites['blocks']);
|
34 |
+
$this->assertCount(0, $rewrites['helpers']);
|
35 |
+
$this->assertCount(1, $rewrites['models']);
|
36 |
+
$this->assertCount(1, $collector->getModuleRewriteConflicts());
|
37 |
+
$this->assertEquals(1, $collector->getModuleRewriteConflictCount());
|
38 |
+
}
|
39 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/TimeDataCollectorTest.php
ADDED
@@ -0,0 +1,30 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_TimeDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
/** @var Ecocode_Profiler_Model_Collector_TimeDataCollector $collector */
|
10 |
+
$collector = new Ecocode_Profiler_Model_Collector_TimeDataCollector();
|
11 |
+
|
12 |
+
$collector->collect(
|
13 |
+
new Mage_Core_Controller_Request_Http(),
|
14 |
+
new Mage_Core_Controller_Response_Http()
|
15 |
+
);
|
16 |
+
|
17 |
+
$this->assertEquals(0, $collector->getTotalTime());
|
18 |
+
return $collector;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @depends testCollect
|
23 |
+
*/
|
24 |
+
public function testLateCollect(Ecocode_Profiler_Model_Collector_TimeDataCollector $collector)
|
25 |
+
{
|
26 |
+
$collector->lateCollect();
|
27 |
+
$this->assertGreaterThan(0, $collector->getTotalTime());
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/TranslationDataCollectorTest.php
ADDED
@@ -0,0 +1,79 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Collector_TranslationDataCollectorTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
public function testCollect()
|
8 |
+
{
|
9 |
+
$translate = new Mage_Core_Model_Translate();
|
10 |
+
/** @var Ecocode_Profiler_Model_Collector_TranslationDataCollector $collector */
|
11 |
+
$collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_TranslationDataCollector')
|
12 |
+
->setMethods(['getTranslator'])
|
13 |
+
->getMock();
|
14 |
+
|
15 |
+
$collector->method('getTranslator')->willReturn($translate);
|
16 |
+
|
17 |
+
$messageLog = [
|
18 |
+
['DE_de', 'code-1', 'the-text', 'the-translation', 'translated'],
|
19 |
+
['DE_de', 'code-1', 'the-text', 'the-translation', 'translated'],
|
20 |
+
['DE_de', 'code-2', 'the-text', 'the-translation', 'missing'],
|
21 |
+
['DE_de', 'code-3', 'the-text', 'the-translation', 'invalid'],
|
22 |
+
['DE_de', 'with-trace', 'the-text', 'the-translation', 'fallback', [], null, ['trace1' => []]],
|
23 |
+
['DE_de', 'with-trace', 'the-text', 'the-translation', 'fallback', [], null, ['trace2' => []]],
|
24 |
+
['DE_de', 'multiple-parameters', 'the-text', 'the-translation', 'fallback', ['a' => 'b'], 'catalog'],
|
25 |
+
['DE_de', 'multiple-parameters', 'the-text', 'the-translation', 'fallback', ['c' => 'd'], 'catalog']
|
26 |
+
];
|
27 |
+
|
28 |
+
$messages = [];
|
29 |
+
foreach ($messageLog as $message) {
|
30 |
+
$messages[] = [
|
31 |
+
'locale' => $message[0],
|
32 |
+
'code' => $message[1],
|
33 |
+
'text' => $message[2],
|
34 |
+
'translation' => $message[3],
|
35 |
+
'state' => $message[4],
|
36 |
+
'parameters' => isset($message[5]) ? $message[5] : [],
|
37 |
+
'module' => isset($message[6]) ? $message[6] : null,
|
38 |
+
'trace' => isset($message[7]) ? $message[7] : [],
|
39 |
+
];
|
40 |
+
}
|
41 |
+
$messagesProperty = new ReflectionProperty('Mage_Core_Model_Translate', 'messages');
|
42 |
+
$messagesProperty->setAccessible(true);
|
43 |
+
$messagesProperty->setValue($translate, $messages);
|
44 |
+
|
45 |
+
$collector->collect(
|
46 |
+
new Mage_Core_Controller_Request_Http(),
|
47 |
+
new Mage_Core_Controller_Response_Http()
|
48 |
+
);
|
49 |
+
|
50 |
+
$translations = $collector->getTranslations();
|
51 |
+
$this->assertCount(5, $translations);
|
52 |
+
$this->assertEquals(5, $collector->getTranslationCount());
|
53 |
+
|
54 |
+
$this->assertEquals(2, $translations['code-1']['count']);
|
55 |
+
$this->assertEquals(1, $translations['code-2']['count']);
|
56 |
+
|
57 |
+
//test stats counts
|
58 |
+
|
59 |
+
//test trace set
|
60 |
+
$this->assertCount(2, $translations['with-trace']['traces']);
|
61 |
+
|
62 |
+
//test parameters
|
63 |
+
$this->assertEmpty($translations['code-1']['parameters']);
|
64 |
+
$this->assertNotEmpty($translations['multiple-parameters']['parameters']);
|
65 |
+
$this->assertEquals([['a' => 'b'], ['c' => 'd']], $translations['multiple-parameters']['parameters']);
|
66 |
+
|
67 |
+
//getStateCount
|
68 |
+
$this->assertTrue(is_array($collector->getStateCount()));
|
69 |
+
$this->assertEquals(1, $collector->getStateCount('translated'));
|
70 |
+
$this->assertEquals(1, $collector->getStateCount('missing'));
|
71 |
+
$this->assertEquals(1, $collector->getStateCount('invalid'));
|
72 |
+
$this->assertEquals(2, $collector->getStateCount('fallback'));
|
73 |
+
|
74 |
+
$this->assertEquals(4, $collector->getNotOkCount());
|
75 |
+
|
76 |
+
|
77 |
+
return $collector;
|
78 |
+
}
|
79 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/HeaderBagTest.php
ADDED
@@ -0,0 +1,192 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
class HeaderBagTest extends \PHPUnit_Framework_TestCase
|
14 |
+
{
|
15 |
+
public function testConstructor()
|
16 |
+
{
|
17 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar'));
|
18 |
+
$this->assertTrue($bag->has('foo'));
|
19 |
+
}
|
20 |
+
|
21 |
+
public function testToStringNull()
|
22 |
+
{
|
23 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag();
|
24 |
+
$this->assertEquals('', $bag->__toString());
|
25 |
+
}
|
26 |
+
|
27 |
+
public function testToStringNotNull()
|
28 |
+
{
|
29 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar'));
|
30 |
+
$this->assertEquals("Foo: bar\r\n", $bag->__toString());
|
31 |
+
}
|
32 |
+
|
33 |
+
public function testKeys()
|
34 |
+
{
|
35 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar'));
|
36 |
+
$keys = $bag->keys();
|
37 |
+
$this->assertEquals('foo', $keys[0]);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function testGetDate()
|
41 |
+
{
|
42 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'Tue, 4 Sep 2012 20:00:00 +0200'));
|
43 |
+
$headerDate = $bag->getDate('foo');
|
44 |
+
$this->assertInstanceOf('DateTime', $headerDate);
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @expectedException \RuntimeException
|
49 |
+
*/
|
50 |
+
public function testGetDateException()
|
51 |
+
{
|
52 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'Tue'));
|
53 |
+
$headerDate = $bag->getDate('foo');
|
54 |
+
}
|
55 |
+
|
56 |
+
public function testGetCacheControlHeader()
|
57 |
+
{
|
58 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag();
|
59 |
+
$bag->addCacheControlDirective('public', '#a');
|
60 |
+
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
61 |
+
$this->assertEquals('#a', $bag->getCacheControlDirective('public'));
|
62 |
+
}
|
63 |
+
|
64 |
+
public function testAll()
|
65 |
+
{
|
66 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar'));
|
67 |
+
$this->assertEquals(array('foo' => array('bar')), $bag->all(), '->all() gets all the input');
|
68 |
+
|
69 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('FOO' => 'BAR'));
|
70 |
+
$this->assertEquals(array('foo' => array('BAR')), $bag->all(), '->all() gets all the input key are lower case');
|
71 |
+
}
|
72 |
+
|
73 |
+
public function testReplace()
|
74 |
+
{
|
75 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar'));
|
76 |
+
|
77 |
+
$bag->replace(array('NOPE' => 'BAR'));
|
78 |
+
$this->assertEquals(array('nope' => array('BAR')), $bag->all(), '->replace() replaces the input with the argument');
|
79 |
+
$this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
|
80 |
+
}
|
81 |
+
|
82 |
+
public function testGet()
|
83 |
+
{
|
84 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
|
85 |
+
$this->assertEquals('bar', $bag->get('foo'), '->get return current value');
|
86 |
+
$this->assertEquals('bar', $bag->get('FoO'), '->get key in case insensitive');
|
87 |
+
$this->assertEquals(array('bar'), $bag->get('foo', 'nope', false), '->get return the value as array');
|
88 |
+
|
89 |
+
// defaults
|
90 |
+
$this->assertNull($bag->get('none'), '->get unknown values returns null');
|
91 |
+
$this->assertEquals('default', $bag->get('none', 'default'), '->get unknown values returns default');
|
92 |
+
$this->assertEquals(array('default'), $bag->get('none', 'default', false), '->get unknown values returns default as array');
|
93 |
+
|
94 |
+
$bag->set('foo', 'bor', false);
|
95 |
+
$this->assertEquals('bar', $bag->get('foo'), '->get return first value');
|
96 |
+
$this->assertEquals(array('bar', 'bor'), $bag->get('foo', 'nope', false), '->get return all values as array');
|
97 |
+
}
|
98 |
+
|
99 |
+
public function testSetAssociativeArray()
|
100 |
+
{
|
101 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag();
|
102 |
+
$bag->set('foo', array('bad-assoc-index' => 'value'));
|
103 |
+
$this->assertSame('value', $bag->get('foo'));
|
104 |
+
$this->assertEquals(array('value'), $bag->get('foo', 'nope', false), 'assoc indices of multi-valued headers are ignored');
|
105 |
+
}
|
106 |
+
|
107 |
+
public function testContains()
|
108 |
+
{
|
109 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('foo' => 'bar', 'fuzz' => 'bizz'));
|
110 |
+
$this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
|
111 |
+
$this->assertTrue($bag->contains('fuzz', 'bizz'), '->contains second value');
|
112 |
+
$this->assertFalse($bag->contains('nope', 'nope'), '->contains unknown value');
|
113 |
+
$this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');
|
114 |
+
|
115 |
+
// Multiple values
|
116 |
+
$bag->set('foo', 'bor', false);
|
117 |
+
$this->assertTrue($bag->contains('foo', 'bar'), '->contains first value');
|
118 |
+
$this->assertTrue($bag->contains('foo', 'bor'), '->contains second value');
|
119 |
+
$this->assertFalse($bag->contains('foo', 'nope'), '->contains unknown value');
|
120 |
+
}
|
121 |
+
|
122 |
+
public function testCacheControlDirectiveAccessors()
|
123 |
+
{
|
124 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag();
|
125 |
+
$bag->addCacheControlDirective('public');
|
126 |
+
|
127 |
+
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
128 |
+
$this->assertTrue($bag->getCacheControlDirective('public'));
|
129 |
+
$this->assertEquals('public', $bag->get('cache-control'));
|
130 |
+
|
131 |
+
$bag->addCacheControlDirective('max-age', 10);
|
132 |
+
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
133 |
+
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
134 |
+
$this->assertEquals('max-age=10, public', $bag->get('cache-control'));
|
135 |
+
|
136 |
+
$bag->removeCacheControlDirective('max-age');
|
137 |
+
$this->assertFalse($bag->hasCacheControlDirective('max-age'));
|
138 |
+
}
|
139 |
+
|
140 |
+
public function testCacheControlDirectiveParsing()
|
141 |
+
{
|
142 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('cache-control' => 'public, max-age=10'));
|
143 |
+
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
144 |
+
$this->assertTrue($bag->getCacheControlDirective('public'));
|
145 |
+
|
146 |
+
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
147 |
+
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
148 |
+
|
149 |
+
$bag->addCacheControlDirective('s-maxage', 100);
|
150 |
+
$this->assertEquals('max-age=10, public, s-maxage=100', $bag->get('cache-control'));
|
151 |
+
}
|
152 |
+
|
153 |
+
public function testCacheControlDirectiveParsingQuotedZero()
|
154 |
+
{
|
155 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('cache-control' => 'max-age="0"'));
|
156 |
+
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
157 |
+
$this->assertEquals(0, $bag->getCacheControlDirective('max-age'));
|
158 |
+
}
|
159 |
+
|
160 |
+
public function testCacheControlDirectiveOverrideWithReplace()
|
161 |
+
{
|
162 |
+
$bag = new Ecocode_Profiler_Model_Http_HeaderBag(array('cache-control' => 'private, max-age=100'));
|
163 |
+
$bag->replace(array('cache-control' => 'public, max-age=10'));
|
164 |
+
$this->assertTrue($bag->hasCacheControlDirective('public'));
|
165 |
+
$this->assertTrue($bag->getCacheControlDirective('public'));
|
166 |
+
|
167 |
+
$this->assertTrue($bag->hasCacheControlDirective('max-age'));
|
168 |
+
$this->assertEquals(10, $bag->getCacheControlDirective('max-age'));
|
169 |
+
}
|
170 |
+
|
171 |
+
public function testGetIterator()
|
172 |
+
{
|
173 |
+
$headers = array('foo' => 'bar', 'hello' => 'world', 'third' => 'charm');
|
174 |
+
$headerBag = new Ecocode_Profiler_Model_Http_HeaderBag($headers);
|
175 |
+
|
176 |
+
$i = 0;
|
177 |
+
foreach ($headerBag as $key => $val) {
|
178 |
+
++$i;
|
179 |
+
$this->assertEquals(array($headers[$key]), $val);
|
180 |
+
}
|
181 |
+
|
182 |
+
$this->assertEquals(count($headers), $i);
|
183 |
+
}
|
184 |
+
|
185 |
+
public function testCount()
|
186 |
+
{
|
187 |
+
$headers = array('foo' => 'bar', 'HELLO' => 'WORLD');
|
188 |
+
$headerBag = new Ecocode_Profiler_Model_Http_HeaderBag($headers);
|
189 |
+
|
190 |
+
$this->assertEquals(count($headers), count($headerBag));
|
191 |
+
}
|
192 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/ParameterBagTest.php
ADDED
@@ -0,0 +1,181 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class ParameterBagTest extends \PHPUnit_Framework_TestCase
|
5 |
+
{
|
6 |
+
public function testConstructor()
|
7 |
+
{
|
8 |
+
$this->testAll();
|
9 |
+
}
|
10 |
+
|
11 |
+
public function testAll()
|
12 |
+
{
|
13 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
14 |
+
$this->assertEquals(array('foo' => 'bar'), $bag->all(), '->all() gets all the input');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testKeys()
|
18 |
+
{
|
19 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
20 |
+
$this->assertEquals(array('foo'), $bag->keys());
|
21 |
+
}
|
22 |
+
|
23 |
+
public function testAdd()
|
24 |
+
{
|
25 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
26 |
+
$bag->add(array('bar' => 'bas'));
|
27 |
+
$this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
|
28 |
+
}
|
29 |
+
|
30 |
+
public function testRemove()
|
31 |
+
{
|
32 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
33 |
+
$bag->add(array('bar' => 'bas'));
|
34 |
+
$this->assertEquals(array('foo' => 'bar', 'bar' => 'bas'), $bag->all());
|
35 |
+
$bag->remove('bar');
|
36 |
+
$this->assertEquals(array('foo' => 'bar'), $bag->all());
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testReplace()
|
40 |
+
{
|
41 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
42 |
+
|
43 |
+
$bag->replace(array('FOO' => 'BAR'));
|
44 |
+
$this->assertEquals(array('FOO' => 'BAR'), $bag->all(), '->replace() replaces the input with the argument');
|
45 |
+
$this->assertFalse($bag->has('foo'), '->replace() overrides previously set the input');
|
46 |
+
}
|
47 |
+
|
48 |
+
public function testGet()
|
49 |
+
{
|
50 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar', 'null' => null));
|
51 |
+
|
52 |
+
$this->assertEquals('bar', $bag->get('foo'), '->get() gets the value of a parameter');
|
53 |
+
$this->assertEquals('default', $bag->get('unknown', 'default'), '->get() returns second argument as default if a parameter is not defined');
|
54 |
+
$this->assertNull($bag->get('null', 'default'), '->get() returns null if null is set');
|
55 |
+
}
|
56 |
+
|
57 |
+
public function testGetDoesNotUseDeepByDefault()
|
58 |
+
{
|
59 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => array('bar' => 'moo')));
|
60 |
+
|
61 |
+
$this->assertNull($bag->get('foo[bar]'));
|
62 |
+
}
|
63 |
+
|
64 |
+
public function testSet()
|
65 |
+
{
|
66 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array());
|
67 |
+
|
68 |
+
$bag->set('foo', 'bar');
|
69 |
+
$this->assertEquals('bar', $bag->get('foo'), '->set() sets the value of parameter');
|
70 |
+
|
71 |
+
$bag->set('foo', 'baz');
|
72 |
+
$this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter');
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testHas()
|
76 |
+
{
|
77 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('foo' => 'bar'));
|
78 |
+
|
79 |
+
$this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined');
|
80 |
+
$this->assertFalse($bag->has('unknown'), '->has() return false if a parameter is not defined');
|
81 |
+
}
|
82 |
+
|
83 |
+
public function testGetAlpha()
|
84 |
+
{
|
85 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('word' => 'foo_BAR_012'));
|
86 |
+
|
87 |
+
$this->assertEquals('fooBAR', $bag->getAlpha('word'), '->getAlpha() gets only alphabetic characters');
|
88 |
+
$this->assertEquals('', $bag->getAlpha('unknown'), '->getAlpha() returns empty string if a parameter is not defined');
|
89 |
+
}
|
90 |
+
|
91 |
+
public function testGetAlnum()
|
92 |
+
{
|
93 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('word' => 'foo_BAR_012'));
|
94 |
+
|
95 |
+
$this->assertEquals('fooBAR012', $bag->getAlnum('word'), '->getAlnum() gets only alphanumeric characters');
|
96 |
+
$this->assertEquals('', $bag->getAlnum('unknown'), '->getAlnum() returns empty string if a parameter is not defined');
|
97 |
+
}
|
98 |
+
|
99 |
+
public function testGetDigits()
|
100 |
+
{
|
101 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('word' => 'foo_BAR_012'));
|
102 |
+
|
103 |
+
$this->assertEquals('012', $bag->getDigits('word'), '->getDigits() gets only digits as string');
|
104 |
+
$this->assertEquals('', $bag->getDigits('unknown'), '->getDigits() returns empty string if a parameter is not defined');
|
105 |
+
}
|
106 |
+
|
107 |
+
public function testGetInt()
|
108 |
+
{
|
109 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array('digits' => '0123'));
|
110 |
+
|
111 |
+
$this->assertEquals(123, $bag->getInt('digits'), '->getInt() gets a value of parameter as integer');
|
112 |
+
$this->assertEquals(0, $bag->getInt('unknown'), '->getInt() returns zero if a parameter is not defined');
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testFilter()
|
116 |
+
{
|
117 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag(array(
|
118 |
+
'digits' => '0123ab',
|
119 |
+
'email' => 'example@example.com',
|
120 |
+
'url' => 'http://example.com/foo',
|
121 |
+
'dec' => '256',
|
122 |
+
'hex' => '0x100',
|
123 |
+
'array' => array('bang'),
|
124 |
+
));
|
125 |
+
|
126 |
+
$this->assertEmpty($bag->filter('nokey'), '->filter() should return empty by default if no key is found');
|
127 |
+
|
128 |
+
$this->assertEquals('0123', $bag->filter('digits', '', FILTER_SANITIZE_NUMBER_INT), '->filter() gets a value of parameter as integer filtering out invalid characters');
|
129 |
+
|
130 |
+
$this->assertEquals('example@example.com', $bag->filter('email', '', FILTER_VALIDATE_EMAIL), '->filter() gets a value of parameter as email');
|
131 |
+
|
132 |
+
$this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, array('flags' => FILTER_FLAG_PATH_REQUIRED)), '->filter() gets a value of parameter as URL with a path');
|
133 |
+
|
134 |
+
// This test is repeated for code-coverage
|
135 |
+
$this->assertEquals('http://example.com/foo', $bag->filter('url', '', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED), '->filter() gets a value of parameter as URL with a path');
|
136 |
+
|
137 |
+
$this->assertFalse($bag->filter('dec', '', FILTER_VALIDATE_INT, array(
|
138 |
+
'flags' => FILTER_FLAG_ALLOW_HEX,
|
139 |
+
'options' => array('min_range' => 1, 'max_range' => 0xff),
|
140 |
+
)), '->filter() gets a value of parameter as integer between boundaries');
|
141 |
+
|
142 |
+
$this->assertFalse($bag->filter('hex', '', FILTER_VALIDATE_INT, array(
|
143 |
+
'flags' => FILTER_FLAG_ALLOW_HEX,
|
144 |
+
'options' => array('min_range' => 1, 'max_range' => 0xff),
|
145 |
+
)), '->filter() gets a value of parameter as integer between boundaries');
|
146 |
+
|
147 |
+
$this->assertEquals(array('bang'), $bag->filter('array', ''), '->filter() gets a value of parameter as an array');
|
148 |
+
}
|
149 |
+
|
150 |
+
public function testGetIterator()
|
151 |
+
{
|
152 |
+
$parameters = array('foo' => 'bar', 'hello' => 'world');
|
153 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag($parameters);
|
154 |
+
|
155 |
+
$i = 0;
|
156 |
+
foreach ($bag as $key => $val) {
|
157 |
+
++$i;
|
158 |
+
$this->assertEquals($parameters[$key], $val);
|
159 |
+
}
|
160 |
+
|
161 |
+
$this->assertEquals(count($parameters), $i);
|
162 |
+
}
|
163 |
+
|
164 |
+
public function testCount()
|
165 |
+
{
|
166 |
+
$parameters = array('foo' => 'bar', 'hello' => 'world');
|
167 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag($parameters);
|
168 |
+
|
169 |
+
$this->assertEquals(count($parameters), count($bag));
|
170 |
+
}
|
171 |
+
|
172 |
+
public function testGetBoolean()
|
173 |
+
{
|
174 |
+
$parameters = array('string_true' => 'true', 'string_false' => 'false');
|
175 |
+
$bag = new Ecocode_Profiler_Model_Http_ParameterBag($parameters);
|
176 |
+
|
177 |
+
$this->assertTrue($bag->getBoolean('string_true'), '->getBoolean() gets the string true as boolean true');
|
178 |
+
$this->assertFalse($bag->getBoolean('string_false'), '->getBoolean() gets the string false as boolean false');
|
179 |
+
$this->assertFalse($bag->getBoolean('unknown'), '->getBoolean() returns false if a parameter is not defined');
|
180 |
+
}
|
181 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Http/ResponseHeaderBagTest.php
ADDED
@@ -0,0 +1,160 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @group time-sensitive
|
15 |
+
*/
|
16 |
+
class ResponseHeaderBagTest extends \PHPUnit_Framework_TestCase
|
17 |
+
{
|
18 |
+
/**
|
19 |
+
* @dataProvider provideAllPreserveCase
|
20 |
+
*/
|
21 |
+
public function testAllPreserveCase($headers, $expected)
|
22 |
+
{
|
23 |
+
$bag = new Ecocode_Profiler_Model_Http_ResponseHeaderBag($headers);
|
24 |
+
|
25 |
+
$this->assertEquals($expected, $bag->allPreserveCase(), '->allPreserveCase() gets all input keys in original case');
|
26 |
+
}
|
27 |
+
|
28 |
+
public function provideAllPreserveCase()
|
29 |
+
{
|
30 |
+
return array(
|
31 |
+
array(
|
32 |
+
array('fOo' => 'BAR'),
|
33 |
+
array('fOo' => array('BAR'), 'Cache-Control' => array('no-cache')),
|
34 |
+
),
|
35 |
+
array(
|
36 |
+
array('ETag' => 'xyzzy'),
|
37 |
+
array('ETag' => array('xyzzy'), 'Cache-Control' => array('private, must-revalidate')),
|
38 |
+
),
|
39 |
+
array(
|
40 |
+
array('Content-MD5' => 'Q2hlY2sgSW50ZWdyaXR5IQ=='),
|
41 |
+
array('Content-MD5' => array('Q2hlY2sgSW50ZWdyaXR5IQ=='), 'Cache-Control' => array('no-cache')),
|
42 |
+
),
|
43 |
+
array(
|
44 |
+
array('P3P' => 'CP="CAO PSA OUR"'),
|
45 |
+
array('P3P' => array('CP="CAO PSA OUR"'), 'Cache-Control' => array('no-cache')),
|
46 |
+
),
|
47 |
+
array(
|
48 |
+
array('WWW-Authenticate' => 'Basic realm="WallyWorld"'),
|
49 |
+
array('WWW-Authenticate' => array('Basic realm="WallyWorld"'), 'Cache-Control' => array('no-cache')),
|
50 |
+
),
|
51 |
+
array(
|
52 |
+
array('X-UA-Compatible' => 'IE=edge,chrome=1'),
|
53 |
+
array('X-UA-Compatible' => array('IE=edge,chrome=1'), 'Cache-Control' => array('no-cache')),
|
54 |
+
),
|
55 |
+
array(
|
56 |
+
array('X-XSS-Protection' => '1; mode=block'),
|
57 |
+
array('X-XSS-Protection' => array('1; mode=block'), 'Cache-Control' => array('no-cache')),
|
58 |
+
),
|
59 |
+
);
|
60 |
+
}
|
61 |
+
|
62 |
+
public function testReplace()
|
63 |
+
{
|
64 |
+
$bag = new Ecocode_Profiler_Model_Http_ResponseHeaderBag(array());
|
65 |
+
$this->assertEquals('no-cache', $bag->get('Cache-Control'));
|
66 |
+
|
67 |
+
$bag->replace(array('Cache-Control' => 'public'));
|
68 |
+
$this->assertEquals('public', $bag->get('Cache-Control'));
|
69 |
+
}
|
70 |
+
|
71 |
+
public function testReplaceWithRemove()
|
72 |
+
{
|
73 |
+
$bag = new Ecocode_Profiler_Model_Http_ResponseHeaderBag(array());
|
74 |
+
$this->assertEquals('no-cache', $bag->get('Cache-Control'));
|
75 |
+
|
76 |
+
$bag->remove('Cache-Control');
|
77 |
+
$bag->replace(array());
|
78 |
+
$this->assertEquals('no-cache', $bag->get('Cache-Control'));
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @expectedException \InvalidArgumentException
|
84 |
+
*/
|
85 |
+
public function testGetCookiesWithInvalidArgument()
|
86 |
+
{
|
87 |
+
$bag = new Ecocode_Profiler_Model_Http_ResponseHeaderBag();
|
88 |
+
|
89 |
+
$cookies = $bag->getCookies('invalid_argument');
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @expectedException \InvalidArgumentException
|
94 |
+
*/
|
95 |
+
public function testMakeDispositionInvalidDisposition()
|
96 |
+
{
|
97 |
+
$headers = new Ecocode_Profiler_Model_Http_ResponseHeaderBag();
|
98 |
+
|
99 |
+
$headers->makeDisposition('invalid', 'foo.html');
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @dataProvider provideMakeDisposition
|
104 |
+
*/
|
105 |
+
public function testMakeDisposition($disposition, $filename, $filenameFallback, $expected)
|
106 |
+
{
|
107 |
+
$headers = new Ecocode_Profiler_Model_Http_ResponseHeaderBag();
|
108 |
+
|
109 |
+
$this->assertEquals($expected, $headers->makeDisposition($disposition, $filename, $filenameFallback));
|
110 |
+
}
|
111 |
+
|
112 |
+
public function testToStringDoesntMessUpHeaders()
|
113 |
+
{
|
114 |
+
$headers = new Ecocode_Profiler_Model_Http_ResponseHeaderBag();
|
115 |
+
|
116 |
+
$headers->set('Location', 'http://www.symfony.com');
|
117 |
+
$headers->set('Content-type', 'text/html');
|
118 |
+
|
119 |
+
(string) $headers;
|
120 |
+
|
121 |
+
$allHeaders = $headers->allPreserveCase();
|
122 |
+
$this->assertEquals(array('http://www.symfony.com'), $allHeaders['Location']);
|
123 |
+
$this->assertEquals(array('text/html'), $allHeaders['Content-type']);
|
124 |
+
}
|
125 |
+
|
126 |
+
public function provideMakeDisposition()
|
127 |
+
{
|
128 |
+
return array(
|
129 |
+
array('attachment', 'foo.html', 'foo.html', 'attachment; filename="foo.html"'),
|
130 |
+
array('attachment', 'foo.html', '', 'attachment; filename="foo.html"'),
|
131 |
+
array('attachment', 'foo bar.html', '', 'attachment; filename="foo bar.html"'),
|
132 |
+
array('attachment', 'foo "bar".html', '', 'attachment; filename="foo \\"bar\\".html"'),
|
133 |
+
array('attachment', 'foo%20bar.html', 'foo bar.html', 'attachment; filename="foo bar.html"; filename*=utf-8\'\'foo%2520bar.html'),
|
134 |
+
array('attachment', 'föö.html', 'foo.html', 'attachment; filename="foo.html"; filename*=utf-8\'\'f%C3%B6%C3%B6.html'),
|
135 |
+
);
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @dataProvider provideMakeDispositionFail
|
140 |
+
* @expectedException \InvalidArgumentException
|
141 |
+
*/
|
142 |
+
public function testMakeDispositionFail($disposition, $filename)
|
143 |
+
{
|
144 |
+
$headers = new Ecocode_Profiler_Model_Http_ResponseHeaderBag();
|
145 |
+
|
146 |
+
$headers->makeDisposition($disposition, $filename);
|
147 |
+
}
|
148 |
+
|
149 |
+
public function provideMakeDispositionFail()
|
150 |
+
{
|
151 |
+
return array(
|
152 |
+
array('attachment', 'foo%20bar.html'),
|
153 |
+
array('attachment', 'foo/bar.html'),
|
154 |
+
array('attachment', '/foo.html'),
|
155 |
+
array('attachment', 'foo\bar.html'),
|
156 |
+
array('attachment', '\foo.html'),
|
157 |
+
array('attachment', 'föö.html'),
|
158 |
+
);
|
159 |
+
}
|
160 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/LoggerTest.php
ADDED
@@ -0,0 +1,87 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Monolog\Handler\TestHandler;
|
4 |
+
|
5 |
+
class Ecocode_Profiler_Tests_Dev_Model_LoggerTest
|
6 |
+
extends TestHelper
|
7 |
+
{
|
8 |
+
protected function setUp()
|
9 |
+
{
|
10 |
+
if (!class_exists('Monolog\Handler\TestHandler')) {
|
11 |
+
$this->markTestSkipped(
|
12 |
+
'Monolog not installed skipping.'
|
13 |
+
);
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testMageLog()
|
18 |
+
{
|
19 |
+
$handler = new Ecocode_Profiler_Model_Logger_DebugHandler();
|
20 |
+
$logger = new Ecocode_Profiler_Model_Logger(__METHOD__, [$handler]);
|
21 |
+
|
22 |
+
$this->assertTrue($logger->mageLog(Zend_Log::ERR, 'error message'));
|
23 |
+
$logs = $logger->getLogs();
|
24 |
+
|
25 |
+
$this->assertCount(1, $logs);
|
26 |
+
$log = reset($logs);
|
27 |
+
$this->assertEquals(Ecocode_Profiler_Model_Logger::ERROR, $log['priority']);
|
28 |
+
}
|
29 |
+
|
30 |
+
public function testGetLogsWithDebugHandler()
|
31 |
+
{
|
32 |
+
$handler = new Ecocode_Profiler_Model_Logger_DebugHandler();
|
33 |
+
$logger = new Ecocode_Profiler_Model_Logger(__METHOD__, [$handler]);
|
34 |
+
|
35 |
+
$this->assertTrue($logger->error('error message'));
|
36 |
+
$this->assertSame(1, count($logger->getLogs()));
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testGetLogsWithoutDebugHandler()
|
40 |
+
{
|
41 |
+
$handler = new TestHandler();
|
42 |
+
$logger = new Ecocode_Profiler_Model_Logger(__METHOD__, [$handler]);
|
43 |
+
|
44 |
+
$this->assertTrue($logger->error('error message'));
|
45 |
+
$this->assertSame([], $logger->getLogs());
|
46 |
+
}
|
47 |
+
|
48 |
+
public function testCountErrorsWithDebugHandler()
|
49 |
+
{
|
50 |
+
$handler = new Ecocode_Profiler_Model_Logger_DebugHandler();
|
51 |
+
$logger = new Ecocode_Profiler_Model_Logger(__METHOD__, [$handler]);
|
52 |
+
|
53 |
+
$this->assertTrue($logger->debug('test message'));
|
54 |
+
$this->assertTrue($logger->info('test message'));
|
55 |
+
$this->assertTrue($logger->notice('test message'));
|
56 |
+
$this->assertTrue($logger->warning('test message'));
|
57 |
+
|
58 |
+
$this->assertTrue($logger->error('test message'));
|
59 |
+
$this->assertTrue($logger->critical('test message'));
|
60 |
+
$this->assertTrue($logger->alert('test message'));
|
61 |
+
$this->assertTrue($logger->emergency('test message'));
|
62 |
+
|
63 |
+
$this->assertSame(4, $logger->countErrors());
|
64 |
+
}
|
65 |
+
|
66 |
+
public function testGetLogs()
|
67 |
+
{
|
68 |
+
$logger = new Ecocode_Profiler_Model_Logger('test');
|
69 |
+
$logger->pushHandler(new Ecocode_Profiler_Model_Logger_DebugHandler());
|
70 |
+
|
71 |
+
$logger->addInfo('test');
|
72 |
+
$this->assertCount(1, $logger->getLogs());
|
73 |
+
list($record) = $logger->getLogs();
|
74 |
+
|
75 |
+
$this->assertEquals('test', $record['message']);
|
76 |
+
$this->assertEquals(Ecocode_Profiler_Model_Logger::INFO, $record['priority']);
|
77 |
+
}
|
78 |
+
|
79 |
+
public function testCountErrorsWithoutDebugHandler()
|
80 |
+
{
|
81 |
+
$handler = new TestHandler();
|
82 |
+
$logger = new Ecocode_Profiler_Model_Logger(__METHOD__, [$handler]);
|
83 |
+
|
84 |
+
$this->assertTrue($logger->error('error message'));
|
85 |
+
$this->assertSame(0, $logger->countErrors());
|
86 |
+
}
|
87 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Observer/ContextTest.php
ADDED
@@ -0,0 +1,66 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Tests_Dev_Model_Observer_ContextTest
|
5 |
+
extends TestHelper
|
6 |
+
{
|
7 |
+
protected $contextHelper;
|
8 |
+
|
9 |
+
protected function setUp()
|
10 |
+
{
|
11 |
+
parent::setUp();
|
12 |
+
|
13 |
+
/** @var Ecocode_Profiler_Helper_Context $contextHelper */
|
14 |
+
$this->contextHelper = $this->getMockBuilder('Ecocode_Profiler_Helper_Context')
|
15 |
+
->getMock();
|
16 |
+
}
|
17 |
+
|
18 |
+
|
19 |
+
public function testOpenBlockContext()
|
20 |
+
{
|
21 |
+
/** @var Ecocode_Profiler_Model_Observer_Context $contextHelper */
|
22 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer_Context')
|
23 |
+
->setMethods(['getHelper'])
|
24 |
+
->getMock();
|
25 |
+
|
26 |
+
$observer->method('getHelper')->willReturn($this->contextHelper);
|
27 |
+
|
28 |
+
$block = new Mage_Core_Block_Template();
|
29 |
+
$block->setTemplate('test.phtml');
|
30 |
+
$eventObserver = $this->getObserver(['block' => $block]);
|
31 |
+
|
32 |
+
$this->contextHelper->expects($this->once())->method('open');
|
33 |
+
$observer->openBlockContext($eventObserver);
|
34 |
+
|
35 |
+
/** @var Ecocode_Profiler_Model_ContextInterface $context */
|
36 |
+
$context = $block->getData('__context');
|
37 |
+
$this->assertInstanceOf('Ecocode_Profiler_Model_ContextInterface', $context);
|
38 |
+
|
39 |
+
return $block;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @depends testOpenBlockContext
|
44 |
+
*/
|
45 |
+
public function testCloseBlockContext(Mage_Core_Block_Template $block )
|
46 |
+
{
|
47 |
+
/** @var Ecocode_Profiler_Model_Observer_Context $contextHelper */
|
48 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer_Context')
|
49 |
+
->setMethods(['getHelper'])
|
50 |
+
->getMock();
|
51 |
+
|
52 |
+
$observer->method('getHelper')->willReturn($this->contextHelper);
|
53 |
+
|
54 |
+
$eventObserver = $this->getObserver(['block' => $block]);
|
55 |
+
|
56 |
+
$this->contextHelper->expects($this->once())->method('close');
|
57 |
+
$observer->closeBlockContext($eventObserver);
|
58 |
+
|
59 |
+
/** @var Ecocode_Profiler_Model_ContextInterface $context */
|
60 |
+
$contextData = $block->getData('__context')->getData();
|
61 |
+
$this->assertEquals('test.phtml', $contextData['template']);
|
62 |
+
|
63 |
+
|
64 |
+
return $block;
|
65 |
+
}
|
66 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/ObserverTest.php
ADDED
@@ -0,0 +1,163 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Tests_Dev_Model_ObserverTest
|
5 |
+
extends TestHelper
|
6 |
+
{
|
7 |
+
protected function setUp()
|
8 |
+
{
|
9 |
+
parent::setUp();
|
10 |
+
|
11 |
+
/** @var Ecocode_Profiler_Helper_Context $contextHelper */
|
12 |
+
$this->contextHelper = $this->getMockBuilder('Ecocode_Profiler_Helper_Context')
|
13 |
+
->getMock();
|
14 |
+
}
|
15 |
+
|
16 |
+
|
17 |
+
public function testControllerFrontSendResponseBefore()
|
18 |
+
{
|
19 |
+
/** @var Ecocode_Profiler_Model_Profiler $profiler */
|
20 |
+
$profiler = $this->getMockBuilder('Ecocode_Profiler_Model_Profiler')
|
21 |
+
->setMethods(['saveProfile', 'collect'])
|
22 |
+
->getMock();
|
23 |
+
|
24 |
+
$profiler->method('collect')
|
25 |
+
->willReturn(new Ecocode_Profiler_Model_Profile('xxx'));
|
26 |
+
|
27 |
+
|
28 |
+
$profiler->disable();
|
29 |
+
$this->checkIfToolbarIsInjected($profiler);
|
30 |
+
$profiler->enable();
|
31 |
+
$observer = $this->checkIfToolbarIsInjected($profiler);
|
32 |
+
|
33 |
+
return $observer;
|
34 |
+
}
|
35 |
+
|
36 |
+
public function testLinkTokenHeader()
|
37 |
+
{
|
38 |
+
$profiler = $this->getMockBuilder('Ecocode_Profiler_Model_Profiler')
|
39 |
+
->setMethods(['collect'])
|
40 |
+
->getMock();
|
41 |
+
|
42 |
+
$frontController = $this->getMockBuilder('Mage_Core_Controller_Varien_Front')
|
43 |
+
->setMethods(['getResponse'])
|
44 |
+
->getMock();
|
45 |
+
|
46 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
47 |
+
$response->setHeader('X-Debug-Token', 'XXX');
|
48 |
+
|
49 |
+
$frontController->method('getResponse')->willReturn($response);
|
50 |
+
|
51 |
+
$eventObserver = $this->getObserver(['front' => $frontController]);
|
52 |
+
|
53 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer')
|
54 |
+
->setMethods(['getProfiler', 'injectToolbar'])
|
55 |
+
->getMock();
|
56 |
+
|
57 |
+
|
58 |
+
$observer->method('getProfiler')->willReturn($profiler);
|
59 |
+
|
60 |
+
$profiler->enable();
|
61 |
+
/** @var Ecocode_Profiler_Model_Observer $observer */
|
62 |
+
$observer->controllerFrontSendResponseBefore($eventObserver);
|
63 |
+
|
64 |
+
$headers = $response->getHeaders();
|
65 |
+
$tokenLinkHeader = false;
|
66 |
+
foreach ($headers as $header) {
|
67 |
+
if ($header['name'] === 'X-Debug-Token-Link') {
|
68 |
+
$tokenLinkHeader = $header;
|
69 |
+
break;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
$this->assertNotFalse($tokenLinkHeader);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function checkIfToolbarIsInjected(Ecocode_Profiler_Model_Profiler $profiler)
|
76 |
+
{
|
77 |
+
$frontController = $this->getMockBuilder('Mage_Core_Controller_Varien_Front')
|
78 |
+
->setMethods(['getResponse'])
|
79 |
+
->getMock();
|
80 |
+
|
81 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
82 |
+
|
83 |
+
$frontController->method('getResponse')->willReturn($response);
|
84 |
+
|
85 |
+
$eventObserver = $this->getObserver(['front' => $frontController]);
|
86 |
+
|
87 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer')
|
88 |
+
->setMethods(['getProfiler', 'injectToolbar'])
|
89 |
+
->getMock();
|
90 |
+
|
91 |
+
|
92 |
+
$observer->method('getProfiler')->willReturn($profiler);
|
93 |
+
|
94 |
+
if ($profiler->isEnabled()) {
|
95 |
+
$observer->expects($this->once())
|
96 |
+
->method('injectToolbar');
|
97 |
+
} else {
|
98 |
+
$observer->expects($this->never())
|
99 |
+
->method('injectToolbar');
|
100 |
+
}
|
101 |
+
/** @var Ecocode_Profiler_Model_Observer $observer */
|
102 |
+
$observer->controllerFrontSendResponseBefore($eventObserver);
|
103 |
+
|
104 |
+
return [$profiler, $observer];
|
105 |
+
}
|
106 |
+
|
107 |
+
|
108 |
+
/**
|
109 |
+
*/
|
110 |
+
public function testOnTerminate()
|
111 |
+
{
|
112 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer')
|
113 |
+
->setMethods(['getProfiler'])
|
114 |
+
->getMock();
|
115 |
+
|
116 |
+
$profilesProperty = new ReflectionProperty('Ecocode_Profiler_Model_Observer', 'profiles');
|
117 |
+
$profilesProperty->setAccessible(true);
|
118 |
+
|
119 |
+
$profile = new Ecocode_Profiler_Model_Profile('token');
|
120 |
+
|
121 |
+
$request = new Mage_Core_Controller_Request_Http();
|
122 |
+
$storage = $profilesProperty->getValue($observer);
|
123 |
+
$storage[$request] = $profile;
|
124 |
+
|
125 |
+
|
126 |
+
$profiler = $this->getMockBuilder('Ecocode_Profiler_Model_Profiler')
|
127 |
+
->setMethods(['saveProfile'])
|
128 |
+
->getMock();
|
129 |
+
|
130 |
+
$observer->method('getProfiler')->willReturn($profiler);
|
131 |
+
|
132 |
+
$profiler->expects($this->once())
|
133 |
+
->method('saveProfile');
|
134 |
+
|
135 |
+
$observer->onTerminate($this->getObserver([]));
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
public function testInjectToolbar()
|
140 |
+
{
|
141 |
+
$layout = new Mage_Core_Model_Layout();
|
142 |
+
$observer = $this->getMockBuilder('Ecocode_Profiler_Model_Observer')
|
143 |
+
->setMethods(['getLayout'])
|
144 |
+
->getMock();
|
145 |
+
|
146 |
+
$observer->method('getLayout')->willReturn($layout);
|
147 |
+
|
148 |
+
$injectToolbarMethod = new ReflectionMethod('Ecocode_Profiler_Model_Observer', 'injectToolbar');
|
149 |
+
$injectToolbarMethod->setAccessible(true);
|
150 |
+
|
151 |
+
$request = new Mage_Core_Controller_Request_Http();
|
152 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
153 |
+
$response->setBody('<html><body>Some Content</body></html>');
|
154 |
+
|
155 |
+
$injectToolbarMethod->invoke($observer, $response, $request);
|
156 |
+
|
157 |
+
$this->assertContains('Some Content', $response->getBody());
|
158 |
+
$this->assertContains('<!-- START of ecocode Web Debug Toolbar -->', $response->getBody());
|
159 |
+
|
160 |
+
$this->assertNotFalse($layout->getBlock('profiler_toolbar'));
|
161 |
+
$this->assertNotFalse($layout->getBlock('profiler_base_js'));
|
162 |
+
}
|
163 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelResourceDbAbstractTest.php
ADDED
@@ -0,0 +1,118 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Overwrite_MageCoreModelResourceDbAbstract
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testLoad()
|
7 |
+
{
|
8 |
+
$testData = ['a' => 'b'];
|
9 |
+
$readAdapter = $this->getMockBuilder('Magento_Db_Adapter_Pdo_Mysql')
|
10 |
+
->disableOriginalConstructor()
|
11 |
+
->setMethods(['fetchRow'])
|
12 |
+
->getMock();
|
13 |
+
|
14 |
+
$readAdapter->method('fetchRow')->willReturn($testData);
|
15 |
+
|
16 |
+
$resourceLog = $this->getMockBuilder('Mage_Log_Model_Resource_Log')
|
17 |
+
->setMethods(['dispatch', '_getReadAdapter', '_getLoadSelect', 'unserializeFields', '_afterLoad'])
|
18 |
+
->getMock();
|
19 |
+
|
20 |
+
$resourceLog->method('_getReadAdapter')->willReturn($readAdapter);
|
21 |
+
|
22 |
+
$visitor = new Mage_Log_Model_Visitor();
|
23 |
+
|
24 |
+
|
25 |
+
$resourceLog->expects($this->once())
|
26 |
+
->method('dispatch')
|
27 |
+
->with(
|
28 |
+
$this->equalTo('model_resource_db_load'),
|
29 |
+
$this->callback(function ($subject) use ($visitor) {
|
30 |
+
return $subject['object'] === $visitor && isset($subject['time']);
|
31 |
+
})
|
32 |
+
);
|
33 |
+
|
34 |
+
|
35 |
+
$resourceLog->load($visitor, 1);
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testSave()
|
39 |
+
{
|
40 |
+
$writeAdapter = $this->getMockBuilder('Magento_Db_Adapter_Pdo_Mysql')
|
41 |
+
->disableOriginalConstructor()
|
42 |
+
->setMethods(['insert', 'lastInsertId'])
|
43 |
+
->getMock();
|
44 |
+
|
45 |
+
|
46 |
+
$resourceLog = $this->getMockBuilder('Mage_Log_Model_Resource_Log')
|
47 |
+
->setMethods([
|
48 |
+
'dispatch', '_serializeFields', '_getWriteAdapter',
|
49 |
+
'_beforeSave', '_checkUnique', '_prepareDataForSave',
|
50 |
+
'getIdFieldName', 'unserializeFields', 'afterSave'])
|
51 |
+
->getMock();
|
52 |
+
|
53 |
+
$resourceLog->method('_getWriteAdapter')->willReturn($writeAdapter);
|
54 |
+
$resourceLog->method('getIdFieldName')->willReturn('id');
|
55 |
+
$resourceLog->method('_prepareDataForSave')->willReturn([]);
|
56 |
+
|
57 |
+
|
58 |
+
$visitor = new Mage_Log_Model_Visitor();
|
59 |
+
$resourceLog->expects($this->once())
|
60 |
+
->method('dispatch')
|
61 |
+
->with(
|
62 |
+
$this->equalTo('model_resource_db_save'),
|
63 |
+
$this->callback(function ($subject) use ($visitor) {
|
64 |
+
return $subject['object'] === $visitor && isset($subject['time']);
|
65 |
+
})
|
66 |
+
);
|
67 |
+
|
68 |
+
|
69 |
+
$resourceLog->save($visitor, 1);
|
70 |
+
}
|
71 |
+
|
72 |
+
public function testSaveDeleted()
|
73 |
+
{
|
74 |
+
$resourceLog = $this->getMockBuilder('Mage_Log_Model_Resource_Log')
|
75 |
+
->setMethods(['dispatch', 'delete'])
|
76 |
+
->getMock();
|
77 |
+
|
78 |
+
$visitor = new Mage_Log_Model_Visitor();
|
79 |
+
$visitor->isDeleted(true);
|
80 |
+
$resourceLog->expects($this->never())
|
81 |
+
->method('dispatch');
|
82 |
+
|
83 |
+
$resourceLog->save($visitor, 1);
|
84 |
+
}
|
85 |
+
|
86 |
+
public function testDelete()
|
87 |
+
{
|
88 |
+
$writeAdapter = $this->getMockBuilder('Magento_Db_Adapter_Pdo_Mysql')
|
89 |
+
->disableOriginalConstructor()
|
90 |
+
->setMethods(['delete', 'quoteInto'])
|
91 |
+
->getMock();
|
92 |
+
|
93 |
+
|
94 |
+
$resourceLog = $this->getMockBuilder('Mage_Log_Model_Resource_Log')
|
95 |
+
->setMethods([
|
96 |
+
'dispatch', '_beforeDelete',
|
97 |
+
'getMainTable', '_getWriteAdapter',
|
98 |
+
'_afterDelete'])
|
99 |
+
->getMock();
|
100 |
+
|
101 |
+
$resourceLog->method('_getWriteAdapter')->willReturn($writeAdapter);
|
102 |
+
|
103 |
+
|
104 |
+
$visitor = new Mage_Log_Model_Visitor();
|
105 |
+
|
106 |
+
$resourceLog->expects($this->once())
|
107 |
+
->method('dispatch')
|
108 |
+
->with(
|
109 |
+
$this->equalTo('model_resource_db_delete'),
|
110 |
+
$this->callback(function ($subject) use ($visitor) {
|
111 |
+
return $subject['object'] === $visitor && isset($subject['time']);
|
112 |
+
})
|
113 |
+
);
|
114 |
+
|
115 |
+
|
116 |
+
$resourceLog->delete($visitor, 1);
|
117 |
+
}
|
118 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelResourceTest.php
ADDED
@@ -0,0 +1,29 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Overwrite_MageCoreModelResourceTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
|
8 |
+
public function testGetConnection()
|
9 |
+
{
|
10 |
+
$configProperty = new ReflectionProperty('Varien_Db_Adapter_Pdo_Mysql', '_config');
|
11 |
+
$configProperty->setAccessible(true);
|
12 |
+
|
13 |
+
$resource = new Mage_Core_Model_Resource();
|
14 |
+
|
15 |
+
|
16 |
+
/** @var Varien_Db_Adapter_Pdo_Mysql $connection */
|
17 |
+
$connection = $resource->getConnection('core_read');
|
18 |
+
|
19 |
+
$this->assertEquals(
|
20 |
+
'Ecocode_Profiler_Db_Statement_Pdo_Mysql',
|
21 |
+
$connection->getStatementClass()
|
22 |
+
);
|
23 |
+
|
24 |
+
|
25 |
+
$connectionConfig = $configProperty->getValue($connection);
|
26 |
+
$this->assertEquals('core_read', $connectionConfig['connection_name']);
|
27 |
+
|
28 |
+
}
|
29 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelTranslateTest.php
ADDED
@@ -0,0 +1,66 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Overwrite_MageCoreModelTranslateTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testTranslatedString()
|
7 |
+
{
|
8 |
+
$translate = new Mage_Core_Model_Translate();
|
9 |
+
|
10 |
+
|
11 |
+
$this->addTranslations($translate, [
|
12 |
+
'test' => 'test-core'
|
13 |
+
], 'Mage_Core');
|
14 |
+
|
15 |
+
$this->addTranslations($translate, [
|
16 |
+
'test' => 'test-page',
|
17 |
+
'test %' => 'test-page %s',
|
18 |
+
], 'Mage_Page');
|
19 |
+
|
20 |
+
|
21 |
+
$this->assertTranslation($translate, 'test-core', 'test', 'none');
|
22 |
+
$this->assertTranslation($translate, 'test-core', 'test', 'Mage_Core');
|
23 |
+
$this->assertTranslation($translate, 'test-page', 'test', 'Mage_Page');
|
24 |
+
$this->assertTranslation($translate, 'test-untranslated', 'test-untranslated', 'Mage_Page');
|
25 |
+
$this->assertTranslation($translate, 'test %s', 'test %s', 'Mage_Page');
|
26 |
+
$this->assertTranslation($translate, 'test-page asd', 'test %', 'Mage_Page', ['asd']);
|
27 |
+
|
28 |
+
$stats = [];
|
29 |
+
foreach ($translate->getMessages() as $message) {
|
30 |
+
if (!isset($stats[$message['state']])) {
|
31 |
+
$stats[$message['state']] = 0;
|
32 |
+
}
|
33 |
+
$stats[$message['state']]++;
|
34 |
+
}
|
35 |
+
|
36 |
+
$this->assertEquals(3, $stats[Mage_Core_Model_Translate::STATE_TRANSLATED]);
|
37 |
+
$this->assertEquals(1, $stats[Mage_Core_Model_Translate::STATE_FALLBACK]);
|
38 |
+
$this->assertEquals(1, $stats[Mage_Core_Model_Translate::STATE_MISSING]);
|
39 |
+
$this->assertEquals(1, $stats[Mage_Core_Model_Translate::STATE_INVALID]);
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function assertTranslation(Mage_Core_Model_Translate $translate, $expect, $key, $module, array $params = [])
|
43 |
+
{
|
44 |
+
$this->assertEquals($expect, $this->__($translate, $key, $module, $params));
|
45 |
+
}
|
46 |
+
|
47 |
+
protected function __(Mage_Core_Model_Translate $translate, $key, $module, array $params = [])
|
48 |
+
{
|
49 |
+
$expr = new Mage_Core_Model_Translate_Expr($key, $module);
|
50 |
+
|
51 |
+
$args = $params;
|
52 |
+
array_unshift($args, $expr);
|
53 |
+
return $translate->translate($args);
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
protected function addTranslations($translate, $data, $scope)
|
58 |
+
{
|
59 |
+
$addDataMethod = new ReflectionMethod('Mage_Core_Model_Translate', '_addData');
|
60 |
+
$addDataMethod->setAccessible(true);
|
61 |
+
|
62 |
+
$addDataMethod->invoke($translate, $data, $scope);
|
63 |
+
|
64 |
+
return $translate;
|
65 |
+
}
|
66 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageEavModelEntityAbstractTest.php
ADDED
@@ -0,0 +1,111 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_Model_Overwrite_MageEavModelEntityAbstractTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
public function testLoad()
|
7 |
+
{
|
8 |
+
$testData = ['a' => 'b'];
|
9 |
+
$readAdapter = $this->getMockBuilder('Magento_Db_Adapter_Pdo_Mysql')
|
10 |
+
->disableOriginalConstructor()
|
11 |
+
->setMethods(['fetchRow'])
|
12 |
+
->getMock();
|
13 |
+
|
14 |
+
$readAdapter->method('fetchRow')->willReturn($testData);
|
15 |
+
|
16 |
+
$entityAbstract = $this->getMockBuilder('Mage_Eav_Model_Entity_Abstract')
|
17 |
+
->setMethods(['dispatch', '_getReadAdapter', '_getLoadRowSelect', 'loadAllAttributes'])
|
18 |
+
->getMock();
|
19 |
+
|
20 |
+
$entityAbstract->method('_getReadAdapter')->willReturn($readAdapter);
|
21 |
+
|
22 |
+
$product = new Mage_Catalog_Model_Product();
|
23 |
+
|
24 |
+
|
25 |
+
$entityAbstract->expects($this->once())
|
26 |
+
->method('dispatch')
|
27 |
+
->with(
|
28 |
+
$this->equalTo('model_resource_db_load'),
|
29 |
+
$this->callback(function($subject) use ($product) {
|
30 |
+
return $subject['object'] === $product && isset($subject['time']);
|
31 |
+
})
|
32 |
+
);
|
33 |
+
|
34 |
+
|
35 |
+
$entityAbstract->load($product, 1);
|
36 |
+
}
|
37 |
+
|
38 |
+
public function testSave()
|
39 |
+
{
|
40 |
+
$entityAbstract = $this->getMockBuilder('Mage_Eav_Model_Entity_Abstract')
|
41 |
+
->setMethods(['dispatch', 'loadAllAttributes', '_beforeSave', '_processSaveData', '_collectSaveData', '_afterSave'])
|
42 |
+
->getMock();
|
43 |
+
|
44 |
+
$product = new Mage_Catalog_Model_Product();
|
45 |
+
$product->setData('entity_type_id', 1);
|
46 |
+
|
47 |
+
$entityAbstract->expects($this->once())
|
48 |
+
->method('dispatch')
|
49 |
+
->with(
|
50 |
+
$this->equalTo('model_resource_db_save'),
|
51 |
+
$this->callback(function($subject) use ($product) {
|
52 |
+
return $subject['object'] === $product && isset($subject['time']);
|
53 |
+
})
|
54 |
+
);
|
55 |
+
|
56 |
+
|
57 |
+
$entityAbstract->save($product, 1);
|
58 |
+
}
|
59 |
+
|
60 |
+
public function testSaveDeleted()
|
61 |
+
{
|
62 |
+
$entityAbstract = $this->getMockBuilder('Mage_Eav_Model_Entity_Abstract')
|
63 |
+
->setMethods(['dispatch', 'delete', 'loadAllAttributes', '_beforeSave', '_processSaveData', '_collectSaveData', '_afterSave'])
|
64 |
+
->getMock();
|
65 |
+
|
66 |
+
$product = new Mage_Catalog_Model_Product();
|
67 |
+
$product->setData('entity_type_id', 1);
|
68 |
+
$product->isDeleted(true);
|
69 |
+
$entityAbstract->expects($this->never())
|
70 |
+
->method('dispatch');
|
71 |
+
|
72 |
+
|
73 |
+
$entityAbstract->save($product, 1);
|
74 |
+
}
|
75 |
+
|
76 |
+
public function testDelete()
|
77 |
+
{
|
78 |
+
$writeAdapter = $this->getMockBuilder('Magento_Db_Adapter_Pdo_Mysql')
|
79 |
+
->disableOriginalConstructor()
|
80 |
+
->setMethods(['delete'])
|
81 |
+
->getMock();
|
82 |
+
|
83 |
+
|
84 |
+
$entityAbstract = $this->getMockBuilder('Mage_Eav_Model_Entity_Abstract')
|
85 |
+
->setMethods([
|
86 |
+
'dispatch', '_beforeDelete',
|
87 |
+
'getEntityIdField', '_getWriteAdapter',
|
88 |
+
'getEntityTable', 'loadAllAttributes', '_afterDelete'])
|
89 |
+
->getMock();
|
90 |
+
|
91 |
+
$entityAbstract->method('_getWriteAdapter')->willReturn($writeAdapter);
|
92 |
+
$entityAbstract->method('getEntityIdField')->willReturn('id');
|
93 |
+
|
94 |
+
|
95 |
+
$product = new Mage_Catalog_Model_Product();
|
96 |
+
$product->setData('entity_type_id', 1);
|
97 |
+
|
98 |
+
$entityAbstract->expects($this->once())
|
99 |
+
->method('dispatch')
|
100 |
+
->with(
|
101 |
+
$this->equalTo('model_resource_db_delete'),
|
102 |
+
$this->callback(function($subject) use ($product) {
|
103 |
+
return $subject['object'] === $product && isset($subject['time']);
|
104 |
+
})
|
105 |
+
);
|
106 |
+
|
107 |
+
|
108 |
+
|
109 |
+
$entityAbstract->delete($product, 1);
|
110 |
+
}
|
111 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageTest.php
ADDED
@@ -0,0 +1,43 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Tests_Dev_Model_Overwrite_MageTest
|
5 |
+
extends TestHelper
|
6 |
+
{
|
7 |
+
public function testGetLogger()
|
8 |
+
{
|
9 |
+
if (!class_exists('Monolog\Handler\TestHandler')) {
|
10 |
+
$this->markTestSkipped(
|
11 |
+
'Monolog not installed skipping.'
|
12 |
+
);
|
13 |
+
}
|
14 |
+
$logger = Mage::getLogger();
|
15 |
+
|
16 |
+
$this->assertInstanceOf('Ecocode_Profiler_Model_Logger', $logger);
|
17 |
+
$this->assertEquals(Mage::getDefaultLogger(), $logger);
|
18 |
+
|
19 |
+
$this->assertNotEquals(Mage::getDefaultLogger(), Mage::getLogger('new'));
|
20 |
+
}
|
21 |
+
|
22 |
+
public function testLog()
|
23 |
+
{
|
24 |
+
if (!class_exists('Monolog\Handler\TestHandler')) {
|
25 |
+
$this->markTestSkipped(
|
26 |
+
'Monolog not installed skipping.'
|
27 |
+
);
|
28 |
+
}
|
29 |
+
$logger = Mage::getLogger();
|
30 |
+
|
31 |
+
$this->assertCount(0, $logger->getLogs());
|
32 |
+
|
33 |
+
Mage::log('test');
|
34 |
+
Mage::log('test', Zend_Log::ALERT, 'error.log');
|
35 |
+
|
36 |
+
$logs = $logger->getLogs();
|
37 |
+
$this->assertCount(2, $logs);
|
38 |
+
$lastLog = end($logs);
|
39 |
+
|
40 |
+
$this->assertEquals(Ecocode_Profiler_Model_Logger::ALERT, $lastLog['priority']);
|
41 |
+
$this->assertEquals('error', $lastLog['channel']);
|
42 |
+
}
|
43 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/Profiler/FileStorageTest.php
ADDED
@@ -0,0 +1,346 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of the Symfony package.
|
5 |
+
*
|
6 |
+
* (c) Fabien Potencier <fabien@symfony.com>
|
7 |
+
*
|
8 |
+
* For the full copyright and license information, please view the LICENSE
|
9 |
+
* file that was distributed with this source code.
|
10 |
+
*/
|
11 |
+
|
12 |
+
|
13 |
+
class Ecocode_Profiler_Tests_Dev_Model_Profiler_FileStorageTest
|
14 |
+
extends \TestHelper
|
15 |
+
{
|
16 |
+
private $tmpDir;
|
17 |
+
private $storage;
|
18 |
+
|
19 |
+
protected function setUp()
|
20 |
+
{
|
21 |
+
$this->tmpDir = sys_get_temp_dir() . '/sf2_profiler_file_storage';
|
22 |
+
if (is_dir($this->tmpDir)) {
|
23 |
+
self::cleanDir();
|
24 |
+
}
|
25 |
+
$this->storage = new Ecocode_Profiler_Model_Profiler_FileStorage(['dsn' => 'file:' . $this->tmpDir]);
|
26 |
+
$this->storage->purge();
|
27 |
+
}
|
28 |
+
|
29 |
+
protected function tearDown()
|
30 |
+
{
|
31 |
+
self::cleanDir();
|
32 |
+
}
|
33 |
+
|
34 |
+
public function testStore()
|
35 |
+
{
|
36 |
+
for ($i = 0; $i < 10; ++$i) {
|
37 |
+
$profile = new Ecocode_Profiler_Model_Profile('token_' . $i);
|
38 |
+
$profile->setIp('127.0.0.1');
|
39 |
+
$profile->setUrl('http://foo.bar');
|
40 |
+
$profile->setMethod('GET');
|
41 |
+
$this->storage->write($profile);
|
42 |
+
}
|
43 |
+
$this->assertCount(10, $this->storage->find('127.0.0.1', 'http://foo.bar', 20, 'GET'), '->write() stores data in the storage');
|
44 |
+
}
|
45 |
+
|
46 |
+
public function testChildren()
|
47 |
+
{
|
48 |
+
$parentProfile = new Ecocode_Profiler_Model_Profile('token_parent');
|
49 |
+
$parentProfile->setIp('127.0.0.1');
|
50 |
+
$parentProfile->setUrl('http://foo.bar/parent');
|
51 |
+
|
52 |
+
$childProfile = new Ecocode_Profiler_Model_Profile('token_child');
|
53 |
+
$childProfile->setIp('127.0.0.1');
|
54 |
+
$childProfile->setUrl('http://foo.bar/child');
|
55 |
+
|
56 |
+
$parentProfile->addChild($childProfile);
|
57 |
+
|
58 |
+
$this->storage->write($parentProfile);
|
59 |
+
$this->storage->write($childProfile);
|
60 |
+
|
61 |
+
// Load them from storage
|
62 |
+
$parentProfile = $this->storage->read('token_parent');
|
63 |
+
$childProfile = $this->storage->read('token_child');
|
64 |
+
|
65 |
+
// Check child has link to parent
|
66 |
+
$this->assertNotNull($childProfile->getParent());
|
67 |
+
$this->assertEquals($parentProfile->getToken(), $childProfile->getParentToken());
|
68 |
+
|
69 |
+
// Check parent has child
|
70 |
+
$children = $parentProfile->getChildren();
|
71 |
+
$this->assertCount(1, $children);
|
72 |
+
$this->assertEquals($childProfile->getToken(), $children[0]->getToken());
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testStoreSpecialCharsInUrl()
|
76 |
+
{
|
77 |
+
// The storage accepts special characters in URLs (Even though URLs are not
|
78 |
+
// supposed to contain them)
|
79 |
+
$profile = new Ecocode_Profiler_Model_Profile('simple_quote');
|
80 |
+
$profile->setUrl('http://foo.bar/\'');
|
81 |
+
$this->storage->write($profile);
|
82 |
+
$this->assertTrue(false !== $this->storage->read('simple_quote'), '->write() accepts single quotes in URL');
|
83 |
+
|
84 |
+
$profile = new Ecocode_Profiler_Model_Profile('double_quote');
|
85 |
+
$profile->setUrl('http://foo.bar/"');
|
86 |
+
$this->storage->write($profile);
|
87 |
+
$this->assertTrue(false !== $this->storage->read('double_quote'), '->write() accepts double quotes in URL');
|
88 |
+
|
89 |
+
$profile = new Ecocode_Profiler_Model_Profile('backslash');
|
90 |
+
$profile->setUrl('http://foo.bar/\\');
|
91 |
+
$this->storage->write($profile);
|
92 |
+
$this->assertTrue(false !== $this->storage->read('backslash'), '->write() accepts backslash in URL');
|
93 |
+
|
94 |
+
$profile = new Ecocode_Profiler_Model_Profile('comma');
|
95 |
+
$profile->setUrl('http://foo.bar/,');
|
96 |
+
$this->storage->write($profile);
|
97 |
+
$this->assertTrue(false !== $this->storage->read('comma'), '->write() accepts comma in URL');
|
98 |
+
}
|
99 |
+
|
100 |
+
public function testStoreDuplicateToken()
|
101 |
+
{
|
102 |
+
$profile = new Ecocode_Profiler_Model_Profile('token');
|
103 |
+
$profile->setUrl('http://example.com/');
|
104 |
+
|
105 |
+
$this->assertTrue($this->storage->write($profile), '->write() returns true when the token is unique');
|
106 |
+
|
107 |
+
$profile->setUrl('http://example.net/');
|
108 |
+
|
109 |
+
$this->assertTrue($this->storage->write($profile), '->write() returns true when the token is already present in the storage');
|
110 |
+
$this->assertEquals('http://example.net/', $this->storage->read('token')->getUrl(), '->write() overwrites the current profile data');
|
111 |
+
|
112 |
+
$this->assertCount(1, $this->storage->find('', '', 1000, ''), '->find() does not return the same profile twice');
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testRetrieveByIp()
|
116 |
+
{
|
117 |
+
$profile = new Ecocode_Profiler_Model_Profile('token');
|
118 |
+
$profile->setIp('127.0.0.1');
|
119 |
+
$profile->setMethod('GET');
|
120 |
+
$this->storage->write($profile);
|
121 |
+
|
122 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', '', 10, 'GET'), '->find() retrieve a record by IP');
|
123 |
+
$this->assertCount(0, $this->storage->find('127.0.%.1', '', 10, 'GET'), '->find() does not interpret a "%" as a wildcard in the IP');
|
124 |
+
$this->assertCount(0, $this->storage->find('127.0._.1', '', 10, 'GET'), '->find() does not interpret a "_" as a wildcard in the IP');
|
125 |
+
}
|
126 |
+
|
127 |
+
public function testRetrieveByStatusCode()
|
128 |
+
{
|
129 |
+
$profile200 = new Ecocode_Profiler_Model_Profile('statuscode200');
|
130 |
+
$profile200->setStatusCode(200);
|
131 |
+
$this->storage->write($profile200);
|
132 |
+
|
133 |
+
$profile404 = new Ecocode_Profiler_Model_Profile('statuscode404');
|
134 |
+
$profile404->setStatusCode(404);
|
135 |
+
$this->storage->write($profile404);
|
136 |
+
|
137 |
+
$this->assertCount(1, $this->storage->find(null, null, 10, null, null, null, '200'), '->find() retrieve a record by Status code 200');
|
138 |
+
$this->assertCount(1, $this->storage->find(null, null, 10, null, null, null, '404'), '->find() retrieve a record by Status code 404');
|
139 |
+
}
|
140 |
+
|
141 |
+
public function testRetrieveByUrl()
|
142 |
+
{
|
143 |
+
$profile = new Ecocode_Profiler_Model_Profile('simple_quote');
|
144 |
+
$profile->setIp('127.0.0.1');
|
145 |
+
$profile->setUrl('http://foo.bar/\'');
|
146 |
+
$profile->setMethod('GET');
|
147 |
+
$this->storage->write($profile);
|
148 |
+
|
149 |
+
$profile = new Ecocode_Profiler_Model_Profile('double_quote');
|
150 |
+
$profile->setIp('127.0.0.1');
|
151 |
+
$profile->setUrl('http://foo.bar/"');
|
152 |
+
$profile->setMethod('GET');
|
153 |
+
$this->storage->write($profile);
|
154 |
+
|
155 |
+
$profile = new Ecocode_Profiler_Model_Profile('backslash');
|
156 |
+
$profile->setIp('127.0.0.1');
|
157 |
+
$profile->setUrl('http://foo\\bar/');
|
158 |
+
$profile->setMethod('GET');
|
159 |
+
$this->storage->write($profile);
|
160 |
+
|
161 |
+
$profile = new Ecocode_Profiler_Model_Profile('percent');
|
162 |
+
$profile->setIp('127.0.0.1');
|
163 |
+
$profile->setUrl('http://foo.bar/%');
|
164 |
+
$profile->setMethod('GET');
|
165 |
+
$this->storage->write($profile);
|
166 |
+
|
167 |
+
$profile = new Ecocode_Profiler_Model_Profile('underscore');
|
168 |
+
$profile->setIp('127.0.0.1');
|
169 |
+
$profile->setUrl('http://foo.bar/_');
|
170 |
+
$profile->setMethod('GET');
|
171 |
+
$this->storage->write($profile);
|
172 |
+
|
173 |
+
$profile = new Ecocode_Profiler_Model_Profile('semicolon');
|
174 |
+
$profile->setIp('127.0.0.1');
|
175 |
+
$profile->setUrl('http://foo.bar/;');
|
176 |
+
$profile->setMethod('GET');
|
177 |
+
$this->storage->write($profile);
|
178 |
+
|
179 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/\'', 10, 'GET'), '->find() accepts single quotes in URLs');
|
180 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/"', 10, 'GET'), '->find() accepts double quotes in URLs');
|
181 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo\\bar/', 10, 'GET'), '->find() accepts backslash in URLs');
|
182 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/;', 10, 'GET'), '->find() accepts semicolon in URLs');
|
183 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/%', 10, 'GET'), '->find() does not interpret a "%" as a wildcard in the URL');
|
184 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', 'http://foo.bar/_', 10, 'GET'), '->find() does not interpret a "_" as a wildcard in the URL');
|
185 |
+
}
|
186 |
+
|
187 |
+
public function testStoreTime()
|
188 |
+
{
|
189 |
+
$dt = new \DateTime('now');
|
190 |
+
$start = $dt->getTimestamp();
|
191 |
+
|
192 |
+
for ($i = 0; $i < 3; ++$i) {
|
193 |
+
$dt->modify('+1 minute');
|
194 |
+
$profile = new Ecocode_Profiler_Model_Profile('time_' . $i);
|
195 |
+
$profile->setIp('127.0.0.1');
|
196 |
+
$profile->setUrl('http://foo.bar');
|
197 |
+
$profile->setTime($dt->getTimestamp());
|
198 |
+
$profile->setMethod('GET');
|
199 |
+
$this->storage->write($profile);
|
200 |
+
}
|
201 |
+
|
202 |
+
$records = $this->storage->find('', '', 3, 'GET', $start, time() + 3 * 60);
|
203 |
+
$this->assertCount(3, $records, '->find() returns all previously added records');
|
204 |
+
$this->assertEquals($records[0]['token'], 'time_2', '->find() returns records ordered by time in descendant order');
|
205 |
+
$this->assertEquals($records[1]['token'], 'time_1', '->find() returns records ordered by time in descendant order');
|
206 |
+
$this->assertEquals($records[2]['token'], 'time_0', '->find() returns records ordered by time in descendant order');
|
207 |
+
|
208 |
+
$records = $this->storage->find('', '', 3, 'GET', $start, time() + 2 * 60);
|
209 |
+
$this->assertCount(2, $records, '->find() should return only first two of the previously added records');
|
210 |
+
}
|
211 |
+
|
212 |
+
public function testRetrieveByEmptyUrlAndIp()
|
213 |
+
{
|
214 |
+
for ($i = 0; $i < 5; ++$i) {
|
215 |
+
$profile = new Ecocode_Profiler_Model_Profile('token_' . $i);
|
216 |
+
$profile->setMethod('GET');
|
217 |
+
$this->storage->write($profile);
|
218 |
+
}
|
219 |
+
$this->assertCount(5, $this->storage->find('', '', 10, 'GET'), '->find() returns all previously added records');
|
220 |
+
$this->storage->purge();
|
221 |
+
}
|
222 |
+
|
223 |
+
public function testRetrieveByMethodAndLimit()
|
224 |
+
{
|
225 |
+
foreach (['POST', 'GET'] as $method) {
|
226 |
+
for ($i = 0; $i < 5; ++$i) {
|
227 |
+
$profile = new Ecocode_Profiler_Model_Profile('token_' . $i . $method);
|
228 |
+
$profile->setMethod($method);
|
229 |
+
$this->storage->write($profile);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
$this->assertCount(5, $this->storage->find('', '', 5, 'POST'));
|
234 |
+
|
235 |
+
$this->storage->purge();
|
236 |
+
}
|
237 |
+
|
238 |
+
public function testPurge()
|
239 |
+
{
|
240 |
+
$profile = new Ecocode_Profiler_Model_Profile('token1');
|
241 |
+
$profile->setIp('127.0.0.1');
|
242 |
+
$profile->setUrl('http://example.com/');
|
243 |
+
$profile->setMethod('GET');
|
244 |
+
$this->storage->write($profile);
|
245 |
+
|
246 |
+
$this->assertTrue(false !== $this->storage->read('token1'));
|
247 |
+
$this->assertCount(1, $this->storage->find('127.0.0.1', '', 10, 'GET'));
|
248 |
+
|
249 |
+
$profile = new Ecocode_Profiler_Model_Profile('token2');
|
250 |
+
$profile->setIp('127.0.0.1');
|
251 |
+
$profile->setUrl('http://example.net/');
|
252 |
+
$profile->setMethod('GET');
|
253 |
+
$this->storage->write($profile);
|
254 |
+
|
255 |
+
$this->assertTrue(false !== $this->storage->read('token2'));
|
256 |
+
$this->assertCount(2, $this->storage->find('127.0.0.1', '', 10, 'GET'));
|
257 |
+
|
258 |
+
$this->storage->purge();
|
259 |
+
|
260 |
+
$this->assertEmpty($this->storage->read('token'), '->purge() removes all data stored by profiler');
|
261 |
+
$this->assertCount(0, $this->storage->find('127.0.0.1', '', 10, 'GET'), '->purge() removes all items from index');
|
262 |
+
}
|
263 |
+
|
264 |
+
public function testDuplicates()
|
265 |
+
{
|
266 |
+
for ($i = 1; $i <= 5; ++$i) {
|
267 |
+
$profile = new Ecocode_Profiler_Model_Profile('foo' . $i);
|
268 |
+
$profile->setIp('127.0.0.1');
|
269 |
+
$profile->setUrl('http://example.net/');
|
270 |
+
$profile->setMethod('GET');
|
271 |
+
|
272 |
+
///three duplicates
|
273 |
+
$this->storage->write($profile);
|
274 |
+
$this->storage->write($profile);
|
275 |
+
$this->storage->write($profile);
|
276 |
+
}
|
277 |
+
$this->assertCount(3, $this->storage->find('127.0.0.1', 'http://example.net/', 3, 'GET'), '->find() method returns incorrect number of entries');
|
278 |
+
}
|
279 |
+
|
280 |
+
public function testStatusCode()
|
281 |
+
{
|
282 |
+
$profile = new Ecocode_Profiler_Model_Profile('token1');
|
283 |
+
$profile->setStatusCode(200);
|
284 |
+
$this->storage->write($profile);
|
285 |
+
|
286 |
+
$profile = new Ecocode_Profiler_Model_Profile('token2');
|
287 |
+
$profile->setStatusCode(404);
|
288 |
+
$this->storage->write($profile);
|
289 |
+
|
290 |
+
$tokens = $this->storage->find('', '', 10, '');
|
291 |
+
$this->assertCount(2, $tokens);
|
292 |
+
$this->assertContains($tokens[0]['status_code'], [200, 404]);
|
293 |
+
$this->assertContains($tokens[1]['status_code'], [200, 404]);
|
294 |
+
}
|
295 |
+
|
296 |
+
public function testMultiRowIndexFile()
|
297 |
+
{
|
298 |
+
$iteration = 3;
|
299 |
+
for ($i = 0; $i < $iteration; ++$i) {
|
300 |
+
$profile = new Ecocode_Profiler_Model_Profile('token' . $i);
|
301 |
+
$profile->setIp('127.0.0.' . $i);
|
302 |
+
$profile->setUrl('http://foo.bar/' . $i);
|
303 |
+
|
304 |
+
$this->storage->write($profile);
|
305 |
+
$this->storage->write($profile);
|
306 |
+
$this->storage->write($profile);
|
307 |
+
}
|
308 |
+
|
309 |
+
$handle = fopen($this->tmpDir . '/index.csv', 'r');
|
310 |
+
for ($i = 0; $i < $iteration; ++$i) {
|
311 |
+
$row = fgetcsv($handle);
|
312 |
+
$this->assertEquals('token' . $i, $row[0]);
|
313 |
+
$this->assertEquals('127.0.0.' . $i, $row[1]);
|
314 |
+
$this->assertEquals('http://foo.bar/' . $i, $row[3]);
|
315 |
+
}
|
316 |
+
$this->assertFalse(fgetcsv($handle));
|
317 |
+
}
|
318 |
+
|
319 |
+
public function testReadLineFromFile()
|
320 |
+
{
|
321 |
+
$r = new \ReflectionMethod($this->storage, 'readLineFromFile');
|
322 |
+
|
323 |
+
$r->setAccessible(true);
|
324 |
+
|
325 |
+
$h = tmpfile();
|
326 |
+
|
327 |
+
fwrite($h, "line1\n\n\nline2\n");
|
328 |
+
fseek($h, 0, SEEK_END);
|
329 |
+
|
330 |
+
$this->assertEquals('line2', $r->invoke($this->storage, $h));
|
331 |
+
$this->assertEquals('line1', $r->invoke($this->storage, $h));
|
332 |
+
}
|
333 |
+
|
334 |
+
protected function cleanDir()
|
335 |
+
{
|
336 |
+
$flags = \FilesystemIterator::SKIP_DOTS;
|
337 |
+
$iterator = new \RecursiveDirectoryIterator($this->tmpDir, $flags);
|
338 |
+
$iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST);
|
339 |
+
|
340 |
+
foreach ($iterator as $file) {
|
341 |
+
if (is_file($file)) {
|
342 |
+
unlink($file);
|
343 |
+
}
|
344 |
+
}
|
345 |
+
}
|
346 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/Model/ProfilerTest.php
ADDED
@@ -0,0 +1,58 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Tests_Dev_Model_ProfilerTest extends TestHelper
|
5 |
+
{
|
6 |
+
private $tmp;
|
7 |
+
/** @var Ecocode_Profiler_Model_Profiler_FileStorage */
|
8 |
+
private $storage;
|
9 |
+
|
10 |
+
public function testFindWorksWithDates()
|
11 |
+
{
|
12 |
+
$profiler = new Ecocode_Profiler_Model_Profiler($this->storage);
|
13 |
+
|
14 |
+
$this->assertCount(0, $profiler->find(null, null, null, null, '7th April 2014', '9th April 2014'));
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testFindWorksWithTimestamps()
|
18 |
+
{
|
19 |
+
$profiler = new Ecocode_Profiler_Model_Profiler($this->storage);
|
20 |
+
|
21 |
+
$this->assertCount(0, $profiler->find(null, null, null, null, '1396828800', '1397001600'));
|
22 |
+
}
|
23 |
+
|
24 |
+
public function testFindWorksWithInvalidDates()
|
25 |
+
{
|
26 |
+
$profiler = new Ecocode_Profiler_Model_Profiler($this->storage);
|
27 |
+
|
28 |
+
$this->assertCount(0, $profiler->find(null, null, null, null, 'some string', ''));
|
29 |
+
}
|
30 |
+
|
31 |
+
public function testFindWorksWithStatusCode()
|
32 |
+
{
|
33 |
+
$profiler = new Ecocode_Profiler_Model_Profiler($this->storage);
|
34 |
+
|
35 |
+
$this->assertCount(0, $profiler->find(null, null, null, null, null, null, '204'));
|
36 |
+
}
|
37 |
+
|
38 |
+
protected function setUp()
|
39 |
+
{
|
40 |
+
$this->tmp = tempnam(sys_get_temp_dir(), 'sf2_profiler');
|
41 |
+
if (file_exists($this->tmp)) {
|
42 |
+
@unlink($this->tmp);
|
43 |
+
}
|
44 |
+
|
45 |
+
$this->storage = new Ecocode_Profiler_Model_Profiler_FileStorage(['dsn' => 'file:' . $this->tmp]);
|
46 |
+
$this->storage->purge();
|
47 |
+
}
|
48 |
+
|
49 |
+
protected function tearDown()
|
50 |
+
{
|
51 |
+
if (null !== $this->storage) {
|
52 |
+
$this->storage->purge();
|
53 |
+
$this->storage = null;
|
54 |
+
|
55 |
+
@unlink($this->tmp);
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Dev/bootstrap.php
ADDED
@@ -0,0 +1,54 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (isset($_SERVER['MAGENTO_DIRECTORY'])) {
|
4 |
+
$_baseDir = $_SERVER['MAGENTO_DIRECTORY'];
|
5 |
+
} else {
|
6 |
+
$_baseDir = getcwd();
|
7 |
+
}
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Define MAGE_PATH
|
11 |
+
* Path to Magento
|
12 |
+
*/
|
13 |
+
define('MAGENTO_ROOT', $_baseDir);
|
14 |
+
|
15 |
+
// Include Mage file by detecting app root
|
16 |
+
require_once $_baseDir . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'MageDev.php';
|
17 |
+
|
18 |
+
if (!Mage::isInstalled()) {
|
19 |
+
throw new RuntimeException('Magento Unit Tests can run only on installed version');
|
20 |
+
}
|
21 |
+
|
22 |
+
|
23 |
+
/* Replace server variables for proper file naming */
|
24 |
+
$_SERVER['SCRIPT_NAME'] = $_baseDir . DS . 'index.php';
|
25 |
+
$_SERVER['SCRIPT_FILENAME'] = $_baseDir . DS . 'index.php';
|
26 |
+
|
27 |
+
//fill the session to prevent session_start issues
|
28 |
+
$_SESSION = ['x' => 'y'];
|
29 |
+
|
30 |
+
//flag to check for unittets
|
31 |
+
define('BASE_TESTS_PATH', realpath(dirname(__FILE__)));
|
32 |
+
require_once BASE_TESTS_PATH . '/../TestHelper.php';
|
33 |
+
|
34 |
+
$options = [
|
35 |
+
'cache' => ['id_prefix' => 'test-dev'],
|
36 |
+
'config_model' => 'Ecocode_Profiler_Model_Core_Config'
|
37 |
+
];
|
38 |
+
Mage::app('', 'store', $options);
|
39 |
+
|
40 |
+
// Removing Varien Autoload, to prevent errors with PHPUnit components
|
41 |
+
spl_autoload_unregister([\Varien_Autoload::instance(), 'autoload']);
|
42 |
+
spl_autoload_register(function ($className) {
|
43 |
+
$filePath = strtr(
|
44 |
+
ltrim($className, '\\'),
|
45 |
+
[
|
46 |
+
'\\' => '/',
|
47 |
+
'_' => '/'
|
48 |
+
]
|
49 |
+
);
|
50 |
+
$file = $filePath . '.php';
|
51 |
+
if (stream_resolve_include_path($file)) {
|
52 |
+
include $filePath . '.php';
|
53 |
+
}
|
54 |
+
});
|
app/code/community/Ecocode/Profiler/Tests/Dev/controllers/CacheControllerTest.php
ADDED
@@ -0,0 +1,168 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_Dev_CacheControllerTest extends TestHelper
|
4 |
+
{
|
5 |
+
protected function getMockedController($class, $request = null, $response = null, $app = null)
|
6 |
+
{
|
7 |
+
if (!$request instanceof Mage_Core_Controller_Request_Http) {
|
8 |
+
$_request = new Mage_Core_Controller_Request_Http();
|
9 |
+
if (is_array($request)) {
|
10 |
+
$_request->setParams($request);
|
11 |
+
|
12 |
+
}
|
13 |
+
$request = $_request;
|
14 |
+
|
15 |
+
}
|
16 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
17 |
+
$appMock = $app ? $app : $this->getMockBuilder('Mage_Core_Model_App')->getMock();
|
18 |
+
|
19 |
+
$controller = $this->getMockBuilder($class)
|
20 |
+
->setMethods(['getApp'])
|
21 |
+
->setConstructorArgs([$request, $response])
|
22 |
+
->getMock();
|
23 |
+
|
24 |
+
$controller->method('getApp')
|
25 |
+
->willReturn($appMock);
|
26 |
+
|
27 |
+
|
28 |
+
return $controller;
|
29 |
+
}
|
30 |
+
|
31 |
+
public function setUp()
|
32 |
+
{
|
33 |
+
parent::setUp();
|
34 |
+
|
35 |
+
require_once Mage::getModuleDir('controllers', 'Ecocode_Profiler') . DS . 'CacheController.php';
|
36 |
+
}
|
37 |
+
|
38 |
+
|
39 |
+
public function testClearAction()
|
40 |
+
{
|
41 |
+
$appMock = $this->getMockBuilder('Mage_Core_Model_App')->getMock();
|
42 |
+
$controller = $this->getMockedController(
|
43 |
+
'Ecocode_Profiler_CacheController',
|
44 |
+
['types' => join(',', ['test', 'block_html', 'config'])],
|
45 |
+
null, $appMock
|
46 |
+
);
|
47 |
+
|
48 |
+
$cache = $this->getMockBuilder('Mage_Core_Model_Cache')->getMock();
|
49 |
+
$appMock->method('getCacheInstance')
|
50 |
+
->willReturn($cache);
|
51 |
+
|
52 |
+
$cache
|
53 |
+
->expects($this->exactly(3))
|
54 |
+
->method('cleanType');
|
55 |
+
|
56 |
+
|
57 |
+
/** @var Ecocode_Profiler_CacheController $controller */
|
58 |
+
$controller->clearAction();
|
59 |
+
}
|
60 |
+
|
61 |
+
public function testClearAllAction()
|
62 |
+
{
|
63 |
+
$appMock = $this->getMockBuilder('Mage_Core_Model_App')->getMock();
|
64 |
+
$controller = $this->getMockedController(
|
65 |
+
'Ecocode_Profiler_CacheController',
|
66 |
+
null, null, $appMock
|
67 |
+
);
|
68 |
+
|
69 |
+
$cache = $this->getMockBuilder('Mage_Core_Model_Cache')->getMock();
|
70 |
+
$appMock->method('getCacheInstance')
|
71 |
+
->willReturn($cache);
|
72 |
+
|
73 |
+
$cache
|
74 |
+
->expects($this->once())
|
75 |
+
->method('flush');
|
76 |
+
|
77 |
+
/** @var Ecocode_Profiler_CacheController $controller */
|
78 |
+
$controller->clearAllAction();
|
79 |
+
}
|
80 |
+
|
81 |
+
public function testEnableAction()
|
82 |
+
{
|
83 |
+
$request = new Mage_Core_Controller_Request_Http();
|
84 |
+
$request->setParams(['types' => 'config,block_html']);
|
85 |
+
|
86 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
87 |
+
$controller = $this->getMockBuilder('Ecocode_Profiler_CacheController')
|
88 |
+
->setMethods(['setCacheStatus'])
|
89 |
+
->setConstructorArgs([$request, $response])
|
90 |
+
->getMock();
|
91 |
+
|
92 |
+
|
93 |
+
$controller
|
94 |
+
->expects($this->once())
|
95 |
+
->method('setCacheStatus')
|
96 |
+
->with(
|
97 |
+
$this->equalTo(['config', 'block_html']),
|
98 |
+
$this->equalTo(1)
|
99 |
+
);
|
100 |
+
|
101 |
+
/** @var Ecocode_Profiler_CacheController $controller */
|
102 |
+
$controller->enableAction();
|
103 |
+
}
|
104 |
+
|
105 |
+
public function testDisableAction()
|
106 |
+
{
|
107 |
+
$request = new Mage_Core_Controller_Request_Http();
|
108 |
+
$request->setParams(['types' => 'config,block_html']);
|
109 |
+
|
110 |
+
$response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp();
|
111 |
+
$controller = $this->getMockBuilder('Ecocode_Profiler_CacheController')
|
112 |
+
->setMethods(['setCacheStatus'])
|
113 |
+
->setConstructorArgs([$request, $response])
|
114 |
+
->getMock();
|
115 |
+
|
116 |
+
|
117 |
+
$controller
|
118 |
+
->expects($this->once())
|
119 |
+
->method('setCacheStatus')
|
120 |
+
->with(
|
121 |
+
$this->equalTo(['config', 'block_html']),
|
122 |
+
$this->equalTo(0)
|
123 |
+
);
|
124 |
+
|
125 |
+
/** @var Ecocode_Profiler_CacheController $controller */
|
126 |
+
$controller->disableAction();
|
127 |
+
}
|
128 |
+
|
129 |
+
public function testSetCacheStatus()
|
130 |
+
{
|
131 |
+
$types = [
|
132 |
+
'config' => new Varien_Object(['id' => 'config', 'status' => 0]),
|
133 |
+
'block_html' => new Varien_Object(['id' => 'block_html', 'status' => 0])
|
134 |
+
];
|
135 |
+
|
136 |
+
|
137 |
+
$cacheMock = $this->getMockBuilder('Mage_Core_Model_Cache')
|
138 |
+
->getMock();
|
139 |
+
$cacheMock->method('getTypes')->willReturn($types);
|
140 |
+
|
141 |
+
$appMock = $this->getMockBuilder('Mage_Core_Model_App')
|
142 |
+
->setMethods(['saveUseCache', 'getCacheInstance', 'getCache'])
|
143 |
+
->getMock();
|
144 |
+
|
145 |
+
$appMock->method('getCacheInstance')->willReturn($cacheMock);
|
146 |
+
$appMock->method('getCache')->willReturn($cacheMock);
|
147 |
+
|
148 |
+
$this->initApp($appMock);
|
149 |
+
$controller = $this->getMockedController(
|
150 |
+
'Ecocode_Profiler_CacheController',
|
151 |
+
null, null, $appMock
|
152 |
+
);
|
153 |
+
|
154 |
+
$status = 1;
|
155 |
+
|
156 |
+
$setCacheStatusMethod = new ReflectionMethod('Ecocode_Profiler_CacheController', 'setCacheStatus');
|
157 |
+
$setCacheStatusMethod->setAccessible(true);
|
158 |
+
|
159 |
+
$types = array_fill_keys(array_keys($types), 0);
|
160 |
+
$types['block_html'] = 1;
|
161 |
+
|
162 |
+
$appMock->expects($this->once())
|
163 |
+
->method('saveUseCache')
|
164 |
+
->with($this->equalTo($types));
|
165 |
+
|
166 |
+
$setCacheStatusMethod->invoke($controller, ['block_html', 'test'], $status);
|
167 |
+
}
|
168 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Prod/DevModeTest.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_Tests_DevModeTest
|
4 |
+
extends TestHelper
|
5 |
+
{
|
6 |
+
|
7 |
+
|
8 |
+
public function testDisabledInProduction()
|
9 |
+
{
|
10 |
+
$app = Mage::app();
|
11 |
+
|
12 |
+
$this->assertNotInstanceOf(
|
13 |
+
'Ecocode_Profiler_Model_AppDev',
|
14 |
+
$app
|
15 |
+
);
|
16 |
+
}
|
17 |
+
|
18 |
+
public function testCollectorsNotLoaded()
|
19 |
+
{
|
20 |
+
$app = Mage::app();
|
21 |
+
|
22 |
+
$value = $app->getConfig()->getNode('ecocode/profiler');
|
23 |
+
$this->assertFalse($value);
|
24 |
+
}
|
25 |
+
|
26 |
+
public function testModelsNotLoaded()
|
27 |
+
{
|
28 |
+
$app = Mage::app();
|
29 |
+
|
30 |
+
$value = $app->getConfig()->getNode('global/models/ecocode_profiler');
|
31 |
+
$this->assertFalse($value);
|
32 |
+
}
|
33 |
+
}
|
app/code/community/Ecocode/Profiler/Tests/Prod/bootstrap.php
ADDED
@@ -0,0 +1,51 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (isset($_SERVER['MAGENTO_DIRECTORY'])) {
|
4 |
+
$_baseDir = $_SERVER['MAGENTO_DIRECTORY'];
|
5 |
+
} else {
|
6 |
+
$_baseDir = getcwd();
|
7 |
+
}
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Define MAGE_PATH
|
11 |
+
* Path to Magento
|
12 |
+
*/
|
13 |
+
define('MAGENTO_ROOT', $_baseDir);
|
14 |
+
|
15 |
+
// Include Mage file by detecting app root
|
16 |
+
require_once $_baseDir . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'Mage.php';
|
17 |
+
|
18 |
+
if (!Mage::isInstalled()) {
|
19 |
+
throw new RuntimeException('Magento Unit Tests can run only on installed version');
|
20 |
+
}
|
21 |
+
|
22 |
+
|
23 |
+
/* Replace server variables for proper file naming */
|
24 |
+
$_SERVER['SCRIPT_NAME'] = $_baseDir . DS . 'index.php';
|
25 |
+
$_SERVER['SCRIPT_FILENAME'] = $_baseDir . DS . 'index.php';
|
26 |
+
|
27 |
+
|
28 |
+
//flag to check for unittets
|
29 |
+
define('BASE_TESTS_PATH', realpath(dirname(__FILE__)));
|
30 |
+
require_once BASE_TESTS_PATH . '/../TestHelper.php';
|
31 |
+
|
32 |
+
$options = [
|
33 |
+
'cache' => ['id_prefix' => 'test-prod']
|
34 |
+
];
|
35 |
+
Mage::app()->cleanCache();
|
36 |
+
Mage::app('', 'store', $options);
|
37 |
+
// Removing Varien Autoload, to prevent errors with PHPUnit components
|
38 |
+
spl_autoload_unregister([\Varien_Autoload::instance(), 'autoload']);
|
39 |
+
spl_autoload_register(function ($className) {
|
40 |
+
$filePath = strtr(
|
41 |
+
ltrim($className, '\\'),
|
42 |
+
[
|
43 |
+
'\\' => '/',
|
44 |
+
'_' => '/'
|
45 |
+
]
|
46 |
+
);
|
47 |
+
$file = $filePath . '.php';
|
48 |
+
if (stream_resolve_include_path($file)) {
|
49 |
+
include $filePath . '.php';
|
50 |
+
}
|
51 |
+
});
|
app/code/community/Ecocode/Profiler/Tests/TestHelper.php
ADDED
@@ -0,0 +1,91 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TestHelper extends PHPUnit_Framework_TestCase
|
4 |
+
{
|
5 |
+
protected static $mageAppReflection;
|
6 |
+
|
7 |
+
protected $reInetMage = false;
|
8 |
+
|
9 |
+
protected $mageDefaultProperties = [
|
10 |
+
'_registry' => [],
|
11 |
+
'_isDownloader' => false,
|
12 |
+
'_isDeveloperMode' => false,
|
13 |
+
'headersSentThrowsException' => true,
|
14 |
+
];
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @beforeClass
|
18 |
+
*/
|
19 |
+
protected function setUp()
|
20 |
+
{
|
21 |
+
$this->initAppOnMageClass($this->reInetMage);
|
22 |
+
}
|
23 |
+
|
24 |
+
public function resetMage()
|
25 |
+
{
|
26 |
+
if (!isset($this->mageDefaultProperties['_appRoot'])) {
|
27 |
+
//save to original mage root
|
28 |
+
$this->mageDefaultProperties['_appRoot'] = Mage::getRoot();
|
29 |
+
}
|
30 |
+
$mageReflectionClass = new \ReflectionClass('Mage');
|
31 |
+
$properties = $mageReflectionClass->getStaticProperties();
|
32 |
+
|
33 |
+
foreach($properties as $key => $value) {
|
34 |
+
$reflectedProperty = $mageReflectionClass->getProperty($key);
|
35 |
+
$reflectedProperty->setAccessible(true);
|
36 |
+
$value = null;
|
37 |
+
if (isset($this->mageDefaultProperties[$key])) {
|
38 |
+
$value = $this->mageDefaultProperties[$key];
|
39 |
+
}
|
40 |
+
$reflectedProperty->setValue($value);
|
41 |
+
}
|
42 |
+
$this->initApp();
|
43 |
+
}
|
44 |
+
|
45 |
+
public function initAppOnMageClass($force = false)
|
46 |
+
{
|
47 |
+
$mageReflectionClass = new \ReflectionClass('Mage');
|
48 |
+
|
49 |
+
if ($force) {
|
50 |
+
$reflectedProperty = $mageReflectionClass->getProperty('_app');
|
51 |
+
$reflectedProperty->setAccessible(true);
|
52 |
+
$reflectedProperty->setValue(null);
|
53 |
+
}
|
54 |
+
$this->initApp();
|
55 |
+
}
|
56 |
+
|
57 |
+
protected function initApp(Mage_Core_Model_App $app = null)
|
58 |
+
{
|
59 |
+
$options = [
|
60 |
+
'cache' => ['id_prefix' => 'dev-test'],
|
61 |
+
'config_model' => 'Ecocode_Profiler_Model_Core_Config'
|
62 |
+
];
|
63 |
+
if ($app) {
|
64 |
+
$app->init('', 'store', $options);
|
65 |
+
} else {
|
66 |
+
Mage::app('', 'store', $options);
|
67 |
+
}
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @param $data
|
73 |
+
* @return Varien_Event_Observer
|
74 |
+
*/
|
75 |
+
protected function getObserver($data)
|
76 |
+
{
|
77 |
+
$observer = new Varien_Event_Observer();
|
78 |
+
$event = new Varien_Event($data);
|
79 |
+
$observer->setEvent($event);
|
80 |
+
|
81 |
+
return $observer;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getProtectedValue($object, $property)
|
85 |
+
{
|
86 |
+
$property = new ReflectionProperty(get_class($object), $property);
|
87 |
+
$property->setAccessible(true);
|
88 |
+
|
89 |
+
return $property->getValue($object);
|
90 |
+
}
|
91 |
+
}
|
app/code/community/Ecocode/Profiler/autoloader.php
ADDED
@@ -0,0 +1,68 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
class Ecocode_Profiler_Autoloader
|
5 |
+
{
|
6 |
+
public static $autoloader;
|
7 |
+
|
8 |
+
/** @var Closure */
|
9 |
+
protected $includeFile;
|
10 |
+
protected $classMap = [];
|
11 |
+
|
12 |
+
|
13 |
+
public static function getAutoloader()
|
14 |
+
{
|
15 |
+
if (self::$autoloader === null) {
|
16 |
+
self::$autoloader = new Ecocode_Profiler_Autoloader();
|
17 |
+
}
|
18 |
+
return self::$autoloader;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Registers this instance as an autoloader.
|
23 |
+
*
|
24 |
+
* @param bool $prepend Whether to prepend the autoloader or not
|
25 |
+
*/
|
26 |
+
public function register($prepend = false)
|
27 |
+
{
|
28 |
+
spl_autoload_register([$this, 'loadClass'], true, $prepend);
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Unregisters this instance as an autoloader.
|
33 |
+
*/
|
34 |
+
public function unregister()
|
35 |
+
{
|
36 |
+
spl_autoload_unregister([$this, 'loadClass']);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function loadClass($class)
|
40 |
+
{
|
41 |
+
if (isset($this->classMap[$class])) {
|
42 |
+
/**
|
43 |
+
* Scope isolated include.
|
44 |
+
*
|
45 |
+
* Prevents access to $this/self from included files.
|
46 |
+
*
|
47 |
+
* @param $file
|
48 |
+
*/
|
49 |
+
$includeFile = function ($file) {
|
50 |
+
include $file;
|
51 |
+
};
|
52 |
+
$includeFile($this->classMap[$class]);
|
53 |
+
return true;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
public function addOverwrite($className, $file)
|
58 |
+
{
|
59 |
+
if (strpos($file, '/') !== 0) {
|
60 |
+
$overwriteDir = __DIR__ . DIRECTORY_SEPARATOR . 'overwrite' . DIRECTORY_SEPARATOR;
|
61 |
+
$file = $overwriteDir . $file;
|
62 |
+
}
|
63 |
+
$this->classMap[$className] = $file;
|
64 |
+
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
|
68 |
+
}
|
app/code/community/Ecocode/Profiler/controllers/CacheController.php
ADDED
@@ -0,0 +1,71 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_CacheController
|
4 |
+
extends Ecocode_Profiler_Controller_AbstractController
|
5 |
+
{
|
6 |
+
public function clearAction()
|
7 |
+
{
|
8 |
+
$app = $this->getApp();
|
9 |
+
$types = $this->getRequest()->getParam('types', '');
|
10 |
+
$types = explode(',', $types);
|
11 |
+
|
12 |
+
foreach ($types as $type) {
|
13 |
+
$app->getCacheInstance()->cleanType($type);
|
14 |
+
}
|
15 |
+
|
16 |
+
$this->getResponse()
|
17 |
+
->setHeader('content-type', 'application/json')
|
18 |
+
->setBody(json_encode(['ok']));
|
19 |
+
}
|
20 |
+
|
21 |
+
public function clearAllAction()
|
22 |
+
{
|
23 |
+
$this->getApp()->getCacheInstance()->flush();
|
24 |
+
|
25 |
+
$this->getResponse()
|
26 |
+
->setHeader('content-type', 'application/json')
|
27 |
+
->setBody(json_encode(['ok']));
|
28 |
+
}
|
29 |
+
|
30 |
+
public function enableAction()
|
31 |
+
{
|
32 |
+
$types = $this->getRequest()->getParam('types', '');
|
33 |
+
$types = explode(',', $types);
|
34 |
+
$this->setCacheStatus($types, 1);
|
35 |
+
|
36 |
+
$this->getResponse()
|
37 |
+
->setHeader('content-type', 'application/json')
|
38 |
+
->setBody(json_encode(['ok']));
|
39 |
+
}
|
40 |
+
|
41 |
+
public function disableAction()
|
42 |
+
{
|
43 |
+
$types = $this->getRequest()->getParam('types', '');
|
44 |
+
$types = explode(',', $types);
|
45 |
+
$this->setCacheStatus($types, 0);
|
46 |
+
|
47 |
+
$this->getResponse()
|
48 |
+
->setHeader('content-type', 'application/json')
|
49 |
+
->setBody(json_encode(['ok']));
|
50 |
+
}
|
51 |
+
|
52 |
+
protected function setCacheStatus(array $types, $status)
|
53 |
+
{
|
54 |
+
$app = $this->getApp();
|
55 |
+
$allTypes = $app->getCacheInstance()->getTypes();
|
56 |
+
$allTypes = array_map(function (Varien_Object $type) {
|
57 |
+
return $type->getData('status');
|
58 |
+
}, $allTypes);
|
59 |
+
|
60 |
+
$updatedTypes = 0;
|
61 |
+
foreach ($types as $code) {
|
62 |
+
if (isset($allTypes[$code])) {
|
63 |
+
$allTypes[$code] = $status;
|
64 |
+
$updatedTypes++;
|
65 |
+
}
|
66 |
+
}
|
67 |
+
if ($updatedTypes > 0) {
|
68 |
+
$app->saveUseCache($allTypes);
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
app/code/community/Ecocode/Profiler/controllers/IndexController.php
ADDED
@@ -0,0 +1,155 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Ecocode_Profiler_IndexController extends Ecocode_Profiler_Controller_AbstractController
|
4 |
+
{
|
5 |
+
public function indexAction()
|
6 |
+
{
|
7 |
+
$this->loadLayout('profiler_default');
|
8 |
+
$this->renderLayout();
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
*
|
13 |
+
*/
|
14 |
+
public function toolbarAction()
|
15 |
+
{
|
16 |
+
$token = $this->getRequest()->getParam(Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER);
|
17 |
+
$profiler = $this->getProfiler();
|
18 |
+
|
19 |
+
$profile = $profiler->loadProfile($token);
|
20 |
+
Mage::register('current_profile', $profile);
|
21 |
+
|
22 |
+
$this->loadLayout(false);
|
23 |
+
$this->renderLayout();
|
24 |
+
}
|
25 |
+
|
26 |
+
public function searchAction()
|
27 |
+
{
|
28 |
+
$request = $this->getRequest();
|
29 |
+
|
30 |
+
$ip = preg_replace('/[^:\d\.]/', '', $request->getParam('ip'));
|
31 |
+
$method = $request->getParam('method');
|
32 |
+
$url = $request->getParam('url');
|
33 |
+
$start = $request->getParam('start');
|
34 |
+
$end = $request->getParam('end');
|
35 |
+
$limit = $request->getParam('limit');
|
36 |
+
$token = $request->getParam('_token');
|
37 |
+
|
38 |
+
if (null !== $session = Mage::getSingleton('core/session')) {
|
39 |
+
$session->setData('_profiler_search_ip', $ip);
|
40 |
+
$session->setData('_profiler_search_method', $method);
|
41 |
+
$session->setData('_profiler_search_url', $url);
|
42 |
+
$session->setData('_profiler_search_start', $start);
|
43 |
+
$session->setData('_profiler_search_end', $end);
|
44 |
+
$session->setData('_profiler_search_limit', $limit);
|
45 |
+
$session->setData('_profiler_search_token', $token);
|
46 |
+
}
|
47 |
+
|
48 |
+
if (!empty($token)) {
|
49 |
+
return $this->_redirect('_profiler/index/panel', [Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER => $token]);
|
50 |
+
}
|
51 |
+
|
52 |
+
return $this->_redirect('_profiler/index/searchResults',
|
53 |
+
[
|
54 |
+
'ip' => $ip,
|
55 |
+
'method' => $method,
|
56 |
+
'url' => $url,
|
57 |
+
'start' => $start,
|
58 |
+
'end' => $end,
|
59 |
+
'limit' => $limit,
|
60 |
+
]
|
61 |
+
);
|
62 |
+
}
|
63 |
+
|
64 |
+
public function searchResultsAction()
|
65 |
+
{
|
66 |
+
$request = $this->getRequest();
|
67 |
+
$profiler = $this->getProfiler();
|
68 |
+
|
69 |
+
$ip = $request->getParam('ip');
|
70 |
+
$method = $request->getParam('method');
|
71 |
+
$statusCode = $request->getParam('status_code');
|
72 |
+
$url = $request->getParam('url');
|
73 |
+
$start = $request->getParam('start');
|
74 |
+
$end = $request->getParam('end');
|
75 |
+
$limit = $request->getParam('limit');
|
76 |
+
|
77 |
+
$data = [
|
78 |
+
'request' => $request,
|
79 |
+
'tokens' => $profiler->find($ip, $url, $limit, $method, $start, $end),
|
80 |
+
'ip' => $ip,
|
81 |
+
'method' => $method,
|
82 |
+
'status_code' => $statusCode,
|
83 |
+
'url' => $url,
|
84 |
+
'start' => $start,
|
85 |
+
'end' => $end,
|
86 |
+
'limit' => $limit,
|
87 |
+
'panel' => null,
|
88 |
+
];
|
89 |
+
|
90 |
+
$this->loadLayout('profiler_default');
|
91 |
+
|
92 |
+
$this
|
93 |
+
->getLayout()
|
94 |
+
->getBlock('profiler.search.results')
|
95 |
+
->addData($data);
|
96 |
+
|
97 |
+
$this->renderLayout();
|
98 |
+
}
|
99 |
+
|
100 |
+
public function panelAction()
|
101 |
+
{
|
102 |
+
$profiler = $this->getProfiler();
|
103 |
+
|
104 |
+
/** @var Mage_Core_Controller_Request_Http $request */
|
105 |
+
$request = $this->getRequest();
|
106 |
+
|
107 |
+
$token = $request->getParam(Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER);
|
108 |
+
if (!$token) {
|
109 |
+
return $this->_redirect('_profiler');
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
$panel = $request->getParam('panel', 'request');
|
114 |
+
|
115 |
+
if ('latest' === $token && $latest = current($profiler->find(null, null, 1, null, null, null))) {
|
116 |
+
$token = $latest['token'];
|
117 |
+
}
|
118 |
+
|
119 |
+
if (!$profile = $this->profiler->loadProfile($token)) {
|
120 |
+
return $this->norouteAction();
|
121 |
+
}
|
122 |
+
|
123 |
+
/** @var Ecocode_Profiler_Model_Profile $profile */
|
124 |
+
if (!$profile->hasCollector($panel)) {
|
125 |
+
throw new Exception(sprintf('Panel "%s" is not available for token "%s".', $panel, $token));
|
126 |
+
}
|
127 |
+
|
128 |
+
Mage::register('current_profile', $profile);
|
129 |
+
Mage::register('current_panel', $panel);
|
130 |
+
|
131 |
+
$collector = $profile->getCollector($panel);
|
132 |
+
|
133 |
+
$layoutHandler = 'collector_' . $collector->getName();
|
134 |
+
$this->loadLayout(['profiler_default', $layoutHandler]);
|
135 |
+
|
136 |
+
$panelBlock = $this->getLayout()->getBlock('panel');
|
137 |
+
|
138 |
+
/** @var Ecocode_Profiler_Model_Profile $profile */
|
139 |
+
if (!$panelBlock) {
|
140 |
+
throw new Exception(sprintf('Panel Block for "%s" is not available for token "%s".', $panel, $token));
|
141 |
+
}
|
142 |
+
if (!($panelBlock instanceof Ecocode_Profiler_Block_Collector_Base)) {
|
143 |
+
throw new Exception(sprintf('Panel Block must extend "Ecocode_Profiler_Block_Collector_AbstractBase"'));
|
144 |
+
}
|
145 |
+
|
146 |
+
$panelBlock->setCollector($collector);
|
147 |
+
|
148 |
+
return $this->renderLayout();
|
149 |
+
}
|
150 |
+
|
151 |
+
public function phpinfoAction()
|
152 |
+
{
|
153 |
+
phpinfo();
|
154 |
+
}
|
155 |
+
}
|
app/code/community/Ecocode/Profiler/debug.php
ADDED
@@ -0,0 +1,24 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
use Symfony\Component\Debug\BufferingLogger;
|
3 |
+
use Symfony\Component\Debug\Debug;
|
4 |
+
use Symfony\Component\Debug\ErrorHandler;
|
5 |
+
|
6 |
+
if (class_exists('\Symfony\Component\Debug\Debug')) {
|
7 |
+
class MagentoErrorHandler extends ErrorHandler
|
8 |
+
{
|
9 |
+
public function handleException($exception, array $error = null)
|
10 |
+
{
|
11 |
+
while (ob_get_level()) {
|
12 |
+
ob_end_clean();
|
13 |
+
}
|
14 |
+
parent::handleException($exception, $error);
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
Debug::enable();
|
19 |
+
$errorHandler = new MagentoErrorHandler(new BufferingLogger());
|
20 |
+
$errorHandler->throwAt(-1, true);
|
21 |
+
|
22 |
+
ErrorHandler::register($errorHandler);
|
23 |
+
$errorHandler->setDefaultLogger(Mage::getLogger());
|
24 |
+
}
|
app/code/community/Ecocode/Profiler/etc/config.xml
ADDED
@@ -0,0 +1,8 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Ecocode_Profiler>
|
5 |
+
<version>1.1.0</version>
|
6 |
+
</Ecocode_Profiler>
|
7 |
+
</modules>
|
8 |
+
</config>
|
app/code/community/Ecocode/Profiler/etc/development.xml
ADDED
@@ -0,0 +1,139 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<ecocode>
|
4 |
+
<profiler>
|
5 |
+
<toolbar>1</toolbar>
|
6 |
+
<allow_ip>127.0.0.1</allow_ip>
|
7 |
+
<collectors>
|
8 |
+
<request>ecocode_profiler/collector_requestDataCollector</request>
|
9 |
+
<memory>ecocode_profiler/collector_memoryDataCollector</memory>
|
10 |
+
<time>ecocode_profiler/collector_timeDataCollector</time>
|
11 |
+
<ajax>ecocode_profiler/collector_ajaxDataCollector</ajax>
|
12 |
+
<mysql>ecocode_profiler/collector_mysqlDataCollector</mysql>
|
13 |
+
<translation>ecocode_profiler/collector_translationDataCollector</translation>
|
14 |
+
<rewrite>ecocode_profiler/collector_rewriteDataCollector</rewrite>
|
15 |
+
<customer>ecocode_profiler/collector_customerDataCollector</customer>
|
16 |
+
<layout>ecocode_profiler/collector_layoutDataCollector</layout>
|
17 |
+
<config>ecocode_profiler/collector_configDataCollector</config>
|
18 |
+
<event>ecocode_profiler/collector_eventDataCollector</event>
|
19 |
+
<cache>ecocode_profiler/collector_cacheDataCollector</cache>
|
20 |
+
<log>ecocode_profiler/collector_logDataCollector</log>
|
21 |
+
<model>ecocode_profiler/collector_modelDataCollector</model>
|
22 |
+
</collectors>
|
23 |
+
</profiler>
|
24 |
+
</ecocode>
|
25 |
+
<global>
|
26 |
+
<models>
|
27 |
+
<ecocode_profiler>
|
28 |
+
<class>Ecocode_Profiler_Model</class>
|
29 |
+
<resourceModel>ecocode_profiler_resource</resourceModel>
|
30 |
+
</ecocode_profiler>
|
31 |
+
<ecocode_profiler_resource>
|
32 |
+
<class>Ecocode_Profiler_Model_Resource</class>
|
33 |
+
</ecocode_profiler_resource>
|
34 |
+
</models>
|
35 |
+
<blocks>
|
36 |
+
<ecocode_profiler>
|
37 |
+
<class>Ecocode_Profiler_Block</class>
|
38 |
+
</ecocode_profiler>
|
39 |
+
</blocks>
|
40 |
+
<helpers>
|
41 |
+
<ecocode_profiler>
|
42 |
+
<class>Ecocode_Profiler_Helper</class>
|
43 |
+
</ecocode_profiler>
|
44 |
+
</helpers>
|
45 |
+
</global>
|
46 |
+
<frontend>
|
47 |
+
<layout>
|
48 |
+
<updates>
|
49 |
+
<ecocode_profiler>
|
50 |
+
<file>ecocode_profiler.xml</file>
|
51 |
+
</ecocode_profiler>
|
52 |
+
</updates>
|
53 |
+
</layout>
|
54 |
+
<routers>
|
55 |
+
<profiler>
|
56 |
+
<use>standard</use>
|
57 |
+
<args>
|
58 |
+
<frontName>_profiler</frontName>
|
59 |
+
<module>Ecocode_Profiler</module>
|
60 |
+
</args>
|
61 |
+
</profiler>
|
62 |
+
</routers>
|
63 |
+
<events>
|
64 |
+
<controller_front_send_response_before>
|
65 |
+
<observers>
|
66 |
+
<ecocode_profiler>
|
67 |
+
<type>singleton</type>
|
68 |
+
<class>ecocode_profiler/observer</class>
|
69 |
+
<method>controllerFrontSendResponseBefore</method>
|
70 |
+
</ecocode_profiler>
|
71 |
+
</observers>
|
72 |
+
</controller_front_send_response_before>
|
73 |
+
<mage_terminate>
|
74 |
+
<observers>
|
75 |
+
<ecocode_profiler>
|
76 |
+
<type>singleton</type>
|
77 |
+
<class>ecocode_profiler/observer</class>
|
78 |
+
<method>onTerminate</method>
|
79 |
+
</ecocode_profiler>
|
80 |
+
</observers>
|
81 |
+
</mage_terminate>
|
82 |
+
<core_block_abstract_to_html_before>
|
83 |
+
<observers>
|
84 |
+
<ecocode_profiler_context>
|
85 |
+
<type>singleton</type>
|
86 |
+
<class>ecocode_profiler/observer_context</class>
|
87 |
+
<method>openBlockContext</method>
|
88 |
+
</ecocode_profiler_context>
|
89 |
+
<ecocode_layout_profiler>
|
90 |
+
<type>singleton</type>
|
91 |
+
<class>ecocode_profiler/collector_layoutDataCollector</class>
|
92 |
+
<method>beforeToHtml</method>
|
93 |
+
</ecocode_layout_profiler>
|
94 |
+
</observers>
|
95 |
+
</core_block_abstract_to_html_before>
|
96 |
+
<core_block_abstract_to_html_after>
|
97 |
+
<observers>
|
98 |
+
<ecocode_profiler_context>
|
99 |
+
<type>singleton</type>
|
100 |
+
<class>ecocode_profiler/observer_context</class>
|
101 |
+
<method>closeBlockContext</method>
|
102 |
+
</ecocode_profiler_context>
|
103 |
+
<ecocode_layout_profiler>
|
104 |
+
<type>singleton</type>
|
105 |
+
<class>ecocode_profiler/collector_layoutDataCollector</class>
|
106 |
+
<method>afterToHtml</method>
|
107 |
+
</ecocode_layout_profiler>
|
108 |
+
</observers>
|
109 |
+
</core_block_abstract_to_html_after>
|
110 |
+
<model_resource_db_load>
|
111 |
+
<observers>
|
112 |
+
<ecocode_profiler_model>
|
113 |
+
<type>singleton</type>
|
114 |
+
<method>trackModelLoad</method>
|
115 |
+
<class>ecocode_profiler/collector_modelDataCollector</class>
|
116 |
+
</ecocode_profiler_model>
|
117 |
+
</observers>
|
118 |
+
</model_resource_db_load>
|
119 |
+
<model_resource_db_save>
|
120 |
+
<observers>
|
121 |
+
<ecocode_profiler_model>
|
122 |
+
<type>singleton</type>
|
123 |
+
<method>trackModelSave</method>
|
124 |
+
<class>ecocode_profiler/collector_modelDataCollector</class>
|
125 |
+
</ecocode_profiler_model>
|
126 |
+
</observers>
|
127 |
+
</model_resource_db_save>
|
128 |
+
<model_resource_db_delete>
|
129 |
+
<observers>
|
130 |
+
<ecocode_profiler_model>
|
131 |
+
<type>singleton</type>
|
132 |
+
<method>trackModelDelete</method>
|
133 |
+
<class>ecocode_profiler/collector_modelDataCollector</class>
|
134 |
+
</ecocode_profiler_model>
|
135 |
+
</observers>
|
136 |
+
</model_resource_db_delete>
|
137 |
+
</events>
|
138 |
+
</frontend>
|
139 |
+
</config>
|
app/code/community/Ecocode/Profiler/overwrite/Mage.php
ADDED
@@ -0,0 +1,124 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
$mageRoot = MAGENTO_ROOT . DIRECTORY_SEPARATOR;
|
5 |
+
$mageVarDir = $mageRoot . 'var' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
|
6 |
+
$mageFile = $mageRoot . 'app' . DIRECTORY_SEPARATOR . 'Mage.php';
|
7 |
+
$mageMd5 = md5_file($mageFile);
|
8 |
+
$mageCacheFile = Ecocode_Profiler_Helper_Data::getOverwriteDir() . 'Original_Mage_' . Ecocode_Profiler_Helper_Data::getVersion() . '-' . $mageMd5 . '.php';
|
9 |
+
|
10 |
+
if (!file_exists($mageCacheFile)) {
|
11 |
+
$mageCode = file_get_contents($mageFile);
|
12 |
+
|
13 |
+
$replace = [
|
14 |
+
'final class Mage' => 'class MageOriginal',
|
15 |
+
' private ' => ' protected ',
|
16 |
+
"define('BP', dirname(dirname(__FILE__)));" => '',
|
17 |
+
"Mage::register('original_include_path', get_include_path());" => '$originalIncludePath = get_include_path();',
|
18 |
+
"Mage::registry('original_include_path')" => '$originalIncludePath',
|
19 |
+
'new Mage_Core_Model_App()' => 'new Ecocode_Profiler_Model_AppDev()',
|
20 |
+
'self::printException($e);' => 'throw $e;'
|
21 |
+
];
|
22 |
+
$mageCode = str_replace(array_keys($replace), array_values($replace), $mageCode);
|
23 |
+
|
24 |
+
$replace = [
|
25 |
+
'/(?<!= )self::/' => 'static::'
|
26 |
+
];
|
27 |
+
$mageCode = preg_replace(array_keys($replace), array_values($replace), $mageCode);
|
28 |
+
|
29 |
+
file_put_contents($mageCacheFile, $mageCode);
|
30 |
+
}
|
31 |
+
|
32 |
+
require_once $mageCacheFile;
|
33 |
+
|
34 |
+
|
35 |
+
class Mage extends MageOriginal
|
36 |
+
{
|
37 |
+
protected static $_logChannels = [];
|
38 |
+
|
39 |
+
protected static $_logger;
|
40 |
+
protected static $_loggerDebugHandler;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return Ecocode_Profiler_Model_Logger
|
44 |
+
*/
|
45 |
+
public static function getLogger($channel = null)
|
46 |
+
{
|
47 |
+
if ($channel === null) {
|
48 |
+
return static::getDefaultLogger();
|
49 |
+
}
|
50 |
+
if (!isset(static::$_logChannels[$channel])) {
|
51 |
+
static::$_logChannels[$channel] = static::getNewLogger($channel);
|
52 |
+
}
|
53 |
+
|
54 |
+
return static::$_logChannels[$channel];
|
55 |
+
}
|
56 |
+
|
57 |
+
public static function getDefaultLogger()
|
58 |
+
{
|
59 |
+
if (static::$_logger === null) {
|
60 |
+
static::$_logger = static::getNewLogger('default');
|
61 |
+
}
|
62 |
+
|
63 |
+
return static::$_logger;
|
64 |
+
}
|
65 |
+
|
66 |
+
protected static function getNewLogger($channel)
|
67 |
+
{
|
68 |
+
if (!@class_exists('\Monolog\Logger')) {
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
if (static::$_loggerDebugHandler === null) {
|
72 |
+
static::$_loggerDebugHandler = new Ecocode_Profiler_Model_Logger_DebugHandler();
|
73 |
+
}
|
74 |
+
|
75 |
+
return new Ecocode_Profiler_Model_Logger(
|
76 |
+
$channel,
|
77 |
+
[static::$_loggerDebugHandler]
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
public static function log($message, $level = null, $file = '', $forceLog = false)
|
82 |
+
{
|
83 |
+
$level = is_null($level) ? Zend_Log::DEBUG : $level;
|
84 |
+
$file = empty($file) ? 'system.log' : $file;
|
85 |
+
|
86 |
+
$channel = preg_replace('/(\..+)$/', '', $file);
|
87 |
+
static::getLogger($channel)->mageLog($level, $message);
|
88 |
+
|
89 |
+
return parent::log($message, $level, $file, $forceLog);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @codeCoverageIgnore
|
94 |
+
*/
|
95 |
+
public static function terminate()
|
96 |
+
{
|
97 |
+
self::dispatchDebugEvent('mage_terminate');
|
98 |
+
}
|
99 |
+
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @codeCoverageIgnore
|
103 |
+
*
|
104 |
+
* @param $name
|
105 |
+
* @param array $data
|
106 |
+
* @return Mage_Core_Model_App
|
107 |
+
*/
|
108 |
+
public static function dispatchDebugEvent($name, array $data = [])
|
109 |
+
{
|
110 |
+
$data['debug'] = true;
|
111 |
+
return parent::dispatchEvent($name, $data);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @codeCoverageIgnore
|
116 |
+
* @return []
|
117 |
+
*/
|
118 |
+
public static function getAllRegistryEntries()
|
119 |
+
{
|
120 |
+
return static::$_registry;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
Mage::register('original_include_path', get_include_path());
|
app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResource.php
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
Ecocode_Profiler_Helper_Data::loadRenamedClass('core/Mage/Core/Model/Resource.php', 'Original_Mage_Core_Model_Resource');
|
4 |
+
|
5 |
+
|
6 |
+
class Mage_Core_Model_Resource extends
|
7 |
+
Original_Mage_Core_Model_Resource
|
8 |
+
{
|
9 |
+
protected $configProperty;
|
10 |
+
|
11 |
+
public function __construct()
|
12 |
+
{
|
13 |
+
$this->configProperty = new ReflectionProperty('Varien_Db_Adapter_Pdo_Mysql', '_config');
|
14 |
+
$this->configProperty->setAccessible(true);
|
15 |
+
}
|
16 |
+
|
17 |
+
public function getConnection($name)
|
18 |
+
{
|
19 |
+
/** @var Magento_Db_Adapter_Pdo_Mysql $connection */
|
20 |
+
$connection = parent::getConnection($name);
|
21 |
+
if ($connection->getStatementClass() !== 'Ecocode_Profiler_Db_Statement_Pdo_Mysql') {
|
22 |
+
$connection->setStatementClass('Ecocode_Profiler_Db_Statement_Pdo_Mysql');
|
23 |
+
$config = $connection->getConfig();
|
24 |
+
if (!isset($config['connection_name'])) {
|
25 |
+
$config['connection_name'] = $name;
|
26 |
+
$this->configProperty->setValue($connection, $config);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
return $connection;
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResourceDbAbstract.php
ADDED
@@ -0,0 +1,83 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
Ecocode_Profiler_Helper_Data::loadRenamedClass('core/Mage/Core/Model/Resource/Db/Abstract.php', 'Original_Mage_Core_Model_Resource_Db_Abstract');
|
4 |
+
|
5 |
+
abstract class Mage_Core_Model_Resource_Db_Abstract extends
|
6 |
+
Original_Mage_Core_Model_Resource_Db_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* @codeCoverageIgnore
|
10 |
+
*
|
11 |
+
* @param $event
|
12 |
+
* @param array $data
|
13 |
+
*/
|
14 |
+
protected function dispatch($event, array $data = [])
|
15 |
+
{
|
16 |
+
Mage::dispatchDebugEvent($event, $data);
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* overwrite load function as "_afterLoad" etc can be overwritten
|
21 |
+
*
|
22 |
+
* @param Mage_Core_Model_Abstract $object
|
23 |
+
* @param mixed $value
|
24 |
+
* @param null $field
|
25 |
+
* @return Mage_Core_Model_Resource_Db_Abstract
|
26 |
+
*/
|
27 |
+
public function load(Mage_Core_Model_Abstract $object, $value, $field = null)
|
28 |
+
{
|
29 |
+
$start = microtime(true);
|
30 |
+
$result = parent::load($object, $value, $field);
|
31 |
+
|
32 |
+
$this->dispatch('model_resource_db_load', [
|
33 |
+
'object' => $object,
|
34 |
+
'time' => microtime(true) - $start
|
35 |
+
]);
|
36 |
+
|
37 |
+
return $result;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* overwrite load function as "_afterSave" etc can be overwritten
|
42 |
+
*
|
43 |
+
* @param Mage_Core_Model_Abstract $object
|
44 |
+
* @return Mage_Core_Model_Resource_Db_Abstract
|
45 |
+
*/
|
46 |
+
public function save(Mage_Core_Model_Abstract $object)
|
47 |
+
{
|
48 |
+
$start = microtime(true);
|
49 |
+
$result = parent::save($object);
|
50 |
+
|
51 |
+
if (!$object->isDeleted()) {
|
52 |
+
//is captured separately
|
53 |
+
$this->dispatch('model_resource_db_save', [
|
54 |
+
'object' => $object,
|
55 |
+
'time' => microtime(true) - $start
|
56 |
+
]);
|
57 |
+
}
|
58 |
+
|
59 |
+
return $result;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* overwrite load function as "_afterDelete" etc can be overwritten
|
64 |
+
*
|
65 |
+
* @param Mage_Core_Model_Abstract $object
|
66 |
+
* @return Mage_Core_Model_Resource_Db_Abstract
|
67 |
+
*/
|
68 |
+
public function delete(Mage_Core_Model_Abstract $object)
|
69 |
+
{
|
70 |
+
$start = microtime(true);
|
71 |
+
$result = parent::delete($object);
|
72 |
+
|
73 |
+
if (!$object->isDeleted()) {
|
74 |
+
//is captured separately
|
75 |
+
$this->dispatch('model_resource_db_delete', [
|
76 |
+
'object' => $object,
|
77 |
+
'time' => microtime(true) - $start
|
78 |
+
]);
|
79 |
+
}
|
80 |
+
|
81 |
+
return $result;
|
82 |
+
}
|
83 |
+
}
|
app/code/community/Ecocode/Profiler/overwrite/MageCoreModelStore.php
ADDED
@@ -0,0 +1,35 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
Ecocode_Profiler_Helper_Data::loadRenamedClass('core/Mage/Core/Model/Store.php', 'Original_Mage_Core_Model_Store');
|
4 |
+
|
5 |
+
|
6 |
+
class Mage_Core_Model_Store extends
|
7 |
+
Original_Mage_Core_Model_Store
|
8 |
+
{
|
9 |
+
protected $_isDev;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Remove script file name from url in case when server rewrites are enabled
|
13 |
+
*
|
14 |
+
* @param string $url
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
protected function _updatePathUseRewrites($url)
|
18 |
+
{
|
19 |
+
$script = $this->isDev() ? 'dev.php' : 'index.php';
|
20 |
+
if ($this->isAdmin() || $this->isDev() || !$this->getConfig(self::XML_PATH_USE_REWRITES) || !Mage::isInstalled()) {
|
21 |
+
$indexFileName = $this->_isCustomEntryPoint() ? $script : basename($_SERVER['SCRIPT_FILENAME']);
|
22 |
+
$url .= $indexFileName . '/';
|
23 |
+
}
|
24 |
+
return $url;
|
25 |
+
}
|
26 |
+
|
27 |
+
protected function isDev()
|
28 |
+
{
|
29 |
+
if ($this->_isDev === null) {
|
30 |
+
$this->_isDev = Mage::app() instanceof Ecocode_Profiler_Model_AppDev;
|
31 |
+
}
|
32 |
+
|
33 |
+
return $this->_isDev;
|
34 |
+
}
|
35 |
+
}
|
app/code/community/Ecocode/Profiler/overwrite/MageCoreModelTranslate.php
ADDED
@@ -0,0 +1,154 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
Ecocode_Profiler_Helper_Data::loadRenamedClass('core/Mage/Core/Model/Translate.php', 'Original_Mage_Core_Model_Translate');
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @author ecocode GmbH <jk@ecocode.de>
|
7 |
+
* @author Justus Krapp <jk@ecocode.de>
|
8 |
+
*/
|
9 |
+
class Mage_Core_Model_Translate extends Original_Mage_Core_Model_Translate
|
10 |
+
{
|
11 |
+
const STATE_TRANSLATED = 'translated';
|
12 |
+
const STATE_FALLBACK = 'fallback';
|
13 |
+
const STATE_MISSING = 'missing';
|
14 |
+
const STATE_INVALID = 'invalid';
|
15 |
+
|
16 |
+
protected $currentMessage = null;
|
17 |
+
|
18 |
+
protected $messages = [];
|
19 |
+
|
20 |
+
|
21 |
+
public function translate($args)
|
22 |
+
{
|
23 |
+
$_args = $args;
|
24 |
+
$this->currentMessage = [
|
25 |
+
'locale' => $this->_locale,
|
26 |
+
'module' => null,
|
27 |
+
'trace' => []
|
28 |
+
];
|
29 |
+
|
30 |
+
$text = array_shift($_args);
|
31 |
+
|
32 |
+
if ($text instanceof Mage_Core_Model_Translate_Expr) {
|
33 |
+
$this->currentMessage['module'] = $text->getModule();
|
34 |
+
}
|
35 |
+
|
36 |
+
$translation = parent::translate($args);
|
37 |
+
if ($translation === '') {
|
38 |
+
//just return nothing we can do here? maybe log a stacktrace?
|
39 |
+
return $translation;
|
40 |
+
}
|
41 |
+
|
42 |
+
if (@vsprintf($this->currentMessage['translation'], $_args) === false) {
|
43 |
+
$trace = $this->addTrace();
|
44 |
+
if ($trace && $this->traceHasFunctionCall($trace, 'getTranslateJson')) {
|
45 |
+
//dont log invalid as strings are used with empty placeholders is intended here
|
46 |
+
} else {
|
47 |
+
$this->currentMessage['state'] = self::STATE_INVALID;
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
$this->currentMessage['parameters'] = $_args;
|
52 |
+
$this->currentMessage['translation'] = $translation;
|
53 |
+
|
54 |
+
$this->log();
|
55 |
+
return $translation;
|
56 |
+
}
|
57 |
+
|
58 |
+
public function _getTranslatedString($text, $code)
|
59 |
+
{
|
60 |
+
$this->currentMessage['text'] = $text;
|
61 |
+
$this->currentMessage['code'] = $code;
|
62 |
+
|
63 |
+
$translated = parent::_getTranslatedString($text, $code);
|
64 |
+
if (array_key_exists($code, $this->_data)) {
|
65 |
+
$state = self::STATE_TRANSLATED;
|
66 |
+
} elseif (array_key_exists($text, $this->_data)) {
|
67 |
+
$state = self::STATE_FALLBACK;
|
68 |
+
$this->addTrace();
|
69 |
+
} else {
|
70 |
+
$state = self::STATE_MISSING;
|
71 |
+
$this->addTrace();
|
72 |
+
}
|
73 |
+
|
74 |
+
$this->currentMessage['state'] = $state;
|
75 |
+
$this->currentMessage['translation'] = $translated;
|
76 |
+
|
77 |
+
return $translated;
|
78 |
+
}
|
79 |
+
|
80 |
+
public function getMessages()
|
81 |
+
{
|
82 |
+
return $this->messages;
|
83 |
+
}
|
84 |
+
|
85 |
+
protected function log()
|
86 |
+
{
|
87 |
+
$this->messages[] = [
|
88 |
+
'locale' => $this->currentMessage['locale'],
|
89 |
+
'code' => $this->currentMessage['code'],
|
90 |
+
'text' => $this->currentMessage['text'],
|
91 |
+
'translation' => $this->currentMessage['translation'],
|
92 |
+
'state' => $this->currentMessage['state'],
|
93 |
+
'parameters' => $this->currentMessage['parameters'],
|
94 |
+
'module' => $this->currentMessage['module'],
|
95 |
+
'trace' => $this->currentMessage['trace']
|
96 |
+
];
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Adding translation data
|
101 |
+
*
|
102 |
+
* @param array $data
|
103 |
+
* @param string $scope
|
104 |
+
* @return Mage_Core_Model_Translate
|
105 |
+
*/
|
106 |
+
protected function _addData($data, $scope, $forceReload = false)
|
107 |
+
{
|
108 |
+
foreach ($data as $key => $value) {
|
109 |
+
|
110 |
+
/*
|
111 |
+
we needed to simplify this to properly detect not translated strings and their scope
|
112 |
+
*/
|
113 |
+
$key = $this->_prepareDataString($key);
|
114 |
+
$value = $this->_prepareDataString($value);
|
115 |
+
|
116 |
+
$scopeKey = $scope . self::SCOPE_SEPARATOR . $key;
|
117 |
+
|
118 |
+
$this->_data[$scopeKey] = $value;
|
119 |
+
if (!isset($this->_data[$key]) && !Mage::getIsDeveloperMode()) {
|
120 |
+
$this->_data[$key] = $value;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
return $this;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @return array
|
128 |
+
*/
|
129 |
+
protected function addTrace()
|
130 |
+
{
|
131 |
+
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
|
132 |
+
|
133 |
+
while (($trace = reset($backtrace)) && (!isset($trace['function']) || $trace['function'] !== '__')) {
|
134 |
+
array_shift($backtrace);
|
135 |
+
}
|
136 |
+
|
137 |
+
return $this->currentMessage['trace'] = array_slice($backtrace, 0, 5);
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param array $trace
|
142 |
+
* @param $functionName
|
143 |
+
* @return bool
|
144 |
+
*/
|
145 |
+
protected function traceHasFunctionCall(array $trace, $functionName)
|
146 |
+
{
|
147 |
+
foreach ($trace as $item) {
|
148 |
+
if (isset($item['function']) && $item['function'] === $functionName) {
|
149 |
+
return true;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
return false;
|
153 |
+
}
|
154 |
+
}
|
app/code/community/Ecocode/Profiler/overwrite/MageEavModelEntityAbstract.php
ADDED
@@ -0,0 +1,70 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
Ecocode_Profiler_Helper_Data::loadRenamedClass('core/Mage/Eav/Model/Entity/Abstract.php', 'Original_Mage_Eav_Model_Entity_Abstract');
|
4 |
+
|
5 |
+
abstract class Mage_Eav_Model_Entity_Abstract extends
|
6 |
+
Original_Mage_Eav_Model_Entity_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* @codeCoverageIgnore
|
10 |
+
*
|
11 |
+
* @param $event
|
12 |
+
* @param array $data
|
13 |
+
*/
|
14 |
+
protected function dispatch($event, array $data = [])
|
15 |
+
{
|
16 |
+
Mage::dispatchDebugEvent($event, $data);
|
17 |
+
}
|
18 |
+
|
19 |
+
public function load($object, $entityId, $attributes = [])
|
20 |
+
{
|
21 |
+
$start = microtime(true);
|
22 |
+
$result = parent::load($object, $entityId, $attributes);
|
23 |
+
|
24 |
+
$this->dispatch('model_resource_db_load', [
|
25 |
+
'object' => $object,
|
26 |
+
'time' => microtime(true) - $start
|
27 |
+
]);
|
28 |
+
|
29 |
+
return $result;
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* overwrite load function as "_afterSave" etc can be overwritten
|
34 |
+
*/
|
35 |
+
public function save(Varien_Object $object)
|
36 |
+
{
|
37 |
+
$start = microtime(true);
|
38 |
+
$result = parent::save($object);
|
39 |
+
|
40 |
+
if (!$object->isDeleted()) {
|
41 |
+
//is captured separately
|
42 |
+
$this->dispatch('model_resource_db_save', [
|
43 |
+
'object' => $object,
|
44 |
+
'time' => microtime(true) - $start
|
45 |
+
]);
|
46 |
+
}
|
47 |
+
|
48 |
+
return $result;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* overwrite load function as "_afterDelete" etc can be overwritten
|
53 |
+
*
|
54 |
+
* @param $object
|
55 |
+
* @return Mage_Eav_Model_Entity_Abstract
|
56 |
+
*/
|
57 |
+
public function delete($object)
|
58 |
+
{
|
59 |
+
$start = microtime(true);
|
60 |
+
$result = parent::delete($object);
|
61 |
+
|
62 |
+
//is captured separately
|
63 |
+
$this->dispatch('model_resource_db_delete', [
|
64 |
+
'object' => $object,
|
65 |
+
'time' => microtime(true) - $start
|
66 |
+
]);
|
67 |
+
|
68 |
+
return $result;
|
69 |
+
}
|
70 |
+
}
|
app/design/frontend/base/default/layout/ecocode_profiler.xml
ADDED
@@ -0,0 +1,120 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<layout>
|
3 |
+
<profiler_default>
|
4 |
+
<block type="page/html" name="root" output="toHtml" template="ecocode_profiler/layout.phtml">
|
5 |
+
<block type="core/template" name="profiler_js" template="ecocode_profiler/profiler/base.js.phtml"/>
|
6 |
+
<block type="core/template" name="profiler_css" template="ecocode_profiler/profiler/base.css.phtml"/>
|
7 |
+
<block type="core/template" name="summery" template="ecocode_profiler/profiler/summery.phtml"/>
|
8 |
+
<block type="core/text_list" name="left" as="left" translate="label">
|
9 |
+
<label>Left Column</label>
|
10 |
+
<block type="ecocode_profiler/profiler_sidebar" name="sidebar" template="ecocode_profiler/layout/sidebar.phtml">
|
11 |
+
<block type="ecocode_profiler/profiler_sidebar_menu" name="menu" template="ecocode_profiler/layout/sidebar/menu.phtml">
|
12 |
+
<block name="request" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/request/menu.phtml"/>
|
13 |
+
<block name="mysql" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/mysql/menu.phtml"/>
|
14 |
+
<block name="event" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/event/menu.phtml"/>
|
15 |
+
<block name="layout" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/layout/menu.phtml"/>
|
16 |
+
<block name="translation" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/translation/menu.phtml"/>
|
17 |
+
<block name="model" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/model/menu.phtml"/>
|
18 |
+
<block name="rewrite" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/rewrite/menu.phtml"/>
|
19 |
+
<block name="log" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/log/menu.phtml"/>
|
20 |
+
<block name="cache" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/cache/menu.phtml"/>
|
21 |
+
<block name="config" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/config/menu.phtml"/>
|
22 |
+
</block>
|
23 |
+
</block>
|
24 |
+
</block>
|
25 |
+
<block type="core/text_list" name="content" as="content" translate="label">
|
26 |
+
<label>Main Content Area</label>
|
27 |
+
</block>
|
28 |
+
</block>
|
29 |
+
|
30 |
+
|
31 |
+
</profiler_default>
|
32 |
+
|
33 |
+
<profiler_index_toolbar>
|
34 |
+
<block type="ecocode_profiler/toolbar" name="root" output="toHtml" template="ecocode_profiler/toolbar.phtml">
|
35 |
+
<block name="profiler.mysql.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/mysql/toolbar.phtml"/>
|
36 |
+
<block name="profiler.request.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/request/toolbar.phtml"/>
|
37 |
+
<block name="profiler.time.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/time/toolbar.phtml"/>
|
38 |
+
<block name="profiler.translation.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/translation/toolbar.phtml"/>
|
39 |
+
<block name="profiler.ajax.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/ajax/toolbar.phtml"/>
|
40 |
+
<block name="profiler.model.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/model/toolbar.phtml"/>
|
41 |
+
<block name="profiler.cache.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/cache/toolbar.phtml"/>
|
42 |
+
<block name="profiler.memory.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/memory/toolbar.phtml"/>
|
43 |
+
<block name="profiler.rewrite.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/rewrite/toolbar.phtml"/>
|
44 |
+
<block name="profiler.log.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/log/toolbar.phtml"/>
|
45 |
+
<block name="profiler.customer.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/customer/toolbar.phtml"/>
|
46 |
+
<block name="profiler.layout.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/layout/toolbar.phtml"/>
|
47 |
+
<block name="profiler.config.toolbar" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/config/toolbar.phtml"/>
|
48 |
+
</block>
|
49 |
+
|
50 |
+
</profiler_index_toolbar>
|
51 |
+
|
52 |
+
|
53 |
+
<profiler_index_searchresults>
|
54 |
+
<reference name="content">
|
55 |
+
<block type="core/template" name="profiler.search.summery" template="ecocode_profiler/profiler/search/summery.phtml"/>
|
56 |
+
<block type="core/template" name="profiler.search.results" template="ecocode_profiler/profiler/search/results.phtml"/>
|
57 |
+
</reference>
|
58 |
+
</profiler_index_searchresults>
|
59 |
+
|
60 |
+
|
61 |
+
<collector_mysql>
|
62 |
+
<reference name="content">
|
63 |
+
<block name="panel" type="ecocode_profiler/collector_mysql_panel" template="ecocode_profiler/collector/mysql/panel.phtml"/>
|
64 |
+
</reference>
|
65 |
+
</collector_mysql>
|
66 |
+
|
67 |
+
<collector_request>
|
68 |
+
<reference name="content">
|
69 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/request/panel.phtml"/>
|
70 |
+
</reference>
|
71 |
+
</collector_request>
|
72 |
+
|
73 |
+
<collector_translation>
|
74 |
+
<reference name="content">
|
75 |
+
<block name="panel" type="ecocode_profiler/collector_translation_panel" template="ecocode_profiler/collector/translation/panel.phtml"/>
|
76 |
+
</reference>
|
77 |
+
</collector_translation>
|
78 |
+
|
79 |
+
<collector_config>
|
80 |
+
<reference name="content">
|
81 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/config/panel.phtml"/>
|
82 |
+
</reference>
|
83 |
+
</collector_config>
|
84 |
+
|
85 |
+
<collector_rewrite>
|
86 |
+
<reference name="content">
|
87 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/rewrite/panel.phtml"/>
|
88 |
+
</reference>
|
89 |
+
</collector_rewrite>
|
90 |
+
|
91 |
+
<collector_event>
|
92 |
+
<reference name="content">
|
93 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/event/panel.phtml"/>
|
94 |
+
</reference>
|
95 |
+
</collector_event>
|
96 |
+
|
97 |
+
<collector_layout>
|
98 |
+
<reference name="content">
|
99 |
+
<block name="panel" type="ecocode_profiler/collector_layout_panel" template="ecocode_profiler/collector/layout/panel.phtml"/>
|
100 |
+
</reference>
|
101 |
+
</collector_layout>
|
102 |
+
|
103 |
+
<collector_cache>
|
104 |
+
<reference name="content">
|
105 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/cache/panel.phtml"/>
|
106 |
+
</reference>
|
107 |
+
</collector_cache>
|
108 |
+
|
109 |
+
<collector_log>
|
110 |
+
<reference name="content">
|
111 |
+
<block name="panel" type="ecocode_profiler/collector_log_panel" template="ecocode_profiler/collector/log/panel.phtml"/>
|
112 |
+
</reference>
|
113 |
+
</collector_log>
|
114 |
+
|
115 |
+
<collector_model>
|
116 |
+
<reference name="content">
|
117 |
+
<block name="panel" type="ecocode_profiler/collector_base" template="ecocode_profiler/collector/model/panel.phtml"/>
|
118 |
+
</reference>
|
119 |
+
</collector_model>
|
120 |
+
</layout>
|
app/design/frontend/base/default/template/ecocode_profiler/back-trace.phtml
ADDED
@@ -0,0 +1,24 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_BackTrace $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Helper_ValueExporter $valueExport */
|
5 |
+
$valueExport = $this->helper('ecocode_profiler/valueExporter');
|
6 |
+
|
7 |
+
$trace = $this->getTrace();
|
8 |
+
?>
|
9 |
+
<?php if ($trace): ?>
|
10 |
+
<div id="stack-<?php echo $this->getTraceId() ?>" class="hidden">
|
11 |
+
<strong class="font-normal text-small">Trace</strong>:
|
12 |
+
<ul class="sf-call-stack ">
|
13 |
+
|
14 |
+
<?php foreach ($trace as $item): ?>
|
15 |
+
<li>
|
16 |
+
<?php echo isset($item['class']) ? $item['class'] . '::' : '' ?><?php echo $item['function'] ?><br>
|
17 |
+
<?php if (isset($item['file'])): ?>
|
18 |
+
<small><?php echo $item['file'] ?>::<?php echo $item['line'] ?></small>
|
19 |
+
<?php endif; ?>
|
20 |
+
</li>
|
21 |
+
<?php endforeach; ?>
|
22 |
+
</ul>
|
23 |
+
</div>
|
24 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/ecocode_profiler/bag.phtml
ADDED
@@ -0,0 +1,33 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Bag $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Helper_ValueExporter $valueExport */
|
5 |
+
$valueExport = $this->helper('ecocode_profiler/valueExporter');
|
6 |
+
|
7 |
+
?>
|
8 |
+
|
9 |
+
<table class="<?php echo $this->getData('class')?>">
|
10 |
+
<thead>
|
11 |
+
<?php $labels = $this->getLabels(); ?>
|
12 |
+
<tr>
|
13 |
+
<th scope="col" class="key"><?php echo isset($labels[0]) ? $labels[0] : 'Key' ?></th>
|
14 |
+
<th scope="col"><?php echo isset($labels[1]) ? $labels[1] : 'Value' ?></th>
|
15 |
+
</tr>
|
16 |
+
</thead>
|
17 |
+
<tbody>
|
18 |
+
<?php if ($bag = $this->getBag()): ?>
|
19 |
+
|
20 |
+
<?php foreach($bag->keys() as $key): ?>
|
21 |
+
<tr>
|
22 |
+
<th><?php echo $key ?></th>
|
23 |
+
<td><?php echo $valueExport->exportValue($bag->get($key)) ?></td>
|
24 |
+
</tr>
|
25 |
+
|
26 |
+
<?php endforeach;?>
|
27 |
+
<?php else: ?>
|
28 |
+
<tr>
|
29 |
+
<td colspan="2">(no data)</td>
|
30 |
+
</tr>
|
31 |
+
<?php endif;?>
|
32 |
+
</tbody>
|
33 |
+
</table>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/ajax/toolbar.phtml
ADDED
@@ -0,0 +1,38 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_MysqlDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
|
8 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-normal">
|
9 |
+
<div class="sf-toolbar-icon">
|
10 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
11 |
+
<path fill="#AAAAAA" d="M9.8,18l-3.8,4.4c-0.3,0.3-0.8,0.4-1.1,0L1,18c-0.4-0.5-0.1-1,0.5-1H3V6.4C3,3.8,5.5,2,8.2,2h3.9
|
12 |
+
c1.1,0,2,0.9,2,2s-0.9,2-2,2H8.2C7.7,6,7,6,7,6.4V17h2.2C9.8,17,10.2,17.5,9.8,18z M23,6l-3.8-4.5c-0.3-0.3-0.8-0.3-1.1,0L14.2,6
|
13 |
+
c-0.4,0.5-0.1,1,0.5,1H17v10.6c0,0.4-0.7,0.4-1.2,0.4h-3.9c-1.1,0-2,0.9-2,2s0.9,2,2,2h3.9c2.6,0,5.2-1.8,5.2-4.4V7h1.5
|
14 |
+
C23.1,7,23.4,6.5,23,6z"/>
|
15 |
+
</svg>
|
16 |
+
<span class="sf-toolbar-value sf-toolbar-ajax-requests">0</span>
|
17 |
+
|
18 |
+
</div>
|
19 |
+
<div class="sf-toolbar-info">
|
20 |
+
<div class="sf-toolbar-info-piece">
|
21 |
+
<b class="sf-toolbar-ajax-info"></b>
|
22 |
+
</div>
|
23 |
+
<div class="sf-toolbar-info-piece">
|
24 |
+
<table class="sf-toolbar-ajax-requests">
|
25 |
+
<thead>
|
26 |
+
<tr>
|
27 |
+
<th>Method</th>
|
28 |
+
<th>Status</th>
|
29 |
+
<th>URL</th>
|
30 |
+
<th>Time</th>
|
31 |
+
<th>Profile</th>
|
32 |
+
</tr>
|
33 |
+
</thead>
|
34 |
+
<tbody class="sf-toolbar-ajax-request-list"></tbody>
|
35 |
+
</table>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/base/menu.phtml
ADDED
@@ -0,0 +1,8 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
?>
|
5 |
+
|
6 |
+
<span class="label">
|
7 |
+
<strong><?php echo ucwords($collector->getName()) ?></strong>
|
8 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/cache/menu.phtml
ADDED
@@ -0,0 +1,8 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<span class="label">
|
2 |
+
<span class="icon">
|
3 |
+
<svg width="24" height="24" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
|
4 |
+
<path fill="#AAAAAA" d="M1168 1216q0 33-23.5 56.5t-56.5 23.5-56.5-23.5-23.5-56.5 23.5-56.5 56.5-23.5 56.5 23.5 23.5 56.5zm256 0q0 33-23.5 56.5t-56.5 23.5-56.5-23.5-23.5-56.5 23.5-56.5 56.5-23.5 56.5 23.5 23.5 56.5zm112 160v-320q0-13-9.5-22.5t-22.5-9.5h-1216q-13 0-22.5 9.5t-9.5 22.5v320q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5-9.5t9.5-22.5zm-1230-480h1180l-157-482q-4-13-16-21.5t-26-8.5h-782q-14 0-26 8.5t-16 21.5zm1358 160v320q0 66-47 113t-113 47h-1216q-66 0-113-47t-47-113v-320q0-25 16-75l197-606q17-53 63-86t101-33h782q55 0 101 33t63 86l197 606q16 50 16 75z"/>
|
5 |
+
</svg>
|
6 |
+
</span>
|
7 |
+
<strong>Cache</strong>
|
8 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/cache/panel.phtml
ADDED
@@ -0,0 +1,164 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_CacheDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
$iconYes = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="28" height="28" viewBox="0 0 12 12" enable-background="new 0 0 12 12" xml:space="preserve">
|
7 |
+
<path fill="#5E976E" d="M12,3.1c0,0.4-0.1,0.8-0.4,1.1L5.9,9.8c-0.3,0.3-0.6,0.4-1,0.4c-0.4,0-0.7-0.1-1-0.4L0.4,6.3
|
8 |
+
C0.1,6,0,5.6,0,5.2c0-0.4,0.2-0.7,0.4-0.9C0.6,4,1,3.9,1.3,3.9c0.4,0,0.8,0.1,1.1,0.4l2.5,2.5l4.7-4.7c0.3-0.3,0.7-0.4,1-0.4
|
9 |
+
c0.4,0,0.7,0.2,0.9,0.4C11.8,2.4,12,2.7,12,3.1z"/>
|
10 |
+
</svg>';
|
11 |
+
$iconNo = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="28" height="28" viewBox="0 0 12 12" enable-background="new 0 0 12 12" xml:space="preserve">
|
12 |
+
<path fill="#B0413E" d="M10.4,8.4L8,6l2.4-2.4c0.8-0.8,0.7-1.6,0.2-2.2C10,0.9,9.2,0.8,8.4,1.6L6,4L3.6,1.6C2.8,0.8,2,0.9,1.4,1.4
|
13 |
+
C0.9,2,0.8,2.8,1.6,3.6L4,6L1.6,8.4C0.8,9.2,0.9,10,1.4,10.6c0.6,0.6,1.4,0.6,2.2-0.2L6,8l2.4,2.4c0.8,0.8,1.6,0.7,2.2,0.2
|
14 |
+
C11.1,10,11.2,9.2,10.4,8.4z"/>
|
15 |
+
</svg>';
|
16 |
+
|
17 |
+
$cacheTypes = Mage::app()->getCacheInstance()->getTypes();
|
18 |
+
?>
|
19 |
+
<h2>Cache metrics</h2>
|
20 |
+
|
21 |
+
<div class="metrics">
|
22 |
+
<?php foreach ($collector->getStats() as $key => $value): ?>
|
23 |
+
<div class="metric">
|
24 |
+
<span class="value"><?php echo $value ?></span>
|
25 |
+
<span class="label"><?php echo uc_words($key) ?></span>
|
26 |
+
</div>
|
27 |
+
|
28 |
+
<?php endforeach; ?>
|
29 |
+
|
30 |
+
<div class="metric">
|
31 |
+
<span class="value"><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
32 |
+
<span class="label">Time</span>
|
33 |
+
</div>
|
34 |
+
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<h2>Cache configuration</h2>
|
38 |
+
<table class="cache-table">
|
39 |
+
<thead>
|
40 |
+
<tr>
|
41 |
+
<th class="key">Id</th>
|
42 |
+
<th>Type</th>
|
43 |
+
<th>Run Status</th>
|
44 |
+
<th>Current Status</th>
|
45 |
+
<th class="text-right">
|
46 |
+
<a data-url="<?php echo Mage::getUrl('_profiler/cache/clearAll') ?>" class="btn btn-sm ajax-action">Clear
|
47 |
+
All</a>
|
48 |
+
</th>
|
49 |
+
</tr>
|
50 |
+
</thead>
|
51 |
+
<tbody>
|
52 |
+
<?php foreach ($collector->getCacheList() as $cache): ?>
|
53 |
+
<?php $currentStatus = $cacheTypes[$cache['id']]->getData('status'); ?>
|
54 |
+
<tr>
|
55 |
+
<td><?php echo $cache['id'] ?></td>
|
56 |
+
<td><?php echo $cache['cache_type'] ?></td>
|
57 |
+
<td>
|
58 |
+
<?php echo $cache['status'] ? $iconYes : $iconNo ?>
|
59 |
+
</td>
|
60 |
+
<td>
|
61 |
+
<?php echo $currentStatus ? $iconYes : $iconNo ?>
|
62 |
+
</td>
|
63 |
+
<td class="text-right">
|
64 |
+
<?php if ($currentStatus): ?>
|
65 |
+
<a href="#"
|
66 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/clear', ['types' => $cache['id']]) ?>"
|
67 |
+
class="btn btn-sm ajax-action">Clear</a>
|
68 |
+
<a href="#"
|
69 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/disable', ['types' => $cache['id']]) ?>"
|
70 |
+
class="btn btn-sm ajax-action">Disable</a>
|
71 |
+
<?php else: ?>
|
72 |
+
<a href="#"
|
73 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/enable', ['types' => $cache['id']]) ?>"
|
74 |
+
class="btn btn-sm ajax-action">Enable</a>
|
75 |
+
<?php endif; ?>
|
76 |
+
</td>
|
77 |
+
</tr>
|
78 |
+
<?php endforeach; ?>
|
79 |
+
</tbody>
|
80 |
+
</table>
|
81 |
+
|
82 |
+
<h2>
|
83 |
+
Cache Backend<br>
|
84 |
+
<small><?php echo $collector->getBackendName() ?></small>
|
85 |
+
</h2>
|
86 |
+
<table>
|
87 |
+
<thead>
|
88 |
+
<tr>
|
89 |
+
<th>Key</th>
|
90 |
+
<th>Time</th>
|
91 |
+
</tr>
|
92 |
+
</thead>
|
93 |
+
<tbody>
|
94 |
+
<?php foreach ($collector->getBackendOptions() as $key => $value): ?>
|
95 |
+
<tr>
|
96 |
+
<td class="nowrap"><?php echo $key ?> </td>
|
97 |
+
<td class="nowrap"><?php echo $value ?></td>
|
98 |
+
</tr>
|
99 |
+
<?php endforeach; ?>
|
100 |
+
</tbody>
|
101 |
+
</table>
|
102 |
+
|
103 |
+
<h2>Cache Calls</h2>
|
104 |
+
<table>
|
105 |
+
<thead>
|
106 |
+
<tr>
|
107 |
+
<th>#</th>
|
108 |
+
<th>Action</th>
|
109 |
+
<th style="width: 100%;">Id</th>
|
110 |
+
<th>Hit</th>
|
111 |
+
<th>Time</th>
|
112 |
+
</tr>
|
113 |
+
</thead>
|
114 |
+
<tbody>
|
115 |
+
<?php foreach ($collector->getCacheCalls() as $index => $call): ?>
|
116 |
+
<tr>
|
117 |
+
<td class="nowrap"><?php echo $index + 1 ?> </td>
|
118 |
+
<td><?php echo $call['action'] ?></td>
|
119 |
+
<td>
|
120 |
+
<?php echo isset($call['id']) ? $call['id'] : '-'; ?>
|
121 |
+
<?php if (!empty($call['tags'])): ?>
|
122 |
+
<br>
|
123 |
+
<small><strong>Tags:</strong> <?php echo implode(', ', $call['tags']) ?></small>
|
124 |
+
<?php endif; ?>
|
125 |
+
</td>
|
126 |
+
<td>
|
127 |
+
<?php if (isset($call['hit'])): ?>
|
128 |
+
<span class="label status-<?php echo $call['hit'] ? 'success' : 'error' ?>">
|
129 |
+
<?php echo $call['hit'] ? 'Hit' : 'Miss' ?>
|
130 |
+
</span>
|
131 |
+
<?php else: ?>
|
132 |
+
-
|
133 |
+
<?php endif ?>
|
134 |
+
</td>
|
135 |
+
<td class="nowrap"><?php echo sprintf('%0.2f', $call['time'] * 1000) ?> ms</td>
|
136 |
+
</tr>
|
137 |
+
<?php endforeach; ?>
|
138 |
+
</tbody>
|
139 |
+
</table>
|
140 |
+
<script>
|
141 |
+
(function () {
|
142 |
+
var actions = document.querySelectorAll('.cache-table .ajax-action');
|
143 |
+
|
144 |
+
for (var i = 0; i < actions.length; i++) {
|
145 |
+
(function () {
|
146 |
+
|
147 |
+
var button = actions[i],
|
148 |
+
url = button.getAttribute('data-url');
|
149 |
+
|
150 |
+
button.addEventListener('click', function (e) {
|
151 |
+
Sfjs.request(url, function () {
|
152 |
+
window.location.reload();
|
153 |
+
});
|
154 |
+
});
|
155 |
+
})();
|
156 |
+
}
|
157 |
+
})();
|
158 |
+
</script>
|
159 |
+
<style>
|
160 |
+
.cache-table td svg {
|
161 |
+
width: 16px;
|
162 |
+
height: 16px;
|
163 |
+
}
|
164 |
+
</style>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/cache/toolbar.phtml
ADDED
@@ -0,0 +1,62 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_CacheDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
|
6 |
+
$cacheList = $collector->getCacheList();
|
7 |
+
$cacheTypes = Mage::app()->getCacheInstance()->getTypes();
|
8 |
+
?>
|
9 |
+
|
10 |
+
<div
|
11 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?>">
|
12 |
+
<a target="_blank"
|
13 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
14 |
+
<div class="sf-toolbar-icon">
|
15 |
+
<svg width="24" height="24" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
|
16 |
+
<path fill="#AAAAAA" d="M1168 1216q0 33-23.5 56.5t-56.5 23.5-56.5-23.5-23.5-56.5 23.5-56.5 56.5-23.5 56.5 23.5 23.5 56.5zm256 0q0 33-23.5 56.5t-56.5 23.5-56.5-23.5-23.5-56.5 23.5-56.5 56.5-23.5 56.5 23.5 23.5 56.5zm112 160v-320q0-13-9.5-22.5t-22.5-9.5h-1216q-13 0-22.5 9.5t-9.5 22.5v320q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5-9.5t9.5-22.5zm-1230-480h1180l-157-482q-4-13-16-21.5t-26-8.5h-782q-14 0-26 8.5t-16 21.5zm1358 160v320q0 66-47 113t-113 47h-1216q-66 0-113-47t-47-113v-320q0-25 16-75l197-606q17-53 63-86t101-33h782q55 0 101 33t63 86l197 606q16 50 16 75z"/>
|
17 |
+
</svg>
|
18 |
+
<span class="sf-toolbar-value"><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
19 |
+
</div>
|
20 |
+
</a>
|
21 |
+
<div class="sf-toolbar-info">
|
22 |
+
<div class="sf-toolbar-info-group" style="float: left;">
|
23 |
+
<?php foreach ($cacheList as $cache): ?>
|
24 |
+
<?php $currentStatus = $cacheTypes[$cache['id']]->getData('status'); ?>
|
25 |
+
<div class="sf-toolbar-info-piece">
|
26 |
+
<b><?php echo uc_words($cache['id'], ' ')?></b>
|
27 |
+
<?php if($cache['status'] == 1): ?>
|
28 |
+
<span class="sf-toolbar-status sf-toolbar-status-green">Yes</span>
|
29 |
+
<?php else:?>
|
30 |
+
<span class="sf-toolbar-status">No</span>
|
31 |
+
<?php endif;?>
|
32 |
+
|
33 |
+
<?php if ($currentStatus): ?>
|
34 |
+
<a href="#"
|
35 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/clear', ['types' => $cache['id']]) ?>"
|
36 |
+
class="btn btn-sm ajax-action">Clear</a> /
|
37 |
+
<a href="#"
|
38 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/disable', ['types' => $cache['id']]) ?>"
|
39 |
+
class="btn btn-sm ajax-action">Disable</a>
|
40 |
+
<?php else: ?>
|
41 |
+
<a href="#"
|
42 |
+
data-url="<?php echo Mage::getUrl('_profiler/cache/enable', ['types' => $cache['id']]) ?>"
|
43 |
+
class="btn btn-sm ajax-action">Enable</a>
|
44 |
+
<?php endif; ?>
|
45 |
+
</div>
|
46 |
+
<?php endforeach; ?>
|
47 |
+
</div>
|
48 |
+
<div class="sf-toolbar-info-group" >
|
49 |
+
<div class="sf-toolbar-info-piece">
|
50 |
+
<b>Cache calls</b>
|
51 |
+
<span class="sf-toolbar-status"><?php echo $collector->getStats('total') ?></span>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<div class="sf-toolbar-info-piece">
|
55 |
+
<b>Time</b>
|
56 |
+
<span><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
57 |
+
</div>
|
58 |
+
</div>
|
59 |
+
|
60 |
+
</div>
|
61 |
+
|
62 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/config/menu.phtml
ADDED
@@ -0,0 +1,10 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<span class="label">
|
2 |
+
<span class="icon">
|
3 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24"
|
4 |
+
enable-background="new 0 0 24 24" xml:space="preserve">
|
5 |
+
<path fill="#AAAAAA"
|
6 |
+
d="M11,5.1C11,3.4,9.6,2,7.9,2H5.1C3.4,2,2,3.4,2,5.1v12.9C2,19.6,3.4,21,5.1,21h2.9c1.7,0,3.1-1.4,3.1-3.1V5.1z M5.2,4h2.7C8.4,4,9,4.8,9,5.3V11H4V5.3C4,4.8,4.6,4,5.2,4z M22,5.1C22,3.4,20.6,2,18.9,2h-2.9C14.4,2,13,3.4,13,5.1v12.9c0,1.7,1.4,3.1,3.1,3.1h2.9c1.7,0,3.1-1.4,3.1-3.1V5.1z M16,4h2.8C19.4,4,20,4.8,20,5.3V8h-5V5.3C15,4.8,15.5,4,16,4z"/>
|
7 |
+
</svg>
|
8 |
+
</span>
|
9 |
+
<strong>Configuration</strong>
|
10 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/config/panel.phtml
ADDED
@@ -0,0 +1,151 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_ConfigDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
$iconYes = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="28" height="28" viewBox="0 0 12 12" enable-background="new 0 0 12 12" xml:space="preserve">
|
7 |
+
<path fill="#5E976E" d="M12,3.1c0,0.4-0.1,0.8-0.4,1.1L5.9,9.8c-0.3,0.3-0.6,0.4-1,0.4c-0.4,0-0.7-0.1-1-0.4L0.4,6.3
|
8 |
+
C0.1,6,0,5.6,0,5.2c0-0.4,0.2-0.7,0.4-0.9C0.6,4,1,3.9,1.3,3.9c0.4,0,0.8,0.1,1.1,0.4l2.5,2.5l4.7-4.7c0.3-0.3,0.7-0.4,1-0.4
|
9 |
+
c0.4,0,0.7,0.2,0.9,0.4C11.8,2.4,12,2.7,12,3.1z"/>
|
10 |
+
</svg>';
|
11 |
+
$iconNo = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="28" height="28" viewBox="0 0 12 12" enable-background="new 0 0 12 12" xml:space="preserve">
|
12 |
+
<path fill="#B0413E" d="M10.4,8.4L8,6l2.4-2.4c0.8-0.8,0.7-1.6,0.2-2.2C10,0.9,9.2,0.8,8.4,1.6L6,4L3.6,1.6C2.8,0.8,2,0.9,1.4,1.4
|
13 |
+
C0.9,2,0.8,2.8,1.6,3.6L4,6L1.6,8.4C0.8,9.2,0.9,10,1.4,10.6c0.6,0.6,1.4,0.6,2.2-0.2L6,8l2.4,2.4c0.8,0.8,1.6,0.7,2.2,0.2
|
14 |
+
C11.1,10,11.2,9.2,10.4,8.4z"/>
|
15 |
+
</svg>';
|
16 |
+
|
17 |
+
?>
|
18 |
+
<h2>PHP Configuration</h2>
|
19 |
+
|
20 |
+
<div class="metrics">
|
21 |
+
<div class="metric">
|
22 |
+
<span class="value"><?php echo $collector->getPhpVersion() ?></span>
|
23 |
+
<span class="label">PHP version</span>
|
24 |
+
</div>
|
25 |
+
|
26 |
+
<div class="metric">
|
27 |
+
<span class="value"><?php echo $collector->hasAccelerator() ? $iconYes : $iconNo; ?></span>
|
28 |
+
<span class="label">PHP acceleration</span>
|
29 |
+
</div>
|
30 |
+
|
31 |
+
<div class="metric">
|
32 |
+
<span class="value"><?php echo $collector->hasXDebug() ? $iconYes : $iconNo; ?></span>
|
33 |
+
<span class="label">Xdebug</span>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
|
37 |
+
<div class="metrics metrics-horizontal">
|
38 |
+
<div class="metric">
|
39 |
+
<span
|
40 |
+
<span class="value"><?php echo $collector->hasZendOpcache() ? $iconYes : $iconNo; ?></span>
|
41 |
+
<span class="label">OPcache</span>
|
42 |
+
</div>
|
43 |
+
|
44 |
+
<div class="metric">
|
45 |
+
<span class="value"><?php echo $collector->hasApc() ? $iconYes : $iconNo; ?></span>
|
46 |
+
<span class="label">APC</span>
|
47 |
+
</div>
|
48 |
+
|
49 |
+
<div class="metric">
|
50 |
+
<span class="value"><?php echo $collector->hasXCache() ? $iconYes : $iconNo; ?></span>
|
51 |
+
<span class="label">XCache</span>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<div class="metric">
|
55 |
+
<span
|
56 |
+
<span class="value"><?php echo $collector->hasEAccelerator() ? $iconYes : $iconNo; ?></span>
|
57 |
+
<span class="label">EAccelerator</span>
|
58 |
+
</div>
|
59 |
+
</div>
|
60 |
+
|
61 |
+
<p>
|
62 |
+
<a href="<?php echo Mage::getUrl('_profiler/index/phpinfo') ?>">View full PHP configuration</a>
|
63 |
+
</p>
|
64 |
+
|
65 |
+
|
66 |
+
<h2>Magento</h2>
|
67 |
+
<table>
|
68 |
+
<thead>
|
69 |
+
<tr>
|
70 |
+
<th class="key">Key</th>
|
71 |
+
<th>Value</th>
|
72 |
+
</tr>
|
73 |
+
</thead>
|
74 |
+
<tbody>
|
75 |
+
<tr>
|
76 |
+
<td>Admin Url</td>
|
77 |
+
<td><?php $adminUrl = Mage::helper('adminhtml')->getUrl('adminhtml'); ?>
|
78 |
+
<a href="<?php echo $adminUrl ?>"><?php echo $adminUrl ?></a>
|
79 |
+
</td>
|
80 |
+
</tr>
|
81 |
+
<tr>
|
82 |
+
<td>Website</td>
|
83 |
+
<td><?php echo $collector->getWebsiteName() ?> (<?php echo $collector->getWebsiteCode() ?>)</td>
|
84 |
+
</tr>
|
85 |
+
<tr>
|
86 |
+
<td>Store</td>
|
87 |
+
<td><?php echo $collector->getStoreName() ?> (<?php echo $collector->getStoreCode() ?>)</td>
|
88 |
+
</tr>
|
89 |
+
</tbody>
|
90 |
+
</table>
|
91 |
+
|
92 |
+
|
93 |
+
<h2>Modules</h2>
|
94 |
+
<?php $activeModules = $collector->geModulesByState(true); ?>
|
95 |
+
<?php $inActiveModules = $collector->geModulesByState(false); ?>
|
96 |
+
<div class="sf-tabs">
|
97 |
+
<div class="tab">
|
98 |
+
<h3 class="tab-title">Enabled Modules
|
99 |
+
<small>(<?php echo count($activeModules) ?>)</small>
|
100 |
+
</h3>
|
101 |
+
|
102 |
+
|
103 |
+
<div class="tab-content">
|
104 |
+
<table>
|
105 |
+
<thead>
|
106 |
+
<tr>
|
107 |
+
<th>Module</th>
|
108 |
+
<th>Namespace</th>
|
109 |
+
<th>Version</th>
|
110 |
+
</tr>
|
111 |
+
</thead>
|
112 |
+
<tbody>
|
113 |
+
<?php foreach ($activeModules as $name => $data): ?>
|
114 |
+
<tr>
|
115 |
+
<td><?php echo $name ?></td>
|
116 |
+
<td><?php echo $data['codePool'] ?></td>
|
117 |
+
<td><?php echo isset($data['version']) ? $data['version'] : '?' ?></td>
|
118 |
+
</tr>
|
119 |
+
|
120 |
+
<?php endforeach; ?>
|
121 |
+
</tbody>
|
122 |
+
</table>
|
123 |
+
</div>
|
124 |
+
</div>
|
125 |
+
<div class="tab">
|
126 |
+
<h3 class="tab-title">Disables Modules
|
127 |
+
<small>(<?php echo count($inActiveModules) ?>)</small>
|
128 |
+
</h3>
|
129 |
+
|
130 |
+
|
131 |
+
<div class="tab-content">
|
132 |
+
<table>
|
133 |
+
<thead>
|
134 |
+
<tr>
|
135 |
+
<th>Module</th>
|
136 |
+
<th>Namespace</th>
|
137 |
+
</tr>
|
138 |
+
</thead>
|
139 |
+
<tbody>
|
140 |
+
<?php foreach ($inActiveModules as $name => $data): ?>
|
141 |
+
<tr>
|
142 |
+
<td><?php echo $name ?></td>
|
143 |
+
<td><?php echo isset($data['codePool']) ? $data['codePool'] : '?' ?></td>
|
144 |
+
</tr>
|
145 |
+
|
146 |
+
<?php endforeach; ?>
|
147 |
+
</tbody>
|
148 |
+
</table>
|
149 |
+
</div>
|
150 |
+
</div>
|
151 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/config/toolbar.phtml
ADDED
@@ -0,0 +1,79 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_ConfigDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
|
8 |
+
<div
|
9 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?> sf-toolbar-status-normal sf-toolbar-block-right">
|
10 |
+
<div class="sf-toolbar-icon">
|
11 |
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svgMageLogo" width="24" xml:space="preserve" height="24" viewBox="0 0 53.692 62" baseProfile="" version="1.1" y="0px" x="0px">
|
12 |
+
<g fill="#AAA">
|
13 |
+
<path d="m26.845 8.857"/><polygon points="53.692 15.5 53.692 46.5 46.021 50.929 46.021 19.929 26.845 8.857 7.67 19.928 7.67 50.929 0 46.5 0 15.5 26.845 0"/><polygon points="26.847 62 15.341 55.356 15.341 24.357 23.011 19.928 23.011 50.929 26.845 53.257 30.682 50.929 30.682 19.929 38.353 24.357 38.353 55.356"/>
|
14 |
+
</g>
|
15 |
+
</svg>
|
16 |
+
<span class="sf-toolbar-value"><?php echo $collector->getMagentoVersion() ?></span>
|
17 |
+
|
18 |
+
</div>
|
19 |
+
<div class="sf-toolbar-info">
|
20 |
+
<div class="sf-toolbar-info-group">
|
21 |
+
|
22 |
+
<div class="sf-toolbar-info-piece">
|
23 |
+
<b>Website</b>
|
24 |
+
<span><?php echo $collector->getWebsiteName() ?> (<?php echo $collector->getWebsiteCode() ?>) </span>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<div class="sf-toolbar-info-piece">
|
28 |
+
<b>Store</b>
|
29 |
+
<span><?php echo $collector->getStoreName() ?> (<?php echo $collector->getStoreCode() ?>) </span>
|
30 |
+
</div>
|
31 |
+
|
32 |
+
<div class="sf-toolbar-info-piece">
|
33 |
+
<b>Profiler token</b>
|
34 |
+
<span>
|
35 |
+
<?php $profilerUrl = Mage::helper('ecocode_profiler')->getUrl($collector->getToken()) ?>
|
36 |
+
<a href="<?php echo $profilerUrl?>"><?php echo $collector->getToken()?></a>
|
37 |
+
</span>
|
38 |
+
</div>
|
39 |
+
|
40 |
+
<div class="sf-toolbar-info-piece">
|
41 |
+
<b>Admin Url</b>
|
42 |
+
<span>
|
43 |
+
<?php $adminUrl = Mage::helper('adminhtml')->getUrl('adminhtml'); ?>
|
44 |
+
<a href="<?php echo $adminUrl?>">Admin</a>
|
45 |
+
</span>
|
46 |
+
</div>
|
47 |
+
|
48 |
+
<div class="sf-toolbar-info-piece">
|
49 |
+
<b>Developermode</b>
|
50 |
+
<span>
|
51 |
+
<?php echo $collector->isDeveloperMode() ? 'on' : 'off'; ?>
|
52 |
+
</span>
|
53 |
+
</div>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
<div class="sf-toolbar-info-group">
|
57 |
+
<div class="sf-toolbar-info-piece sf-toolbar-info-php">
|
58 |
+
<b>PHP version</b>
|
59 |
+
<span>
|
60 |
+
<?php echo $collector->getPhpVersion() ?>
|
61 |
+
<a href="<?php echo Mage::getUrl('_profiler/index/phpinfo') ?> ">View phpinfo()</a>
|
62 |
+
</span>
|
63 |
+
</div>
|
64 |
+
|
65 |
+
<div class="sf-toolbar-info-piece sf-toolbar-info-php-ext">
|
66 |
+
<b>PHP Extensions</b>
|
67 |
+
<span
|
68 |
+
class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->hasXDebug() ? 'green' : 'red' ?>">xdebug</span>
|
69 |
+
<span
|
70 |
+
class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->hasAccelerator() ? 'green' : 'red' ?>">accel</span>
|
71 |
+
</div>
|
72 |
+
|
73 |
+
<div class="sf-toolbar-info-piece">
|
74 |
+
<b>PHP SAPI</b>
|
75 |
+
<span><?php echo $collector->getSapiName() ?></span>
|
76 |
+
</div>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/customer/toolbar.phtml
ADDED
@@ -0,0 +1,45 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_CustomerDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
|
8 |
+
<div
|
9 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?>">
|
10 |
+
<div class="sf-toolbar-icon">
|
11 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
12 |
+
<path fill="#AAAAAA" d="M21,20.4V22H3v-1.6c0-3.7,2.4-6.9,5.8-8c-1.7-1.1-2.9-3-2.9-5.2c0-3.4,2.7-6.1,6.1-6.1s6.1,2.7,6.1,6.1c0,2.2-1.2,4.1-2.9,5.2C18.6,13.5,21,16.7,21,20.4z"/>
|
13 |
+
</svg>
|
14 |
+
<span class="sf-toolbar-value">
|
15 |
+
<?php if ($collector->isLoggedIn()): ?>
|
16 |
+
<?php echo $collector->getCustomerEmail(); ?>
|
17 |
+
<?php else: ?>
|
18 |
+
n/a
|
19 |
+
<?php endif; ?>
|
20 |
+
</span>
|
21 |
+
|
22 |
+
</div>
|
23 |
+
<div class="sf-toolbar-info">
|
24 |
+
<?php if ($collector->isLoggedIn()): ?>
|
25 |
+
<div class="sf-toolbar-info-piece">
|
26 |
+
<b>Logged in as</b>
|
27 |
+
<span><?php echo $collector->getCustomerEmail(); ?></span>
|
28 |
+
</div>
|
29 |
+
<div class="sf-toolbar-info-piece">
|
30 |
+
<b>Name</b>
|
31 |
+
<span><?php echo $collector->getCustomerName(); ?></span>
|
32 |
+
</div>
|
33 |
+
<?php endif; ?>
|
34 |
+
|
35 |
+
<div class="sf-toolbar-info-piece">
|
36 |
+
<b>Customer Group</b>
|
37 |
+
<span><?php echo $collector->getGroupCode(); ?> (Id: <?php echo $collector->getGroupId(); ?>) </span>
|
38 |
+
</div>
|
39 |
+
|
40 |
+
<div class="sf-toolbar-info-piece">
|
41 |
+
<b>Tax Class</b>
|
42 |
+
<span><?php echo $collector->getTaxClassName(); ?> (Id: <?php echo $collector->getTaxClassId(); ?>) </span>
|
43 |
+
</div>
|
44 |
+
</div>
|
45 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/event/menu.phtml
ADDED
@@ -0,0 +1,17 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<span class="label">
|
2 |
+
<span class="icon">
|
3 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
4 |
+
<path fill="#AAAAAA" d="M19.2,20.8c0.4,0.7,0.1,1.6-0.6,2c-0.2,0.1-0.5,0.2-0.7,0.2c-0.5,0-1-0.3-1.3-0.8l-3.7-6.7
|
5 |
+
c-0.3,0.1-0.7,0.1-1,0.1c-0.3,0-0.6,0-0.9-0.1l-3.7,6.7C6.9,22.7,6.4,23,5.8,23c-0.2,0-0.5-0.1-0.7-0.2c-0.7-0.4-1-1.3-0.6-2
|
6 |
+
l3.8-6.9c-0.5-0.7-0.9-1.6-0.9-2.6C7.5,8.9,9.4,7,11.8,7s4.3,1.9,4.3,4.3c0,0.9-0.3,1.8-0.8,2.5L19.2,20.8z M5.2,11
|
7 |
+
C5.2,11,5.2,11,5.2,11c0.6,0,1-0.3,1-0.8c0-2.1,1.6-3.8,3.7-4.1c0.5-0.1,0.9-0.6,0.8-1.2C10.6,4.4,10.1,4,9.6,4
|
8 |
+
c-3.1,0.5-5.3,3-5.3,6.1C4.2,10.7,4.7,11,5.2,11z M13.6,6c2.1,0.3,3.7,2.1,3.8,4.2c0,0.5,0.5,0.8,1,0.8c0,0,0,0,0,0
|
9 |
+
c0.6,0,1-0.3,1-0.8c0-3.1-2.4-5.6-5.5-6.1c-0.5-0.1-1.1,0.3-1.1,0.8C12.6,5.5,13,5.9,13.6,6z M9,3c0.5-0.1,0.9-0.6,0.8-1.1
|
10 |
+
C9.7,1.3,9.2,1,8.7,1.1C4.5,1.8,1.4,5.5,1.3,9.8c0,0.6,0.4,1.2,1,1.2c0,0,0,0,0,0c0.5,0,1-0.6,1-1.2C3.3,6.5,5.7,3.5,9,3z M14.7,1
|
11 |
+
c-0.5-0.1-1.1,0.3-1.1,0.9S13.9,3,14.4,3c3.3,0.5,5.8,3.4,5.8,6.8c0,0.5,0.5,1.2,1,1.2c0,0,0,0,0,0c0.6,0,1-0.7,1-1.2
|
12 |
+
C22.2,5.5,19,1.6,14.7,1z"/>
|
13 |
+
</svg>
|
14 |
+
|
15 |
+
</span>
|
16 |
+
<strong>Events</strong>
|
17 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/event/panel.phtml
ADDED
@@ -0,0 +1,116 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
4 |
+
|
5 |
+
/** @var Ecocode_Profiler_Model_Collector_EventDataCollector $collector */
|
6 |
+
$collector = $this->getCollector();
|
7 |
+
|
8 |
+
$eventsFired = $collector->getFiredEvents();
|
9 |
+
?>
|
10 |
+
<h2>Events</h2>
|
11 |
+
|
12 |
+
<?php if (!$eventsFired): ?>
|
13 |
+
<div class="empty">
|
14 |
+
<p>No events have been recorded. Check that you are loading "AppDev"</p>
|
15 |
+
</div>
|
16 |
+
<?php else: ?>
|
17 |
+
<?php
|
18 |
+
$calledListeners = $collector->getCalledListeners()
|
19 |
+
?>
|
20 |
+
<div class="sf-tabs">
|
21 |
+
<div class="tab">
|
22 |
+
<h3 class="tab-title">Events Fired <span class="badge"><?php echo count($eventsFired) ?></span></h3>
|
23 |
+
<div class="tab-content">
|
24 |
+
<table>
|
25 |
+
<thead>
|
26 |
+
<tr>
|
27 |
+
<th>Event</th>
|
28 |
+
<th>Observer</th>
|
29 |
+
<th>Count</th>
|
30 |
+
</tr>
|
31 |
+
</thead>
|
32 |
+
<tbody>
|
33 |
+
|
34 |
+
<?php foreach ($eventsFired as $index => $event): ?>
|
35 |
+
<tr>
|
36 |
+
<td>
|
37 |
+
<?php echo $event['name'] ?>
|
38 |
+
<?php if ($event['observer_count']): ?>
|
39 |
+
<a href="#" class="sf-toggle link-inverse text-small"
|
40 |
+
data-toggle-selector="#event-observer-<?php echo $index ?>"
|
41 |
+
data-toggle-alt-content="Hide observer">Show observer</a>
|
42 |
+
<div id="event-observer-<?php echo $index ?>" class="hidden">
|
43 |
+
<ul>
|
44 |
+
<?php foreach ($event['observer'] as $area => $observers):?>
|
45 |
+
<li>
|
46 |
+
<?php echo $area ?>
|
47 |
+
<table>
|
48 |
+
<thead>
|
49 |
+
<tr>
|
50 |
+
<th>Name</th>
|
51 |
+
<th>Type</th>
|
52 |
+
<th>Model</th>
|
53 |
+
<th>Method</th>
|
54 |
+
</tr>
|
55 |
+
</thead>
|
56 |
+
<?php foreach ($observers as $name => $observer):?>
|
57 |
+
<tr>
|
58 |
+
<td><?php echo $name ?></td>
|
59 |
+
<td><?php echo $observer['type'] ? $observer['type'] : 'singleton' ?></td>
|
60 |
+
<td><?php echo $observer['model'] ?></td>
|
61 |
+
<td><?php echo $observer['method'] ?></td>
|
62 |
+
</tr>
|
63 |
+
<?php endforeach;?>
|
64 |
+
</table>
|
65 |
+
|
66 |
+
</li>
|
67 |
+
<?php endforeach;?>
|
68 |
+
</ul>
|
69 |
+
</div>
|
70 |
+
<?php endif; ?>
|
71 |
+
|
72 |
+
</td>
|
73 |
+
<td>
|
74 |
+
<?php if ($event['observer_count']): ?>
|
75 |
+
<?php echo $event['observer_count'] ?>
|
76 |
+
<?php else: ?>
|
77 |
+
-
|
78 |
+
<?php endif; ?>
|
79 |
+
</td>
|
80 |
+
<td><?php echo $event['count'] ?></td>
|
81 |
+
</tr>
|
82 |
+
|
83 |
+
<?php endforeach; ?>
|
84 |
+
</tbody>
|
85 |
+
|
86 |
+
</table>
|
87 |
+
</div>
|
88 |
+
</div>
|
89 |
+
|
90 |
+
<div class="tab">
|
91 |
+
<h3 class="tab-title">Called Listeners <span class="badge"><?php echo count($calledListeners) ?></span></h3>
|
92 |
+
|
93 |
+
<div class="tab-content">
|
94 |
+
<table>
|
95 |
+
<thead>
|
96 |
+
<tr>
|
97 |
+
<th>Event</th>
|
98 |
+
<th>Listener</th>
|
99 |
+
</tr>
|
100 |
+
</thead>
|
101 |
+
<tbody>
|
102 |
+
|
103 |
+
<?php foreach ($calledListeners as $listener): ?>
|
104 |
+
<tr>
|
105 |
+
<td><?php echo $listener['event_name'] ?></td>
|
106 |
+
<td><?php echo $listener['class'] ?>:<?php echo $listener['method'] ?></td>
|
107 |
+
</tr>
|
108 |
+
<?php endforeach; ?>
|
109 |
+
</tbody>
|
110 |
+
|
111 |
+
</table>
|
112 |
+
</div>
|
113 |
+
</div>
|
114 |
+
</div>
|
115 |
+
|
116 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/layout/menu.phtml
ADDED
@@ -0,0 +1,15 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_RewriteDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
?>
|
5 |
+
|
6 |
+
<span class="label label-status-normal">
|
7 |
+
<span class="icon">
|
8 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
9 |
+
<path fill="#AAAAAA" d="M20.1,1H3.9C2.3,1,1,2.3,1,3.9v16.3C1,21.7,2.3,23,3.9,23h16.3c1.6,0,2.9-1.3,2.9-2.9V3.9
|
10 |
+
C23,2.3,21.7,1,20.1,1z M21,20.1c0,0.5-0.4,0.9-0.9,0.9H3.9C3.4,21,3,20.6,3,20.1V3.9C3,3.4,3.4,3,3.9,3h16.3C20.6,3,21,3.4,21,3.9
|
11 |
+
V20.1z M5,5h14v3H5V5z M5,10h3v9H5V10z M10,10h9v9h-9V10z"/>
|
12 |
+
</svg>
|
13 |
+
</span>
|
14 |
+
<strong>Layout</strong>
|
15 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/layout/panel.phtml
ADDED
@@ -0,0 +1,69 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Layout_Panel $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_LayoutDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
|
7 |
+
?>
|
8 |
+
<h2>Render Metrics </h2>
|
9 |
+
<div class="metrics">
|
10 |
+
<div class="metric">
|
11 |
+
<span class="value"><?php echo sprintf('%0.0f', $collector->getTotalRenderTime() * 1000)?> <span class="unit">ms</span></span>
|
12 |
+
<span class="label">Render time</span>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
|
16 |
+
<div class="metric">
|
17 |
+
<span class="value"><?php echo $collector->getBlocksCreatedCount()?></span>
|
18 |
+
<span class="label">Block created</span>
|
19 |
+
</div>
|
20 |
+
|
21 |
+
<div class="metric">
|
22 |
+
<span class="value"><?php echo $collector->getBlocksRenderedCount()?></span>
|
23 |
+
<span class="label">Block rendered</span>
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<h2>Layout Handler</h2>
|
28 |
+
<table>
|
29 |
+
<thead>
|
30 |
+
<tr>
|
31 |
+
<th scope="col">Handler</th>
|
32 |
+
</tr>
|
33 |
+
</thead>
|
34 |
+
<tbody>
|
35 |
+
<?php foreach($collector->getLayoutHandles() as $handle): ?>
|
36 |
+
<tr>
|
37 |
+
<td><?php echo $handle?></td>
|
38 |
+
</tr>
|
39 |
+
</tbody>
|
40 |
+
<?php endforeach;?>
|
41 |
+
</table>
|
42 |
+
|
43 |
+
<h2>Created but not rendered blocks</h2>
|
44 |
+
<table>
|
45 |
+
<thead>
|
46 |
+
<tr>
|
47 |
+
<th scope="col">Name</th>
|
48 |
+
<th scope="col">Module</th>
|
49 |
+
<th scope="col">Type</th>
|
50 |
+
<th scope="col">Class</th>
|
51 |
+
</tr>
|
52 |
+
</thead>
|
53 |
+
<tbody>
|
54 |
+
<?php foreach($collector->getBlocksNotRendered() as $block): ?>
|
55 |
+
<tr>
|
56 |
+
<td><?php echo $block['name']?></td>
|
57 |
+
<td><?php echo $block['module']?></td>
|
58 |
+
<td><?php echo $block['type']?></td>
|
59 |
+
<td><?php echo $block['class']?></td>
|
60 |
+
</tr>
|
61 |
+
</tbody>
|
62 |
+
<?php endforeach;?>
|
63 |
+
</table>
|
64 |
+
|
65 |
+
|
66 |
+
<h2>Rendering Call Graph</h2>
|
67 |
+
<div id="twig-dump">
|
68 |
+
<?php echo $this->renderTree(); ?>
|
69 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/layout/toolbar.phtml
ADDED
@@ -0,0 +1,48 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_LayoutDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
<div
|
8 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?>">
|
9 |
+
<a target="_blank"
|
10 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
11 |
+
<div class="sf-toolbar-icon">
|
12 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
13 |
+
<path fill="#AAAAAA" d="M20.1,1H3.9C2.3,1,1,2.3,1,3.9v16.3C1,21.7,2.3,23,3.9,23h16.3c1.6,0,2.9-1.3,2.9-2.9V3.9
|
14 |
+
C23,2.3,21.7,1,20.1,1z M21,20.1c0,0.5-0.4,0.9-0.9,0.9H3.9C3.4,21,3,20.6,3,20.1V3.9C3,3.4,3.4,3,3.9,3h16.3C20.6,3,21,3.4,21,3.9
|
15 |
+
V20.1z M5,5h14v3H5V5z M5,10h3v9H5V10z M10,10h9v9h-9V10z"/>
|
16 |
+
</svg>
|
17 |
+
<span class="sf-toolbar-value"><?php echo sprintf('%0.0f', $collector->getTotalRenderTime() * 1000)?> <span class="unit">ms</span></span>
|
18 |
+
</div>
|
19 |
+
</a>
|
20 |
+
<div class="sf-toolbar-info">
|
21 |
+
<div class="sf-toolbar-info-group" >
|
22 |
+
<div class="sf-toolbar-info-piece">
|
23 |
+
<b>Layout handles</b>
|
24 |
+
<?php foreach ($collector->getLayoutHandles() as $handle): ?>
|
25 |
+
<?php echo $handle ?><br>
|
26 |
+
<?php endforeach; ?>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
<div class="sf-toolbar-info-group" >
|
30 |
+
<div class="sf-toolbar-info-piece">
|
31 |
+
<b>Render Time</b>
|
32 |
+
<span><?php echo sprintf('%0.0f', $collector->getTotalRenderTime() * 1000)?> ms</span>
|
33 |
+
</div>
|
34 |
+
|
35 |
+
|
36 |
+
<div class="sf-toolbar-info-piece">
|
37 |
+
<b>Block created</b>
|
38 |
+
<span class="sf-toolbar-status"><?php echo $collector->getBlocksCreatedCount()?></span>
|
39 |
+
</div>
|
40 |
+
|
41 |
+
|
42 |
+
<div class="sf-toolbar-info-piece">
|
43 |
+
<b>Block rendered</b>
|
44 |
+
<span class="sf-toolbar-status"><?php echo $collector->getBlocksRenderedCount()?></span>
|
45 |
+
</div>
|
46 |
+
</div>
|
47 |
+
</div>
|
48 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/log/menu.phtml
ADDED
@@ -0,0 +1,25 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$logCount = $collector->getLogCount();
|
5 |
+
$statusColor = $collector->countErrors() ? 'error' : ($collector->countDeprecations() ? 'warning' : '');
|
6 |
+
?>
|
7 |
+
|
8 |
+
<span class="label label-status-<?php echo $statusColor ?>">
|
9 |
+
<span class="icon">
|
10 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24"
|
11 |
+
enable-background="new 0 0 24 24" xml:space="preserve">
|
12 |
+
<path fill="#AAAAAA" d="M21,4v13.8c0,2.7-2.5,5.2-5.2,5.2H6c-0.6,0-1-0.4-1-1s0.4-1,1-1h9.8c1.6,0,3.2-1.7,3.2-3.2V4
|
13 |
+
c0-0.6,0.4-1,1-1S21,3.4,21,4z M5.5,20C4.1,20,3,18.9,3,17.5V3.5C3,2.1,4.1,1,5.5,1h10.1C16.9,1,18,2.1,18,3.5v14.1
|
14 |
+
c0,1.4-1.1,2.5-2.5,2.5H5.5z M9,11.4C9,11.7,9.3,12,9.6,12h1.8c0.3,0,0.6-0.3,0.6-0.6V4.6C12,4.3,11.7,4,11.4,4H9.6
|
15 |
+
C9.3,4,9,4.3,9,4.6V11.4z M9,16.4C9,16.7,9.3,17,9.6,17h1.8c0.3,0,0.6-0.3,0.6-0.6v-1.8c0-0.3-0.3-0.6-0.6-0.6H9.6
|
16 |
+
C9.3,14,9,14.3,9,14.6V16.4z"></path>
|
17 |
+
</svg>
|
18 |
+
</span>
|
19 |
+
<strong>Log</strong>
|
20 |
+
<?php if ($collector->countErrors() || $collector->countDeprecations()): ?>
|
21 |
+
<span class="count">
|
22 |
+
<span><?php echo $collector->countErrors() ? $collector->countErrors() : $collector->countDeprecations() ?></span>
|
23 |
+
</span>
|
24 |
+
<?php endif ?>
|
25 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/log/panel.phtml
ADDED
@@ -0,0 +1,118 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Log_Panel $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
?>
|
7 |
+
|
8 |
+
<h2>Log Messages</h2>
|
9 |
+
|
10 |
+
<?php if (Mage::getLogger() === false): ?>
|
11 |
+
<div class="empty status-error">
|
12 |
+
<p>No log messages available as the "monolog/monolog" is not installed please check the composer.json</p>
|
13 |
+
</div>
|
14 |
+
<?php elseif (!$collector->getLogs()): ?>
|
15 |
+
<div class="empty">
|
16 |
+
<p>No log messages available.</p>
|
17 |
+
</div>
|
18 |
+
<?php else: ?>
|
19 |
+
<div class="sf-tabs">
|
20 |
+
<?php $showLevel = true;?>
|
21 |
+
<?php $groups = $this->getLogGroups();?>
|
22 |
+
<div class="tab">
|
23 |
+
<h3 class="tab-title">Info. & Errors <span class="badge"><?php echo count($groups['info_and_error']); ?></span></h3>
|
24 |
+
|
25 |
+
<div class="tab-content">
|
26 |
+
<?php if (!$groups['info_and_error']): ?>
|
27 |
+
<div class="empty">
|
28 |
+
<p>There are no log messages of this level.</p>
|
29 |
+
</div>
|
30 |
+
<?php else: ?>
|
31 |
+
<?php echo $this->renderLogTable($groups['info_and_error'], 'info', true); ?>
|
32 |
+
<?php endif;?>
|
33 |
+
</div>
|
34 |
+
</div>
|
35 |
+
|
36 |
+
<div class="tab">
|
37 |
+
<h3 class="tab-title">Deprecations <span class="badge"><?php echo $collector->countDeprecations()?></span></h3>
|
38 |
+
|
39 |
+
<div class="tab-content">
|
40 |
+
<?php if (empty($groups['deprecation'])): ?>
|
41 |
+
<div class="empty">
|
42 |
+
<p>There are no log messages about deprecated features.</p>
|
43 |
+
</div>
|
44 |
+
<?php else: ?>
|
45 |
+
<?php echo $this->renderLogTable($groups['deprecation'], 'deprecation', false, true); ?>
|
46 |
+
<?php endif;?>
|
47 |
+
</div>
|
48 |
+
</div>
|
49 |
+
|
50 |
+
<div class="tab">
|
51 |
+
<h3 class="tab-title">Debug <span class="badge"><?php echo count($groups['debug'])?></span></h3>
|
52 |
+
|
53 |
+
<div class="tab-content">
|
54 |
+
<?php if (empty($groups['debug'])): ?>
|
55 |
+
<div class="empty">
|
56 |
+
<p><p>There are no log messages of this level.</p>
|
57 |
+
</div>
|
58 |
+
<?php else: ?>
|
59 |
+
<?php echo $this->renderLogTable($groups['debug'], 'debug'); ?>
|
60 |
+
<?php endif;?>
|
61 |
+
</div>
|
62 |
+
</div>
|
63 |
+
|
64 |
+
<div class="tab">
|
65 |
+
<h3 class="tab-title">Silenced Errors <span class="badge"><?php echo $collector->countScreams() ?></span></h3>
|
66 |
+
|
67 |
+
<div class="tab-content">
|
68 |
+
<?php if (empty($groups['silenced'])): ?>
|
69 |
+
<div class="empty">
|
70 |
+
<p><p>There are no log messages of this level.</p>
|
71 |
+
</div>
|
72 |
+
<?php else: ?>
|
73 |
+
<?php echo $this->renderLogTable($groups['silenced'], 'silenced'); ?>
|
74 |
+
<?php endif;?>
|
75 |
+
</div>
|
76 |
+
</div>
|
77 |
+
|
78 |
+
<?php /* foreach ($this->getLogGroups() as $groupName => $logs): ?>
|
79 |
+
<div class="tab">
|
80 |
+
<h3 class="tab-title">
|
81 |
+
<?php echo $groupData['name'] ?>
|
82 |
+
<span class="badge"><?php echo count($groupData['logs']); ?></span><br>
|
83 |
+
</h3>
|
84 |
+
|
85 |
+
<div class="tab-content">
|
86 |
+
<small><?php echo $groupData['file']; ?></small>
|
87 |
+
<table class="logs">
|
88 |
+
<thead>
|
89 |
+
<tr>
|
90 |
+
<th>Level</th>
|
91 |
+
<th>Message</th>
|
92 |
+
</tr>
|
93 |
+
</thead>
|
94 |
+
|
95 |
+
<tbody>
|
96 |
+
<?php foreach ($groupData['logs'] as $index => $entry): ?>
|
97 |
+
<?php
|
98 |
+
$level = $entry['level'];
|
99 |
+
$cssClass = $this->getEntryCssClass($entry['level']);
|
100 |
+
?>
|
101 |
+
|
102 |
+
<tr class="<?php echo $cssClass; ?>">
|
103 |
+
<td class="font-normal text-small">
|
104 |
+
<span
|
105 |
+
class="colored text-bold nowrap"><?php echo $this->getPriorityName($level) ?></span>
|
106 |
+
<!--<span class="text-muted nowrap newline">{{ log.timestamp|date('H:i:s') }}</span>-->
|
107 |
+
</td>
|
108 |
+
|
109 |
+
<td class="font-normal"><?php echo $entry['message'] ?></td>
|
110 |
+
</tr>
|
111 |
+
<?php endforeach; ?>
|
112 |
+
</tbody>
|
113 |
+
</table>
|
114 |
+
</div>
|
115 |
+
</div>
|
116 |
+
<?php endforeach; */?>
|
117 |
+
</div>
|
118 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/log/panel/log-table.phtml
ADDED
@@ -0,0 +1,130 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Renderer_Log_LogTable $this */
|
3 |
+
$channelIsDefined = $this->isChannelDefined();
|
4 |
+
$showLevel = $this->getShowLevel();
|
5 |
+
$isDeprecation = $this->isDeprecation();
|
6 |
+
|
7 |
+
/** @var Ecocode_Profiler_Helper_Code $codeHelper */
|
8 |
+
$codeHelper = Mage::helper('ecocode_profiler/code');
|
9 |
+
|
10 |
+
/** @var Ecocode_Profiler_Helper_ValueExporter $valueExporter */
|
11 |
+
$valueExporter = Mage::helper('ecocode_profiler/valueExporter');
|
12 |
+
?>
|
13 |
+
<table class="logs" xmlns="http://www.w3.org/1999/html">
|
14 |
+
<thead>
|
15 |
+
<tr>
|
16 |
+
<th><?php echo $showLevel ? 'Level' : 'Time' ?></th>
|
17 |
+
<?php echo $channelIsDefined ? '<th>Channel</th>' : '' ?>
|
18 |
+
<th style="width: 100%">Message</th>
|
19 |
+
</tr>
|
20 |
+
</thead>
|
21 |
+
|
22 |
+
<tbody>
|
23 |
+
<?php foreach ($this->getLogs() as $index => $log): ?>
|
24 |
+
<?php
|
25 |
+
$cssClass = '';
|
26 |
+
if (!$isDeprecation) {
|
27 |
+
switch ($log['priorityName']) {
|
28 |
+
case 'CRITICAL':
|
29 |
+
case 'ERROR':
|
30 |
+
case 'ALERT':
|
31 |
+
case 'EMERGENCY':
|
32 |
+
$cssClass = 'status-error';
|
33 |
+
break;
|
34 |
+
case 'WARNING':
|
35 |
+
case 'NOTICE':
|
36 |
+
$cssClass = 'status-warning';
|
37 |
+
|
38 |
+
}
|
39 |
+
}
|
40 |
+
?>
|
41 |
+
<tr class="<?php echo $cssClass ?>">
|
42 |
+
<td class="font-normal text-small">
|
43 |
+
<?php if ($showLevel): ?>
|
44 |
+
<span class="colored text-bold nowrap"><?php echo $log['priorityName'] ?></span>
|
45 |
+
<?php endif ?>
|
46 |
+
<span class="text-muted nowrap newline"><?php echo date('H:i:s', $log['timestamp']) ?></span>
|
47 |
+
</td>
|
48 |
+
|
49 |
+
<?php if ($channelIsDefined): ?>
|
50 |
+
<td class="font-normal text-small text-bold nowrap"><?php echo $log['channel'] ?></td>
|
51 |
+
<?php endif; ?>
|
52 |
+
|
53 |
+
<td class="font-normal">
|
54 |
+
<?php echo $log['message']; ?>
|
55 |
+
|
56 |
+
<?php if ($this->isDeprecation()): ?>
|
57 |
+
<?php $stack = isset($log['context']['stack']) ? $log['context']['stack'] : []; ?>
|
58 |
+
<?php array_shift($stack); //remove the error handler from stack ?>
|
59 |
+
<?php $stackId = 'sf-call-stack-' . $this->getCategory() . '-' . $index; ?>
|
60 |
+
|
61 |
+
<?php if (isset($log['context']['errorCount'])): ?>
|
62 |
+
<span class="text-small text-bold">(<?php echo $log['context']['errorCount'] ?> times)</span>
|
63 |
+
<?php endif; ?>
|
64 |
+
|
65 |
+
<?php if ($stack): ?>
|
66 |
+
<button class="btn-link text-small sf-toggle" data-toggle-selector="#<?php echo $stackId ?>"
|
67 |
+
data-toggle-alt-content="Hide stack trace">Show stack trace
|
68 |
+
</button>
|
69 |
+
<?php endif; ?>
|
70 |
+
|
71 |
+
<ul class="sf-call-stack hidden" id="<?php echo $stackId ?>">
|
72 |
+
<?php foreach ($stack as $index => $call): ?>
|
73 |
+
<?php
|
74 |
+
$from = '-';
|
75 |
+
if (isset($call['class'])) {
|
76 |
+
$from = $codeHelper->abbrClass($call['class']) . '::' . $codeHelper->abbrMethod($call['function']);
|
77 |
+
} elseif (isset($call['function'])) {
|
78 |
+
$from = $codeHelper->abbrMethod($call['function']);
|
79 |
+
} elseif (isset($call['file'])) {
|
80 |
+
$from = $call['file'];
|
81 |
+
}
|
82 |
+
|
83 |
+
$fileName = null;
|
84 |
+
if (isset($call['file'], $call['line'])) {
|
85 |
+
$fileName = str_replace('\\', '/', $call['file']);
|
86 |
+
$fileName = explode('/', $fileName);
|
87 |
+
$fileName = end($fileName);
|
88 |
+
}
|
89 |
+
?>
|
90 |
+
|
91 |
+
<li>
|
92 |
+
<?php echo $from; ?>
|
93 |
+
<?php if ($fileName): ?>
|
94 |
+
<span
|
95 |
+
class="text-small">(called from <?php echo $codeHelper->formatFile($call['file'], $call['line'], $fileName) ?>
|
96 |
+
)</span>
|
97 |
+
<?php endif; ?>
|
98 |
+
</li>
|
99 |
+
<?php endforeach; ?>
|
100 |
+
</ul>
|
101 |
+
<?php else: ?>
|
102 |
+
<?php if (!empty($log['context'])): ?>
|
103 |
+
<?php $contextId = 'context-' . $this->getCategory() . '-' . $index; ?>
|
104 |
+
<?php $contextDump = $valueExporter->exportValue($log['context']); ?>
|
105 |
+
|
106 |
+
<div class="metadata">
|
107 |
+
<strong>Context</strong>:
|
108 |
+
<?php if (strlen($contextDump) > 120): ?>
|
109 |
+
<?php substr($contextDump, 120); ?> ...
|
110 |
+
|
111 |
+
<a class="btn-link text-small sf-toggle"
|
112 |
+
data-toggle-selector="#<?php echo $contextId ?>"
|
113 |
+
data-toggle-alt-content="Hide full context">Show full context</a>
|
114 |
+
|
115 |
+
<div id="<?php echo $contextId ?>" class="context">
|
116 |
+
<pre><?php echo $contextDump ?></pre>
|
117 |
+
</div>
|
118 |
+
<?php else: ?>
|
119 |
+
<?php echo $contextDump ?>
|
120 |
+
<?php endif; ?>
|
121 |
+
</div>
|
122 |
+
<?php endif; ?>
|
123 |
+
<?php endif; ?>
|
124 |
+
|
125 |
+
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
+
<?php endforeach; ?>
|
129 |
+
</tbody>
|
130 |
+
</table>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/log/toolbar.phtml
ADDED
@@ -0,0 +1,52 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
$logCount = $collector->getLogCount();
|
6 |
+
$statusColor = $collector->countErrors() ? 'red' : ($collector->countDeprecations() ? 'yellow' : '');
|
7 |
+
?>
|
8 |
+
|
9 |
+
<?php if ($logCount): ?>
|
10 |
+
<div
|
11 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?> sf-toolbar-status-<?php echo $statusColor ?>">
|
12 |
+
<a target="_blank"
|
13 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
14 |
+
<div class="sf-toolbar-icon">
|
15 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24"
|
16 |
+
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
17 |
+
<path fill="#AAAAAA" d="M21,4v13.8c0,2.7-2.5,5.2-5.2,5.2H6c-0.6,0-1-0.4-1-1s0.4-1,1-1h9.8c1.6,0,3.2-1.7,3.2-3.2V4
|
18 |
+
c0-0.6,0.4-1,1-1S21,3.4,21,4z M5.5,20C4.1,20,3,18.9,3,17.5V3.5C3,2.1,4.1,1,5.5,1h10.1C16.9,1,18,2.1,18,3.5v14.1
|
19 |
+
c0,1.4-1.1,2.5-2.5,2.5H5.5z M9,11.4C9,11.7,9.3,12,9.6,12h1.8c0.3,0,0.6-0.3,0.6-0.6V4.6C12,4.3,11.7,4,11.4,4H9.6
|
20 |
+
C9.3,4,9,4.3,9,4.6V11.4z M9,16.4C9,16.7,9.3,17,9.6,17h1.8c0.3,0,0.6-0.3,0.6-0.6v-1.8c0-0.3-0.3-0.6-0.6-0.6H9.6
|
21 |
+
C9.3,14,9,14.3,9,14.6V16.4z"></path>
|
22 |
+
</svg>
|
23 |
+
<?php $errorCount = $collector->countErrors() + $collector->countScreams(); ?>
|
24 |
+
<span class="sf-toolbar-value"><?php echo $errorCount ? $errorCount : '' ?> </span>
|
25 |
+
</div>
|
26 |
+
</a>
|
27 |
+
|
28 |
+
<div class="sf-toolbar-info">
|
29 |
+
<div class="sf-toolbar-info-piece">
|
30 |
+
<b>All</b>
|
31 |
+
<span class="sf-toolbar-status"><?php echo $logCount ?></span>
|
32 |
+
</div>
|
33 |
+
<div class="sf-toolbar-info-piece">
|
34 |
+
<b>Errors</b>
|
35 |
+
<span
|
36 |
+
class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->countErrors() ? 'red' : '' ?>"><?php echo $collector->countErrors() ?></span>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<div class="sf-toolbar-info-piece">
|
40 |
+
<b>Deprecated Calls</b>
|
41 |
+
<span
|
42 |
+
class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->countDeprecations() ? 'yellow' : '' ?>"><?php echo $collector->countDeprecations() ?></span>
|
43 |
+
</div>
|
44 |
+
|
45 |
+
<div class="sf-toolbar-info-piece">
|
46 |
+
<b>Silenced Errors</b>
|
47 |
+
<span class="sf-toolbar-status"><?php echo $collector->countScreams() ?></span>
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
+
|
51 |
+
</div>
|
52 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/memory/toolbar.phtml
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_MemoryDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
|
8 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?> sf-toolbar-status-normal">
|
9 |
+
<div class="sf-toolbar-icon">
|
10 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24"
|
11 |
+
enable-background="new 0 0 24 24" xml:space="preserve">
|
12 |
+
<path fill="#AAAAAA" d="M6,18.9V15h12v3.9c0,0.7-0.2,1.1-1,1.1H7C6.2,20,6,19.6,6,18.9z M20,1C20,1,20,1,20,1c-0.6,0-1,0.5-1,1.1
|
13 |
+
l0,18c0,0.5-0.4,0.9-0.9,0.9H5.9C5.4,21,5,20.6,5,20.1l0-18C5,1.5,4.6,1,4,1c0,0,0,0,0,0C3.5,1,3,1.5,3,2.1l0,18
|
14 |
+
C3,21.7,4.3,23,5.9,23h12.2c1.6,0,2.9-1.3,2.9-2.9l0-18C21,1.5,20.6,1,20,1z M18,9H6v5h12V9z"/>
|
15 |
+
</svg>
|
16 |
+
<span class="sf-toolbar-value"><?php echo sprintf('%.1f', $collector->getMemory() / 1024 / 1024) ?></span>
|
17 |
+
<span class="sf-toolbar-label">MB</span>
|
18 |
+
|
19 |
+
</div>
|
20 |
+
<div class="sf-toolbar-info">
|
21 |
+
<div class="sf-toolbar-info-piece">
|
22 |
+
<b>Peak memory usage</b>
|
23 |
+
<span><?php echo sprintf('%.1f', $collector->getMemory() / 1024 / 1024) ?> MB</span>
|
24 |
+
</div>
|
25 |
+
|
26 |
+
<div class="sf-toolbar-info-piece">
|
27 |
+
<b>PHP memory limit</b>
|
28 |
+
<span><?php echo $collector->getMemoryLimit() == -1 ? 'Unlimited' : sprintf('%.0f MB', $collector->getMemoryLimit() / 1024 / 1024) ?></span>
|
29 |
+
</div>
|
30 |
+
</div>
|
31 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/model/menu.phtml
ADDED
@@ -0,0 +1,20 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_ModelDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
|
5 |
+
$statusColor = $collector->getMetric('loop_load') ? 'error' : ($collector->getMetric('load') > $collector->getLoadCallThreshold() ? 'warning' : 'normal');
|
6 |
+
?>
|
7 |
+
|
8 |
+
<span class="label label-status-<?php echo $statusColor ?>">
|
9 |
+
<span class="icon">
|
10 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="31" height="24" viewBox="0 0 576 448">
|
11 |
+
<path fill="#AAAAAA" d="M576 192h-32v160h32v96h-96v-32h-224v32h-96v-96h32v-32h-96v32h-96v-96h32v-160h-32v-96h96v32h224v-32h96v96h-32v32h96v-32h96v96zM512 128v32h32v-32h-32zM352 32v32h32v-32h-32zM32 32v32h32v-32h-32zM64 320v-32h-32v32h32zM384 288h-32v32h32v-32zM96 288h224v-32h32v-160h-32v-32h-224v32h-32v160h32v32zM224 416v-32h-32v32h32zM544 416v-32h-32v32h32zM512 352v-160h-32v-32h-96v96h32v96h-96v-32h-96v32h32v32h224v-32h32z"></path>
|
12 |
+
</svg>
|
13 |
+
</span>
|
14 |
+
<strong>Models</strong>
|
15 |
+
<?php if ($collector->getMetric('loop_load')): ?>
|
16 |
+
<span class="count">
|
17 |
+
<span><?php echo $collector->getMetric('loop_load')?></span>
|
18 |
+
</span>
|
19 |
+
<?php endif; ?>
|
20 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/model/panel.phtml
ADDED
@@ -0,0 +1,177 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_ModelDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$operations = ['save', 'delete', 'load'];
|
5 |
+
|
6 |
+
/** @var Ecocode_Profiler_Helper_Renderer $rendererHelper */
|
7 |
+
$rendererHelper = Mage::helper('ecocode_profiler/renderer');
|
8 |
+
?>
|
9 |
+
|
10 |
+
|
11 |
+
<h2>Model CRUD metrics</h2>
|
12 |
+
<p class="help">
|
13 |
+
All model <strong>->load</strong> calls. Collection loads are not included
|
14 |
+
</p>
|
15 |
+
<div class="metrics">
|
16 |
+
<?php foreach ($collector->getMetric() as $name => $value): ?>
|
17 |
+
<div class="metric">
|
18 |
+
<span class="value"><?php echo $value ?></span>
|
19 |
+
<span class="label"><?php echo ucfirst(str_replace('_', ' ', $name)) ?> count</span>
|
20 |
+
</div>
|
21 |
+
<?php endforeach; ?>
|
22 |
+
<div class="metric">
|
23 |
+
<span class="value"><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
24 |
+
<span class="label">Total time</span>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
|
28 |
+
<div class="sf-tabs">
|
29 |
+
<div class="tab">
|
30 |
+
<?php $callLog = $collector->getCallLog(); ?>
|
31 |
+
<h3 class="tab-title">
|
32 |
+
All
|
33 |
+
<span class="badge"><?php echo count($callLog) ?></span>
|
34 |
+
</h3>
|
35 |
+
<div id="all-crud-operations" class="tab-content">
|
36 |
+
<strong>Operation: </strong>
|
37 |
+
<?php foreach ($operations as $operation): ?>
|
38 |
+
<span data-toggle="crud-operation" data-operation="<?php echo $operation ?>" class="label">
|
39 |
+
<strong><?php echo strtoupper($operation) ?></strong>
|
40 |
+
<span class="count">
|
41 |
+
(<span><?php echo $collector->getMetric($operation) ?></span>)
|
42 |
+
</span>
|
43 |
+
</span>
|
44 |
+
<?php endforeach; ?>
|
45 |
+
<table>
|
46 |
+
<thead>
|
47 |
+
<tr>
|
48 |
+
<th>#</th>
|
49 |
+
<th>Action</th>
|
50 |
+
<th>Time</th>
|
51 |
+
<th style="width:100%;">Class</th>
|
52 |
+
</tr>
|
53 |
+
</thead>
|
54 |
+
<tbody>
|
55 |
+
<?php $prefix = 'all-'; ?>
|
56 |
+
|
57 |
+
<?php foreach ($callLog as $index => $log): ?>
|
58 |
+
|
59 |
+
<tr data-operation="<?php echo $log['action'] ?>">
|
60 |
+
<td class="nowrap"><?php echo $index + 1 ?></td>
|
61 |
+
<td><?php echo $log['action'] ?></td>
|
62 |
+
<td class="nowrap"><?php echo sprintf('%0.2f', $log['time'] * 1000) ?> ms</td>
|
63 |
+
<td>
|
64 |
+
<?php echo $log['class'] ?><br>
|
65 |
+
<div class="text-small font-normal">
|
66 |
+
<strong><?php echo $log['class_group'] ?></strong>
|
67 |
+
<?php if (isset($log['trace'])): ?>
|
68 |
+
<a href="#" class="sf-toggle link-inverse"
|
69 |
+
data-toggle-selector="#stack-<?php echo $prefix . $index ?>"
|
70 |
+
data-toggle-alt-content="Hide stack trace">Show trace</a>
|
71 |
+
<?php endif; ?>
|
72 |
+
</div>
|
73 |
+
<?php if (isset($log['trace'])): ?>
|
74 |
+
<?php echo $rendererHelper->renderBackTrace($prefix . $index, $log['trace']) ?>
|
75 |
+
<?php endif; ?>
|
76 |
+
</td>
|
77 |
+
</tr>
|
78 |
+
|
79 |
+
<?php endforeach; ?>
|
80 |
+
</tbody>
|
81 |
+
</table>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
<div class="tab">
|
85 |
+
<?php $loadLoopCalls = $collector->getLoadLoopCalls(); ?>
|
86 |
+
<h3 class="tab-title">
|
87 |
+
Load calls in loops
|
88 |
+
<span class="badge"><?php echo count($loadLoopCalls) ?></span>
|
89 |
+
</h3>
|
90 |
+
<div class="tab-content">
|
91 |
+
<p class="help">
|
92 |
+
Calling <strong>->load</strong> within a "loop" is a sign of bad coding style and should be fixed!
|
93 |
+
</p>
|
94 |
+
<?php if (!$loadLoopCalls): ?>
|
95 |
+
<div class="empty">
|
96 |
+
<p>No load calls in loops detected</p>
|
97 |
+
</div>
|
98 |
+
<?php else: ?>
|
99 |
+
<table>
|
100 |
+
<thead>
|
101 |
+
<tr>
|
102 |
+
<th>#</th>
|
103 |
+
<th>Count</th>
|
104 |
+
<th>Total time</th>
|
105 |
+
<th style="width:100%;">Class</th>
|
106 |
+
</tr>
|
107 |
+
</thead>
|
108 |
+
<tbody>
|
109 |
+
<?php $prefix = 'loop-'; ?>
|
110 |
+
|
111 |
+
<?php foreach ($loadLoopCalls as $index => $log): ?>
|
112 |
+
|
113 |
+
<tr>
|
114 |
+
<td class="nowrap"><?php echo $index + 1 ?></td>
|
115 |
+
<td class="nowrap"><?php echo $log['count'] ?></td>
|
116 |
+
<td class="nowrap"><?php echo sprintf('%0.2f', $log['total_time'] * 1000) ?> ms</td>
|
117 |
+
<td>
|
118 |
+
<?php echo $log['class'] ?><br>
|
119 |
+
<div class="text-small font-normal">
|
120 |
+
<strong><?php echo $log['class_group'] ?></strong>
|
121 |
+
<?php if (isset($log['trace'])): ?>
|
122 |
+
<a href="#" class="sf-toggle link-inverse"
|
123 |
+
data-toggle-selector="#stack-<?php echo $prefix . $index ?>"
|
124 |
+
data-toggle-alt-content="Hide stack trace">Show trace</a>
|
125 |
+
<?php endif; ?>
|
126 |
+
</div>
|
127 |
+
<?php if (isset($log['trace'])): ?>
|
128 |
+
<?php echo $rendererHelper->renderBackTrace($prefix . $index, $log['trace']) ?>
|
129 |
+
<?php endif; ?>
|
130 |
+
</td>
|
131 |
+
</tr>
|
132 |
+
|
133 |
+
<?php endforeach; ?>
|
134 |
+
</tbody>
|
135 |
+
</table>
|
136 |
+
<?php endif; ?>
|
137 |
+
|
138 |
+
</div>
|
139 |
+
</div>
|
140 |
+
</div>
|
141 |
+
<script>
|
142 |
+
$(function () {
|
143 |
+
var allOperations = $('#all-crud-operations'),
|
144 |
+
crudOperations = allOperations.find('span[data-toggle="crud-operation"]');
|
145 |
+
|
146 |
+
|
147 |
+
crudOperations.click(function () {
|
148 |
+
var $this = $(this),
|
149 |
+
operation = $this.data('operation'),
|
150 |
+
makeActive = !$this.hasClass('status-success');
|
151 |
+
|
152 |
+
crudOperations.removeClass('status-success');
|
153 |
+
allOperations.removeAttr('data-operation');
|
154 |
+
|
155 |
+
if (makeActive) {
|
156 |
+
$this.addClass('status-success');
|
157 |
+
allOperations.attr('data-operation', operation);
|
158 |
+
}
|
159 |
+
});
|
160 |
+
});
|
161 |
+
</script>
|
162 |
+
<style>
|
163 |
+
#all-crud-operations span[data-toggle="crud-operation"] {
|
164 |
+
cursor: pointer;
|
165 |
+
}
|
166 |
+
|
167 |
+
<?php foreach ($operations as $name): ?>
|
168 |
+
#all-crud-operations[data-operation="<?php echo $name ?>"] tbody > tr:not([data-operation="<?php echo $name ?>"]) {
|
169 |
+
display: none;
|
170 |
+
}
|
171 |
+
|
172 |
+
<?php endforeach;?>
|
173 |
+
</style>
|
174 |
+
|
175 |
+
|
176 |
+
|
177 |
+
|
app/design/frontend/base/default/template/ecocode_profiler/collector/model/toolbar.phtml
ADDED
@@ -0,0 +1,48 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_ModelDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
|
6 |
+
?>
|
7 |
+
<?php $statusColor = $collector->getMetric('loop_load') ? 'red' : ($collector->getMetric('load') > $collector->getLoadCallThreshold() ? 'yellow' : 'normal') ?>
|
8 |
+
|
9 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-<?php echo $statusColor ?>">
|
10 |
+
<a target="_blank"
|
11 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
12 |
+
<div class="sf-toolbar-icon">
|
13 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 576 448">
|
14 |
+
<path fill="#AAAAAA" d="M576 192h-32v160h32v96h-96v-32h-224v32h-96v-96h32v-32h-96v32h-96v-96h32v-160h-32v-96h96v32h224v-32h96v96h-32v32h96v-32h96v96zM512 128v32h32v-32h-32zM352 32v32h32v-32h-32zM32 32v32h32v-32h-32zM64 320v-32h-32v32h32zM384 288h-32v32h32v-32zM96 288h224v-32h32v-160h-32v-32h-224v32h-32v160h32v32zM224 416v-32h-32v32h32zM544 416v-32h-32v32h32zM512 352v-160h-32v-32h-96v96h32v96h-96v-32h-96v32h32v32h224v-32h32z"></path>
|
15 |
+
</svg>
|
16 |
+
<span class="sf-toolbar-value"><?php echo array_sum($collector->getMetric()) - $collector->getMetric('loop_load') ?></span>
|
17 |
+
</div>
|
18 |
+
</a>
|
19 |
+
<div class="sf-toolbar-info">
|
20 |
+
<div class="sf-toolbar-info-piece">
|
21 |
+
<b>Model loads</b>
|
22 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->getMetric('load') > $collector->getLoadCallThreshold() ? 'yellow' : '' ?>">
|
23 |
+
<?php echo $collector->getMetric('load') ?>
|
24 |
+
</span>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<div class="sf-toolbar-info-piece">
|
28 |
+
<b>Loads in loops</b>
|
29 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->getMetric('loop_load') ? 'red' : '' ?>">
|
30 |
+
<?php echo $collector->getMetric('loop_load') ?>
|
31 |
+
</span>
|
32 |
+
</div>
|
33 |
+
|
34 |
+
<div class="sf-toolbar-info-piece">
|
35 |
+
<b>Model save</b>
|
36 |
+
<span class="sf-toolbar-status">
|
37 |
+
<?php echo $collector->getMetric('save') ?>
|
38 |
+
</span>
|
39 |
+
</div>
|
40 |
+
|
41 |
+
<div class="sf-toolbar-info-piece">
|
42 |
+
<b>Model delete</b>
|
43 |
+
<span class="sf-toolbar-status">
|
44 |
+
<?php echo $collector->getMetric('delete') ?>
|
45 |
+
</span>
|
46 |
+
</div>
|
47 |
+
</div>
|
48 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/menu.phtml
ADDED
@@ -0,0 +1,19 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_MysqlDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
?>
|
5 |
+
|
6 |
+
<span class="label <?php echo $collector->getQueryCount() == 0 ? 'disabled' : '' ?>">
|
7 |
+
<span class="icon">
|
8 |
+
<svg version="1.1"xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
9 |
+
<path fill="#AAAAAA" d="M5,8h14c1.7,0,3-1.3,3-3s-1.3-3-3-3H5C3.3,2,2,3.3,2,5S3.3,8,5,8z M18,3.6c0.8,0,1.5,0.7,1.5,1.5S18.8,6.6,18,6.6s-1.5-0.7-1.5-1.5S17.2,3.6,18,3.6z M19,9H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,9,19,9z M18,13.6
|
10 |
+
c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,13.6,18,13.6z M19,16H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,16,19,16z M18,20.6c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,20.6,18,20.6z"/>
|
11 |
+
</svg>
|
12 |
+
</span>
|
13 |
+
<strong>Mysql</strong>
|
14 |
+
<!-- {% if collector.invalidEntityCount %}
|
15 |
+
<span class="count">
|
16 |
+
<span>{{ collector.invalidEntityCount }}</span>
|
17 |
+
</span>
|
18 |
+
{% endif %}-->
|
19 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/panel.phtml
ADDED
@@ -0,0 +1,343 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Mysql_Panel $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_MysqlDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
$identicalQueries = $this->getIdenticalQueries();
|
7 |
+
$identicalQueriesCount = count($identicalQueries);
|
8 |
+
|
9 |
+
$queriesByContext = $this->getByContext();
|
10 |
+
$contextHelper = Mage::helper('ecocode_profiler/context');
|
11 |
+
$queryTableRenderer = $this->getQueryTableRenderer();
|
12 |
+
?>
|
13 |
+
|
14 |
+
|
15 |
+
<div style="float:left; width: 50%">
|
16 |
+
<h2>Query metrics</h2>
|
17 |
+
<div class="metrics">
|
18 |
+
<div class="metric">
|
19 |
+
<span class="value"><?php echo $collector->getQueryCount() ?></span>
|
20 |
+
<span class="label">Database queries</span>
|
21 |
+
</div>
|
22 |
+
|
23 |
+
<div class="metric">
|
24 |
+
<span class="value"><?php echo $identicalQueriesCount ?></span>
|
25 |
+
<span class="label">Identical queries</span>
|
26 |
+
</div>
|
27 |
+
|
28 |
+
<div class="metric">
|
29 |
+
<span class="value"><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
30 |
+
<span class="label">Query time</span>
|
31 |
+
</div>
|
32 |
+
</div>
|
33 |
+
</div>
|
34 |
+
<?php $connections = $collector->getConnectionData(); ?>
|
35 |
+
<?php if (count($connections) > 1): ?>
|
36 |
+
<div style="float:left; width: 50%">
|
37 |
+
<h2>Queries by connection</h2>
|
38 |
+
|
39 |
+
<div class="metrics">
|
40 |
+
<?php foreach ($connections as $name => $queryCount): ?>
|
41 |
+
<div class="metric">
|
42 |
+
<span class="value"><?php echo $queryCount ?></span>
|
43 |
+
<span class="label"><?php echo $name ?></span>
|
44 |
+
</div>
|
45 |
+
<?php endforeach; ?>
|
46 |
+
</div>
|
47 |
+
</div>
|
48 |
+
<?php endif; ?>
|
49 |
+
<div style="clear: both;"></div>
|
50 |
+
|
51 |
+
<div class="sf-tabs">
|
52 |
+
<div class="tab">
|
53 |
+
<h3 class="tab-title">
|
54 |
+
Queries
|
55 |
+
<span class="badge"><?php echo $collector->getQueryCount() ?></span>
|
56 |
+
</h3>
|
57 |
+
<div id="all-queries" class="tab-content">
|
58 |
+
<?php if ($this->getQueryCountByType()): ?>
|
59 |
+
<div style="float:left; width: 50%">
|
60 |
+
<strong>Type: </strong>
|
61 |
+
<?php foreach ($this->getQueryCountByType() as $type => $count): ?>
|
62 |
+
<span data-toggle="query-type" data-type="<?php echo $type ?>" class="label">
|
63 |
+
<strong><?php echo strtoupper($type) ?></strong>
|
64 |
+
<span class="count">
|
65 |
+
(<span><?php echo $count ?></span>)
|
66 |
+
</span>
|
67 |
+
</span>
|
68 |
+
<?php endforeach; ?>
|
69 |
+
</div>
|
70 |
+
<?php endif; ?>
|
71 |
+
<?php if (count($connections) > 1): ?>
|
72 |
+
<div style="float:left; width: 50%">
|
73 |
+
<strong>Connection: </strong>
|
74 |
+
<?php foreach ($connections as $connection => $count): ?>
|
75 |
+
<span data-toggle="query-connection" data-connection="<?php echo $connection ?>" class="label">
|
76 |
+
<strong><?php echo $connection ?></strong>
|
77 |
+
<span class="count">
|
78 |
+
(<span><?php echo $count ?></span>)
|
79 |
+
</span>
|
80 |
+
</span>
|
81 |
+
<?php endforeach; ?>
|
82 |
+
</div>
|
83 |
+
<?php endif; ?>
|
84 |
+
<div style="clear: both;"></div>
|
85 |
+
<?php echo $this->renderQueryTable('all', $this->getQueries()); ?>
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
<div class="tab">
|
89 |
+
<h3 class="tab-title">
|
90 |
+
Queries by context
|
91 |
+
<span class="badge"><?php echo count($queriesByContext) ?></span>
|
92 |
+
</h3>
|
93 |
+
|
94 |
+
<div class="tab-content">
|
95 |
+
<table>
|
96 |
+
<thead>
|
97 |
+
<tr>
|
98 |
+
<th>#</th>
|
99 |
+
<th>Context</th>
|
100 |
+
<th>Queries</th>
|
101 |
+
<th>Total Time</th>
|
102 |
+
<th></th>
|
103 |
+
</tr>
|
104 |
+
</thead>
|
105 |
+
<tbody>
|
106 |
+
|
107 |
+
<?php foreach ($queriesByContext as $index => $contextData): ?>
|
108 |
+
<tr>
|
109 |
+
<td><?php echo $index + 1 ?> </td>
|
110 |
+
<td>
|
111 |
+
<?php echo $contextHelper->render('context', $contextData['name']); ?>
|
112 |
+
</td>
|
113 |
+
<td><?php echo $contextData['count'] ?></td>
|
114 |
+
<td><?php echo sprintf('%0.2f', $contextData['total_time'] * 1000) ?> ms</td>
|
115 |
+
<td class="text-right">
|
116 |
+
<a href="#" class="sf-toggle link-inverse"
|
117 |
+
data-toggle-selector="#context-queries-<?php echo $index ?>"
|
118 |
+
data-toggle-alt-content="Hide queries">View queries</a>
|
119 |
+
</td>
|
120 |
+
</tr>
|
121 |
+
<tr class="hidden" id="context-queries-<?php echo $index ?>">
|
122 |
+
<td colspan="5">
|
123 |
+
Queries:<br>
|
124 |
+
<?php echo $this->renderQueryTable('context-' . $index, $contextData['queries']); ?>
|
125 |
+
</td>
|
126 |
+
</tr>
|
127 |
+
<?php endforeach; ?>
|
128 |
+
</tbody>
|
129 |
+
|
130 |
+
</table>
|
131 |
+
</div>
|
132 |
+
</div>
|
133 |
+
<div class="tab">
|
134 |
+
<h3 class="tab-title">
|
135 |
+
Identical queries
|
136 |
+
<span class="badge"><?php echo $identicalQueriesCount ?></span>
|
137 |
+
</h3>
|
138 |
+
|
139 |
+
|
140 |
+
<div class="tab-content">
|
141 |
+
<?php $prefix = 'identical-'; ?>
|
142 |
+
<table class="alt queries-table">
|
143 |
+
<thead>
|
144 |
+
<tr>
|
145 |
+
<th class="nowrap">#</th>
|
146 |
+
<th class="nowrap">Count</th>
|
147 |
+
<th class="nowrap">Total time<span></span></th>
|
148 |
+
<th style="width: 100%;">Info</th>
|
149 |
+
</tr>
|
150 |
+
</thead>
|
151 |
+
<tbody>
|
152 |
+
<?php foreach ($identicalQueries as $index => $query): ?>
|
153 |
+
<?php $queryData = $query['query']; ?>
|
154 |
+
<tr>
|
155 |
+
<td class="nowrap"><?php echo $index + 1 ?> </td>
|
156 |
+
<td class="nowrap"><?php echo $query['count'] ?> </td>
|
157 |
+
<td class="nowrap"><?php echo sprintf('%0.2f', $query['total_time'] * 1000) ?> ms</td>
|
158 |
+
<td>
|
159 |
+
<?php echo $queryData['sql_highlighted'] ?>
|
160 |
+
<div>
|
161 |
+
<strong class="font-normal text-small">Parameters</strong>:
|
162 |
+
<?php echo $queryTableRenderer->dumpParameters($queryData['params']) ?>
|
163 |
+
|
164 |
+
</div>
|
165 |
+
<div>
|
166 |
+
<?php echo $contextHelper->render('identical', $queryData['context']); ?>
|
167 |
+
</div>
|
168 |
+
|
169 |
+
<div class="text-small font-normal">
|
170 |
+
<?php if (isset($query['traces'])): ?>
|
171 |
+
<a href="#" class="sf-toggle link-inverse"
|
172 |
+
data-toggle-selector="#stack-<?php echo $prefix . $index ?>"
|
173 |
+
data-toggle-alt-content="Hide stack trace">Show trace</a>
|
174 |
+
<?php endif; ?>
|
175 |
+
<a href="#" class="sf-toggle link-inverse"
|
176 |
+
data-toggle-selector="#formatted-query-<?php echo $prefix . $index ?>"
|
177 |
+
data-toggle-alt-content="Hide formatted query">View formatted query</a>
|
178 |
+
<a href="#" class="sf-toggle link-inverse"
|
179 |
+
data-toggle-selector="#original-query-<?php echo $prefix . $index ?>"
|
180 |
+
data-toggle-alt-content="Hide runnable query">View runnable query</a>
|
181 |
+
</div>
|
182 |
+
|
183 |
+
<div id="formatted-query-<?php echo $prefix . $index ?>" class="sql-runnable hidden">
|
184 |
+
<?php echo $queryData['sql_formatted']; ?>
|
185 |
+
</div>
|
186 |
+
|
187 |
+
<div id="original-query-<?php echo $prefix . $index ?>" class="sql-runnable hidden">
|
188 |
+
<?php echo $queryData['sql_runnable']; ?>
|
189 |
+
</div>
|
190 |
+
|
191 |
+
<?php if (isset($query['traces'])): ?>
|
192 |
+
<div id="stack-<?php echo $prefix . $index ?>" class="hidden">
|
193 |
+
<strong class="font-normal text-small">Traces</strong>:
|
194 |
+
<table class="">
|
195 |
+
<tbody>
|
196 |
+
<?php foreach ($query['traces'] as $j => $trace): ?>
|
197 |
+
<tr>
|
198 |
+
<td class="nowrap">#<?php echo $j + 1 ?></td>
|
199 |
+
<td>
|
200 |
+
<ul class="sf-call-stack ">
|
201 |
+
<?php foreach ($trace as $item): ?>
|
202 |
+
<li>
|
203 |
+
<?php echo isset($item['class']) ? $item['class'] : '' ?>
|
204 |
+
::<?php echo $item['function'] ?><br>
|
205 |
+
<?php if (isset($item['file'])): ?>
|
206 |
+
<small><?php echo $item['file'] ?>
|
207 |
+
::<?php echo $item['line'] ?></small>
|
208 |
+
<?php endif; ?>
|
209 |
+
</li>
|
210 |
+
<?php endforeach; ?>
|
211 |
+
</ul>
|
212 |
+
</td>
|
213 |
+
</tr>
|
214 |
+
<?php endforeach; ?>
|
215 |
+
</tbody>
|
216 |
+
</table>
|
217 |
+
</div>
|
218 |
+
<?php endif; ?>
|
219 |
+
</td>
|
220 |
+
</tr>
|
221 |
+
<?php endforeach; ?>
|
222 |
+
</tbody>
|
223 |
+
</table>
|
224 |
+
</div>
|
225 |
+
</div>
|
226 |
+
</div>
|
227 |
+
<script>
|
228 |
+
$(function () {
|
229 |
+
var allQueries = $('#all-queries'),
|
230 |
+
queryTypes = allQueries.find('span[data-toggle="query-type"]'),
|
231 |
+
connections = allQueries.find('span[data-toggle="query-connection"]');
|
232 |
+
|
233 |
+
|
234 |
+
queryTypes.click(function () {
|
235 |
+
var $this = $(this),
|
236 |
+
type = $this.data('type'),
|
237 |
+
makeActive = !$this.hasClass('status-success');
|
238 |
+
|
239 |
+
queryTypes.removeClass('status-success');
|
240 |
+
allQueries.removeAttr('data-type');
|
241 |
+
|
242 |
+
if (makeActive) {
|
243 |
+
$this.addClass('status-success');
|
244 |
+
allQueries.attr('data-type', type);
|
245 |
+
}
|
246 |
+
});
|
247 |
+
|
248 |
+
connections.click(function () {
|
249 |
+
var $this = $(this),
|
250 |
+
connection = $this.data('connection'),
|
251 |
+
makeActive = !$this.hasClass('status-success');
|
252 |
+
|
253 |
+
connections.removeClass('status-success');
|
254 |
+
allQueries.removeAttr('data-connection');
|
255 |
+
|
256 |
+
if (makeActive) {
|
257 |
+
$this.addClass('status-success');
|
258 |
+
allQueries.attr('data-connection', connection);
|
259 |
+
}
|
260 |
+
});
|
261 |
+
});
|
262 |
+
</script>
|
263 |
+
<style>
|
264 |
+
<?php foreach ($connections as $name => $queryCount): ?>
|
265 |
+
#all-queries[data-connection="<?php echo $name ?>"] tbody > tr:not([data-connection="<?php echo $name ?>"]) {
|
266 |
+
display: none;
|
267 |
+
}
|
268 |
+
<?php endforeach; ?>
|
269 |
+
|
270 |
+
<?php foreach ($this->getQueryCountByType() as $name => $queryCount): ?>
|
271 |
+
#all-queries[data-type="<?php echo $name ?>"] tbody > tr:not([data-type="<?php echo $name ?>"]) {
|
272 |
+
display: none;
|
273 |
+
}
|
274 |
+
<?php endforeach; ?>
|
275 |
+
|
276 |
+
#all-queries span[data-toggle="query-type"],
|
277 |
+
#all-queries span[data-toggle="query-connection"] {
|
278 |
+
cursor: pointer;
|
279 |
+
}
|
280 |
+
|
281 |
+
tr.sf-toggle-content.sf-toggle-visible {
|
282 |
+
display: table-row !important;
|
283 |
+
}
|
284 |
+
|
285 |
+
td > .context > strong {
|
286 |
+
display: none;
|
287 |
+
}
|
288 |
+
|
289 |
+
.hidden {
|
290 |
+
display: none;
|
291 |
+
}
|
292 |
+
|
293 |
+
.queries-table td, .queries-table th {
|
294 |
+
vertical-align: top;
|
295 |
+
}
|
296 |
+
|
297 |
+
.queries-table td > div {
|
298 |
+
margin-bottom: 6px;
|
299 |
+
}
|
300 |
+
|
301 |
+
.highlight pre {
|
302 |
+
margin: 0;
|
303 |
+
white-space: pre-wrap;
|
304 |
+
}
|
305 |
+
|
306 |
+
.highlight .keyword {
|
307 |
+
color: #8959A8;
|
308 |
+
font-weight: bold;
|
309 |
+
}
|
310 |
+
|
311 |
+
.highlight .word {
|
312 |
+
color: #222222;
|
313 |
+
}
|
314 |
+
|
315 |
+
.highlight .variable {
|
316 |
+
color: #916319;
|
317 |
+
}
|
318 |
+
|
319 |
+
.highlight .symbol {
|
320 |
+
color: #222222;
|
321 |
+
}
|
322 |
+
|
323 |
+
.highlight .comment {
|
324 |
+
color: #999999;
|
325 |
+
}
|
326 |
+
|
327 |
+
.highlight .backtick {
|
328 |
+
color: #718C00;
|
329 |
+
}
|
330 |
+
|
331 |
+
.highlight .string {
|
332 |
+
color: #718C00;
|
333 |
+
}
|
334 |
+
|
335 |
+
.highlight .number {
|
336 |
+
color: #F5871F;
|
337 |
+
font-weight: bold;
|
338 |
+
}
|
339 |
+
|
340 |
+
.highlight .error {
|
341 |
+
color: #C82829;
|
342 |
+
}
|
343 |
+
</style>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/panel/query-table.phtml
ADDED
@@ -0,0 +1,63 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
$prefix = $this->getData('prefix');
|
3 |
+
$contextHelper = Mage::helper('ecocode_profiler/context');
|
4 |
+
|
5 |
+
/** @var Ecocode_Profiler_Helper_Renderer $rendererHelper */
|
6 |
+
$rendererHelper = Mage::helper('ecocode_profiler/renderer');
|
7 |
+
?>
|
8 |
+
<table class="alt queries-table">
|
9 |
+
<thead>
|
10 |
+
<tr>
|
11 |
+
<th class="nowrap">#</th>
|
12 |
+
<th class="nowrap">Connection</th>
|
13 |
+
<th class="nowrap">Time<span></span></th>
|
14 |
+
<th style="width: 100%;">Info</th>
|
15 |
+
</tr>
|
16 |
+
</thead>
|
17 |
+
<tbody>
|
18 |
+
<?php foreach ($this->getData('queries') as $index => $queryData): ?>
|
19 |
+
<tr data-type="<?php echo $queryData['type']?>" data-connection="<?php echo $queryData['connection'] ?>">
|
20 |
+
<td class="nowrap"><?php echo $index + 1 ?> </td>
|
21 |
+
<td class="nowrap"><?php echo $queryData['connection'] ?> </td>
|
22 |
+
<td class="nowrap"><?php echo sprintf('%0.2f', $queryData['time'] * 1000) ?> ms</td>
|
23 |
+
<td>
|
24 |
+
<?php echo $queryData['sql_highlighted']; ?>
|
25 |
+
<div>
|
26 |
+
<strong class="font-normal text-small">Parameters</strong>:
|
27 |
+
<?php echo $this->dumpParameters($queryData['params']) ?>
|
28 |
+
|
29 |
+
</div>
|
30 |
+
<div>
|
31 |
+
<?php echo $contextHelper->render($prefix, $queryData['context']); ?>
|
32 |
+
</div>
|
33 |
+
|
34 |
+
<div class="text-small font-normal">
|
35 |
+
<?php if (isset($queryData['trace'])): ?>
|
36 |
+
<a href="#" class="sf-toggle link-inverse"
|
37 |
+
data-toggle-selector="#stack-<?php echo $prefix . $index ?>"
|
38 |
+
data-toggle-alt-content="Hide stack trace">Show trace</a>
|
39 |
+
<?php endif; ?>
|
40 |
+
<a href="#" class="sf-toggle link-inverse"
|
41 |
+
data-toggle-selector="#formatted-query-<?php echo $prefix . $index ?>"
|
42 |
+
data-toggle-alt-content="Hide formatted query">View formatted query</a>
|
43 |
+
<a href="#" class="sf-toggle link-inverse"
|
44 |
+
data-toggle-selector="#original-query-<?php echo $prefix . $index ?>"
|
45 |
+
data-toggle-alt-content="Hide runnable query">View runnable query</a>
|
46 |
+
</div>
|
47 |
+
|
48 |
+
<div id="formatted-query-<?php echo $prefix . $index ?>" class="sql-runnable hidden">
|
49 |
+
<?php echo $queryData['sql_formatted']; ?>
|
50 |
+
</div>
|
51 |
+
|
52 |
+
<div id="original-query-<?php echo $prefix . $index ?>" class="sql-runnable hidden">
|
53 |
+
<?php echo $queryData['sql_runnable']; ?>
|
54 |
+
</div>
|
55 |
+
|
56 |
+
<?php if (isset($queryData['trace'])): ?>
|
57 |
+
<?php echo $rendererHelper->renderBackTrace($prefix . $index, $queryData['trace']) ?>
|
58 |
+
<?php endif; ?>
|
59 |
+
</td>
|
60 |
+
</tr>
|
61 |
+
<?php endforeach; ?>
|
62 |
+
</tbody>
|
63 |
+
</table>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/toolbar.phtml
ADDED
@@ -0,0 +1,36 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_MysqlDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-normal">
|
8 |
+
<a target="_blank"
|
9 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
10 |
+
<div class="sf-toolbar-icon">
|
11 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" height="24"
|
12 |
+
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
13 |
+
<path fill="#AAAAAA" d="M5,8h14c1.7,0,3-1.3,3-3s-1.3-3-3-3H5C3.3,2,2,3.3,2,5S3.3,8,5,8z M18,3.6c0.8,0,1.5,0.7,1.5,1.5S18.8,6.6,18,6.6s-1.5-0.7-1.5-1.5S17.2,3.6,18,3.6z M19,9H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,9,19,9z M18,13.6
|
14 |
+
c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,13.6,18,13.6z M19,16H5c-1.7,0-3,1.3-3,3s1.3,3,3,3h14c1.7,0,3-1.3,3-3S20.7,16,19,16z M18,20.6c-0.8,0-1.5-0.7-1.5-1.5s0.7-1.5,1.5-1.5s1.5,0.7,1.5,1.5S18.8,20.6,18,20.6z"></path>
|
15 |
+
</svg>
|
16 |
+
|
17 |
+
<span class="sf-toolbar-value"><?php echo $collector->getQueryCount() ?></span>
|
18 |
+
<span class="sf-toolbar-info-piece-additional-detail">
|
19 |
+
<span class="sf-toolbar-label">in</span>
|
20 |
+
<span class="sf-toolbar-value"><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?></span>
|
21 |
+
<span class="sf-toolbar-label">ms</span>
|
22 |
+
</span>
|
23 |
+
|
24 |
+
</div>
|
25 |
+
</a>
|
26 |
+
<div class="sf-toolbar-info">
|
27 |
+
<div class="sf-toolbar-info-piece">
|
28 |
+
<b>Database Queries</b>
|
29 |
+
<span class="sf-toolbar-status "><?php echo $collector->getQueryCount() ?></span>
|
30 |
+
</div>
|
31 |
+
<div class="sf-toolbar-info-piece">
|
32 |
+
<b>Query time</b>
|
33 |
+
<span><?php echo sprintf('%0.2f', $collector->getTotalTime() * 1000) ?> ms</span>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/request/menu.phtml
ADDED
@@ -0,0 +1,22 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<span class="label">
|
2 |
+
<span class="icon">
|
3 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
4 |
+
<path fill="#AAAAAA" d="M15.8,6.4h-1.1c0,0-0.1,0.1-0.1,0l0.8-0.7c0.5-0.5,0.5-1.3,0-1.9l-1.4-1.4c-0.5-0.5-1.4-0.5-1.9,0l-0.6,0.8
|
5 |
+
c-0.1,0,0,0,0-0.1V2.1c0-0.8-1-1.4-1.8-1.4h-2c-0.8,0-1.9,0.6-1.9,1.4v1.1c0,0,0.1,0.1,0.1,0.1L5.1,2.5c-0.5-0.5-1.3-0.5-1.9,0
|
6 |
+
L1.8,3.9c-0.5,0.5-0.5,1.4,0,1.9l0.8,0.6c0,0.1,0,0-0.1,0H1.4C0.7,6.4,0,7.5,0,8.2v2c0,0.8,0.7,1.8,1.4,1.8h1.2c0,0,0.1-0.1,0.1-0.1
|
7 |
+
l-0.8,0.7c-0.5,0.5-0.5,1.3,0,1.9L3.3,16c0.5,0.5,1.4,0.5,1.9,0l0.6-0.8c0.1,0-0.1,0-0.1,0.1v1.2c0,0.8,1.1,1.4,1.9,1.4h2
|
8 |
+
c0.8,0,1.8-0.6,1.8-1.4v-1.2c0,0-0.1-0.1,0-0.1l0.7,0.8c0.5,0.5,1.3,0.5,1.9,0l1.4-1.4c0.5-0.5,0.5-1.4,0-1.9L14.6,12
|
9 |
+
c0-0.1,0,0.1,0.1,0.1h1.1c0.8,0,1.3-1.1,1.3-1.8v-2C17.1,7.5,16.5,6.4,15.8,6.4z M8.6,13c-2.1,0-3.8-1.7-3.8-3.8
|
10 |
+
c0-2.1,1.7-3.8,3.8-3.8c2.1,0,3.8,1.7,3.8,3.8C12.3,11.3,10.6,13,8.6,13z"/>
|
11 |
+
<path fill="#AAAAAA" d="M22.3,15.6l-0.6,0.2c0,0,0,0.1,0,0l0.3-0.5c0.2-0.4,0-0.8-0.4-1l-1-0.4c-0.4-0.2-0.8,0-1,0.4l-0.1,0.5
|
12 |
+
c0,0,0,0,0,0l-0.2-0.6c-0.2-0.4-0.8-0.5-1.2-0.3l-1.1,0.4c-0.4,0.2-0.8,0.7-0.7,1.1l0.2,0.6c0,0,0.1,0,0.1,0l-0.5-0.3
|
13 |
+
c-0.4-0.2-0.8,0-1,0.4l-0.4,1c-0.2,0.4,0,0.8,0.4,1l0.5,0.1c0,0,0,0,0,0l-0.6,0.2c-0.4,0.2-0.5,0.8-0.4,1.2l0.4,1.1
|
14 |
+
c0.2,0.4,0.7,0.8,1.1,0.7l0.6-0.2c0,0,0-0.1,0,0l-0.3,0.5c-0.2,0.4,0,0.8,0.4,1l1,0.4c0.4,0.2,0.8,0,1-0.4l0.1-0.5c0,0,0,0,0,0
|
15 |
+
l0.2,0.6c0.2,0.4,0.9,0.5,1.2,0.3l1.1-0.4c0.4-0.2,0.8-0.7,0.6-1.1l-0.2-0.6c0,0-0.1,0,0,0l0.5,0.3c0.4,0.2,0.8,0,1-0.4l0.4-1
|
16 |
+
c0.2-0.4,0-0.8-0.4-1l-0.5-0.1c0,0,0,0,0,0l0.6-0.2c0.4-0.2,0.5-0.8,0.3-1.2l-0.4-1.1C23.2,15.9,22.7,15.5,22.3,15.6z M19.9,20.5
|
17 |
+
c-1.1,0.4-2.3-0.1-2.7-1.2c-0.4-1.1,0.1-2.3,1.2-2.7c1.1-0.4,2.3,0.1,2.7,1.2C21.5,18.9,21,20.1,19.9,20.5z"/>
|
18 |
+
</svg>
|
19 |
+
|
20 |
+
</span>
|
21 |
+
<strong>Request / Response</strong>
|
22 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/request/panel.phtml
ADDED
@@ -0,0 +1,163 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_RequestDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
?>
|
7 |
+
|
8 |
+
|
9 |
+
<div class="sf-tabs">
|
10 |
+
<div class="tab">
|
11 |
+
<h3 class="tab-title">Request</h3>
|
12 |
+
|
13 |
+
<div class="tab-content">
|
14 |
+
<h3>GET Parameters</h3>
|
15 |
+
|
16 |
+
<?php if (!count($collector->getRequestQuery())): ?>
|
17 |
+
<div class="empty">
|
18 |
+
<p>No GET parameters</p>
|
19 |
+
</div>
|
20 |
+
<?php else: ?>
|
21 |
+
<?php echo $this->renderBag($collector->getRequestQuery()) ?>
|
22 |
+
<?php endif ?>
|
23 |
+
|
24 |
+
<h3>POST Parameters</h3>
|
25 |
+
|
26 |
+
<?php if (!count($collector->getRequestRequest())): ?>
|
27 |
+
<div class="empty">
|
28 |
+
<p>No POST parameters</p>
|
29 |
+
</div>
|
30 |
+
<?php else: ?>
|
31 |
+
<?php echo $this->renderBag($collector->getRequestRequest()) ?>
|
32 |
+
<?php endif ?>
|
33 |
+
|
34 |
+
<h3>Request Attributes</h3>
|
35 |
+
|
36 |
+
<?php if (!count($collector->getRequestAttributes())): ?>
|
37 |
+
<div class="empty">
|
38 |
+
<p>No attributes</p>
|
39 |
+
</div>
|
40 |
+
<?php else: ?>
|
41 |
+
<?php echo $this->renderBag($collector->getRequestAttributes()) ?>
|
42 |
+
<?php endif ?>
|
43 |
+
|
44 |
+
<h3>Cookies</h3>
|
45 |
+
|
46 |
+
<?php if (!count($collector->getRequestCookies())): ?>
|
47 |
+
<div class="empty">
|
48 |
+
<p>No cookies</p>
|
49 |
+
</div>
|
50 |
+
<?php else: ?>
|
51 |
+
<?php echo $this->renderBag($collector->getRequestCookies()) ?>
|
52 |
+
<?php endif ?>
|
53 |
+
|
54 |
+
<h3>Request Headers</h3>
|
55 |
+
<?php echo $this->renderBag($collector->getRequestHeaders()) ?>
|
56 |
+
|
57 |
+
<h3>Request Content</h3>
|
58 |
+
|
59 |
+
<?php if ($collector->getContent() === false): ?>
|
60 |
+
<div class="empty">
|
61 |
+
<p>Request content not available (it was retrieved as a resource).</p>
|
62 |
+
</div>
|
63 |
+
<?php elseif ($collector->getContent()): ?>
|
64 |
+
<div class="card">
|
65 |
+
<pre class="break-long-words"><?php echo $collector->getContent() ?></pre>
|
66 |
+
</div>
|
67 |
+
<?php else: ?>
|
68 |
+
<div class="empty">
|
69 |
+
<p>No content</p>
|
70 |
+
</div>
|
71 |
+
<?php endif ?>
|
72 |
+
|
73 |
+
<h3>Server Parameters</h3>
|
74 |
+
<?php echo $this->renderBag($collector->getRequestServer()) ?>
|
75 |
+
</div>
|
76 |
+
</div>
|
77 |
+
|
78 |
+
<div class="tab">
|
79 |
+
<h3 class="tab-title">Response</h3>
|
80 |
+
|
81 |
+
<div class="tab-content">
|
82 |
+
<h3>Response Headers</h3>
|
83 |
+
|
84 |
+
<?php echo $this->renderBag($collector->getResponseHeaders()) ?>
|
85 |
+
</div>
|
86 |
+
</div>
|
87 |
+
|
88 |
+
<!--<div class="tab {{ collector.sessionmetadata is empty ? 'disabled' }}">
|
89 |
+
<h3 class="tab-title">Session</h3>
|
90 |
+
|
91 |
+
<div class="tab-content">
|
92 |
+
<h3>Session Metadata</h3>
|
93 |
+
|
94 |
+
{% if collector.sessionmetadata is empty %}
|
95 |
+
<div class="empty">
|
96 |
+
<p>No session metadata</p>
|
97 |
+
</div>
|
98 |
+
{% else %}
|
99 |
+
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.sessionmetadata }, with_context = false) }}
|
100 |
+
{% endif %}
|
101 |
+
|
102 |
+
<h3>Session Attributes</h3>
|
103 |
+
|
104 |
+
{% if collector.sessionattributes is empty %}
|
105 |
+
<div class="empty">
|
106 |
+
<p>No session attributes</p>
|
107 |
+
</div>
|
108 |
+
{% else %}
|
109 |
+
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.sessionattributes, labels: ['Attribute', 'Value'] }, with_context = false) }}
|
110 |
+
{% endif %}
|
111 |
+
</div>
|
112 |
+
</div>
|
113 |
+
|
114 |
+
<div class="tab {{ collector.flashes is empty ? 'disabled' }}">
|
115 |
+
<h3 class="tab-title">Flashes</h3>
|
116 |
+
|
117 |
+
<div class="tab-content">
|
118 |
+
<h3>Flashes</h3>
|
119 |
+
|
120 |
+
{% if collector.flashes is empty %}
|
121 |
+
<div class="empty">
|
122 |
+
<p>No flash messages were created.</p>
|
123 |
+
</div>
|
124 |
+
{% else %}
|
125 |
+
{{ include('@WebProfiler/Profiler/table.html.twig', { data: collector.flashes }, with_context = false) }}
|
126 |
+
{% endif %}
|
127 |
+
</div>
|
128 |
+
</div>
|
129 |
+
|
130 |
+
{% if profile.parent %}
|
131 |
+
<div class="tab">
|
132 |
+
<h3 class="tab-title">Parent Request</h3>
|
133 |
+
|
134 |
+
<div class="tab-content">
|
135 |
+
<h3>
|
136 |
+
<a href="{{ path('_profiler', { token: profile.parent.token }) }}">Return to parent request</a>
|
137 |
+
<small>(token = {{ profile.parent.token }})</small>
|
138 |
+
</h3>
|
139 |
+
|
140 |
+
{{ include('@WebProfiler/Profiler/bag.html.twig', { bag: profile.parent.getcollector('request').requestattributes }, with_context = false) }}
|
141 |
+
</div>
|
142 |
+
</div>
|
143 |
+
{% endif %}
|
144 |
+
|
145 |
+
{% if profile.children|length %}
|
146 |
+
<div class="tab">
|
147 |
+
<h3 class="tab-title">Sub Requests <span class="badge">{{ profile.children|length }}</span></h3>
|
148 |
+
|
149 |
+
<div class="tab-content">
|
150 |
+
{% for child in profile.children %}
|
151 |
+
<h3>
|
152 |
+
<a href="{{ path('_profiler', { token: child.token }) }}">
|
153 |
+
{{- child.getcollector('request').requestattributes.get('_controller') -}}
|
154 |
+
</a>
|
155 |
+
<small>(token = {{ child.token }})</small>
|
156 |
+
</h3>
|
157 |
+
|
158 |
+
{{ include('@WebProfiler/Profiler/bag.html.twig', { bag: child.getcollector('request').requestattributes }, with_context = false) }}
|
159 |
+
{% endfor %}
|
160 |
+
</div>
|
161 |
+
</div>
|
162 |
+
{% endif %}-->
|
163 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/request/toolbar.phtml
ADDED
@@ -0,0 +1,51 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_RequestDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
$token = $this->getToken();
|
7 |
+
$requestStatusCodeColor = $collector->getStatusCode() >= 400 ? 'red' : $collector->getStatusCode() >= 300 ? 'yellow' : 'green';
|
8 |
+
?>
|
9 |
+
|
10 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-normal ">
|
11 |
+
<a target="_blank" href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
12 |
+
<div class="sf-toolbar-icon">
|
13 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $requestStatusCodeColor?>"><?php echo $collector->getStatusCode()?></span>
|
14 |
+
<?php if($collector->getRoute()): ?>
|
15 |
+
<span class="sf-toolbar-label"><?php echo $collector->getMethod() !== 'GET' ? $collector->getMethod() : ''?> @</span>
|
16 |
+
<span class="sf-toolbar-value sf-toolbar-info-piece-additional"><?php echo $collector->getRoute()?></span>
|
17 |
+
<?php endif?>
|
18 |
+
</div>
|
19 |
+
</a>
|
20 |
+
<div class="sf-toolbar-info">
|
21 |
+
<div class="sf-toolbar-info-group">
|
22 |
+
<div class="sf-toolbar-info-piece">
|
23 |
+
<b>HTTP status</b>
|
24 |
+
<span><?php echo $collector->getStatusCode() ?></span>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
|
28 |
+
<div class="sf-toolbar-info-piece">
|
29 |
+
<b>Route Name</b><span><?php echo $collector->getRoute() ?></span>
|
30 |
+
</div>
|
31 |
+
<div class="sf-toolbar-info-piece">
|
32 |
+
<b>Module</b><span><?php echo $collector->getModuleName() ?></span>
|
33 |
+
</div>
|
34 |
+
<div class="sf-toolbar-info-piece">
|
35 |
+
<b>Controller</b>
|
36 |
+
<span><?php echo $collector->getControllerName() ?>::<?php echo $collector->getActionName() ?> </span>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<?php $controllerData = $collector->getController(); ?>
|
40 |
+
<div class="sf-toolbar-info-piece">
|
41 |
+
<b>Controller class</b>
|
42 |
+
<span><?php echo $controllerData['class'] ?></span>
|
43 |
+
</div>
|
44 |
+
<div class="sf-toolbar-info-piece">
|
45 |
+
<b>Full action name</b>
|
46 |
+
<span><?php echo $collector->getRoute(); ?></span>
|
47 |
+
</div>
|
48 |
+
</div>
|
49 |
+
|
50 |
+
</div>
|
51 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/menu.phtml
ADDED
@@ -0,0 +1,22 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_RewriteDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$conflictCount = $collector->getModuleRewriteConflictCount();
|
5 |
+
$statusColor = $conflictCount ? 'error' : 'normal';
|
6 |
+
?>
|
7 |
+
|
8 |
+
<span class="label label-status-<?php echo $statusColor ?>">
|
9 |
+
<span class="icon">
|
10 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
11 |
+
<path style="fill:#aaa" d="M23.61,11.07L17.07,4.35A1.2,1.2,0,0,0,15,5.28V9H1.4A1.82,1.82,0,0,0,0,10.82v2.61A1.55,
|
12 |
+
1.55,0,0,0,1.4,15H15v3.72a1.2,1.2,0,0,0,2.07.93l6.63-6.72A1.32,1.32,0,0,0,23.61,11.07Z"/>
|
13 |
+
</svg>
|
14 |
+
|
15 |
+
</span>
|
16 |
+
<strong>Rewrites</strong>
|
17 |
+
<?php if ($conflictCount): ?>
|
18 |
+
<span class="count">
|
19 |
+
<span><?php echo $conflictCount ?> </span>
|
20 |
+
</span>
|
21 |
+
<?php endif ?>
|
22 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/panel.phtml
ADDED
@@ -0,0 +1,77 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_RewriteDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
|
7 |
+
?>
|
8 |
+
<?php $conflicts = $collector->getModuleRewriteConflicts(); ?>
|
9 |
+
<h2>Rewrite Conflicts</h2>
|
10 |
+
<?php if ($conflicts): ?>
|
11 |
+
<table>
|
12 |
+
<thead>
|
13 |
+
<tr>
|
14 |
+
<th>Type</th>
|
15 |
+
<th>Class</th>
|
16 |
+
<th>Rewrites</th>
|
17 |
+
<th>Loaded Class</th>
|
18 |
+
</tr>
|
19 |
+
</thead>
|
20 |
+
<tbody>
|
21 |
+
<?php foreach ($conflicts as $conflict): ?>
|
22 |
+
<tr>
|
23 |
+
<td><?php echo $conflict['type'] ?></td>
|
24 |
+
<td><?php echo $conflict['class'] ?></td>
|
25 |
+
<td><?php echo implode('<br>', $conflict['rewrites']) ?></td>
|
26 |
+
<td><?php echo $conflict['loaded_class'] ?></td>
|
27 |
+
</tr>
|
28 |
+
|
29 |
+
<?php endforeach; ?>
|
30 |
+
</tbody>
|
31 |
+
</table>
|
32 |
+
|
33 |
+
<?php else: ?>
|
34 |
+
<div class="empty">
|
35 |
+
<p>No rewrite conflicts</p>
|
36 |
+
</div>
|
37 |
+
|
38 |
+
<?php endif; ?>
|
39 |
+
|
40 |
+
<?php
|
41 |
+
$rewrites = $collector->getModuleRewrites();
|
42 |
+
?>
|
43 |
+
<h2>Rewrites</h2>
|
44 |
+
|
45 |
+
<div class="sf-tabs">
|
46 |
+
<?php foreach ($rewrites as $type => $typeRewrites): ?>
|
47 |
+
<div class="tab">
|
48 |
+
<h3 class="tab-title"><?php echo ucwords($type) ?>
|
49 |
+
<small>(<?php echo count($typeRewrites) ?>)</small>
|
50 |
+
</h3>
|
51 |
+
<div class="tab-content">
|
52 |
+
<?php if ($typeRewrites): ?>
|
53 |
+
<table>
|
54 |
+
<thead>
|
55 |
+
<tr>
|
56 |
+
<th>Class Group</th>
|
57 |
+
<th>Rewrites</th>
|
58 |
+
</tr>
|
59 |
+
</thead>
|
60 |
+
<tbody>
|
61 |
+
<?php foreach ($typeRewrites as $classGroup => $rewrites): ?>
|
62 |
+
<tr>
|
63 |
+
<td><?php echo $classGroup ?></td>
|
64 |
+
<td><?php echo implode('<br>', $rewrites) ?></td>
|
65 |
+
</tr>
|
66 |
+
<?php endforeach; ?>
|
67 |
+
</tbody>
|
68 |
+
</table>
|
69 |
+
<?php else: ?>
|
70 |
+
<div class="empty">
|
71 |
+
<p>No rewrite conflicts</p>
|
72 |
+
</div>
|
73 |
+
<?php endif; ?>
|
74 |
+
</div>
|
75 |
+
</div>
|
76 |
+
<?php endforeach; ?>
|
77 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/toolbar.phtml
ADDED
@@ -0,0 +1,40 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_RewriteDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
|
6 |
+
$conflictCount = $collector->getModuleRewriteConflictCount();
|
7 |
+
?>
|
8 |
+
|
9 |
+
<?php if ($conflictCount): ?>
|
10 |
+
<div
|
11 |
+
class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName() ?> sf-toolbar-status-<?php echo $conflictCount ? 'red' : 'normal' ?>">
|
12 |
+
<a target="_blank"
|
13 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
14 |
+
<div class="sf-toolbar-icon">
|
15 |
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
16 |
+
<path style="fill:#aaa" d="M23.61,11.07L17.07,4.35A1.2,1.2,0,0,0,15,5.28V9H1.4A1.82,1.82,0,0,0,0,10.82v2.61A1.55,
|
17 |
+
1.55,0,0,0,1.4,15H15v3.72a1.2,1.2,0,0,0,2.07.93l6.63-6.72A1.32,1.32,0,0,0,23.61,11.07Z"/>
|
18 |
+
</svg>
|
19 |
+
|
20 |
+
<span class="sf-toolbar-value"><?php echo $conflictCount ? $conflictCount : '' ?> </span>
|
21 |
+
|
22 |
+
</div>
|
23 |
+
</a>
|
24 |
+
<div class="sf-toolbar-info">
|
25 |
+
|
26 |
+
<?php foreach($collector->getModuleRewrites() as $type => $typeRewrites):?>
|
27 |
+
<div class="sf-toolbar-info-piece">
|
28 |
+
<b><?php echo ucwords($type)?> Rewrites</b>
|
29 |
+
<span><?php echo count($typeRewrites) ?></span>
|
30 |
+
</div>
|
31 |
+
<?php endforeach;?>
|
32 |
+
|
33 |
+
<div class="sf-toolbar-info-piece">
|
34 |
+
<b>Rewrite Conflict Count</b>
|
35 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $conflictCount ? 'red' : 'normal' ?>"><?php echo $conflictCount ?></span>
|
36 |
+
</div>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
</div>
|
40 |
+
<?php endif; ?>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/time/toolbar.phtml
ADDED
@@ -0,0 +1,23 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_TimeDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
|
7 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-normal">
|
8 |
+
<div class="sf-toolbar-icon">
|
9 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
10 |
+
<path fill="#AAAAAA" d="M15.1,4.3c-2.1-0.5-4.2-0.5-6.2,0C8.6,4.3,8.2,4.1,8.2,3.8V3.4c0-1.2,1-2.3,2.3-2.3h3c1.2,0,2.3,1,2.3,2.3
|
11 |
+
v0.3C15.8,4.1,15.4,4.3,15.1,4.3z M20.9,14c0,4.9-4,8.9-8.9,8.9s-8.9-4-8.9-8.9s4-8.9,8.9-8.9S20.9,9.1,20.9,14z M16.7,15
|
12 |
+
c0-0.6-0.4-1-1-1H13V8.4c0-0.6-0.4-1-1-1s-1,0.4-1,1v6.2c0,0.6,0.4,1.3,1,1.3h3.7C16.2,16,16.7,15.6,16.7,15z"/>
|
13 |
+
</svg>
|
14 |
+
<span class="sf-toolbar-value"><?php echo sprintf('%0.0f', $collector->getTotalTime() * 1000)?></span>
|
15 |
+
<span class="sf-toolbar-label">ms</span>
|
16 |
+
</div>
|
17 |
+
<div class="sf-toolbar-info">
|
18 |
+
<div class="sf-toolbar-info-piece">
|
19 |
+
<b>Total Time</b>
|
20 |
+
<span><?php echo sprintf('%0.0f', $collector->getTotalTime() * 1000)?> ms</span>
|
21 |
+
</div>
|
22 |
+
</div>
|
23 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/translation/menu.phtml
ADDED
@@ -0,0 +1,31 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_TranslationDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$statusColor = ($collector->getStateCount('invalid') || $collector->getStateCount('missing')) ? 'error' : ($collector->getStateCount('fallback') ? 'warning' : 'normal');
|
5 |
+
?>
|
6 |
+
|
7 |
+
|
8 |
+
<span class="label label-status-<?php echo $statusColor ?>">
|
9 |
+
<span class="icon">
|
10 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24"
|
11 |
+
enable-background="new 0 0 24 24" xml:space="preserve">
|
12 |
+
<path fill="#AAAAAA" d="M5.4,6H7v0.3c0,1.2-0.7,1.9-1.7,1.9c-1.1,0-1.4-0.4-1.4-1.1C3.9,6.2,4.5,6,5.4,6z M9.2,0H2.7
|
13 |
+
C1.2,0,0,0.9,0,2.4v6.5C0,10.4,1.2,11,2.7,11h1.2l3.3,3.2C7.6,14.4,8,14.5,8,14.1c0-1.4,0-2.8,0-4.2c0-0.4,0-0.7,0.1-1.1
|
14 |
+
c-0.1,0-0.3,0-0.4,0C7.4,8.9,7,8.7,7,8.4V7.9c0,0.7-1,1-1.8,1c-1.5,0-2.4-0.7-2.4-2c0-1.3,1.1-2,2.6-2H7V4.5c0-1-0.4-1.6-1.5-1.6
|
15 |
+
C4.8,2.9,4.4,3.1,4,3.6C3.8,3.8,3.8,3.8,3.7,3.8c-0.2,0-0.4-0.2-0.4-0.4c0-0.1,0-0.2,0.1-0.2C3.8,2.5,4.4,2,5.6,2C7.2,2,8,3,8,4.5v3
|
16 |
+
c1-1.4,1.8-2.4,4-2.4c0,0,0-1.9,0-2.7C12,0.9,10.7,0,9.2,0z M20.7,6h-8C10.8,6,9,7.2,9,9v8c0,1.8,2,3.3,4,3.3v3
|
17 |
+
c0,0.5,0.5,0.7,0.9,0.3l4-3.7h2.7c1.8,0,3.3-1.2,3.3-3V9C24,7.2,22.5,6,20.7,6z M13,9c0,0,0.6,0,1.1,0h4.8C19.3,9,20,9,20,9v0.8
|
18 |
+
c0,0-0.7,0.3-1.1,0.3h-4.8C13.7,10,13,9.7,13,9.7V9z M12.5,16.9c-0.2-0.2-0.3-0.3-0.6-0.5c1-0.8,1.8-2.1,2.2-3.4l0.7,0.3
|
19 |
+
C14.2,14.8,13.4,15.9,12.5,16.9z M17,12v4.8c0,0.7-0.2,0.8-1.2,0.8c-0.4,0-1,0-1.4-0.1c0-0.3-0.1-0.4-0.2-0.7
|
20 |
+
c0.6,0.1,0.9,0.1,1.4,0.1c0.4,0,0.4,0,0.4-0.3V12h-2.9c-0.4,0-1.1,0.1-1.1,0.1v-0.8c0,0,0.7-0.4,1.1-0.4h6.8c0.5,0,1.1,0.4,1.1,0.4
|
21 |
+
v0.8c0,0-0.6-0.1-1.1-0.1H17z M20.7,16.8c-1-1.1-1.6-1.9-2.3-3.6L19,13c0.5,1.1,0.8,1.7,1.4,2.4c0.3,0.3,0.5,0.5,0.8,0.9
|
22 |
+
C21.1,16.4,20.9,16.6,20.7,16.8z"/>
|
23 |
+
</svg>
|
24 |
+
</span>
|
25 |
+
<strong>Translation</strong>
|
26 |
+
<?php if ($collector->getNotOkCount()): ?>
|
27 |
+
<span class="count">
|
28 |
+
<span><?php echo $collector->getNotOkCount() ?> </span>
|
29 |
+
</span>
|
30 |
+
<?php endif ?>
|
31 |
+
</span>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/translation/panel.phtml
ADDED
@@ -0,0 +1,121 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Collector_Translation_Panel $this */
|
3 |
+
|
4 |
+
/** @var Ecocode_Profiler_Model_Collector_TranslationDataCollector $collector */
|
5 |
+
$collector = $this->getCollector();
|
6 |
+
?>
|
7 |
+
|
8 |
+
|
9 |
+
<h2>Translation Metrics</h2>
|
10 |
+
|
11 |
+
<div class="metrics">
|
12 |
+
<div class="metric">
|
13 |
+
<span class="value"><?php echo $collector->getStateCount('translated'); ?></span>
|
14 |
+
<span class="label">Defined messages</span>
|
15 |
+
</div>
|
16 |
+
|
17 |
+
<div class="metric">
|
18 |
+
<span class="value"><?php echo $collector->getStateCount('fallback'); ?></span>
|
19 |
+
<span class="label">Fallback messages</span>
|
20 |
+
</div>
|
21 |
+
|
22 |
+
<div class="metric">
|
23 |
+
<span class="value"><?php echo $collector->getStateCount('missing'); ?></span>
|
24 |
+
<span class="label">Missing messages</span>
|
25 |
+
</div>
|
26 |
+
|
27 |
+
<div class="metric">
|
28 |
+
<span class="value"><?php echo $collector->getStateCount('invalid'); ?></span>
|
29 |
+
<span class="label">Invalid messages</span>
|
30 |
+
</div>
|
31 |
+
</div>
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
<h2>Translation Messages</h2>
|
36 |
+
|
37 |
+
<?php $messageGroups = $this->getMessageGroups();?>
|
38 |
+
<div class="sf-tabs">
|
39 |
+
<div class="tab">
|
40 |
+
<h3 class="tab-title">Defined <span class="badge"><?php echo count($messageGroups['translated']) ?></span></h3>
|
41 |
+
|
42 |
+
<div class="tab-content">
|
43 |
+
<p class="help">
|
44 |
+
These messages are correctly translated into the given locale.
|
45 |
+
</p>
|
46 |
+
|
47 |
+
<?php if (empty($messageGroups['translated'])): ?>
|
48 |
+
<div class="empty">
|
49 |
+
<p>None of the used translation messages are defined for the given locale.</p>
|
50 |
+
</div>
|
51 |
+
<?php else: ?>
|
52 |
+
<?php echo $this->renderTable($messageGroups['translated']); ?>
|
53 |
+
<?php endif ?>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
|
57 |
+
<div class="tab">
|
58 |
+
<h3 class="tab-title">Fallback <span class="badge"><?php echo count($messageGroups['fallback']) ?></span></h3>
|
59 |
+
|
60 |
+
<div class="tab-content">
|
61 |
+
<p class="help">
|
62 |
+
These messages are not available for the given Module
|
63 |
+
but Magento found them in the global namespace.
|
64 |
+
</p>
|
65 |
+
|
66 |
+
<?php if (empty($messageGroups['fallback'])): ?>
|
67 |
+
<div class="empty">
|
68 |
+
<p>No fallback translation messages were used.</p>
|
69 |
+
</div>
|
70 |
+
<?php else: ?>
|
71 |
+
<?php echo $this->renderTable($messageGroups['fallback']); ?>
|
72 |
+
<?php endif ?>
|
73 |
+
</div>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<div class="tab">
|
77 |
+
<h3 class="tab-title">Missing <span class="badge"><?php echo count($messageGroups['missing']) ?></span></h3>
|
78 |
+
|
79 |
+
<div class="tab-content">
|
80 |
+
<p class="help">
|
81 |
+
These messages are not available for the given locale and cannot
|
82 |
+
be found in the fallback locales. Add them to the translation
|
83 |
+
catalogue to avoid Magento outputting untranslated contents.
|
84 |
+
</p>
|
85 |
+
|
86 |
+
|
87 |
+
<?php if (empty($messageGroups['missing'])): ?>
|
88 |
+
<div class="empty">
|
89 |
+
<p>There are no messages of this category.</p>
|
90 |
+
</div>
|
91 |
+
<?php else: ?>
|
92 |
+
<?php echo $this->renderTable($messageGroups['missing']); ?>
|
93 |
+
<?php endif ?>
|
94 |
+
</div>
|
95 |
+
</div>
|
96 |
+
|
97 |
+
<div class="tab">
|
98 |
+
<h3 class="tab-title">Invalid <span class="badge"><?php echo count($messageGroups['invalid']) ?></span></h3>
|
99 |
+
|
100 |
+
<div class="tab-content">
|
101 |
+
<p class="help">
|
102 |
+
These messages are not correctly translated as its not correctly formatted or parameters were missing
|
103 |
+
</p>
|
104 |
+
|
105 |
+
<?php if (empty($messageGroups['invalid'])): ?>
|
106 |
+
<div class="empty">
|
107 |
+
<p>There are no messages of this category.</p>
|
108 |
+
</div>
|
109 |
+
<?php else: ?>
|
110 |
+
<?php echo $this->renderTable($messageGroups['invalid']); ?>
|
111 |
+
<?php endif ?>
|
112 |
+
</div>
|
113 |
+
</div>
|
114 |
+
</div>
|
115 |
+
|
116 |
+
<style>
|
117 |
+
tr.sf-toggle-content.sf-toggle-visible {
|
118 |
+
display: table-row!important;
|
119 |
+
}
|
120 |
+
|
121 |
+
</style>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/translation/panel/table.phtml
ADDED
@@ -0,0 +1,82 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Helper_ValueExporter $valueExporter */
|
3 |
+
$valueExporter = $this->helper('ecocode_profiler/valueExporter');
|
4 |
+
$prefix = 'trans-' . uniqid(); ?>
|
5 |
+
<table>
|
6 |
+
<thead>
|
7 |
+
<tr>
|
8 |
+
<th>Locale</th>
|
9 |
+
<th>Module</th>
|
10 |
+
<th>Times used</th>
|
11 |
+
<th>Message ID</th>
|
12 |
+
<th>Message Preview</th>
|
13 |
+
</tr>
|
14 |
+
</thead>
|
15 |
+
<tbody>
|
16 |
+
<?php foreach ($this->getData('messages') as $index => $message): ?>
|
17 |
+
<tr>
|
18 |
+
<td class="font-normal text-small"><?php echo $message['locale'] ?></td>
|
19 |
+
<td class="font-normal text-small text-bold"><?php echo $message['module'] ?></td>
|
20 |
+
<td class="font-normal text-small"><?php echo $message['count'] ?></td>
|
21 |
+
<td>
|
22 |
+
<?php echo $message['code'] ?>
|
23 |
+
|
24 |
+
<?php if ($message['parameters']): ?>
|
25 |
+
<button class="btn-link newline text-small sf-toggle"
|
26 |
+
data-toggle-selector="#parameters-<?php echo $prefix . $index ?>"
|
27 |
+
data-toggle-alt-content="Hide parameters">Show parameters
|
28 |
+
</button>
|
29 |
+
|
30 |
+
<div id="parameters-<?php echo $prefix . $index ?>" class="hidden">
|
31 |
+
<?php foreach ($message['parameters'] as $parameters): ?>
|
32 |
+
<?php echo $valueExporter->exportValue($parameters); ?>
|
33 |
+
<?php endforeach; ?>
|
34 |
+
</div>
|
35 |
+
<?php endif; ?>
|
36 |
+
<?php if ($message['traces']): ?>
|
37 |
+
<button class="btn-link newline text-small sf-toggle"
|
38 |
+
data-toggle-selector="#traces-<?php echo $prefix . $index ?>"
|
39 |
+
data-toggle-alt-content="Hide traces">Show traces
|
40 |
+
</button>
|
41 |
+
|
42 |
+
<?php endif; ?>
|
43 |
+
</td>
|
44 |
+
<td><?php echo $message['translation'] ?></td>
|
45 |
+
</tr>
|
46 |
+
<?php if (!empty($message['traces'])): ?>
|
47 |
+
<tr class="hidden" id="traces-<?php echo $prefix . $index ?>">
|
48 |
+
<td colspan="3"></td>
|
49 |
+
<td colspan="2">
|
50 |
+
<div id="stack-<?php echo $prefix . $index ?>" class="hiddenx">
|
51 |
+
<table class="">
|
52 |
+
<tbody>
|
53 |
+
<?php foreach ($message['traces'] as $j => $trace): ?>
|
54 |
+
<tr>
|
55 |
+
<td class="nowrap">#<?php echo $j + 1 ?></td>
|
56 |
+
<td>
|
57 |
+
<ul class="sf-call-stack ">
|
58 |
+
<?php foreach ($trace as $item): ?>
|
59 |
+
<li>
|
60 |
+
<?php echo isset($item['class']) ? $item['class'] . '::' : '' ?><?php echo $item['function'] ?>
|
61 |
+
<br>
|
62 |
+
<?php if (isset($item['file'])): ?>
|
63 |
+
<small><?php echo $item['file'] ?>
|
64 |
+
::<?php echo $item['line'] ?></small>
|
65 |
+
<?php endif; ?>
|
66 |
+
</li>
|
67 |
+
<?php endforeach; ?>
|
68 |
+
</ul>
|
69 |
+
</td>
|
70 |
+
</tr>
|
71 |
+
<?php endforeach; ?>
|
72 |
+
|
73 |
+
</tbody>
|
74 |
+
</table>
|
75 |
+
</div>
|
76 |
+
</td>
|
77 |
+
</tr>
|
78 |
+
<?php endif; ?>
|
79 |
+
|
80 |
+
<?php endforeach; ?>
|
81 |
+
</tbody>
|
82 |
+
</table>
|
app/design/frontend/base/default/template/ecocode_profiler/collector/translation/toolbar.phtml
ADDED
@@ -0,0 +1,56 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Collector_TranslationDataCollector $collector */
|
3 |
+
$collector = $this->getCollector();
|
4 |
+
$token = $this->getToken();
|
5 |
+
?>
|
6 |
+
<?php $statusColor = $collector->getStateCount('invalid') || $collector->getStateCount('missing') ? 'red' : $collector->getStateCount('fallback') ? 'yellow' : 'normal' ?>
|
7 |
+
|
8 |
+
<div class="sf-toolbar-block sf-toolbar-block-<?php echo $collector->getName()?> sf-toolbar-status-<?php echo $statusColor ?>">
|
9 |
+
<a target="_blank"
|
10 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getCollectorUrl($token, $collector); ?>">
|
11 |
+
<div class="sf-toolbar-icon">
|
12 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24"
|
13 |
+
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
14 |
+
<path fill="#AAAAAA" d="M5.4,6H7v0.3c0,1.2-0.7,1.9-1.7,1.9c-1.1,0-1.4-0.4-1.4-1.1C3.9,6.2,4.5,6,5.4,6z M9.2,0H2.7
|
15 |
+
C1.2,0,0,0.9,0,2.4v6.5C0,10.4,1.2,11,2.7,11h1.2l3.3,3.2C7.6,14.4,8,14.5,8,14.1c0-1.4,0-2.8,0-4.2c0-0.4,0-0.7,0.1-1.1
|
16 |
+
c-0.1,0-0.3,0-0.4,0C7.4,8.9,7,8.7,7,8.4V7.9c0,0.7-1,1-1.8,1c-1.5,0-2.4-0.7-2.4-2c0-1.3,1.1-2,2.6-2H7V4.5c0-1-0.4-1.6-1.5-1.6
|
17 |
+
C4.8,2.9,4.4,3.1,4,3.6C3.8,3.8,3.8,3.8,3.7,3.8c-0.2,0-0.4-0.2-0.4-0.4c0-0.1,0-0.2,0.1-0.2C3.8,2.5,4.4,2,5.6,2C7.2,2,8,3,8,4.5v3
|
18 |
+
c1-1.4,1.8-2.4,4-2.4c0,0,0-1.9,0-2.7C12,0.9,10.7,0,9.2,0z M20.7,6h-8C10.8,6,9,7.2,9,9v8c0,1.8,2,3.3,4,3.3v3
|
19 |
+
c0,0.5,0.5,0.7,0.9,0.3l4-3.7h2.7c1.8,0,3.3-1.2,3.3-3V9C24,7.2,22.5,6,20.7,6z M13,9c0,0,0.6,0,1.1,0h4.8C19.3,9,20,9,20,9v0.8
|
20 |
+
c0,0-0.7,0.3-1.1,0.3h-4.8C13.7,10,13,9.7,13,9.7V9z M12.5,16.9c-0.2-0.2-0.3-0.3-0.6-0.5c1-0.8,1.8-2.1,2.2-3.4l0.7,0.3
|
21 |
+
C14.2,14.8,13.4,15.9,12.5,16.9z M17,12v4.8c0,0.7-0.2,0.8-1.2,0.8c-0.4,0-1,0-1.4-0.1c0-0.3-0.1-0.4-0.2-0.7
|
22 |
+
c0.6,0.1,0.9,0.1,1.4,0.1c0.4,0,0.4,0,0.4-0.3V12h-2.9c-0.4,0-1.1,0.1-1.1,0.1v-0.8c0,0,0.7-0.4,1.1-0.4h6.8c0.5,0,1.1,0.4,1.1,0.4
|
23 |
+
v0.8c0,0-0.6-0.1-1.1-0.1H17z M20.7,16.8c-1-1.1-1.6-1.9-2.3-3.6L19,13c0.5,1.1,0.8,1.7,1.4,2.4c0.3,0.3,0.5,0.5,0.8,0.9
|
24 |
+
C21.1,16.4,20.9,16.6,20.7,16.8z"/>
|
25 |
+
</svg>
|
26 |
+
|
27 |
+
<span class="sf-toolbar-value"><?php echo $collector->getTranslationCount() ?></span>
|
28 |
+
|
29 |
+
</div>
|
30 |
+
</a>
|
31 |
+
<div class="sf-toolbar-info">
|
32 |
+
<div class="sf-toolbar-info-piece">
|
33 |
+
<b>Missing messages</b>
|
34 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->getStateCount('missing') ? 'red' : '' ?>">
|
35 |
+
<?php echo $collector->getStateCount('missing') ?>
|
36 |
+
</span>
|
37 |
+
</div>
|
38 |
+
|
39 |
+
<div class="sf-toolbar-info-piece">
|
40 |
+
<b>Fallback messages</b>
|
41 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->getStateCount('missing') ? 'yellow' : '' ?>">
|
42 |
+
<?php echo $collector->getStateCount('fallback') ?>
|
43 |
+
</span>
|
44 |
+
</div>
|
45 |
+
<div class="sf-toolbar-info-piece">
|
46 |
+
<b>Invalid messages</b>
|
47 |
+
<span class="sf-toolbar-status sf-toolbar-status-<?php echo $collector->getStateCount('invalid') ? 'red' : '' ?>">
|
48 |
+
<?php echo $collector->getStateCount('invalid') ?>
|
49 |
+
</span>
|
50 |
+
</div>
|
51 |
+
<div class="sf-toolbar-info-piece">
|
52 |
+
<b>Defined messages</b>
|
53 |
+
<span class="sf-toolbar-status"><?php echo $collector->getStateCount('translated') ?></span>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/layout.phtml
ADDED
@@ -0,0 +1,87 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="utf-8"/>
|
5 |
+
<meta name="robots" content="noindex,nofollow"/>
|
6 |
+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
7 |
+
<title>Magento Profiler</title>
|
8 |
+
<link rel="icon" type="image/x-icon" sizes="16x16"
|
9 |
+
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
|
10 |
+
WXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4AkNDCcsxO0sbAAAAYBJREFUOMvdk80rZXEYxz/PPV6u
|
11 |
+
bDBervHSdWaklLJQVrKxslQ2QoqNjS5ZTDTNyPYmFrIh6pDF/QvUNOU/UEgmLoW8zGAl3Ov8ntmc
|
12 |
+
ezt0yGznu/ye7/OpU5+f8Equeux6YzEDhEFGI87hTtBOXha3A9GilAl9USUG5Ht1GnTZPOVOflz/
|
13 |
+
9ScQoN1YVwWfhlR1GigDnkAXvNkwkAP8FpGv5feHi5LAzQLO+6LtoqFZhGaP9xNDLLKW3AY4661r
|
14 |
+
sERmgE4PuCe4oxXO8YYAXPTZ10AJcKDoRKVzlAj638t+u0OVOaARuIk4yQ85/kE6L9Vas3R6czsQ
|
15 |
+
LXp0Q98qHpLjAJdhO55vmanileSPk8HqttxU3nXmJuQHhLUwDfBorF0g5vsU87rsJhCQjWrJu7pX
|
16 |
+
Af+Q/wWgmC6UrfefyZ5gevD0pNI53tRuWviMPhMnbMdfnpbW7t+xS1NG5axIksDF80+ReUFHfC6k
|
17 |
+
FZkHkO+YN19jJj7/cVXHqlaP9oN2fwF3BYdp8BgRAQAAAABJRU5ErkJggg==">
|
18 |
+
<?php echo $this->getChildHtml('profiler_head'); ?>
|
19 |
+
<style type="text/css">
|
20 |
+
<?php echo $this->getChildHtml('profiler_css'); ?>
|
21 |
+
</style>
|
22 |
+
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
23 |
+
<script>
|
24 |
+
<?php echo $this->getChildHtml('profiler_js'); ?>
|
25 |
+
</script>
|
26 |
+
</head>
|
27 |
+
<body>
|
28 |
+
<div id="header">
|
29 |
+
<div class="container">
|
30 |
+
<h1>
|
31 |
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svgMageLogo"
|
32 |
+
width="24" xml:space="preserve" height="24" viewBox="0 0 53.692 62" baseProfile="" version="1.1"
|
33 |
+
y="0px" x="0px">
|
34 |
+
<g fill="#E85D22">
|
35 |
+
<path d="m26.845 8.857"/>
|
36 |
+
<polygon points="53.692 15.5 53.692 46.5 46.021 50.929 46.021 19.929 26.845 8.857 7.67 19.928 7.67 50.929 0 46.5 0 15.5 26.845 0"/>
|
37 |
+
<polygon points="26.847 62 15.341 55.356 15.341 24.357 23.011 19.928 23.011 50.929 26.845 53.257 30.682 50.929 30.682 19.929 38.353 24.357 38.353 55.356"/>
|
38 |
+
</g>
|
39 |
+
</svg>
|
40 |
+
Magento <span>Profiler</span>
|
41 |
+
</h1>
|
42 |
+
</div>
|
43 |
+
<div class="logo-ecocode" style="float: right">
|
44 |
+
<a href="http://www.ecocode.de">
|
45 |
+
<svg version="1.1"
|
46 |
+
xmlns="http://www.w3.org/2000/svg"
|
47 |
+
viewBox="0 0 606.25408 139.86"
|
48 |
+
xml:space="preserve" height="28">
|
49 |
+
<g transform="translate(-86.277155,-273.24507)">
|
50 |
+
<g fill="#6c3">
|
51 |
+
<path d="m 110.93715,360.72507 1.98,6.66 47.16,0 c 0.36,-2.7 0.54,-5.4 0.54,-7.92 0,-19.98 -12.24,-34.56 -34.74,-34.56 -23.94,0 -39.599995,19.44 -39.599995,45.72 0,23.76 15.659995,41.4 39.059995,41.4 11.16,0 25.2,-2.16 32.04,-10.08 l -5.4,-3.96 c -7.38,4.14 -12.42,5.22 -18.72,5.22 -20.88,0 -30.06,-14.58 -30.06,-35.82 0,-14.4 3.24,-36.9 21.24,-36.9 14.76,0 20.16,12.42 20.16,30.24 l -33.66,0 z"/>
|
52 |
+
<path d="m 408.97778,398.52507 c -6.3,3.6 -11.52,5.58 -18.54,5.58 -23.4,0 -29.16,-22.14 -29.16,-40.32 0,-19.8 13.32,-29.52 29.16,-29.52 5.58,0 12.24,2.88 16.56,6.3 l 5.76,-5.76 c -4.86,-5.22 -12.78,-9.9 -23.76,-9.9 -28.26,0 -44.1,21.78 -44.1,46.98 0,24.3 13.68,41.22 38.7,41.22 17.82,0 24.66,-5.22 30.42,-10.98 l -5.04,-3.6 z"/>
|
53 |
+
</g>
|
54 |
+
<g fill="#666">
|
55 |
+
<path d="m 234.95434,398.52507 c -6.3,3.6 -11.52,5.58 -18.54,5.58 -23.4,0 -29.16,-22.14 -29.16,-40.32 0,-19.8 13.32,-29.52 29.16,-29.52 5.58,0 12.24,2.88 16.56,6.3 l 5.76,-5.76 c -4.86,-5.22 -12.78,-9.9 -23.76,-9.9 -28.26,0 -44.1,21.78 -44.1,46.98 0,24.3 13.68,41.22 38.7,41.22 17.82,0 24.66,-5.22 30.42,-10.98 l -5.04,-3.6 z"/>
|
56 |
+
<path d="m 332.64653,366.48507 c 0,-26.82 -14.58,-41.22 -39.96,-41.22 l -4.68,0 c 23.58,9.18 27.72,23.94 27.72,47.88 0,21.42 -11.88,33.3 -25.02,33.3 -15.84,0 -25.2,-18.36 -25.2,-43.38 0,-21.06 8.64,-32.4 23.94,-32.4 l 0.36,0 c -3.06,-1.44 -5.94,-2.16 -9,-2.16 -4.86,0 -10.08,1.8 -15.48,5.22 -10.26,7.92 -16.02,19.8 -16.02,34.92 0,26.1 13.5,44.46 38.7,44.46 26.46,0 44.64,-18.72 44.64,-46.62 z"/>
|
57 |
+
<path d="m 509.48247,366.48507 c 0,-26.82 -14.58,-41.22 -39.96,-41.22 l -4.68,0 c 23.58,9.18 27.72,23.94 27.72,47.88 0,21.42 -11.88,33.3 -25.02,33.3 -15.84,0 -25.2,-18.36 -25.2,-43.38 0,-21.06 8.64,-32.4 23.94,-32.4 l 0.36,0 c -3.06,-1.44 -5.94,-2.16 -9,-2.16 -4.86,0 -10.08,1.8 -15.48,5.22 -10.26,7.92 -16.02,19.8 -16.02,34.92 0,26.1 13.5,44.46 38.7,44.46 26.46,0 44.64,-18.72 44.64,-46.62 z"/>
|
58 |
+
<path d="m 537.21372,366.48507 c 0,-15.3 5.76,-32.76 23.76,-32.76 9.36,0 12.24,3.24 15.48,6.66 l 4.86,-5.4 c -6.3,-7.02 -11.7,-10.26 -20.34,-10.26 -26.82,0 -39.6,23.94 -39.6,46.98 0,22.68 12.6,41.22 36.36,41.22 16.2,0 21.6,-10.26 26.82,-16.92 0,8.1 -0.18,10.8 -0.18,13.5 l 27.72,0 0,-4.86 c -3.24,0 -9.18,-1.08 -10.26,-2.7 -1.44,-2.16 -1.62,-5.22 -1.62,-11.7 l 0,-76.32 c 0,-10.98 0,-28.8 1.44,-40.68 l -18.18,9.18 c 0.72,0.9 1.08,3.06 1.08,6.48 l 0,81.9 c 0,9.36 -1.8,17.82 -6.12,23.04 -3.78,4.86 -9,8.82 -16.74,8.82 -21.78,0 -24.48,-16.92 -24.48,-36.18 z"/>
|
59 |
+
<path d="m 642.85122,360.72507 1.98,6.66 47.16,0 c 0.36,-2.7 0.54,-5.4 0.54,-7.92 0,-19.98 -12.24,-34.56 -34.74,-34.56 -23.94,0 -39.6,19.44 -39.6,45.72 0,23.76 15.66,41.4 39.06,41.4 11.16,0 25.2,-2.16 32.04,-10.08 l -5.4,-3.96 c -7.38,4.14 -12.42,5.22 -18.72,5.22 -20.88,0 -30.06,-14.58 -30.06,-35.82 0,-14.4 3.24,-36.9 21.24,-36.9 14.76,0 20.16,12.42 20.16,30.24 l -33.66,0 z"/>
|
60 |
+
</g>
|
61 |
+
</g>
|
62 |
+
</svg><br>
|
63 |
+
|
64 |
+
<small>Made with Herzblut in Berlin</small>
|
65 |
+
</a>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
|
69 |
+
|
70 |
+
<div id="summary">
|
71 |
+
<?php echo $this->getChildHtml('summery'); ?>
|
72 |
+
</div>
|
73 |
+
|
74 |
+
<div id="content" class="container">
|
75 |
+
<div id="main">
|
76 |
+
<div id="collector-wrapper">
|
77 |
+
<div id="collector-content">
|
78 |
+
<?php echo $this->getChildHtml('content'); ?>
|
79 |
+
</div>
|
80 |
+
</div>
|
81 |
+
<?php echo $this->getChildHtml('left'); ?>
|
82 |
+
</div>
|
83 |
+
</div>
|
84 |
+
|
85 |
+
|
86 |
+
</body>
|
87 |
+
</html>
|
app/design/frontend/base/default/template/ecocode_profiler/layout/sidebar.phtml
ADDED
@@ -0,0 +1,103 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Profile $profile */
|
3 |
+
$profile = Mage::registry('current_profile');
|
4 |
+
|
5 |
+
$request = $this->getRequest();
|
6 |
+
$token = false;
|
7 |
+
if ($profile && $profile->getToken()) {
|
8 |
+
$token = $profile->getToken();
|
9 |
+
}
|
10 |
+
?>
|
11 |
+
|
12 |
+
<div id="sidebar">
|
13 |
+
<div id="sidebar-shortcuts">
|
14 |
+
<div class="shortcuts">
|
15 |
+
<a href="#" class="visible-small"
|
16 |
+
onclick="Sfjs.toggleClass(document.getElementById('sidebar'), 'expanded'); return false;">
|
17 |
+
<span class="icon">
|
18 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" xml:space="preserve">
|
19 |
+
<path fill="#AAAAAA" d="m 2.571,17.5 18.859,0 c 0.87,0 1.57,0.7 1.57,1.57 l 0,1.57 c 0,0.87 -0.7,1.57 -1.57,1.57 l -18.859,0 C 1.702,22.21 1,21.51 1,20.64 L 1,19.07 C 1,18.2 1.702,17.5 2.571,17.5 Z M 1,11.21 1,12.79 c 0,0.86 0.702,1.56 1.571,1.56 l 18.859,0 c 0.87,0 1.57,-0.7 1.57,-1.56 l 0,-1.58 C 23,10.35 22.3,9.644 21.43,9.644 l -18.859,0 C 1.702,9.644 1,10.35 1,11.21 Z M 1,3.357 1,4.929 c 0,0.869 0.702,1.572 1.571,1.572 l 18.859,0 C 22.3,6.501 23,5.798 23,4.929 L 23,3.357 C 23,2.489 22.3,1.786 21.43,1.786 l -18.859,0 C 1.702,1.786 1,2.489 1,3.357 Z" />
|
20 |
+
</svg>
|
21 |
+
</span>
|
22 |
+
</a>
|
23 |
+
|
24 |
+
<a class="btn btn-sm" href="<?php echo Mage::getUrl('_profiler/index/search', ['limit' => 10])?>">Last 10</a>
|
25 |
+
<a class="btn btn-sm"
|
26 |
+
href="<?php echo Mage::helper('ecocode_profiler')->getUrl('latest'); ?>">Latest</a>
|
27 |
+
|
28 |
+
<a class="sf-toggle btn btn-sm" data-toggle-selector="#sidebar-search" <?php echo $token ?: 'data-toggle-initial="display"'?>>
|
29 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24"
|
30 |
+
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
31 |
+
<path fill="#AAAAAA" d="M11.61,0.357c-4.4,0-7.98,3.58-7.98,7.98c0,1.696,0.526,3.308,1.524,4.679l-4.374,4.477
|
32 |
+
c-0.238,0.238-0.369,0.554-0.369,0.891c0,0.336,0.131,0.653,0.369,0.891c0.238,0.238,0.554,0.369,0.891,0.369
|
33 |
+
c0.336,0,0.653-0.131,0.893-0.371l4.372-4.475c1.369,0.996,2.98,1.521,4.674,1.521c4.4,0,7.98-3.58,7.98-7.98
|
34 |
+
S16.01,0.357,11.61,0.357z M17.07,8.337c0,3.011-2.449,5.46-5.46,5.46c-3.011,0-5.46-2.449-5.46-5.46s2.449-5.46,5.46-5.46
|
35 |
+
C14.62,2.877,17.07,5.326,17.07,8.337z"/>
|
36 |
+
</svg>
|
37 |
+
<span class="hidden-small">Search</span>
|
38 |
+
</a>
|
39 |
+
|
40 |
+
<!--{{ render(path('_profiler_search_bar', request.query.all)) }}-->
|
41 |
+
<div id="sidebar-search">
|
42 |
+
<form action="<?php echo Mage::getUrl('_profiler/index/search', [])?>" method="get">
|
43 |
+
<div class="form-group">
|
44 |
+
<label for="ip">IP</label>
|
45 |
+
<input type="text" name="ip" id="ip" value="<?php echo $request->getParam('ip');?> ">
|
46 |
+
</div>
|
47 |
+
|
48 |
+
<div class="form-group">
|
49 |
+
<label for="method">Method</label>
|
50 |
+
<select name="method" id="method">
|
51 |
+
<option value="">Any</option>
|
52 |
+
<?php foreach (['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT'] as $m):?>
|
53 |
+
<option <?php echo $request->getParam('method') === $m ? 'selected="selected"' : ''?>><?php echo $m?></option>
|
54 |
+
<?php endforeach;?>
|
55 |
+
</select>
|
56 |
+
</div>
|
57 |
+
|
58 |
+
<div class="form-group">
|
59 |
+
<label for="status_code">Status</label>
|
60 |
+
<input type="number" name="status_code" id="status_code" value="<?php echo $request->getParam('status_code');?>">
|
61 |
+
</div>
|
62 |
+
|
63 |
+
<div class="form-group">
|
64 |
+
<label for="url">URL</label>
|
65 |
+
<input type="text" name="url" id="url" value="<?php echo $request->getParam('url');?>">
|
66 |
+
</div>
|
67 |
+
|
68 |
+
<div class="form-group">
|
69 |
+
<label for="token">Token</label>
|
70 |
+
<input type="text" name="_token" id="token" value="<?php echo $request->getParam('_token');?>">
|
71 |
+
</div>
|
72 |
+
|
73 |
+
<div class="form-group">
|
74 |
+
<label for="start">From</label>
|
75 |
+
<input type="date" name="start" id="start" value="<?php echo $request->getParam('start');?>">
|
76 |
+
</div>
|
77 |
+
|
78 |
+
<div class="form-group">
|
79 |
+
<label for="end">Until</label>
|
80 |
+
<input type="date" name="end" id="end" value="<?php echo $request->getParam('end');?>">
|
81 |
+
</div>
|
82 |
+
|
83 |
+
<div class="form-group">
|
84 |
+
<label for="limit">Results</label>
|
85 |
+
<select name="limit" id="limit">
|
86 |
+
<?php foreach ([10, 50, 100] as $l):?>
|
87 |
+
<option <?php echo $request->getParam('limit') === $l ? 'selected="selected"' : ''?>><?php echo $l?></option>
|
88 |
+
<?php endforeach;?>
|
89 |
+
</select>
|
90 |
+
</div>
|
91 |
+
|
92 |
+
<div class="form-group">
|
93 |
+
<button type="submit" class="btn btn-sm">Search</button>
|
94 |
+
</div>
|
95 |
+
</form>
|
96 |
+
</div>
|
97 |
+
</div>
|
98 |
+
</div>
|
99 |
+
|
100 |
+
<ul id="menu-profiler">
|
101 |
+
<?php echo $this->getChildHtml('menu'); ?>
|
102 |
+
</ul>
|
103 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/layout/sidebar/menu.phtml
ADDED
@@ -0,0 +1,22 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php /** @var Ecocode_Profiler_Block_Profiler_Sidebar_Menu $this */ ?>
|
2 |
+
<?php
|
3 |
+
if (!$this->getProfile()) {
|
4 |
+
return '';
|
5 |
+
}
|
6 |
+
$token = $this->getProfile()->getToken();
|
7 |
+
$panel = Mage::registry('current_panel');
|
8 |
+
$helper = Mage::helper('ecocode_profiler');
|
9 |
+
?>
|
10 |
+
<?php foreach ($this->getMenuBlocks() as $name => $block): ?>
|
11 |
+
<?php
|
12 |
+
/** @var Ecocode_Profiler_Block_Collector_Base $block */
|
13 |
+
/** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */
|
14 |
+
$collector = $block->getCollector();
|
15 |
+
$url = $helper->getUrl($token, $name);
|
16 |
+
?>
|
17 |
+
<li class="<?php echo $name ?> <?php echo $name === $panel ? 'selected' : '' ?>">
|
18 |
+
<a href="<?php echo $url ?>"><?php echo $block->toHtml(); ?></a>
|
19 |
+
</li>
|
20 |
+
|
21 |
+
<?php endforeach; ?>
|
22 |
+
|
app/design/frontend/base/default/template/ecocode_profiler/profiler/base.css.phtml
ADDED
@@ -0,0 +1,935 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
$colors = [
|
3 |
+
'success' => '#4F805D',
|
4 |
+
'warning' => '#A46A1F',
|
5 |
+
'error' => '#B0413E'
|
6 |
+
]
|
7 |
+
?>
|
8 |
+
html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}
|
9 |
+
|
10 |
+
body {
|
11 |
+
background-color: #F9F9F9;
|
12 |
+
color: #222;
|
13 |
+
font-family: Helvetica, Arial, sans-serif;
|
14 |
+
font-size: 14px;
|
15 |
+
line-height: 1.4;
|
16 |
+
}
|
17 |
+
|
18 |
+
.logo-ecocode{
|
19 |
+
float: right;
|
20 |
+
}
|
21 |
+
|
22 |
+
.logo-ecocode{
|
23 |
+
float: right;
|
24 |
+
text-align: center;
|
25 |
+
padding: 0 10px;
|
26 |
+
}
|
27 |
+
.logo-ecocode a{
|
28 |
+
color: #CCC;
|
29 |
+
}
|
30 |
+
|
31 |
+
|
32 |
+
h2, h3, h4 {
|
33 |
+
font-weight: 500;
|
34 |
+
margin: 1.5em 0 .5em;
|
35 |
+
}
|
36 |
+
h2 + h3,
|
37 |
+
h3 + h4 {
|
38 |
+
margin-top: 1em;
|
39 |
+
}
|
40 |
+
h2 {
|
41 |
+
font-size: 24px;
|
42 |
+
}
|
43 |
+
h3 {
|
44 |
+
font-size: 21px;
|
45 |
+
}
|
46 |
+
h4 {
|
47 |
+
font-size: 18px;
|
48 |
+
}
|
49 |
+
h2 span, h3 span, h4 span,
|
50 |
+
h2 small, h3 small, h4 small {
|
51 |
+
color: #999;
|
52 |
+
}
|
53 |
+
|
54 |
+
li {
|
55 |
+
margin-bottom: 10px;
|
56 |
+
}
|
57 |
+
|
58 |
+
p {
|
59 |
+
font-size: 16px;
|
60 |
+
margin-bottom: 1em;
|
61 |
+
}
|
62 |
+
|
63 |
+
a {
|
64 |
+
color: #218BC3;
|
65 |
+
text-decoration: none;
|
66 |
+
}
|
67 |
+
a:hover {
|
68 |
+
text-decoration: underline;
|
69 |
+
}
|
70 |
+
a.link-inverse {
|
71 |
+
text-decoration: underline;
|
72 |
+
}
|
73 |
+
a.link-inverse:hover {
|
74 |
+
text-decoration: none;
|
75 |
+
}
|
76 |
+
a:active,
|
77 |
+
a:hover {
|
78 |
+
outline: 0;
|
79 |
+
}
|
80 |
+
h2 a,
|
81 |
+
h3 a,
|
82 |
+
h4 a {
|
83 |
+
text-decoration: underline;
|
84 |
+
}
|
85 |
+
h2 a:hover,
|
86 |
+
h3 a:hover,
|
87 |
+
h4 a:hover {
|
88 |
+
text-decoration: none;
|
89 |
+
}
|
90 |
+
|
91 |
+
abbr {
|
92 |
+
border-bottom: 1px dotted #444;
|
93 |
+
cursor: help;
|
94 |
+
}
|
95 |
+
|
96 |
+
code, pre {
|
97 |
+
font-family: Helvetica, Arial, sans-serif;
|
98 |
+
}
|
99 |
+
|
100 |
+
button {
|
101 |
+
font-family: Helvetica, Arial, sans-serif;
|
102 |
+
}
|
103 |
+
.btn {
|
104 |
+
background: #777;
|
105 |
+
border-radius: 2px;
|
106 |
+
border: 0;
|
107 |
+
color: #F5F5F5;
|
108 |
+
display: inline-block;
|
109 |
+
padding: .5em .75em;
|
110 |
+
}
|
111 |
+
.btn:hover {
|
112 |
+
cursor: pointer;
|
113 |
+
opacity: 0.8;
|
114 |
+
text-decoration: none;
|
115 |
+
}
|
116 |
+
.btn-sm {
|
117 |
+
font-size: 12px;
|
118 |
+
}
|
119 |
+
.btn-sm svg {
|
120 |
+
height: 16px;
|
121 |
+
width: 16px;
|
122 |
+
vertical-align: middle;
|
123 |
+
}
|
124 |
+
.btn-link {
|
125 |
+
border-color: transparent;
|
126 |
+
color: #218BC3;
|
127 |
+
text-decoration: none;
|
128 |
+
background-color: transparent;
|
129 |
+
outline: none;
|
130 |
+
border: 0;
|
131 |
+
padding: 0;
|
132 |
+
}
|
133 |
+
.btn-link:hover {
|
134 |
+
text-decoration: underline;
|
135 |
+
}
|
136 |
+
|
137 |
+
table, tr, th, td {
|
138 |
+
background: #FFF;
|
139 |
+
border-collapse: collapse;
|
140 |
+
line-height: 1.5;
|
141 |
+
vertical-align: top;
|
142 |
+
}
|
143 |
+
table {
|
144 |
+
background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2);;
|
145 |
+
margin: 1em 0;
|
146 |
+
width: 100%;
|
147 |
+
}
|
148 |
+
|
149 |
+
table th, table td {
|
150 |
+
padding: 8px 10px;
|
151 |
+
}
|
152 |
+
|
153 |
+
table th {
|
154 |
+
font-weight: bold;
|
155 |
+
text-align: left;
|
156 |
+
}
|
157 |
+
table thead th {
|
158 |
+
background-color: #E0E0E0;
|
159 |
+
}
|
160 |
+
table thead th.key {
|
161 |
+
width: 19%;
|
162 |
+
}
|
163 |
+
|
164 |
+
table tbody th,
|
165 |
+
table tbody td {
|
166 |
+
font-family: Helvetica, Arial, sans-serif;
|
167 |
+
border: 1px solid #E0E0E0;
|
168 |
+
border-width: 1px 0;
|
169 |
+
}
|
170 |
+
|
171 |
+
table tbody td {
|
172 |
+
word-break: break-all; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto;
|
173 |
+
}
|
174 |
+
|
175 |
+
table tbody div {
|
176 |
+
margin: .25em 0;
|
177 |
+
}
|
178 |
+
table tbody ul {
|
179 |
+
margin: 0;
|
180 |
+
padding: 0 0 0 1em;
|
181 |
+
}
|
182 |
+
|
183 |
+
.block {
|
184 |
+
display: block;
|
185 |
+
}
|
186 |
+
.hidden {
|
187 |
+
display: none;
|
188 |
+
}
|
189 |
+
.nowrap {
|
190 |
+
white-space: pre;
|
191 |
+
}
|
192 |
+
.newline {
|
193 |
+
display: block;
|
194 |
+
}
|
195 |
+
.break-long-words {
|
196 |
+
word-break: break-all; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto;
|
197 |
+
}
|
198 |
+
.text-small {
|
199 |
+
font-size: 12px !important;
|
200 |
+
}
|
201 |
+
.text-muted {
|
202 |
+
color: #999;
|
203 |
+
}
|
204 |
+
.text-bold {
|
205 |
+
font-weight: bold;
|
206 |
+
}
|
207 |
+
.text-right {
|
208 |
+
text-align: right;
|
209 |
+
}
|
210 |
+
.text-center {
|
211 |
+
text-align: center;
|
212 |
+
}
|
213 |
+
.font-normal {
|
214 |
+
font-family: Helvetica, Arial, sans-serif;
|
215 |
+
font-size: 14px;
|
216 |
+
}
|
217 |
+
.help {
|
218 |
+
color: #999;
|
219 |
+
font-size: 14px;
|
220 |
+
margin-bottom: .5em;
|
221 |
+
}
|
222 |
+
.empty {
|
223 |
+
border: 4px dashed #E0E0E0;
|
224 |
+
color: #999;
|
225 |
+
margin: 1em 0;
|
226 |
+
padding: .5em 2em;
|
227 |
+
}
|
228 |
+
|
229 |
+
.label {
|
230 |
+
background-color: #666;
|
231 |
+
color: #FAFAFA;
|
232 |
+
display: inline-block;
|
233 |
+
font-size: 12px;
|
234 |
+
font-weight: bold;
|
235 |
+
padding: 3px 7px;
|
236 |
+
white-space: nowrap;
|
237 |
+
}
|
238 |
+
.label.same-width {
|
239 |
+
min-width: 70px;
|
240 |
+
text-align: center;
|
241 |
+
}
|
242 |
+
.label.status-success { background: <?php echo $colors['success']; ?>; color: #FFF; }
|
243 |
+
.label.status-warning { background: <?php echo $colors['warning']; ?>; color: #FFF; }
|
244 |
+
.label.status-error { background: <?php echo $colors['error']; ?>; color: #FFF; }
|
245 |
+
|
246 |
+
.metrics {
|
247 |
+
margin: 1em 0;
|
248 |
+
overflow: auto;
|
249 |
+
}
|
250 |
+
.metrics .metric {
|
251 |
+
float: left;
|
252 |
+
margin-right: 1em;
|
253 |
+
}
|
254 |
+
|
255 |
+
.metric {
|
256 |
+
background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2);
|
257 |
+
min-width: 100px;
|
258 |
+
min-height: 70px;
|
259 |
+
}
|
260 |
+
.metric .value {
|
261 |
+
display: block;
|
262 |
+
font-size: 28px;
|
263 |
+
padding: 8px 15px 4px;
|
264 |
+
text-align: center;
|
265 |
+
}
|
266 |
+
.metric .value svg {
|
267 |
+
margin: 5px 0 -5px;
|
268 |
+
}
|
269 |
+
.metric .unit {
|
270 |
+
color: #999;
|
271 |
+
font-size: 18px;
|
272 |
+
margin-left: -4px;
|
273 |
+
}
|
274 |
+
.metric .label {
|
275 |
+
background: #E0E0E0;
|
276 |
+
color: #222;
|
277 |
+
display: block;
|
278 |
+
font-size: 12px;
|
279 |
+
padding: 5px;
|
280 |
+
text-align: center;
|
281 |
+
}
|
282 |
+
|
283 |
+
.metrics-horizontal .metric {
|
284 |
+
min-height: 0;
|
285 |
+
min-width: 0;
|
286 |
+
}
|
287 |
+
.metrics-horizontal .metric .value,
|
288 |
+
.metrics-horizontal .metric .label {
|
289 |
+
display: inline;
|
290 |
+
padding: 2px 6px;
|
291 |
+
}
|
292 |
+
.metrics-horizontal .metric .label {
|
293 |
+
display: inline-block;
|
294 |
+
padding: 6px;
|
295 |
+
}
|
296 |
+
.metrics-horizontal .metric .value {
|
297 |
+
font-size: 16px;
|
298 |
+
}
|
299 |
+
.metrics-horizontal .metric .value svg {
|
300 |
+
max-height: 14px;
|
301 |
+
line-height: 10px;
|
302 |
+
margin: 0;
|
303 |
+
padding-left: 4px;
|
304 |
+
vertical-align: middle;
|
305 |
+
}
|
306 |
+
|
307 |
+
.card {
|
308 |
+
background: #FFF; border: 1px solid #E0E0E0; box-shadow: 0px 0px 1px rgba(128, 128, 128, .2);;
|
309 |
+
margin: 1em 0;
|
310 |
+
padding: 10px;
|
311 |
+
}
|
312 |
+
.card-block + .card-block {
|
313 |
+
border-top: 1px solid #E0E0E0;
|
314 |
+
padding-top: 10px;
|
315 |
+
}
|
316 |
+
.card *:first-child,
|
317 |
+
.card-block *:first-child {
|
318 |
+
margin-top: 0;
|
319 |
+
}
|
320 |
+
.card .label {
|
321 |
+
background-color: #EEE;
|
322 |
+
color: #222;
|
323 |
+
}
|
324 |
+
|
325 |
+
.status-success {
|
326 |
+
background: rgba(94, 151, 110, 0.3);
|
327 |
+
}
|
328 |
+
.status-warning {
|
329 |
+
background: rgba(240, 181, 24, 0.3);
|
330 |
+
}
|
331 |
+
.status-error {
|
332 |
+
background: rgba(176, 65, 62, 0.2);
|
333 |
+
}
|
334 |
+
.status-success td,
|
335 |
+
.status-warning td,
|
336 |
+
.status-error td {
|
337 |
+
background: transparent;
|
338 |
+
}
|
339 |
+
tr.status-error td,
|
340 |
+
tr.status-warning td {
|
341 |
+
border-bottom: 1px solid #FAFAFA;
|
342 |
+
border-top: 1px solid #FAFAFA;
|
343 |
+
}
|
344 |
+
|
345 |
+
.status-warning .colored {
|
346 |
+
color: <?php echo $colors['warning']; ?>;
|
347 |
+
}
|
348 |
+
.status-error .colored {
|
349 |
+
color: <?php echo $colors['error']; ?>;
|
350 |
+
}
|
351 |
+
|
352 |
+
.highlight pre {
|
353 |
+
margin: 0;
|
354 |
+
white-space: pre-wrap;
|
355 |
+
}
|
356 |
+
|
357 |
+
.highlight .keyword { color: #8959A8; font-weight: bold; }
|
358 |
+
.highlight .word { color: #222222; }
|
359 |
+
.highlight .variable { color: #916319; }
|
360 |
+
.highlight .symbol { color: #222222; }
|
361 |
+
.highlight .comment { color: #999999; }
|
362 |
+
.highlight .backtick { color: #718C00; }
|
363 |
+
.highlight .string { color: #718C00; }
|
364 |
+
.highlight .number { color: #F5871F; font-weight: bold; }
|
365 |
+
.highlight .error { color: #C82829; }
|
366 |
+
|
367 |
+
.sf-icon {
|
368 |
+
vertical-align: middle;
|
369 |
+
background-repeat: no-repeat;
|
370 |
+
background-size: contain;
|
371 |
+
width: 16px;
|
372 |
+
height: 16px;
|
373 |
+
display: inline-block;
|
374 |
+
}
|
375 |
+
.sf-icon svg {
|
376 |
+
width: 16px;
|
377 |
+
height: 16px;
|
378 |
+
}
|
379 |
+
.sf-icon.sf-medium,
|
380 |
+
.sf-icon.sf-medium svg {
|
381 |
+
width: 24px;
|
382 |
+
height: 24px;
|
383 |
+
}
|
384 |
+
.sf-icon.sf-large,
|
385 |
+
.sf-icon.sf-large svg {
|
386 |
+
width: 32px;
|
387 |
+
height: 32px;
|
388 |
+
}
|
389 |
+
|
390 |
+
|
391 |
+
.container {
|
392 |
+
max-width: 1300px;
|
393 |
+
padding-right: 15px;
|
394 |
+
}
|
395 |
+
#content {
|
396 |
+
min-height: 1024px;
|
397 |
+
overflow: hidden;
|
398 |
+
}
|
399 |
+
#collector-wrapper {
|
400 |
+
float: left;
|
401 |
+
width: 100%;
|
402 |
+
}
|
403 |
+
#collector-content {
|
404 |
+
margin: 0 0 30px 220px;
|
405 |
+
padding: 14px 0 14px 20px;
|
406 |
+
}
|
407 |
+
|
408 |
+
#main h2:first-of-type {
|
409 |
+
margin-top: 0;
|
410 |
+
}
|
411 |
+
|
412 |
+
#header {
|
413 |
+
background-color: #222;
|
414 |
+
overflow: hidden;
|
415 |
+
}
|
416 |
+
#header h1 {
|
417 |
+
color: #FFF;
|
418 |
+
font-weight: normal;
|
419 |
+
font-size: 21px;
|
420 |
+
float: left;
|
421 |
+
margin: 0;
|
422 |
+
padding: 10px 10px 8px;
|
423 |
+
}
|
424 |
+
#header h1 span {
|
425 |
+
color: #CCC;
|
426 |
+
}
|
427 |
+
#header h1 svg {
|
428 |
+
height: 40px;
|
429 |
+
width: 40px;
|
430 |
+
margin-top: -4px;
|
431 |
+
vertical-align: middle;
|
432 |
+
}
|
433 |
+
#header h1 svg path {
|
434 |
+
fill: #FFF;
|
435 |
+
}
|
436 |
+
#header .search {
|
437 |
+
float: right;
|
438 |
+
padding-top: 11px;
|
439 |
+
}
|
440 |
+
#header .search input {
|
441 |
+
border: 1px solid #DDD;
|
442 |
+
margin-right: 4px;
|
443 |
+
padding: 7px 8px;
|
444 |
+
width: 200px;
|
445 |
+
}
|
446 |
+
|
447 |
+
#summary .status {
|
448 |
+
background: #E0E0E0;
|
449 |
+
border: solid rgba(0, 0, 0, 0.1);
|
450 |
+
border-width: 2px 0;
|
451 |
+
padding: 10px;
|
452 |
+
}
|
453 |
+
#summary h2,
|
454 |
+
#summary h2 a {
|
455 |
+
color: #222;
|
456 |
+
font-size: 21px;
|
457 |
+
margin: 0;
|
458 |
+
text-decoration: none;
|
459 |
+
}
|
460 |
+
#summary h2 a:hover {
|
461 |
+
text-decoration: underline;
|
462 |
+
}
|
463 |
+
|
464 |
+
#summary .status-success { background: <?php echo $colors['success']; ?>; }
|
465 |
+
#summary .status-warning { background: <?php echo $colors['warning']; ?>; }
|
466 |
+
#summary .status-error { background: <?php echo $colors['error']; ?>; }
|
467 |
+
|
468 |
+
#summary .status-success h2,
|
469 |
+
#summary .status-success a,
|
470 |
+
#summary .status-warning h2,
|
471 |
+
#summary .status-warning a,
|
472 |
+
#summary .status-error h2,
|
473 |
+
#summary .status-error a {
|
474 |
+
color: #FFF;
|
475 |
+
}
|
476 |
+
|
477 |
+
#summary dl.metadata {
|
478 |
+
margin: 5px 0 0;
|
479 |
+
color: rgba(255, 255, 255, 0.75);
|
480 |
+
}
|
481 |
+
#summary dl.metadata dt,
|
482 |
+
#summary dl.metadata dd {
|
483 |
+
display: inline-block;
|
484 |
+
font-size: 13px;
|
485 |
+
}
|
486 |
+
#summary dl.metadata dt {
|
487 |
+
font-weight: bold;
|
488 |
+
}
|
489 |
+
#summary dl.metadata dt:after {
|
490 |
+
content: ':';
|
491 |
+
}
|
492 |
+
#summary dl.metadata dd {
|
493 |
+
margin: 0 1.5em 0 0;
|
494 |
+
}
|
495 |
+
|
496 |
+
#summary dl.metadata .label {
|
497 |
+
background: rgba(255, 255, 255, 0.2);
|
498 |
+
}
|
499 |
+
|
500 |
+
#sidebar {
|
501 |
+
background: #444;
|
502 |
+
color: #CCC;
|
503 |
+
float: left;
|
504 |
+
margin-bottom: -99999px;
|
505 |
+
margin-left: -100%;
|
506 |
+
padding-bottom: 99999px;
|
507 |
+
position: relative;
|
508 |
+
width: 220px;
|
509 |
+
z-index: 9999;
|
510 |
+
}
|
511 |
+
#sidebar .module {
|
512 |
+
padding: 10px;
|
513 |
+
width: 220px;
|
514 |
+
}
|
515 |
+
|
516 |
+
#sidebar #sidebar-shortcuts {
|
517 |
+
background: #333;
|
518 |
+
width: 220px;
|
519 |
+
}
|
520 |
+
#sidebar #sidebar-shortcuts .shortcuts {
|
521 |
+
position: relative;
|
522 |
+
padding: 16px 10px;
|
523 |
+
}
|
524 |
+
#sidebar-shortcuts .icon {
|
525 |
+
display: block;
|
526 |
+
float: left;
|
527 |
+
width: 50px;
|
528 |
+
margin: 2px 0 0 -10px;
|
529 |
+
text-align: center;
|
530 |
+
}
|
531 |
+
#sidebar #sidebar-shortcuts .btn {
|
532 |
+
color: #F5F5F5;
|
533 |
+
}
|
534 |
+
#sidebar #sidebar-shortcuts .btn + .btn {
|
535 |
+
margin-left: 5px;
|
536 |
+
}
|
537 |
+
#sidebar #sidebar-shortcuts .btn {
|
538 |
+
padding: .5em;
|
539 |
+
}
|
540 |
+
|
541 |
+
#sidebar-search .form-group:first-of-type {
|
542 |
+
padding-top: 20px;
|
543 |
+
}
|
544 |
+
#sidebar-search .form-group {
|
545 |
+
clear: both;
|
546 |
+
overflow: hidden;
|
547 |
+
padding-bottom: 10px;
|
548 |
+
}
|
549 |
+
#sidebar-search .form-group label {
|
550 |
+
float: left;
|
551 |
+
font-size: 13px;
|
552 |
+
line-height: 24px;
|
553 |
+
width: 60px;
|
554 |
+
}
|
555 |
+
#sidebar-search .form-group input,
|
556 |
+
#sidebar-search .form-group select {
|
557 |
+
float: left;
|
558 |
+
font-size: 13px;
|
559 |
+
padding: 3px 6px;
|
560 |
+
}
|
561 |
+
#sidebar-search .form-group input {
|
562 |
+
background: #CCC;
|
563 |
+
border: 1px solid #999;
|
564 |
+
color: #222;
|
565 |
+
width: 120px;
|
566 |
+
}
|
567 |
+
#sidebar-search .form-group select {
|
568 |
+
color: #222;
|
569 |
+
}
|
570 |
+
#sidebar-search .form-group .btn {
|
571 |
+
float: right;
|
572 |
+
margin-right: 10px;
|
573 |
+
}
|
574 |
+
|
575 |
+
#menu-profiler {
|
576 |
+
margin: 0;
|
577 |
+
padding: 0;
|
578 |
+
list-style-type: none;
|
579 |
+
}
|
580 |
+
#menu-profiler li {
|
581 |
+
position: relative;
|
582 |
+
margin-bottom: 0;
|
583 |
+
width: 220px;
|
584 |
+
}
|
585 |
+
#menu-profiler li a {
|
586 |
+
border: solid transparent;
|
587 |
+
border-width: 2px 0;
|
588 |
+
color: #CCC;
|
589 |
+
display: block;
|
590 |
+
}
|
591 |
+
#menu-profiler li a:hover {
|
592 |
+
text-decoration: none;
|
593 |
+
}
|
594 |
+
#menu-profiler li a .label {
|
595 |
+
background: transparent;
|
596 |
+
color: #EEE;
|
597 |
+
display: block;
|
598 |
+
padding: 8px 10px 8px 50px;
|
599 |
+
overflow: hidden;
|
600 |
+
white-space: nowrap;
|
601 |
+
}
|
602 |
+
#menu-profiler li a .label .icon {
|
603 |
+
display: block;
|
604 |
+
position: absolute;
|
605 |
+
left: 0;
|
606 |
+
top: 8px;
|
607 |
+
width: 50px;
|
608 |
+
text-align: center;
|
609 |
+
}
|
610 |
+
#menu-profiler .label .icon img,
|
611 |
+
#menu-profiler .label .icon svg {
|
612 |
+
height: 24px;
|
613 |
+
max-width: 24px;
|
614 |
+
}
|
615 |
+
#menu-profiler li a .label .icon svg path {
|
616 |
+
fill: #DDD;
|
617 |
+
}
|
618 |
+
#menu-profiler li a .label strong {
|
619 |
+
font-size: 16px;
|
620 |
+
font-weight: normal;
|
621 |
+
}
|
622 |
+
#menu-profiler li a .label.disabled {
|
623 |
+
opacity: .25;
|
624 |
+
}
|
625 |
+
#menu-profiler li a:hover .label.disabled,
|
626 |
+
#menu-profiler li.selected a .label.disabled {
|
627 |
+
opacity: 1;
|
628 |
+
}
|
629 |
+
|
630 |
+
#menu-profiler li.selected a,
|
631 |
+
#menu-profiler:hover li.selected a:hover,
|
632 |
+
#menu-profiler li a:hover {
|
633 |
+
background: #666;
|
634 |
+
border: solid #555;
|
635 |
+
border-width: 2px 0;
|
636 |
+
}
|
637 |
+
#menu-profiler li.selected a .label,
|
638 |
+
#menu-profiler li a:hover .label {
|
639 |
+
color: #FFF;
|
640 |
+
}
|
641 |
+
#menu-profiler li.selected a .icon svg path,
|
642 |
+
#menu-profiler li a:hover .icon svg path {
|
643 |
+
fill: #FFF;
|
644 |
+
}
|
645 |
+
|
646 |
+
#menu-profiler li a .count {
|
647 |
+
background-color: #666;
|
648 |
+
color: #FFF;
|
649 |
+
display: inline-block;
|
650 |
+
font-weight: bold;
|
651 |
+
min-width: 10px;
|
652 |
+
padding: 2px 6px;
|
653 |
+
position: absolute;
|
654 |
+
right: 10px;
|
655 |
+
text-align: center;
|
656 |
+
vertical-align: baseline;
|
657 |
+
white-space: nowrap;
|
658 |
+
}
|
659 |
+
#menu-profiler li a span.count span {
|
660 |
+
font-size: 12px;
|
661 |
+
|
662 |
+
}
|
663 |
+
#menu-profiler li a span.count span + span::before {
|
664 |
+
content: " / ";
|
665 |
+
color: #AAA;
|
666 |
+
}
|
667 |
+
|
668 |
+
#menu-profiler .label-status-warning .count {
|
669 |
+
background: <?php echo $colors['warning']; ?>;
|
670 |
+
}
|
671 |
+
#menu-profiler .label-status-error .count {
|
672 |
+
background: <?php echo $colors['error']; ?>;
|
673 |
+
}
|
674 |
+
|
675 |
+
#timeline-control {
|
676 |
+
background: #FFF;
|
677 |
+
margin: 1em 0;
|
678 |
+
padding: 10px;
|
679 |
+
}
|
680 |
+
#timeline-control label {
|
681 |
+
font-weight: bold;
|
682 |
+
margin-right: 1em;
|
683 |
+
}
|
684 |
+
#timeline-control input {
|
685 |
+
font-size: 16px;
|
686 |
+
padding: 4px;
|
687 |
+
text-align: right;
|
688 |
+
width: 40px;
|
689 |
+
}
|
690 |
+
#timeline-control .help {
|
691 |
+
margin-left: 1em;
|
692 |
+
}
|
693 |
+
|
694 |
+
.sf-profiler-timeline .legends {
|
695 |
+
font-size: 12px;
|
696 |
+
line-height: 1.5em;
|
697 |
+
}
|
698 |
+
.sf-profiler-timeline .legends span {
|
699 |
+
border-left: solid 14px;
|
700 |
+
padding: 0 10px 0 5px;
|
701 |
+
}
|
702 |
+
.sf-profiler-timeline canvas {
|
703 |
+
border: 1px solid #DDD;
|
704 |
+
background: #FFF;
|
705 |
+
margin: .5em 0;
|
706 |
+
}
|
707 |
+
.sf-profiler-timeline + p.help {
|
708 |
+
margin-top: 0;
|
709 |
+
}
|
710 |
+
|
711 |
+
.tab-navigation {
|
712 |
+
margin: 0 0 1em 0;
|
713 |
+
padding: 0;
|
714 |
+
}
|
715 |
+
.tab-navigation li {
|
716 |
+
background: #FFF;
|
717 |
+
border: 1px solid #DDD;
|
718 |
+
color: #444;
|
719 |
+
cursor: pointer;
|
720 |
+
display: inline-block;
|
721 |
+
font-size: 16px;
|
722 |
+
margin: 0 0 0 -1px;
|
723 |
+
padding: .5em .75em;
|
724 |
+
z-index: 1;
|
725 |
+
}
|
726 |
+
.tab-navigation li:hover {
|
727 |
+
background: #EEE;
|
728 |
+
}
|
729 |
+
.tab-navigation li .badge {
|
730 |
+
background-color: #F5F5F5;
|
731 |
+
color: #777;
|
732 |
+
display: inline-block;
|
733 |
+
font-size: 14px;
|
734 |
+
font-weight: bold;
|
735 |
+
margin-left: 8px;
|
736 |
+
min-width: 10px;
|
737 |
+
padding: 1px 6px;
|
738 |
+
text-align: center;
|
739 |
+
white-space: nowrap;
|
740 |
+
}
|
741 |
+
.tab-navigation li:hover .badge {
|
742 |
+
background: #FAFAFA;
|
743 |
+
color: #777;
|
744 |
+
}
|
745 |
+
.tab-navigation li.disabled {
|
746 |
+
background: #F5F5F5;
|
747 |
+
color: #999;
|
748 |
+
}
|
749 |
+
.tab-navigation li.active {
|
750 |
+
background: #666;
|
751 |
+
border-color: #666;
|
752 |
+
color: #FAFAFA;
|
753 |
+
z-index: 1100;
|
754 |
+
}
|
755 |
+
.tab-navigation li.active .badge {
|
756 |
+
background-color: #444;
|
757 |
+
color: #FFF;
|
758 |
+
}
|
759 |
+
.tab-content > *:first-child {
|
760 |
+
margin-top: 0;
|
761 |
+
}
|
762 |
+
|
763 |
+
.sf-toggle-content {
|
764 |
+
-moz-transition: display .25s ease;
|
765 |
+
-webkit-transition: display .25s ease;
|
766 |
+
transition: display .25s ease;
|
767 |
+
}
|
768 |
+
.sf-toggle-content.sf-toggle-hidden {
|
769 |
+
display: none!important;
|
770 |
+
}
|
771 |
+
.sf-toggle-content.sf-toggle-visible {
|
772 |
+
display: block!important;
|
773 |
+
}
|
774 |
+
|
775 |
+
#twig-dump pre {
|
776 |
+
font-size: 12px;
|
777 |
+
line-height: 1.7;
|
778 |
+
}
|
779 |
+
#twig-dump span {
|
780 |
+
border-radius: 2px;
|
781 |
+
padding: 1px 2px;
|
782 |
+
}
|
783 |
+
#twig-dump .status-error { background: transparent; color: #B0413E; }
|
784 |
+
#twig-dump .status-warning { background: rgba(240, 181, 24, 0.3); }
|
785 |
+
#twig-dump .status-success { background: rgba(100, 189, 99, 0.2); }
|
786 |
+
|
787 |
+
table.logs .metadata {
|
788 |
+
color: #777;
|
789 |
+
display: block;
|
790 |
+
font-size: 12px;
|
791 |
+
padding-top: 4px;
|
792 |
+
}
|
793 |
+
table.logs .metadata strong {
|
794 |
+
color: #222;
|
795 |
+
}
|
796 |
+
table.logs .metadata .context {
|
797 |
+
background: #F5F5F5;
|
798 |
+
color: #222;
|
799 |
+
}
|
800 |
+
table.logs .metadata .context pre {
|
801 |
+
margin: 5px 0;
|
802 |
+
padding: 5px 10px;
|
803 |
+
white-space: pre-wrap;
|
804 |
+
}
|
805 |
+
|
806 |
+
table.logs .sf-call-stack {
|
807 |
+
margin: 1em 0 1em 1.5em;
|
808 |
+
}
|
809 |
+
table.logs .sf-call-stack li {
|
810 |
+
margin-bottom: 5px;
|
811 |
+
}
|
812 |
+
table.logs .sf-call-stack abbr {
|
813 |
+
border: none;
|
814 |
+
}
|
815 |
+
|
816 |
+
.sql-runnable {
|
817 |
+
background: #F5F5F5;
|
818 |
+
margin: .5em 0;
|
819 |
+
padding: 1em;
|
820 |
+
}
|
821 |
+
.queries-table pre {
|
822 |
+
word-break: break-all; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto;
|
823 |
+
margin: 0;
|
824 |
+
white-space: pre-wrap;
|
825 |
+
}
|
826 |
+
|
827 |
+
#collector-content .sf-dump {
|
828 |
+
margin-bottom: 2em;
|
829 |
+
}
|
830 |
+
#collector-content pre.sf-dump,
|
831 |
+
#collector-content .sf-dump code,
|
832 |
+
#collector-content .sf-dump samp {
|
833 |
+
font-family: Helvetica, Arial, sans-serif;
|
834 |
+
}
|
835 |
+
#collector-content pre.sf-dump {
|
836 |
+
background: #222;
|
837 |
+
line-height: 1.4;
|
838 |
+
margin-top: .5em;
|
839 |
+
padding: 1em;
|
840 |
+
}
|
841 |
+
#collector-content .sf-dump h3 {
|
842 |
+
font-size: 18px;
|
843 |
+
margin: .5em 0 0;
|
844 |
+
}
|
845 |
+
#collector-content .sf-dump h3 a {
|
846 |
+
cursor: pointer;
|
847 |
+
}
|
848 |
+
|
849 |
+
#collector-content pre.sf-dump { color: #CC7832; }
|
850 |
+
#collector-content .sf-dump-str { color: #629755; }
|
851 |
+
#collector-content .sf-dump-private,
|
852 |
+
#collector-content .sf-dump-protected,
|
853 |
+
#collector-content .sf-dump-public { color: #E0E0E0; }
|
854 |
+
#collector-content .sf-dump-note { color: #6897BB; }
|
855 |
+
#collector-content .sf-dump-key { color: #A5C261; }
|
856 |
+
|
857 |
+
#collector-content .sf-dump .trace {
|
858 |
+
border: 1px solid #DDD;
|
859 |
+
background: #FFF;
|
860 |
+
padding: 10px;
|
861 |
+
margin: 1em 0;
|
862 |
+
}
|
863 |
+
#collector-content .sf-dump .trace {
|
864 |
+
font-size: 12px;
|
865 |
+
}
|
866 |
+
#collector-content .sf-dump .trace code {
|
867 |
+
font-size: 14px;
|
868 |
+
}
|
869 |
+
#collector-content .sf-dump .trace li {
|
870 |
+
margin-bottom: 0;
|
871 |
+
padding: 5px 0;
|
872 |
+
}
|
873 |
+
#collector-content .sf-dump .trace li.selected {
|
874 |
+
background: rgba(255, 255, 153, 0.5);
|
875 |
+
}
|
876 |
+
|
877 |
+
#search-results td {
|
878 |
+
font-family: Helvetica, Arial, sans-serif;
|
879 |
+
vertical-align: middle;
|
880 |
+
}
|
881 |
+
|
882 |
+
#search-results .sf-search {
|
883 |
+
visibility: hidden;
|
884 |
+
margin-left: 2px;
|
885 |
+
}
|
886 |
+
#search-results tr:hover .sf-search {
|
887 |
+
visibility: visible;
|
888 |
+
}
|
889 |
+
|
890 |
+
.visible-small {
|
891 |
+
display: none;
|
892 |
+
}
|
893 |
+
.hidden-small {
|
894 |
+
display: inherit;
|
895 |
+
}
|
896 |
+
|
897 |
+
@media (max-width: 768px) {
|
898 |
+
#collector-content {
|
899 |
+
margin-left: 50px;
|
900 |
+
}
|
901 |
+
|
902 |
+
#sidebar {
|
903 |
+
width: 50px;
|
904 |
+
overflow-y: hidden;
|
905 |
+
transition: width 200ms ease-out;
|
906 |
+
}
|
907 |
+
#sidebar:hover, #sidebar.expanded {
|
908 |
+
width: 220px;
|
909 |
+
}
|
910 |
+
|
911 |
+
#sidebar-search {
|
912 |
+
display: none;
|
913 |
+
}
|
914 |
+
#sidebar:hover #sidebar-search.sf-toggle-visible, #sidebar.expanded #sidebar-search.sf-toggle-visible {
|
915 |
+
display: block;
|
916 |
+
}
|
917 |
+
|
918 |
+
#sidebar .module {
|
919 |
+
display: none;
|
920 |
+
}
|
921 |
+
#sidebar:hover .module, #sidebar.expanded .module {
|
922 |
+
display: block;
|
923 |
+
}
|
924 |
+
|
925 |
+
.visible-small {
|
926 |
+
display: inherit;
|
927 |
+
}
|
928 |
+
.hidden-small {
|
929 |
+
display: none;
|
930 |
+
}
|
931 |
+
|
932 |
+
.btn-sm svg {
|
933 |
+
margin-left: 2px;
|
934 |
+
}
|
935 |
+
}
|
app/design/frontend/base/default/template/ecocode_profiler/profiler/base.js.phtml
ADDED
@@ -0,0 +1,464 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
$request = Mage::app()->getRequest();
|
3 |
+
$schemeAndHost = $request->getScheme() . '://' . $request->getHttpHost();
|
4 |
+
$this->setData('excluded_ajax_paths', '^/_profiler');
|
5 |
+
?>
|
6 |
+
<?php /* Caution: the contents of this file are processed by Twig before loading
|
7 |
+
them as JavaScript source code. Always use '/*' comments instead
|
8 |
+
of '//' comments to avoid impossible-to-debug side-effects */ ?>
|
9 |
+
|
10 |
+
Sfjs = (function() {
|
11 |
+
"use strict";
|
12 |
+
|
13 |
+
var classListIsSupported = 'classList' in document.documentElement;
|
14 |
+
|
15 |
+
if (classListIsSupported) {
|
16 |
+
var hasClass = function (el, cssClass) { return el.classList.contains(cssClass); };
|
17 |
+
var removeClass = function(el, cssClass) { el.classList.remove(cssClass); };
|
18 |
+
var addClass = function(el, cssClass) { el.classList.add(cssClass); };
|
19 |
+
var toggleClass = function(el, cssClass) { el.classList.toggle(cssClass); };
|
20 |
+
} else {
|
21 |
+
var hasClass = function (el, cssClass) { return el.className.match(new RegExp('\\b' + cssClass + '\\b')); };
|
22 |
+
var removeClass = function(el, cssClass) { el.className = el.className.replace(new RegExp('\\b' + cssClass + '\\b'), ' '); };
|
23 |
+
var addClass = function(el, cssClass) { if (!hasClass(el, cssClass)) { el.className += " " + cssClass; } };
|
24 |
+
var toggleClass = function(el, cssClass) { hasClass(el, cssClass) ? removeClass(el, cssClass) : addClass(el, cssClass); };
|
25 |
+
}
|
26 |
+
|
27 |
+
var noop = function() {},
|
28 |
+
|
29 |
+
collectionToArray = function (collection) {
|
30 |
+
var length = collection.length || 0,
|
31 |
+
results = new Array(length);
|
32 |
+
|
33 |
+
while (length--) {
|
34 |
+
results[length] = collection[length];
|
35 |
+
}
|
36 |
+
|
37 |
+
return results;
|
38 |
+
},
|
39 |
+
|
40 |
+
profilerStorageKey = 'sf2/profiler/',
|
41 |
+
|
42 |
+
request = function(url, onSuccess, onError, payload, options) {
|
43 |
+
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
|
44 |
+
options = options || {};
|
45 |
+
options.maxTries = options.maxTries || 0;
|
46 |
+
xhr.open(options.method || 'GET', url, true);
|
47 |
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
48 |
+
xhr.onreadystatechange = function(state) {
|
49 |
+
if (4 !== xhr.readyState) {
|
50 |
+
return null;
|
51 |
+
}
|
52 |
+
|
53 |
+
if (xhr.status == 404 && options.maxTries > 1) {
|
54 |
+
setTimeout(function(){
|
55 |
+
options.maxTries--;
|
56 |
+
request(url, onSuccess, onError, payload, options);
|
57 |
+
}, 500);
|
58 |
+
|
59 |
+
return null;
|
60 |
+
}
|
61 |
+
|
62 |
+
if (200 === xhr.status) {
|
63 |
+
(onSuccess || noop)(xhr);
|
64 |
+
} else {
|
65 |
+
(onError || noop)(xhr);
|
66 |
+
}
|
67 |
+
};
|
68 |
+
xhr.send(payload || '');
|
69 |
+
},
|
70 |
+
|
71 |
+
getPreference = function(name) {
|
72 |
+
if (!window.localStorage) {
|
73 |
+
return null;
|
74 |
+
}
|
75 |
+
|
76 |
+
return localStorage.getItem(profilerStorageKey + name);
|
77 |
+
},
|
78 |
+
|
79 |
+
setPreference = function(name, value) {
|
80 |
+
if (!window.localStorage) {
|
81 |
+
return null;
|
82 |
+
}
|
83 |
+
|
84 |
+
localStorage.setItem(profilerStorageKey + name, value);
|
85 |
+
},
|
86 |
+
|
87 |
+
requestStack = [],
|
88 |
+
|
89 |
+
extractHeaders = function(xhr, stackElement) {
|
90 |
+
/* Here we avoid to call xhr.getResponseHeader in order to */
|
91 |
+
/* prevent polluting the console with CORS security errors */
|
92 |
+
var allHeaders = xhr.getAllResponseHeaders();
|
93 |
+
var ret;
|
94 |
+
console.log(allHeaders);
|
95 |
+
if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) {
|
96 |
+
stackElement.profile = ret[1];
|
97 |
+
}
|
98 |
+
if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) {
|
99 |
+
stackElement.profilerUrl = ret[1];
|
100 |
+
}
|
101 |
+
},
|
102 |
+
|
103 |
+
renderAjaxRequests = function() {
|
104 |
+
var requestCounter = document.querySelectorAll('.sf-toolbar-ajax-requests');
|
105 |
+
if (!requestCounter.length) {
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
|
109 |
+
var ajaxToolbarPanel = document.querySelector('.sf-toolbar-block-ajax');
|
110 |
+
var tbodies = document.querySelectorAll('.sf-toolbar-ajax-request-list');
|
111 |
+
var state = 'ok';
|
112 |
+
if (tbodies.length) {
|
113 |
+
var tbody = tbodies[0];
|
114 |
+
|
115 |
+
var rows = document.createDocumentFragment();
|
116 |
+
if (requestStack.length) {
|
117 |
+
for (var i = 0; i < requestStack.length; i++) {
|
118 |
+
var request = requestStack[i];
|
119 |
+
|
120 |
+
var row = document.createElement('tr');
|
121 |
+
rows.insertBefore(row, rows.firstChild);
|
122 |
+
|
123 |
+
var methodCell = document.createElement('td');
|
124 |
+
if (request.error) {
|
125 |
+
methodCell.className = 'sf-ajax-request-error';
|
126 |
+
}
|
127 |
+
methodCell.textContent = request.method;
|
128 |
+
row.appendChild(methodCell);
|
129 |
+
|
130 |
+
var statusCodeCell = document.createElement('td');
|
131 |
+
var statusCode = document.createElement('span');
|
132 |
+
if (request.statusCode < 300) {
|
133 |
+
statusCode.setAttribute('class', 'sf-toolbar-status');
|
134 |
+
} else if (request.statusCode < 400) {
|
135 |
+
statusCode.setAttribute('class', 'sf-toolbar-status sf-toolbar-status-yellow');
|
136 |
+
} else {
|
137 |
+
statusCode.setAttribute('class', 'sf-toolbar-status sf-toolbar-status-red');
|
138 |
+
}
|
139 |
+
statusCode.textContent = request.statusCode || '-';
|
140 |
+
statusCodeCell.appendChild(statusCode);
|
141 |
+
row.appendChild(statusCodeCell);
|
142 |
+
|
143 |
+
var pathCell = document.createElement('td');
|
144 |
+
pathCell.className = 'sf-ajax-request-url';
|
145 |
+
if ('GET' === request.method) {
|
146 |
+
var pathLink = document.createElement('a');
|
147 |
+
pathLink.setAttribute('href', request.url);
|
148 |
+
pathLink.textContent = request.url;
|
149 |
+
pathCell.appendChild(pathLink);
|
150 |
+
} else {
|
151 |
+
pathCell.textContent = request.url;
|
152 |
+
}
|
153 |
+
pathCell.setAttribute('title', request.url);
|
154 |
+
row.appendChild(pathCell);
|
155 |
+
|
156 |
+
var durationCell = document.createElement('td');
|
157 |
+
durationCell.className = 'sf-ajax-request-duration';
|
158 |
+
|
159 |
+
if (request.duration) {
|
160 |
+
durationCell.textContent = request.duration + "ms";
|
161 |
+
} else {
|
162 |
+
durationCell.textContent = '-';
|
163 |
+
}
|
164 |
+
row.appendChild(durationCell);
|
165 |
+
|
166 |
+
row.appendChild(document.createTextNode(' '));
|
167 |
+
var profilerCell = document.createElement('td');
|
168 |
+
|
169 |
+
if (request.profilerUrl) {
|
170 |
+
var profilerLink = document.createElement('a');
|
171 |
+
profilerLink.setAttribute('href', request.profilerUrl);
|
172 |
+
profilerLink.textContent = request.profile;
|
173 |
+
profilerCell.appendChild(profilerLink);
|
174 |
+
} else {
|
175 |
+
profilerCell.textContent = 'n/a';
|
176 |
+
}
|
177 |
+
|
178 |
+
row.appendChild(profilerCell);
|
179 |
+
|
180 |
+
var requestState = 'ok';
|
181 |
+
if (request.error) {
|
182 |
+
requestState = 'error';
|
183 |
+
if (state != "loading" && i > requestStack.length - 4) {
|
184 |
+
state = 'error';
|
185 |
+
}
|
186 |
+
} else if (request.loading) {
|
187 |
+
requestState = 'loading';
|
188 |
+
state = 'loading';
|
189 |
+
}
|
190 |
+
row.className = 'sf-ajax-request sf-ajax-request-' + requestState;
|
191 |
+
}
|
192 |
+
|
193 |
+
var infoSpan = document.querySelectorAll(".sf-toolbar-ajax-info")[0];
|
194 |
+
var children = collectionToArray(tbody.children);
|
195 |
+
for (var i = 0; i < children.length; i++) {
|
196 |
+
tbody.removeChild(children[i]);
|
197 |
+
}
|
198 |
+
tbody.appendChild(rows);
|
199 |
+
|
200 |
+
if (infoSpan) {
|
201 |
+
var text = requestStack.length + ' AJAX request' + (requestStack.length > 1 ? 's' : '');
|
202 |
+
infoSpan.textContent = text;
|
203 |
+
}
|
204 |
+
|
205 |
+
ajaxToolbarPanel.style.display = 'block';
|
206 |
+
} else {
|
207 |
+
ajaxToolbarPanel.style.display = 'none';
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
requestCounter[0].textContent = requestStack.length;
|
212 |
+
|
213 |
+
var className = 'sf-toolbar-ajax-requests sf-toolbar-value';
|
214 |
+
requestCounter[0].className = className;
|
215 |
+
|
216 |
+
if (state == 'ok') {
|
217 |
+
Sfjs.removeClass(ajaxToolbarPanel, 'sf-ajax-request-loading');
|
218 |
+
Sfjs.removeClass(ajaxToolbarPanel, 'sf-toolbar-status-red');
|
219 |
+
} else if (state == 'error') {
|
220 |
+
Sfjs.addClass(ajaxToolbarPanel, 'sf-toolbar-status-red');
|
221 |
+
Sfjs.removeClass(ajaxToolbarPanel, 'sf-ajax-request-loading');
|
222 |
+
} else {
|
223 |
+
Sfjs.addClass(ajaxToolbarPanel, 'sf-ajax-request-loading');
|
224 |
+
}
|
225 |
+
};
|
226 |
+
|
227 |
+
var addEventListener;
|
228 |
+
|
229 |
+
var el = document.createElement('div');
|
230 |
+
if (!('addEventListener' in el)) {
|
231 |
+
addEventListener = function (element, eventName, callback) {
|
232 |
+
element.attachEvent('on' + eventName, callback);
|
233 |
+
};
|
234 |
+
} else {
|
235 |
+
addEventListener = function (element, eventName, callback) {
|
236 |
+
element.addEventListener(eventName, callback, false);
|
237 |
+
};
|
238 |
+
}
|
239 |
+
|
240 |
+
<?php if ($this->getData('excluded_ajax_paths')): ?>
|
241 |
+
if (window.XMLHttpRequest && XMLHttpRequest.prototype.addEventListener) {
|
242 |
+
var proxied = XMLHttpRequest.prototype.open;
|
243 |
+
|
244 |
+
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
245 |
+
var self = this;
|
246 |
+
|
247 |
+
/* prevent logging AJAX calls to static and inline files, like templates */
|
248 |
+
var path = url;
|
249 |
+
|
250 |
+
/*if (url.substr(0, 1) === '/') {
|
251 |
+
if (0 === url.indexOf('{{ request.basePath|e('js') }}')) {
|
252 |
+
path = url.substr({{ request.basePath|length }});
|
253 |
+
}
|
254 |
+
} else */
|
255 |
+
if (0 === url.indexOf('<?php echo Mage::getBaseUrl()?>')) {
|
256 |
+
path = url.substr(<?php echo strlen(rtrim(Mage::getBaseUrl(), '/'))?>);
|
257 |
+
}
|
258 |
+
|
259 |
+
if (!path.match(new RegExp(<?php echo json_encode($this->getData('excluded_ajax_paths'));?>))) {
|
260 |
+
var stackElement = {
|
261 |
+
loading: true,
|
262 |
+
error: false,
|
263 |
+
url: url,
|
264 |
+
method: method,
|
265 |
+
start: new Date()
|
266 |
+
};
|
267 |
+
|
268 |
+
requestStack.push(stackElement);
|
269 |
+
|
270 |
+
this.addEventListener('readystatechange', function() {
|
271 |
+
if (self.readyState == 4) {
|
272 |
+
stackElement.duration = new Date() - stackElement.start;
|
273 |
+
stackElement.loading = false;
|
274 |
+
stackElement.error = self.status < 200 || self.status >= 400;
|
275 |
+
stackElement.statusCode = self.status;
|
276 |
+
extractHeaders(self, stackElement);
|
277 |
+
|
278 |
+
Sfjs.renderAjaxRequests();
|
279 |
+
}
|
280 |
+
}, false);
|
281 |
+
|
282 |
+
Sfjs.renderAjaxRequests();
|
283 |
+
}
|
284 |
+
|
285 |
+
proxied.apply(this, Array.prototype.slice.call(arguments));
|
286 |
+
};
|
287 |
+
}
|
288 |
+
<?php endif;?>
|
289 |
+
|
290 |
+
return {
|
291 |
+
hasClass: hasClass,
|
292 |
+
|
293 |
+
removeClass: removeClass,
|
294 |
+
|
295 |
+
addClass: addClass,
|
296 |
+
|
297 |
+
toggleClass: toggleClass,
|
298 |
+
|
299 |
+
getPreference: getPreference,
|
300 |
+
|
301 |
+
setPreference: setPreference,
|
302 |
+
|
303 |
+
addEventListener: addEventListener,
|
304 |
+
|
305 |
+
request: request,
|
306 |
+
|
307 |
+
renderAjaxRequests: renderAjaxRequests,
|
308 |
+
|
309 |
+
load: function(selector, url, onSuccess, onError, options) {
|
310 |
+
var el = document.getElementById(selector);
|
311 |
+
|
312 |
+
if (el && el.getAttribute('data-sfurl') !== url) {
|
313 |
+
request(
|
314 |
+
url,
|
315 |
+
function(xhr) {
|
316 |
+
el.innerHTML = xhr.responseText;
|
317 |
+
el.setAttribute('data-sfurl', url);
|
318 |
+
removeClass(el, 'loading');
|
319 |
+
(onSuccess || noop)(xhr, el);
|
320 |
+
},
|
321 |
+
function(xhr) { (onError || noop)(xhr, el); },
|
322 |
+
'',
|
323 |
+
options
|
324 |
+
);
|
325 |
+
}
|
326 |
+
|
327 |
+
return this;
|
328 |
+
},
|
329 |
+
|
330 |
+
toggle: function(selector, elOn, elOff) {
|
331 |
+
var tmp = elOn.style.display,
|
332 |
+
el = document.getElementById(selector);
|
333 |
+
|
334 |
+
elOn.style.display = elOff.style.display;
|
335 |
+
elOff.style.display = tmp;
|
336 |
+
|
337 |
+
if (el) {
|
338 |
+
el.style.display = 'none' === tmp ? 'none' : 'block';
|
339 |
+
}
|
340 |
+
|
341 |
+
return this;
|
342 |
+
},
|
343 |
+
|
344 |
+
createTabs: function() {
|
345 |
+
var tabGroups = document.querySelectorAll('.sf-tabs');
|
346 |
+
|
347 |
+
/* create the tab navigation for each group of tabs */
|
348 |
+
for (var i = 0; i < tabGroups.length; i++) {
|
349 |
+
var tabs = tabGroups[i].querySelectorAll('.tab');
|
350 |
+
var tabNavigation = document.createElement('ul');
|
351 |
+
tabNavigation.className = 'tab-navigation';
|
352 |
+
|
353 |
+
for (var j = 0; j < tabs.length; j++) {
|
354 |
+
var tabId = 'tab-' + i + '-' + j;
|
355 |
+
var tabTitle = tabs[j].querySelector('.tab-title').innerHTML;
|
356 |
+
|
357 |
+
var tabNavigationItem = document.createElement('li');
|
358 |
+
tabNavigationItem.setAttribute('data-tab-id', tabId);
|
359 |
+
if (j == 0) { Sfjs.addClass(tabNavigationItem, 'active'); }
|
360 |
+
if (Sfjs.hasClass(tabs[j], 'disabled')) { Sfjs.addClass(tabNavigationItem, 'disabled'); }
|
361 |
+
tabNavigationItem.innerHTML = tabTitle;
|
362 |
+
tabNavigation.appendChild(tabNavigationItem);
|
363 |
+
|
364 |
+
var tabContent = tabs[j].querySelector('.tab-content');
|
365 |
+
tabContent.parentElement.setAttribute('id', tabId);
|
366 |
+
}
|
367 |
+
|
368 |
+
tabGroups[i].insertBefore(tabNavigation, tabGroups[i].firstChild);
|
369 |
+
}
|
370 |
+
|
371 |
+
/* display the active tab and add the 'click' event listeners */
|
372 |
+
for (i = 0; i < tabGroups.length; i++) {
|
373 |
+
tabNavigation = tabGroups[i].querySelectorAll('.tab-navigation li');
|
374 |
+
|
375 |
+
for (j = 0; j < tabNavigation.length; j++) {
|
376 |
+
tabId = tabNavigation[j].getAttribute('data-tab-id');
|
377 |
+
document.getElementById(tabId).querySelector('.tab-title').className = 'hidden';
|
378 |
+
|
379 |
+
if (Sfjs.hasClass(tabNavigation[j], 'active')) {
|
380 |
+
document.getElementById(tabId).className = 'block';
|
381 |
+
} else {
|
382 |
+
document.getElementById(tabId).className = 'hidden';
|
383 |
+
}
|
384 |
+
|
385 |
+
tabNavigation[j].addEventListener('click', function(e) {
|
386 |
+
var activeTab = e.target || e.srcElement;
|
387 |
+
|
388 |
+
/* needed because when the tab contains HTML contents, user can click */
|
389 |
+
/* on any of those elements instead of their parent '<li>' element */
|
390 |
+
while (activeTab.tagName.toLowerCase() !== 'li') {
|
391 |
+
activeTab = activeTab.parentNode;
|
392 |
+
}
|
393 |
+
|
394 |
+
/* get the full list of tabs through the parent of the active tab element */
|
395 |
+
var tabNavigation = activeTab.parentNode.children;
|
396 |
+
for (var k = 0; k < tabNavigation.length; k++) {
|
397 |
+
var tabId = tabNavigation[k].getAttribute('data-tab-id');
|
398 |
+
document.getElementById(tabId).className = 'hidden';
|
399 |
+
Sfjs.removeClass(tabNavigation[k], 'active');
|
400 |
+
}
|
401 |
+
|
402 |
+
Sfjs.addClass(activeTab, 'active');
|
403 |
+
var activeTabId = activeTab.getAttribute('data-tab-id');
|
404 |
+
document.getElementById(activeTabId).className = 'block';
|
405 |
+
});
|
406 |
+
}
|
407 |
+
}
|
408 |
+
},
|
409 |
+
|
410 |
+
createToggles: function() {
|
411 |
+
var toggles = document.querySelectorAll('.sf-toggle');
|
412 |
+
|
413 |
+
for (var i = 0; i < toggles.length; i++) {
|
414 |
+
var elementSelector = toggles[i].getAttribute('data-toggle-selector');
|
415 |
+
var element = document.querySelector(elementSelector);
|
416 |
+
|
417 |
+
Sfjs.addClass(element, 'sf-toggle-content');
|
418 |
+
|
419 |
+
if (toggles[i].hasAttribute('data-toggle-initial') && toggles[i].getAttribute('data-toggle-initial') == 'display') {
|
420 |
+
Sfjs.addClass(element, 'sf-toggle-visible');
|
421 |
+
} else {
|
422 |
+
Sfjs.addClass(element, 'sf-toggle-hidden');
|
423 |
+
}
|
424 |
+
|
425 |
+
Sfjs.addEventListener(toggles[i], 'click', function(e) {
|
426 |
+
e.preventDefault();
|
427 |
+
|
428 |
+
var toggle = e.target || e.srcElement;
|
429 |
+
|
430 |
+
/* needed because when the toggle contains HTML contents, user can click */
|
431 |
+
/* on any of those elements instead of their parent '.sf-toggle' element */
|
432 |
+
while (!Sfjs.hasClass(toggle, 'sf-toggle')) {
|
433 |
+
toggle = toggle.parentNode;
|
434 |
+
}
|
435 |
+
|
436 |
+
var element = document.querySelector(toggle.getAttribute('data-toggle-selector'));
|
437 |
+
|
438 |
+
Sfjs.toggleClass(element, 'sf-toggle-hidden');
|
439 |
+
Sfjs.toggleClass(element, 'sf-toggle-visible');
|
440 |
+
|
441 |
+
/* the toggle doesn't change its contents when clicking on it */
|
442 |
+
if (!toggle.hasAttribute('data-toggle-alt-content')) {
|
443 |
+
return;
|
444 |
+
}
|
445 |
+
|
446 |
+
if (!toggle.hasAttribute('data-toggle-original-content')) {
|
447 |
+
toggle.setAttribute('data-toggle-original-content', toggle.innerHTML);
|
448 |
+
}
|
449 |
+
|
450 |
+
var currentContent = toggle.innerHTML;
|
451 |
+
var originalContent = toggle.getAttribute('data-toggle-original-content');
|
452 |
+
var altContent = toggle.getAttribute('data-toggle-alt-content');
|
453 |
+
toggle.innerHTML = currentContent !== altContent ? altContent : originalContent;
|
454 |
+
});
|
455 |
+
}
|
456 |
+
}
|
457 |
+
};
|
458 |
+
})();
|
459 |
+
|
460 |
+
Sfjs.addEventListener(window, 'load', function() {
|
461 |
+
Sfjs.createTabs();
|
462 |
+
Sfjs.createToggles();
|
463 |
+
});
|
464 |
+
|
app/design/frontend/base/default/template/ecocode_profiler/profiler/search/results.phtml
ADDED
@@ -0,0 +1,71 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
$data = $this->getData();
|
3 |
+
?>
|
4 |
+
<h2><?php echo $data['tokens'] ? count($data['tokens']) : 'No' ?> results found</h2>
|
5 |
+
|
6 |
+
<?php if ($data['tokens']): ?>
|
7 |
+
<table id="search-results">
|
8 |
+
<thead>
|
9 |
+
<tr>
|
10 |
+
<th scope="col" class="text-center">Status</th>
|
11 |
+
<th scope="col">IP</th>
|
12 |
+
<th scope="col">Method</th>
|
13 |
+
<th scope="col">URL</th>
|
14 |
+
<th scope="col">Time</th>
|
15 |
+
<th scope="col">Token</th>
|
16 |
+
</tr>
|
17 |
+
</thead>
|
18 |
+
<tbody>
|
19 |
+
<?php foreach ($data['tokens'] as $result): ?>
|
20 |
+
<?php
|
21 |
+
$statusCode = isset($result['status_code']) ? $result['status_code'] : 0;
|
22 |
+
$cssClass = $statusCode > 399 ? 'status-error' : $statusCode > 299 ? 'status-warning' : 'status-success';
|
23 |
+
?>
|
24 |
+
|
25 |
+
<tr>
|
26 |
+
<td class="text-center">
|
27 |
+
<span class="label <?php echo $cssClass?>"><?php echo $statusCode ? $statusCode : 'n/a'?></span>
|
28 |
+
</td>
|
29 |
+
<td>
|
30 |
+
<span class="nowrap"><?php echo $result['ip']?></span>
|
31 |
+
<!-- {% if request.session is not null %}
|
32 |
+
<a href="{{ path('_profiler_search_results', request.query.all|merge({'ip': result.ip, 'token': result.token})) }}"
|
33 |
+
title="Search">
|
34 |
+
<span title="Search" class="sf-icon sf-search">{{ include('@WebProfiler/Icon/search.svg') }}</span>
|
35 |
+
</a>
|
36 |
+
{% endif %}-->
|
37 |
+
</td>
|
38 |
+
<td>
|
39 |
+
<?php echo $result['method']?>
|
40 |
+
<!-- {% if request.session is not null %}
|
41 |
+
<a href="{{ path('_profiler_search_results', request.query.all|merge({'method': result.method, 'token': result.token})) }}"
|
42 |
+
title="Search">
|
43 |
+
<span title="Search" class="sf-icon sf-search">{{ include('@WebProfiler/Icon/search.svg') }}</span>
|
44 |
+
</a>
|
45 |
+
{% endif %}-->
|
46 |
+
</td>
|
47 |
+
<td class="break-long-words">
|
48 |
+
<?php echo $result['url']?>
|
49 |
+
<!-- {% if request.session is not null %}
|
50 |
+
<a href="{{ path('_profiler_search_results', request.query.all|merge({'url': result.url, 'token': result.token})) }}"
|
51 |
+
title="Search">
|
52 |
+
<span title="Search" class="sf-icon sf-search">{{ include('@WebProfiler/Icon/search.svg') }}</span>
|
53 |
+
</a>
|
54 |
+
{% endif %}-->
|
55 |
+
</td>
|
56 |
+
<td class="text-small">
|
57 |
+
<?php $date = (new DateTime())->setTimestamp($result['time']);?>
|
58 |
+
<span class="nowrap"><?php echo $date->format('d-M-Y')?></span>
|
59 |
+
<span class="nowrap newline"><?php echo $date->format('H:i:s')?></span>
|
60 |
+
</td>
|
61 |
+
<td class="nowrap"><a href="<?php echo Mage::helper('ecocode_profiler')->getUrl($result['token']) ?>"><?php echo $result['token']?></a></td>
|
62 |
+
</tr>
|
63 |
+
<?php endforeach;?>
|
64 |
+
</tbody>
|
65 |
+
</table>
|
66 |
+
<?php else: ?>
|
67 |
+
<div class="empty">
|
68 |
+
<p>The query returned no result.</p>
|
69 |
+
</div>
|
70 |
+
<?php endif ?>
|
71 |
+
|
app/design/frontend/base/default/template/ecocode_profiler/profiler/search/summery.phtml
ADDED
@@ -0,0 +1,5 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<div class="status">
|
2 |
+
<div class="container">
|
3 |
+
<h2>Profile Search</h2>
|
4 |
+
</div>
|
5 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/profiler/summery.phtml
ADDED
@@ -0,0 +1,90 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Model_Profile $profile */
|
3 |
+
$profile = Mage::registry('current_profile');
|
4 |
+
?>
|
5 |
+
<?php if ($profile): ?>
|
6 |
+
<?php
|
7 |
+
/** @var Ecocode_Profiler_Model_Collector_RequestDataCollector $requestCollector */
|
8 |
+
$requestCollector = $profile->getCollector('request');
|
9 |
+
$statusCode = $requestCollector->getStatusCode();
|
10 |
+
$cssClass = ($statusCode > 399) ? 'status-error' : $statusCode > 299 ? 'status-warning' : 'status-success';
|
11 |
+
?>
|
12 |
+
|
13 |
+
<div class="status <?php echo $cssClass?>">
|
14 |
+
<div class="container">
|
15 |
+
<h2 class="break-long-words">
|
16 |
+
<?php if (in_array(strtoupper($profile->getMethod()), ['GET', 'HEAD'])): ?>
|
17 |
+
<a href="<?php echo $profile->getUrl()?>"><?php echo $profile->getUrl()?></a>
|
18 |
+
<?php else: ?>
|
19 |
+
<?php echo $profile->getUrl()?>
|
20 |
+
<?php endif;?>
|
21 |
+
</h2>
|
22 |
+
|
23 |
+
<!-- {% if request_collector is defined and request_collector.redirect -%}
|
24 |
+
{%- set redirect = request_collector.redirect -%}
|
25 |
+
{%- set controller = redirect.controller -%}
|
26 |
+
{%- set redirect_route = '@' ~ redirect.route %}
|
27 |
+
<dl class="metadata">
|
28 |
+
<dt>
|
29 |
+
<span class="label">{{ redirect.status_code }}</span>
|
30 |
+
Redirect from
|
31 |
+
</dt>
|
32 |
+
<dd>
|
33 |
+
{{ 'GET' != redirect.method ? redirect.method }}
|
34 |
+
{% if redirect.controller.class is defined -%}
|
35 |
+
{%- set link = controller.file|file_link(controller.line) -%}
|
36 |
+
{% if link %}<a href="{{ link }}" title="{{ controller.file }}">{% endif -%}
|
37 |
+
{{ redirect_route }}
|
38 |
+
{%- if link %}</a>{% endif -%}
|
39 |
+
{%- else -%}
|
40 |
+
{{ redirect_route }}
|
41 |
+
{%- endif %}
|
42 |
+
(<a href="{{ path('_profiler', { token: redirect.token }) }}">{{ redirect.token }}</a>)
|
43 |
+
</dd>
|
44 |
+
</dl>
|
45 |
+
{%- endif %}-->
|
46 |
+
|
47 |
+
<!-- {% if request_collector and request_collector.forward|default(false) and request_collector.forward.controller.class is defined -%}
|
48 |
+
{%- set forward = request_collector.forward -%}
|
49 |
+
{%- set controller = forward.controller -%}
|
50 |
+
<dl class="metadata">
|
51 |
+
<dt>Forwarded to</dt>
|
52 |
+
<dd>
|
53 |
+
{% set link = controller.file|file_link(controller.line) -%}
|
54 |
+
{%- if link %}<a href="{{ link }}" title="{{ controller.file }}">{% endif -%}
|
55 |
+
{{- controller.class|abbr_class|striptags -}}
|
56 |
+
{{- controller.method ? ' :: ' ~ controller.method }}
|
57 |
+
{%- if link %}</a>{% endif %}
|
58 |
+
(<a href="{{ path('_profiler', { token: forward.token }) }}">{{ forward.token }}</a>)
|
59 |
+
</dd>
|
60 |
+
</dl>
|
61 |
+
{%- endif %}-->
|
62 |
+
|
63 |
+
<dl class="metadata">
|
64 |
+
<dt>Method</dt>
|
65 |
+
<dd><?php echo strtoupper($profile->getMethod()) ?></dd>
|
66 |
+
|
67 |
+
<?php if ($profile->hasCollector('request')):?>
|
68 |
+
<?php
|
69 |
+
/** @var Ecocode_Profiler_Model_Collector_RequestDataCollector $collector */
|
70 |
+
$collector = $profile->getCollector('request');
|
71 |
+
?>
|
72 |
+
<dt>Route</dt>
|
73 |
+
<dd><?php echo $collector->getRoute(); ?></dd>
|
74 |
+
<?php endif; ?>
|
75 |
+
|
76 |
+
<dt>HTTP Status</dt>
|
77 |
+
<dd><?php echo $statusCode ?></dd>
|
78 |
+
|
79 |
+
<dt>IP</dt>
|
80 |
+
<dd><?php echo $profile->getIp() ?></dd>
|
81 |
+
|
82 |
+
<dt>Profiled on</dt>
|
83 |
+
<dd><?php echo date('r', $profile->getTime()) ?></dd>
|
84 |
+
|
85 |
+
<dt>Token</dt>
|
86 |
+
<dd><?php echo $profile->getToken(); ?></dd>
|
87 |
+
</dl>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
<?php endif;?>
|
app/design/frontend/base/default/template/ecocode_profiler/renderer/context.phtml
ADDED
@@ -0,0 +1,30 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
/** @var Ecocode_Profiler_Block_Renderer_Context $this */
|
3 |
+
$prefix = $this->getData('prefix');
|
4 |
+
|
5 |
+
/** @var Ecocode_Profiler_Model_Context $context */
|
6 |
+
$context = $this->getData('context');
|
7 |
+
|
8 |
+
/** @var Ecocode_Profiler_Helper_ValueExporter $exporter */
|
9 |
+
$exporter = Mage::helper('ecocode_profiler/valueExporter')
|
10 |
+
?>
|
11 |
+
|
12 |
+
<div class="context font-normal text-small">
|
13 |
+
<strong>Context: </strong><?php echo $context->getKey()?>
|
14 |
+
<?php if($context->getData()):?>
|
15 |
+
<a href="#" class="sf-toggle link-inverse text-small"
|
16 |
+
data-toggle-selector="#context-<?php echo $prefix . $context->getId() ?>"
|
17 |
+
data-toggle-alt-content="Hide metadata">View metadata</a>
|
18 |
+
<div id="context-<?php echo $prefix . $context->getId() ?>" class="hidden text-small">
|
19 |
+
<table>
|
20 |
+
<?php foreach($context->getData() as $key => $value):?>
|
21 |
+
<tr>
|
22 |
+
<th class="key"><?php echo $key?></th>
|
23 |
+
<td><?php echo $exporter->exportValue($value, true)?></td>
|
24 |
+
</tr>
|
25 |
+
<?php endforeach;?>
|
26 |
+
</table>
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<?php endif?>
|
30 |
+
</div>
|
app/design/frontend/base/default/template/ecocode_profiler/toolbar.css.phtml
ADDED
@@ -0,0 +1,479 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
|
2 |
+
<?php
|
3 |
+
$colors = [
|
4 |
+
'success' => '#4F805D',
|
5 |
+
'warning' => '#A46A1F',
|
6 |
+
'error' => '#B0413E'
|
7 |
+
]
|
8 |
+
?>
|
9 |
+
.sf-minitoolbar {
|
10 |
+
background-color: #222;
|
11 |
+
border-top-left-radius: 4px;
|
12 |
+
bottom: 0;
|
13 |
+
-webkit-box-sizing: border-box;
|
14 |
+
-moz-box-sizing: border-box;
|
15 |
+
box-sizing: border-box;
|
16 |
+
display: none;
|
17 |
+
height: 36px;
|
18 |
+
padding: 6px;
|
19 |
+
position: fixed;
|
20 |
+
right: 0;
|
21 |
+
z-index: 99999;
|
22 |
+
}
|
23 |
+
|
24 |
+
.sf-minitoolbar a {
|
25 |
+
display: block;
|
26 |
+
}
|
27 |
+
.sf-minitoolbar svg,
|
28 |
+
.sf-minitoolbar img {
|
29 |
+
max-height: 24px;
|
30 |
+
max-width: 24px;
|
31 |
+
display: inline;
|
32 |
+
}
|
33 |
+
|
34 |
+
.sf-toolbarreset * {
|
35 |
+
-webkit-box-sizing: content-box;
|
36 |
+
-moz-box-sizing: content-box;
|
37 |
+
box-sizing: content-box;
|
38 |
+
vertical-align: baseline;
|
39 |
+
}
|
40 |
+
|
41 |
+
.sf-toolbarreset {
|
42 |
+
background-color: #222;
|
43 |
+
bottom: 0;
|
44 |
+
box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
|
45 |
+
color: #EEE;
|
46 |
+
font: 11px Arial, sans-serif;
|
47 |
+
left: 0;
|
48 |
+
margin: 0;
|
49 |
+
padding: 0 36px 0 0;
|
50 |
+
position: fixed;
|
51 |
+
right: 0;
|
52 |
+
text-align: left;
|
53 |
+
text-transform: none;
|
54 |
+
z-index: 99999;
|
55 |
+
|
56 |
+
/* neutralize the aliasing defined by external CSS styles */
|
57 |
+
-webkit-font-smoothing: subpixel-antialiased;
|
58 |
+
-moz-osx-font-smoothing: auto;
|
59 |
+
}
|
60 |
+
.sf-toolbarreset abbr {
|
61 |
+
border: dashed #777;
|
62 |
+
border-width: 0 0 1px;
|
63 |
+
}
|
64 |
+
.sf-toolbarreset svg,
|
65 |
+
.sf-toolbarreset img {
|
66 |
+
height: 20px;
|
67 |
+
display: inline-block;
|
68 |
+
}
|
69 |
+
|
70 |
+
.sf-toolbarreset .hide-button {
|
71 |
+
background: #444;
|
72 |
+
display: block;
|
73 |
+
position: absolute;
|
74 |
+
top: 0;
|
75 |
+
right: 0;
|
76 |
+
width: 36px;
|
77 |
+
height: 36px;
|
78 |
+
cursor: pointer;
|
79 |
+
text-align: center;
|
80 |
+
}
|
81 |
+
.sf-toolbarreset .hide-button svg {
|
82 |
+
max-height: 18px;
|
83 |
+
margin-top: 10px;
|
84 |
+
}
|
85 |
+
|
86 |
+
.sf-toolbar-block {
|
87 |
+
cursor: default;
|
88 |
+
display: block;
|
89 |
+
float: left;
|
90 |
+
height: 36px;
|
91 |
+
margin-right: 0;
|
92 |
+
white-space: nowrap;
|
93 |
+
}
|
94 |
+
.sf-toolbar-block > a,
|
95 |
+
.sf-toolbar-block > a:hover {
|
96 |
+
display: block;
|
97 |
+
text-decoration: none;
|
98 |
+
}
|
99 |
+
|
100 |
+
.sf-toolbar-block span {
|
101 |
+
display: inline-block;
|
102 |
+
}
|
103 |
+
.sf-toolbar-block .sf-toolbar-value {
|
104 |
+
color: #F5F5F5;
|
105 |
+
font-size: 13px;
|
106 |
+
line-height: 36px;
|
107 |
+
padding: 0;
|
108 |
+
}
|
109 |
+
.sf-toolbar-block .sf-toolbar-label,
|
110 |
+
.sf-toolbar-block .sf-toolbar-class-separator {
|
111 |
+
color: #AAA;
|
112 |
+
font-size: 12px;
|
113 |
+
}
|
114 |
+
|
115 |
+
.sf-toolbar-block .sf-toolbar-info {
|
116 |
+
border-collapse: collapse;
|
117 |
+
display: table;
|
118 |
+
z-index: 100000;
|
119 |
+
}
|
120 |
+
.sf-toolbar-block hr {
|
121 |
+
border-top: 1px solid #777;
|
122 |
+
margin: 4px 0;
|
123 |
+
padding-top: 4px;
|
124 |
+
}
|
125 |
+
.sf-toolbar-block .sf-toolbar-info-piece {
|
126 |
+
/* this 'border-bottom' trick is needed because 'margin-bottom' doesn't work for table rows */
|
127 |
+
border-bottom: solid transparent 3px;
|
128 |
+
display: table-row;
|
129 |
+
}
|
130 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional,
|
131 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional-detail {
|
132 |
+
display: none;
|
133 |
+
}
|
134 |
+
.sf-toolbar-block .sf-toolbar-info-group {
|
135 |
+
margin-bottom: 4px;
|
136 |
+
padding-bottom: 2px;
|
137 |
+
border-bottom: 1px solid #333333;
|
138 |
+
}
|
139 |
+
.sf-toolbar-block .sf-toolbar-info-group:last-child {
|
140 |
+
margin-bottom: 0;
|
141 |
+
padding-bottom: 0;
|
142 |
+
border-bottom: none;
|
143 |
+
}
|
144 |
+
|
145 |
+
.sf-toolbar-block .sf-toolbar-info-piece .sf-toolbar-status {
|
146 |
+
padding: 2px 5px;
|
147 |
+
margin-bottom: 0;
|
148 |
+
}
|
149 |
+
.sf-toolbar-block .sf-toolbar-info-piece .sf-toolbar-status + .sf-toolbar-status {
|
150 |
+
margin-left: 4px;
|
151 |
+
}
|
152 |
+
|
153 |
+
.sf-toolbar-block .sf-toolbar-info-piece:last-child {
|
154 |
+
margin-bottom: 0;
|
155 |
+
}
|
156 |
+
|
157 |
+
.sf-toolbar-block .sf-toolbar-info-piece a {
|
158 |
+
color: #99CDD8;
|
159 |
+
text-decoration: underline;
|
160 |
+
}
|
161 |
+
.sf-toolbar-block .sf-toolbar-info-piece a:hover {
|
162 |
+
text-decoration: none;
|
163 |
+
}
|
164 |
+
|
165 |
+
.sf-toolbar-block .sf-toolbar-info-piece b {
|
166 |
+
color: #AAA;
|
167 |
+
display: table-cell;
|
168 |
+
font-size: 11px;
|
169 |
+
padding: 4px 8px 4px 0;
|
170 |
+
}
|
171 |
+
.sf-toolbar-block .sf-toolbar-info-piece span {
|
172 |
+
|
173 |
+
}
|
174 |
+
.sf-toolbar-block .sf-toolbar-info-piece span {
|
175 |
+
color: #F5F5F5;
|
176 |
+
font-size: 12px;
|
177 |
+
}
|
178 |
+
|
179 |
+
.sf-toolbar-block .sf-toolbar-info {
|
180 |
+
background-color: #444;
|
181 |
+
bottom: 36px;
|
182 |
+
color: #F5F5F5;
|
183 |
+
display: none;
|
184 |
+
padding: 9px 0;
|
185 |
+
position: absolute;
|
186 |
+
}
|
187 |
+
|
188 |
+
.sf-toolbar-block .sf-toolbar-info:empty {
|
189 |
+
visibility: hidden;
|
190 |
+
}
|
191 |
+
|
192 |
+
.sf-toolbar-block .sf-toolbar-status {
|
193 |
+
display: inline-block;
|
194 |
+
color: #FFF;
|
195 |
+
background-color: #666;
|
196 |
+
padding: 3px 6px;
|
197 |
+
margin-bottom: 2px;
|
198 |
+
vertical-align: middle;
|
199 |
+
min-width: 15px;
|
200 |
+
min-height: 13px;
|
201 |
+
text-align: center;
|
202 |
+
}
|
203 |
+
|
204 |
+
.sf-toolbar-block .sf-toolbar-status-green {
|
205 |
+
background-color: <?php echo $colors['success']; ?>;
|
206 |
+
}
|
207 |
+
.sf-toolbar-block .sf-toolbar-status-red {
|
208 |
+
background-color: <?php echo $colors['error']; ?>;
|
209 |
+
}
|
210 |
+
.sf-toolbar-block .sf-toolbar-status-yellow {
|
211 |
+
background-color: <?php echo $colors['warning']; ?>;
|
212 |
+
}
|
213 |
+
|
214 |
+
.sf-toolbar-block.sf-toolbar-status-green {
|
215 |
+
background-color: <?php echo $colors['success']; ?>;
|
216 |
+
color: #FFF;
|
217 |
+
}
|
218 |
+
.sf-toolbar-block.sf-toolbar-status-red {
|
219 |
+
background-color: <?php echo $colors['error']; ?>;
|
220 |
+
color: #FFF;
|
221 |
+
}
|
222 |
+
.sf-toolbar-block.sf-toolbar-status-yellow {
|
223 |
+
background-color: <?php echo $colors['warning']; ?>;
|
224 |
+
color: #FFF;
|
225 |
+
}
|
226 |
+
|
227 |
+
.sf-toolbar-block-request .sf-toolbar-status {
|
228 |
+
color: #FFF;
|
229 |
+
display: inline-block;
|
230 |
+
font-size: 14px;
|
231 |
+
height: 36px;
|
232 |
+
line-height: 36px;
|
233 |
+
padding: 0 10px;
|
234 |
+
}
|
235 |
+
.sf-toolbar-block-request .sf-toolbar-info-piece a {
|
236 |
+
text-decoration: none;
|
237 |
+
}
|
238 |
+
.sf-toolbar-block-request .sf-toolbar-info-piece a:hover {
|
239 |
+
text-decoration: underline;
|
240 |
+
}
|
241 |
+
.sf-toolbar-block-request .sf-toolbar-redirection-status {
|
242 |
+
font-weight: normal;
|
243 |
+
padding: 2px 4px;
|
244 |
+
line-height: 18px;
|
245 |
+
}
|
246 |
+
.sf-toolbar-block-request .sf-toolbar-info-piece span.sf-toolbar-redirection-method {
|
247 |
+
font-size: 12px;
|
248 |
+
height: 17px;
|
249 |
+
line-height: 17px;
|
250 |
+
}
|
251 |
+
|
252 |
+
.sf-toolbar-status-green .sf-toolbar-label,
|
253 |
+
.sf-toolbar-status-yellow .sf-toolbar-label,
|
254 |
+
.sf-toolbar-status-red .sf-toolbar-label {
|
255 |
+
color: #FFF;
|
256 |
+
}
|
257 |
+
.sf-toolbar-status-green svg path,
|
258 |
+
.sf-toolbar-status-red svg path,
|
259 |
+
.sf-toolbar-status-yellow svg path {
|
260 |
+
fill: #FFF;
|
261 |
+
}
|
262 |
+
.sf-toolbar-block-config svg path {
|
263 |
+
fill: #FFF;
|
264 |
+
}
|
265 |
+
|
266 |
+
.sf-toolbar-block .sf-toolbar-icon {
|
267 |
+
display: block;
|
268 |
+
height: 36px;
|
269 |
+
padding: 0 7px;
|
270 |
+
}
|
271 |
+
.sf-toolbar-block-request .sf-toolbar-icon {
|
272 |
+
padding-left: 0;
|
273 |
+
padding-right: 0;
|
274 |
+
}
|
275 |
+
|
276 |
+
.sf-toolbar-block .sf-toolbar-icon img,
|
277 |
+
.sf-toolbar-block .sf-toolbar-icon svg {
|
278 |
+
border-width: 0;
|
279 |
+
position: relative;
|
280 |
+
top: 8px;
|
281 |
+
}
|
282 |
+
|
283 |
+
.sf-toolbar-block .sf-toolbar-icon img + span,
|
284 |
+
.sf-toolbar-block .sf-toolbar-icon svg + span {
|
285 |
+
margin-left: 4px;
|
286 |
+
}
|
287 |
+
.sf-toolbar-block-config .sf-toolbar-icon .sf-toolbar-value {
|
288 |
+
margin-left: 4px;
|
289 |
+
}
|
290 |
+
|
291 |
+
.sf-toolbar-block:hover {
|
292 |
+
position: relative;
|
293 |
+
}
|
294 |
+
.sf-toolbar-block:hover .sf-toolbar-icon {
|
295 |
+
background-color: #444;
|
296 |
+
position: relative;
|
297 |
+
z-index: 10002;
|
298 |
+
}
|
299 |
+
.sf-toolbar-block:hover .sf-toolbar-info {
|
300 |
+
display: block;
|
301 |
+
padding: 10px;
|
302 |
+
max-width: 480px;
|
303 |
+
max-height: 480px;
|
304 |
+
word-wrap: break-word;
|
305 |
+
overflow: hidden;
|
306 |
+
overflow-y: auto;
|
307 |
+
}
|
308 |
+
.sf-toolbar-info-piece b.sf-toolbar-ajax-info {
|
309 |
+
color: #F5F5F5;
|
310 |
+
}
|
311 |
+
.sf-toolbar-ajax-requests {
|
312 |
+
table-layout: auto;
|
313 |
+
width: 100%;
|
314 |
+
}
|
315 |
+
.sf-toolbar-ajax-requests td {
|
316 |
+
background-color: #444;
|
317 |
+
border-bottom: 1px solid #777;
|
318 |
+
color: #F5F5F5;
|
319 |
+
font-size: 12px;
|
320 |
+
padding: 4px;
|
321 |
+
}
|
322 |
+
.sf-toolbar-ajax-requests tr:last-child td {
|
323 |
+
border-bottom: 0;
|
324 |
+
}
|
325 |
+
.sf-toolbar-ajax-requests th {
|
326 |
+
background-color: #222;
|
327 |
+
border-bottom: 0;
|
328 |
+
color: #AAA;
|
329 |
+
font-size: 11px;
|
330 |
+
padding: 4px;
|
331 |
+
}
|
332 |
+
.sf-ajax-request-url {
|
333 |
+
max-width: 300px;
|
334 |
+
line-height: 9px;
|
335 |
+
overflow: hidden;
|
336 |
+
text-overflow: ellipsis;
|
337 |
+
}
|
338 |
+
.sf-toolbar-ajax-requests .sf-ajax-request-url a {
|
339 |
+
text-decoration: none;
|
340 |
+
}
|
341 |
+
.sf-toolbar-ajax-requests .sf-ajax-request-url a:hover {
|
342 |
+
text-decoration: underline;
|
343 |
+
}
|
344 |
+
.sf-ajax-request-duration {
|
345 |
+
text-align: right;
|
346 |
+
}
|
347 |
+
.sf-ajax-request-loading {
|
348 |
+
-webkit-animation: sf-blink .5s ease-in-out infinite;
|
349 |
+
-o-animation: sf-blink .5s ease-in-out infinite;
|
350 |
+
-moz-animation: sf-blink .5s ease-in-out infinite;
|
351 |
+
animation: sf-blink .5s ease-in-out infinite;
|
352 |
+
}
|
353 |
+
@-webkit-keyframes sf-blink {
|
354 |
+
0% { background: #222; }
|
355 |
+
50% { background: #444; }
|
356 |
+
100% { background: #222; }
|
357 |
+
}
|
358 |
+
@-moz-keyframes sf-blink {
|
359 |
+
0% { background: #222; }
|
360 |
+
50% { background: #444; }
|
361 |
+
100% { background: #222; }
|
362 |
+
}
|
363 |
+
@keyframes sf-blink {
|
364 |
+
0% { background: #222; }
|
365 |
+
50% { background: #444; }
|
366 |
+
100% { background: #222; }
|
367 |
+
}
|
368 |
+
|
369 |
+
.sf-toolbar-block-dump pre.sf-dump {
|
370 |
+
background-color: #222;
|
371 |
+
border-color: #777;
|
372 |
+
border-radius: 0;
|
373 |
+
margin: 6px 0 12px 0;
|
374 |
+
width: 200px;
|
375 |
+
}
|
376 |
+
.sf-toolbar-block-dump pre.sf-dump:last-child {
|
377 |
+
margin-bottom: 0;
|
378 |
+
}
|
379 |
+
.sf-toolbar-block-dump .sf-toolbar-info-piece .sf-toolbar-file-line {
|
380 |
+
color: #AAA;
|
381 |
+
margin-left: 4px;
|
382 |
+
}
|
383 |
+
.sf-toolbar-block-dump .sf-toolbar-info img {
|
384 |
+
display: none;
|
385 |
+
}
|
386 |
+
|
387 |
+
/* Responsive Design */
|
388 |
+
.sf-toolbar-icon .sf-toolbar-label,
|
389 |
+
.sf-toolbar-icon .sf-toolbar-value {
|
390 |
+
display: none;
|
391 |
+
}
|
392 |
+
.sf-toolbar-block-config .sf-toolbar-icon .sf-toolbar-label {
|
393 |
+
display: inline-block;
|
394 |
+
}
|
395 |
+
|
396 |
+
/* Legacy Design - these styles are maintained to make old panels look
|
397 |
+
a bit better on the new toolbar */
|
398 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional-detail {
|
399 |
+
color: #AAA;
|
400 |
+
font-size: 12px;
|
401 |
+
}
|
402 |
+
.sf-toolbar-status-green .sf-toolbar-info-piece-additional-detail,
|
403 |
+
.sf-toolbar-status-yellow .sf-toolbar-info-piece-additional-detail,
|
404 |
+
.sf-toolbar-status-red .sf-toolbar-info-piece-additional-detail {
|
405 |
+
color: #FFF;
|
406 |
+
}
|
407 |
+
|
408 |
+
@media (min-width: 768px) {
|
409 |
+
|
410 |
+
.sf-toolbar-icon .sf-toolbar-label,
|
411 |
+
.sf-toolbar-icon .sf-toolbar-value {
|
412 |
+
display: inline;
|
413 |
+
}
|
414 |
+
|
415 |
+
.sf-toolbar-block .sf-toolbar-icon img,
|
416 |
+
.sf-toolbar-block .sf-toolbar-icon svg {
|
417 |
+
top: 6px;
|
418 |
+
}
|
419 |
+
.sf-toolbar-block-time .sf-toolbar-icon svg,
|
420 |
+
.sf-toolbar-block-memory .sf-toolbar-icon svg {
|
421 |
+
display: none;
|
422 |
+
}
|
423 |
+
.sf-toolbar-block-time .sf-toolbar-icon svg + span,
|
424 |
+
.sf-toolbar-block-memory .sf-toolbar-icon svg + span {
|
425 |
+
margin-left: 0;
|
426 |
+
}
|
427 |
+
|
428 |
+
.sf-toolbar-block .sf-toolbar-icon {
|
429 |
+
padding: 0 10px;
|
430 |
+
}
|
431 |
+
.sf-toolbar-block-time .sf-toolbar-icon {
|
432 |
+
padding-right: 5px;
|
433 |
+
}
|
434 |
+
.sf-toolbar-block-memory .sf-toolbar-icon {
|
435 |
+
padding-left: 5px;
|
436 |
+
}
|
437 |
+
.sf-toolbar-block-request .sf-toolbar-icon {
|
438 |
+
padding-left: 0;
|
439 |
+
padding-right: 0;
|
440 |
+
}
|
441 |
+
.sf-toolbar-block-request .sf-toolbar-status {
|
442 |
+
margin-right: 5px;
|
443 |
+
}
|
444 |
+
.sf-toolbar-block-request .sf-toolbar-icon svg + .sf-toolbar-label {
|
445 |
+
margin-left: 0;
|
446 |
+
}
|
447 |
+
.sf-toolbar-block-request .sf-toolbar-label + .sf-toolbar-value {
|
448 |
+
margin-right: 10px;
|
449 |
+
}
|
450 |
+
|
451 |
+
.sf-toolbar-block-request:hover .sf-toolbar-info {
|
452 |
+
max-width: none;
|
453 |
+
}
|
454 |
+
|
455 |
+
.sf-toolbar-block .sf-toolbar-info-piece b {
|
456 |
+
font-size: 12px;
|
457 |
+
}
|
458 |
+
.sf-toolbar-block .sf-toolbar-info-piece span {
|
459 |
+
font-size: 13px;
|
460 |
+
}
|
461 |
+
|
462 |
+
.sf-toolbar-block-right {
|
463 |
+
float: right;
|
464 |
+
margin-left: 0;
|
465 |
+
margin-right: 0;
|
466 |
+
}
|
467 |
+
}
|
468 |
+
|
469 |
+
@media (min-width: 1024px) {
|
470 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional,
|
471 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional-detail {
|
472 |
+
display: inline-block;
|
473 |
+
}
|
474 |
+
|
475 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional:empty,
|
476 |
+
.sf-toolbar-block .sf-toolbar-info-piece-additional-detail:empty {
|
477 |
+
display: none;
|
478 |
+
}
|
479 |
+
}
|
app/design/frontend/base/default/template/ecocode_profiler/toolbar.phtml
ADDED
@@ -0,0 +1,75 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<!-- START of ecocode Web Debug Toolbar -->
|
2 |
+
<?php $token = $this->getToken(); ?>
|
3 |
+
<style>
|
4 |
+
<?php include 'toolbar.css.phtml';?>
|
5 |
+
</style>
|
6 |
+
<div id="sfwdt<?php echo $token; ?>" class="sf-toolbar">
|
7 |
+
<div id="sfMiniToolbar-<?php echo $token; ?>" class="sf-minitoolbar" data-no-turbolink>
|
8 |
+
<a href="javascript:void(0);" title="Show Symfony toolbar" tabindex="-1" accesskey="D" onclick="
|
9 |
+
var elem = this.parentNode;
|
10 |
+
if (elem.style.display == 'none') {
|
11 |
+
document.getElementById('sfToolbarMainContent-<?php echo $token; ?>').style.display = 'none';
|
12 |
+
document.getElementById('sfToolbarClearer-<?php echo $token; ?>').style.display = 'none';
|
13 |
+
elem.style.display = 'block';
|
14 |
+
} else {
|
15 |
+
document.getElementById('sfToolbarMainContent-<?php echo $token; ?>').style.display = 'block';
|
16 |
+
document.getElementById('sfToolbarClearer-<?php echo $token; ?>').style.display = 'block';
|
17 |
+
elem.style.display = 'none'
|
18 |
+
}
|
19 |
+
">
|
20 |
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svgMageLogo" width="24" xml:space="preserve" height="24" viewBox="0 0 53.692 62" baseProfile="" version="1.1" y="0px" x="0px">
|
21 |
+
<g fill="#AAAAAA">
|
22 |
+
<path d="m26.845 8.857"></path><polygon points="53.692 15.5 53.692 46.5 46.021 50.929 46.021 19.929 26.845 8.857 7.67 19.928 7.67 50.929 0 46.5 0 15.5 26.845 0"></polygon><polygon points="26.847 62 15.341 55.356 15.341 24.357 23.011 19.928 23.011 50.929 26.845 53.257 30.682 50.929 30.682 19.929 38.353 24.357 38.353 55.356"></polygon>
|
23 |
+
</g>
|
24 |
+
</svg>
|
25 |
+
</a>
|
26 |
+
</div>
|
27 |
+
|
28 |
+
<div id="sfToolbarClearer-<?php echo $token; ?>" style="clear: both; height: 36px;"></div>
|
29 |
+
|
30 |
+
<?php
|
31 |
+
$action = Mage::app()->getFrontController()->getAction();
|
32 |
+
$request = Mage::app()->getRequest();
|
33 |
+
$response = Mage::app()->getResponse();
|
34 |
+
?>
|
35 |
+
<div id="sfToolbarMainContent-<?php echo $token; ?>" class="sf-toolbarreset clear-fix" data-no-turbolink>
|
36 |
+
<?php foreach ($this->getToolbarItems() as $block): ?>
|
37 |
+
<?php echo $block->toHtml(); ?>
|
38 |
+
<?Php endforeach;?>
|
39 |
+
|
40 |
+
<a class="hide-button" title="Close Toolbar" tabindex="-1" accesskey="D" onclick="
|
41 |
+
var p = this.parentNode;
|
42 |
+
p.style.display = 'none';
|
43 |
+
(p.previousElementSibling || p.previousSibling).style.display = 'none';
|
44 |
+
document.getElementById('sfMiniToolbar-<?php echo $token; ?>').style.display = 'block';
|
45 |
+
">
|
46 |
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="24" height="24"
|
47 |
+
viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
|
48 |
+
<path fill="#AAAAAA" d="M21.1,18.3c0.8,0.8,0.8,2,0,2.8c-0.4,0.4-0.9,0.6-1.4,0.6s-1-0.2-1.4-0.6L12,14.8l-6.3,6.3
|
49 |
+
c-0.4,0.4-0.9,0.6-1.4,0.6s-1-0.2-1.4-0.6c-0.8-0.8-0.8-2,0-2.8L9.2,12L2.9,5.7c-0.8-0.8-0.8-2,0-2.8c0.8-0.8,2-0.8,2.8,0L12,9.2
|
50 |
+
l6.3-6.3c0.8-0.8,2-0.8,2.8,0c0.8,0.8,0.8,2,0,2.8L14.8,12L21.1,18.3z"/>
|
51 |
+
</svg>
|
52 |
+
|
53 |
+
</a>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
|
57 |
+
<!-- END of Symfony Web Debug Toolbar -->
|
58 |
+
|
59 |
+
|
60 |
+
<style>
|
61 |
+
/*remove me*/
|
62 |
+
.sf-toggle-content {
|
63 |
+
-moz-transition: display .25s ease;
|
64 |
+
-webkit-transition: display .25s ease;
|
65 |
+
transition: display .25s ease;
|
66 |
+
}
|
67 |
+
|
68 |
+
.sf-toggle-content.sf-toggle-hidden {
|
69 |
+
display: none !important;
|
70 |
+
}
|
71 |
+
|
72 |
+
.sf-toggle-content.sf-toggle-visible {
|
73 |
+
display: block !important;
|
74 |
+
}
|
75 |
+
</style>
|
app/design/frontend/base/default/template/ecocode_profiler/toolbar_js.phtml
ADDED
@@ -0,0 +1,81 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<!-- START of ecocode Web Debug Toolbar -->
|
2 |
+
<?php $token = $this->getToken(); ?>
|
3 |
+
|
4 |
+
<div id="sfwdt<?php echo $token?>" class="sf-toolbar" style="display: none"></div>
|
5 |
+
<script>
|
6 |
+
<?php echo $this->getChildHtml('base_js');?>
|
7 |
+
(function () {
|
8 |
+
Sfjs.load(
|
9 |
+
'sfwdt<?php echo $token?>',
|
10 |
+
'<?php echo Mage::getUrl('_profiler/index/toolbar', [Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER => $token])?>',
|
11 |
+
function(xhr, el) {
|
12 |
+
el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none';
|
13 |
+
|
14 |
+
if (el.style.display == 'none') {
|
15 |
+
return;
|
16 |
+
}
|
17 |
+
|
18 |
+
if (Sfjs.getPreference('toolbar/displayState') == 'none') {
|
19 |
+
document.getElementById('sfToolbarMainContent-<?php echo $token?>').style.display = 'none';
|
20 |
+
document.getElementById('sfToolbarClearer-<?php echo $token?>').style.display = 'none';
|
21 |
+
document.getElementById('sfMiniToolbar-<?php echo $token?>').style.display = 'block';
|
22 |
+
} else {
|
23 |
+
document.getElementById('sfToolbarMainContent-<?php echo $token?>').style.display = 'block';
|
24 |
+
document.getElementById('sfToolbarClearer-<?php echo $token?>').style.display = 'block';
|
25 |
+
document.getElementById('sfMiniToolbar-<?php echo $token?>').style.display = 'none';
|
26 |
+
}
|
27 |
+
|
28 |
+
Sfjs.renderAjaxRequests();
|
29 |
+
|
30 |
+
/* Handle toolbar-info position */
|
31 |
+
var toolbarBlocks = document.querySelectorAll('.sf-toolbar-block');
|
32 |
+
for (var i = 0; i < toolbarBlocks.length; i += 1) {
|
33 |
+
toolbarBlocks[i].onmouseover = function () {
|
34 |
+
var toolbarInfo = this.querySelectorAll('.sf-toolbar-info')[0];
|
35 |
+
var pageWidth = document.body.clientWidth;
|
36 |
+
var elementWidth = toolbarInfo.offsetWidth;
|
37 |
+
var leftValue = (elementWidth + this.offsetLeft) - pageWidth;
|
38 |
+
var rightValue = (elementWidth + (pageWidth - this.offsetLeft)) - pageWidth;
|
39 |
+
|
40 |
+
/* Reset right and left value, useful on window resize */
|
41 |
+
toolbarInfo.style.right = '';
|
42 |
+
toolbarInfo.style.left = '';
|
43 |
+
|
44 |
+
if (elementWidth > pageWidth) {
|
45 |
+
toolbarInfo.style.left = 0;
|
46 |
+
}
|
47 |
+
else if (leftValue > 0 && rightValue > 0) {
|
48 |
+
toolbarInfo.style.right = (rightValue * -1) + 'px';
|
49 |
+
} else if (leftValue < 0) {
|
50 |
+
toolbarInfo.style.left = 0;
|
51 |
+
} else {
|
52 |
+
toolbarInfo.style.right = '0px';
|
53 |
+
}
|
54 |
+
};
|
55 |
+
}
|
56 |
+
|
57 |
+
var actions = document.querySelectorAll('.sf-toolbar .ajax-action');
|
58 |
+
|
59 |
+
for (var j = 0; j < actions.length; j++) {
|
60 |
+
(function () {
|
61 |
+
|
62 |
+
var button = actions[j],
|
63 |
+
url = button.getAttribute('data-url');
|
64 |
+
|
65 |
+
button.addEventListener('click', function (e) {
|
66 |
+
Sfjs.request(url, function () {
|
67 |
+
window.location.reload();
|
68 |
+
});
|
69 |
+
});
|
70 |
+
})();
|
71 |
+
}
|
72 |
+
},
|
73 |
+
function(xhr) {
|
74 |
+
if (xhr.status !== 0) {
|
75 |
+
confirm('An error occurred while loading the web debug toolbar (' + xhr.status + ': ' + xhr.statusText + ').\n\nDo you want to open the profiler?') && (window.location = '<?php echo Mage::helper('ecocode_profiler')->getUrl($token)?>');
|
76 |
+
}
|
77 |
+
},
|
78 |
+
{'maxTries': 5}
|
79 |
+
);
|
80 |
+
})();
|
81 |
+
</script>
|
app/etc/modules/Ecocode_Profiler.xml
ADDED
@@ -0,0 +1,9 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Ecocode_Profiler>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</Ecocode_Profiler>
|
8 |
+
</modules>
|
9 |
+
</config>
|
dev.php
ADDED
@@ -0,0 +1,59 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
if ((!isset($_SERVER['ALLOW_PROFILER']) || $_SERVER['ALLOW_PROFILER'] !== '1') && (
|
3 |
+
isset($_SERVER['HTTP_CLIENT_IP'])
|
4 |
+
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|
5 |
+
|| !(in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1']) || php_sapi_name() === 'cli-server')
|
6 |
+
)
|
7 |
+
) {
|
8 |
+
header('HTTP/1.0 403 Forbidden');
|
9 |
+
//exit here, if you do not deploy the profiler on production you can comment these lines
|
10 |
+
exit('You are not allowed to access this file. Check ' . basename(__FILE__) . ' for more information.');
|
11 |
+
}
|
12 |
+
|
13 |
+
if (version_compare(phpversion(), '5.4.0', '<') === true) {
|
14 |
+
throw new RuntimeException('ERROR: Whoops, it looks like you have an invalid PHP version. Magento supports PHP 5.4.0 or newer.');
|
15 |
+
}
|
16 |
+
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Error reporting
|
20 |
+
*/
|
21 |
+
error_reporting(E_ALL | E_STRICT);
|
22 |
+
|
23 |
+
|
24 |
+
define('MAGENTO_ROOT', getcwd());
|
25 |
+
|
26 |
+
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
|
27 |
+
$mageFilename = MAGENTO_ROOT . '/app/MageDev.php';
|
28 |
+
$maintenanceFile = 'maintenance.flag';
|
29 |
+
|
30 |
+
if (!file_exists($mageFilename)) {
|
31 |
+
throw new RuntimeException($mageFilename . " was not found");
|
32 |
+
}
|
33 |
+
|
34 |
+
require_once $mageFilename;
|
35 |
+
require_once PROFILER_DIR . 'debug.php';
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
|
40 |
+
Mage::setIsDeveloperMode(true);
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
umask(0);
|
45 |
+
|
46 |
+
/* Store or website code */
|
47 |
+
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
|
48 |
+
|
49 |
+
/* Run store or run website */
|
50 |
+
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
|
51 |
+
|
52 |
+
|
53 |
+
$options = [
|
54 |
+
'cache' => ['id_prefix' => 'dev'],
|
55 |
+
'config_model' => 'Ecocode_Profiler_Model_Core_Config'
|
56 |
+
];
|
57 |
+
Mage::run($mageRunCode, $mageRunType, $options);
|
58 |
+
|
59 |
+
Mage::terminate();
|
package.xml
ADDED
@@ -0,0 +1,448 @@
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
2 |
+
<root>
|
3 |
+
<name>Ecocode_Profiler</name>
|
4 |
+
<channel>community</channel>
|
5 |
+
<version>1.1.0</version>
|
6 |
+
<description><h1 id="ecocode-profiler-magento-1-x-web-profiler">ecocode Profiler - Magento 1.x Web Profiler</h1>
|
7 |
+
<p><a href="https://travis-ci.org/ecoco/magento_profiler"><img src="https://travis-ci.org/ecoco/magento_profiler.svg?branch=master" alt="Build Status"></a>
|
8 |
+
<a href="https://coveralls.io/github/ecoco/magento_profiler?branch=master"><img src="https://coveralls.io/repos/github/ecoco/magento_profiler/badge.svg?branch=master" alt="Coverage Status"></a>
|
9 |
+
<a href="https://codeclimate.com/github/ecoco/magento_profiler"><img src="https://codeclimate.com/github/ecoco/magento_profiler/badges/gpa.svg" alt="Code Climate"></a>
|
10 |
+
<a href="https://insight.sensiolabs.com/projects/f86c6354-5604-4472-8c59-daa3f71dad54"><img src="https://insight.sensiolabs.com/projects/f86c6354-5604-4472-8c59-daa3f71dad54/mini.png" alt="SensioLabsInsight"></a></p>
|
11 |
+
<p>The ecocode profiler provides a development toolbar for Magento which displays a wide range of metrics and page load data for all the pages of the shop. It gives you direct access to the page&#39;s database queries, memory usage, events, requests, layout rendering, translation resolution and many other useful statistics. It is also easily extendable if you need to track additional metrics.</p>
|
12 |
+
<p>This profiler is based on the awesome <a href="https://github.com/symfony/web-profiler-bundle">Symfony WebProfiler</a>.
|
13 |
+
The concept and code of the WebProfiler have been ported to assist with Magento as much as possible.</p>
|
14 |
+
<h2 id="requirements">Requirements</h2>
|
15 |
+
<ul>
|
16 |
+
<li>php &gt;= 5.5.9</li>
|
17 |
+
<li>magento &lt; 2</li>
|
18 |
+
</ul>
|
19 |
+
<p>Tested with magento
|
20 |
+
1.7, 1.8. 1.9</p>
|
21 |
+
<p>Demo Stores:</p>
|
22 |
+
<ul>
|
23 |
+
<li><a href="http://1.7.0.2.magento-profiler.ecocode.de/dev.php">Profiler with Magento 1.7.0.2</a></li>
|
24 |
+
<li><a href="http://1.8.1.0.magento-profiler.ecocode.de/dev.php">Profiler with Magento 1.8.1.0</a></li>
|
25 |
+
<li><a href="http://1.9.2.4.magento-profiler.ecocode.de/dev.php">Profiler with Magento 1.9.2.4</a></li>
|
26 |
+
</ul>
|
27 |
+
<hr>
|
28 |
+
<p><img src="https://github.com/ecoco/magento_profiler/raw/v1.1.0/docs/image/toolbar.jpg" alt="Toolbar" title="Toolbar"></p>
|
29 |
+
<p><img src="/docs/image/profiler.jpg" alt="Profiler" title="Profiler"></p>
|
30 |
+
<p><a href="docs/images.md">More Images</a></p>
|
31 |
+
<h2 id="installation">Installation</h2>
|
32 |
+
<h3 id="composer-recommended-">Composer (recommended)</h3>
|
33 |
+
<p>If you have not already configured <a href="https://github.com/Cotya/magento-composer-installer">magento-composer-installer</a> add</p>
|
34 |
+
<pre><code>&quot;extra&quot;: {
|
35 |
+
&quot;magento-root-dir&quot;: &quot;httpdocs/&quot;
|
36 |
+
}
|
37 |
+
</code></pre><p>to your <strong>composer.json</strong>. If your magento root dir is the same directory as the one containing your <strong>composer.json</strong> use <code>&quot;.&quot;</code> as the <code>magento-root-dir</code></p>
|
38 |
+
<p><code>composer require --dev ecocode/magento-profiler</code></p>
|
39 |
+
<h3 id="manually">Manually</h3>
|
40 |
+
<p>Download the module and copy the <strong>app</strong> folder + &quot;dev.php&quot; into your magento
|
41 |
+
root directory</p>
|
42 |
+
<p>If you install the module manually, it will miss some functionality until you install
|
43 |
+
the dependencies. This is currently only possible via composer as we do need the composer autoloader.</p>
|
44 |
+
<p>To install the dependencies run the following from your magento root dir or a parent directory:</p>
|
45 |
+
<pre><code>composer require --dev symfony/debug 3.1
|
46 |
+
composer require --dev symfony/yaml 3.1
|
47 |
+
composer require --dev jdorn/sql-formatter 1.2
|
48 |
+
composer require --dev monolog/monolog 1.11
|
49 |
+
</code></pre><h3 id="magento-connect">Magento Connect</h3>
|
50 |
+
<p>In progress</p>
|
51 |
+
<h3 id="webserver-config">Webserver Config</h3>
|
52 |
+
<p>It might be necessary to extend your webserver config to handle &quot;dev.php&quot; correctly</p>
|
53 |
+
<h3 id="nginx-">Nginx:</h3>
|
54 |
+
<p>If you are using nginx and get a <code>404</code> for the profiler, try adding the following to your nginx config before the php location definition:</p>
|
55 |
+
<pre><code>location /dev.php/ {
|
56 |
+
rewrite / /dev.php;
|
57 |
+
}
|
58 |
+
</code></pre><hr>
|
59 |
+
<h4 id="apache-">Apache:</h4>
|
60 |
+
<p>nothing to do here, should run out of the box</p>
|
61 |
+
<h2 id="usage">Usage</h2>
|
62 |
+
<p>The profiler is only enabled if you open your shop via <code>http://myshop.local/dev.php/</code>.
|
63 |
+
The idea is to develop always in dev mode alias &quot;dev.php&quot; and only switch back to &quot;production&quot; from
|
64 |
+
time to time to verify the result.</p>
|
65 |
+
<h2 id="features">Features</h2>
|
66 |
+
<ul>
|
67 |
+
<li>Improved exception handling in dev mode with the <a href="https://github.com/symfony/debug">symfony/debug</a>. No more checking the log files!</li>
|
68 |
+
<li>Easily extendable, just add a new <strong>collector</strong> via your configuration</li>
|
69 |
+
</ul>
|
70 |
+
<h2 id="collectors">Collectors</h2>
|
71 |
+
<ul>
|
72 |
+
<li>Request/Response<ul>
|
73 |
+
<li>Display of request/response server parameters</li>
|
74 |
+
</ul>
|
75 |
+
</li>
|
76 |
+
<li>Memory<ul>
|
77 |
+
<li>Display of memory usage </li>
|
78 |
+
</ul>
|
79 |
+
</li>
|
80 |
+
<li>Mysql<ul>
|
81 |
+
<li>Display of all queries with syntax highlighting and stack traces to locate the origin</li>
|
82 |
+
<li>Queries by context so you can easily determine the origin block</li>
|
83 |
+
<li><strong>Detection of identical</strong> queries that can be avoided</li>
|
84 |
+
<li>Metrics for &quot;mysql crud&quot; operations</li>
|
85 |
+
<li>Support for multiple database connections</li>
|
86 |
+
</ul>
|
87 |
+
</li>
|
88 |
+
<li>Events<ul>
|
89 |
+
<li>Display of all events that have been fired during page load</li>
|
90 |
+
<li>List of all called observers</li>
|
91 |
+
</ul>
|
92 |
+
</li>
|
93 |
+
<li>Ajax<ul>
|
94 |
+
<li>Recording of ajax calls</li>
|
95 |
+
</ul>
|
96 |
+
</li>
|
97 |
+
<li>Customer<ul>
|
98 |
+
<li>Display of customer group and tax class </li>
|
99 |
+
</ul>
|
100 |
+
</li>
|
101 |
+
<li>Layout<ul>
|
102 |
+
<li>Metrics including created and rendered blocks and total rendering time</li>
|
103 |
+
<li>List of layout handlers used</li>
|
104 |
+
<li>List of blocks created but not rendered</li>
|
105 |
+
<li>Call graph including rendering times by block, including and excluding children</li>
|
106 |
+
</ul>
|
107 |
+
</li>
|
108 |
+
<li>Translations<ul>
|
109 |
+
<li>Display of translations that are defined, missing, invalid or are using a fallback</li>
|
110 |
+
</ul>
|
111 |
+
</li>
|
112 |
+
<li>Rewrites<ul>
|
113 |
+
<li>Detection of rewrites and rewrite conflicts (credits to <a href="https://github.com/netz98/n98-magerun">magen98-magerun</a> for the detection)</li>
|
114 |
+
</ul>
|
115 |
+
</li>
|
116 |
+
<li>Logs<ul>
|
117 |
+
<li>Display of all <code>Mage::log</code> calls</li>
|
118 |
+
</ul>
|
119 |
+
</li>
|
120 |
+
<li>Models<ul>
|
121 |
+
<li>Display of all model load, delete and save calls</li>
|
122 |
+
<li><strong>Detection of &quot;load&quot; calls within loops!</strong></li>
|
123 |
+
</ul>
|
124 |
+
</li>
|
125 |
+
<li>Cache<ul>
|
126 |
+
<li>Display of current cache configuration including the option to enable/disable and flush from the profiler</li>
|
127 |
+
<li>Display of all cache calls including not-for-cache <strong>hits</strong> and <strong>misses</strong></li>
|
128 |
+
</ul>
|
129 |
+
</li>
|
130 |
+
<li>Configuration<ul>
|
131 |
+
<li>Base PHP configuration</li>
|
132 |
+
<li>Option to view <code>phpinfo()</code></li>
|
133 |
+
<li>Basic magento configuration</li>
|
134 |
+
<li>Display of enabled and disabled modules</li>
|
135 |
+
</ul>
|
136 |
+
</li>
|
137 |
+
</ul>
|
138 |
+
<h2 id="security">Security</h2>
|
139 |
+
<p>It should be safe to add this module to your own vcs by default. The profiler
|
140 |
+
is only active when you are visiting your page via &quot;dev.php&quot;, which is restricted to
|
141 |
+
localhost by default.</p>
|
142 |
+
<p>If you are using a vm you can edit the <code>dev.php</code> or set <code>$_SERVER[&#39;ALLOW_PROFILER&#39;] = 1</code>
|
143 |
+
via your nginx or htaccess</p>
|
144 |
+
<h2 id="todo">TODO</h2>
|
145 |
+
<ul>
|
146 |
+
<li>Session Data</li>
|
147 |
+
<li>Catch url redirects</li>
|
148 |
+
<li>Improve docs</li>
|
149 |
+
<li>&quot;how to extend&quot;</li>
|
150 |
+
</ul>
|
151 |
+
<h2 id="mixed">Mixed</h2>
|
152 |
+
<p>If you get a <code>gateway timeout 503</code> instead of an error message please try to adjust your
|
153 |
+
nginx config</p>
|
154 |
+
<pre><code>http {
|
155 |
+
...
|
156 |
+
fastcgi_buffers 8 16k;
|
157 |
+
fastcgi_buffer_size 32k;
|
158 |
+
...
|
159 |
+
}
|
160 |
+
</code></pre><h2 id="need-help-">Need help?</h2>
|
161 |
+
<p>Feel free to contact me jk@ecocode.de</p>
|
162 |
+
<h2 id="thanks-to">Thanks to</h2>
|
163 |
+
<ul>
|
164 |
+
<li><a href="https://github.com/symfony/debug">symfony/debug</a> for the awesome debug component</li>
|
165 |
+
<li><a href="https://github.com/netz98/n98-magerun">magen98-magerun</a> for the rewrite conflict detection</li>
|
166 |
+
<li><a href="https://github.com/symfony/web-profiler-bundle">Symfony WebProfiler</a></li>
|
167 |
+
</ul>
|
168 |
+
</description>
|
169 |
+
<summery>Web Profiler for Magento 1.x</summery>
|
170 |
+
<license>MIT</license>
|
171 |
+
<stability>stable</stability>
|
172 |
+
<notes/>
|
173 |
+
<date>2016-10-11</date>
|
174 |
+
<time>19:23:09</time>
|
175 |
+
<authors>
|
176 |
+
<author>
|
177 |
+
<name>Justus Krapp</name>
|
178 |
+
<email>jk@ecocode.de</email>
|
179 |
+
<user>MAG000111800</user>
|
180 |
+
</author>
|
181 |
+
</authors>
|
182 |
+
<dependencies>
|
183 |
+
<required>
|
184 |
+
<php>
|
185 |
+
<min>5.5.9</min>
|
186 |
+
<max>7.0.10</max>
|
187 |
+
</php>
|
188 |
+
</required>
|
189 |
+
</dependencies>
|
190 |
+
<contents>
|
191 |
+
<target name="mage">
|
192 |
+
<file name="dev.php" hash="614dafcdeea3f796b0f2b9111ed3f1e3"/>
|
193 |
+
<dir name="app">
|
194 |
+
<file name="MageDev.php" hash="0c7257cd6c825f65ecdc230e172d9cca"/>
|
195 |
+
</dir>
|
196 |
+
</target>
|
197 |
+
<target name="mageetc">
|
198 |
+
<dir name="modules">
|
199 |
+
<file name="Ecocode_Profiler.xml" hash="7d3910686ef4f32eedfdadf3e3ccdcaf"/>
|
200 |
+
</dir>
|
201 |
+
</target>
|
202 |
+
<target name="magedesign">
|
203 |
+
<dir name="frontend">
|
204 |
+
<dir name="base">
|
205 |
+
<dir name="default">
|
206 |
+
<dir name="layout">
|
207 |
+
<file name="ecocode_profiler.xml" hash="77c53c870841abec7e9b991d3d13be23"/>
|
208 |
+
</dir>
|
209 |
+
<dir name="template">
|
210 |
+
<dir name="ecocode_profiler">
|
211 |
+
<file name="back-trace.phtml" hash="3e87214048db56081377577284b0ed92"/>
|
212 |
+
<file name="bag.phtml" hash="bd4363dfe3f58bb352cd2f7aecc220a0"/>
|
213 |
+
<file name="layout.phtml" hash="4b7a285bcf3811a63089f23de5f7bb2a"/>
|
214 |
+
<file name="toolbar_js.phtml" hash="4c55d25dba7c8528fc12fb132cf95670"/>
|
215 |
+
<file name="toolbar.css.phtml" hash="e69c6cab4024a1c92859bd6d9a5c90bc"/>
|
216 |
+
<file name="toolbar.phtml" hash="8fcffc1866e836ddd02939c67b75cc26"/>
|
217 |
+
<dir name="collector">
|
218 |
+
<dir name="ajax">
|
219 |
+
<file name="toolbar.phtml" hash="82f3f425377c110b2b2931c0a2021b5e"/>
|
220 |
+
</dir>
|
221 |
+
<dir name="base">
|
222 |
+
<file name="menu.phtml" hash="a9ce631d4f2e5f1422e24b85904d266b"/>
|
223 |
+
</dir>
|
224 |
+
<dir name="cache">
|
225 |
+
<file name="menu.phtml" hash="7c84720f0d33760a719d1700fb4aeb90"/>
|
226 |
+
<file name="panel.phtml" hash="4ec12213e351cf5b8ef33710abeee8eb"/>
|
227 |
+
<file name="toolbar.phtml" hash="ef01eabfdee95829d4f4a6e71daac816"/>
|
228 |
+
</dir>
|
229 |
+
<dir name="config">
|
230 |
+
<file name="menu.phtml" hash="3413b99ba04b314a14c1ee3394ea0cde"/>
|
231 |
+
<file name="panel.phtml" hash="c02443a2aacb437474a72c051a60b186"/>
|
232 |
+
<file name="toolbar.phtml" hash="658434996a5dc668093f395663f6872b"/>
|
233 |
+
</dir>
|
234 |
+
<dir name="customer">
|
235 |
+
<file name="toolbar.phtml" hash="0d9c3fcd3ef232d5be1b3057c6db1c28"/>
|
236 |
+
</dir>
|
237 |
+
<dir name="event">
|
238 |
+
<file name="menu.phtml" hash="de69ecbd1f53771890c9156325e80729"/>
|
239 |
+
<file name="panel.phtml" hash="a01c50694d3c17142a43fb75d169b4a0"/>
|
240 |
+
</dir>
|
241 |
+
<dir name="layout">
|
242 |
+
<file name="menu.phtml" hash="f69f33c6d3bd734c3a3742dca91c81bd"/>
|
243 |
+
<file name="panel.phtml" hash="dcaf56b67e95691a2a685b039df53db8"/>
|
244 |
+
<file name="toolbar.phtml" hash="2e9e5942ad2e202ecb36069f4520285f"/>
|
245 |
+
</dir>
|
246 |
+
<dir name="log">
|
247 |
+
<file name="menu.phtml" hash="38c8d9ba8e803dcdffcba07c532e8cfa"/>
|
248 |
+
<file name="panel.phtml" hash="c1580c5591d9ed1e7508223e0440139e"/>
|
249 |
+
<file name="toolbar.phtml" hash="f9f4c1aa7eb6e2b4c5f9fb29c4355c3b"/>
|
250 |
+
<dir name="panel">
|
251 |
+
<file name="log-table.phtml" hash="0d305d9cecc0f8cd2daa559577f22e59"/>
|
252 |
+
</dir>
|
253 |
+
</dir>
|
254 |
+
<dir name="memory">
|
255 |
+
<file name="toolbar.phtml" hash="01d23d6a986ea9a838ff37974814c17d"/>
|
256 |
+
</dir>
|
257 |
+
<dir name="model">
|
258 |
+
<file name="menu.phtml" hash="00a2226bc05b0fef429160ecafd60204"/>
|
259 |
+
<file name="panel.phtml" hash="fb85a775faea43e0fddc3e71179e8310"/>
|
260 |
+
<file name="toolbar.phtml" hash="cbd77333b03d1ade489c249346b4e5fe"/>
|
261 |
+
</dir>
|
262 |
+
<dir name="mysql">
|
263 |
+
<file name="menu.phtml" hash="e9ff757f0330116f232961470ab63ffe"/>
|
264 |
+
<file name="panel.phtml" hash="c291f1492478fe99ffd90efc974d041d"/>
|
265 |
+
<file name="toolbar.phtml" hash="166394a1bef92a73f3a9c60b35249eb9"/>
|
266 |
+
<dir name="panel">
|
267 |
+
<file name="query-table.phtml" hash="68d4a6d2206477ef1d4ecca49ceda721"/>
|
268 |
+
</dir>
|
269 |
+
</dir>
|
270 |
+
<dir name="request">
|
271 |
+
<file name="menu.phtml" hash="45de32145ba7d367dd400ffdfb726295"/>
|
272 |
+
<file name="panel.phtml" hash="2b4543345ad9ab659d165f71b0837539"/>
|
273 |
+
<file name="toolbar.phtml" hash="d31ee40313be5c70d844bf85204432d4"/>
|
274 |
+
</dir>
|
275 |
+
<dir name="rewrite">
|
276 |
+
<file name="menu.phtml" hash="881118b3135e5a2f15e2cb8072b0c2ed"/>
|
277 |
+
<file name="panel.phtml" hash="b354f137b3b6fb4a58d0c1b0018c3273"/>
|
278 |
+
<file name="toolbar.phtml" hash="03f8a4320132fa28a1bdd53b6aeb15bb"/>
|
279 |
+
</dir>
|
280 |
+
<dir name="time">
|
281 |
+
<file name="toolbar.phtml" hash="f32576053b7f4f4e8063eee3ad915d19"/>
|
282 |
+
</dir>
|
283 |
+
<dir name="translation">
|
284 |
+
<file name="menu.phtml" hash="27a3539bb8a93b2cc811e68f5e07a898"/>
|
285 |
+
<file name="panel.phtml" hash="1eef90a79983a141c1db14ca0bcd2afb"/>
|
286 |
+
<file name="toolbar.phtml" hash="12702548344ed6a63487394201f0eb56"/>
|
287 |
+
<dir name="panel">
|
288 |
+
<file name="table.phtml" hash="e0f080dbe249cede69b8f566dd7be82c"/>
|
289 |
+
</dir>
|
290 |
+
</dir>
|
291 |
+
</dir>
|
292 |
+
<dir name="layout">
|
293 |
+
<file name="sidebar.phtml" hash="0cdebfdd9daabcd6e8d36d13c094fb59"/>
|
294 |
+
<dir name="sidebar">
|
295 |
+
<file name="menu.phtml" hash="5ba837a64ccb3ade9e178a67865b0363"/>
|
296 |
+
</dir>
|
297 |
+
</dir>
|
298 |
+
<dir name="profiler">
|
299 |
+
<file name="base.css.phtml" hash="5aa4306149ccb84867915bce7e4a5f12"/>
|
300 |
+
<file name="base.js.phtml" hash="dc8fdc11af0a8458aceee4766e337620"/>
|
301 |
+
<file name="summery.phtml" hash="9a71359e8e47ded85f55299aed93371e"/>
|
302 |
+
<dir name="search">
|
303 |
+
<file name="results.phtml" hash="970d81fff56177afcc882f8efb467f7e"/>
|
304 |
+
<file name="summery.phtml" hash="7d3e70179beef079a5efde9fea6dd504"/>
|
305 |
+
</dir>
|
306 |
+
</dir>
|
307 |
+
<dir name="renderer">
|
308 |
+
<file name="context.phtml" hash="38f3f9e0b17f96eb6e01332e78337f55"/>
|
309 |
+
</dir>
|
310 |
+
</dir>
|
311 |
+
</dir>
|
312 |
+
</dir>
|
313 |
+
</dir>
|
314 |
+
</dir>
|
315 |
+
</target>
|
316 |
+
<target name="magecommunity">
|
317 |
+
<dir name="Ecocode">
|
318 |
+
<dir name="Profiler">
|
319 |
+
<file name="autoloader.php" hash="625350c21fc1ce3b298e5cef41198308"/>
|
320 |
+
<file name="debug.php" hash="f5b9e0a679f16a948f540b2e7fa6c25b"/>
|
321 |
+
<dir name="Block">
|
322 |
+
<file name="Bag.php" hash="6f574bbd70410b7cc4198c88131ab9fd"/>
|
323 |
+
<file name="Toolbar.php" hash="f1a247c7cc273598d80d0b3c69263536"/>
|
324 |
+
<dir name="Collector">
|
325 |
+
<file name="Base.php" hash="8f6852999389c3e6159c93a8dc21a3a7"/>
|
326 |
+
<file name="Menu.php" hash="be064554e1868ef0d06d0a9393fbe460"/>
|
327 |
+
<dir name="Layout">
|
328 |
+
<file name="Panel.php" hash="a3250d15e46573d07e6be930bff09bbc"/>
|
329 |
+
</dir>
|
330 |
+
<dir name="Log">
|
331 |
+
<file name="Panel.php" hash="7836cb8d57f778765c433e1887908aac"/>
|
332 |
+
</dir>
|
333 |
+
<dir name="Mysql">
|
334 |
+
<file name="Panel.php" hash="95c41d688e01ab371a8b74a207342e07"/>
|
335 |
+
</dir>
|
336 |
+
<dir name="Translation">
|
337 |
+
<file name="Panel.php" hash="f3da35eb4848ad9bc8baa99f89ae6748"/>
|
338 |
+
</dir>
|
339 |
+
</dir>
|
340 |
+
<dir name="Profiler">
|
341 |
+
<file name="Sidebar.php" hash="9b0727ba0af64f5f4f395c36d32b0bcc"/>
|
342 |
+
<dir name="Sidebar">
|
343 |
+
<file name="Menu.php" hash="b336bdb43b417d00b6c4e8aeed306c0e"/>
|
344 |
+
</dir>
|
345 |
+
</dir>
|
346 |
+
<dir name="Renderer">
|
347 |
+
<file name="AbstractRenderer.php" hash="451a64191ddd17741195511b357179f0"/>
|
348 |
+
<file name="BackTrace.php" hash="7bf2d900481bed0c5a06613ab687b7ef"/>
|
349 |
+
<file name="Context.php" hash="d570e34a9565e3cad0781ee354bd4ef9"/>
|
350 |
+
<file name="RendererInterface.php" hash="a34a484b2c7859696c214ade11208b04"/>
|
351 |
+
<dir name="Log">
|
352 |
+
<file name="LogTable.php" hash="ace6bc645cbbcd0f5fb4cfd9b08e6859"/>
|
353 |
+
</dir>
|
354 |
+
<dir name="Mysql">
|
355 |
+
<file name="QueryTable.php" hash="38a9b601e5f1379285d07e4361d94ac1"/>
|
356 |
+
</dir>
|
357 |
+
</dir>
|
358 |
+
</dir>
|
359 |
+
<dir name="Controller">
|
360 |
+
<file name="AbstractController.php" hash="df479a9daa699be75d49930cc7468648"/>
|
361 |
+
</dir>
|
362 |
+
<dir name="controllers">
|
363 |
+
<file name="CacheController.php" hash="cba1eefa1c5b487abbd44eaa6167900b"/>
|
364 |
+
<file name="IndexController.php" hash="263e2bf4631e037fb61a5d1f131cb555"/>
|
365 |
+
</dir>
|
366 |
+
<dir name="Db">
|
367 |
+
<dir name="Statement">
|
368 |
+
<dir name="Pdo">
|
369 |
+
<file name="Mysql.php" hash="a9772c14b6e5d517e4a1900210ec76fe"/>
|
370 |
+
</dir>
|
371 |
+
</dir>
|
372 |
+
</dir>
|
373 |
+
<dir name="etc">
|
374 |
+
<file name="config.xml" hash="3e655889fd41aa91071c68fa0b63d93e"/>
|
375 |
+
<file name="development.xml" hash="569481da5b5fc6a17e0f69747ddb41be"/>
|
376 |
+
</dir>
|
377 |
+
<dir name="Helper">
|
378 |
+
<file name="AbstractHelper.php" hash="f3b8fc47c99b7a9f492c09ee38d2a4dd"/>
|
379 |
+
<file name="Code.php" hash="5cd26ca017a787618fdf552e48ac0f72"/>
|
380 |
+
<file name="Context.php" hash="c8d0d66a13a558b26092fbe375643819"/>
|
381 |
+
<file name="Data.php" hash="d2a72158860ba97e4c493bec643e2bed"/>
|
382 |
+
<file name="Renderer.php" hash="5129f2242f9456cb72cd10fb205531af"/>
|
383 |
+
<file name="Rewrite.php" hash="5d14a5cade6df7fe4f0fdb14b381d21c"/>
|
384 |
+
<file name="Sql.php" hash="2daba313727d3376f63f5096f4c67532"/>
|
385 |
+
<file name="ValueExporter.php" hash="d5c47a798bf0bc63e22ac8e530c97513"/>
|
386 |
+
</dir>
|
387 |
+
<dir name="Model">
|
388 |
+
<file name="AppDev.php" hash="3452f2a7476bda585f2e117fe6b2007f"/>
|
389 |
+
<file name="Context.php" hash="6f88c38762b1cea9b61dceffa28d4bfe"/>
|
390 |
+
<file name="ContextInterface.php" hash="6fa0b665a1f66469072c7a15064241fe"/>
|
391 |
+
<file name="DebugLoggerInterface.php" hash="fb77da964513216bced10423f9e9ef79"/>
|
392 |
+
<file name="Logger.php" hash="6b7a41a4b32d61c757291f4611bcb065"/>
|
393 |
+
<file name="Observer.php" hash="d470dd34415b67c1d210322cafbe6b52"/>
|
394 |
+
<file name="Profile.php" hash="b109854a402cb400d689939db515a8f7"/>
|
395 |
+
<file name="Profiler.php" hash="d656aa79765761d6af7d41c0692db62c"/>
|
396 |
+
<dir name="Collector">
|
397 |
+
<file name="AbstractDataCollector.php" hash="7a58e7a7f781fcb25596ec454a0941fa"/>
|
398 |
+
<file name="AjaxDataCollector.php" hash="8abe36cbc71801d9509a1607cb510872"/>
|
399 |
+
<file name="CacheDataCollector.php" hash="121234aaeff67cfb7e367f4d0ea6ca74"/>
|
400 |
+
<file name="ConfigDataCollector.php" hash="2717afc87c5c67af0b09219c14ebb10f"/>
|
401 |
+
<file name="ContextDataCollector.php" hash="ea8e04938af2e1ec2a095306d8c0a07d"/>
|
402 |
+
<file name="CustomerDataCollector.php" hash="b49edceafe5c60a2ffb96dc3c62b4a82"/>
|
403 |
+
<file name="DataCollectorInterface.php" hash="33082cfb75eedf75b6af2c6afac3d782"/>
|
404 |
+
<file name="EventDataCollector.php" hash="b54c69b72dd4694c33a8934c4588aa14"/>
|
405 |
+
<file name="LateDataCollectorInterface.php" hash="11f0136ac985fbadde129c2de7082df1"/>
|
406 |
+
<file name="LayoutDataCollector.php" hash="a0161acecfe24eae72f1a23055d8dd31"/>
|
407 |
+
<file name="LogDataCollector.php" hash="ed5554e57957606f11debbf4f5d3b6a9"/>
|
408 |
+
<file name="MemoryDataCollector.php" hash="6b9df2616c98fb717fe987650b05e839"/>
|
409 |
+
<file name="ModelDataCollector.php" hash="1942b69c4b7e205e85a03f400f25e357"/>
|
410 |
+
<file name="MysqlDataCollector.php" hash="6b22fb7c698632f38516ae67f5e72e3e"/>
|
411 |
+
<file name="RequestDataCollector.php" hash="2a7c8fcea477da650c6fde974fdddd54"/>
|
412 |
+
<file name="RewriteDataCollector.php" hash="94c7822840a6a8e56662df45c3c05a13"/>
|
413 |
+
<file name="TimeDataCollector.php" hash="9ba56d95b0cdf1b736ec09c101bcc17a"/>
|
414 |
+
<file name="TranslationDataCollector.php" hash="f2dbb421aded73ecad1d28288c0852f2"/>
|
415 |
+
</dir>
|
416 |
+
<dir name="Core">
|
417 |
+
<file name="Cache.php" hash="4d5153b5ef8d3f32b01a20b6f33a694c"/>
|
418 |
+
<file name="Config.php" hash="57785aff3f8db11bbbea1f29b6c30ad3"/>
|
419 |
+
</dir>
|
420 |
+
<dir name="Http">
|
421 |
+
<file name="HeaderBag.php" hash="271c1a70189c1be4c2016274528df777"/>
|
422 |
+
<file name="ParameterBag.php" hash="07feaabf7c5c355c330624f94d3a4073"/>
|
423 |
+
<file name="ResponseHeaderBag.php" hash="d27b8d35c3a4fc7ff050f5971ffea835"/>
|
424 |
+
</dir>
|
425 |
+
<dir name="Logger">
|
426 |
+
<file name="DebugHandler.php" hash="2e64a8afb1f054668992ab9026155988"/>
|
427 |
+
</dir>
|
428 |
+
<dir name="Observer">
|
429 |
+
<file name="Context.php" hash="46486a8e8d854dc8c022addae27eb713"/>
|
430 |
+
</dir>
|
431 |
+
<dir name="Profiler">
|
432 |
+
<file name="FileStorage.php" hash="0f7b9b499d7d0ef070db55d00608d086"/>
|
433 |
+
<file name="StorageInterface.php" hash="fe90e695474f4354bd6481d904c6c56c"/>
|
434 |
+
</dir>
|
435 |
+
</dir>
|
436 |
+
<dir name="overwrite">
|
437 |
+
<file name="Mage.php" hash="6141bb3e6e7e307d37e4bc9d92a409da"/>
|
438 |
+
<file name="MageCoreModelResource.php" hash="f800cbedca91b1ffbd522b7e2e9262ca"/>
|
439 |
+
<file name="MageCoreModelResourceDbAbstract.php" hash="1cac148b8666cf267f8d3cfeca80a114"/>
|
440 |
+
<file name="MageCoreModelStore.php" hash="8b254445c375ecba32f02eb67566b759"/>
|
441 |
+
<file name="MageCoreModelTranslate.php" hash="981b052d60c99afbfce2499d624438de"/>
|
442 |
+
<file name="MageEavModelEntityAbstract.php" hash="2f8f6ed49f554d0eb68a6ccf83464a5b"/>
|
443 |
+
</dir>
|
444 |
+
</dir>
|
445 |
+
</dir>
|
446 |
+
</target>
|
447 |
+
</contents>
|
448 |
+
</root>
|