├── app
├── etc
│ └── modules
│ │ └── Bubble_Debug.xml
└── code
│ ├── community
│ └── Bubble
│ │ └── Debug
│ │ ├── etc
│ │ └── config.xml
│ │ └── Model
│ │ └── Observer.php
│ └── local
│ └── Zend
│ └── Db
│ └── Adapter
│ └── Pdo
│ └── Abstract.php
└── README.md
/app/etc/modules/Bubble_Debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
'; 235 | $html .= 'All SQL Queries ('. $count .')'; 236 | $html .= '
'; 237 | $html .= ''; 265 | $html .= ''; 282 | 283 | return $html; 284 | } 285 | } -------------------------------------------------------------------------------- /app/code/local/Zend/Db/Adapter/Pdo/Abstract.php: -------------------------------------------------------------------------------- 1 | _config settings. 57 | * 58 | * @return string 59 | */ 60 | protected function _dsn() 61 | { 62 | // baseline of DSN parts 63 | $dsn = $this->_config; 64 | 65 | // don't pass the username, password, charset, persistent and driver_options in the DSN 66 | unset($dsn['username']); 67 | unset($dsn['password']); 68 | unset($dsn['options']); 69 | unset($dsn['charset']); 70 | unset($dsn['persistent']); 71 | unset($dsn['driver_options']); 72 | 73 | // use all remaining parts in the DSN 74 | foreach ($dsn as $key => $val) { 75 | $dsn[$key] = "$key=$val"; 76 | } 77 | 78 | return $this->_pdoType . ':' . implode(';', $dsn); 79 | } 80 | 81 | /** 82 | * Creates a PDO object and connects to the database. 83 | * 84 | * @return void 85 | * @throws Zend_Db_Adapter_Exception 86 | */ 87 | protected function _connect() 88 | { 89 | // if we already have a PDO object, no need to re-connect. 90 | if ($this->_connection) { 91 | return; 92 | } 93 | 94 | // get the dsn first, because some adapters alter the $_pdoType 95 | $dsn = $this->_dsn(); 96 | 97 | // check for PDO extension 98 | if (!extension_loaded('pdo')) { 99 | /** 100 | * @see Zend_Db_Adapter_Exception 101 | */ 102 | #require_once 'Zend/Db/Adapter/Exception.php'; 103 | throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded'); 104 | } 105 | 106 | // check the PDO driver is available 107 | if (!in_array($this->_pdoType, PDO::getAvailableDrivers())) { 108 | /** 109 | * @see Zend_Db_Adapter_Exception 110 | */ 111 | #require_once 'Zend/Db/Adapter/Exception.php'; 112 | throw new Zend_Db_Adapter_Exception('The ' . $this->_pdoType . ' driver is not currently installed'); 113 | } 114 | 115 | // create PDO connection 116 | $q = $this->_profiler->queryStart('connect', Zend_Db_Profiler::CONNECT); 117 | 118 | // add the persistence flag if we find it in our config array 119 | if (isset($this->_config['persistent']) && ($this->_config['persistent'] == true)) { 120 | $this->_config['driver_options'][PDO::ATTR_PERSISTENT] = true; 121 | } 122 | 123 | try { 124 | $this->_connection = new PDO( 125 | $dsn, 126 | $this->_config['username'], 127 | $this->_config['password'], 128 | $this->_config['driver_options'] 129 | ); 130 | 131 | $this->_profiler->queryEnd($q); 132 | 133 | // set the PDO connection to perform case-folding on array keys, or not 134 | $this->_connection->setAttribute(PDO::ATTR_CASE, $this->_caseFolding); 135 | 136 | // always use exceptions. 137 | $this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 138 | 139 | } catch (PDOException $e) { 140 | /** 141 | * @see Zend_Db_Adapter_Exception 142 | */ 143 | #require_once 'Zend/Db/Adapter/Exception.php'; 144 | throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e); 145 | } 146 | 147 | } 148 | 149 | /** 150 | * Test if a connection is active 151 | * 152 | * @return boolean 153 | */ 154 | public function isConnected() 155 | { 156 | return ((bool) ($this->_connection instanceof PDO)); 157 | } 158 | 159 | /** 160 | * Force the connection to close. 161 | * 162 | * @return void 163 | */ 164 | public function closeConnection() 165 | { 166 | $this->_connection = null; 167 | } 168 | 169 | /** 170 | * Prepares an SQL statement. 171 | * 172 | * @param string $sql The SQL statement with placeholders. 173 | * @param array $bind An array of data to bind to the placeholders. 174 | * @return PDOStatement 175 | */ 176 | public function prepare($sql) 177 | { 178 | $this->_connect(); 179 | $stmtClass = $this->_defaultStmtClass; 180 | if (!class_exists($stmtClass)) { 181 | #require_once 'Zend/Loader.php'; 182 | Zend_Loader::loadClass($stmtClass); 183 | } 184 | $stmt = new $stmtClass($this, $sql); 185 | $stmt->setFetchMode($this->_fetchMode); 186 | return $stmt; 187 | } 188 | 189 | /** 190 | * Gets the last ID generated automatically by an IDENTITY/AUTOINCREMENT column. 191 | * 192 | * As a convention, on RDBMS brands that support sequences 193 | * (e.g. Oracle, PostgreSQL, DB2), this method forms the name of a sequence 194 | * from the arguments and returns the last id generated by that sequence. 195 | * On RDBMS brands that support IDENTITY/AUTOINCREMENT columns, this method 196 | * returns the last value generated for such a column, and the table name 197 | * argument is disregarded. 198 | * 199 | * On RDBMS brands that don't support sequences, $tableName and $primaryKey 200 | * are ignored. 201 | * 202 | * @param string $tableName OPTIONAL Name of table. 203 | * @param string $primaryKey OPTIONAL Name of primary key column. 204 | * @return string 205 | */ 206 | public function lastInsertId($tableName = null, $primaryKey = null) 207 | { 208 | $this->_connect(); 209 | return $this->_connection->lastInsertId(); 210 | } 211 | 212 | /** 213 | * Special handling for PDO query(). 214 | * All bind parameter names must begin with ':' 215 | * 216 | * @param string|Zend_Db_Select $sql The SQL statement with placeholders. 217 | * @param array $bind An array of data to bind to the placeholders. 218 | * @return Zend_Db_Statement_Pdo 219 | * @throws Zend_Db_Adapter_Exception To re-throw PDOException. 220 | */ 221 | public function query($sql, $bind = array()) 222 | { 223 | if (empty($bind) && $sql instanceof Zend_Db_Select) { 224 | $bind = $sql->getBind(); 225 | } 226 | 227 | if (is_array($bind)) { 228 | foreach ($bind as $name => $value) { 229 | if (!is_int($name) && !preg_match('/^:/', $name)) { 230 | $newName = ":$name"; 231 | unset($bind[$name]); 232 | $bind[$newName] = $value; 233 | } 234 | } 235 | } 236 | 237 | // Bubble_Debug start 238 | try { 239 | $start = microtime(true); 240 | $result = parent::query($sql, $bind); 241 | 242 | if (class_exists('Mage')) { 243 | Mage::dispatchEvent('bubble_debug_sql_query_before', array( 244 | 'adapter' => $this, 245 | 'query' => $sql, 246 | 'bind' => $bind, 247 | 'took' => microtime(true) - $start, 248 | )); 249 | } 250 | 251 | return $result; 252 | } catch (PDOException $e) { 253 | /** 254 | * @see Zend_Db_Statement_Exception 255 | */ 256 | #require_once 'Zend/Db/Statement/Exception.php'; 257 | throw new Zend_Db_Statement_Exception($e->getMessage(), $e->getCode(), $e); 258 | } 259 | // Bubble_Debug end 260 | } 261 | 262 | /** 263 | * Executes an SQL statement and return the number of affected rows 264 | * 265 | * @param mixed $sql The SQL statement with placeholders. 266 | * May be a string or Zend_Db_Select. 267 | * @return integer Number of rows that were modified 268 | * or deleted by the SQL statement 269 | */ 270 | public function exec($sql) 271 | { 272 | if ($sql instanceof Zend_Db_Select) { 273 | $sql = $sql->assemble(); 274 | } 275 | 276 | try { 277 | $affected = $this->getConnection()->exec($sql); 278 | 279 | if ($affected === false) { 280 | $errorInfo = $this->getConnection()->errorInfo(); 281 | /** 282 | * @see Zend_Db_Adapter_Exception 283 | */ 284 | #require_once 'Zend/Db/Adapter/Exception.php'; 285 | throw new Zend_Db_Adapter_Exception($errorInfo[2]); 286 | } 287 | 288 | return $affected; 289 | } catch (PDOException $e) { 290 | /** 291 | * @see Zend_Db_Adapter_Exception 292 | */ 293 | #require_once 'Zend/Db/Adapter/Exception.php'; 294 | throw new Zend_Db_Adapter_Exception($e->getMessage(), $e->getCode(), $e); 295 | } 296 | } 297 | 298 | /** 299 | * Quote a raw string. 300 | * 301 | * @param string $value Raw string 302 | * @return string Quoted string 303 | */ 304 | protected function _quote($value) 305 | { 306 | if (is_int($value) || is_float($value)) { 307 | return $value; 308 | } 309 | $this->_connect(); 310 | return $this->_connection->quote($value); 311 | } 312 | 313 | /** 314 | * Begin a transaction. 315 | */ 316 | protected function _beginTransaction() 317 | { 318 | $this->_connect(); 319 | $this->_connection->beginTransaction(); 320 | } 321 | 322 | /** 323 | * Commit a transaction. 324 | */ 325 | protected function _commit() 326 | { 327 | $this->_connect(); 328 | $this->_connection->commit(); 329 | } 330 | 331 | /** 332 | * Roll-back a transaction. 333 | */ 334 | protected function _rollBack() { 335 | $this->_connect(); 336 | $this->_connection->rollBack(); 337 | } 338 | 339 | /** 340 | * Set the PDO fetch mode. 341 | * 342 | * @todo Support FETCH_CLASS and FETCH_INTO. 343 | * 344 | * @param int $mode A PDO fetch mode. 345 | * @return void 346 | * @throws Zend_Db_Adapter_Exception 347 | */ 348 | public function setFetchMode($mode) 349 | { 350 | //check for PDO extension 351 | if (!extension_loaded('pdo')) { 352 | /** 353 | * @see Zend_Db_Adapter_Exception 354 | */ 355 | #require_once 'Zend/Db/Adapter/Exception.php'; 356 | throw new Zend_Db_Adapter_Exception('The PDO extension is required for this adapter but the extension is not loaded'); 357 | } 358 | switch ($mode) { 359 | case PDO::FETCH_LAZY: 360 | case PDO::FETCH_ASSOC: 361 | case PDO::FETCH_NUM: 362 | case PDO::FETCH_BOTH: 363 | case PDO::FETCH_NAMED: 364 | case PDO::FETCH_OBJ: 365 | $this->_fetchMode = $mode; 366 | break; 367 | default: 368 | /** 369 | * @see Zend_Db_Adapter_Exception 370 | */ 371 | #require_once 'Zend/Db/Adapter/Exception.php'; 372 | throw new Zend_Db_Adapter_Exception("Invalid fetch mode '$mode' specified"); 373 | break; 374 | } 375 | } 376 | 377 | /** 378 | * Check if the adapter supports real SQL parameters. 379 | * 380 | * @param string $type 'positional' or 'named' 381 | * @return bool 382 | */ 383 | public function supportsParameters($type) 384 | { 385 | switch ($type) { 386 | case 'positional': 387 | case 'named': 388 | default: 389 | return true; 390 | } 391 | } 392 | 393 | /** 394 | * Retrieve server version in PHP style 395 | * 396 | * @return string 397 | */ 398 | public function getServerVersion() 399 | { 400 | $this->_connect(); 401 | try { 402 | $version = $this->_connection->getAttribute(PDO::ATTR_SERVER_VERSION); 403 | } catch (PDOException $e) { 404 | // In case of the driver doesn't support getting attributes 405 | return null; 406 | } 407 | $matches = null; 408 | if (preg_match('/((?:[0-9]{1,2}\.){1,3}[0-9]{1,2})/', $version, $matches)) { 409 | return $matches[1]; 410 | } else { 411 | return null; 412 | } 413 | } 414 | } 415 | 416 | --------------------------------------------------------------------------------'; 266 | $html .= 'Design'; 267 | $html .= '
'; 268 | $html .= sprintf('Package: %s
', Mage::getDesign()->getPackageName()); 269 | $html .= sprintf('Theme: %s
', Mage::getDesign()->getTheme('default')); 270 | $html .= ''; 271 | $html .= 'Layout Updates'; 272 | $html .= '
'; 273 | $html .= implode('
', Mage::app()->getLayout()->getUpdate()->getHandles()); 274 | $html .= ''; 275 | $html .= 'Rendered Blocks'; 276 | $html .= '
'; 277 | foreach ($this->_debug['blocks'] as $block) { 278 | $this->_getBlockInfoHtml($html, $block); 279 | } 280 | $html .= $this->_getSqlDebugHtml(); 281 | $html .= '