├── .codeclimate.yml ├── .coveralls.yml ├── .gitignore ├── .sensiolabs.yml ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── app ├── MageDev.php ├── code │ └── community │ │ └── Ecocode │ │ └── Profiler │ │ ├── Block │ │ ├── Collector │ │ │ ├── Base.php │ │ │ ├── Layout │ │ │ │ └── Panel.php │ │ │ ├── Log │ │ │ │ └── Panel.php │ │ │ ├── Menu.php │ │ │ ├── Mysql │ │ │ │ └── Panel.php │ │ │ ├── Request │ │ │ │ └── Toolbar.php │ │ │ ├── Time │ │ │ │ └── Panel.php │ │ │ └── Translation │ │ │ │ └── Panel.php │ │ ├── Profiler │ │ │ ├── Settings.php │ │ │ ├── Sidebar.php │ │ │ └── Sidebar │ │ │ │ └── Menu.php │ │ ├── Renderer │ │ │ ├── AbstractRenderer.php │ │ │ ├── Bag.php │ │ │ ├── CallStack.php │ │ │ ├── Context.php │ │ │ ├── Log │ │ │ │ └── LogTable.php │ │ │ ├── Mysql │ │ │ │ └── QueryTable.php │ │ │ ├── RendererInterface.php │ │ │ ├── Request │ │ │ │ └── ToolbarHandler.php │ │ │ ├── Settings │ │ │ │ ├── Field.php │ │ │ │ └── Row.php │ │ │ └── Table.php │ │ └── Toolbar.php │ │ ├── Controller │ │ └── AbstractController.php │ │ ├── Db │ │ └── Statement │ │ │ └── Pdo │ │ │ └── Mysql.php │ │ ├── Helper │ │ ├── AbstractHelper.php │ │ ├── Code.php │ │ ├── Context.php │ │ ├── Data.php │ │ ├── Renderer.php │ │ ├── Rewrite.php │ │ ├── Sql.php │ │ └── ValueExporter.php │ │ ├── Model │ │ ├── AppDev.php │ │ ├── Collector │ │ │ ├── AbstractDataCollector.php │ │ │ ├── AjaxDataCollector.php │ │ │ ├── CacheDataCollector.php │ │ │ ├── ConfigDataCollector.php │ │ │ ├── ContextDataCollector.php │ │ │ ├── CustomerDataCollector.php │ │ │ ├── DataCollectorInterface.php │ │ │ ├── EventDataCollector.php │ │ │ ├── LateDataCollectorInterface.php │ │ │ ├── LayoutDataCollector.php │ │ │ ├── LogDataCollector.php │ │ │ ├── MemoryDataCollector.php │ │ │ ├── ModelDataCollector.php │ │ │ ├── MysqlDataCollector.php │ │ │ ├── RequestDataCollector.php │ │ │ ├── RewriteDataCollector.php │ │ │ ├── TimeDataCollector.php │ │ │ └── TranslationDataCollector.php │ │ ├── Config.php │ │ ├── Context.php │ │ ├── ContextInterface.php │ │ ├── Core │ │ │ ├── Cache.php │ │ │ └── Config.php │ │ ├── Http │ │ │ ├── HeaderBag.php │ │ │ ├── ParameterBag.php │ │ │ └── ResponseHeaderBag.php │ │ ├── Logger.php │ │ ├── Logger │ │ │ ├── DebugHandler.php │ │ │ └── DebugHandlerInterface.php │ │ ├── LoggerInterface.php │ │ ├── NullLogger.php │ │ ├── Observer.php │ │ ├── Observer │ │ │ └── Context.php │ │ ├── Profile.php │ │ ├── Profiler.php │ │ ├── Profiler │ │ │ ├── FileStorage.php │ │ │ └── StorageInterface.php │ │ └── Session.php │ │ ├── Tests │ │ ├── Dev │ │ │ ├── Block │ │ │ │ ├── Collector │ │ │ │ │ ├── Layout │ │ │ │ │ │ └── PanelTest.php │ │ │ │ │ ├── Mysql │ │ │ │ │ │ └── PanelTest.php │ │ │ │ │ └── Time │ │ │ │ │ │ └── PanelTest.php │ │ │ │ └── Renderer │ │ │ │ │ ├── BagTest.php │ │ │ │ │ ├── Settings │ │ │ │ │ └── FieldTest.php │ │ │ │ │ └── TableTest.php │ │ │ ├── Controller │ │ │ │ └── AbstractControllerTest.php │ │ │ ├── DevModeTest.php │ │ │ ├── Fixtures │ │ │ │ ├── .profiler.conf.json │ │ │ │ ├── DummyCacheBackend.php │ │ │ │ ├── ResponseHttp.php │ │ │ │ ├── config.json │ │ │ │ └── renderer │ │ │ │ │ └── settings │ │ │ │ │ └── field.phtml │ │ │ ├── Helper │ │ │ │ ├── CodeTest.php │ │ │ │ ├── ContextTest.php │ │ │ │ ├── DataTest.php │ │ │ │ ├── RendererTest.php │ │ │ │ ├── RewriteTest.php │ │ │ │ ├── SqlTest.php │ │ │ │ └── ValueExporterTest.php │ │ │ ├── Model │ │ │ │ ├── Collector │ │ │ │ │ ├── CacheDataCollectorTest.php │ │ │ │ │ ├── ConfigCollectorTest.php │ │ │ │ │ ├── ContextDataCollectorTest.php │ │ │ │ │ ├── CustomerDataCollectorTest.php │ │ │ │ │ ├── EventDataCollectorTest.php │ │ │ │ │ ├── LayoutDataCollectorTest.php │ │ │ │ │ ├── LogDataCollectorTest.php │ │ │ │ │ ├── MemoryDataCollectorTest.php │ │ │ │ │ ├── ModelDataCollectorTest.php │ │ │ │ │ ├── MysqlDataCollectorTest.php │ │ │ │ │ ├── RequestDataCollectorTest.php │ │ │ │ │ ├── RewriteDataCollectorTest.php │ │ │ │ │ ├── TimeDataCollectorTest.php │ │ │ │ │ └── TranslationDataCollectorTest.php │ │ │ │ ├── ConfigTest.php │ │ │ │ ├── Http │ │ │ │ │ ├── HeaderBagTest.php │ │ │ │ │ ├── ParameterBagTest.php │ │ │ │ │ └── ResponseHeaderBagTest.php │ │ │ │ ├── LoggerTest.php │ │ │ │ ├── Observer │ │ │ │ │ └── ContextTest.php │ │ │ │ ├── ObserverTest.php │ │ │ │ ├── Overwrite │ │ │ │ │ ├── MageCoreModelResourceDbAbstractTest.php │ │ │ │ │ ├── MageCoreModelResourceTest.php │ │ │ │ │ ├── MageCoreModelTranslateTest.php │ │ │ │ │ ├── MageEavModelEntityAbstractTest.php │ │ │ │ │ ├── MageTest.php │ │ │ │ │ └── VarienProfilerTest.php │ │ │ │ ├── Profiler │ │ │ │ │ └── FileStorageTest.php │ │ │ │ └── ProfilerTest.php │ │ │ ├── bootstrap.php │ │ │ └── controllers │ │ │ │ ├── CacheControllerTest.php │ │ │ │ └── SettingsControllerTest.php │ │ ├── Prod │ │ │ ├── DevModeTest.php │ │ │ └── bootstrap.php │ │ ├── TestControllerHelper.php │ │ └── TestHelper.php │ │ ├── autoloader.php │ │ ├── controllers │ │ ├── CacheController.php │ │ ├── IndexController.php │ │ └── SettingsController.php │ │ ├── debug.php │ │ ├── etc │ │ ├── config.json │ │ ├── config.xml │ │ └── development.xml │ │ └── overwrite │ │ ├── Mage.php │ │ ├── MageCoreModelResource.php │ │ ├── MageCoreModelResourceDbAbstract.php │ │ ├── MageCoreModelStore.php │ │ ├── MageCoreModelTranslate.php │ │ ├── MageEavModelEntityAbstract.php │ │ └── VarienProfiler.php ├── design │ └── frontend │ │ └── base │ │ └── default │ │ ├── layout │ │ └── ecocode_profiler.xml │ │ └── template │ │ └── ecocode_profiler │ │ ├── collector │ │ ├── ajax │ │ │ └── toolbar.phtml │ │ ├── base │ │ │ └── menu.phtml │ │ ├── cache │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ ├── config │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ ├── customer │ │ │ └── toolbar.phtml │ │ ├── event │ │ │ ├── menu.phtml │ │ │ └── panel.phtml │ │ ├── layout │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ ├── log │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ ├── panel │ │ │ │ └── log-table.phtml │ │ │ └── toolbar.phtml │ │ ├── memory │ │ │ └── toolbar.phtml │ │ ├── model │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ ├── mysql │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ ├── panel │ │ │ │ └── query-table.phtml │ │ │ ├── settings.phtml │ │ │ └── toolbar.phtml │ │ ├── request │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ ├── toolbar.phtml │ │ │ └── toolbar │ │ │ │ └── handler.phtml │ │ ├── rewrite │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ ├── time │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ └── toolbar.phtml │ │ └── translation │ │ │ ├── menu.phtml │ │ │ ├── panel.phtml │ │ │ ├── panel │ │ │ └── table.phtml │ │ │ └── toolbar.phtml │ │ ├── layout.phtml │ │ ├── layout │ │ ├── sidebar.phtml │ │ └── sidebar │ │ │ └── menu.phtml │ │ ├── profiler │ │ ├── base.js.phtml │ │ ├── search │ │ │ ├── results.phtml │ │ │ └── summery.phtml │ │ └── summery.phtml │ │ ├── renderer │ │ ├── bag.phtml │ │ ├── call-stack.phtml │ │ ├── context.phtml │ │ ├── settings │ │ │ ├── input.phtml │ │ │ ├── row.phtml │ │ │ └── select.phtml │ │ └── table.phtml │ │ ├── settings │ │ ├── menu.phtml │ │ └── panel.phtml │ │ ├── toolbar.css.phtml │ │ ├── toolbar.phtml │ │ └── toolbar_js.phtml └── etc │ └── modules │ └── Ecocode_Profiler.xml ├── composer.json ├── dev.php ├── docs ├── image │ ├── collector │ │ ├── event_panel_fired.jpg │ │ ├── layout_panel.jpg │ │ ├── log_panel.jpg │ │ ├── model_panel_all.jpg │ │ ├── model_panel_loop_loads.jpg │ │ ├── mysql_panel_context.jpg │ │ ├── mysql_panel_identical.jpg │ │ ├── rewrite_panel.jpg │ │ └── time_panel.jpg │ ├── profiler.jpg │ └── toolbar.jpg └── images.md ├── js └── ecocode_profiler │ ├── profiler.js │ └── vendor │ ├── jquery.min.js │ └── stupidtable.min.js ├── modman ├── phpmd-ruleset.xml ├── phpunit-dev.xml.dist ├── phpunit-prod.xml.dist ├── skin └── frontend │ └── base │ └── default │ └── css │ └── ecocode_profiler │ ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 │ ├── profiler.css │ └── vendor │ └── font-awesome.min.css └── travis-install.sh /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | duplication: 3 | enabled: true 4 | config: 5 | languages: 6 | - javascript 7 | - php 8 | fixme: 9 | enabled: true 10 | phpmd: 11 | enabled: true 12 | config: 13 | file_extensions: "php" 14 | rulesets: "phpmd-ruleset.xml" 15 | #disable check class camelCaseFirst 16 | # phpcodesniffer: 17 | # enabled: true 18 | 19 | ratings: 20 | paths: 21 | - "**.js" 22 | - "**.php" 23 | exclude_paths: 24 | - "app/code/community/Ecocode/Profiler/Tests/" 25 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | coverage_clover: build/logs/clover.xml 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | build/ 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.sensiolabs.yml: -------------------------------------------------------------------------------- 1 | exclude_patterns: 2 | - 'dev.php' 3 | - '*.css.phtml' 4 | - '*.js.phtml' 5 | 6 | rules: 7 | php.psr1: 8 | enabled: false 9 | #no way to get around this with the magento autoloader 10 | php.silenced_error: 11 | enabled: false 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: php 3 | dist: trusty 4 | php: 5 | - 7.1 6 | - 5.6 7 | - 5.5 8 | 9 | env: 10 | - MAGENTO_VERSION=magento-mirror-1.9.4.1 11 | - MAGENTO_VERSION=magento-mirror-1.9.3.10 12 | - MAGENTO_VERSION=magento-mirror-1.8.1.0 13 | - MAGENTO_VERSION=ecocode-mirror-1.7.0.2 14 | 15 | matrix: 16 | include: 17 | - php: 7.1 18 | env: MAGENTO_VERSION=magento-mirror-1.9.4.1 NO_DEPS=1 19 | 20 | services: 21 | - mysql 22 | 23 | # Deletes build directory and adds new tools 24 | install: 25 | # Clean build directory 26 | - rm -rf build; mkdir build; cd build 27 | 28 | # install modman 29 | - bash < <(wget -q --no-check-certificate -O - https://raw.github.com/colinmollenhour/modman/master/modman-installer) 30 | - modman --version 31 | 32 | # install n98-magerun 33 | - wget --no-check-certificate https://files.magerun.net/n98-magerun.phar 34 | - chmod +x n98-magerun.phar 35 | - ./n98-magerun.phar --version 36 | 37 | - export PATH=$PWD:$PATH 38 | 39 | before_script: 40 | - cd $TRAVIS_BUILD_DIR 41 | - ./travis-install.sh 42 | 43 | script: 44 | - cd $TRAVIS_BUILD_DIR 45 | - mkdir -p build/logs 46 | 47 | - cd $TRAVIS_BUILD_DIR/build/magento 48 | - cp $TRAVIS_BUILD_DIR/phpunit-prod.xml.dist . 49 | - cp $TRAVIS_BUILD_DIR/phpunit-dev.xml.dist . 50 | - php $TRAVIS_BUILD_DIR/util/phpunit.phar -c phpunit-prod.xml.dist && php $TRAVIS_BUILD_DIR/util/phpunit.phar -c phpunit-dev.xml.dist --coverage-clover $TRAVIS_BUILD_DIR/build/logs/clover.xml 51 | 52 | after_success: 53 | - cd $TRAVIS_BUILD_DIR 54 | - travis_retry $TRAVIS_BUILD_DIR/util/vendor/bin/php-coveralls -v 55 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | CHANGELOG 2 | ========= 3 | 4 | 1.3.0 5 | ----- 6 | * introduced a settings section which will allow adjust some settings to your needs 7 | * improved ssl handling 8 | * improved handling of "xdebug.file_link_format" 9 | * improved context display to make use of "file_link_format" 10 | * added timings to event collector 11 | * made tables sortable 12 | * added profile size in MB to search results 13 | * added purge profile button to search result page 14 | * introduced a replacement for the Varien_Profiler 15 | * introduced new "Performance" Tab 16 | 17 | 1.2.1 18 | ----- 19 | * fix for #1 Not working in secure environment with magento 1.9.2 (https://) 20 | * fix for #6 Undefined index error in layout data collector 21 | * added magento 1.9.3 to test stack 22 | 23 | 1.2.0 24 | ----- 25 | * fixed an exception in debug mode when block output is suppressed with "disable module output" 26 | * fixed an exception when logging and monolog is not installed 27 | * unified call stack rendering 28 | * improved request collector to capture also redirects, session data and flash messages 29 | * improved support for "xdebug.file_link_format" to also work with urls like "http://localhost:63342/api/file/%f:%l" 30 | 31 | 1.1.0 32 | ----- 33 | * improved logger, will now also display deprecations 34 | * added unit tests 35 | * small toolbar adjustments 36 | * general clean up 37 | * cleaned up overwrite logic 38 | 39 | 1.0.1 40 | ----- 41 | 42 | * added the new "model" collector 43 | * minor improvements into the documentation 44 | * small stability fixes 45 | * improved event data collector + display, now also showing the observers 46 | * added clear/enable/disable caches actions to the toolbar 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 ecocode GmbH 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /app/MageDev.php: -------------------------------------------------------------------------------- 1 | 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 | if (@class_exists('Symfony\Component\Stopwatch\Stopwatch')) { 37 | $autoloader->addOverwrite('Varien_Profiler', 'VarienProfiler.php'); 38 | } 39 | 40 | require_once $profilerDir . 'Helper' . DIRECTORY_SEPARATOR . 'Data.php'; 41 | 42 | require_once $overwriteBasePath . 'Mage.php'; 43 | 44 | //load overwrites so we can get around the autoloader 45 | Mage::setRoot(MAGENTO_ROOT . DIRECTORY_SEPARATOR . 'app'); 46 | 47 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Base.php: -------------------------------------------------------------------------------- 1 | collector = $collector; 26 | 27 | return $this; 28 | } 29 | 30 | /** 31 | * @codeCoverageIgnore 32 | * @return Ecocode_Profiler_Model_Collector_DataCollectorInterface 33 | */ 34 | public function getCollector() 35 | { 36 | return $this->collector; 37 | } 38 | 39 | /** 40 | * @codeCoverageIgnore 41 | * @return Ecocode_Profiler_Model_Profile 42 | */ 43 | public function getProfile() 44 | { 45 | if ($this->profile === null) { 46 | $this->profile = Mage::registry('current_profile'); 47 | } 48 | return $this->profile; 49 | } 50 | 51 | /** 52 | * @codeCoverageIgnore 53 | * @return Ecocode_Profiler_Helper_Renderer 54 | */ 55 | public function getRendererHelper() 56 | { 57 | if ($this->rendererHelper === null) { 58 | $this->rendererHelper = Mage::helper('ecocode_profiler/renderer'); 59 | } 60 | 61 | return $this->rendererHelper; 62 | } 63 | 64 | public function getToken() 65 | { 66 | return $this->getProfile()->getToken(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Log/Panel.php: -------------------------------------------------------------------------------- 1 | '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 | } 99 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Menu.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/collector/base/menu.phtml'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Request/Toolbar.php: -------------------------------------------------------------------------------- 1 | getRendererHelper()->getInstance('request_toolbarHandler'); 12 | 13 | return $renderer->render( 14 | ['controller' => $controller, 'route' => $route, 'method' => $method] 15 | ); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Time/Panel.php: -------------------------------------------------------------------------------- 1 | getCollector()->getEvents(); 13 | $events = []; 14 | foreach ($eventList as $name => $event) { 15 | /** @var \Symfony\Component\Stopwatch\StopwatchEvent $event */ 16 | if ($name === '__section__' || $name === 'mage') { 17 | continue; 18 | } 19 | $periods = []; 20 | foreach ($event->getPeriods() as $period) { 21 | $periods[] = [ 22 | 'start' => sprintf('%F', $period->getStartTime()), 23 | 'end' => sprintf('%F', $period->getEndTime()) 24 | ]; 25 | } 26 | 27 | $events[] = [ 28 | 'name' => $name, 29 | 'category' => $event->getCategory(), 30 | 'origin' => sprintf('%F', $event->getOrigin()), 31 | 'starttime' => sprintf('%F', $event->getStartTime()), 32 | 'endtime' => sprintf('%F', $event->getEndTime()), 33 | 'duration' => sprintf('%F', $event->getDuration()), 34 | 'memory' => sprintf('%.1F', $event->getMemory() / 1024 / 1024), 35 | 'periods' => $periods 36 | ]; 37 | } 38 | 39 | return [ 40 | 'id' => $this->getToken(), 41 | 'left' => $eventList['__section__']->getStartTime(), 42 | 'events' => $events 43 | ]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Collector/Translation/Panel.php: -------------------------------------------------------------------------------- 1 | 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 | } 34 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Profiler/Settings.php: -------------------------------------------------------------------------------- 1 | getLayout(); 12 | foreach ($this->getCollectors() as $collector) { 13 | /** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */ 14 | 15 | $blockName = sprintf('profiler.%s.settings', $collector->getName()); 16 | if (!$block = $layout->getBlock($blockName)) { 17 | continue; 18 | } 19 | $block->setCollector($collector); 20 | $blocks[$collector->getName()] = $block; 21 | } 22 | 23 | return $blocks; 24 | } 25 | 26 | 27 | public function getCollectors() 28 | { 29 | return Mage::getSingleton('ecocode_profiler/profiler')->getDataCollectors(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar.php: -------------------------------------------------------------------------------- 1 | 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 | } 34 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Profiler/Sidebar/Menu.php: -------------------------------------------------------------------------------- 1 | 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 | } 46 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/AbstractRenderer.php: -------------------------------------------------------------------------------- 1 | setData($data); 21 | $html = $this->renderView(); 22 | 23 | $this->unsetData(); 24 | return $html; 25 | } 26 | 27 | public function getTemplateFile() 28 | { 29 | $template = $this->getTemplate(); 30 | $key = $this->getArea() . '_' . $template; 31 | 32 | if (!isset($this->_templateFileCache[$key])) { 33 | $this->_templateFileCache[$key] = parent::getTemplateFile(); 34 | } 35 | 36 | return $this->_templateFileCache[$key]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Bag.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/renderer/bag.phtml'); 14 | parent::_construct(); 15 | } 16 | 17 | public function getLabels() 18 | { 19 | $labels = $this->getData('labels'); 20 | 21 | return $labels ? $labels : []; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/CallStack.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/renderer/call-stack.phtml'); 14 | parent::_construct(); 15 | } 16 | 17 | public function getStackId() 18 | { 19 | $id = $this->getData('id'); 20 | if (!$id) { 21 | $this->setData('id', uniqid()); 22 | } 23 | 24 | return $id; 25 | } 26 | 27 | public function getStack() 28 | { 29 | $trace = $this->getData('stack'); 30 | if (!$trace) { 31 | return []; 32 | } 33 | 34 | return $trace; 35 | } 36 | 37 | public function shouldWarp() 38 | { 39 | $wrap = $this->getData('wrap'); 40 | 41 | return $wrap === null ? true : $wrap; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Context.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/renderer/context.phtml'); 17 | parent::_construct(); 18 | } 19 | 20 | public function getContextData() 21 | { 22 | /** @var Ecocode_Profiler_Model_Context $context */ 23 | $context = $this->getData('context'); 24 | 25 | $data = $context->getData(); 26 | if (isset($data['class'])) { 27 | $reflector = new ReflectionClass($data['class']); 28 | $data['class'] = $this->getCodeHelper() 29 | ->formatFile($reflector->getFileName(), $reflector->getStartLine(), $data['class']); 30 | } 31 | 32 | if (isset($data['template'])) { 33 | $template = $this->getDesignBaseDir() . $data['template']; 34 | $data['template'] = $this->getCodeHelper() 35 | ->formatFile($template, null, $data['template']); 36 | } 37 | 38 | return $data; 39 | } 40 | 41 | /** 42 | * @codeCoverageIgnore 43 | * @return string 44 | */ 45 | protected function getDesignBaseDir() 46 | { 47 | return Mage::getBaseDir('design') . DS; 48 | } 49 | 50 | /** 51 | * @codeCoverageIgnore 52 | * @return Ecocode_Profiler_Helper_Code 53 | */ 54 | protected function getCodeHelper() 55 | { 56 | if ($this->codeHelper === null) { 57 | /** @var Ecocode_Profiler_Helper_Code $codeHelper */ 58 | $this->codeHelper = Mage::helper('ecocode_profiler/code'); 59 | } 60 | 61 | return $this->codeHelper; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Log/LogTable.php: -------------------------------------------------------------------------------- 1 | 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 | 40 | return isset($log['channel']); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Mysql/QueryTable.php: -------------------------------------------------------------------------------- 1 | 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 | } 44 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/RendererInterface.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/collector/request/toolbar/handler.phtml'); 16 | parent::_construct(); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Settings/Field.php: -------------------------------------------------------------------------------- 1 | 'ecocode_profiler/renderer/settings/input.phtml', 12 | 'select' => 'ecocode_profiler/renderer/settings/select.phtml' 13 | ]; 14 | 15 | protected $fieldAttributes = [ 16 | 'base' => ['id', 'type', 'class', 'name', 'value'], 17 | 'text' => ['length'], 18 | 'number' => ['min', 'max'] 19 | ]; 20 | 21 | 22 | public function renderField($type, $name, $value, array $data = []) 23 | { 24 | $data['type'] = $type; 25 | $data['name'] = $name; 26 | $data['value'] = $value; 27 | 28 | return $this->render($data); 29 | } 30 | 31 | /** 32 | * @param array $data 33 | * @return string 34 | */ 35 | public function render(array $data = []) 36 | { 37 | $type = isset($data['type']) ? $data['type'] : 'base'; 38 | if (!isset($data['template'])) { 39 | if (!isset($this->templateFiles[$type])) { 40 | $data['template'] = $this->templateFiles['base']; 41 | } else { 42 | $data['template'] = $this->templateFiles[$type]; 43 | } 44 | } 45 | $this->setTemplate($data['template']); 46 | 47 | $data['attributes'] = $this->prepareAttributes($type, $data); 48 | 49 | return parent::render($data); 50 | } 51 | 52 | protected function prepareAttributes($type, array $data) 53 | { 54 | $fieldAttributeKeys = isset($this->fieldAttributes[$type]) ? $this->fieldAttributes[$type] : []; 55 | $fieldAttributeKeys = array_merge($this->fieldAttributes['base'], $fieldAttributeKeys); 56 | $attributes = array_intersect_key($data, array_fill_keys($fieldAttributeKeys, 1)); 57 | 58 | if (isset($data['attributes'])) { 59 | $attributes = array_merge($attributes, $data['attributes']); 60 | } 61 | 62 | if (isset($data['data'])) { 63 | $dataAttributeKeys = array_keys($data['data']); 64 | //prepend with 'data-' 65 | $dataAttributeKeys = array_map(function ($key) { 66 | return 'data-' . $key; 67 | }, $dataAttributeKeys); 68 | 69 | $dataAttributes = array_combine($dataAttributeKeys, $data['data']); 70 | $attributes = array_merge($attributes, $dataAttributes); 71 | } 72 | 73 | array_walk($attributes, function (&$value, $key) { 74 | $value = sprintf('%s="%s"', $key, $this->escapeHtml($value)); 75 | }); 76 | 77 | return $attributes; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Settings/Row.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/renderer/settings/row.phtml'); 14 | parent::_construct(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Renderer/Table.php: -------------------------------------------------------------------------------- 1 | setTemplate('ecocode_profiler/renderer/table.phtml'); 13 | parent::_construct(); 14 | } 15 | 16 | public function getClass() 17 | { 18 | $class = $this->getData('class'); 19 | 20 | return $class ? $class : ''; 21 | } 22 | 23 | public function getLabels() 24 | { 25 | $labels = $this->getData('labels'); 26 | 27 | return $labels ? $labels : []; 28 | } 29 | 30 | 31 | public function getItems() 32 | { 33 | $items = $this->getData('items'); 34 | 35 | return $items ? $items : []; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Block/Toolbar.php: -------------------------------------------------------------------------------- 1 | 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 | 25 | return false; 26 | } 27 | 28 | public function getCollectors() 29 | { 30 | if ($this->collectors === null) { 31 | $this->collectors = $this->getProfile()->getCollectors(); 32 | 33 | } 34 | 35 | return $this->collectors; 36 | } 37 | 38 | public function getToolbarItems() 39 | { 40 | $blocks = []; 41 | 42 | $layout = $this->getLayout(); 43 | foreach ($this->getCollectors() as $collector) { 44 | /** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */ 45 | if (!$block = $layout->getBlock($collector->getBlockToolbarName())) { 46 | continue; 47 | } 48 | $block->setCollector($collector); 49 | $block->setData('token', $this->getToken()); 50 | $blocks[$collector->getName()] = $block; 51 | } 52 | 53 | return $blocks; 54 | } 55 | 56 | /** 57 | * @codeCoverageIgnore 58 | * @return Ecocode_Profiler_Model_Profile 59 | */ 60 | public function getProfile() 61 | { 62 | if ($this->profile === null) { 63 | $this->profile = Mage::registry('current_profile'); 64 | } 65 | 66 | return $this->profile; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Controller/AbstractController.php: -------------------------------------------------------------------------------- 1 | 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 | } 53 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Db/Statement/Pdo/Mysql.php: -------------------------------------------------------------------------------- 1 | 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 | } 95 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Helper/AbstractHelper.php: -------------------------------------------------------------------------------- 1 | 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 | } 105 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Helper/Renderer.php: -------------------------------------------------------------------------------- 1 | getInstance('bag') 16 | ->render($data); 17 | } 18 | 19 | public function renderTable($data, $labels = null) 20 | { 21 | return $this->getInstance('table') 22 | ->render(['items' => $data, 'labels' => $labels]); 23 | } 24 | 25 | public function renderCallStack($id, $stack, $wrap = true) 26 | { 27 | return $this->getInstance('callStack') 28 | ->render(['id' => $id, 'stack' => $stack, 'wrap' => $wrap]); 29 | } 30 | 31 | /** 32 | * @param $name 33 | * @return Ecocode_Profiler_Block_Renderer_RendererInterface 34 | */ 35 | public function getInstance($name) 36 | { 37 | if (strpos($name, '/') === false) { 38 | $name = 'ecocode_profiler/renderer_' . $name; 39 | } 40 | 41 | if (!isset($this->renderer[$name])) { 42 | $this->renderer[$name] = Mage::app()->getLayout()->createBlock($name); 43 | } 44 | 45 | return $this->renderer[$name]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Helper/ValueExporter.php: -------------------------------------------------------------------------------- 1 | 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 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 | $all = []; 50 | foreach ($value as $key => $val) { 51 | if (is_array($val)) { 52 | $deep = true; 53 | } 54 | $all[] = sprintf('%s => %s', $key, $this->exportValue($val, $depth + 1, $deep)); 55 | } 56 | 57 | if ($deep) { 58 | return sprintf("[\n%s%s\n%s]", $indent, implode(sprintf(", \n%s", $indent), $all), str_repeat(' ', $depth - 1)); 59 | } 60 | 61 | $str = sprintf('[%s]', implode(', ', $all)); 62 | 63 | if (80 > strlen($str)) { 64 | return $str; 65 | } 66 | 67 | return sprintf("[\n%s%s\n]", $indent, implode(sprintf(",\n%s", $indent), $all)); 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 | } 96 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Collector/AjaxDataCollector.php: -------------------------------------------------------------------------------- 1 | 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 | } 46 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Collector/CustomerDataCollector.php: -------------------------------------------------------------------------------- 1 | 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 | } 92 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Collector/DataCollectorInterface.php: -------------------------------------------------------------------------------- 1 | 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 | } 114 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Collector/RewriteDataCollector.php: -------------------------------------------------------------------------------- 1 | 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 | } 63 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Collector/TimeDataCollector.php: -------------------------------------------------------------------------------- 1 | data = [ 21 | 'start_time' => Mage::app()->getStartTime() * 1000, 22 | 'events' => [] 23 | ]; 24 | } 25 | 26 | 27 | public function lateCollect() 28 | { 29 | if (!$this->isVarienProfiler()) { 30 | $this->setEvents($this->getEventsFromProfiler()); 31 | } 32 | 33 | if (!$this->getDuration()) { 34 | $this->data['duration'] = (microtime(true) * 1000) - $this->getData('start_time', 0); 35 | } 36 | 37 | return $this; 38 | } 39 | 40 | /** 41 | * Sets the request events. 42 | * 43 | * @param array $events The request events 44 | */ 45 | public function setEvents(array $events) 46 | { 47 | foreach ($events as $event) { 48 | $event->ensureStopped(); 49 | } 50 | 51 | $this->data['events'] = $events; 52 | } 53 | 54 | /** 55 | * Gets the request elapsed time. 56 | * 57 | * @return float The elapsed time 58 | */ 59 | public function getDuration() 60 | { 61 | if (!isset($this->data['events']['__section__'])) { 62 | return $this->getData('duration', 0); 63 | } 64 | 65 | /** @var \Symfony\Component\Stopwatch\StopwatchEvent $event */ 66 | $event = $this->data['events']['__section__']; 67 | 68 | return $event->getDuration(); 69 | } 70 | 71 | /** 72 | * Gets the request time. 73 | * 74 | * @return int The time 75 | */ 76 | public function getStartTime() 77 | { 78 | return $this->getData('start_time', 0); 79 | } 80 | 81 | public function getEvents() 82 | { 83 | return $this->getData('events', []); 84 | } 85 | 86 | 87 | /** 88 | * @codeCoverageIgnore 89 | * @return string 90 | */ 91 | public function getName() 92 | { 93 | return 'time'; 94 | } 95 | 96 | /** 97 | * @codeCoverageIgnore 98 | * @return [] 99 | */ 100 | protected function getEventsFromProfiler() 101 | { 102 | if (@class_exists('Symfony\Component\Stopwatch\Stopwatch')) { 103 | return Varien_Profiler::getTimers(); 104 | } 105 | 106 | return []; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Context.php: -------------------------------------------------------------------------------- 1 | id = uniqid(); 22 | $this->key = $key; 23 | $this->data = $data; 24 | } 25 | 26 | public function getId() 27 | { 28 | return $this->id; 29 | } 30 | 31 | public function getParentId() 32 | { 33 | return $this->parentId; 34 | } 35 | 36 | public function setParentId($id) 37 | { 38 | $this->parentId = 0; 39 | } 40 | 41 | 42 | public function getKey() 43 | { 44 | return $this->key; 45 | } 46 | 47 | public function addData($key, $value) 48 | { 49 | $this->data[$key] = $value; 50 | 51 | return $this; 52 | } 53 | 54 | public function getData() 55 | { 56 | return $this->data; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/ContextInterface.php: -------------------------------------------------------------------------------- 1 | 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 | } 47 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Core/Config.php: -------------------------------------------------------------------------------- 1 | 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 | } 57 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Logger.php: -------------------------------------------------------------------------------- 1 | 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 18 | */ 19 | class Ecocode_Profiler_Model_Logger 20 | extends BaseLogger 21 | implements Ecocode_Profiler_Model_LoggerInterface 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 | if (is_array($message) || is_object($message)) { 39 | $message = print_r($message, true); 40 | } 41 | 42 | $level = self::$levelMap[$level]; 43 | return $this->log($level, $message, $context); 44 | } 45 | 46 | /** 47 | * {@inheritdoc} 48 | */ 49 | public function getLogs() 50 | { 51 | if ($logger = $this->getDebugLogger()) { 52 | return $logger->getLogs(); 53 | } 54 | 55 | return []; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function countErrors() 62 | { 63 | if ($logger = $this->getDebugLogger()) { 64 | return $logger->countErrors(); 65 | } 66 | 67 | return 0; 68 | } 69 | 70 | /** 71 | * Returns a Ecocode_Profiler_Model_Logger_DebugHandlerInterface instance if one is registered with this logger. 72 | * 73 | * @return Ecocode_Profiler_Model_Logger_DebugHandlerInterface|null A DebugLoggerInterface instance or null if none is registered 74 | */ 75 | private function getDebugLogger() 76 | { 77 | foreach ($this->handlers as $handler) { 78 | if ($handler instanceof Ecocode_Profiler_Model_Logger_DebugHandlerInterface) { 79 | return $handler; 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Logger/DebugHandler.php: -------------------------------------------------------------------------------- 1 | 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 20 | */ 21 | class Ecocode_Profiler_Model_Logger_DebugHandler extends TestHandler 22 | implements Ecocode_Profiler_Model_Logger_DebugHandlerInterface 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 | 61 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Logger/DebugHandlerInterface.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | interface Ecocode_Profiler_Model_Logger_DebugHandlerInterface 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 | } 29 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/LoggerInterface.php: -------------------------------------------------------------------------------- 1 | getEvent(); 14 | $block = $event->getData('block'); 15 | 16 | if (!$this->canOpenBlockContext($block)) { 17 | //do not open block context as it would not get closed 18 | return; 19 | } 20 | 21 | $data = [ 22 | 'class' => get_class($block), 23 | 'module' => $block->getModuleName() 24 | ]; 25 | 26 | $context = new Ecocode_Profiler_Model_Context('block::' . $block->getNameInLayout(), $data); 27 | $block->setData('__context', $context); 28 | 29 | $this->getHelper() 30 | ->open($context); 31 | } 32 | 33 | public function closeBlockContext(Varien_Event_Observer $observer) 34 | { 35 | $event = $observer->getEvent(); 36 | $block = $event->getData('block'); 37 | 38 | /** @var Ecocode_Profiler_Model_Context $context */ 39 | if ($context = $block->getData('__context')) { 40 | if ($block instanceof Mage_Core_Block_Template) { 41 | $context->addData('template', $block->getTemplateFile()); 42 | } 43 | 44 | $this->getHelper() 45 | ->close($context); 46 | } 47 | } 48 | 49 | /** 50 | * @codeCoverageIgnore 51 | * @return Ecocode_Profiler_Helper_Context 52 | */ 53 | public function getHelper() 54 | { 55 | if ($this->helper === null) { 56 | $this->helper = Mage::helper('ecocode_profiler/context'); 57 | } 58 | 59 | return $this->helper; 60 | } 61 | 62 | /** 63 | * @codeCoverageIgnore 64 | * @param Mage_Core_Block_Abstract $block 65 | * @return bool 66 | */ 67 | public function canOpenBlockContext(Mage_Core_Block_Abstract $block) 68 | { 69 | if (Mage::getStoreConfig('advanced/modules_disable_output/' . $block->getModuleName())) { 70 | return false; 71 | } 72 | 73 | return true; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Profiler/StorageInterface.php: -------------------------------------------------------------------------------- 1 | 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 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 | } 59 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Model/Session.php: -------------------------------------------------------------------------------- 1 | init('eco_profiler', $name); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Block/Collector/Layout/PanelTest.php: -------------------------------------------------------------------------------- 1 | ['id' => 2], 11 | 'node-3' => ['id' => 3, 'children' => ['node-4']], 12 | 'node-4' => ['id' => 4, 'children' => []], 13 | ]; 14 | 15 | $blockReflection = new ReflectionMethod('Ecocode_Profiler_Block_Collector_Layout_Panel', 'resolveChildren'); 16 | $blockReflection->setAccessible(true); 17 | 18 | $block = new Ecocode_Profiler_Block_Collector_Layout_Panel(); 19 | 20 | $node = ['node-1' => [ 21 | 'id' => 1, 22 | 'children' => [ 23 | 'node-2', 24 | 'node-3' 25 | ] 26 | ]]; 27 | $node = $node['node-1']; 28 | //use invokeArgs to prevent deprecation warning for pass by reference 29 | $blockReflection->invokeArgs($block, [&$node, $nodeList]); 30 | 31 | $this->assertEquals([ 32 | 'id' => 1, 33 | 'children' => [ 34 | 'node-2' => array_merge($nodeList['node-2'], ['children' => []]), 35 | 'node-3' => array_merge( 36 | $nodeList['node-3'], 37 | ['children' => ['node-4' => $nodeList['node-4']]] 38 | ) 39 | ] 40 | ], $node); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Block/Renderer/BagTest.php: -------------------------------------------------------------------------------- 1 | renderer = new Ecocode_Profiler_Block_Renderer_Bag(); 13 | } 14 | 15 | public function testClassRendering() 16 | { 17 | $html = $this->renderer->render(['class' => 'test-class']); 18 | 19 | $this->assertNotFalse(strpos($html, 'renderer->render(); 25 | 26 | $this->assertNotFalse(strpos($html, 'Key')); 27 | $this->assertNotFalse(strpos($html, 'Value')); 28 | } 29 | 30 | public function testLabelRendering() 31 | { 32 | $html = $this->renderer->render(['labels' => ['Key1', 'Value1']]); 33 | 34 | $this->assertNotFalse(strpos($html, 'Key1')); 35 | $this->assertNotFalse(strpos($html, 'Value1')); 36 | } 37 | 38 | public function testRowRendering() 39 | { 40 | $params = [ 41 | 'test' => 'value', 42 | 'test2' => 'value2' 43 | ]; 44 | $bag = new Ecocode_Profiler_Model_Http_ParameterBag($params); 45 | $html = $this->renderer->render(['bag' => $bag]); 46 | 47 | foreach($params as $key => $value) { 48 | $this->assertNotFalse(strpos($html, $key . '')); 49 | $this->assertNotFalse(strpos($html, $value . '')); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Block/Renderer/Settings/FieldTest.php: -------------------------------------------------------------------------------- 1 | renderer = new Ecocode_Profiler_Block_Renderer_Settings_Field(); 13 | } 14 | 15 | public function testRenderField() 16 | { 17 | $html = $this->renderer->renderField('text', 'email', 'test@test.de', ['id' => 'idx']); 18 | 19 | $expect = ''; 20 | $this->assertEquals($expect, trim($html)); 21 | } 22 | 23 | /** 24 | * @dataProvider prepareAttributesProvider 25 | * @param $type 26 | * @param array $data 27 | * @param array $expectAttributes 28 | */ 29 | public function testPrepareAttributes($type, array $data, array $expectAttributes) 30 | { 31 | $prepareAttributesMethod = new ReflectionMethod($this->renderer, 'prepareAttributes'); 32 | $prepareAttributesMethod->setAccessible(true); 33 | 34 | $attributes = $prepareAttributesMethod->invoke( 35 | $this->renderer, 36 | $type, $data 37 | ); 38 | 39 | $this->assertEquals($expectAttributes, $attributes); 40 | } 41 | 42 | 43 | public function prepareAttributesProvider() 44 | { 45 | return [ 46 | ['text', ['id' => 'test-id', 'class' => 'test-class', 'name' => 'test-name'], ['id' => 'id="test-id"', 'class' => 'class="test-class"', 'name' => 'name="test-name"']], 47 | ['text', ['id' => 'x', 'attributes' => ['custom' => 'y']], ['id' => 'id="x"', 'custom' => 'custom="y"']], 48 | ['text', ['id' => 'x', 'attributes' => ['custom' => 'y'], 'data' => ['key' => 'value']], ['id' => 'id="x"', 'custom' => 'custom="y"', 'data-key' => 'data-key="value"']] 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Block/Renderer/TableTest.php: -------------------------------------------------------------------------------- 1 | renderer = new Ecocode_Profiler_Block_Renderer_Table(); 13 | } 14 | 15 | public function testClassRendering() 16 | { 17 | $html = $this->renderer->render(['class' => 'test-class']); 18 | 19 | $this->assertNotFalse(strpos($html, '
renderer->render(); 25 | 26 | $this->assertNotFalse(strpos($html, 'Key')); 27 | $this->assertNotFalse(strpos($html, 'Value')); 28 | } 29 | 30 | public function testLabelRendering() 31 | { 32 | $html = $this->renderer->render(['labels' => ['Key1', 'Value1']]); 33 | 34 | $this->assertNotFalse(strpos($html, 'Key1')); 35 | $this->assertNotFalse(strpos($html, 'Value1')); 36 | } 37 | 38 | public function testRowRendering() 39 | { 40 | $items = [ 41 | 'test' => 'value', 42 | 'test2' => 'value2' 43 | ]; 44 | $html = $this->renderer->render(['items' => $items]); 45 | 46 | foreach($items as $key => $value) { 47 | $this->assertNotFalse(strpos($html, $key . '')); 48 | $this->assertNotFalse(strpos($html, $value . '')); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Controller/AbstractControllerTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 71 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/DevModeTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 34 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/.profiler.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "overwrite-1": "overwrite-1", 3 | "overwrite": { 4 | "overwrite-2": "overwrite-2", 5 | "nested": { 6 | "overwrite-3": "overwrite-3" 7 | } 8 | }, 9 | "collector": { 10 | "mysql": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/DummyCacheBackend.php: -------------------------------------------------------------------------------- 1 | 0]; 7 | } 8 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Fixtures/ResponseHttp.php: -------------------------------------------------------------------------------- 1 | getData('attributes'))?>> 2 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Helper/DataTest.php: -------------------------------------------------------------------------------- 1 | getNewHelper(); 12 | 13 | $this->assertEquals( 14 | $classGroup, 15 | $helper->resolveClassGroup($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->resolveClassGroup($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 | } 95 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Helper/SqlTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 57 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Helper/ValueExporterTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 61 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ConfigCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 52 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/ContextDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 55 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/CustomerDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 55 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/EventDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | $calledListeners = [ 33 | ['event_name' => 'non-existing'], 34 | ['event_name' => 'controller_action_predispatch', 35 | 'class' => 'TEST_CLASS', 36 | 'method' => 'xxx', 37 | 'execution_time' => 10] 38 | ]; 39 | 40 | $app->dispatchEvent('resource_get_tablename', []); 41 | $app->dispatchEvent('controller_action_predispatch', []); 42 | $app->dispatchEvent('controller_action_predispatch', []); 43 | 44 | $this->setProtectedValue($app, '_events', $events); 45 | $this->setProtectedValue($app, 'calledListeners', $calledListeners); 46 | 47 | 48 | $collector->lateCollect(); 49 | 50 | $firedEvents = $collector->getFiredEvents(); 51 | $this->assertCount(2, $collector->getCalledListeners()); 52 | $this->assertCount(2, $collector->getFiredEvents()); 53 | $this->assertEquals(10, $collector->getTotalTime()); 54 | 55 | $data = $firedEvents['controller_action_predispatch']; 56 | $this->assertEquals(2, $data['count']); 57 | $this->assertEquals(2, $data['observer_count']); 58 | $this->assertCount(1, $data['observer']); 59 | $this->assertCount(2, $data['observer']['global']); 60 | 61 | } 62 | 63 | /** 64 | * @return Ecocode_Profiler_Model_Collector_EventDataCollector 65 | */ 66 | public function getMockedCollector() 67 | { 68 | $collectorMock = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_EventDataCollector') 69 | ->setMethods(['getApp']) 70 | ->getMock(); 71 | 72 | 73 | return $collectorMock; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/LogDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | collect( 17 | new Mage_Core_Controller_Request_Http(), 18 | new Mage_Core_Controller_Response_Http() 19 | ); 20 | 21 | $this->assertEmpty(0, $collector->getLogs()); 22 | $this->assertEquals(0, $collector->getLogCount()); 23 | } 24 | 25 | public function testLateCollect() 26 | { 27 | if (!class_exists('Monolog\Handler\TestHandler')) { 28 | $this->markTestSkipped( 29 | 'Monolog not installed skipping.' 30 | ); 31 | } 32 | $logHandler = new Ecocode_Profiler_Model_Logger_DebugHandler(); 33 | $logger = new Ecocode_Profiler_Model_Logger('test', [$logHandler]); 34 | 35 | $collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_LogDataCollector') 36 | ->setMethods(['getLogger']) 37 | ->getMock(); 38 | 39 | $collector->method('getLogger') 40 | ->willReturn($logger); 41 | 42 | 43 | $logger->debug('test'); 44 | $logger->debug('test'); 45 | 46 | $context = [ 47 | "type" => 8192, "file" => "path/xxxxCategoryController.php", "line" => 43, "level" => 32767 48 | ]; 49 | //simulate 3 times same error like in a loop 50 | $logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context); 51 | $logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context); 52 | $logger->info('iconv_set_encoding(): Use of iconv.internal_encoding is deprecated', $context); 53 | 54 | $logger->info('another deprecation', ['level' => E_USER_ERROR, 'type' => E_USER_DEPRECATED]); 55 | 56 | 57 | $logger->critical('Fatal Parse Error:', ['level' => E_ALL, 'type' => E_PARSE]); 58 | 59 | /** @var Ecocode_Profiler_Model_Collector_LogDataCollector $collector */ 60 | $collector->lateCollect(); 61 | 62 | 63 | 64 | $logsByPriorities = $collector->getPriorities(); 65 | 66 | $this->assertEquals(2, $logsByPriorities[Ecocode_Profiler_Model_Logger::DEBUG]['count']); 67 | $this->assertEquals(4, $logsByPriorities[Ecocode_Profiler_Model_Logger::INFO]['count']); 68 | $this->assertEquals(1, $logsByPriorities[Ecocode_Profiler_Model_Logger::CRITICAL]['count']); 69 | 70 | 71 | $this->assertEquals(0, $collector->countScreams()); 72 | $this->assertEquals(1, $collector->countErrors()); 73 | $this->assertEquals(4, $collector->countDeprecations()); 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/MemoryDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 72 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/RewriteDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 40 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Collector/TimeDataCollectorTest.php: -------------------------------------------------------------------------------- 1 | checkCanRunTest(); 12 | 13 | $collector = $this->getMockBuilder('Ecocode_Profiler_Model_Collector_TimeDataCollector') 14 | ->setMethods(['getEventsFromProfiler']) 15 | ->getMock(); 16 | 17 | $stopWatch = new Stopwatch(); 18 | $stopWatch->openSection(); 19 | $stopWatch->start('test-event'); 20 | usleep(1000); 21 | $stopWatch->stop('test-event'); 22 | $stopWatch->stopSection('test'); 23 | 24 | $collector->method('getEventsFromProfiler') 25 | ->willReturn($stopWatch->getSectionEvents('test')); 26 | 27 | /** @var Ecocode_Profiler_Model_Collector_TimeDataCollector $collector */ 28 | 29 | $collector->collect( 30 | new Mage_Core_Controller_Request_Http(), 31 | new Mage_Core_Controller_Response_Http() 32 | ); 33 | 34 | $this->assertEquals(0, $collector->getDuration()); 35 | return $collector; 36 | } 37 | 38 | /** 39 | * @depends testCollect 40 | */ 41 | public function testLateCollect(Ecocode_Profiler_Model_Collector_TimeDataCollector $collector) 42 | { 43 | $this->checkCanUseDepends(); 44 | 45 | $collector->lateCollect(); 46 | $this->assertGreaterThan(0, $collector->getStartTime()); 47 | $this->assertGreaterThan(0, $collector->getDuration()); 48 | $this->assertCount(2, $collector->getEvents()); 49 | } 50 | 51 | 52 | protected function checkCanRunTest() 53 | { 54 | if (defined('Varien_Profiler::CATEGORY_SECTION') && @class_exists('Symfony\Component\Stopwatch\Stopwatch')) { 55 | return true; 56 | } else { 57 | $this->markTestSkipped('symfony stopwatch is not installed'); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/LoggerTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 88 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Observer/ContextTest.php: -------------------------------------------------------------------------------- 1 | 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('frontend/base/default/template/test.phtml', $contextData['template']); 62 | 63 | 64 | return $block; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageCoreModelResourceTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 30 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/Overwrite/MageTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 44 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/Model/ProfilerTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 59 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Dev/bootstrap.php: -------------------------------------------------------------------------------- 1 | '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 | require_once BASE_TESTS_PATH . '/../TestControllerHelper.php'; 34 | 35 | $options = [ 36 | 'cache' => ['id_prefix' => 'test-dev'], 37 | 'config_model' => 'Ecocode_Profiler_Model_Core_Config' 38 | ]; 39 | Mage::app('', 'store', $options); 40 | 41 | // Removing Varien Autoload, to prevent errors with PHPUnit components 42 | spl_autoload_unregister([\Varien_Autoload::instance(), 'autoload']); 43 | spl_autoload_register(function ($className) { 44 | $filePath = strtr( 45 | ltrim($className, '\\'), 46 | [ 47 | '\\' => '/', 48 | '_' => '/' 49 | ] 50 | ); 51 | $file = $filePath . '.php'; 52 | if (stream_resolve_include_path($file)) { 53 | include $filePath . '.php'; 54 | } 55 | }); 56 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Prod/DevModeTest.php: -------------------------------------------------------------------------------- 1 | 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 | } 34 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/Prod/bootstrap.php: -------------------------------------------------------------------------------- 1 | ['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 | }); 52 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/Tests/TestControllerHelper.php: -------------------------------------------------------------------------------- 1 | setParams($request); 16 | 17 | } 18 | $request = $_request; 19 | 20 | } 21 | if (!$response) { 22 | $response = new Ecocode_Profiler_Tests_Dev_Fixtures_ResponseHttp(); 23 | } 24 | 25 | $methods[] = 'getApp'; 26 | $appMock = $this->getMockBuilder('Mage_Core_Model_App')->getMock(); 27 | 28 | $controller = $this->getMockBuilder($class) 29 | ->setMethods($methods) 30 | ->setConstructorArgs([$request, $response]) 31 | ->getMock(); 32 | 33 | $controller->method('getApp') 34 | ->willReturn($appMock); 35 | 36 | 37 | return $controller; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/autoloader.php: -------------------------------------------------------------------------------- 1 | classMap[$class])) { 47 | /** 48 | * Scope isolated include. 49 | * 50 | * Prevents access to $this/self from included files. 51 | * 52 | * @param $file 53 | */ 54 | $includeFile = function ($file) { 55 | include $file; 56 | }; 57 | $includeFile($this->classMap[$class]); 58 | 59 | return true; 60 | } 61 | 62 | return false; 63 | } 64 | 65 | public function addOverwrite($className, $file) 66 | { 67 | if (strpos($file, '/') !== 0) { 68 | $overwriteDir = __DIR__ . DIRECTORY_SEPARATOR . 'overwrite' . DIRECTORY_SEPARATOR; 69 | $file = $overwriteDir . $file; 70 | } 71 | 72 | $this->addToClassMap($className, $file); 73 | 74 | 75 | return $this; 76 | } 77 | 78 | public function addToClassMap($className, $file) 79 | { 80 | $this->classMap[$className] = $file; 81 | 82 | return $this; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/controllers/CacheController.php: -------------------------------------------------------------------------------- 1 | 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 | } 72 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/controllers/SettingsController.php: -------------------------------------------------------------------------------- 1 | getRequest(); 26 | $token = $request->getParam(Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER); 27 | if ($token && $profile = $this->getProfiler()->loadProfile($token)) { 28 | //make the menu available if we have a token 29 | Mage::register('current_profile', $profile); 30 | } 31 | 32 | $this->loadLayout('profiler_default'); 33 | $this->renderLayout(); 34 | } 35 | 36 | public function saveAction() 37 | { 38 | $request = $this->getRequest(); 39 | $key = $request->getParam('key'); 40 | $value = $request->getParam('value'); 41 | 42 | if (!$key || !$value) { 43 | throw new \Exception('missing "key" or "value"'); 44 | } else { 45 | /** @var Ecocode_Profiler_Model_Config $config */ 46 | $config = $this->getConfig(); 47 | if ($collectorName = $request->getParam('collector')) { 48 | $collector = $this->getProfiler()->getDataCollector($collectorName); 49 | $config->saveCollectorValue($collector, $key, $value); 50 | } else { 51 | $config->saveValue($key, $value); 52 | } 53 | } 54 | } 55 | 56 | public function resetAction() 57 | { 58 | $request = $this->getRequest(); 59 | $key = $request->getParam('key'); 60 | 61 | if (!$key) { 62 | throw new \Exception('missing "key"'); 63 | } else { 64 | /** @var Ecocode_Profiler_Model_Config $configHelper */ 65 | $configHelper = $this->getConfig(); 66 | if ($collectorName = $request->getParam('collector')) { 67 | $collector = $this->getProfiler()->getDataCollector($collectorName); 68 | $configHelper->deleteCollectorValue($collector, $key); 69 | $value = $configHelper->getValue($key); 70 | } else { 71 | $configHelper->deleteValue($key); 72 | $value = $configHelper->getValue($key); 73 | } 74 | } 75 | 76 | $this->getResponse()->setHeader('Content-Type', 'application/json'); 77 | $this->getResponse()->setBody(json_encode(['value' => $value])); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/debug.php: -------------------------------------------------------------------------------- 1 | 17 | '; 18 | } catch (Exception $e) { 19 | //if this fails we dont care 20 | } 21 | } 22 | } 23 | 24 | Debug::enable(); 25 | $errorHandler = new MagentoErrorHandler(new BufferingLogger()); 26 | $errorHandler->throwAt(-1, true); 27 | 28 | ErrorHandler::register($errorHandler); 29 | $errorHandler->setDefaultLogger(Mage::getLogger()); 30 | } 31 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/etc/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "stacktrace_length": 15, 3 | "collector": { 4 | "mysql": { 5 | "stacktrace_length": 10 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1.3.0 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResource.php: -------------------------------------------------------------------------------- 1 | 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 | } 34 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/overwrite/MageCoreModelResourceDbAbstract.php: -------------------------------------------------------------------------------- 1 | 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 | } 84 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/overwrite/MageCoreModelStore.php: -------------------------------------------------------------------------------- 1 | isDev() ? 'dev.php' : 'index.php'; 21 | if ($this->isAdmin() || $this->isDev() || !$this->getConfig(self::XML_PATH_USE_REWRITES) || !Mage::isInstalled()) { 22 | $indexFileName = $this->_isCustomEntryPoint() ? $script : basename($_SERVER['SCRIPT_FILENAME']); 23 | $url .= $indexFileName . '/'; 24 | } 25 | return $url; 26 | } 27 | 28 | protected function isDev() 29 | { 30 | if ($this->_isDev === null) { 31 | $this->_isDev = Mage::app() instanceof Ecocode_Profiler_Model_AppDev; 32 | } 33 | 34 | return $this->_isDev; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/code/community/Ecocode/Profiler/overwrite/MageEavModelEntityAbstract.php: -------------------------------------------------------------------------------- 1 | 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 | } 71 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/ajax/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | ?> 6 | 7 | 8 |
9 |
10 | 11 | 15 | 16 | 0 17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
MethodStatusURLTimeProfile
36 | 37 | 38 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/base/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | ?> 5 | 6 | 7 | getName()) ?> 8 | 9 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/cache/menu.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cache 8 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/config/menu.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | 9 | Configuration 10 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/customer/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | ?> 6 | 7 | 8 |
10 |
11 | 12 | 13 | 14 | 15 | isLoggedIn()): ?> 16 | getCustomerEmail(); ?> 17 | 18 | n/a 19 | 20 | 21 | 22 |
23 |
24 | isLoggedIn()): ?> 25 |
26 | Logged in as 27 | getCustomerEmail(); ?> 28 |
29 |
30 | Name 31 | getCustomerName(); ?> 32 |
33 | 34 | 35 |
36 | Customer Group 37 | getGroupCode(); ?> (Id: getGroupId(); ?>) 38 |
39 | 40 |
41 | Tax Class 42 | getTaxClassName(); ?> (Id: getTaxClassId(); ?>) 43 |
44 |
45 |
-------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/event/menu.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | Events 17 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/layout/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | ?> 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | Layout 15 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/layout/panel.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 6 | 7 | ?> 8 |

