Lib_Magento - Version 1.8.0.0

Version Notes

1.8.0.0

Download this release

Release Info

Developer Magento Core Team
Extension Lib_Magento
Version 1.8.0.0
Comparing to
See all releases


Version 1.8.0.0

lib/Magento/Crypt.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Crypt
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Class encapsulates cryptographic algorithm
13
+ */
14
+ class Magento_Crypt
15
+ {
16
+ /**
17
+ * @var string
18
+ */
19
+ protected $_cipher;
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ protected $_mode;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected $_initVector;
30
+
31
+ /**
32
+ * Encryption algorithm module handle
33
+ *
34
+ * @var resource
35
+ */
36
+ protected $_handle;
37
+
38
+ /**
39
+ * Constructor
40
+ *
41
+ * @param string $key Secret encryption key.
42
+ * It's unsafe to store encryption key in memory, so no getter for key exists.
43
+ * @param string $cipher Cipher algorithm (one of the MCRYPT_ciphername constants)
44
+ * @param string $mode Mode of cipher algorithm (MCRYPT_MODE_modeabbr constants)
45
+ * @param string|bool $initVector Initial vector to fill algorithm blocks.
46
+ * TRUE generates a random initial vector.
47
+ * FALSE fills initial vector with zero bytes to not use it.
48
+ * @throws Magento_Exception
49
+ */
50
+ public function __construct($key, $cipher = MCRYPT_BLOWFISH, $mode = MCRYPT_MODE_ECB, $initVector = false)
51
+ {
52
+ $this->_cipher = $cipher;
53
+ $this->_mode = $mode;
54
+ $this->_handle = mcrypt_module_open($cipher, '', $mode, '');
55
+ try {
56
+ $maxKeySize = mcrypt_enc_get_key_size($this->_handle);
57
+ if (strlen($key) > $maxKeySize) {
58
+ throw new Magento_Exception('Key must not exceed ' . $maxKeySize . ' bytes.');
59
+ }
60
+ $initVectorSize = mcrypt_enc_get_iv_size($this->_handle);
61
+ if (true === $initVector) {
62
+ /* Generate a random vector from human-readable characters */
63
+ $abc = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
64
+ $initVector = '';
65
+ for ($i = 0; $i < $initVectorSize; $i++) {
66
+ $initVector .= $abc{rand(0, strlen($abc) - 1)};
67
+ }
68
+ } else if (false === $initVector) {
69
+ /* Set vector to zero bytes to not use it */
70
+ $initVector = str_repeat("\0", $initVectorSize);
71
+ } else if (!is_string($initVector) || strlen($initVector) != $initVectorSize) {
72
+ throw new Magento_Exception('Init vector must be a string of ' . $initVectorSize . ' bytes.');
73
+ }
74
+ $this->_initVector = $initVector;
75
+ } catch (Exception $e) {
76
+ mcrypt_module_close($this->_handle);
77
+ throw $e;
78
+ }
79
+ mcrypt_generic_init($this->_handle, $key, $initVector);
80
+ }
81
+
82
+ /**
83
+ * Destructor frees allocated resources
84
+ */
85
+ public function __destruct()
86
+ {
87
+ mcrypt_generic_deinit($this->_handle);
88
+ mcrypt_module_close($this->_handle);
89
+ }
90
+
91
+ /**
92
+ * Retrieve a name of currently used cryptographic algorithm
93
+ *
94
+ * @return string
95
+ */
96
+ public function getCipher()
97
+ {
98
+ return $this->_cipher;
99
+ }
100
+
101
+ /**
102
+ * Mode in which cryptographic algorithm is running
103
+ *
104
+ * @return string
105
+ */
106
+ public function getMode()
107
+ {
108
+ return $this->_mode;
109
+ }
110
+
111
+ /**
112
+ * Retrieve an actual value of initial vector that has been used to initialize a cipher
113
+ *
114
+ * @return string
115
+ */
116
+ public function getInitVector()
117
+ {
118
+ return $this->_initVector;
119
+ }
120
+
121
+ /**
122
+ * Encrypt a data
123
+ *
124
+ * @param string $data String to encrypt
125
+ * @return string
126
+ */
127
+ public function encrypt($data)
128
+ {
129
+ if (strlen($data) == 0) {
130
+ return $data;
131
+ }
132
+ return mcrypt_generic($this->_handle, $data);
133
+ }
134
+
135
+ /**
136
+ * Decrypt a data
137
+ *
138
+ * @param string $data String to decrypt
139
+ * @return string
140
+ */
141
+ public function decrypt($data)
142
+ {
143
+ if (strlen($data) == 0) {
144
+ return $data;
145
+ }
146
+ $data = mdecrypt_generic($this->_handle, $data);
147
+ /*
148
+ * Returned string can in fact be longer than the unencrypted string due to the padding of the data
149
+ * @link http://www.php.net/manual/en/function.mdecrypt-generic.php
150
+ */
151
+ $data = rtrim($data, "\0");
152
+ return $data;
153
+ }
154
+ }
lib/Magento/Db/Adapter/Pdo/Mysql.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento PDO MySQL DB adapter
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Adapter_Pdo_Mysql extends Varien_Db_Adapter_Pdo_Mysql
35
+ {
36
+ /**
37
+ * Returns flag is transaction now?
38
+ *
39
+ * @return bool
40
+ */
41
+ public function isTransaction()
42
+ {
43
+ return (bool)$this->_transactionLevel;
44
+ }
45
+
46
+ /**
47
+ * Batched insert of specified select
48
+ *
49
+ * @param Varien_Db_Select $select
50
+ * @param string $table
51
+ * @param array $fields
52
+ * @param bool $mode
53
+ * @param int $step
54
+ * @return int
55
+ */
56
+ public function insertBatchFromSelect(Varien_Db_Select $select, $table, array $fields = array(),
57
+ $mode = false, $step = 10000
58
+ ) {
59
+ $limitOffset = 0;
60
+ $totalAffectedRows = 0;
61
+
62
+ do {
63
+ $select->limit($step, $limitOffset);
64
+ $result = $this->query(
65
+ $this->insertFromSelect($select, $table, $fields, $mode)
66
+ );
67
+
68
+ $affectedRows = $result->rowCount();
69
+ $totalAffectedRows += $affectedRows;
70
+ $limitOffset += $step;
71
+ } while ($affectedRows > 0);
72
+
73
+ return $totalAffectedRows;
74
+ }
75
+
76
+ /**
77
+ * Retrieve bunch of queries for specified select splitted by specified step
78
+ *
79
+ * @param Varien_Db_Select $select
80
+ * @param string $entityIdField
81
+ * @param int $step
82
+ * @return array
83
+ */
84
+ public function splitSelect(Varien_Db_Select $select, $entityIdField = '*', $step = 10000)
85
+ {
86
+ $countSelect = clone $select;
87
+
88
+ $countSelect->reset(Zend_Db_Select::COLUMNS);
89
+ $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
90
+ $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
91
+ $countSelect->columns('COUNT(' . $entityIdField . ')');
92
+
93
+ $row = $this->fetchRow($countSelect);
94
+ $totalRows = array_shift($row);
95
+
96
+ $bunches = array();
97
+ for ($i = 0; $i <= $totalRows; $i += $step) {
98
+ $bunchSelect = clone $select;
99
+ $bunches[] = $bunchSelect->limit($step, $i);
100
+ }
101
+
102
+ return $bunches;
103
+ }
104
+ }
lib/Magento/Db/Object.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Object
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ abstract class Magento_Db_Object
35
+ {
36
+ /**
37
+ * @var Varien_Db_Adapter_Interface
38
+ */
39
+ protected $_adapter = null;
40
+
41
+ /**
42
+ * @var string
43
+ */
44
+ protected $_objectName = null;
45
+
46
+ /**
47
+ * @var string
48
+ */
49
+ protected $_dbType = null;
50
+
51
+ /**
52
+ * @var string
53
+ */
54
+ protected $_schemaName = null;
55
+
56
+ /**
57
+ * Constructor
58
+ * @param $objectName
59
+ * @param Varien_Db_Adapter_Interface $adapter
60
+ * @param $schemaName
61
+ */
62
+ public function __construct(Varien_Db_Adapter_Interface $adapter, $objectName, $schemaName = null)
63
+ {
64
+ $this->_objectName = $objectName;
65
+ $this->_adapter = $adapter;
66
+ $this->_schemaName = $schemaName;
67
+ }
68
+
69
+ /**
70
+ * Returns object type
71
+ *
72
+ * @return string
73
+ */
74
+ public function getDbType()
75
+ {
76
+ return $this->_dbType;
77
+ }
78
+
79
+
80
+ /**
81
+ * Returns current schema name
82
+ *
83
+ * @return string
84
+ */
85
+ protected function _getCurrentSchema()
86
+ {
87
+ return $this->_adapter->fetchOne('SELECT SCHEMA()');
88
+ }
89
+
90
+ /**
91
+ * Returns schema name
92
+ *
93
+ * @return string
94
+ */
95
+ public function getSchemaName()
96
+ {
97
+ if (!$this->_schemaName) {
98
+ $this->_schemaName = $this->_getCurrentSchema();
99
+ }
100
+
101
+ return $this->_schemaName;
102
+ }
103
+
104
+ /**
105
+ * Drop database object
106
+ *
107
+ * @return Magento_Db_Object
108
+ */
109
+ public function drop()
110
+ {
111
+ $query = 'DROP ' . $this->getDbType() . ' IF EXISTS '
112
+ . $this->_adapter->quoteIdentifier($this->_objectName);
113
+ $this->_adapter->query($query);
114
+
115
+ return $this;
116
+ }
117
+
118
+ /**
119
+ * Returns object name
120
+ *
121
+ * @return string
122
+ */
123
+ public function getFullName()
124
+ {
125
+ return ($this->getSchemaName() ? $this->getSchemaName() . '.' : '') . $this->_objectName;
126
+ }
127
+
128
+ /**
129
+ * Returns object name
130
+ *
131
+ * @return string
132
+ */
133
+ public function getObjectName()
134
+ {
135
+ return $this->_objectName;
136
+ }
137
+ }
lib/Magento/Db/Object/Interface.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Object_Interface
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ interface Magento_Db_Object_Interface
35
+ {
36
+ /**
37
+ * Describe database object
38
+ *
39
+ * @return array
40
+ */
41
+ public function describe();
42
+
43
+ /**
44
+ * Drop database object
45
+ */
46
+ public function drop();
47
+
48
+ /**
49
+ * Check that database object is exist
50
+ */
51
+ public function isExists();
52
+ }
lib/Magento/Db/Object/Table.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Object_Table
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Object_Table extends Magento_Db_Object implements Magento_Db_Object_Interface
35
+ {
36
+ /**
37
+ * @var string
38
+ */
39
+ protected $_dbType = 'TABLE';
40
+
41
+ /**
42
+ * Check is object exists
43
+ *
44
+ * @return bool
45
+ */
46
+ public function isExists()
47
+ {
48
+ return $this->_adapter->isTableExists($this->_objectName, $this->_schemaName);
49
+ }
50
+
51
+ /**
52
+ * Create a new table from source
53
+ *
54
+ * @param $source Zend_Db_Select
55
+ * @return Magento_Db_Object_Table
56
+ */
57
+ public function createFromSource(Zend_Db_Select $source)
58
+ {
59
+ $this->_adapter->query(
60
+ 'CREATE ' . $this->getDbType() . ' ' . $this->_objectName . ' AS ' . $source
61
+ );
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Describe Table
67
+ *
68
+ * @return array
69
+ */
70
+ public function describe()
71
+ {
72
+ return $this->_adapter->describeTable($this->_objectName, $this->_schemaName);
73
+ }
74
+ }
lib/Magento/Db/Object/Trigger.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Object_Trigger
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Object_Trigger extends Magento_Db_Object implements Magento_Db_Object_Interface
35
+ {
36
+ /**
37
+ * @var string
38
+ */
39
+ protected $_dbType = 'TRIGGER';
40
+
41
+ /**
42
+ * @var array
43
+ */
44
+ protected $_data = array();
45
+
46
+ /**
47
+ * @return bool
48
+ */
49
+ public function isExists()
50
+ {
51
+ if (!isset($this->_data['triggers'][$this->_schemaName])) {
52
+ $this->describe();
53
+ }
54
+
55
+ if (isset($this->_data['triggers'][$this->_schemaName][$this->_objectName])) {
56
+ return true;
57
+ }
58
+
59
+ return false;
60
+ }
61
+
62
+ public function describe()
63
+ {
64
+ $columns = array(
65
+ 'TRIGGER_NAME',
66
+ 'EVENT_MANIPULATION',
67
+ 'EVENT_OBJECT_CATALOG',
68
+ 'EVENT_OBJECT_SCHEMA',
69
+ 'EVENT_OBJECT_TABLE',
70
+ 'ACTION_ORDER',
71
+ 'ACTION_CONDITION',
72
+ 'ACTION_STATEMENT',
73
+ 'ACTION_ORIENTATION',
74
+ 'ACTION_TIMING',
75
+ 'ACTION_REFERENCE_OLD_TABLE',
76
+ 'ACTION_REFERENCE_NEW_TABLE',
77
+ 'ACTION_REFERENCE_OLD_ROW',
78
+ 'ACTION_REFERENCE_NEW_ROW',
79
+ 'CREATED',
80
+ );
81
+ $sql = 'SELECT ' . implode(', ', $columns)
82
+ . ' FROM ' . $this->_adapter->quoteIdentifier(array('INFORMATION_SCHEMA','TRIGGERS'))
83
+ . ' WHERE ';
84
+
85
+ $schema = $this->getSchemaName();
86
+ if ($schema) {
87
+ $sql .= $this->_adapter->quoteIdentifier('EVENT_OBJECT_SCHEMA')
88
+ . ' = ' . $this->_adapter->quote($schema);
89
+ } else {
90
+ $sql .= $this->_adapter->quoteIdentifier('EVENT_OBJECT_SCHEMA')
91
+ . ' != ' . $this->_adapter->quote('INFORMATION_SCHEMA');
92
+ }
93
+
94
+ $results = $this->_adapter->query($sql);
95
+
96
+ $data = array();
97
+ foreach ($results as $row) {
98
+ $row = array_change_key_case($row, CASE_LOWER);
99
+ if (null !== $row['created']) {
100
+ $row['created'] = new DateTime($row['created']);
101
+ }
102
+ $data[$row['trigger_name']] = $row;
103
+ }
104
+ $this->_data['triggers'][$schema] = $data;
105
+
106
+ return $data;
107
+ }
108
+ }
109
+
lib/Magento/Db/Object/View.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Object_View
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Object_View extends Magento_Db_Object implements Magento_Db_Object_Interface
35
+ {
36
+ const ALGORITHM_MERGE = 'MERGE';
37
+ const ALGORITHM_TEMPTABLE = 'TEMPTABLE';
38
+
39
+ /**
40
+ * @var string
41
+ */
42
+ protected $_dbType = 'VIEW';
43
+
44
+ /**
45
+ * Create view from source
46
+ *
47
+ * @param $source
48
+ * @param string $algorithm
49
+ * @return Magento_Db_Object_View
50
+ */
51
+ public function createFromSource(Zend_Db_Select $source, $algorithm = self::ALGORITHM_MERGE)
52
+ {
53
+ $this->_adapter->query(
54
+ 'CREATE ALGORITHM = ' . $algorithm . ' ' . $this->getDbType() . ' '
55
+ . $this->getObjectName() . ' AS ' . $source
56
+ );
57
+ return $this;
58
+ }
59
+
60
+ /**
61
+ * Describe Table
62
+ *
63
+ * @return array
64
+ */
65
+ public function describe()
66
+ {
67
+ return $this->_adapter->describeTable($this->_objectName, $this->_schemaName);
68
+ }
69
+
70
+ /**
71
+ * Check is object exists
72
+ *
73
+ * @return bool
74
+ */
75
+ public function isExists()
76
+ {
77
+ return $this->_adapter->isTableExists($this->_objectName, $this->_schemaName);
78
+ }
79
+ }
lib/Magento/Db/Sql/Select.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Sql_Select
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Sql_Select extends Varien_Db_Select
35
+ {
36
+
37
+ }
lib/Magento/Db/Sql/Trigger.php ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Magento
22
+ * @package Magento_Db
23
+ * @copyright Copyright (c) 2012 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Magento_Db_Sql_Trigger
29
+ *
30
+ * @category Magento
31
+ * @package Magento_Db
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Magento_Db_Sql_Trigger
35
+ {
36
+ const NAME = 'name';
37
+ const TARGET = 'target';
38
+ const TIME = 'time';
39
+ const EVENT = 'event';
40
+ const SCOPE = 'scope';
41
+ const BODY = 'body';
42
+
43
+ /**
44
+ * SQL constants
45
+ */
46
+ const SQL_TIME_BEFORE = 'BEFORE';
47
+ const SQL_TIME_AFTER = 'AFTER';
48
+ const SQL_EVENT_INSERT = 'INSERT';
49
+ const SQL_EVENT_UPDATE = 'UPDATE';
50
+ const SQL_EVENT_DELETE = 'DELETE';
51
+ const SQL_FOR_EACH_ROW = 'FOR EACH ROW';
52
+
53
+ /**
54
+ * Trigger parts
55
+ *
56
+ * @var array
57
+ */
58
+ protected $_parts = array();
59
+
60
+ /**
61
+ * Allowed time types
62
+ *
63
+ * @var array
64
+ */
65
+ protected $_timeTypes = array(
66
+ self::SQL_TIME_AFTER,
67
+ self::SQL_TIME_BEFORE
68
+ );
69
+
70
+ /**
71
+ * Allowed event types
72
+ *
73
+ * @var array
74
+ */
75
+ protected $_eventTypes = array(
76
+ self::SQL_EVENT_INSERT,
77
+ self::SQL_EVENT_UPDATE,
78
+ self::SQL_EVENT_DELETE
79
+ );
80
+
81
+ /**
82
+ * Initial trigger structure, for MySQL scope is always "FOR EACH ROW".
83
+ * Time "AFTER" is default
84
+ *
85
+ * @var array
86
+ */
87
+ protected static $_partsInit = array(
88
+ self::TARGET => null,
89
+ self::TIME => self::SQL_TIME_AFTER,
90
+ self::EVENT => null,
91
+ self::SCOPE => self::SQL_FOR_EACH_ROW,
92
+ self::BODY => array()
93
+ );
94
+
95
+ /**
96
+ * Constructor
97
+ */
98
+ public function __construct()
99
+ {
100
+ $this->_parts = self::$_partsInit;
101
+ }
102
+
103
+ /**
104
+ * Validate where all trigger parts set?
105
+ *
106
+ * @return Magento_Db_Sql_Trigger
107
+ * @throws Exception
108
+ */
109
+ protected function _validateIsComplete()
110
+ {
111
+ foreach (array_keys(self::$_partsInit) as $part) {
112
+ if (empty($this->_parts[$part])) {
113
+ throw new Exception('Part [' . $part . '] should be set');
114
+ }
115
+ }
116
+ return $this;
117
+ }
118
+
119
+ /**
120
+ * Set trigger part
121
+ *
122
+ * @param $part
123
+ * @param $value
124
+ * @return Magento_Db_Sql_Trigger
125
+ * @throws InvalidArgumentException
126
+ */
127
+ protected function _setPart($part, $value)
128
+ {
129
+ if ($value != null) {
130
+ $this->_parts[$part] = $value;
131
+ } else {
132
+ throw new InvalidArgumentException('Part [' . $part . '] can not be empty');
133
+ }
134
+ return $this;
135
+ }
136
+
137
+ /**
138
+ * Set trigger part
139
+ *
140
+ * @param $part
141
+ * @return string|array
142
+ * @throws Exception
143
+ */
144
+ protected function _getPart($part)
145
+ {
146
+ if (isset($this->_parts[$part])) {
147
+ return $this->_parts[$part];
148
+ }
149
+
150
+ throw new Exception('Part [' . $part . '] does\'t exists');
151
+ }
152
+
153
+ /**
154
+ * Set body part to trigger
155
+ *
156
+ * @param $part
157
+ * @param $value
158
+ * @return Magento_Db_Sql_Trigger
159
+ * @throws InvalidArgumentException
160
+ */
161
+ public function setBodyPart($part, $value)
162
+ {
163
+ if ($value != null) {
164
+ $this->_parts[self::BODY][$part] = $value;
165
+ } else {
166
+ throw new InvalidArgumentException('Part [' . $part . '] can not be empty');
167
+ }
168
+ return $this;
169
+ }
170
+
171
+
172
+ /**
173
+ * Set body part to trigger
174
+ *
175
+ * @param string $part
176
+ * @return string
177
+ * @throws Exception
178
+ */
179
+ public function getBodyPart($part)
180
+ {
181
+ if (isset($this->_parts[self::BODY][$part])) {
182
+ return $this->_parts[self::BODY][$part];
183
+ }
184
+
185
+ throw new Exception('Part [' . $part . '] does\'t exists');
186
+ }
187
+
188
+ /**
189
+ * Generate trigger name
190
+ *
191
+ * @return string
192
+ */
193
+ protected function _generateTriggerName()
194
+ {
195
+ return strtolower('trg_' . $this->_parts[self::TARGET]
196
+ . '_' . $this->_parts[self::TIME]
197
+ . '_' . $this->_parts[self::EVENT]);
198
+ }
199
+
200
+ /**
201
+ * Set trigger time {BEFORE/AFTER}
202
+ * @param $time
203
+ * @return Magento_Db_Sql_Trigger
204
+ * @throws InvalidArgumentException
205
+ */
206
+ public function setTime($time)
207
+ {
208
+ if (in_array($time, $this->getTimeTypes())) {
209
+ $this->_setPart(self::TIME, $time);
210
+ } else {
211
+ throw new InvalidArgumentException('Unsupported time type!');
212
+ }
213
+ return $this;
214
+ }
215
+
216
+ /**
217
+ * Set trigger event {INSERT/UPDATE/DELETE}
218
+ *
219
+ * @param $event
220
+ * @return Magento_Db_Sql_Trigger
221
+ * @throws InvalidArgumentException
222
+ */
223
+ public function setEvent($event)
224
+ {
225
+ if (in_array($event, $this->getEventTypes())) {
226
+ $this->_setPart(self::EVENT, $event);
227
+ } else {
228
+ throw new InvalidArgumentException('Unsupported event type!');
229
+ }
230
+ return $this;
231
+ }
232
+
233
+ /**
234
+ * Set trigger target, table name
235
+ *
236
+ * @param $target
237
+ * @return Magento_Db_Sql_Trigger
238
+ */
239
+ public function setTarget($target)
240
+ {
241
+ $this->_setPart(self::TARGET, $target);
242
+ return $this;
243
+ }
244
+
245
+ /**
246
+ * Set trigger name
247
+ *
248
+ * @param $name
249
+ * @return Magento_Db_Sql_Trigger
250
+ */
251
+ public function setName($name)
252
+ {
253
+ $this->_setPart(self::NAME, $name);
254
+ return $this;
255
+ }
256
+
257
+ /**
258
+ * Retrieve trigger name.
259
+ * If trigger name does not exists generate it by template 'trg_{TARGET}_{TIME}_{EVENT}'.
260
+ *
261
+ * @return mixed
262
+ */
263
+ public function getName()
264
+ {
265
+ if (empty($this->_parts[self::NAME])) {
266
+ $this->_parts[self::NAME] = $this->_generateTriggerName();
267
+ }
268
+ return $this->_parts[self::NAME];
269
+ }
270
+
271
+ /**
272
+ * Set trigger body
273
+ *
274
+ * @param array|string $body
275
+ * @return Magento_Db_Sql_Trigger
276
+ */
277
+ public function setBody($body)
278
+ {
279
+ if (!is_array($body)) {
280
+ $body = array($body);
281
+ }
282
+ $this->_setPart(self::BODY, $body);
283
+ return $this;
284
+ }
285
+
286
+ /**
287
+ * Get body parts of trigger
288
+ *
289
+ * @return array
290
+ */
291
+ public function getBody()
292
+ {
293
+ return $this->_getPart(self::BODY);
294
+ }
295
+
296
+ /**
297
+ * Get trigger creating SQL script
298
+ *
299
+ * @return string
300
+ */
301
+ public function assemble()
302
+ {
303
+ $this->_validateIsComplete();
304
+ return "CREATE TRIGGER "
305
+ . $this->getName() . "\n"
306
+ . $this->_parts[self::TIME] . " " . $this->_parts[self::EVENT] . "\n"
307
+ . "ON " . $this->_parts[self::TARGET] . " " . $this->_parts[self::SCOPE] . "\n"
308
+ . "BEGIN\n"
309
+ . implode("\n", $this->_parts[self::BODY]) . "\n"
310
+ . "END;\n";
311
+ }
312
+
313
+ /**
314
+ * Implement magic method
315
+ *
316
+ * @return string
317
+ */
318
+ public function __toString()
319
+ {
320
+ return $this->assemble();
321
+ }
322
+
323
+ /**
324
+ * Retrieve list of allowed events
325
+ *
326
+ * @return array
327
+ */
328
+ public function getEventTypes()
329
+ {
330
+ return $this->_eventTypes;
331
+ }
332
+
333
+ /**
334
+ * Retrieve list of allowed time types
335
+ *
336
+ * @return array
337
+ */
338
+ public function getTimeTypes()
339
+ {
340
+ return $this->_timeTypes;
341
+ }
342
+
343
+ /**
344
+ * Reset trigger parts
345
+ *
346
+ * @return Magento_Db_Sql_Trigger
347
+ */
348
+ public function reset()
349
+ {
350
+ $this->_parts = self::$_partsInit;
351
+ return $this;
352
+ }
353
+ }
lib/Magento/Exception.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Exception
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ class Magento_Exception extends Exception
12
+ {
13
+
14
+ }
lib/Magento/Profiler.php ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Profiler
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Static class that represents profiling tool
13
+ */
14
+ class Magento_Profiler
15
+ {
16
+ /**
17
+ * Separator literal to assemble timer identifier from timer names
18
+ */
19
+ const NESTING_SEPARATOR = '->';
20
+
21
+ /**
22
+ * FETCH_* constants represent keys to retrieve profiling results
23
+ */
24
+ const FETCH_TIME = 'sum';
25
+ const FETCH_COUNT = 'count';
26
+ const FETCH_AVG = 'avg';
27
+ const FETCH_REALMEM = 'realmem';
28
+ const FETCH_EMALLOC = 'emalloc';
29
+
30
+ /**
31
+ * Storage for timers statistics
32
+ *
33
+ * @var array
34
+ */
35
+ static private $_timers = array();
36
+
37
+ /**
38
+ * Whether profiling is active or not
39
+ *
40
+ * @var bool
41
+ */
42
+ static private $_enabled = false;
43
+
44
+ /**
45
+ * Nesting path that represents namespace to resolve timer names
46
+ *
47
+ * @var array
48
+ */
49
+ static private $_currentPath = array();
50
+
51
+ /**
52
+ * Collection of profiler outputs
53
+ *
54
+ * @var array
55
+ */
56
+ static private $_outputs = array();
57
+
58
+ /**
59
+ * Whether an initialization is done or not
60
+ *
61
+ * @var bool
62
+ */
63
+ static private $_isInitialized = false;
64
+
65
+ /**
66
+ * Supported timer statistics keys
67
+ *
68
+ * @var array
69
+ */
70
+ private static $_supportedFetchKeys = array(
71
+ self::FETCH_TIME,
72
+ self::FETCH_AVG,
73
+ self::FETCH_COUNT,
74
+ self::FETCH_EMALLOC,
75
+ self::FETCH_REALMEM,
76
+ );
77
+
78
+ /**
79
+ * Retrieve unique identifier among all timers
80
+ *
81
+ * @param string|null $timerName Timer name
82
+ * @return string
83
+ */
84
+ private static function _getTimerId($timerName = null)
85
+ {
86
+ $currentPath = self::$_currentPath;
87
+ if ($timerName) {
88
+ $currentPath[] = $timerName;
89
+ }
90
+ return implode(self::NESTING_SEPARATOR, $currentPath);
91
+ }
92
+
93
+ /**
94
+ * Enable profiling.
95
+ * Any call to profiler does nothing until profiler is enabled.
96
+ */
97
+ public static function enable()
98
+ {
99
+ if (!self::$_isInitialized) {
100
+ register_shutdown_function(array(__CLASS__, 'display'));
101
+ self::$_isInitialized = true;
102
+ }
103
+ self::$_enabled = true;
104
+ }
105
+
106
+ /**
107
+ * Disable profiling.
108
+ * Any call to profiler is silently ignored while profiler is disabled.
109
+ */
110
+ public static function disable()
111
+ {
112
+ self::$_enabled = false;
113
+ }
114
+
115
+ /**
116
+ * Reset collected statistics for specified timer or for whole profiler if timer name is omitted
117
+ *
118
+ * @param string|null $timerName
119
+ */
120
+ public static function reset($timerName = null)
121
+ {
122
+ if ($timerName === null) {
123
+ self::$_timers = array();
124
+ self::$_currentPath = array();
125
+ return;
126
+ }
127
+ $timerId = self::_getTimerId($timerName);
128
+ self::$_timers[$timerId] = array(
129
+ 'start' => false,
130
+ self::FETCH_TIME => 0,
131
+ self::FETCH_COUNT => 0,
132
+ self::FETCH_REALMEM => 0,
133
+ self::FETCH_EMALLOC => 0,
134
+ );
135
+ }
136
+
137
+ /**
138
+ * Start collecting statistics for specified timer
139
+ *
140
+ * @param string $timerName
141
+ * @throws Varien_Exception
142
+ */
143
+ public static function start($timerName)
144
+ {
145
+ if (!self::$_enabled) {
146
+ return;
147
+ }
148
+
149
+ if (strpos($timerName, self::NESTING_SEPARATOR) !== false) {
150
+ throw new Varien_Exception('Timer name must not contain a nesting separator.');
151
+ }
152
+
153
+ $timerId = self::_getTimerId($timerName);
154
+
155
+ if (empty(self::$_timers[$timerId])) {
156
+ self::reset($timerName);
157
+ }
158
+
159
+ /* Continue collecting timers statistics under the latest started one */
160
+ self::$_currentPath[] = $timerName;
161
+
162
+ self::$_timers[$timerId]['realmem_start'] = memory_get_usage(true);
163
+ self::$_timers[$timerId]['emalloc_start'] = memory_get_usage();
164
+ self::$_timers[$timerId]['start'] = microtime(true);
165
+ self::$_timers[$timerId][self::FETCH_COUNT]++;
166
+ }
167
+
168
+ /**
169
+ * Stop recording statistics for specified timer.
170
+ * Call with no arguments to stop the recently started timer.
171
+ * Only the latest started timer can be stopped.
172
+ *
173
+ * @param string|null $timerName
174
+ * @throws Varien_Exception
175
+ */
176
+ public static function stop($timerName = null)
177
+ {
178
+ if (!self::$_enabled) {
179
+ return;
180
+ }
181
+
182
+ /* Get current time as quick as possible to make more accurate calculations */
183
+ $time = microtime(true);
184
+
185
+ $latestTimerName = end(self::$_currentPath);
186
+ if ($timerName !== null && $timerName !== $latestTimerName) {
187
+ if (in_array($timerName, self::$_currentPath)) {
188
+ $exceptionMsg = sprintf('Timer "%s" should be stopped before "%s".', $latestTimerName, $timerName);
189
+ } else {
190
+ $exceptionMsg = sprintf('Timer "%s" has not been started.', $timerName);
191
+ }
192
+ throw new Varien_Exception($exceptionMsg);
193
+ }
194
+
195
+ $timerId = self::_getTimerId();
196
+
197
+ self::$_timers[$timerId][self::FETCH_TIME] += ($time - self::$_timers[$timerId]['start']);
198
+ self::$_timers[$timerId]['start'] = false;
199
+ self::$_timers[$timerId][self::FETCH_REALMEM] += memory_get_usage(true);
200
+ self::$_timers[$timerId][self::FETCH_REALMEM] -= self::$_timers[$timerId]['realmem_start'];
201
+ self::$_timers[$timerId][self::FETCH_EMALLOC] += memory_get_usage();
202
+ self::$_timers[$timerId][self::FETCH_EMALLOC] -= self::$_timers[$timerId]['emalloc_start'];
203
+
204
+ /* Move one level up in timers nesting tree */
205
+ array_pop(self::$_currentPath);
206
+ }
207
+
208
+ /**
209
+ * Retrieve statistics on specified timer
210
+ *
211
+ * @param string $timerId
212
+ * @param string $key Information to return
213
+ * @return int|float
214
+ * @throws Varien_Exception
215
+ */
216
+ public static function fetch($timerId, $key = self::FETCH_TIME)
217
+ {
218
+ if (empty(self::$_timers[$timerId])) {
219
+ throw new Varien_Exception(sprintf('Timer "%s" does not exist.', $timerId));
220
+ }
221
+ if (!in_array($key, self::$_supportedFetchKeys)) {
222
+ throw new Varien_Exception(sprintf('Requested key "%s" is not supported.', $key));
223
+ }
224
+ /* FETCH_AVG = FETCH_TIME / FETCH_COUNT */
225
+ $isAvg = ($key == self::FETCH_AVG);
226
+ if ($isAvg) {
227
+ $key = self::FETCH_TIME;
228
+ }
229
+ $result = self::$_timers[$timerId][$key];
230
+ if ($key == self::FETCH_TIME && self::$_timers[$timerId]['start'] !== false) {
231
+ $result += (microtime(true) - self::$_timers[$timerId]['start']);
232
+ }
233
+ if ($isAvg) {
234
+ $result /= self::$_timers[$timerId][self::FETCH_COUNT];
235
+ }
236
+ return $result;
237
+ }
238
+
239
+ /**
240
+ * Retrieve the list of unique timer identifiers
241
+ *
242
+ * @return array
243
+ */
244
+ public static function getTimers()
245
+ {
246
+ return array_keys(self::$_timers);
247
+ }
248
+
249
+ /**
250
+ * Register profiler output instance to display profiling result at the end of execution
251
+ *
252
+ * @param Magento_Profiler_OutputAbstract $output
253
+ */
254
+ public static function registerOutput(Magento_Profiler_OutputAbstract $output)
255
+ {
256
+ self::enable();
257
+ self::$_outputs[] = $output;
258
+ }
259
+
260
+ /**
261
+ * Display collected statistics with registered outputs
262
+ */
263
+ public static function display()
264
+ {
265
+ if (!self::$_enabled) {
266
+ return;
267
+ }
268
+ /** @var $output Magento_Profiler_OutputAbstract */
269
+ foreach (self::$_outputs as $output) {
270
+ $output->display();
271
+ }
272
+ }
273
+ }
lib/Magento/Profiler/Output/Csvfile.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Profiler
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Class that represents profiler output in Html format
13
+ */
14
+ class Magento_Profiler_Output_Csvfile extends Magento_Profiler_OutputAbstract
15
+ {
16
+ /**
17
+ * @var string
18
+ */
19
+ protected $_filename;
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ protected $_delimiter;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected $_enclosure;
30
+
31
+ /**
32
+ * Start output buffering
33
+ *
34
+ * @param string $filename Target file to save CSV data
35
+ * @param string|null $filter Pattern to filter timers by their identifiers (SQL LIKE syntax)
36
+ * @param string $delimiter Delimiter for CSV format
37
+ * @param string $enclosure Enclosure for CSV format
38
+ */
39
+ public function __construct($filename, $filter = null, $delimiter = ',', $enclosure = '"')
40
+ {
41
+ parent::__construct($filter);
42
+
43
+ $this->_filename = $filename;
44
+ $this->_delimiter = $delimiter;
45
+ $this->_enclosure = $enclosure;
46
+ }
47
+
48
+ /**
49
+ * Display profiling results
50
+ */
51
+ public function display()
52
+ {
53
+ $fileHandle = fopen($this->_filename, 'w');
54
+ if (!$fileHandle) {
55
+ throw new Varien_Exception(sprintf('Can not open a file "%s".', $this->_filename));
56
+ }
57
+
58
+ $needLock = (strpos($this->_filename, 'php://') !== 0);
59
+ $isLocked = false;
60
+ while ($needLock && !$isLocked) {
61
+ $isLocked = flock($fileHandle, LOCK_EX);
62
+ }
63
+
64
+ $this->_writeFileContent($fileHandle);
65
+
66
+ if ($isLocked) {
67
+ flock($fileHandle, LOCK_UN);
68
+ }
69
+ fclose($fileHandle);
70
+ }
71
+
72
+ /**
73
+ * Write content into an opened file handle
74
+ *
75
+ * @param resource $fileHandle
76
+ */
77
+ protected function _writeFileContent($fileHandle)
78
+ {
79
+ foreach ($this->_getTimers() as $timerId) {
80
+ $row = array();
81
+ foreach ($this->_getColumns() as $columnId) {
82
+ $row[] = $this->_renderColumnValue($timerId, $columnId);
83
+ }
84
+ fputcsv($fileHandle, $row, $this->_delimiter, $this->_enclosure);
85
+ }
86
+ }
87
+ }
lib/Magento/Profiler/Output/Firebug.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Profiler
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Class that outputs profiling results to Firebug
13
+ */
14
+ class Magento_Profiler_Output_Firebug extends Magento_Profiler_OutputAbstract
15
+ {
16
+ /**
17
+ * @var Zend_Controller_Request_Abstract
18
+ */
19
+ private $_request;
20
+
21
+ /**
22
+ * @var Zend_Controller_Response_Abstract
23
+ */
24
+ private $_response;
25
+
26
+ /**
27
+ * Start output buffering
28
+ *
29
+ * @param string|null $filter Pattern to filter timers by their identifiers (SQL LIKE syntax)
30
+ */
31
+ public function __construct($filter = null)
32
+ {
33
+ parent::__construct($filter);
34
+ ob_start();
35
+ }
36
+
37
+ /**
38
+ * Request setter
39
+ *
40
+ * @param Zend_Controller_Request_Abstract $request
41
+ */
42
+ public function setRequest(Zend_Controller_Request_Abstract $request)
43
+ {
44
+ $this->_request = $request;
45
+ }
46
+
47
+ /**
48
+ * Response setter
49
+ *
50
+ * @param Zend_Controller_Response_Abstract $response
51
+ */
52
+ public function setResponse(Zend_Controller_Response_Abstract $response)
53
+ {
54
+ $this->_response = $response;
55
+ }
56
+
57
+ /**
58
+ * Display profiling results and flush output buffer
59
+ */
60
+ public function display()
61
+ {
62
+ $firebugMessage = new Zend_Wildfire_Plugin_FirePhp_TableMessage($this->_renderCaption());
63
+ $firebugMessage->setHeader(array_keys($this->_getColumns()));
64
+
65
+ foreach ($this->_getTimers() as $timerId) {
66
+ $row = array();
67
+ foreach ($this->_getColumns() as $columnId) {
68
+ $row[] = $this->_renderColumnValue($timerId, $columnId);
69
+ }
70
+ $firebugMessage->addRow($row);
71
+ }
72
+
73
+ Zend_Wildfire_Plugin_FirePhp::getInstance()->send($firebugMessage);
74
+
75
+ // setup the wildfire channel
76
+ $firebugChannel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
77
+ $firebugChannel->setRequest($this->_request ? $this->_request : new Zend_Controller_Request_Http());
78
+ $firebugChannel->setResponse($this->_response ? $this->_response : new Zend_Controller_Response_Http());
79
+
80
+ // flush the wildfire headers into the response object
81
+ $firebugChannel->flush();
82
+
83
+ // send the response headers
84
+ $firebugChannel->getResponse()->sendHeaders();
85
+
86
+ ob_end_flush();
87
+ }
88
+
89
+ /**
90
+ * Render timer id column value
91
+ *
92
+ * @param string $timerId
93
+ * @return string
94
+ */
95
+ protected function _renderTimerId($timerId)
96
+ {
97
+ $nestingSep = preg_quote(Magento_Profiler::NESTING_SEPARATOR, '/');
98
+ return preg_replace('/.+?' . $nestingSep . '/', '. ', $timerId);
99
+ }
100
+ }
lib/Magento/Profiler/Output/Html.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Profiler
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Class that represents profiler output in Html format
13
+ */
14
+ class Magento_Profiler_Output_Html extends Magento_Profiler_OutputAbstract
15
+ {
16
+ /**
17
+ * Display profiling results
18
+ */
19
+ public function display()
20
+ {
21
+ $out = '<table border="1" cellspacing="0" cellpadding="2">';
22
+ $out .= '<caption>' . $this->_renderCaption() . '</caption>';
23
+ $out .= '<tr>';
24
+ foreach (array_keys($this->_getColumns()) as $columnLabel) {
25
+ $out .= '<th>' . $columnLabel . '</th>';
26
+ }
27
+ $out .= '</tr>';
28
+ foreach ($this->_getTimers() as $timerId) {
29
+ $out .= '<tr>';
30
+ foreach ($this->_getColumns() as $columnId) {
31
+ $out .= '<td title="' . $timerId . '">' . $this->_renderColumnValue($timerId, $columnId) . '</td>';
32
+ }
33
+ $out .= '</tr>';
34
+ }
35
+ $out .= '</table>';
36
+
37
+ echo $out;
38
+ }
39
+
40
+ /**
41
+ * Render timer id column value
42
+ *
43
+ * @param string $timerId
44
+ * @return string
45
+ */
46
+ protected function _renderTimerId($timerId)
47
+ {
48
+ $nestingSep = preg_quote(Magento_Profiler::NESTING_SEPARATOR, '/');
49
+ return preg_replace('/.+?' . $nestingSep . '/', '&middot;&nbsp;&nbsp;', $timerId);
50
+ }
51
+ }
lib/Magento/Profiler/OutputAbstract.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * {license_notice}
4
+ *
5
+ * @category Magento
6
+ * @package Magento_Profiler
7
+ * @copyright {copyright}
8
+ * @license {license_link}
9
+ */
10
+
11
+ /**
12
+ * Abstract class that represents profiler output
13
+ */
14
+ abstract class Magento_Profiler_OutputAbstract
15
+ {
16
+ /**
17
+ * PCRE Regular Expression for filter
18
+ *
19
+ * @var null|string
20
+ */
21
+ private $_filter;
22
+
23
+ /**
24
+ * List of threshold (minimal allowed) values for profiler data
25
+ *
26
+ * @var array
27
+ */
28
+ private $_thresholds = array(
29
+ Magento_Profiler::FETCH_TIME => 0.001,
30
+ Magento_Profiler::FETCH_COUNT => 10,
31
+ Magento_Profiler::FETCH_EMALLOC => 10000,
32
+ );
33
+
34
+ /**
35
+ * Initialize profiler output with timer identifiers filter
36
+ *
37
+ * @param string|null $filter Pattern to filter timers by their identifiers.
38
+ * Supports syntax similar to SQL LIKE operator:
39
+ * % - Matches any number of characters, even zero characters
40
+ * _ - Matches exactly one character
41
+ */
42
+ public function __construct($filter = null)
43
+ {
44
+ $this->_filter = $filter;
45
+ }
46
+
47
+ /**
48
+ * Override in descendants to display profiling results in appropriate format
49
+ */
50
+ abstract public function display();
51
+
52
+ /**
53
+ * Retrieve the list of (column_label; column_id) pairs
54
+ *
55
+ * @return array
56
+ */
57
+ protected function _getColumns()
58
+ {
59
+ return array(
60
+ 'Timer Id' => 'timer_id',
61
+ 'Time' => Magento_Profiler::FETCH_TIME,
62
+ 'Avg' => Magento_Profiler::FETCH_AVG,
63
+ 'Cnt' => Magento_Profiler::FETCH_COUNT,
64
+ 'Emalloc' => Magento_Profiler::FETCH_EMALLOC,
65
+ 'RealMem' => Magento_Profiler::FETCH_REALMEM,
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Render statistics column value for specified timer
71
+ *
72
+ * @param string $timerId
73
+ * @param string $columnId
74
+ */
75
+ protected function _renderColumnValue($timerId, $columnId)
76
+ {
77
+ if ($columnId == 'timer_id') {
78
+ return $this->_renderTimerId($timerId);
79
+ }
80
+ $value = (string)Magento_Profiler::fetch($timerId, $columnId);
81
+ if (in_array($columnId, array(Magento_Profiler::FETCH_TIME, Magento_Profiler::FETCH_AVG))) {
82
+ $value = number_format($value, 6);
83
+ } else {
84
+ $value = number_format($value);
85
+ }
86
+ return $value;
87
+ }
88
+
89
+ /**
90
+ * Render timer id column value
91
+ *
92
+ * @param string $timerId
93
+ * @return string
94
+ */
95
+ protected function _renderTimerId($timerId)
96
+ {
97
+ return $timerId;
98
+ }
99
+
100
+ /**
101
+ * Retrieve timer ids sorted to correspond the nesting
102
+ *
103
+ * @return array
104
+ */
105
+ private function _getSortedTimers()
106
+ {
107
+ $timerIds = Magento_Profiler::getTimers();
108
+ if (count($timerIds) <= 2) {
109
+ /* No sorting needed */
110
+ return $timerIds;
111
+ }
112
+
113
+ /* Prepare PCRE once to use it inside the loop body */
114
+ $nestingSep = preg_quote(Magento_Profiler::NESTING_SEPARATOR, '/');
115
+ $patternLastTimerName = '/' . $nestingSep . '(?:.(?!' . $nestingSep . '))+$/';
116
+
117
+ $prevTimerId = $timerIds[0];
118
+ $result = array($prevTimerId);
119
+ for ($i = 1; $i < count($timerIds); $i++) {
120
+ $timerId = $timerIds[$i];
121
+ /* Skip already added timer */
122
+ if (!$timerId) {
123
+ continue;
124
+ }
125
+ /* Loop over all timers that need to be closed under previous timer */
126
+ while (strpos($timerId, $prevTimerId . Magento_Profiler::NESTING_SEPARATOR) !== 0) {
127
+ /* Add to result all timers nested in the previous timer */
128
+ for ($j = $i + 1; $j < count($timerIds); $j++) {
129
+ if (strpos($timerIds[$j], $prevTimerId . Magento_Profiler::NESTING_SEPARATOR) === 0) {
130
+ $result[] = $timerIds[$j];
131
+ /* Mark timer as already added */
132
+ $timerIds[$j] = null;
133
+ }
134
+ }
135
+ /* Go to upper level timer */
136
+ $count = 0;
137
+ $prevTimerId = preg_replace($patternLastTimerName, '', $prevTimerId, -1, $count);
138
+ /* Break the loop if no replacements was done. It is possible when we are */
139
+ /* working with top level (root) item */
140
+ if (!$count) {
141
+ break;
142
+ }
143
+ }
144
+ /* Add current timer to the result */
145
+ $result[] = $timerId;
146
+ $prevTimerId = $timerId;
147
+ }
148
+ return $result;
149
+ }
150
+
151
+ /**
152
+ * Retrieve the list of timer Ids
153
+ *
154
+ * @return array
155
+ */
156
+ protected function _getTimers()
157
+ {
158
+ $pattern = $this->_filter;
159
+ $timerIds = $this->_getSortedTimers();
160
+ $result = array();
161
+ foreach ($timerIds as $timerId) {
162
+ /* Filter by timer id pattern */
163
+ if ($pattern && !preg_match($pattern, $timerId)) {
164
+ continue;
165
+ }
166
+ /* Filter by column value thresholds */
167
+ $skip = false;
168
+ foreach ($this->_thresholds as $fetchKey => $minAllowedValue) {
169
+ $skip = (Magento_Profiler::fetch($timerId, $fetchKey) < $minAllowedValue);
170
+ /* First value not less than the allowed one forces to include timer to the result */
171
+ if (!$skip) {
172
+ break;
173
+ }
174
+ }
175
+ if (!$skip) {
176
+ $result[] = $timerId;
177
+ }
178
+ }
179
+ return $result;
180
+ }
181
+
182
+ /**
183
+ * Render a caption for the profiling results
184
+ *
185
+ * @return string
186
+ */
187
+ protected function _renderCaption()
188
+ {
189
+ $result = 'Code Profiler (Memory usage: real - %s, emalloc - %s)';
190
+ $result = sprintf($result, memory_get_usage(true), memory_get_usage());
191
+ return $result;
192
+ }
193
+
194
+ /**
195
+ * Set threshold (minimal allowed) value for timer column.
196
+ * Timer is being rendered if at least one of its columns is not less than the minimal allowed value.
197
+ *
198
+ * @param string $fetchKey
199
+ * @param int|float|null $minAllowedValue
200
+ */
201
+ public function setThreshold($fetchKey, $minAllowedValue)
202
+ {
203
+ if ($minAllowedValue === null) {
204
+ unset($this->_thresholds[$fetchKey]);
205
+ } else {
206
+ $this->_thresholds[$fetchKey] = $minAllowedValue;
207
+ }
208
+ }
209
+ }
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Lib_Magento</name>
4
+ <version>1.8.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">OSL v3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Magento Library</summary>
10
+ <description>Magento Library</description>
11
+ <notes>1.8.0.0</notes>
12
+ <authors><author><name>Magento Core Team</name><user>core</user><email>core@magentocommerce.com</email></author></authors>
13
+ <date>2013-09-24</date>
14
+ <time>09:09:43</time>
15
+ <contents><target name="magelib"><dir name="Magento"><file name="Crypt.php" hash="0375279e6d5f6fe5c355e55ed567d50c"/><dir name="Db"><dir name="Adapter"><dir name="Pdo"><file name="Mysql.php" hash="4c72a737a41d548d816b9b23846d6d55"/></dir></dir><dir name="Object"><file name="Interface.php" hash="75538d642ffbd217e6b4f0d6c47ee41d"/><file name="Table.php" hash="4782020387d53b62131ccedaa84a1c07"/><file name="Trigger.php" hash="33e76ea340956805d2951e2d7b166323"/><file name="View.php" hash="e813377fd04712667ad00d6c2cc295cf"/></dir><file name="Object.php" hash="b61d21392c22ed7c035d7232b05997b7"/><dir name="Sql"><file name="Select.php" hash="666a857be35c4cfa3fb153ef757e19b6"/><file name="Trigger.php" hash="2364b625b934404de9965c120d84ca0f"/></dir></dir><file name="Exception.php" hash="d6af7ed137881f7bb5b1687ab0c71626"/><dir name="Profiler"><dir name="Output"><file name="Csvfile.php" hash="4d26324422704578a6f0f10f24b206b1"/><file name="Firebug.php" hash="188662da429ea2f349adeb5dbd30736d"/><file name="Html.php" hash="eb0b933bdd9061385aafdded108db6a0"/></dir><file name="OutputAbstract.php" hash="3a16286d897eae373dc0f8bf5f28d4d3"/></dir><file name="Profiler.php" hash="00b200d890f107c748794e2e31dad910"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
+ </package>