heartbeat_extension_for_magento - Version 0.0.5

Version Notes

Reworked tests structure,
Error management,
Add email notification feature,
Remove deprecated tests

Download this release

Release Info

Developer Gorilla Team
Extension heartbeat_extension_for_magento
Version 0.0.5
Comparing to
See all releases


Version 0.0.5

app/code/local/Gorilla/Heartbeat/Helper/Data.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Data helper
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_Helper_Data extends Mage_Core_Helper_Abstract
7
+ {
8
+ public function log($message, $level = null, $file = '')
9
+ {
10
+ $level = is_null($level) ? Zend_Log::DEBUG : $level;
11
+ $file = empty($file) ? 'system.log' : $file;
12
+
13
+ try {
14
+ $logDir = Mage::getBaseDir('var') . DS . 'log';
15
+ $logFile = $logDir . DS . $file;
16
+
17
+ if (!is_dir($logDir)) {
18
+ mkdir($logDir);
19
+ chmod($logDir, 0777);
20
+ }
21
+
22
+ if (!file_exists($logFile)) {
23
+ file_put_contents($logFile, '');
24
+ chmod($logFile, 0777);
25
+ }
26
+
27
+ $format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
28
+ $formatter = new Zend_Log_Formatter_Simple($format);
29
+
30
+ $writer = new Zend_Log_Writer_Stream($logFile);
31
+
32
+ $writer->setFormatter($formatter);
33
+ $loggers[$file] = new Zend_Log($writer);
34
+
35
+ if (is_array($message) || is_object($message)) {
36
+ $message = print_r($message, true);
37
+ }
38
+
39
+ $loggers[$file]->log($message, $level);
40
+ }
41
+ catch (Exception $e) {
42
+ }
43
+ }
44
+ }
app/code/local/Gorilla/Heartbeat/Model/Observer.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gorilla_Heartbeat_Model_Observer
4
+ {
5
+ protected $_warnings;
6
+
7
+ public function processMailQueue()
8
+ {
9
+ $schedules = Mage::getModel('heartbeat/system_config_source_schedule')->toArray();
10
+ $config = Mage::getStoreConfig('heartbeat/general/email_schedule');
11
+ $hours = $schedules[$config];
12
+ $receiver = Mage::getStoreConfig('heartbeat/general/email');
13
+ if (empty($receiver)) {
14
+ return;
15
+ }
16
+ $lastSent = $this->getLastSentStamp();
17
+ if ($lastSent && (now() < $lastSent + $hours*3600)) {
18
+ return;
19
+ }
20
+ $warnings = $this->getWarnings();
21
+ if (!$warnings) {
22
+ return;
23
+ }
24
+ // send email
25
+
26
+ /** @var Mage_Core_Model_Email_Template_Mailer $mailer */
27
+ $mailer = Mage::getModel('core/email_template_mailer');
28
+ /** @var Mage_Core_Model_Email_Info $emailInfo */
29
+ $emailInfo = Mage::getModel('core/email_info');
30
+ $emailInfo->addTo($receiver, '');
31
+ $mailer->addEmailInfo($emailInfo);
32
+
33
+ // Set all required params and send emails
34
+ $mailer->setSender(Mage::getStoreConfig('trans_email/ident_support/email', 0));
35
+ $mailer->setStoreId(0);
36
+ $mailer->setTemplateId('heartbeat_warning_email_template');
37
+ $mailer->setTemplateParams(array(
38
+ 'warnings' => $this->_getWarningHtml()
39
+ )
40
+ );
41
+ try {
42
+ $mailer->send();
43
+ $this->_setLastSentStamp();
44
+ $this->_truncateWarnings();
45
+ } catch (Exception $e) {
46
+ //
47
+ }
48
+ }
49
+
50
+ public function getLastSentStamp()
51
+ {
52
+ try {
53
+ /** @var Mage_Core_Model_Resource $resource */
54
+ $resource = Mage::getModel('core/resource');
55
+ $connection = $resource->getConnection('core_read');
56
+ $select = $connection->select()
57
+ ->from($resource->getTableName('core_config_data'), array('value'))
58
+ ->where('path = ?', 'heartbeat/warnings/last_sent_stamp');
59
+ return $connection->fetchOne($select);
60
+ } catch (Exception $e) {
61
+ return null;
62
+ }
63
+ }
64
+
65
+ protected function _setLastSentStamp()
66
+ {
67
+ try {
68
+ /** @var Mage_Core_Model_Resource $resource */
69
+ $resource = Mage::getModel('core/resource');
70
+ $connection = $resource->getConnection('core_write');
71
+ $connection->insertOnDuplicate($resource->getTableName('core_config_data'), array(
72
+ 'scope' => 'default',
73
+ 'scope_id' => '0',
74
+ 'path' => 'heartbeat/warnings/last_sent_stamp',
75
+ 'value' => time(),
76
+ ), array());
77
+ } catch (Exception $e) {
78
+ Mage::logException($e);
79
+ }
80
+ return $this;
81
+ }
82
+
83
+ protected function _getWarningHtml()
84
+ {
85
+ $html = '<ul>';
86
+ foreach ($this->getWarnings() as $warning) {
87
+ $html .= "<li>{$warning}</li>";
88
+ }
89
+ $html .= '</ul>';
90
+ return $html;
91
+ }
92
+
93
+
94
+ public function getWarnings()
95
+ {
96
+ if (!$this->_warnings) {
97
+ try {
98
+ /** @var Mage_Core_Model_Resource $resource */
99
+ $resource = Mage::getModel('core/resource');
100
+ $connection = $resource->getConnection('core_read');
101
+ $select = $connection->select()->from($resource->getTableName('heartbeat_warnings'), array('warning'));
102
+ $this->_warnings = $connection->fetchCol($select);
103
+ } catch (Exception $e) {
104
+ $this->_warnings = array();
105
+ }
106
+ }
107
+ return $this->_warnings;
108
+ }
109
+
110
+ protected function _truncateWarnings()
111
+ {
112
+ try {
113
+ /** @var Mage_Core_Model_Resource $resource */
114
+ $resource = Mage::getModel('core/resource');
115
+ $connection = $resource->getConnection('core_write');
116
+ $sql = "DELETE FROM {$resource->getTableName('heartbeat_warnings')}";
117
+ $connection->query($sql);
118
+ } catch (Exception $e) {}
119
+ }
120
+ }
app/code/local/Gorilla/Heartbeat/Model/System/Config/Source/Schedule.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Gorilla_Heartbeat_Model_System_Config_Source_Schedule
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ return array(
12
+ array('value' => '0', 'label' => Mage::helper('core')->__('Each hour')),
13
+ array('value' => '1', 'label' => Mage::helper('core')->__('Each 2 hours')),
14
+ array('value' => '2', 'label' => Mage::helper('core')->__('Each 6 hours')),
15
+ array('value' => '3', 'label' => Mage::helper('core')->__('Each 12 hours')),
16
+ array('value' => '4', 'label' => Mage::helper('core')->__('Each 24 hours')),
17
+ );
18
+ }
19
+
20
+ /**
21
+ * Get options in "key-value" format
22
+ *
23
+ * @return array
24
+ */
25
+ public function toArray()
26
+ {
27
+ return array(
28
+ '0' => Mage::helper('core')->__('1'),
29
+ '1' => Mage::helper('core')->__('2'),
30
+ '2' => Mage::helper('core')->__('6'),
31
+ '3' => Mage::helper('core')->__('12'),
32
+ '4' => Mage::helper('core')->__('24'),
33
+ );
34
+ }
35
+ }
app/code/local/Gorilla/Heartbeat/Model/System/Config/Source/Tests.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Gorilla_Heartbeat_Model_System_Config_Source_Tests
3
+ {
4
+ /**
5
+ * Options getter
6
+ *
7
+ * @return array
8
+ */
9
+ public function toOptionArray()
10
+ {
11
+ /** @var Gorilla_Heartbeat_Model_TestsCollector $helper */
12
+ $collector = Mage::getModel('Gorilla_Heartbeat_Model_TestsCollector');
13
+ $tests = $collector->getAllTests();
14
+ $returnArray = array();
15
+ foreach ($tests as $code => $data) {
16
+ $returnArray[] = array('value' => $code, 'label' => $data['label']);
17
+ }
18
+ return $returnArray;
19
+ }
20
+
21
+ /**
22
+ * Get options in "key-value" format
23
+ *
24
+ * @return array
25
+ */
26
+ public function toArray()
27
+ {
28
+ /** @var Gorilla_Heartbeat_Model_TestsCollector $helper */
29
+ $collector = Mage::getModel('Gorilla_Heartbeat_Model_TestsCollector');
30
+ $tests = $collector->getAllTests();
31
+ $returnArray = array();
32
+ foreach ($tests as $code => $data) {
33
+ $returnArray[$code] = $data['label'];
34
+ }
35
+ return $returnArray;
36
+ }
37
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Abstract.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ abstract class Gorilla_Heartbeat_Model_Tests_Abstract extends Mage_Core_Model_Abstract
3
+ {
4
+ const SEVERITY_SUCCESS = 'success';
5
+ const SEVERITY_ERROR = 'error';
6
+ const SEVERITY_WARNING = 'warning';
7
+
8
+ protected $_errors = array();
9
+ protected $_warnings = array();
10
+ protected $_warningLog = 'gorilla_heartbeat_warning.log';
11
+ protected $_errorLog = 'gorilla_heartbeat_error.log';
12
+
13
+ public function addError($message)
14
+ {
15
+ array_push($this->_errors, $message);
16
+ return $this;
17
+ }
18
+
19
+ public function hasErrors()
20
+ {
21
+ return count($this->_errors) > 0;
22
+ }
23
+
24
+ public function addWarning($message)
25
+ {
26
+ array_push($this->_warnings, $message);
27
+ return $this;
28
+ }
29
+
30
+ public function hasWarnings()
31
+ {
32
+ return count($this->_warnings) > 0;
33
+ }
34
+
35
+ /**
36
+ * Returns result of the test
37
+ * @return mixed
38
+ */
39
+ public function getResult()
40
+ {
41
+ if ($this->hasErrors()) {
42
+ return self::SEVERITY_ERROR;
43
+ }
44
+ if ($this->hasWarnings()) {
45
+ return self::SEVERITY_WARNING;
46
+ }
47
+ return self::SEVERITY_SUCCESS;
48
+ }
49
+
50
+ public function getErrors()
51
+ {
52
+ return $this->_errors;
53
+ }
54
+
55
+ public function getWarnings()
56
+ {
57
+ return $this->_warnings;
58
+ }
59
+
60
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Api.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Api test model.
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_Model_Tests_Api
7
+ extends Gorilla_Heartbeat_Model_Tests_Abstract
8
+ implements Gorilla_Heartbeat_Model_TestsInterface
9
+ {
10
+ /**
11
+ * Returns true if test enabled
12
+ * @return boolean
13
+ * @deprecated after 0.0.2
14
+ */
15
+ public function isEnabled()
16
+ {
17
+ return true;
18
+ }
19
+
20
+ /**
21
+ * Returns true if test passed
22
+ * @return boolean
23
+ * @deprecated after 0.0.2
24
+ */
25
+ public function isPassed()
26
+ {
27
+ foreach ($this->_collectActiveUrls() as $url) {
28
+ if (! $this->_request($url) && strstr($url, 'http')) {
29
+ Mage::helper('heartbeat')->log('Api Test Error. Can\'t access url: ' . $url, null, 'gorilla_heartbeat.log');
30
+ return false;
31
+ }
32
+ }
33
+
34
+ return true;
35
+ }
36
+
37
+ public function process()
38
+ {
39
+ foreach ($this->_collectActiveUrls() as $url) {
40
+ if (! $this->_request($url) && strstr($url, 'http')) {
41
+ Mage::helper('heartbeat')->log('Api Test Error. Can\'t access url: ' . $url, null, $this->_warningLog);
42
+ $this->addWarning('Api Test Error. Can\'t access url: ' . $url);
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Making request to the $url
49
+ * @param string $url
50
+ * @param string $request
51
+ * @return string
52
+ */
53
+ private function _request($url, $request = '')
54
+ {
55
+ $ch = curl_init();
56
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
57
+ curl_setopt($ch, CURLOPT_URL, $url);
58
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
59
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
60
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
61
+ $responseBody = curl_exec($ch);
62
+ curl_close($ch);
63
+
64
+ return $responseBody;
65
+ }
66
+
67
+ /**
68
+ * Collecting active magento third-party integrations. Returns array of urls.
69
+ * @return array
70
+ */
71
+ private function _collectActiveUrls()
72
+ {
73
+ $urls = array();
74
+
75
+ if (Mage::getStoreConfig('carriers/ups/active')) {
76
+ if (Mage::getStoreConfig('carriers/ups/type') == 'UPS_XML') {
77
+ $urls[] = Mage::getStoreConfig('carriers/ups/gateway_xml_url');
78
+ }
79
+ if (Mage::getStoreConfig('carriers/ups/type') == 'UPS') {
80
+ $urls[] = Mage::getStoreConfig('carriers/ups/gateway_url');
81
+ }
82
+ $urls[] = Mage::getStoreConfig('carriers/ups/tracking_xml_url');
83
+
84
+ }
85
+
86
+ if (Mage::getStoreConfig('carriers/usps/active')) {
87
+ $urls[] = Mage::getStoreConfig('carriers/usps/gateway_url');
88
+ $urls[] = Mage::getStoreConfig('carriers/usps/gateway_secure_url');
89
+
90
+ }
91
+
92
+ if (Mage::getStoreConfig('carriers/fedex/active')) {
93
+ $urls[] = 'https://wsbeta.fedex.com:443/web-services/rate';
94
+ $urls[] = 'https://ws.fedex.com:443/web-services/rate';
95
+
96
+ }
97
+
98
+ if (Mage::getStoreConfig('carriers/dhl/active')) {
99
+ $urls[] = Mage::getStoreConfig('carriers/dhl/gateway_url');
100
+
101
+ }
102
+
103
+ if (Mage::getStoreConfig('payment/authorizenet/active')) {
104
+ if (Mage::getStoreConfig('payment/authorizenet_directpost/active')) {
105
+ $urls[] = Mage::getStoreConfig('payment/authorizenet_directpost/cgi_url');
106
+ } else {
107
+ $urls[] = Mage::getStoreConfig('payment/authorizenet/cgi_url');
108
+ }
109
+ }
110
+
111
+ if (Mage::getStoreConfig('payment/ogone/active')) {
112
+ $urls[] = Mage::getStoreConfig('payment/ogone/ogone_gateway');
113
+ }
114
+
115
+ return $urls;
116
+ }
117
+
118
+ public function getRecommendations() {
119
+ return 'One of the APIs in not reachable.';
120
+ }
121
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Catalog.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * catalog test model.
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_Model_Tests_Catalog
7
+ extends Gorilla_Heartbeat_Model_Tests_Abstract
8
+ implements Gorilla_Heartbeat_Model_TestsInterface
9
+ {
10
+ /**
11
+ * Returns true if test enabled
12
+ * @return boolean
13
+ * @deprecated after 0.0.2
14
+ */
15
+ public function isEnabled()
16
+ {
17
+ return true;
18
+ }
19
+
20
+ /**
21
+ * Returns true if test passed
22
+ * @return boolean
23
+ * @deprecated after 0.0.2
24
+ */
25
+ public function isPassed()
26
+ {
27
+ $collection = Mage::getModel('catalog/product')->getCollection();
28
+ $collection->getSelect()->limit(1);
29
+ if (is_int($collection->count())) {
30
+ return true;
31
+ }
32
+
33
+ Mage::helper('heartbeat')->log('Catalog Test Error. Catalog is empty.', null, 'gorilla_heartbeat.log');
34
+ return false;
35
+ }
36
+
37
+ public function process()
38
+ {
39
+ $collection = Mage::getModel('catalog/product')->getCollection();
40
+ $collection->getSelect()->limit(1);
41
+ if (!is_int($collection->count())) {
42
+ Mage::helper('heartbeat')->log('Catalog Test Error. Catalog is empty.', null, $this->_errorLog);
43
+ $this->addError('Catalog Test Error. Catalog is empty.');
44
+ }
45
+ }
46
+
47
+ public function getRecommendations() {
48
+ return 'Magento catalog is not reachable. Please check the database integrity.';
49
+ }
50
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Database.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * database test model.
4
+ * @package
5
+ * @deprecated after 0.0.2
6
+ */
7
+ class Gorilla_Heartbeat_Model_Tests_Database
8
+ extends Mage_Core_Model_Abstract
9
+ implements Gorilla_Heartbeat_Model_TestsInterface
10
+ {
11
+ /**
12
+ * Returns true if test enabled
13
+ * @return boolean
14
+ * @deprecated after 0.0.2
15
+ */
16
+ public function isEnabled()
17
+ {
18
+ return false;
19
+ /* this test is deprecated */
20
+ }
21
+
22
+ /**
23
+ * Returns true if test passed
24
+ * @return boolean
25
+ * @deprecated after 0.0.2
26
+ */
27
+ public function isPassed()
28
+ {
29
+ //$write = Mage::getSingleton('core/resource')->getConnection('core_write');
30
+ //$writeItem = $write->query("INSERT INTO core_config_data (`value`, `path`) VALUES ('test', 'heartbeat/test/test') ON DUPLICATE KEY UPDATE `value` = 'test'");
31
+
32
+ $read = Mage::getSingleton('core/resource')->getConnection('core_read');
33
+ $readItem = $read->query('SELECT * FROM `core_config_data` LIMIT 1')->fetch();
34
+
35
+ if ($readItem /*&& $writeItem*/) {
36
+ return true;
37
+ }
38
+
39
+ Mage::helper('heartbeat')->log('Database Test Error. Cant read from database.', null, 'gorilla_heartbeat.log');
40
+ return false;
41
+ }
42
+
43
+ /**
44
+ * Returns result of the rest
45
+ * @return mixed
46
+ */
47
+ public function getResult()
48
+ {
49
+ return true;
50
+ }
51
+
52
+ public function getRecommendations() {
53
+ return 'Database is not reachable. Please check the database credentials.';
54
+ }
55
+
56
+ public function process(){}
57
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Filesystem.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * filesystem test model.
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_Model_Tests_Filesystem
7
+ extends Gorilla_Heartbeat_Model_Tests_Abstract
8
+ implements Gorilla_Heartbeat_Model_TestsInterface
9
+ {
10
+ const MODE_WRITE = 'write';
11
+ const MODE_READ = 'read';
12
+
13
+ /**
14
+ * Returns true if test enabled
15
+ * @return boolean
16
+ * @deprecated after 0.0.2
17
+ */
18
+ public function isEnabled()
19
+ {
20
+ return true;
21
+ }
22
+
23
+ /**
24
+ * Returns true if test passed
25
+ * @return boolean
26
+ * @deprecated after 0.0.2
27
+ */
28
+ public function isPassed()
29
+ {
30
+ $file = new Varien_Io_File();
31
+ $filename = Mage::getBaseDir('var') . DS . 'test.txt';
32
+ $dirname = Mage::getBaseDir('var');
33
+
34
+ if (file_exists($filename)) {
35
+ if (!is_writeable($filename)) {
36
+ Mage::helper('heartbeat')->log('Filesystem Test Error. Files in var directory are no writable.', null, 'gorilla_heartbeat.log');
37
+ return false;
38
+ }
39
+ }
40
+
41
+ if (!is_writable($dirname)) {
42
+ Mage::helper('heartbeat')->log('Filesystem Test Error. Var directory is no writable.', null, 'gorilla_heartbeat.log');
43
+ return false;
44
+ }
45
+
46
+ $file->open($dirname);
47
+ $file->write($filename, 'testcontent');
48
+ $fileContent = $file->read($filename);
49
+
50
+ if ($fileContent == 'testcontent') {
51
+ return true;
52
+ }
53
+
54
+ Mage::helper('heartbeat')->log('Filesystem Test Error. Cant read or write to the test file in var directory.', null, 'gorilla_heartbeat.log');
55
+ return false;
56
+ }
57
+
58
+ public function process()
59
+ {
60
+ // filesystem
61
+ $config = Mage::getSingleton('install/config')->getPathForCheck();
62
+
63
+ if (isset($config['writeable'])) {
64
+ foreach ($config['writeable'] as $item) {
65
+ $recursive = isset($item['recursive']) ? $item['recursive'] : false;
66
+ $existence = isset($item['existence']) ? $item['existence'] : false;
67
+ $this->_checkPath($item['path'], $recursive, $existence, 'write');
68
+ }
69
+ }
70
+
71
+ // php extensions
72
+ $config = Mage::getSingleton('install/config')->getExtensionsForCheck();
73
+ foreach ($config as $extension => $info) {
74
+ if (!empty($info) && is_array($info)) {
75
+ $this->_checkExtension($info);
76
+ }
77
+ else {
78
+ $this->_checkExtension($extension);
79
+ }
80
+ }
81
+ }
82
+
83
+ public function getRecommendations() {
84
+ return 'Cant write file to the var folder. Not enough rights or hard drive is full.';
85
+ }
86
+
87
+ protected function _checkExtension($extension)
88
+ {
89
+ if (is_array($extension)) {
90
+ $oneLoaded = false;
91
+ foreach ($extension as $item) {
92
+ if (extension_loaded($item)) {
93
+ $oneLoaded = true;
94
+ }
95
+ }
96
+
97
+ if (!$oneLoaded) {
98
+ $this->addWarning(
99
+ Mage::helper('heartbeat')->__('One of PHP Extensions "%s" must be loaded.', implode(',', $extension))
100
+ );
101
+ Mage::helper('heartbeat')->log(
102
+ Mage::helper('heartbeat')->__('One of PHP Extensions "%s" must be loaded.', implode(',', $extension)),
103
+ null,
104
+ $this->_warningLog
105
+ );
106
+ return false;
107
+ }
108
+ }
109
+ elseif (!extension_loaded($extension)) {
110
+ $this->addWarning(
111
+ Mage::helper('install')->__('PHP extension "%s" must be loaded.', $extension)
112
+ );
113
+ Mage::helper('heartbeat')->log(
114
+ Mage::helper('install')->__('PHP extension "%s" must be loaded.', $extension),
115
+ null,
116
+ $this->_warningLog
117
+ );
118
+ return false;
119
+ }
120
+ else {
121
+ //
122
+ }
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * Check file system path
128
+ *
129
+ * @param string $path
130
+ * @param bool $recursive
131
+ * @param bool $existence
132
+ * @param string $mode
133
+ * @return bool
134
+ */
135
+ protected function _checkPath($path, $recursive, $existence, $mode)
136
+ {
137
+ $res = true;
138
+ $fullPath = dirname(Mage::getRoot()) . $path;
139
+ if ($mode == self::MODE_WRITE) {
140
+ $setError = false;
141
+ if ($existence) {
142
+ if ((is_dir($fullPath) && !is_dir_writeable($fullPath)) || !is_writable($fullPath)) {
143
+ $setError = true;
144
+ }
145
+ }
146
+ else {
147
+ if (file_exists($fullPath) && !is_writable($fullPath)) {
148
+ $setError = true;
149
+ }
150
+ }
151
+
152
+ if ($setError) {
153
+ $this->addError(
154
+ Mage::helper('install')->__('Path "%s" must be writable.', $fullPath)
155
+ );
156
+ $res = false;
157
+ }
158
+ }
159
+
160
+ if ($recursive && is_dir($fullPath)) {
161
+ foreach (new DirectoryIterator($fullPath) as $file) {
162
+ if (!$file->isDot() && $file->getFilename() != '.svn' && $file->getFilename() != '.htaccess') {
163
+ $res = $res && $this->_checkPath($path . DS . $file->getFilename(), $recursive, $existence, $mode);
164
+ }
165
+ }
166
+ }
167
+ return $res;
168
+ }
169
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Flattable.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * flat table test model.
4
+ * @package
5
+ * @deprecated after 0.0.2
6
+ */
7
+ class Gorilla_Heartbeat_Model_Tests_Flattable
8
+ extends Mage_Core_Model_Abstract
9
+ implements Gorilla_Heartbeat_Model_TestsInterface
10
+ {
11
+ /**
12
+ * Returns true if test enabled
13
+ * @return boolean
14
+ * @deprecated after 0.0.2
15
+ */
16
+ public function isEnabled()
17
+ {
18
+ return false;
19
+ /* this test is deprecated */
20
+
21
+ /* if flat catalog is active */
22
+ if (Mage::getStoreConfig('catalog/frontend/flat_catalog_product')) {
23
+ return true;
24
+ }
25
+
26
+ return false;
27
+ }
28
+
29
+ /**
30
+ * Returns true if test passed
31
+ * @return boolean
32
+ * @deprecated after 0.0.2
33
+ */
34
+ public function isPassed()
35
+ {
36
+ $read = Mage::getSingleton('core/resource')->getConnection('core_read');
37
+ $flatTables = $read->query('SHOW TABLES LIKE "catalog_product_flat_%"')->fetchAll();
38
+
39
+ $flatProductIds = array();
40
+ foreach ($flatTables as $flatTable) {
41
+ $items = $read->query('SELECT `entity_id` FROM `' . array_pop($flatTable) . '`')->fetchAll();
42
+
43
+ foreach ($items as $item) {
44
+ $flatProductIds[$item['entity_id']] = $item['entity_id'];
45
+ }
46
+ }
47
+
48
+ $productsCountArray = $read->query("
49
+ SELECT COUNT(DISTINCT `cpe`.`entity_id`) FROM `catalog_product_entity` AS `cpe`, `catalog_product_entity_int` AS `cpei`, `eav_attribute` AS `ea`, `eav_entity_type` AS `eet`
50
+ WHERE `eet`.`entity_type_code` = 'catalog_product'
51
+ AND `eet`.`entity_type_id` = `ea`.`entity_type_id`
52
+ AND `ea`.`attribute_code` = 'status'
53
+ AND `cpei`.`attribute_id` = `ea`.`attribute_id`
54
+ AND `cpei`.`entity_id` = `cpe`.`entity_id`
55
+ AND `cpei`.`value` = '1'")
56
+ ->fetch();
57
+ $productsCount = array_pop($productsCountArray);
58
+
59
+ if ($productsCount == count($flatProductIds)) {
60
+ return true;
61
+ }
62
+
63
+ Mage::helper('heartbeat')->log('Flattable Test Error. Products count in catalog doesn\'t match products count in the flat table(s).', null, 'gorilla_heartbeat.log');
64
+ return false;
65
+ }
66
+
67
+ /**
68
+ * Returns result of the rest
69
+ * @return mixed
70
+ */
71
+ public function getResult()
72
+ {
73
+ return true;
74
+ }
75
+
76
+ public function getRecommendations() {
77
+ return 'Please try to make reindex.';
78
+ }
79
+
80
+ public function process(){}
81
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Index.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * index test model.
4
+ * @package
5
+ * @deprecated after 0.0.2
6
+ */
7
+ class Gorilla_Heartbeat_Model_Tests_Index
8
+ extends Mage_Core_Model_Abstract
9
+ implements Gorilla_Heartbeat_Model_TestsInterface
10
+ {
11
+ /**
12
+ * Returns true if test enabled
13
+ * @return boolean
14
+ * @deprecated after 0.0.2
15
+ */
16
+ public function isEnabled()
17
+ {
18
+ return false;
19
+ /* this test is deprecated */
20
+ }
21
+
22
+ /**
23
+ * Returns true if test passed
24
+ * @return boolean
25
+ * @deprecated after 0.0.2
26
+ */
27
+ public function isPassed()
28
+ {
29
+ $read = Mage::getSingleton('core/resource')->getConnection('core_read');
30
+ $indexes = $read->query("SELECT * FROM `index_process` WHERE `status` = 'require_reindex'")->fetch();
31
+
32
+ if (!$indexes) {
33
+ return true;
34
+ }
35
+
36
+ Mage::helper('heartbeat')->log('Index Test Error. Reindex required for one or mode indexes.', null, 'gorilla_heartbeat.log');
37
+ return false;
38
+ }
39
+
40
+ /**
41
+ * Returns result of the rest
42
+ * @return mixed
43
+ */
44
+ public function getResult()
45
+ {
46
+ return true;
47
+ }
48
+
49
+ public function getRecommendations() {
50
+ return 'Indexes are invalidated. Please try to make reindex.';
51
+ }
52
+
53
+ public function process(){}
54
+ }
app/code/local/Gorilla/Heartbeat/Model/Tests/Log.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Logs test model.
4
+ * @package
5
+ * @deprecated after 0.0.2
6
+ */
7
+ class Gorilla_Heartbeat_Model_Tests_Log
8
+ extends Mage_Core_Model_Abstract
9
+ implements Gorilla_Heartbeat_Model_TestsInterface
10
+ {
11
+ /**
12
+ * Returns true if test enabled
13
+ * @return boolean
14
+ * @deprecated after 0.0.2
15
+ */
16
+ public function isEnabled()
17
+ {
18
+ return false;
19
+ /* this test is deprecated */
20
+ }
21
+
22
+ /**
23
+ * Returns true if test passed
24
+ * @return boolean
25
+ * @deprecated after 0.0.2
26
+ */
27
+ public function isPassed()
28
+ {
29
+
30
+ $logFile = Mage::getStoreConfig('dev/log/exception_file');
31
+ $logDir = Mage::getBaseDir('var') . DS . 'log';
32
+ if (file_exists($logDir . DS . $logFile) && file_get_contents($logDir. DS .$logFile)) {
33
+ return false;
34
+ }
35
+
36
+ Mage::helper('heartbeat')->log('Log Test Error. Exception.log is not empty.', null, 'gorilla_heartbeat.log');
37
+ return true;
38
+ }
39
+
40
+ /**
41
+ * Returns result of the rest
42
+ * @return mixed
43
+ */
44
+ public function getResult()
45
+ {
46
+ return true;
47
+ }
48
+
49
+ public function getRecommendations() {
50
+ return 'You have exception log in your var/log folder.';
51
+ }
52
+
53
+ public function process(){}
54
+ }
app/code/local/Gorilla/Heartbeat/Model/TestsCollector.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Collector model.
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_Model_TestsCollector extends Mage_Core_Model_Abstract
7
+ {
8
+ private $_start_time;
9
+ private $_end_time;
10
+ protected $_testsConfigNode = 'global/tests';
11
+ protected $_tests = array();
12
+ protected $_availableTests = array();
13
+
14
+ private $_errors = array();
15
+ private $_warnings = array();
16
+
17
+ /**
18
+ * Returns directory with test models
19
+ * @return string
20
+ */
21
+ private function _getTestsDir()
22
+ {
23
+ return Mage::getConfig()->getModuleDir(null, 'Gorilla_Heartbeat') . DS . 'Model' . DS . 'Tests';
24
+ }
25
+
26
+ /**
27
+ * Collects test modeles
28
+ * @return Varien_Data_Collection
29
+ * @deprecated from 0.0.2
30
+ */
31
+ private function _getTestsCollection()
32
+ {
33
+ $handle = new Varien_Io_File();
34
+ $handle->cd($this->_getTestsDir());
35
+ $listOfFiles = $handle->ls('files_only');
36
+
37
+ $collection = new Varien_Data_Collection();
38
+ foreach ($listOfFiles as $file) {
39
+ try {
40
+ $modelName = strtolower(str_replace('.php', '', $file['text']));
41
+ $testModel = Mage::getModel('heartbeat/tests_' . $modelName);
42
+
43
+ if ($testModel->isEnabled()) {
44
+ $collection->addItem(
45
+ new Varien_Object(
46
+ array(
47
+ 'test_object' => $testModel,
48
+ )
49
+ )
50
+ );
51
+ }
52
+ } catch (Exception $e) {
53
+ Mage::helper('heartbeat')->log('Cant load test ' . $modelName . '(' . $e->getMessage() . ')', null, 'gorilla_heartbeat.log');
54
+ }
55
+ }
56
+
57
+ return $collection;
58
+ }
59
+
60
+ /**
61
+ * return true if all test passed
62
+ * @return boolean
63
+ */
64
+ public function isAllPassed()
65
+ {
66
+ $allPassed = true;
67
+ foreach ($this->getAvailableTests() as $testModel) {
68
+ if ($testModel->getResult() == Gorilla_Heartbeat_Model_Tests_Abstract::SEVERITY_ERROR) {
69
+ $allPassed = false;
70
+ break;
71
+ }
72
+ }
73
+ return $allPassed;
74
+ }
75
+
76
+ /**
77
+ * Process tests
78
+ * @return void
79
+ */
80
+ public function processTests()
81
+ {
82
+ /* reset errors */
83
+ $this->_errors = array();
84
+ $this->_warnings = array();
85
+
86
+ /* start timer */
87
+ $this->_start_time = $this->_getTime();
88
+
89
+ foreach ($this->getAvailableTests() as $testModel) {
90
+ $testModel->process();
91
+ }
92
+
93
+ /* end timer */
94
+ $this->_end_time = $this->_getTime();
95
+
96
+ /* process warnings */
97
+ $this->_processWarnings();
98
+ }
99
+
100
+ /**
101
+ * update warnings - only unique
102
+ */
103
+ private function _processWarnings()
104
+ {
105
+ $warnings = $this->getWarnings();
106
+ if (count($warnings)) {
107
+ try {
108
+ /** @var Mage_Core_Model_Resource $resource */
109
+ $resource = Mage::getModel('core/resource');
110
+ $connection = $resource->getConnection('core_write');
111
+ foreach ($warnings as $warning) {
112
+ $connection->insertOnDuplicate($resource->getTableName('heartbeat_warnings'), array('warning' => $warning), array('warning'));
113
+ }
114
+ } catch (Exception $e) {
115
+ //
116
+ }
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Return tests passing time
122
+ * @return float
123
+ */
124
+ public function getPassingTime()
125
+ {
126
+ return round($this->_end_time * 1000 - $this->_start_time * 1000, 3) >= 0? round($this->_end_time * 1000 - $this->_start_time * 1000, 3) : 0;
127
+ }
128
+
129
+ /**
130
+ * Return current time in seconds
131
+ * @return float
132
+ */
133
+ private function _getTime()
134
+ {
135
+ /* detect the time */
136
+ $timeNow = microtime();
137
+ /* separates seconds and milliseconds in array */
138
+ $arrayTime = explode(' ', $timeNow);
139
+ /* we put together seconds and milliseconds */
140
+ $timeReturn = floatval($arrayTime[1]) + floatval($arrayTime[0]);
141
+
142
+ return $timeReturn;
143
+ }
144
+
145
+ public function getErrors()
146
+ {
147
+ if (!$this->_errors) {
148
+ foreach ($this->getAvailableTests() as $testModel) {
149
+ if ($testModel->hasErrors()) {
150
+ $this->_errors = array_merge($this->_errors, $testModel->getErrors());
151
+ }
152
+ }
153
+ }
154
+ return $this->_errors;
155
+ }
156
+
157
+ public function getWarnings()
158
+ {
159
+ if (!$this->_warnings) {
160
+ foreach ($this->getAvailableTests() as $testModel) {
161
+ if ($testModel->hasWarnings()) {
162
+ $this->_warnings = array_merge($this->_warnings, $testModel->getWarnings());
163
+ }
164
+ }
165
+ }
166
+ return $this->_warnings;
167
+ }
168
+
169
+ /**
170
+ * Return all test entries from config file
171
+ * Array has structure
172
+ * 'code' => ('class' => string $class, 'label' => string $label)
173
+ *
174
+ * @return array
175
+ */
176
+ public function getAllTests()
177
+ {
178
+ if (empty($this->_tests)) {
179
+ $testsConfig = Mage::getConfig()->getNode($this->_testsConfigNode);
180
+
181
+ foreach ($testsConfig->children() as $testCode => $testConfig) {
182
+ $class = $testConfig->getClassName();
183
+ if (!empty($class)) {
184
+ $this->_tests[$testCode] = array('class' => $class, 'label' => (string) $testConfig->label);
185
+ }
186
+ }
187
+ }
188
+ return $this->_tests;
189
+ }
190
+
191
+ /**
192
+ * Return available test models
193
+ * Array has structure
194
+ * 'code' => ('model' => Gorilla_Heartbeat_Model_Tests_Abstract $model)
195
+ *
196
+ * @return array
197
+ */
198
+ public function getAvailableTests()
199
+ {
200
+ $enabledTests = Mage::getStoreConfig('heartbeat/general/tests');
201
+ $enabledTests = explode(',', $enabledTests);
202
+ if (empty($this->_availableTests)) {
203
+ $tests = $this->getAllTests();
204
+ foreach ($tests as $code => $data) {
205
+ if (!in_array($code, $enabledTests)) {
206
+ continue;
207
+ }
208
+ $this->_availableTests[$code] = Mage::getModel($data['class'])->setLabel($data['label']);
209
+ }
210
+ }
211
+ return $this->_availableTests;
212
+ }
213
+ }
app/code/local/Gorilla/Heartbeat/Model/TestsInterface.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ interface Gorilla_Heartbeat_Model_TestsInterface
3
+ {
4
+ /**
5
+ * Main test process
6
+ * @return void
7
+ */
8
+ public function process();
9
+
10
+ /**
11
+ * Must return result of the test
12
+ * @return mixed
13
+ */
14
+ public function getResult();
15
+
16
+ /**
17
+ * Must return recommendations how to fix issues
18
+ * @return string
19
+ */
20
+ public function getRecommendations();
21
+ }
app/code/local/Gorilla/Heartbeat/controllers/IndexController.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Index controller
4
+ * @package
5
+ */
6
+ class Gorilla_Heartbeat_IndexController extends Mage_Core_Controller_Front_Action
7
+ {
8
+ const CODE_SUCCESS = 'OK';
9
+ const CODE_ERROR = 'ERROR';
10
+
11
+ protected $_collector;
12
+
13
+ /**
14
+ * Index action.
15
+ * Checks if all tests is passes. Returns response code in heders 200 if OK of 500 if something is wrong.
16
+ * Alse returns XML statistics in headers for pingdom in format
17
+ * <pingdom_http_custom_check>
18
+ * <status>CODE</status>
19
+ * <response_time>TIME</response_time>
20
+ * </pingdom_http_custom_check>
21
+ */
22
+ public function indexAction()
23
+ {
24
+ if (!Mage::getStoreConfig('heartbeat/general/enable')) {
25
+ $this->_redirect('/');
26
+ return;
27
+ }
28
+ $this->_getCollector()->processTests();
29
+ $code = 500;
30
+ $textCode = self::CODE_ERROR;
31
+ if ($this->_getCollector()->isAllPassed()) {
32
+ $code = 200;
33
+ $textCode = self::CODE_SUCCESS;
34
+ }
35
+
36
+ $errors = $this->_getCollector()->getErrors();
37
+ $errorCodes = '';
38
+ if (count($errors)) {
39
+ $errorCodes = '<errors>';
40
+ foreach ($errors as $error) {
41
+ $errorCodes .= '<error>' . $error . '</error>';
42
+ }
43
+ $errorCodes .='</errors>';
44
+ }
45
+
46
+ $warnings = $this->_getCollector()->getWarnings();
47
+ $warningCodes = '';
48
+ if (count($warnings)) {
49
+ $warningCodes = '<warnings>';
50
+ foreach ($warnings as $warning) {
51
+ $warningCodes .= '<warning>' . $warning . '</warning>';
52
+ }
53
+ $warningCodes .='</warnings>';
54
+ }
55
+
56
+ $time = $this->_getCollector()->getPassingTime();
57
+
58
+ $this->getResponse()
59
+ ->setHttpResponseCode($code)
60
+ ->setHeader('Content-type', 'application/xml', true)
61
+ ->setBody('<?xml version="1.0" encoding="UTF-8" ?><pingdom_http_custom_check><status>' . $textCode . '</status><response_time>' . $time . '</response_time>' . $errorCodes . $warningCodes . '</pingdom_http_custom_check>')
62
+ ;
63
+ }
64
+
65
+
66
+ /**
67
+ * @return Gorilla_Heartbeat_Model_TestsCollector
68
+ */
69
+ protected function _getCollector()
70
+ {
71
+ if (!$this->_collector) {
72
+ $this->_collector = Mage::getSingleton('heartbeat/testsCollector');
73
+ }
74
+ return $this->_collector;
75
+ }
76
+
77
+ // public function testAction()
78
+ // {
79
+ // $observer = new Gorilla_Heartbeat_Model_Observer();
80
+ // print_r($observer->processMailQueue());
81
+ // }
82
+ }
app/code/local/Gorilla/Heartbeat/etc/adminhtml.xml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+
4
+ <menu>
5
+ <gorilla module="heartbeat">
6
+ <title>Gorilla InStore</title>
7
+ <sort_order>999</sort_order>
8
+ <children>
9
+ <heartbeat module="heartbeat">
10
+ <title>Heart Beat (Pingdom Integration)</title>
11
+ <sort_order>0</sort_order>
12
+ <children>
13
+ <configuration module="adminhtml">
14
+ <title>Configuration</title>
15
+ <sort_order>1</sort_order>
16
+ <action>adminhtml/system_config/edit/section/heartbeat</action>
17
+ </configuration>
18
+ </children>
19
+ </heartbeat>
20
+ </children>
21
+ </gorilla>
22
+ </menu>
23
+ <acl>
24
+ <resources>
25
+ <all>
26
+ <title>Allow Everything</title>
27
+ </all>
28
+ <admin>
29
+ <children>
30
+ <Gorilla_Heartbeat>
31
+ <title>Gorilla InStore - Heart Beat (Pingdom Integration) - Module</title>
32
+ <sort_order>10</sort_order>
33
+ </Gorilla_Heartbeat>
34
+ <system>
35
+ <children>
36
+ <config>
37
+ <children>
38
+ <heartbeat>
39
+ <title>Gorilla InStore - Heart Beat (Pingdom Integration) - Config</title>
40
+ </heartbeat>
41
+ </children>
42
+ </config>
43
+ </children>
44
+ </system>
45
+ </children>
46
+ </admin>
47
+ </resources>
48
+ </acl>
49
+ </config>
app/code/local/Gorilla/Heartbeat/etc/config.xml ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Gorilla_Heartbeat>
5
+ <version>0.0.2</version>
6
+ </Gorilla_Heartbeat>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <heartbeat>
11
+ <class>Gorilla_Heartbeat_Model</class>
12
+ </heartbeat>
13
+ </models>
14
+ <helpers>
15
+ <heartbeat>
16
+ <class>Gorilla_Heartbeat_Helper</class>
17
+ </heartbeat>
18
+ </helpers>
19
+ <resources>
20
+ <heartbeat_setup>
21
+ <setup>
22
+ <module>Gorilla_Heartbeat</module>
23
+ <class>Mage_Core_Model_Resource_Setup</class>
24
+ </setup>
25
+ </heartbeat_setup>
26
+ </resources>
27
+ <tests>
28
+ <api>
29
+ <class>heartbeat/tests_api</class>
30
+ <label>Api</label>
31
+ </api>
32
+ <catalog>
33
+ <class>heartbeat/tests_catalog</class>
34
+ <label>Catalog</label>
35
+ </catalog>
36
+ <filesystem>
37
+ <class>heartbeat/tests_filesystem</class>
38
+ <label>Filesystem</label>
39
+ </filesystem>
40
+ </tests>
41
+ <template>
42
+ <email>
43
+ <heartbeat_warning_email_template translate="label" module="heartbeat">
44
+ <label>Warning Template</label>
45
+ <file>heartbeat_warnings.html</file>
46
+ <type>html</type>
47
+ </heartbeat_warning_email_template>
48
+ </email>
49
+ </template>
50
+ </global>
51
+ <frontend>
52
+ <routers>
53
+ <heartbeat>
54
+ <use>standard</use>
55
+ <args>
56
+ <module>Gorilla_Heartbeat</module>
57
+ <frontName>heartbeat</frontName>
58
+ </args>
59
+ </heartbeat>
60
+ </routers>
61
+ </frontend>
62
+ <default>
63
+ <heartbeat>
64
+ <general>
65
+ <enable>1</enable>
66
+ <tests>api,catalog,filesystem</tests>
67
+ <email_schedule>4</email_schedule>
68
+ </general>
69
+ </heartbeat>
70
+ </default>
71
+ <crontab>
72
+ <jobs>
73
+ <heartbeat_send_warnings>
74
+ <schedule>
75
+ <cron_expr>1 * * * *</cron_expr>
76
+ </schedule>
77
+ <run>
78
+ <model>heartbeat/observer::processMailQueue</model>
79
+ </run>
80
+ </heartbeat_send_warnings>
81
+ </jobs>
82
+ </crontab>
83
+ </config>
app/code/local/Gorilla/Heartbeat/etc/system.xml ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <config>
4
+ <tabs>
5
+ <gorilla translate="label" module="heartbeat">
6
+ <label>Gorilla InStore</label>
7
+ <sort_order>100</sort_order>
8
+ </gorilla>
9
+ </tabs>
10
+ <sections>
11
+ <heartbeat translate="label" module="heartbeat">
12
+ <label>Heart Beat (Pingdom Integration)</label>
13
+ <tab>gorilla</tab>
14
+ <frontend_type>text</frontend_type>
15
+ <sort_order>30</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <groups>
20
+ <general translate="label">
21
+ <label>General</label>
22
+ <frontend_type>text</frontend_type>
23
+ <sort_order>1</sort_order>
24
+ <show_in_default>1</show_in_default>
25
+ <show_in_website>1</show_in_website>
26
+ <show_in_store>1</show_in_store>
27
+ <fields>
28
+ <enable translate="label">
29
+ <label>Enable module</label>
30
+ <frontend_type>select</frontend_type>
31
+ <sort_order>1</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ <source_model>adminhtml/system_config_source_yesno</source_model>
36
+ </enable>
37
+ <tests translate="label">
38
+ <label>Enabled Test Types</label>
39
+ <frontend_type>multiselect</frontend_type>
40
+ <sort_order>2</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ <source_model>heartbeat/system_config_source_tests</source_model>
45
+ <can_be_empty>1</can_be_empty>
46
+ </tests>
47
+ <email translate="label">
48
+ <label>Warning Email Receiver</label>
49
+ <frontend_type>text</frontend_type>
50
+ <sort_order>3</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>1</show_in_website>
53
+ <show_in_store>1</show_in_store>
54
+ </email>
55
+ <email_schedule translate="label">
56
+ <label>Warning Email Frequency</label>
57
+ <frontend_type>select</frontend_type>
58
+ <sort_order>4</sort_order>
59
+ <show_in_default>1</show_in_default>
60
+ <show_in_website>1</show_in_website>
61
+ <show_in_store>1</show_in_store>
62
+ <source_model>heartbeat/system_config_source_Schedule</source_model>
63
+ </email_schedule>
64
+ </fields>
65
+ </general>
66
+ </groups>
67
+ </heartbeat>
68
+ </sections>
69
+ </config>
app/code/local/Gorilla/Heartbeat/sql/heartbeat_setup/mysql4-install-0.0.2.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Mage_Core_Model_Resource_Setup $installer */
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+ $installer->run("
6
+ CREATE TABLE {$installer->getTable('heartbeat_warnings')} (
7
+ `warning_id` int(11) NOT NULL auto_increment,
8
+ `warning` varchar(255) NOT NULL,
9
+ PRIMARY KEY (warning_id),
10
+ UNIQUE (warning)
11
+ ) ENGINE=InnoDb DEFAULT CHARSET=utf8;
12
+ ");
13
+ $installer->endSetup();
app/etc/modules/Gorilla_Heartbeat.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <modules>
3
+ <Gorilla_Heartbeat>
4
+ <active>true</active>
5
+ <codePool>local</codePool>
6
+ </Gorilla_Heartbeat>
7
+ </modules>
8
+ </config>
app/locale/en_US/template/email/heartbeat_warnings.html ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <!--@subject Heartbeat Warnings @-->
2
+ <!--@vars
3
+ {"var warnings":"Warnings"}
4
+ @-->
5
+ Heartbeat Warnings:
6
+
7
+ {{var warnings}}
package.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>heartbeat_extension_for_magento</name>
4
+ <version>0.0.5</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://instore.gorillagroup.com/license-agreement">Gorilla License</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>The HeartBeat module is designed to provide in-depth monitoring for your Magento site. There are two ways to monitor the status of your site &#x2013; via an XML report or through Pingdom.</summary>
10
+ <description>The HeartBeat module is designed to provide in-depth monitoring for your Magento site. There are two ways to monitor the status of your site &#x2013; via an XML report or through Pingdom.&#xD;
11
+ Pingdom is monitoring service that tracks all website &amp;amp; server vitals in one convenient monitoring platform. It helps you spot performance trends, share data with others, and helps with issue resolution. Pingdom also sends users real-time updates via email, SMS (texts), Twitter, or mobile notification via iOS or Android devices.&#xD;
12
+ &#xD;
13
+ The HeartBeat module monitors seven components that are vital for site functionality and performance of any Magento website. These tests include: API availability, database, flat table, logs, catalog, file system, and indexes.</description>
14
+ <notes>Reworked tests structure,&#xD;
15
+ Error management,&#xD;
16
+ Add email notification feature,&#xD;
17
+ Remove deprecated tests</notes>
18
+ <authors><author><name>Gorilla Team</name><user>briangrady</user><email>grady@gorillagroup.com</email></author></authors>
19
+ <date>2012-10-15</date>
20
+ <time>10:53:25</time>
21
+ <contents><target name="magelocal"><dir name="Gorilla"><dir name="Heartbeat"><dir name="Helper"><file name="Data.php" hash="e90a9d9d93dcbed32c7ab6b50ffceb03"/></dir><dir name="Model"><file name="Observer.php" hash="b12b640b75bdaea342f9bfb0e4ea9b86"/><dir name="System"><dir name="Config"><dir name="Source"><file name="Schedule.php" hash="836c6dc6336bab755cc4ea1d28ad99a6"/><file name="Tests.php" hash="d5d6f576c9363e216bd2d7b9b84f988e"/></dir></dir></dir><dir name="Tests"><file name="Abstract.php" hash="3f2adb51043309db16913cf6974c0e43"/><file name="Api.php" hash="b5e05ceba40b4f11ae7a205718d0efce"/><file name="Catalog.php" hash="2bf00561c40928511288b34e32d5f958"/><file name="Database.php" hash="c3a80636fa827751dd1904dcf3bc9c83"/><file name="Filesystem.php" hash="e24bdf8e8bebd7c9c2fcae75d79bd5ec"/><file name="Flattable.php" hash="4135860b36e7a430eafeb2c515f35bb6"/><file name="Index.php" hash="41eda1da4d293487bf0becb33a248b0f"/><file name="Log.php" hash="c49403fa2505a6aaaa62c40f74686187"/></dir><file name="TestsCollector.php" hash="0733f25ae16643a39145910f8ee8a63a"/><file name="TestsInterface.php" hash="68b9b24f2b85732d6e0769ba11ffae2c"/></dir><dir name="controllers"><file name="IndexController.php" hash="3be2670585b1490d9443ce2e61f5d7b9"/></dir><dir name="etc"><file name="adminhtml.xml" hash="818551d3d7ba1962d837eff1f85f0203"/><file name="config.xml" hash="00e6de371238530deb346b46a5fba22d"/><file name="system.xml" hash="72a254f644686b8d888bbc09a69056bf"/></dir><dir name="sql"><dir name="heartbeat_setup"><file name="mysql4-install-0.0.2.php" hash="d4dc069f68c14c3ac78db35ad916f5f3"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Gorilla_Heartbeat.xml" hash="73424503c8a3a95a747570ac3e05b4cb"/></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><file name="heartbeat_warnings.html" hash="50668b0f4a86bf4dc56e62f8b58dbe9f"/></dir></dir></dir></target></contents>
22
+ <compatible/>
23
+ <dependencies><required><php><min>5.0.0</min><max>5.4.3</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.0</min><max>1.7.0</max></package></required></dependencies>
24
+ </package>