Render Metrics

9 |
10 |
11 | getTotalRenderTime() * 1000)?> ms 12 | Render time 13 |
14 | 15 | 16 |
17 | getBlocksCreatedCount()?> 18 | Block created 19 |
20 | 21 |
22 | getBlocksRenderedCount()?> 23 | Block rendered 24 |
25 |
26 | 27 |

Layout Handler

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | getLayoutHandles() as $handle): ?> 36 | 37 | 38 | 39 | 40 | 41 |
Handler
42 | 43 |

Created but not rendered blocks

44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | getBlocksNotRendered() as $block): ?> 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
NameModuleTypeClass
64 | 65 | 66 |

Rendering Call Graph

67 |
68 | renderTree(); ?> 69 |
70 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/layout/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | ?> 6 | 7 |
9 | 11 |
12 | 13 | 16 | 17 | getTotalRenderTime() * 1000)?> ms 18 |
19 |
20 |
21 |
22 |
23 | Layout handles 24 | getLayoutHandles() as $handle): ?> 25 |
26 | 27 |
28 |
29 |
30 |
31 | Render Time 32 | getTotalRenderTime() * 1000)?> ms 33 |
34 | 35 | 36 |
37 | Block created 38 | getBlocksCreatedCount()?> 39 |
40 | 41 | 42 |
43 | Block rendered 44 | getBlocksRenderedCount()?> 45 |
46 |
47 |
48 |
-------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/log/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $logCount = $collector->getLogCount(); 5 | $statusColor = $collector->countErrors() ? 'error' : ($collector->countDeprecations() ? 'warning' : ''); 6 | ?> 7 | 8 | 9 | 10 | 12 | 17 | 18 | 19 | Log 20 | countErrors() || $collector->countDeprecations()): ?> 21 | 22 | countErrors() ? $collector->countErrors() : $collector->countDeprecations() ?> 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/log/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | $logCount = $collector->getLogCount(); 6 | $statusColor = $collector->countErrors() ? 'red' : ($collector->countDeprecations() ? 'yellow' : ''); 7 | ?> 8 | 9 | 10 |
12 | 14 |
15 | 17 | 22 | 23 | countErrors() + $collector->countScreams(); ?> 24 | 25 |
26 |
27 | 28 |
29 |
30 | All 31 | 32 |
33 |
34 | Errors 35 | countErrors() ?> 37 |
38 | 39 |
40 | Deprecated Calls 41 | countDeprecations() ?> 43 |
44 | 45 |
46 | Silenced Errors 47 | countScreams() ?> 48 |
49 |
50 | 51 |
52 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/memory/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | ?> 6 | 7 | 8 |
9 |
10 | 12 | 15 | 16 | getMemory() / 1024 / 1024) ?> 17 | MB 18 | 19 |
20 |
21 |
22 | Peak memory usage 23 | getMemory() / 1024 / 1024) ?> MB 24 |
25 | 26 |
27 | PHP memory limit 28 | getMemoryLimit() == -1 ? 'Unlimited' : sprintf('%.0f MB', $collector->getMemoryLimit() / 1024 / 1024) ?> 29 |
30 |
31 |
-------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/model/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | 5 | $statusColor = $collector->getMetric('loop_load') ? 'error' : ($collector->getMetric('load') > $collector->getLoadCallThreshold() ? 'warning' : 'normal'); 6 | ?> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Models 15 | getMetric('loop_load')): ?> 16 | 17 | getMetric('loop_load')?> 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/model/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | 6 | ?> 7 | getMetric('loop_load') ? 'red' : ($collector->getMetric('load') > $collector->getLoadCallThreshold() ? 'yellow' : 'normal') ?> 8 | 9 |
10 | 12 |
13 | 14 | 15 | 16 | getMetric()) - $collector->getMetric('loop_load') ?> 17 |
18 |
19 |
20 |
21 | Model loads 22 | 23 | getMetric('load') ?> 24 | 25 |
26 | 27 |
28 | Loads in loops 29 | 30 | getMetric('loop_load') ?> 31 | 32 |
33 | 34 |
35 | Model save 36 | 37 | getMetric('save') ?> 38 | 39 |
40 | 41 |
42 | Model delete 43 | 44 | getMetric('delete') ?> 45 | 46 |
47 |
48 |
-------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | ?> 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | Mysql 14 | 15 | 16 | getQueryCount()?> / 17 | getTotalTime() * 1000) ?> ms 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/settings.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 7 | 8 | /** @var Ecocode_Profiler_Block_Renderer_Settings_Row $rowRenderer */ 9 | $rowRenderer = Mage::helper('ecocode_profiler/renderer')->getInstance('settings_row'); 10 | 11 | $settings = [ 12 | 'stacktrace_length' => [ 13 | 'label' => 'Stacktrace Length', 14 | 'label_description' => 'This setting will significantly influence the size of the saved profile', 15 | 'type' => 'number', 16 | 'min' => 0 17 | ], 18 | ] 19 | ?> 20 | 21 |
22 | 23 | 24 | $data) { 26 | $data['key'] = $key; 27 | $data['collector'] = $collector; 28 | echo $rowRenderer->render($data); 29 | } 30 | ?> 31 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/mysql/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | ?> 6 | 7 |
8 | 10 |
11 | 13 | 15 | 16 | 17 | getQueryCount() ?> 18 | 19 | in 20 | getTotalTime() * 1000) ?> 21 | ms 22 | 23 | 24 |
25 |
26 |
27 |
28 | Database Queries 29 | getQueryCount() ?> 30 |
31 |
32 | Query time 33 | getTotalTime() * 1000) ?> ms 34 |
35 |
36 |
-------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/request/menu.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 18 | 19 | 20 | 21 | Request / Response 22 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/request/toolbar/handler.phtml: -------------------------------------------------------------------------------- 1 | getController(); 8 | ?> 9 | 10 | 11 | getMethod()): ?> 12 | getMethod() ?> 13 | 14 | getFileLink($controller['file'], $controller['line']); ?> 15 | 16 | 17 | 18 | 19 | getRoute()): ?> 20 | @getRoute(); ?> 21 | 22 | abbrClass($controller['class'])); ?> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | getRoute() ? $this->getRoute() : $controller?> 32 | 33 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $conflictCount = $collector->getModuleRewriteConflictCount(); 5 | $statusColor = $conflictCount ? 'error' : 'normal'; 6 | ?> 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | Rewrites 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/panel.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 6 | 7 | ?> 8 | getModuleRewriteConflicts(); ?> 9 |

Rewrite Conflicts

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
TypeClassRewritesLoaded Class
', $conflict['rewrites']) ?>
32 | 33 | 34 |
35 |

No rewrite conflicts

36 |
37 | 38 | 39 | 40 | getModuleRewrites(); 42 | ?> 43 |

Rewrites

44 | 45 |
46 | $typeRewrites): ?> 47 |
48 |

49 | () 50 |

51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | $rewrites): ?> 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Class GroupRewrites
', $rewrites) ?>
69 | 70 |
71 |

No rewrite conflicts

72 |
73 | 74 |
75 |
76 | 77 |
78 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/rewrite/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | 6 | $conflictCount = $collector->getModuleRewriteConflictCount(); 7 | ?> 8 | 9 | 10 |
12 | 14 |
15 | 16 | 18 | 19 | 20 | 21 | 22 |
23 |
24 |
25 | 26 | getModuleRewrites() as $type => $typeRewrites):?> 27 |
28 | Rewrites 29 | 30 |
31 | 32 | 33 |
34 | Rewrite Conflict Count 35 | 36 |
37 |
38 | 39 |
40 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/time/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | ?> 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | Performance 15 | 16 | 17 | getDuration()) ?> ms 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/time/toolbar.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $token = $this->getToken(); 5 | 6 | /** @var Ecocode_Profiler_Helper_Data $helper */ 7 | $helper = Mage::helper('ecocode_profiler'); 8 | ?> 9 | 10 | 30 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/collector/translation/menu.phtml: -------------------------------------------------------------------------------- 1 | getCollector(); 4 | $statusColor = ($collector->getStateCount('invalid') || $collector->getStateCount('missing')) ? 'error' : ($collector->getStateCount('fallback') ? 'warning' : 'normal'); 5 | ?> 6 | 7 | 8 | 9 | 10 | 12 | 23 | 24 | 25 | Translation 26 | getNotOkCount()): ?> 27 | 28 | getNotOkCount() ?> 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/layout/sidebar/menu.phtml: -------------------------------------------------------------------------------- 1 | 2 | getProfile()): ?> 4 | 5 | getProfile()->getToken(); 7 | $panel = Mage::registry('current_panel'); 8 | $helper = Mage::helper('ecocode_profiler'); 9 | ?> 10 | getMenuBlocks() as $name => $block): ?> 11 | getUrl($token, $name); 14 | ?> 15 |
  • 16 | toHtml(); ?> 17 |
  • 18 | 19 | 20 | 21 | getChildHtml('settings'); ?> 22 | 23 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/profiler/search/results.phtml: -------------------------------------------------------------------------------- 1 | getData(); 3 | ?> 4 |

    results found

    5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 399 ? 'status-error' : $statusCode > 299 ? 'status-warning' : 'status-success'; 24 | ?> 25 | 26 | 27 | 30 | 33 | 36 | 39 | 42 | 47 | 48 | 49 | 50 | 51 |
    StatusIPMethodURLSizeTimeToken
    28 | 29 | 31 | 32 | 34 | 35 | 37 | 38 | 40 | MB 41 | 43 | setTimestamp($result['time']);?> 44 | format('d-M-Y')?> 45 | format('H:i:s')?> 46 |
    52 | 53 |
    54 |

    The query returned no result.

    55 |
    56 | 57 | 58 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/profiler/search/summery.phtml: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    4 | Profile Search 5 | 6 | 7 | 8 |

    9 |
    10 |
    11 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/bag.phtml: -------------------------------------------------------------------------------- 1 | helper('ecocode_profiler/valueExporter'); 6 | 7 | $bag = $this->getBag(); 8 | ?> 9 | 10 | 11 | 12 | getLabels(); ?> 13 | 14 | 15 | 16 | 17 | 18 | 19 | getBag()): ?> 20 | 21 | keys() as $key): ?> 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
    exportValue($bag->get($key)) ?>
    (no data)
    35 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/call-stack.phtml: -------------------------------------------------------------------------------- 1 | getStack(); 9 | ?> 10 | 11 | shouldWarp()): ?> 12 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/context.phtml: -------------------------------------------------------------------------------- 1 | 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 |
    13 | Context: getKey() ?> 14 | getData()): ?> 15 | View metadata 18 | 29 | 30 | 31 |
    32 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/settings/input.phtml: -------------------------------------------------------------------------------- 1 | getData('attributes'))?>> 2 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/settings/row.phtml: -------------------------------------------------------------------------------- 1 | getInstance('settings_field'); 4 | 5 | /** @var Ecocode_Profiler_Model_Config $config */ 6 | $config = Mage::getSingleton('ecocode_profiler/config'); 7 | 8 | $data = [ 9 | 'name' => $this->getData('key'), 10 | ]; 11 | 12 | /** @var Ecocode_Profiler_Model_Collector_DataCollectorInterface $collector */ 13 | if ($collector = $this->getData('collector')) { 14 | $data['id'] = sprintf('setting-collector-%s-%s', $collector->getName(), $this->getData('key')); 15 | $data['value'] = $config->getCollectorValue($collector, $this->getData('key')); 16 | 17 | if (!isset($data['data'])) { 18 | $data['data'] = []; 19 | } 20 | $data['data']['collector'] = $collector->getName(); 21 | } else { 22 | $data['id'] = sprintf('setting-base-%s', $this->getData('key')); 23 | $data['value'] = $config->getValue($this->getData('key')); 24 | } 25 | 26 | $this->addData($data); 27 | ?> 28 | 29 | 30 | 31 | getData('label_description')): ?> 32 |
    33 | getData('label_description') ?> 34 | 35 | 36 | 37 | render($this->getData()) ?> 38 | getData('value_description')): ?> 39 |
    40 | getData('value_description') ?> 41 | 42 | 43 | 44 | 45 | 46 | 47 | save 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/settings/select.phtml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/app/design/frontend/base/default/template/ecocode_profiler/renderer/settings/select.phtml -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/renderer/table.phtml: -------------------------------------------------------------------------------- 1 | helper('ecocode_profiler/valueExporter'); 6 | $labels = $this->getLabels(); 7 | ?> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | getItems() as $key => $value): ?> 17 | 18 | 19 | 20 | 21 | 22 | 23 |
    exportValue($value) ?>
    24 | -------------------------------------------------------------------------------- /app/design/frontend/base/default/template/ecocode_profiler/settings/menu.phtml: -------------------------------------------------------------------------------- 1 | getToken()) { 7 | $url = Mage::getUrl('_profiler/settings', [Ecocode_Profiler_Model_Profiler::URL_TOKEN_PARAMETER => $profile->getToken()]); 8 | } else { 9 | $url = Mage::getUrl('_profiler/settings'); 10 | } 11 | ?> 12 |
  • 13 | 14 | 15 | 16 | 17 | 18 | Settings 19 | 20 | 21 |
  • 22 | -------------------------------------------------------------------------------- /app/etc/modules/Ecocode_Profiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecocode/magento_profiler", 3 | "description": "Web Profiler for Magento 1.x", 4 | "license": "MIT", 5 | "type": "magento-module", 6 | "keywords": ["Magento", "logging", "performance", "toolbar", "profiler"], 7 | "homepage": "https://github.com/ecoco/magento_profiler", 8 | "support": { 9 | "wiki": "https://github.com/ecoco/magento_profiler/wiki", 10 | "issues": "https://github.com/ecoco/magento_profiler/issues", 11 | "source": "https://github.com/ecoco/magento_profiler" 12 | }, 13 | "authors": [ 14 | { 15 | "name": "Justus Krapp", 16 | "email": "jk@ecocode.de" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=5.5.9", 21 | "symfony/debug": "^3.0|^4.0", 22 | "symfony/yaml": "^3.1|^4.0", 23 | "jdorn/sql-formatter": "^1.2", 24 | "monolog/monolog": "^1.0", 25 | "symfony/stopwatch": "^3.2|^4.0" 26 | }, 27 | "require-dev": { 28 | "magento-hackathon/magento-composer-installer": "^3.0|^4.0", 29 | "phpunit/phpunit": "~4.0|~5.0", 30 | "satooshi/php-coveralls": "~1.0", 31 | "phpmd/phpmd": "^2.4" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dev.php: -------------------------------------------------------------------------------- 1 | ['id_prefix' => 'dev'], 55 | 'config_model' => 'Ecocode_Profiler_Model_Core_Config' 56 | ]; 57 | Varien_Profiler::enable(); 58 | Mage::run($mageRunCode, $mageRunType, $options); 59 | 60 | Mage::terminate(); 61 | -------------------------------------------------------------------------------- /docs/image/collector/event_panel_fired.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/event_panel_fired.jpg -------------------------------------------------------------------------------- /docs/image/collector/layout_panel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/layout_panel.jpg -------------------------------------------------------------------------------- /docs/image/collector/log_panel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/log_panel.jpg -------------------------------------------------------------------------------- /docs/image/collector/model_panel_all.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/model_panel_all.jpg -------------------------------------------------------------------------------- /docs/image/collector/model_panel_loop_loads.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/model_panel_loop_loads.jpg -------------------------------------------------------------------------------- /docs/image/collector/mysql_panel_context.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/mysql_panel_context.jpg -------------------------------------------------------------------------------- /docs/image/collector/mysql_panel_identical.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/mysql_panel_identical.jpg -------------------------------------------------------------------------------- /docs/image/collector/rewrite_panel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/rewrite_panel.jpg -------------------------------------------------------------------------------- /docs/image/collector/time_panel.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/collector/time_panel.jpg -------------------------------------------------------------------------------- /docs/image/profiler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/profiler.jpg -------------------------------------------------------------------------------- /docs/image/toolbar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/docs/image/toolbar.jpg -------------------------------------------------------------------------------- /docs/images.md: -------------------------------------------------------------------------------- 1 | # Images 2 | 3 | ## Toolbar in frontend 4 | ![Toolbar](/docs/image/toolbar.jpg "Toolbar") 5 | 6 | ## The profiler itself 7 | ![Profiler](/docs/image/profiler.jpg "Profiler") 8 | 9 | 10 | # Collector images 11 | 12 | ## Mysql 13 | ![Profiler](/docs/image/collector/mysql_panel_context.jpg "Mysql Collector") 14 | ![Profiler](/docs/image/collector/mysql_panel_identical.jpg "Mysql Collector") 15 | 16 | ## Performance 17 | ![Profiler](/docs/image/collector/time_panel.jpg "Time Collector") 18 | 19 | ## Events 20 | ![Profiler](/docs/image/collector/event_panel_fired.jpg "Event Collector") 21 | 22 | ## Layout 23 | ![Profiler](/docs/image/collector/layout_panel.jpg "Layout Collector") 24 | 25 | ## Layout 26 | ![Profiler](/docs/image/collector/model_panel_all.jpg "Model Collector") 27 | ![Profiler](/docs/image/collector/model_panel_loop_loads.jpg "Model Collector") 28 | 29 | ## Rewrites 30 | ![Profiler](/docs/image/collector/rewrite_panel.jpg "Rewrite Collector") 31 | 32 | ## Log 33 | ![Profiler](/docs/image/collector/log_panel.jpg "Log Collector") 34 | -------------------------------------------------------------------------------- /js/ecocode_profiler/profiler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | jQuery(function ($) { 4 | "use strict"; 5 | var iframe = $(''); 6 | $(document.body).append(iframe); 7 | $(document).on('click.setting.remove', '.file_link, a[title="Go to source"]', function (e) { 8 | e.preventDefault(); 9 | var href = $(this).attr('href'); 10 | if (href.indexOf('//') === 0 || href.indexOf('http') === 0) { 11 | $.get(href) 12 | .fail(function () { 13 | var win = window.open(href, '_blank'); 14 | win.focus(); 15 | }); 16 | } else { 17 | iframe.attr('src', href); 18 | } 19 | }); 20 | 21 | $(".sortable-table").stupidtable(); 22 | }); 23 | -------------------------------------------------------------------------------- /js/ecocode_profiler/vendor/stupidtable.min.js: -------------------------------------------------------------------------------- 1 | (function(c){c.fn.stupidtable=function(b){return this.each(function(){var a=c(this);b=b||{};b=c.extend({},c.fn.stupidtable.default_sort_fns,b);a.data("sortFns",b);a.on("click.stupidtable","thead th",function(){c(this).stupidsort()})})};c.fn.stupidsort=function(b){var a=c(this),g=0,f=c.fn.stupidtable.dir,e=a.closest("table"),k=a.data("sort")||null;if(null!==k){a.parents("tr").find("th").slice(0,c(this).index()).each(function(){var a=c(this).attr("colspan")||1;g+=parseInt(a,10)});var d;1==arguments.length? 2 | d=b:(d=b||a.data("sort-default")||f.ASC,a.data("sort-dir")&&(d=a.data("sort-dir")===f.ASC?f.DESC:f.ASC));if(a.data("sort-dir")!==d)return a.data("sort-dir",d),e.trigger("beforetablesort",{column:g,direction:d}),e.css("display"),setTimeout(function(){var b=[],l=e.data("sortFns")[k],h=e.children("tbody").children("tr");h.each(function(a,d){var e=c(d).children().eq(g),f=e.data("sort-value");"undefined"===typeof f&&(f=e.text(),e.data("sort-value",f));b.push([f,d])});b.sort(function(a,b){return l(a[0], 3 | b[0])});d!=f.ASC&&b.reverse();h=c.map(b,function(a){return a[1]});e.children("tbody").append(h);e.find("th").data("sort-dir",null).removeClass("sorting-desc sorting-asc");a.data("sort-dir",d).addClass("sorting-"+d);e.trigger("aftertablesort",{column:g,direction:d});e.css("display")},10),a}};c.fn.updateSortVal=function(b){var a=c(this);a.is("[data-sort-value]")&&a.attr("data-sort-value",b);a.data("sort-value",b);return a};c.fn.stupidtable.dir={ASC:"asc",DESC:"desc"};c.fn.stupidtable.default_sort_fns= 4 | {"int":function(b,a){return parseInt(b,10)-parseInt(a,10)},"float":function(b,a){return parseFloat(b)-parseFloat(a)},string:function(b,a){return b.toString().localeCompare(a.toString())},"string-ins":function(b,a){b=b.toString().toLocaleLowerCase();a=a.toString().toLocaleLowerCase();return b.localeCompare(a)}}})(jQuery); 5 | -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | dev.php dev.php 2 | app/MageDev.php app/MageDev.php 3 | app/etc/modules/* app/etc/modules/ 4 | app/code/community/Ecocode/Profiler/* app/code/community/Ecocode/Profiler/ 5 | app/design/frontend/base/default/layout/* app/design/frontend/base/default/layout/ 6 | app/design/frontend/base/default/template/* app/design/frontend/base/default/template/ 7 | app/design/frontend/base/default/layout/* app/design/adminhtml/base/default/layout/ 8 | app/design/frontend/base/default/template/* app/design/adminhtml/base/default/template/ 9 | skin/frontend/base/default/css/* skin/frontend/base/default/css/ 10 | js/* js/ 11 | -------------------------------------------------------------------------------- /phpmd-ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /phpunit-dev.xml.dist: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | app/code/community/Ecocode/Profiler/Tests/Dev 11 | 12 | 13 | 14 | 15 | app/code/community/Ecocode/Profiler 16 | 17 | app/code/community/Ecocode/Profiler/Tests 18 | app/code/community/Ecocode/Profiler/functions.php 19 | app/code/community/Ecocode/Profiler/debug.php 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /phpunit-prod.xml.dist: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | app/code/community/Ecocode/Profiler/Tests/Prod 8 | 9 | 10 | 11 | 12 | app/code/community/Ecocode/Profiler 13 | 14 | app/code/community/Ecocode/Profiler/Tests 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /skin/frontend/base/default/css/ecocode_profiler/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/skin/frontend/base/default/css/ecocode_profiler/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ecoco/magento_profiler/8906240b7c86d3f41ad0ad3dcc9f8275167babed/skin/frontend/base/default/css/ecocode_profiler/fonts/fontawesome-webfont.woff2 --------------------------------------------------------------------------------