Version Notes
02.29.2013 - Extension release (Compatibility: CE 1.4.х-1.7.0.2)
Download this release
Release Info
Developer | Aitoc |
Extension | ServerLoadMonitorFree |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- License agreement Server Load Monitor.pdf +0 -0
- Server Load Monitor Manual.pdf +0 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitlink.php +22 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon.php +60 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/BarGraph.php +166 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/Filter.php +150 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/LineGraph.php +204 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Calculator.php +59 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/CalculatorResult.php +44 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Indicator.php +38 -0
- app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Manage.php +133 -0
- app/code/local/Aitoc/Aitloadmon/Helper/Data.php +67 -0
- app/code/local/Aitoc/Aitloadmon/Model/Aitloadmon.php +34 -0
- app/code/local/Aitoc/Aitloadmon/Model/Analytics.php +32 -0
- app/code/local/Aitoc/Aitloadmon/Model/Calculator.php +129 -0
- app/code/local/Aitoc/Aitloadmon/Model/Calculator/Abstract.php +90 -0
- app/code/local/Aitoc/Aitloadmon/Model/Calculator/Hardware.php +69 -0
- app/code/local/Aitoc/Aitloadmon/Model/Calculator/Magento.php +142 -0
- app/code/local/Aitoc/Aitloadmon/Model/Calculator/Software.php +104 -0
- app/code/local/Aitoc/Aitloadmon/Model/CompressSource.php +56 -0
- app/code/local/Aitoc/Aitloadmon/Model/Dblog.php +16 -0
- app/code/local/Aitoc/Aitloadmon/Model/LevelSource.php +66 -0
- app/code/local/Aitoc/Aitloadmon/Model/Manage.php +31 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon.php +170 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon/Collection.php +67 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator.php +25 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator/Collection.php +15 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog.php +17 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog/Collection.php +15 -0
- app/code/local/Aitoc/Aitloadmon/Model/Mysql4/UrlRewrite.php +64 -0
- app/code/local/Aitoc/Aitloadmon/Model/Observer.php +48 -0
- app/code/local/Aitoc/Aitloadmon/Model/Process.php +309 -0
- app/code/local/Aitoc/Aitloadmon/Model/Router.php +162 -0
- app/code/local/Aitoc/Aitloadmon/Model/SysInfo.php +12 -0
- app/code/local/Aitoc/Aitloadmon/Model/System.php +12 -0
- app/code/local/Aitoc/Aitloadmon/Model/System/Abstract.php +33 -0
- app/code/local/Aitoc/Aitloadmon/Model/UrlRewrite.php +25 -0
- app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/AitloadmonController.php +108 -0
- app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/CalculatorController.php +42 -0
- app/code/local/Aitoc/Aitloadmon/etc/adminhtml.xml +44 -0
- app/code/local/Aitoc/Aitloadmon/etc/config.xml +112 -0
- app/code/local/Aitoc/Aitloadmon/etc/system.xml +67 -0
- app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-install-1.0.0.php +49 -0
- app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-uninstall-1.0.0.php +21 -0
- app/code/local/Aitoc/Aitsys/install/Aitoc_Aitloadmon.phtml +112 -0
- app/design/adminhtml/default/default/layout/aitloadmon.xml +50 -0
- app/design/adminhtml/default/default/template/aitloadmon/back.phtml +8 -0
- app/design/adminhtml/default/default/template/aitloadmon/bar.phtml +30 -0
- app/design/adminhtml/default/default/template/aitloadmon/graph.phtml +28 -0
- app/design/adminhtml/default/default/template/aitloadmon/indicator.phtml +12 -0
- app/design/adminhtml/default/default/template/aitloadmon/line.phtml +115 -0
- app/design/adminhtml/default/default/template/aitloadmon/quick.phtml +28 -0
- app/design/adminhtml/default/default/template/aitloadmon/sysInfo.phtml +11 -0
- app/design/adminhtml/default/default/template/aitloadmon/system.phtml +11 -0
- app/etc/modules/Aitoc_Aitloadmon.xml +16 -0
- js/aitoc/aitloadmon/grafico.bar.custom.js +204 -0
- js/aitoc/aitloadmon/grafico.line.custom.js +138 -0
- js/aitoc/aitloadmon/grafico.min.js +80 -0
- js/aitoc/aitloadmon/raphael-min.js +7 -0
- lib/Aitoc/Aitloadmon/Adapter/Apc.php +56 -0
- lib/Aitoc/Aitloadmon/Adapter/File.php +116 -0
- lib/Aitoc/Aitloadmon/Adapter/Memcached.php +66 -0
- lib/Aitoc/Aitloadmon/Collect.php +266 -0
- package.xml +37 -0
- readme.txt +34 -0
License agreement Server Load Monitor.pdf
ADDED
Binary file
|
Server Load Monitor Manual.pdf
ADDED
Binary file
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitlink.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Aitlink extends Mage_Adminhtml_Block_System_Config_Form_Field
|
7 |
+
{
|
8 |
+
protected function _getElementHtml (Varien_Data_Form_Element_Abstract $element)
|
9 |
+
{
|
10 |
+
$buttonBlock = $element->getForm()->getParent()->getLayout()->createBlock('adminhtml/widget_button');
|
11 |
+
|
12 |
+
$data = array(
|
13 |
+
'label' => Mage::helper('adminhtml')->__('Manage'),
|
14 |
+
'onclick' => 'setLocation(\''.Mage::helper('adminhtml')->getUrl("adminhtml/aitloadmon/manage").'\' )',
|
15 |
+
'class' => '',
|
16 |
+
);
|
17 |
+
|
18 |
+
$html = $buttonBlock->setData($data)->toHtml();
|
19 |
+
|
20 |
+
return $html;
|
21 |
+
}
|
22 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon extends Mage_Adminhtml_Block_Template
|
7 |
+
{
|
8 |
+
|
9 |
+
protected $_collection;
|
10 |
+
protected $_compareCollection;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Returns a collection of data for main graphics
|
14 |
+
*
|
15 |
+
* @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
|
16 |
+
*/
|
17 |
+
public function getCollection()
|
18 |
+
{
|
19 |
+
if(!isset($this->_collection))
|
20 |
+
{
|
21 |
+
$this->_collection = Mage::getModel('aitloadmon/aitloadmon')->getCollectionByDates($this->getData('start_date'),$this->getData('end_date'));
|
22 |
+
}
|
23 |
+
return $this->_collection;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Returns a collection of data for compare graphics
|
28 |
+
*
|
29 |
+
* @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
|
30 |
+
*/
|
31 |
+
public function getCompareCollection()
|
32 |
+
{
|
33 |
+
if(!isset($this->_compareCollection))
|
34 |
+
{
|
35 |
+
$this->_compareCollection = Mage::getModel('aitloadmon/aitloadmon')->getCollectionByDates($this->getData('start_date_compare'),$this->getData('end_date_compare'));
|
36 |
+
}
|
37 |
+
return $this->_compareCollection;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Checks if there is enough data in collection to build graphics (more then 2 dots)
|
42 |
+
*
|
43 |
+
* @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
|
44 |
+
* @return bool
|
45 |
+
*/
|
46 |
+
public function isEnoughDataToBuildGraph($collection)
|
47 |
+
{
|
48 |
+
$data = array();
|
49 |
+
foreach($collection as $item)
|
50 |
+
{
|
51 |
+
$data[$item->getMeasureTime()] = 1;
|
52 |
+
if(count($data)>2)
|
53 |
+
{
|
54 |
+
return true;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
return false;
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/BarGraph.php
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_BarGraph extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Gets collection(s) from parent block and processes data for javascript graphics
|
10 |
+
*/
|
11 |
+
protected function _beforeToHtml()
|
12 |
+
{
|
13 |
+
$collection = $this->getParentBlock()->getCollection();
|
14 |
+
if($this->getCompare())
|
15 |
+
{
|
16 |
+
$collectionCompare = $this->getParentBlock()->getCompareCollection();
|
17 |
+
}
|
18 |
+
|
19 |
+
$barData = $this->_preProcessDataForBar($collection);
|
20 |
+
$barDataCompare = null;
|
21 |
+
if($this->getCompare())
|
22 |
+
{
|
23 |
+
$barDataCompare = $this->_preProcessDataForBar($collectionCompare);
|
24 |
+
}
|
25 |
+
$this->_processDataForBar($barData,$barDataCompare);
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Returns whether the compare mode is enabled
|
30 |
+
*
|
31 |
+
* @return bool
|
32 |
+
*/
|
33 |
+
public function getCompare()
|
34 |
+
{
|
35 |
+
return $this->getParentBlock()->getCompare();
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Pre-processes data for further data processing
|
40 |
+
*
|
41 |
+
* @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
|
42 |
+
* @param bool $dataForCompare [false]
|
43 |
+
* @return array
|
44 |
+
*/
|
45 |
+
private function _preProcessDataForBar($collection, $dataForCompare = false)
|
46 |
+
{
|
47 |
+
$data = array();
|
48 |
+
$totalPageViews = 0;
|
49 |
+
$maxLoad = 0;
|
50 |
+
$maxLoadTime = 0;
|
51 |
+
$totalPageViewsByGroup = array();
|
52 |
+
|
53 |
+
foreach($collection as $item)
|
54 |
+
{
|
55 |
+
$pageGroupId = $item->getData('page_group_id');
|
56 |
+
if(!isset($totalPageViewsByGroup[$pageGroupId]))
|
57 |
+
{
|
58 |
+
$totalPageViewsByGroup[$pageGroupId]=0;
|
59 |
+
}
|
60 |
+
$totalPageViewsByGroup[$pageGroupId] += $item->getPageViews();
|
61 |
+
$totalPageViews +=$item->getPageViews();
|
62 |
+
if($item->getLoadTimeMax()>$maxLoad)
|
63 |
+
{
|
64 |
+
$maxLoad = $item->getLoadTimeMax();
|
65 |
+
$maxLoadTime = $item->getMeasureTime();
|
66 |
+
}
|
67 |
+
}
|
68 |
+
if(!$dataForCompare)
|
69 |
+
{
|
70 |
+
$this->getParentBlock()->setTotalPageViews($totalPageViews);
|
71 |
+
$this->getParentBlock()->setMaxLoad($maxLoad);
|
72 |
+
$this->getParentBlock()->setMaxLoadTime($maxLoadTime);
|
73 |
+
}
|
74 |
+
|
75 |
+
foreach($collection as $item)
|
76 |
+
{
|
77 |
+
$pageGroupId = $item->getData('page_group_id');
|
78 |
+
if(!isset($data[$pageGroupId]))
|
79 |
+
{
|
80 |
+
$data[$pageGroupId] = array('avg'=>0,'max'=>0);
|
81 |
+
}
|
82 |
+
if($item->getLoadTimeMax()>$data[$pageGroupId]['max'])
|
83 |
+
{
|
84 |
+
$data[$pageGroupId]['max'] = $item->getLoadTimeMax();
|
85 |
+
}
|
86 |
+
$data[$pageGroupId]['avg'] += $item->getLoadTimeAvg() * $item->getPageViews()/$totalPageViewsByGroup[$pageGroupId];
|
87 |
+
|
88 |
+
}
|
89 |
+
return $data;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Processes data and stores it as this object property
|
94 |
+
*
|
95 |
+
* @param array $data
|
96 |
+
* @param bool $dataCompare
|
97 |
+
*/
|
98 |
+
private function _processDataForBar($data, $dataCompare)
|
99 |
+
{
|
100 |
+
$loadAvg = 'avg_load: [';
|
101 |
+
$loadMax = 'max_load: [';
|
102 |
+
$groups = Mage::helper('aitloadmon')->getGroupsArray();
|
103 |
+
$gcnt = 0;
|
104 |
+
foreach($groups as $pageGroupId)
|
105 |
+
{
|
106 |
+
if(!isset($data[$pageGroupId]))
|
107 |
+
{
|
108 |
+
$loadAvg .= '0';
|
109 |
+
$loadMax .= '0';
|
110 |
+
}
|
111 |
+
else
|
112 |
+
{
|
113 |
+
$loadAvg .= $data[$pageGroupId]['avg'];
|
114 |
+
$loadMax .= $data[$pageGroupId]['max'];
|
115 |
+
}
|
116 |
+
|
117 |
+
if($dataCompare)
|
118 |
+
{
|
119 |
+
if(!isset($dataCompare[$pageGroupId]))
|
120 |
+
{
|
121 |
+
$loadAvg .= ',0';
|
122 |
+
$loadMax .= ',0';
|
123 |
+
}
|
124 |
+
else
|
125 |
+
{
|
126 |
+
$loadAvg .= ','.$dataCompare[$pageGroupId]['avg'];
|
127 |
+
$loadMax .= ','.$dataCompare[$pageGroupId]['max'];
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
$gcnt++;
|
132 |
+
if($gcnt != count($groups))
|
133 |
+
{
|
134 |
+
$loadAvg .= ',';
|
135 |
+
$loadMax .= ',';
|
136 |
+
}
|
137 |
+
}
|
138 |
+
$loadAvg .= ']';
|
139 |
+
$loadMax .= ']';
|
140 |
+
|
141 |
+
$this->setBarGraphData($loadMax.','.$loadAvg);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Returns a JS array of labels
|
146 |
+
*
|
147 |
+
* @param bool $compareMode
|
148 |
+
* @return string
|
149 |
+
*/
|
150 |
+
public function getBarLabels($compareMode)
|
151 |
+
{
|
152 |
+
|
153 |
+
$groups = array_keys(Mage::helper('aitloadmon')->getGroupsArray());
|
154 |
+
if($compareMode)
|
155 |
+
{
|
156 |
+
$glue = '\',\'\',\'';
|
157 |
+
}
|
158 |
+
else
|
159 |
+
{
|
160 |
+
$glue = '\',\'';
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
return '[\''.implode($glue, $groups).($compareMode?'\',\'':'').'\']';
|
165 |
+
}
|
166 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/Filter.php
ADDED
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_Filter extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Preparing needed data for form
|
10 |
+
*/
|
11 |
+
private function _prepareData()
|
12 |
+
{
|
13 |
+
$collection = $this->getParentBlock()->getCollection();
|
14 |
+
|
15 |
+
$totalPageViews = 0;
|
16 |
+
$maxLoad = 0;
|
17 |
+
$maxLoadTime = 0;
|
18 |
+
|
19 |
+
foreach($collection as $item)
|
20 |
+
{
|
21 |
+
$totalPageViews +=$item->getPageViews();
|
22 |
+
if($item->getLoadTimeMax()>$maxLoad)
|
23 |
+
{
|
24 |
+
$maxLoad = $item->getLoadTimeMax();
|
25 |
+
$maxLoadTime = $item->getMeasureTime();
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
$this->setTotalPageViews($totalPageViews);
|
30 |
+
$this->setMaxLoad($maxLoad);
|
31 |
+
$this->setMaxLoadTime($maxLoadTime);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Preparing form
|
36 |
+
*
|
37 |
+
* @return Mage_Adminhtml_Block_Widget_Form
|
38 |
+
*/
|
39 |
+
protected function _prepareForm()
|
40 |
+
{
|
41 |
+
$this->_prepareData();
|
42 |
+
|
43 |
+
$form = new Varien_Data_Form(array(
|
44 |
+
'id' => 'edit_form',
|
45 |
+
'action' => $this->getUrl('*/*/index'),
|
46 |
+
'method' => 'post',
|
47 |
+
)
|
48 |
+
);
|
49 |
+
$fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Custom Filter Options')));
|
50 |
+
|
51 |
+
$fieldset->addField('starts', 'date', array(
|
52 |
+
'name' => 'startDate',
|
53 |
+
'title' => Mage::helper('aitloadmon')->__('Start Date'),
|
54 |
+
'label' => Mage::helper('aitloadmon')->__('Start Date'),
|
55 |
+
'image' => $this->getSkinUrl('images/grid-cal.gif'),
|
56 |
+
'format' => 'yyyy-MM-dd HH:mm:ss',
|
57 |
+
'value' => $this->getParentBlock()->getStartDate(),
|
58 |
+
'time' => true,
|
59 |
+
'required' => true,
|
60 |
+
));
|
61 |
+
|
62 |
+
$fieldset->addField('ends', 'date', array(
|
63 |
+
'name' => 'endDate',
|
64 |
+
'title' => Mage::helper('aitloadmon')->__('End Date'),
|
65 |
+
'label' => Mage::helper('aitloadmon')->__('End Date'),
|
66 |
+
'image' => $this->getSkinUrl('images/grid-cal.gif'),
|
67 |
+
'format' => 'yyyy-MM-dd HH:mm:ss',
|
68 |
+
'value' => $this->getParentBlock()->getEndDate(),
|
69 |
+
'time' => true,
|
70 |
+
'required' => true,
|
71 |
+
));
|
72 |
+
|
73 |
+
|
74 |
+
$fieldset->addField('type','select',array(
|
75 |
+
'title' => Mage::helper('aitloadmon')->__('Graph displays:'),
|
76 |
+
'label' => Mage::helper('aitloadmon')->__('Graph displays:'),
|
77 |
+
'name' => 'type',
|
78 |
+
'options' => array(
|
79 |
+
'max' => Mage::helper('aitloadmon')->__('Maximum load'),
|
80 |
+
'avg' => Mage::helper('aitloadmon')->__('Average load'),
|
81 |
+
),
|
82 |
+
'value' => $this->getParentBlock()->getType(),
|
83 |
+
));
|
84 |
+
|
85 |
+
|
86 |
+
$compare = $fieldset->addField('compare','select',array(
|
87 |
+
'title' => Mage::helper('aitloadmon')->__('Compare with the same period'),
|
88 |
+
'label' => Mage::helper('aitloadmon')->__('Compare with the same period'),
|
89 |
+
'name' => 'compare',
|
90 |
+
'options' => array(
|
91 |
+
0 => Mage::helper('aitloadmon')->__('No'),
|
92 |
+
1 => Mage::helper('aitloadmon')->__('Yes'),
|
93 |
+
),
|
94 |
+
'value' => $this->getParentBlock()->getCompare(),
|
95 |
+
));
|
96 |
+
|
97 |
+
$compareDate = $fieldset->addField('starts_compare', 'date', array(
|
98 |
+
'name' => 'startDateCompare',
|
99 |
+
'title' => Mage::helper('aitloadmon')->__('From Date'),
|
100 |
+
'label' => Mage::helper('aitloadmon')->__('From Date'),
|
101 |
+
'image' => $this->getSkinUrl('images/grid-cal.gif'),
|
102 |
+
'format' => 'yyyy-MM-dd HH:mm:ss',
|
103 |
+
'value' => $this->getParentBlock()->getStartDateCompare(),
|
104 |
+
'time' => true,
|
105 |
+
));
|
106 |
+
|
107 |
+
|
108 |
+
$fieldset->addField('submit1', 'submit', array(
|
109 |
+
'name' => 'submit1',
|
110 |
+
'title' => Mage::helper('aitloadmon')->__('Filter'),
|
111 |
+
'value' => Mage::helper('aitloadmon')->__('Filter'),
|
112 |
+
'class' => 'form-button',
|
113 |
+
));
|
114 |
+
|
115 |
+
$fieldset = $form->addFieldset('aitloadmon_stat', array('legend'=>Mage::helper('aitloadmon')->__('Global stats for the selected period')));
|
116 |
+
|
117 |
+
|
118 |
+
$fieldset->addField('page_views', 'label', array(
|
119 |
+
'label' => Mage::helper('aitloadmon')->__('Total page views'),
|
120 |
+
'title' => Mage::helper('aitloadmon')->__('Total page views'),
|
121 |
+
'value' => $this->getTotalPageViews(),
|
122 |
+
));
|
123 |
+
|
124 |
+
|
125 |
+
$fieldset->addField('max_load', 'label', array(
|
126 |
+
'label' => Mage::helper('aitloadmon')->__('Max load'),
|
127 |
+
'title' => Mage::helper('aitloadmon')->__('Max load'),
|
128 |
+
'value' => number_format($this->getMaxLoad(),2).' Sec',
|
129 |
+
));
|
130 |
+
|
131 |
+
$fieldset->addField('max_load_time', 'label', array(
|
132 |
+
'label' => Mage::helper('aitloadmon')->__('Max load time'),
|
133 |
+
'title' => Mage::helper('aitloadmon')->__('Max load time'),
|
134 |
+
'value' => $this->getMaxLoadTime(),
|
135 |
+
));
|
136 |
+
|
137 |
+
$form->setUseContainer(true);
|
138 |
+
$this->setForm($form);
|
139 |
+
$this->setChild('form_after', $this->getLayout()->createBlock('adminhtml/widget_form_element_dependence')
|
140 |
+
->addFieldMap($compare->getHtmlId(), $compare->getName())
|
141 |
+
->addFieldMap($compareDate->getHtmlId(), $compareDate->getName())
|
142 |
+
->addFieldDependence(
|
143 |
+
$compareDate->getName(),
|
144 |
+
$compare->getName(),
|
145 |
+
1
|
146 |
+
)
|
147 |
+
);
|
148 |
+
return parent::_prepareForm();
|
149 |
+
}
|
150 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/LineGraph.php
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_LineGraph extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
|
9 |
+
private $_maxLabelsInGraph = 20;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Gets collection(s) from parent block and processes data for javascript graphics
|
13 |
+
*/
|
14 |
+
protected function _beforeToHtml()
|
15 |
+
{
|
16 |
+
|
17 |
+
$collection = $this->getParentBlock()->getCollection();
|
18 |
+
if($this->getCompare())
|
19 |
+
{
|
20 |
+
$collectionCompare = $this->getParentBlock()->getCompareCollection();
|
21 |
+
}
|
22 |
+
|
23 |
+
$type = $this->getType();
|
24 |
+
$lineData = $this->_preProcessDataForLine($collection);
|
25 |
+
$this->_processDataForLine($lineData, $type);
|
26 |
+
|
27 |
+
if($this->getCompare())
|
28 |
+
{
|
29 |
+
$lineDataCompare = $this->_preProcessDataForLine($collectionCompare);
|
30 |
+
$this->_processDataForLine($lineDataCompare, $type, true);
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Getting the type of values we show in graph (average or maximum)
|
36 |
+
*
|
37 |
+
* @return mixed
|
38 |
+
*/
|
39 |
+
public function getType()
|
40 |
+
{
|
41 |
+
return $this->getParentBlock()->getType();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Returns whether the compare mode is enabled
|
46 |
+
*
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
public function getCompare()
|
50 |
+
{
|
51 |
+
return $this->getParentBlock()->getCompare();
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Returns html for graphics controls
|
56 |
+
*
|
57 |
+
* @return string
|
58 |
+
*/
|
59 |
+
public function getCheckBoxes()
|
60 |
+
{
|
61 |
+
$groups = Mage::helper('aitloadmon')->getGroupsArray();
|
62 |
+
$html = '';
|
63 |
+
foreach($groups as $groupName => $groupValue)
|
64 |
+
{
|
65 |
+
$html .= '<label><input type="checkbox" checked="checked" rel="'.$groupValue.'" onclick="toggleLines(this);" class="linegraph_check"/>'.ucfirst($groupName).'</label>';
|
66 |
+
}
|
67 |
+
return $html;
|
68 |
+
}
|
69 |
+
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Pre-processes data for further data processing
|
73 |
+
*
|
74 |
+
* @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
private function _preProcessDataForLine($collection)
|
78 |
+
{
|
79 |
+
$data = array();
|
80 |
+
foreach($collection as $item)
|
81 |
+
{
|
82 |
+
$pageGroupId = $item->getData('page_group_id');
|
83 |
+
$time = $item->getData('measure_time');
|
84 |
+
if(!isset($data[$time]))
|
85 |
+
{
|
86 |
+
$data[$time] = array();
|
87 |
+
}
|
88 |
+
$data[$time][$pageGroupId]['avg'] = number_format($item->getLoadTimeAvg(),2);
|
89 |
+
$data[$time][$pageGroupId]['max'] = number_format($item->getLoadTimeMax(),2);
|
90 |
+
$data[$time][$pageGroupId]['pgv'] = $item->getPageViews();
|
91 |
+
}
|
92 |
+
return $data;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Processes data and stores it as this object property
|
97 |
+
* @param $data
|
98 |
+
* @param string $type
|
99 |
+
* @param bool $compare
|
100 |
+
*/
|
101 |
+
private function _processDataForLine($data, $type = 'avg', $compare = false)
|
102 |
+
{
|
103 |
+
$groups = Mage::helper('aitloadmon')->getGroupsArray();
|
104 |
+
$dataString = '';
|
105 |
+
$dataSizeString = '';
|
106 |
+
$gcnt = 0;
|
107 |
+
foreach($groups as $pageGroupCode => $pageGroupId)
|
108 |
+
{
|
109 |
+
$dataString .= $pageGroupCode.': [';
|
110 |
+
$dataSizeString .= $pageGroupId.': [';
|
111 |
+
$dcnt = 0;
|
112 |
+
foreach($data as $timeData)
|
113 |
+
{
|
114 |
+
if(!isset($timeData[$pageGroupId][$type]))
|
115 |
+
{
|
116 |
+
$dataString .= '0';
|
117 |
+
$dataSizeString .= '0';
|
118 |
+
}
|
119 |
+
else
|
120 |
+
{
|
121 |
+
$dataString .= $timeData[$pageGroupId][$type];
|
122 |
+
$dataSizeString .= $timeData[$pageGroupId]['pgv'];
|
123 |
+
}
|
124 |
+
$dcnt++;
|
125 |
+
if($dcnt != count($data))
|
126 |
+
{
|
127 |
+
$dataString .= ',';
|
128 |
+
$dataSizeString .= ',';
|
129 |
+
}
|
130 |
+
}
|
131 |
+
$dataString .= ']';
|
132 |
+
$dataSizeString .= ']';
|
133 |
+
$gcnt++;
|
134 |
+
if($gcnt != count($groups))
|
135 |
+
{
|
136 |
+
$dataString .= ',';
|
137 |
+
$dataSizeString .= ',';
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
$method = 'setLineGraphData';
|
142 |
+
if($compare)
|
143 |
+
{
|
144 |
+
$method .= 'Compared';
|
145 |
+
}
|
146 |
+
|
147 |
+
$times = $this->_prepareHorizontalLabels(array_keys($data));
|
148 |
+
$this->$method(array('data'=>$dataString,'labels'=>'[\''.implode('\',\'',$times).'\']','dot_labels'=>'[\''.implode('\',\'',array_keys($data)).'\']','dataSize'=>$dataSizeString));
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Preparing horizontal labels for graph
|
153 |
+
*
|
154 |
+
* @param array $labelArray
|
155 |
+
* @return array
|
156 |
+
*/
|
157 |
+
private function _prepareHorizontalLabels($labelArray = array())
|
158 |
+
{
|
159 |
+
$labelArrayCount = count($labelArray);
|
160 |
+
if($labelArrayCount>$this->_maxLabelsInGraph)
|
161 |
+
{
|
162 |
+
$each = 2;
|
163 |
+
while(($labelArrayCount/$each) > $this->_maxLabelsInGraph)
|
164 |
+
{
|
165 |
+
$each++;
|
166 |
+
}
|
167 |
+
$cnt = 0;
|
168 |
+
foreach($labelArray as $key=>$value)
|
169 |
+
{
|
170 |
+
$cnt++;
|
171 |
+
if($cnt==$each)
|
172 |
+
{
|
173 |
+
$cnt=0;
|
174 |
+
}
|
175 |
+
else
|
176 |
+
{
|
177 |
+
$labelArray[$key]='';
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
$currentDate = '';
|
183 |
+
foreach($labelArray as $key=>$value)
|
184 |
+
{
|
185 |
+
if($value=='')
|
186 |
+
{
|
187 |
+
continue;
|
188 |
+
}
|
189 |
+
|
190 |
+
list($date,$time) = explode(' ',$value);
|
191 |
+
if($currentDate != $date)
|
192 |
+
{
|
193 |
+
$currentDate = $date;
|
194 |
+
$labelArray[$key]=$time.'\n\r'.$date;
|
195 |
+
}
|
196 |
+
else
|
197 |
+
{
|
198 |
+
$labelArray[$key]=$time;
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
return $labelArray;
|
203 |
+
}
|
204 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Calculator.php
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Calculator extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Preparing form for the block
|
10 |
+
*
|
11 |
+
* @return Mage_Adminhtml_Block_Widget_Form|void
|
12 |
+
*/
|
13 |
+
protected function _prepareForm()
|
14 |
+
{
|
15 |
+
$form = new Varien_Data_Form(array(
|
16 |
+
'id' => 'edit_form',
|
17 |
+
'action' => $this->getUrl('*/calculator/submit'),
|
18 |
+
'method' => 'post',
|
19 |
+
'enctype' => 'multipart/form-data',
|
20 |
+
)
|
21 |
+
);
|
22 |
+
$fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Source selection')));
|
23 |
+
$source = $fieldset->addField('source','select',array(
|
24 |
+
'title' => Mage::helper('aitloadmon')->__('Please select source for exemplary server load'),
|
25 |
+
'label' => Mage::helper('aitloadmon')->__('Please select source for exemplary server load'),
|
26 |
+
'name' => 'source',
|
27 |
+
'options' => array(
|
28 |
+
'monitor' => Mage::helper('aitloadmon')->__('Server Load Monitor'),
|
29 |
+
'log' => Mage::helper('aitloadmon')->__('Magento Logs'),
|
30 |
+
'analytics' => Mage::helper('aitloadmon')->__('Google Analytics File'),
|
31 |
+
),
|
32 |
+
));
|
33 |
+
$file = $fieldset->addField('csv_file', 'file', array(
|
34 |
+
'label' => Mage::helper('aitloadmon')->__('Google Analytics File'),
|
35 |
+
'required' => true,
|
36 |
+
'name' => 'csv_file',
|
37 |
+
));
|
38 |
+
$fieldset->addField('submit', 'submit', array(
|
39 |
+
'name' => 'submit',
|
40 |
+
'title' => Mage::helper('aitloadmon')->__('Submit'),
|
41 |
+
'value' => Mage::helper('aitloadmon')->__('Submit'),
|
42 |
+
'class' => 'form-button',
|
43 |
+
'onclick' => 'var validator = new Validation(\'edit_form\');if (!validator.validate()) {return false;}',
|
44 |
+
));
|
45 |
+
|
46 |
+
$form->setUseContainer(true);
|
47 |
+
$this->setForm($form);
|
48 |
+
|
49 |
+
$this->setChild('form_after', $this->getLayout()->createBlock('adminhtml/widget_form_element_dependence')
|
50 |
+
->addFieldMap($source->getHtmlId(), $source->getName())
|
51 |
+
->addFieldMap($file->getHtmlId(), $file->getName())
|
52 |
+
->addFieldDependence(
|
53 |
+
$file->getName(),
|
54 |
+
$source->getName(),
|
55 |
+
'analytics'
|
56 |
+
)
|
57 |
+
);
|
58 |
+
}
|
59 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/CalculatorResult.php
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_CalculatorResult extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Preparing form for the block
|
10 |
+
*
|
11 |
+
* @return Mage_Adminhtml_Block_Widget_Form|void
|
12 |
+
*/
|
13 |
+
protected function _prepareForm()
|
14 |
+
{
|
15 |
+
$form = new Varien_Data_Form(array(
|
16 |
+
'id' => 'edit_form',
|
17 |
+
'action' => $this->getUrl('*/calculator/submit'),
|
18 |
+
'method' => 'post',
|
19 |
+
'enctype' => 'multipart/form-data',
|
20 |
+
)
|
21 |
+
);
|
22 |
+
$fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Data to enter in server calculator')));
|
23 |
+
|
24 |
+
$fieldset->addField('products', 'label', array(
|
25 |
+
'label' => Mage::helper('aitloadmon')->__('Product number'),
|
26 |
+
'title' => Mage::helper('aitloadmon')->__('Product number'),
|
27 |
+
'value' => $this->getProducts(),
|
28 |
+
));
|
29 |
+
|
30 |
+
$fieldset->addField('max_load_time', 'label', array(
|
31 |
+
'label' => Mage::helper('aitloadmon')->__('Exemplary server load'),
|
32 |
+
'title' => Mage::helper('aitloadmon')->__('Exemplary server load'),
|
33 |
+
'value' => $this->getLoad(),
|
34 |
+
));
|
35 |
+
|
36 |
+
$fieldset->addField('back', 'button', array(
|
37 |
+
'value' => Mage::helper('aitloadmon')->__('Go Back'),
|
38 |
+
'onclick' => 'document.location.href=\''.$this->getUrl('*/calculator/index').'\'',
|
39 |
+
'class' => 'form-button submit',
|
40 |
+
));
|
41 |
+
|
42 |
+
$this->setForm($form);
|
43 |
+
}
|
44 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Indicator.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Indicator extends Mage_Adminhtml_Block_Template
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Returns an array of colors to use for different load levels in indicator
|
10 |
+
*
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
private function _getColors()
|
14 |
+
{
|
15 |
+
return array(
|
16 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN => '#1B7B00',
|
17 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW => '#f5861a',
|
18 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED => '#a0151e',
|
19 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK => '#000000',
|
20 |
+
);
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Returns the color of the current load level or a green color whe the load level is unavailable for some reason
|
25 |
+
*
|
26 |
+
* @return string
|
27 |
+
*/
|
28 |
+
public function getColor()
|
29 |
+
{
|
30 |
+
$colors = $this->_getColors();
|
31 |
+
$loadLevel = Mage::helper('aitloadmon')->getLoadLevel();
|
32 |
+
if($loadLevel && isset($colors[$loadLevel]))
|
33 |
+
{
|
34 |
+
return $colors[$loadLevel];
|
35 |
+
}
|
36 |
+
return $colors[Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN];
|
37 |
+
}
|
38 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Manage.php
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_Widget_Form
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Returns the compress date types
|
10 |
+
*
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
private function _getCompressTypes()
|
14 |
+
{
|
15 |
+
return Mage::getModel('aitloadmon/compressSource')->toArray();
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Preparing form for the block
|
20 |
+
*
|
21 |
+
* @return Mage_Adminhtml_Block_Widget_Form|void
|
22 |
+
*/
|
23 |
+
protected function _prepareForm()
|
24 |
+
{
|
25 |
+
$settings = Mage::getModel('aitloadmon/manage')->getSettings();
|
26 |
+
|
27 |
+
$form = new Varien_Data_Form(array(
|
28 |
+
'id' => 'manageData_form',
|
29 |
+
'action' => $this->getUrl('*/*/manage'),
|
30 |
+
'method' => 'post',
|
31 |
+
)
|
32 |
+
);
|
33 |
+
|
34 |
+
$fieldset = $form->addFieldset('manage_stat', array('legend'=>Mage::helper('aitloadmon')->__('Data stats').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('Server Load Monitor collects data from CMS, Checkout, Catalog, Catalogsearch and Other groups of pages every single minute by cron. It stores 60*5 values per hour, 24*60*5 per 24 hours.').')</span>'));
|
35 |
+
|
36 |
+
$fieldset->addField('total_records', 'label', array(
|
37 |
+
'label' => Mage::helper('aitloadmon')->__('Total records'),
|
38 |
+
'title' => Mage::helper('aitloadmon')->__('Total records'),
|
39 |
+
'value' => Mage::getModel('aitloadmon/aitloadmon')->getResource()->getRows(),
|
40 |
+
));
|
41 |
+
|
42 |
+
$fieldset->addField('total_size', 'label', array(
|
43 |
+
'label' => Mage::helper('aitloadmon')->__('Total size in bytes'),
|
44 |
+
'title' => Mage::helper('aitloadmon')->__('Total size in bytes'),
|
45 |
+
'value' => Mage::getModel('aitloadmon/aitloadmon')->getResource()->getWeight(),
|
46 |
+
));
|
47 |
+
|
48 |
+
$fieldset = $form->addFieldset('manage_auto', array('legend'=>Mage::helper('aitloadmon')->__('Automatic data compression').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('In order not to overload database Server Load Monitor compresses data automatically.').')</span>'));
|
49 |
+
|
50 |
+
$fieldset->addField('auto_enable','select', array(
|
51 |
+
'label' => Mage::helper('aitloadmon')->__('Enable automatic data compression'),
|
52 |
+
'title' => Mage::helper('aitloadmon')->__('Enable automatic data compression'),
|
53 |
+
'name' => 'auto_enable',
|
54 |
+
'options' => array(
|
55 |
+
0 => Mage::helper('aitloadmon')->__('No'),
|
56 |
+
1 => Mage::helper('aitloadmon')->__('Yes'),
|
57 |
+
),
|
58 |
+
'value' => isset($settings['enabled'])?$settings['enabled']:1,
|
59 |
+
));
|
60 |
+
|
61 |
+
$fieldset->addField('auto_day','select', array(
|
62 |
+
'label' => Mage::helper('aitloadmon')->__('Compress data of last day to'),
|
63 |
+
'title' => Mage::helper('aitloadmon')->__('Compress data of last day to'),
|
64 |
+
'name' => 'auto_day',
|
65 |
+
'options' => $this->_getCompressTypes(),
|
66 |
+
'value' => isset($settings['day'])?$settings['day']:1,
|
67 |
+
));
|
68 |
+
|
69 |
+
$fieldset->addField('auto_month','select', array(
|
70 |
+
'label' => Mage::helper('aitloadmon')->__('Compress data of last month to'),
|
71 |
+
'title' => Mage::helper('aitloadmon')->__('Compress data of last month to'),
|
72 |
+
'name' => 'auto_month',
|
73 |
+
'options' => $this->_getCompressTypes(),
|
74 |
+
'value' => isset($settings['month'])?$settings['month']:2,
|
75 |
+
));
|
76 |
+
|
77 |
+
$fieldset->addField('auto_year','select', array(
|
78 |
+
'label' => Mage::helper('aitloadmon')->__('Compress data of last year to'),
|
79 |
+
'title' => Mage::helper('aitloadmon')->__('Compress data of last year to'),
|
80 |
+
'name' => 'auto_year',
|
81 |
+
'options' => $this->_getCompressTypes(),
|
82 |
+
'value' => isset($settings['year'])?$settings['year']:3,
|
83 |
+
));
|
84 |
+
|
85 |
+
$fieldset->addField('submit_auto', 'submit', array(
|
86 |
+
'name' => 'submit_auto',
|
87 |
+
'title' => Mage::helper('aitloadmon')->__('Save settings'),
|
88 |
+
'value' => Mage::helper('aitloadmon')->__('Save settings'),
|
89 |
+
'class' => 'form-button',
|
90 |
+
));
|
91 |
+
|
92 |
+
$fieldset = $form->addFieldset('manage_manual', array('legend'=>Mage::helper('aitloadmon')->__('Manual data compression').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('Default compression settings are optimized and recommended but Admin is enabled to choose preferred compression settings as well as compress the data manually.').')</span>'));
|
93 |
+
|
94 |
+
$fieldset->addField('manual_from', 'date', array(
|
95 |
+
'name' => 'manual_from',
|
96 |
+
'title' => Mage::helper('aitloadmon')->__('From date'),
|
97 |
+
'label' => Mage::helper('aitloadmon')->__('From date'),
|
98 |
+
'image' => $this->getSkinUrl('images/grid-cal.gif'),
|
99 |
+
'format' => 'yyyy-MM-dd HH:mm:ss',
|
100 |
+
'value' => date('Y-m-d H:i:s', time()-2*24*3600),
|
101 |
+
'time' => true,
|
102 |
+
));
|
103 |
+
|
104 |
+
$fieldset->addField('manual_to', 'date', array(
|
105 |
+
'name' => 'manual_to',
|
106 |
+
'title' => Mage::helper('aitloadmon')->__('To date'),
|
107 |
+
'label' => Mage::helper('aitloadmon')->__('To date'),
|
108 |
+
'image' => $this->getSkinUrl('images/grid-cal.gif'),
|
109 |
+
'format' => 'yyyy-MM-dd HH:mm:ss',
|
110 |
+
'value' => date('Y-m-d H:i:s', time()-24*3600),
|
111 |
+
'time' => true,
|
112 |
+
));
|
113 |
+
|
114 |
+
$fieldset->addField('manual_compress','select', array(
|
115 |
+
'label' => Mage::helper('aitloadmon')->__('Compress data to'),
|
116 |
+
'title' => Mage::helper('aitloadmon')->__('Compress data to'),
|
117 |
+
'name' => 'manual_compress',
|
118 |
+
'options' => $this->_getCompressTypes(),
|
119 |
+
'value' => 1,
|
120 |
+
));
|
121 |
+
|
122 |
+
$fieldset->addField('submit_manual', 'submit', array(
|
123 |
+
'name' => 'submit_manual',
|
124 |
+
'title' => Mage::helper('aitloadmon')->__('Compress data'),
|
125 |
+
'value' => Mage::helper('aitloadmon')->__('Compress data'),
|
126 |
+
'class' => 'form-button',
|
127 |
+
));
|
128 |
+
|
129 |
+
$form->setUseContainer(true);
|
130 |
+
$this->setForm($form);
|
131 |
+
}
|
132 |
+
|
133 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Helper/Data.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Helper_Data extends Mage_Core_Helper_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Returns an array of page groups we are dividing the page views
|
10 |
+
*
|
11 |
+
* @return array
|
12 |
+
*/
|
13 |
+
public function getGroupsArray()
|
14 |
+
{
|
15 |
+
return array(
|
16 |
+
'other' => 1,
|
17 |
+
'cms' => 2,
|
18 |
+
'checkout' => 3,
|
19 |
+
'catalogsearch' => 4,
|
20 |
+
'catalog' => 5,
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Gets current load level
|
26 |
+
*
|
27 |
+
* @return int
|
28 |
+
*/
|
29 |
+
public function getLoadLevel()
|
30 |
+
{
|
31 |
+
return Aitoc_Aitloadmon_Collect::getLoadLevel();
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets current page group
|
37 |
+
*
|
38 |
+
* @return int|bool
|
39 |
+
*/
|
40 |
+
public function getGroupIdOfCurrentPage()
|
41 |
+
{
|
42 |
+
$module = Mage::app()->getRequest()->getModuleName();
|
43 |
+
$groupIds = Mage::helper('aitloadmon')->getGroupsArray();
|
44 |
+
if($module == 'admin')
|
45 |
+
{
|
46 |
+
return false;
|
47 |
+
}
|
48 |
+
elseif(isset($groupIds[$module]))
|
49 |
+
{
|
50 |
+
return $groupIds[$module];
|
51 |
+
}
|
52 |
+
else
|
53 |
+
{
|
54 |
+
return 1;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Sets current load level
|
60 |
+
* @param int $loadLevel
|
61 |
+
*/
|
62 |
+
public function setLoadLevel($loadLevel)
|
63 |
+
{
|
64 |
+
Aitoc_Aitloadmon_Collect::setLoadLevel($loadLevel);
|
65 |
+
}
|
66 |
+
|
67 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Aitloadmon.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Aitloadmon extends Mage_Core_Model_Abstract
|
7 |
+
{
|
8 |
+
const LOAD_LEVEL_GREEN = 1;
|
9 |
+
const LOAD_LEVEL_YELLOW = 2;
|
10 |
+
const LOAD_LEVEL_RED = 3;
|
11 |
+
const LOAD_LEVEL_BLACK = 4;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Standard model constructor
|
15 |
+
*/
|
16 |
+
public function _construct()
|
17 |
+
{
|
18 |
+
parent::_construct();
|
19 |
+
$this->_init('aitloadmon/aitloadmon');
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Gets a data collection bounded by 2 dates
|
24 |
+
*
|
25 |
+
* @param $startDate
|
26 |
+
* @param $endDate
|
27 |
+
* @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
|
28 |
+
*/
|
29 |
+
public function getCollectionByDates($startDate, $endDate)
|
30 |
+
{
|
31 |
+
return $this->getCollection()->filterByDates($startDate, $endDate);
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Analytics.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Analytics
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Gets the max number of visitors per minute parsing google analytics file
|
10 |
+
*
|
11 |
+
* @param string $filename
|
12 |
+
* @return int
|
13 |
+
*/
|
14 |
+
public function getVisitors($filename)
|
15 |
+
{
|
16 |
+
$f = fopen($filename,"r");
|
17 |
+
$max = 0;
|
18 |
+
while($line = fgetcsv($f,0,','))
|
19 |
+
{
|
20 |
+
if(count($line)==2 && $line[0]!='' && isset($line[1]))
|
21 |
+
{
|
22 |
+
if($line[1]>$max)
|
23 |
+
{
|
24 |
+
$max = $line[1];
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
28 |
+
fclose($f);
|
29 |
+
|
30 |
+
return ceil($max/60);
|
31 |
+
}
|
32 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Calculator.php
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Calculator extends Mage_Core_Model_Abstract
|
7 |
+
{
|
8 |
+
|
9 |
+
private $_apiUrl = 'http://www.aitoc.com/api/xmlrpc/statistic/';
|
10 |
+
|
11 |
+
private $_infoClasses = array('magento','hardware','software');
|
12 |
+
private $_period = '1 WEEK';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Standard model constructor
|
16 |
+
*/
|
17 |
+
public function _construct()
|
18 |
+
{
|
19 |
+
parent::_construct();
|
20 |
+
$this->_init('aitloadmon/calculator');
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Getter for use in calculator results
|
25 |
+
*
|
26 |
+
* @return int
|
27 |
+
*/
|
28 |
+
public function getProductInfo()
|
29 |
+
{
|
30 |
+
return Mage::getModel('catalog/product')->getCollection()->getSize();
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Collects the info that will be sent to Server Calculator
|
35 |
+
*
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
private function _collectSendingInfo()
|
39 |
+
{
|
40 |
+
$data = array();
|
41 |
+
foreach($this->_infoClasses as $class)
|
42 |
+
{
|
43 |
+
$model = Mage::getModel('aitloadmon/calculator_'.$class);
|
44 |
+
if($model instanceof Aitoc_Aitloadmon_Model_Calculator_Abstract)
|
45 |
+
{
|
46 |
+
$data += $model->toArray();
|
47 |
+
}
|
48 |
+
}
|
49 |
+
return $data;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Sends the info required for server calculator and clears the load info table
|
54 |
+
*/
|
55 |
+
public function sendCalcInfo()
|
56 |
+
{
|
57 |
+
$client = new Zend_XmlRpc_Client($this->_apiUrl);
|
58 |
+
try{
|
59 |
+
$client->call('call', array('1234567890', 'aitcalc.addStatistic', array($this->_collectSendingInfo())));
|
60 |
+
}catch(Exception $e){
|
61 |
+
Mage::log('Data sending error in '.__METHOD__.': '.$e->getMessage());
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Gets the maximum number of page views per minute based on Magento logs
|
67 |
+
*
|
68 |
+
* @return int
|
69 |
+
*/
|
70 |
+
public function getLogVisitors()
|
71 |
+
{
|
72 |
+
$collection = Mage::getModel('aitloadmon/dblog')->getCollection();
|
73 |
+
$collection->getSelect()
|
74 |
+
->reset(Zend_Db_Select::COLUMNS)
|
75 |
+
->columns('COUNT(*) AS visitors')
|
76 |
+
->where('visit_time > DATE_SUB(NOW(), INTERVAL '.$this->_period.')')
|
77 |
+
->group('DATE_FORMAT(visit_time,"%y-%m-%d-%H-%i")');
|
78 |
+
$max = 0;
|
79 |
+
foreach($collection as $item)
|
80 |
+
{
|
81 |
+
if($item->getVisitors()>$max)
|
82 |
+
{
|
83 |
+
$max = $item->getVisitors();
|
84 |
+
}
|
85 |
+
}
|
86 |
+
return $max;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Gets the maximum number of page views per minute based on monitor
|
91 |
+
*
|
92 |
+
* @return int
|
93 |
+
*/
|
94 |
+
public function getMonitorVisitors()
|
95 |
+
{
|
96 |
+
$collection = Mage::getModel('aitloadmon/aitloadmon')->getCollection();
|
97 |
+
$collection->getSelect()
|
98 |
+
->reset(Zend_Db_Select::COLUMNS)
|
99 |
+
->columns('SUM(max_page_views_per_minute) AS visitors')
|
100 |
+
->where('measure_time > DATE_SUB(NOW(), INTERVAL '.$this->_period.')')
|
101 |
+
->group('DATE_FORMAT(measure_time,"%y-%m-%d-%H-%i")');
|
102 |
+
|
103 |
+
$max = 0;
|
104 |
+
foreach($collection as $item)
|
105 |
+
{
|
106 |
+
if($item->getVisitors()>$max)
|
107 |
+
{
|
108 |
+
$max = $item->getVisitors();
|
109 |
+
}
|
110 |
+
}
|
111 |
+
return $max;
|
112 |
+
}
|
113 |
+
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Gets the maximum number of page views per minute based on Google Analytics file
|
117 |
+
*
|
118 |
+
* @return int|null
|
119 |
+
*/
|
120 |
+
public function getAnalyticsVisitors()
|
121 |
+
{
|
122 |
+
if(file_exists($this->getCsvFile()))
|
123 |
+
{
|
124 |
+
return Mage::getModel('aitloadmon/analytics')->getVisitors($this->getCsvFile());
|
125 |
+
}
|
126 |
+
|
127 |
+
return null;
|
128 |
+
}
|
129 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Abstract.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
abstract class Aitoc_Aitloadmon_Model_Calculator_Abstract
|
7 |
+
{
|
8 |
+
protected $_infoMethodPattern = '/_get\w+Info/';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Executes a system command and returns its output
|
12 |
+
*
|
13 |
+
* @param $command
|
14 |
+
* @return string
|
15 |
+
*/
|
16 |
+
protected function _exec($command)
|
17 |
+
{
|
18 |
+
$data = array();
|
19 |
+
@exec($command, $data);
|
20 |
+
if(count($data))
|
21 |
+
{
|
22 |
+
return implode("\r\n",$data);
|
23 |
+
}
|
24 |
+
else
|
25 |
+
{
|
26 |
+
return '';
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Safely gets the contents of a file
|
32 |
+
*
|
33 |
+
* @param string $file
|
34 |
+
* @return null|string
|
35 |
+
*/
|
36 |
+
protected function _getFileSafe($file)
|
37 |
+
{
|
38 |
+
try{
|
39 |
+
if($data = @file_get_contents($file))
|
40 |
+
{
|
41 |
+
return $data;
|
42 |
+
}
|
43 |
+
if($data = $this->_exec('cat '.$file))
|
44 |
+
{
|
45 |
+
return $data;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
catch(Exception $e)
|
49 |
+
{
|
50 |
+
return null;
|
51 |
+
}
|
52 |
+
return null;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Finds the methods that return required and returns them
|
57 |
+
*
|
58 |
+
* @return array
|
59 |
+
*/
|
60 |
+
protected function _getInfoMethods()
|
61 |
+
{
|
62 |
+
$methods = get_class_methods(get_class($this));
|
63 |
+
$infoMethods = array();
|
64 |
+
foreach($methods as $method)
|
65 |
+
{
|
66 |
+
if(preg_match($this->_infoMethodPattern,$method))
|
67 |
+
{
|
68 |
+
$infoMethods[] = $method;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
return $infoMethods;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Returns the required info as a joined array
|
77 |
+
*
|
78 |
+
* @return array
|
79 |
+
*/
|
80 |
+
public function toArray()
|
81 |
+
{
|
82 |
+
$returnArray = array();
|
83 |
+
foreach($this->_getInfoMethods() as $method)
|
84 |
+
{
|
85 |
+
$returnArray += $this->$method();
|
86 |
+
}
|
87 |
+
|
88 |
+
return $returnArray;
|
89 |
+
}
|
90 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Hardware.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Calculator_Hardware extends Aitoc_Aitloadmon_Model_Calculator_Abstract
|
7 |
+
{
|
8 |
+
private $_linuxCpuFile = '/proc/cpuinfo';
|
9 |
+
private $_linuxMemFile = '/proc/meminfo';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Gets the CPU info of a server
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
protected function _getCpuInfo()
|
17 |
+
{
|
18 |
+
$info = $this->_getFileSafe($this->_linuxCpuFile);
|
19 |
+
if($info)
|
20 |
+
{//^(processor\s+:\s+\d+)\s*$.*?
|
21 |
+
$freqs = array();
|
22 |
+
$bogomipss = array();
|
23 |
+
$modelNames = array();
|
24 |
+
if(preg_match_all('/^cpu\sMHz\s+:\s+([\d\.]+)\s*$/ms',$info,$matches))
|
25 |
+
{
|
26 |
+
$freqs = $matches[1];
|
27 |
+
}
|
28 |
+
if(preg_match_all('/^bogomips\s+:\s+([\d\.]+)\s*$/ms',$info,$matches))
|
29 |
+
{
|
30 |
+
$bogomipss = $matches[1];
|
31 |
+
}
|
32 |
+
if(preg_match_all('/^model\sname\s+:\s+([\w\d\s\(\)]+)\s*$/ms',$info,$matches))
|
33 |
+
{
|
34 |
+
$modelNames = $matches[1];
|
35 |
+
}
|
36 |
+
return array('cpu'=>array('cores'=>count($freqs),'freq'=>max($freqs),'bogomips'=>max($bogomipss),'model name'=>isset($modelNames[0])?$modelNames[0]:''));
|
37 |
+
}
|
38 |
+
|
39 |
+
return null;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Gets the memory info of a server
|
44 |
+
*
|
45 |
+
* @return array|null
|
46 |
+
*/
|
47 |
+
protected function _getMemInfo()
|
48 |
+
{
|
49 |
+
$info = $this->_getFileSafe($this->_linuxMemFile);
|
50 |
+
if($info)
|
51 |
+
{
|
52 |
+
if(preg_match('/MemTotal:(.*?B)/si',$info,$matches))
|
53 |
+
{
|
54 |
+
return array('mem'=>trim($matches[1]));
|
55 |
+
}
|
56 |
+
}
|
57 |
+
return null;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Gets if the server is virual
|
62 |
+
*
|
63 |
+
* @return array
|
64 |
+
*/
|
65 |
+
protected function _getVirtualInfo()
|
66 |
+
{//todo think of the additional ways
|
67 |
+
return array('virtual'=>file_exists('/proc/vz/veinfo')?'true':'false');
|
68 |
+
}
|
69 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Magento.php
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Calculator_Magento extends Aitoc_Aitloadmon_Model_Calculator_Abstract
|
7 |
+
{
|
8 |
+
private $_interval = '5';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Gets the system cache types
|
12 |
+
*
|
13 |
+
* @return array
|
14 |
+
*/
|
15 |
+
protected function _getSystemcacheInfo()
|
16 |
+
{
|
17 |
+
return array('system_cache' => array('backend' => (string)Mage::app()->getConfig()->getNode('global/cache/backend'), 'slow_backend' => (string)Mage::app()->getConfig()->getNode('global/cache/slow_backend')));
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Gets the statuses of caches
|
22 |
+
*
|
23 |
+
* @return array
|
24 |
+
*/
|
25 |
+
protected function _getCacheInfo()
|
26 |
+
{
|
27 |
+
$caches = array();
|
28 |
+
foreach (Mage::app()->getCacheInstance()->getTypes() as $type) {
|
29 |
+
$caches[$type->getId()] = $type->getStatus();
|
30 |
+
}
|
31 |
+
return array('caches' => $caches);
|
32 |
+
}
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the compiler status
|
37 |
+
*
|
38 |
+
* @return array
|
39 |
+
*/
|
40 |
+
protected function _getCompilerInfo()
|
41 |
+
{
|
42 |
+
return array('compiler' => defined('COMPILER_INCLUDE_PATH'));
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Gets the number of customers
|
47 |
+
*
|
48 |
+
* @return array
|
49 |
+
*/
|
50 |
+
protected function _getCustomerInfo()
|
51 |
+
{
|
52 |
+
return array('customers'=>Mage::getModel('customer/customer')->getCollection()->getSize());
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Gets the number of products
|
57 |
+
*
|
58 |
+
* @return array
|
59 |
+
*/
|
60 |
+
protected function _getProductInfo()
|
61 |
+
{
|
62 |
+
return array('products'=>Mage::getModel('catalog/product')->getCollection()->getSize());
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Gets the number of quotes
|
67 |
+
*
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
protected function _getQuoteInfo()
|
71 |
+
{
|
72 |
+
return array('quotes'=>Mage::getModel('sales/quote')->getCollection()->getSize());
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Gets the number of orders
|
77 |
+
*
|
78 |
+
* @return array
|
79 |
+
*/
|
80 |
+
protected function _getOrderInfo()
|
81 |
+
{
|
82 |
+
return array('orders'=>Mage::getModel('sales/order')->getCollection()->getSize());
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Gets Magento version
|
87 |
+
*
|
88 |
+
* @return array
|
89 |
+
*/
|
90 |
+
protected function _getVersionInfo()
|
91 |
+
{
|
92 |
+
return array('version'=>Mage::getVersion());
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Gets the info about server load
|
97 |
+
*
|
98 |
+
* @return array
|
99 |
+
*/
|
100 |
+
protected function _getLoadInfo()
|
101 |
+
{
|
102 |
+
$collection = Mage::getModel('aitloadmon/calculator')->getCollection();
|
103 |
+
$colString = '';
|
104 |
+
for($i=1; $i<6; $i++)
|
105 |
+
{
|
106 |
+
$colString .= 'MAX(pg'.$i.'_avg_load) AS pg'.$i.'_avg_load, pg'.$i.'_views, ';
|
107 |
+
}
|
108 |
+
$collection->getSelect()
|
109 |
+
->reset(Zend_Db_Select::COLUMNS)
|
110 |
+
->columns($colString.'CEIL(max_page_views_per_minute/'.$this->_interval.')*'.$this->_interval.' AS views, MAX(load_time_avg) AS load')
|
111 |
+
->group('views');
|
112 |
+
$data = array();
|
113 |
+
foreach($collection as $item)
|
114 |
+
{
|
115 |
+
$data[$item->getViews()] = array('avg_load'=>$item->getLoad());
|
116 |
+
for($i=1; $i<6; $i++)
|
117 |
+
{
|
118 |
+
$key = 'pg'.$i;
|
119 |
+
$data[$item->getViews()][$key.'_avg_load'] = $item->getData($key.'_avg_load');
|
120 |
+
$data[$item->getViews()][$key.'_views'] = $item->getData($key.'_views');
|
121 |
+
}
|
122 |
+
}
|
123 |
+
Mage::getModel('aitloadmon/calculator')->getResource()->deleteAll();
|
124 |
+
return array('load'=>$data);
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Gets the info whether the booster is installed
|
129 |
+
*
|
130 |
+
* @return array
|
131 |
+
*/
|
132 |
+
protected function _getBoosterInfo()
|
133 |
+
{
|
134 |
+
$enabled = 'false';
|
135 |
+
$config = @simplexml_load_file(Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.'Aitoc_Aitpagecache.xml');
|
136 |
+
if ($config){
|
137 |
+
$enabled = (string)$config->modules->Aitoc_Aitpagecache->active;
|
138 |
+
}
|
139 |
+
|
140 |
+
return array('booster'=>$enabled);
|
141 |
+
}
|
142 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Software.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Calculator_Software extends Aitoc_Aitloadmon_Model_Calculator_Abstract
|
7 |
+
{
|
8 |
+
protected $_acceleratorInis = array('eAccelerator'=>'eaccelerator.enable','APC'=>'apc.enabled','xCache'=>'xcache.cacher','Zend Optimizer+'=>'zend_optimizer.optimization_level','WinCache'=>'wincache.ocenabled');
|
9 |
+
protected $_osInfoFiles = array('/etc/SUSE-release','/etc/redhat-release','/etc/redhat_version','/etc/fedora-release','/etc/slackware-release','/etc/slackware-version',
|
10 |
+
'/etc/debian_release','/etc/debian_version','/etc/mandrake-release','/etc/yellowdog-release','/etc/sun-release','/etc/release','/etc/gentoo-release','/etc/UnitedLinux-release',
|
11 |
+
'/etc/lsb-release'
|
12 |
+
);
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Gets OS info from system files
|
16 |
+
*
|
17 |
+
* @return null|string
|
18 |
+
*/
|
19 |
+
protected function _readOsInfoFromFiles()
|
20 |
+
{
|
21 |
+
foreach($this->_osInfoFiles as $file)
|
22 |
+
{
|
23 |
+
if($data = $this->_getFileSafe($file))
|
24 |
+
{
|
25 |
+
if(strlen($data)>256)
|
26 |
+
{
|
27 |
+
$data = substr($data,0,256);
|
28 |
+
}
|
29 |
+
break;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
return $data;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Gets the OS info
|
37 |
+
*
|
38 |
+
* @return array
|
39 |
+
*/
|
40 |
+
protected function _getOsInfo()
|
41 |
+
{
|
42 |
+
if(!($os = $this->_exec('lsb_release -a')) && !($os = $this->_readOsInfoFromFiles()))
|
43 |
+
{
|
44 |
+
$os = php_uname();
|
45 |
+
}
|
46 |
+
return array('os'=>$os);
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Get webserver type
|
52 |
+
*
|
53 |
+
* @return array
|
54 |
+
*/
|
55 |
+
protected function _getWebserverInfo()
|
56 |
+
{
|
57 |
+
return array('webserver' => isset($_SERVER["SERVER_SOFTWARE"])?$_SERVER["SERVER_SOFTWARE"]:'');
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Get MySQL version
|
62 |
+
*
|
63 |
+
* @return array
|
64 |
+
*/
|
65 |
+
protected function _getMysqlInfo()
|
66 |
+
{
|
67 |
+
$resource = Mage::getSingleton('core/resource');
|
68 |
+
$readConnection = $resource->getConnection('core_read');
|
69 |
+
$query = 'SELECT VERSION()';
|
70 |
+
return array('mysql' => $readConnection->fetchOne($query));
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Get PHP information
|
75 |
+
*
|
76 |
+
* @return array
|
77 |
+
*/
|
78 |
+
protected function _getPhpInfo()
|
79 |
+
{
|
80 |
+
|
81 |
+
return array('php' => array('version' => phpversion(),'memory_limit' => ini_get('memory_limit'), 'server_api' => php_sapi_name()));
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get PHP Accelerator information
|
86 |
+
*
|
87 |
+
* @return array
|
88 |
+
*/
|
89 |
+
protected function _getPhpAccelInfo()
|
90 |
+
{
|
91 |
+
$accelerator = '';
|
92 |
+
foreach($this->_acceleratorInis as $name => $setting)
|
93 |
+
{
|
94 |
+
if(ini_get($setting))
|
95 |
+
{
|
96 |
+
$accelerator = $name;
|
97 |
+
break;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
return array('php_accel' => $accelerator);
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/CompressSource.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_CompressSource
|
7 |
+
{
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Returns compress types as a simple array
|
11 |
+
*
|
12 |
+
* @return array
|
13 |
+
*/
|
14 |
+
public function getCompressTypesArray()
|
15 |
+
{
|
16 |
+
return array(
|
17 |
+
1 => Mage::helper('aitloadmon')->__('hour'),
|
18 |
+
2 => Mage::helper('aitloadmon')->__('day'),
|
19 |
+
3 => Mage::helper('aitloadmon')->__('month'),
|
20 |
+
);
|
21 |
+
}
|
22 |
+
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Returns compress types as an array for settings
|
26 |
+
*
|
27 |
+
* @return array
|
28 |
+
*/
|
29 |
+
public function toOptionArray()
|
30 |
+
{
|
31 |
+
$levels = $this->getCompressTypesArray();
|
32 |
+
|
33 |
+
foreach($levels as $key=>$value)
|
34 |
+
{
|
35 |
+
$array[] = array('value' => $key, 'label'=>Mage::helper('aitloadmon')->__(ucfirst($value)));
|
36 |
+
}
|
37 |
+
|
38 |
+
return $array;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Returns compress types as an array for settings
|
43 |
+
*
|
44 |
+
* @return array
|
45 |
+
*/
|
46 |
+
public function toArray()
|
47 |
+
{
|
48 |
+
$levels = $this->getCompressTypesArray();
|
49 |
+
|
50 |
+
foreach($levels as $key=>$value)
|
51 |
+
{
|
52 |
+
$array[$key] = Mage::helper('aitloadmon')->__(ucfirst($value));
|
53 |
+
}
|
54 |
+
return $array;
|
55 |
+
}
|
56 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Dblog.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Dblog extends Mage_Core_Model_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard model constructor
|
10 |
+
*/
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
parent::_construct();
|
14 |
+
$this->_init('aitloadmon/dblog');
|
15 |
+
}
|
16 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/LevelSource.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_LevelSource
|
7 |
+
{
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Returns load levels as a simple array
|
11 |
+
*
|
12 |
+
* @return array
|
13 |
+
*/
|
14 |
+
public function getLoadArray()
|
15 |
+
{
|
16 |
+
return array(
|
17 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN => 'green',
|
18 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW => 'yellow',
|
19 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED => 'red',
|
20 |
+
Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK => 'black'
|
21 |
+
);
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Returns load levels as an array for settings
|
27 |
+
*
|
28 |
+
* @return array
|
29 |
+
*/
|
30 |
+
public function toOptionArray()
|
31 |
+
{
|
32 |
+
$array = array(
|
33 |
+
array('value' => 0, 'label'=>Mage::helper('aitloadmon')->__('No level')),
|
34 |
+
);
|
35 |
+
|
36 |
+
$levels = $this->getLoadArray();
|
37 |
+
|
38 |
+
foreach($levels as $key=>$value)
|
39 |
+
{
|
40 |
+
$array[] = array('value' => $key, 'label'=>Mage::helper('aitloadmon')->__(ucfirst($value)));
|
41 |
+
}
|
42 |
+
|
43 |
+
return $array;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Returns load levels as an array for settings
|
48 |
+
*
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function toArray()
|
52 |
+
{
|
53 |
+
$array = array(
|
54 |
+
0 => Mage::helper('aitloadmon')->__('No level'),
|
55 |
+
);
|
56 |
+
|
57 |
+
$levels = $this->getLoadArray();
|
58 |
+
|
59 |
+
foreach($levels as $key=>$value)
|
60 |
+
{
|
61 |
+
$array[$key] = Mage::helper('aitloadmon')->__(ucfirst($value));
|
62 |
+
}
|
63 |
+
|
64 |
+
return $array;
|
65 |
+
}
|
66 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Manage.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Manage extends Mage_Core_Controller_Varien_Front
|
7 |
+
{
|
8 |
+
private $_settingsKey = 'system/aitloadmon/manage';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Gets the setting of the module
|
12 |
+
*
|
13 |
+
* @return mixed
|
14 |
+
*/
|
15 |
+
public function getSettings()
|
16 |
+
{
|
17 |
+
return unserialize(Mage::getStoreConfig($this->_settingsKey));
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Sets the settings of the module
|
22 |
+
*
|
23 |
+
* @param $settings
|
24 |
+
*/
|
25 |
+
public function setSettings($settings)
|
26 |
+
{
|
27 |
+
$config = Mage::getConfig();
|
28 |
+
$config->saveConfig($this->_settingsKey, serialize($settings), 'default', 0)->reinit();
|
29 |
+
}
|
30 |
+
|
31 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon extends Mage_Core_Model_Mysql4_Abstract
|
7 |
+
{
|
8 |
+
|
9 |
+
private $_sysInfo;
|
10 |
+
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Standard model constructor
|
14 |
+
*/
|
15 |
+
public function _construct()
|
16 |
+
{
|
17 |
+
$this->_init('aitloadmon/aitloadmon', 'id');
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Initiates the data compression based on settings
|
22 |
+
*/
|
23 |
+
public function compress()
|
24 |
+
{
|
25 |
+
|
26 |
+
$settings = Mage::getModel('aitloadmon/manage')->getSettings();
|
27 |
+
|
28 |
+
if(!$settings['enabled'])
|
29 |
+
{
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
//last day
|
34 |
+
$format = $this->_getFormatByCompressType($settings['day']);
|
35 |
+
$from = 'DATE_SUB( NOW( ) , INTERVAL 2 DAY )';
|
36 |
+
$to = 'DATE_SUB( NOW( ) , INTERVAL 1 DAY )';
|
37 |
+
$this->_compress($from, $to, $format);
|
38 |
+
|
39 |
+
//last month
|
40 |
+
$format = $this->_getFormatByCompressType($settings['month']);
|
41 |
+
$from = 'DATE_SUB( NOW( ) , INTERVAL 2 MONTH )';
|
42 |
+
$to = 'DATE_SUB( NOW( ) , INTERVAL 1 MONTH )';
|
43 |
+
$this->_compress($from, $to, $format);
|
44 |
+
|
45 |
+
//last year
|
46 |
+
$format = $this->_getFormatByCompressType($settings['year']);
|
47 |
+
$from = 'DATE_SUB( NOW( ) , INTERVAL 2 YEAR )';
|
48 |
+
$to = 'DATE_SUB( NOW( ) , INTERVAL 1 YEAR )';
|
49 |
+
$this->_compress($from, $to, $format);
|
50 |
+
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Returns compress formats for the data compression
|
55 |
+
*
|
56 |
+
* @return array
|
57 |
+
*/
|
58 |
+
private function _getCompressFormats()
|
59 |
+
{
|
60 |
+
return array(
|
61 |
+
1 => '%y-%m-%d-%H',
|
62 |
+
2 => '%y-%m-%d',
|
63 |
+
3 => '%y-%m',
|
64 |
+
);
|
65 |
+
}
|
66 |
+
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Gets the compress format by the compress type
|
70 |
+
*
|
71 |
+
* @param $id
|
72 |
+
* @return mixed
|
73 |
+
*/
|
74 |
+
private function _getFormatByCompressType($id)
|
75 |
+
{
|
76 |
+
$formats = $this->_getCompressFormats();
|
77 |
+
if(isset($formats[$id]))
|
78 |
+
{
|
79 |
+
return $formats[$id];
|
80 |
+
}
|
81 |
+
else
|
82 |
+
{
|
83 |
+
return $formats[1];
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Initiates manual compression
|
89 |
+
*
|
90 |
+
* @param string $from
|
91 |
+
* @param string $to
|
92 |
+
* @param int $formatId
|
93 |
+
*/
|
94 |
+
public function manualCompress($from, $to, $formatId)
|
95 |
+
{
|
96 |
+
$this->_compress('\''.$from.'\'', '\''.$to.'\'', $this->_getFormatByCompressType($formatId));
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Gets the system table info
|
101 |
+
*
|
102 |
+
* @return mixed
|
103 |
+
*/
|
104 |
+
private function _getSysInfo()
|
105 |
+
{
|
106 |
+
if(!isset($this->_sysInfo))
|
107 |
+
{
|
108 |
+
$read = Mage::getSingleton('core/resource')->getConnection('core_read');
|
109 |
+
$query = 'SHOW TABLE STATUS WHERE Name = \''.$this->getTable('aitloadmon/aitloadmon').'\'';
|
110 |
+
$this->_sysInfo = $read->fetchRow($query);
|
111 |
+
}
|
112 |
+
|
113 |
+
return $this->_sysInfo;
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Gets the number of rows of the table
|
118 |
+
*
|
119 |
+
* @return int
|
120 |
+
*/
|
121 |
+
public function getRows()
|
122 |
+
{
|
123 |
+
$data = $this->_getSysInfo();
|
124 |
+
return isset($data['Rows'])?$data['Rows']:0;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Gets the size of the table
|
129 |
+
*
|
130 |
+
* @return int
|
131 |
+
*/
|
132 |
+
public function getWeight()
|
133 |
+
{
|
134 |
+
$data = $this->_getSysInfo();
|
135 |
+
return isset($data['Data_length'])?$data['Data_length']:0;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Compresses data in the database
|
140 |
+
*
|
141 |
+
* @param string $from
|
142 |
+
* @param string $to
|
143 |
+
* @param string $format
|
144 |
+
*/
|
145 |
+
private function _compress($from, $to, $format)
|
146 |
+
{
|
147 |
+
$table = $this->getTable('aitloadmon');
|
148 |
+
|
149 |
+
$read = Mage::getSingleton('core/resource')->getConnection('core_read');
|
150 |
+
$write = $read = Mage::getSingleton('core/resource')->getConnection('core_write');
|
151 |
+
|
152 |
+
$where = 'measure_time>='.$from.' AND measure_time<='.$to;
|
153 |
+
|
154 |
+
$readIdsQuery = 'SELECT id FROM '.$table.' WHERE '.$where;
|
155 |
+
$ids = $read->fetchCol($readIdsQuery);
|
156 |
+
if(!empty($ids))
|
157 |
+
{
|
158 |
+
$insertQuery ='INSERT INTO '.$table.' (measure_time, load_time_avg, load_time_max, page_group_id, page_views, max_page_views_per_minute)
|
159 |
+
SELECT MAX( measure_time ) AS measure_time, AVG( load_time_avg ) AS load_time_avg, MAX( load_time_max ) AS load_time_max, page_group_id, SUM( page_views ) AS page_views, MAX( max_page_views_per_minute ) AS max_page_views_per_minute
|
160 |
+
FROM '.$table.'
|
161 |
+
WHERE '.$where.'
|
162 |
+
GROUP BY DATE_FORMAT( `measure_time` , \''.$format.'\' ) , page_group_id';
|
163 |
+
$write->query($insertQuery);
|
164 |
+
|
165 |
+
$deleteQuery = 'DELETE FROM '.$table.' WHERE id IN('.implode(',',$ids).')';
|
166 |
+
$write->query($deleteQuery);
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon/Collection.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard constructor
|
10 |
+
*/
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('aitloadmon/aitloadmon');
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Returns a string for GROUP BY in SQL
|
18 |
+
*
|
19 |
+
* @param string $startDate
|
20 |
+
* @param string $endDate
|
21 |
+
* @return bool|string
|
22 |
+
*/
|
23 |
+
private function _getGroupString($startDate, $endDate)
|
24 |
+
{
|
25 |
+
$diff = strtotime($endDate) - strtotime($startDate);
|
26 |
+
switch($diff)
|
27 |
+
{
|
28 |
+
case ($diff>30*24*3600):
|
29 |
+
$format = '%y-%m';
|
30 |
+
break;
|
31 |
+
case ($diff>24*3600):
|
32 |
+
$format = '%y-%m-%d';
|
33 |
+
break;
|
34 |
+
case ($diff>3600):
|
35 |
+
$format = '%y-%m-%d-%H';
|
36 |
+
break;
|
37 |
+
default:
|
38 |
+
return false;
|
39 |
+
//$format = '%y-%m-%d-%H-%i';
|
40 |
+
break;
|
41 |
+
}
|
42 |
+
|
43 |
+
return 'DATE_FORMAT (`measure_time`, "'.$format.'"), page_group_id';
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Gets a data collection bounded by 2 dates
|
48 |
+
*
|
49 |
+
* @param string $startDate
|
50 |
+
* @param string $endDate
|
51 |
+
* @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
|
52 |
+
*/
|
53 |
+
public function filterByDates($startDate, $endDate)
|
54 |
+
{
|
55 |
+
if($groupString = $this->_getGroupString($startDate, $endDate))
|
56 |
+
{
|
57 |
+
$this->getSelect()->group($groupString)
|
58 |
+
->reset(Zend_Db_Select::COLUMNS)
|
59 |
+
->columns('measure_time, page_group_id, AVG(load_time_avg) AS load_time_avg, MAX(load_time_max) AS load_time_max, SUM(page_views) AS page_views');
|
60 |
+
}
|
61 |
+
|
62 |
+
$this->getSelect()->where('measure_time >=?',$startDate)
|
63 |
+
->where('measure_time <=?',$endDate)
|
64 |
+
->order('measure_time');
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Calculator extends Mage_Core_Model_Mysql4_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard model constructor
|
10 |
+
*/
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('aitloadmon/calculator', 'id');
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Deletes everything from the table
|
18 |
+
*/
|
19 |
+
public function deleteAll()
|
20 |
+
{
|
21 |
+
$adapter = $this->_getWriteAdapter();
|
22 |
+
$sql = 'DELETE FROM '.$this->getTable('aitloadmon/calculator');
|
23 |
+
$adapter->query($sql);
|
24 |
+
}
|
25 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator/Collection.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Calculator_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard constructor
|
10 |
+
*/
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('aitloadmon/calculator');
|
14 |
+
}
|
15 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Dblog extends Mage_Core_Model_Mysql4_Abstract
|
7 |
+
{
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Standard model constructor
|
11 |
+
*/
|
12 |
+
public function _construct()
|
13 |
+
{
|
14 |
+
$this->_init('aitloadmon/dblog', 'url_id');
|
15 |
+
}
|
16 |
+
|
17 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog/Collection.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_Dblog_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard constructor
|
10 |
+
*/
|
11 |
+
public function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('aitloadmon/dblog');
|
14 |
+
}
|
15 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/UrlRewrite.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Mysql4_UrlRewrite extends Mage_Core_Model_Mysql4_Url_Rewrite
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Load rewrite information for request
|
10 |
+
* If $path is array - we must load all possible records and choose one matching earlier record in array
|
11 |
+
*
|
12 |
+
* @param Mage_Core_Model_Url_Rewrite $object
|
13 |
+
* @param array|string $path
|
14 |
+
* @return Mage_Core_Model_Resource_Url_Rewrite
|
15 |
+
*/
|
16 |
+
public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
|
17 |
+
{
|
18 |
+
if (!is_array($path)) {
|
19 |
+
$path = array($path);
|
20 |
+
}
|
21 |
+
|
22 |
+
$pathBind = array();
|
23 |
+
foreach ($path as $key => $url) {
|
24 |
+
$pathBind['path' . $key] = $url;
|
25 |
+
}
|
26 |
+
// Form select
|
27 |
+
$adapter = $this->_getReadAdapter();
|
28 |
+
$select = $adapter->select()
|
29 |
+
->from($this->getMainTable())
|
30 |
+
->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')');
|
31 |
+
//->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId()));
|
32 |
+
|
33 |
+
$items = $adapter->fetchAll($select, $pathBind);
|
34 |
+
|
35 |
+
// Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
|
36 |
+
$mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
|
37 |
+
$currentPenalty = null;
|
38 |
+
$foundItem = null;
|
39 |
+
foreach ($items as $item) {
|
40 |
+
if (!array_key_exists($item['request_path'], $mapPenalty)) {
|
41 |
+
continue;
|
42 |
+
}
|
43 |
+
$penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
|
44 |
+
if (!$foundItem || $currentPenalty > $penalty) {
|
45 |
+
$foundItem = $item;
|
46 |
+
$currentPenalty = $penalty;
|
47 |
+
if (!$currentPenalty) {
|
48 |
+
break; // Found best matching item with zero penalty, no reason to continue
|
49 |
+
}
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
// Set data and finish loading
|
54 |
+
if ($foundItem) {
|
55 |
+
$object->setData($foundItem);
|
56 |
+
}
|
57 |
+
|
58 |
+
// Finish
|
59 |
+
//$this->unserializeFields($object);
|
60 |
+
$this->_afterLoad($object);
|
61 |
+
|
62 |
+
return $this;
|
63 |
+
}
|
64 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Observer.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Observer
|
7 |
+
{
|
8 |
+
protected $_systemKey = 'system/aitloadmon/sent_info_date';
|
9 |
+
protected $_expire = 604799;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Initiates the data processing job
|
13 |
+
*/
|
14 |
+
public function processData()
|
15 |
+
{
|
16 |
+
Mage::getModel('aitloadmon/process')->processData();
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Initiates the data compressing job
|
21 |
+
*/
|
22 |
+
public function compressData()
|
23 |
+
{
|
24 |
+
Mage::getModel('aitloadmon/aitloadmon')->getResource()->compress();
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Sends the info to Server Calculator by cron
|
29 |
+
*/
|
30 |
+
public function sendToAitoc()
|
31 |
+
{
|
32 |
+
$date = Mage::getStoreConfig($this->_systemKey);
|
33 |
+
$expire = $this->_expire;
|
34 |
+
if(!$date)
|
35 |
+
{
|
36 |
+
Mage::getConfig()
|
37 |
+
->saveConfig($this->_systemKey, time(), 'default', 0)
|
38 |
+
->reinit();
|
39 |
+
}
|
40 |
+
elseif((time() - $date) >= $expire)
|
41 |
+
{
|
42 |
+
Mage::getModel('aitloadmon/calculator')->sendCalcInfo();
|
43 |
+
Mage::getConfig()
|
44 |
+
->saveConfig($this->_systemKey, time(), 'default', 0)
|
45 |
+
->reinit();
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Process.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Process extends Mage_Core_Controller_Varien_Front
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Collects Magento routes
|
10 |
+
*
|
11 |
+
* @return Aitoc_Aitloadmon_Model_Process
|
12 |
+
*/
|
13 |
+
protected function _init()
|
14 |
+
{
|
15 |
+
$router = Mage::getModel('aitloadmon/router');
|
16 |
+
$router->collectRoutes('frontend', 'standard');
|
17 |
+
$this->addRouter('custom', $router);
|
18 |
+
|
19 |
+
$default = new Mage_Core_Controller_Varien_Router_Default();
|
20 |
+
$this->addRouter('default', $default);
|
21 |
+
|
22 |
+
return $this;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Pre-processes data for saving
|
27 |
+
*
|
28 |
+
* @param array $data
|
29 |
+
* @return array
|
30 |
+
*/
|
31 |
+
private function _prepareForSave($data)
|
32 |
+
{
|
33 |
+
$result = array();
|
34 |
+
foreach($data as $data_item)
|
35 |
+
{
|
36 |
+
if(isset($data_item['request_uri']) && isset($data_item['start']) && $data_item['start'] && isset($data_item['end']) && $data_item['end'])
|
37 |
+
{
|
38 |
+
if($groupId = $this->_getGroupIdByUri('http://some.host'.$data_item['request_uri']))
|
39 |
+
{
|
40 |
+
if(!isset($result[$groupId]))
|
41 |
+
{
|
42 |
+
$result[$groupId] = array('sum'=>0,'max'=>0,'cnt'=>0);
|
43 |
+
}
|
44 |
+
$loadTime = (float)$data_item['end'] - (float)$data_item['start'];
|
45 |
+
$result[$groupId]['sum'] += $loadTime;
|
46 |
+
$result[$groupId]['end'] = $data_item['end'];
|
47 |
+
if($loadTime > $result[$groupId]['max'])
|
48 |
+
{
|
49 |
+
$result[$groupId]['max'] = $loadTime;
|
50 |
+
}
|
51 |
+
$result[$groupId]['cnt']++;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
}
|
56 |
+
return $result;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Saves the processed data to database
|
61 |
+
*
|
62 |
+
* @param array $result
|
63 |
+
* @return float|int
|
64 |
+
*/
|
65 |
+
private function _saveData($result)
|
66 |
+
{
|
67 |
+
$model = Mage::getModel('aitloadmon/aitloadmon');
|
68 |
+
$calcModel = Mage::getModel('aitloadmon/calculator');
|
69 |
+
$calcModel->load(0);
|
70 |
+
$maxAvgLoadTime = 0;
|
71 |
+
$maxPageViewsPerMinute = 0;
|
72 |
+
$sumLoadTime = 0;
|
73 |
+
foreach($result as $groupId => $resultItem)
|
74 |
+
{
|
75 |
+
$avgLoadTime = $resultItem['sum']/$resultItem['cnt'];
|
76 |
+
if($avgLoadTime > $maxAvgLoadTime)
|
77 |
+
{
|
78 |
+
$maxAvgLoadTime = $avgLoadTime;
|
79 |
+
}
|
80 |
+
$model->load(0);
|
81 |
+
$model->setData(array(
|
82 |
+
|
83 |
+
'measure_time' => date('Y-m-d H:i:s',ceil($resultItem['end']/60)*60),
|
84 |
+
'load_time_avg' => $avgLoadTime,
|
85 |
+
'load_time_max' => $resultItem['max'],
|
86 |
+
'page_group_id' => $groupId,
|
87 |
+
'page_views' => $resultItem['cnt'],
|
88 |
+
'max_page_views_per_minute' => $resultItem['cnt'],
|
89 |
+
|
90 |
+
));
|
91 |
+
$model->save();
|
92 |
+
|
93 |
+
$calcModel->addData(array(
|
94 |
+
'pg'.$groupId.'_avg_load' => $avgLoadTime,
|
95 |
+
'pg'.$groupId.'_views' => $resultItem['cnt'],
|
96 |
+
));
|
97 |
+
|
98 |
+
$sumLoadTime += $resultItem['sum'];
|
99 |
+
$maxPageViewsPerMinute += $resultItem['cnt'];
|
100 |
+
}
|
101 |
+
|
102 |
+
if($maxPageViewsPerMinute)
|
103 |
+
{
|
104 |
+
$calcModel->addData(array(
|
105 |
+
'load_time_avg' => $sumLoadTime/$maxPageViewsPerMinute,
|
106 |
+
'max_page_views_per_minute' => $maxPageViewsPerMinute,
|
107 |
+
));
|
108 |
+
$calcModel->save();
|
109 |
+
}
|
110 |
+
return $maxAvgLoadTime;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Returns a load level based on load time
|
115 |
+
*
|
116 |
+
* @param float|int $maxAvgLoadTime
|
117 |
+
* @return int
|
118 |
+
*/
|
119 |
+
private function _getLoadLevelByLoad($maxAvgLoadTime)
|
120 |
+
{
|
121 |
+
$yellow = Mage::getStoreConfig('system/aitloadmon/load_yellow');
|
122 |
+
$red = Mage::getStoreConfig('system/aitloadmon/load_red');
|
123 |
+
$black = Mage::getStoreConfig('system/aitloadmon/load_black');
|
124 |
+
if($maxAvgLoadTime > $black)
|
125 |
+
{
|
126 |
+
$loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK;
|
127 |
+
}
|
128 |
+
elseif($maxAvgLoadTime > $red)
|
129 |
+
{
|
130 |
+
$loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED;
|
131 |
+
}
|
132 |
+
elseif($maxAvgLoadTime > $yellow)
|
133 |
+
{
|
134 |
+
$loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW;
|
135 |
+
}
|
136 |
+
else
|
137 |
+
{
|
138 |
+
$loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN;
|
139 |
+
}
|
140 |
+
return $loadLevel;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Splits the data by minutes
|
145 |
+
*
|
146 |
+
* @param $data
|
147 |
+
* @return array
|
148 |
+
*/
|
149 |
+
private function _getTimedData($data)
|
150 |
+
{
|
151 |
+
$return = array();
|
152 |
+
foreach($data as $dataItem)
|
153 |
+
{
|
154 |
+
if(isset($dataItem['end']))
|
155 |
+
{
|
156 |
+
$minute = ceil($dataItem['end']/60);
|
157 |
+
if(!isset($dataItem['end']))
|
158 |
+
{
|
159 |
+
continue;
|
160 |
+
}
|
161 |
+
if(!isset($return[$minute]))
|
162 |
+
{
|
163 |
+
$return[$minute] = array();
|
164 |
+
}
|
165 |
+
$return[$minute][] = $dataItem;
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
return $return;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Processes the data collected earlier
|
174 |
+
*
|
175 |
+
* @return array
|
176 |
+
*/
|
177 |
+
public function processData()
|
178 |
+
{
|
179 |
+
|
180 |
+
$this->_init();
|
181 |
+
$rawData = Aitoc_Aitloadmon_Collect::getData();
|
182 |
+
$maxAvgLoadTime = 0;
|
183 |
+
|
184 |
+
$timedData = $this->_getTimedData($rawData);
|
185 |
+
|
186 |
+
foreach($timedData as $data)
|
187 |
+
{
|
188 |
+
$result = $this->_prepareForSave($data);
|
189 |
+
$maxAvgLoadTimeTemp = $this->_saveData($result);
|
190 |
+
$maxAvgLoadTime = ($maxAvgLoadTime<$maxAvgLoadTimeTemp)?$maxAvgLoadTimeTemp:$maxAvgLoadTime;
|
191 |
+
}
|
192 |
+
|
193 |
+
$currentLoadLevel = $this->_getLoadLevelByLoad($maxAvgLoadTime);
|
194 |
+
$oldLoadLevel = Mage::helper('aitloadmon')->getLoadLevel();
|
195 |
+
if($currentLoadLevel != $oldLoadLevel)
|
196 |
+
{
|
197 |
+
Mage::helper('aitloadmon')->setLoadLevel($currentLoadLevel);
|
198 |
+
Mage::dispatchEvent('aitloadmon_load_level_changed',array('from'=>$oldLoadLevel,'to'=>$currentLoadLevel));
|
199 |
+
}
|
200 |
+
return isset($result)?$result:array();
|
201 |
+
}
|
202 |
+
|
203 |
+
private function _getUrlCuts()
|
204 |
+
{
|
205 |
+
if(!isset($this->_urlCuts))
|
206 |
+
{
|
207 |
+
$stores = Mage::getModel('core/store')->getCollection();
|
208 |
+
$storeUrls = array();
|
209 |
+
$urlCuts = array();
|
210 |
+
foreach($stores as $store)
|
211 |
+
{
|
212 |
+
$id = $store->getId();
|
213 |
+
$storeUrls[] = Mage::getStoreConfig('web/unsecure/base_url',$id);
|
214 |
+
$storeUrls[] = Mage::getStoreConfig('web/secure/base_url',$id);
|
215 |
+
$storeUrls[] = Mage::getStoreConfig('web/unsecure/base_link_url',$id);
|
216 |
+
$storeUrls[] = Mage::getStoreConfig('web/secure/base_link_url',$id);
|
217 |
+
}
|
218 |
+
foreach(array_unique($storeUrls) as $url)
|
219 |
+
{
|
220 |
+
$parsedUrl = parse_url($url);
|
221 |
+
if(isset($parsedUrl['path']))
|
222 |
+
{
|
223 |
+
$url = ltrim($parsedUrl['path'],'/');
|
224 |
+
if($url)
|
225 |
+
{
|
226 |
+
$urlCuts[] = $url;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
}
|
230 |
+
$this->_urlCuts = $urlCuts;
|
231 |
+
}
|
232 |
+
return $this->_urlCuts;
|
233 |
+
}
|
234 |
+
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Gets page view group based on its request uri
|
238 |
+
*
|
239 |
+
* @param string $uri
|
240 |
+
* @return int|bool
|
241 |
+
*/
|
242 |
+
private function _getGroupIdByUri($uri)
|
243 |
+
{
|
244 |
+
$urlCuts = $this->_getUrlCuts();
|
245 |
+
foreach($urlCuts as $urlCut)
|
246 |
+
{
|
247 |
+
$uri = str_replace($urlCut,'',$uri);
|
248 |
+
}
|
249 |
+
$uri = str_replace('index.php/','',$uri);
|
250 |
+
$request = new Mage_Core_Controller_Request_Http($uri);
|
251 |
+
//commented if for 1401 support
|
252 |
+
//if (!$request->isStraight()) {
|
253 |
+
Mage::getModel('aitloadmon/urlRewrite')->rewrite($request);
|
254 |
+
//}
|
255 |
+
$this->_rewriteRequest($request);
|
256 |
+
|
257 |
+
foreach ($this->_routers as $router) {
|
258 |
+
if ($router->match($request)) {
|
259 |
+
break;
|
260 |
+
}
|
261 |
+
}
|
262 |
+
$module = $request->getModuleName();
|
263 |
+
$groupIds = Mage::helper('aitloadmon')->getGroupsArray();
|
264 |
+
if($module == 'admin')
|
265 |
+
{
|
266 |
+
return false;
|
267 |
+
}
|
268 |
+
elseif(isset($groupIds[$module]))
|
269 |
+
{
|
270 |
+
return $groupIds[$module];
|
271 |
+
}
|
272 |
+
else
|
273 |
+
{
|
274 |
+
return 1;
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Applies rewrites to the request object
|
280 |
+
*
|
281 |
+
* @param $request
|
282 |
+
*/
|
283 |
+
private function _rewriteRequest($request)
|
284 |
+
{
|
285 |
+
$config = Mage::getConfig()->getNode('global/rewrite');
|
286 |
+
if (!$config) {
|
287 |
+
return;
|
288 |
+
}
|
289 |
+
foreach ($config->children() as $rewrite) {
|
290 |
+
$from = (string)$rewrite->from;
|
291 |
+
$to = (string)$rewrite->to;
|
292 |
+
if (empty($from) || empty($to)) {
|
293 |
+
continue;
|
294 |
+
}
|
295 |
+
$from = $this->_processRewriteUrl($from);
|
296 |
+
$to = $this->_processRewriteUrl($to);
|
297 |
+
|
298 |
+
$pathInfo = preg_replace($from, $to, $request->getPathInfo());
|
299 |
+
|
300 |
+
if (isset($rewrite->complete)) {
|
301 |
+
$request->setPathInfo($pathInfo);
|
302 |
+
} else {
|
303 |
+
$request->rewritePathInfo($pathInfo);
|
304 |
+
}
|
305 |
+
}
|
306 |
+
|
307 |
+
}
|
308 |
+
|
309 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/Router.php
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_Router extends Mage_Core_Controller_Varien_Router_Standard
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Dispatches the request until the needed module is found and sets the module params to the request object.
|
10 |
+
* Is needed to detect the requested page view group by its module name
|
11 |
+
*
|
12 |
+
* This is mainly a copy paste from Magento core, but it does not execute the routed action
|
13 |
+
*
|
14 |
+
* @param Zend_Controller_Request_Http $request
|
15 |
+
* @return bool
|
16 |
+
*/
|
17 |
+
|
18 |
+
public function match(Zend_Controller_Request_Http $request)
|
19 |
+
{
|
20 |
+
//checking before even try to find out that current module
|
21 |
+
//should use this router
|
22 |
+
#if (!$this->_beforeModuleMatch()) {
|
23 |
+
# return false;
|
24 |
+
#}
|
25 |
+
|
26 |
+
$this->fetchDefault();
|
27 |
+
|
28 |
+
$front = $this->getFront();
|
29 |
+
$path = trim($request->getPathInfo(), '/');
|
30 |
+
|
31 |
+
if ($path) {
|
32 |
+
$p = explode('/', $path);
|
33 |
+
} else {
|
34 |
+
$p = explode('/', Mage::getStoreConfig('web/default/front'));
|
35 |
+
}
|
36 |
+
|
37 |
+
// get module name
|
38 |
+
if ($request->getModuleName()) {
|
39 |
+
$module = $request->getModuleName();
|
40 |
+
} else {
|
41 |
+
if (!empty($p[0])) {
|
42 |
+
$module = $p[0];
|
43 |
+
} else {
|
44 |
+
$module = $this->getFront()->getDefault('module');
|
45 |
+
$request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
|
46 |
+
}
|
47 |
+
}
|
48 |
+
if (!$module) {
|
49 |
+
if (Mage::app()->getStore()->isAdmin()) {
|
50 |
+
$module = 'admin';
|
51 |
+
} else {
|
52 |
+
return false;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Searching router args by module name from route using it as key
|
58 |
+
*/
|
59 |
+
$modules = $this->getModuleByFrontName($module);
|
60 |
+
|
61 |
+
if ($modules === false) {
|
62 |
+
return false;
|
63 |
+
}
|
64 |
+
|
65 |
+
// checks after we found out that this router should be used for current module
|
66 |
+
#if (!$this->_afterModuleMatch()) {
|
67 |
+
# return false;
|
68 |
+
#}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Going through modules to find appropriate controller
|
72 |
+
*/
|
73 |
+
$found = false;
|
74 |
+
foreach ($modules as $realModule) {
|
75 |
+
$request->setRouteName($this->getRouteByFrontName($module));
|
76 |
+
|
77 |
+
// get controller name
|
78 |
+
if ($request->getControllerName()) {
|
79 |
+
$controller = $request->getControllerName();
|
80 |
+
} else {
|
81 |
+
if (!empty($p[1])) {
|
82 |
+
$controller = $p[1];
|
83 |
+
} else {
|
84 |
+
$controller = $front->getDefault('controller');
|
85 |
+
$request->setAlias(
|
86 |
+
Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
|
87 |
+
ltrim($request->getOriginalPathInfo(), '/')
|
88 |
+
);
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
// get action name
|
93 |
+
if (empty($action)) {
|
94 |
+
if ($request->getActionName()) {
|
95 |
+
$action = $request->getActionName();
|
96 |
+
} else {
|
97 |
+
$action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
//checking if this place should be secure
|
102 |
+
$this->_checkShouldBeSecure($request, '/'.$module.'/'.$controller.'/'.$action);
|
103 |
+
|
104 |
+
$controllerClassName = $this->_validateControllerClassName($realModule, $controller);
|
105 |
+
if (!$controllerClassName) {
|
106 |
+
continue;
|
107 |
+
}
|
108 |
+
|
109 |
+
// instantiate controller class
|
110 |
+
$controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
|
111 |
+
|
112 |
+
if (!$controllerInstance->hasAction($action)) {
|
113 |
+
continue;
|
114 |
+
}
|
115 |
+
|
116 |
+
$found = true;
|
117 |
+
break;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* if we did not found any suitable
|
122 |
+
*/
|
123 |
+
if (!$found) {
|
124 |
+
if ($this->_noRouteShouldBeApplied()) {
|
125 |
+
$controller = 'index';
|
126 |
+
$action = 'noroute';
|
127 |
+
|
128 |
+
$controllerClassName = $this->_validateControllerClassName($realModule, $controller);
|
129 |
+
if (!$controllerClassName) {
|
130 |
+
return false;
|
131 |
+
}
|
132 |
+
|
133 |
+
// instantiate controller class
|
134 |
+
$controllerInstance = Mage::getControllerInstance($controllerClassName, $request,
|
135 |
+
$front->getResponse());
|
136 |
+
|
137 |
+
if (!$controllerInstance->hasAction($action)) {
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
} else {
|
141 |
+
return false;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
// set values only after all the checks are done
|
146 |
+
$request->setModuleName($module);
|
147 |
+
$request->setControllerName($controller);
|
148 |
+
$request->setActionName($action);
|
149 |
+
$request->setControllerModule($realModule);
|
150 |
+
|
151 |
+
// set parameters from pathinfo
|
152 |
+
#for ($i = 3, $l = sizeof($p); $i < $l; $i += 2) {
|
153 |
+
# $request->setParam($p[$i], isset($p[$i+1]) ? urldecode($p[$i+1]) : '');
|
154 |
+
#}
|
155 |
+
|
156 |
+
// dispatch action
|
157 |
+
#$request->setDispatched(true);
|
158 |
+
#$controllerInstance->dispatch($action);
|
159 |
+
|
160 |
+
return true;
|
161 |
+
}
|
162 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/SysInfo.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_SysInfo extends Aitoc_Aitloadmon_Model_System_Abstract
|
7 |
+
{
|
8 |
+
protected $_systemUrl = 'http://www.aitoc.com/configuration-calculator';
|
9 |
+
protected $_systemKey = 'system/aitloadmon/system_info';
|
10 |
+
protected $_systemDateKey = 'system/aitloadmon/system_info_date';
|
11 |
+
protected $_expire = 86400;
|
12 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/System.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_System extends Aitoc_Aitloadmon_Model_System_Abstract
|
7 |
+
{
|
8 |
+
protected $_systemUrl = 'http://www.aitoc.com/monitor-module-news';
|
9 |
+
protected $_systemKey = 'system/aitloadmon/system';
|
10 |
+
protected $_systemDateKey = 'system/aitloadmon/system_date';
|
11 |
+
protected $_expire = 86400;
|
12 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/System/Abstract.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
abstract class Aitoc_Aitloadmon_Model_System_Abstract
|
7 |
+
{
|
8 |
+
public function getSystem()
|
9 |
+
{
|
10 |
+
$system_body = Mage::getStoreConfig($this->_systemKey);
|
11 |
+
$date = Mage::getStoreConfig($this->_systemDateKey);
|
12 |
+
if(!$system_body || (time()-$date)>$this->_expire)
|
13 |
+
{
|
14 |
+
$system = @file_get_contents($this->_systemUrl);
|
15 |
+
preg_match('/<body.*?>(.*)<\/body>/msi',$system,$matches);
|
16 |
+
$system_body = '';
|
17 |
+
if(isset($matches[1]))
|
18 |
+
{
|
19 |
+
$system_body = $matches[1];
|
20 |
+
}
|
21 |
+
Mage::getConfig()
|
22 |
+
->saveConfig($this->_systemKey, $system_body, 'default', 0)
|
23 |
+
->saveConfig($this->_systemDateKey, time(), 'default', 0)
|
24 |
+
->reinit();
|
25 |
+
}
|
26 |
+
return $system_body;
|
27 |
+
}
|
28 |
+
|
29 |
+
public function getSystemUrl()
|
30 |
+
{
|
31 |
+
return $this->_systemUrl;
|
32 |
+
}
|
33 |
+
}
|
app/code/local/Aitoc/Aitloadmon/Model/UrlRewrite.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Model_UrlRewrite extends Mage_Core_Model_Url_Rewrite
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Standard model constructor
|
10 |
+
*/
|
11 |
+
protected function _construct()
|
12 |
+
{
|
13 |
+
$this->_init('aitloadmon/urlRewrite');
|
14 |
+
}
|
15 |
+
|
16 |
+
public function loadByRequestPath($path)
|
17 |
+
{
|
18 |
+
$this->setId(null);
|
19 |
+
$this->_getResource()->loadByRequestPath($this, $path);
|
20 |
+
$this->_afterLoad();
|
21 |
+
$this->setOrigData();
|
22 |
+
$this->_hasDataChanges = false;
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
}
|
app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/AitloadmonController.php
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Adminhtml_AitloadmonController extends Mage_Adminhtml_Controller_Action
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Sets active menu, breadcrumbs and title
|
10 |
+
*
|
11 |
+
* @return Aitoc_Aitloadmon_Adminhtml_AitloadmonController
|
12 |
+
*/
|
13 |
+
protected function _initIndexAction()
|
14 |
+
{
|
15 |
+
if(!class_exists('Aitoc_Aitloadmon_Collect',false))
|
16 |
+
{
|
17 |
+
Mage::getSingleton('core/session')->addError(Mage::helper('aitloadmon')->__('Please add the following line to your index.php file(s):<br>include_once(dirname($_SERVER[\'SCRIPT_FILENAME\']).DIRECTORY_SEPARATOR.\'lib\'.DIRECTORY_SEPARATOR.\'Aitoc\'.DIRECTORY_SEPARATOR.\'Aitloadmon\'.DIRECTORY_SEPARATOR.\'Collect.php\');new Aitoc_Aitloadmon_Collect();'));
|
18 |
+
}
|
19 |
+
$this->loadLayout()
|
20 |
+
->_setActiveMenu('system/aitloadmon')
|
21 |
+
->_addBreadcrumb(Mage::helper('aitloadmon')->__('View Stats'), Mage::helper('aitloadmon')->__('View Stats'));
|
22 |
+
$this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('View Stats'));
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Sets active menu, breadcrumbs and title
|
28 |
+
*
|
29 |
+
* @return Aitoc_Aitloadmon_Adminhtml_AitloadmonController
|
30 |
+
*/
|
31 |
+
protected function _initManageAction()
|
32 |
+
{
|
33 |
+
$this->loadLayout()
|
34 |
+
->_setActiveMenu('system/aitloadmon')
|
35 |
+
->_addBreadcrumb(Mage::helper('aitloadmon')->__('Manage Data'), Mage::helper('aitloadmon')->__('Manage Data'));
|
36 |
+
$this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Manage Data'));
|
37 |
+
return $this;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Processes request and sets its data to the main block
|
42 |
+
*/
|
43 |
+
public function indexAction() {
|
44 |
+
$this->_initIndexAction();
|
45 |
+
|
46 |
+
if(!$startDate = $this->getRequest()->getParam('startDate'))
|
47 |
+
{
|
48 |
+
$startDate = date('Y-m-d H:i:s', time()-3600+1);
|
49 |
+
}
|
50 |
+
|
51 |
+
if(!$endDate = $this->getRequest()->getParam('endDate'))
|
52 |
+
{
|
53 |
+
$endDate = date('Y-m-d H:i:s');
|
54 |
+
}
|
55 |
+
|
56 |
+
$type = $this->getRequest()->getParam('type');
|
57 |
+
if(!$type)
|
58 |
+
{
|
59 |
+
$type = 'max';
|
60 |
+
}
|
61 |
+
|
62 |
+
$this->getLayout()->getBlock('main_bl')
|
63 |
+
->setType($type)
|
64 |
+
->setStartDate($startDate)
|
65 |
+
->setEndDate($endDate);
|
66 |
+
|
67 |
+
$compare = $this->getRequest()->getParam('compare');
|
68 |
+
|
69 |
+
if($compare && !$startDateCompare = $this->getRequest()->getParam('startDateCompare'))
|
70 |
+
{
|
71 |
+
$startDateCompare = date('Y-m-d H:i:s', time()-86400);
|
72 |
+
}
|
73 |
+
|
74 |
+
if($compare)
|
75 |
+
{
|
76 |
+
$endDateCompare = date('Y-m-d H:i:s', strtotime($startDateCompare) + (strtotime($endDate) - strtotime($startDate)));
|
77 |
+
$this->getLayout()->getBlock('main_bl')->setCompare($compare)
|
78 |
+
->setStartDateCompare($startDateCompare)
|
79 |
+
->setEndDateCompare($endDateCompare);
|
80 |
+
}
|
81 |
+
|
82 |
+
$this->renderLayout();
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* This action is used to display the manage data blocks and forms
|
87 |
+
*/
|
88 |
+
public function manageAction() {
|
89 |
+
if(Mage::app()->getRequest()->getParam('submit_auto'))
|
90 |
+
{
|
91 |
+
$data = array(
|
92 |
+
'enabled' => Mage::app()->getRequest()->getParam('auto_enable'),
|
93 |
+
'year' => Mage::app()->getRequest()->getParam('auto_year'),
|
94 |
+
'month' => Mage::app()->getRequest()->getParam('auto_month'),
|
95 |
+
'day' => Mage::app()->getRequest()->getParam('auto_day'),
|
96 |
+
);
|
97 |
+
Mage::getModel('aitloadmon/manage')->setSettings($data);
|
98 |
+
Mage::getSingleton('core/session')->addSuccess(Mage::helper('aitloadmon')->__('The settings are successfully saved.'));
|
99 |
+
}
|
100 |
+
elseif(Mage::app()->getRequest()->getParam('submit_manual'))
|
101 |
+
{
|
102 |
+
Mage::getModel('aitloadmon/aitloadmon')->getResource()->manualCompress(Mage::app()->getRequest()->getParam('manual_from'), Mage::app()->getRequest()->getParam('manual_to'), Mage::app()->getRequest()->getParam('manual_compress'));
|
103 |
+
Mage::getSingleton('core/session')->addSuccess(Mage::helper('aitloadmon')->__('The data is successfully compressed.'));
|
104 |
+
}
|
105 |
+
$this->_initManageAction();
|
106 |
+
$this->renderLayout();
|
107 |
+
}
|
108 |
+
}
|
app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/CalculatorController.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Adminhtml_CalculatorController extends Mage_Adminhtml_Controller_Action
|
7 |
+
{
|
8 |
+
/**
|
9 |
+
* Opens the form for data source selection for Server Calculator
|
10 |
+
*/
|
11 |
+
public function indexAction()
|
12 |
+
{
|
13 |
+
$this->loadLayout()
|
14 |
+
->_setActiveMenu('system/aitloadmon')
|
15 |
+
->_addBreadcrumb(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'), Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
|
16 |
+
$this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
|
17 |
+
$this->renderLayout();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Displays the result to enter to Server Calculator
|
22 |
+
*/
|
23 |
+
public function submitAction()
|
24 |
+
{
|
25 |
+
$this->loadLayout()
|
26 |
+
->_setActiveMenu('system/aitloadmon')
|
27 |
+
->_addBreadcrumb(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'), Mage::helper('aitloadmon')->__('Info for Server Calculator'));
|
28 |
+
$this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
|
29 |
+
|
30 |
+
$model = Mage::getModel('aitloadmon/calculator');
|
31 |
+
if(isset($_FILES['csv_file']['name']))
|
32 |
+
{
|
33 |
+
$model->setCsvFile($_FILES['csv_file']['tmp_name']);
|
34 |
+
}
|
35 |
+
$method = 'get'.ucfirst($this->getRequest()->getParam('source')).'Visitors';
|
36 |
+
$this->getLayout()->getBlock('aitload_calculator_result')
|
37 |
+
->setProducts($model->getProductInfo())
|
38 |
+
->setLoad($model->$method());
|
39 |
+
$this->renderLayout();
|
40 |
+
}
|
41 |
+
|
42 |
+
}
|
app/code/local/Aitoc/Aitloadmon/etc/adminhtml.xml
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<menu>
|
4 |
+
<system>
|
5 |
+
<children>
|
6 |
+
<stats module="aitloadmon">
|
7 |
+
<title>Server Load Monitor</title>
|
8 |
+
<sort_order>2</sort_order>
|
9 |
+
<action>adminhtml/aitloadmon</action>
|
10 |
+
<children>
|
11 |
+
<stats translate="title" module="aitloadmon">
|
12 |
+
<title>View Stats</title>
|
13 |
+
<action>adminhtml/aitloadmon</action>
|
14 |
+
<sort_order>10</sort_order>
|
15 |
+
</stats>
|
16 |
+
<calc translate="title" module="aitloadmon">
|
17 |
+
<title>Info for Magento Server Configuration Calculator</title>
|
18 |
+
<action>adminhtml/calculator</action>
|
19 |
+
<sort_order>20</sort_order>
|
20 |
+
</calc>
|
21 |
+
</children>
|
22 |
+
</stats>
|
23 |
+
</children>
|
24 |
+
</system>
|
25 |
+
</menu>
|
26 |
+
<acl>
|
27 |
+
<resources>
|
28 |
+
<admin>
|
29 |
+
<children>
|
30 |
+
<aitloadmon>
|
31 |
+
<title>Server Load Monitor</title>
|
32 |
+
<sort_order>300</sort_order>
|
33 |
+
</aitloadmon>
|
34 |
+
</children>
|
35 |
+
</admin>
|
36 |
+
</resources>
|
37 |
+
</acl>
|
38 |
+
</config>
|
39 |
+
<!--
|
40 |
+
/**
|
41 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
42 |
+
* @license License agreement could be found at the root folder of this package
|
43 |
+
*/
|
44 |
+
-->
|
app/code/local/Aitoc/Aitloadmon/etc/config.xml
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Aitoc_Aitloadmon>
|
5 |
+
<version>1.0.0</version>
|
6 |
+
</Aitoc_Aitloadmon>
|
7 |
+
</modules>
|
8 |
+
<admin>
|
9 |
+
<routers>
|
10 |
+
<adminhtml>
|
11 |
+
<args>
|
12 |
+
<modules>
|
13 |
+
<aitloadmon before="Mage_Adminhtml">Aitoc_Aitloadmon_Adminhtml</aitloadmon>
|
14 |
+
</modules>
|
15 |
+
</args>
|
16 |
+
</adminhtml>
|
17 |
+
</routers>
|
18 |
+
</admin>
|
19 |
+
<adminhtml>
|
20 |
+
<layout>
|
21 |
+
<updates>
|
22 |
+
<aitloadmon>
|
23 |
+
<file>aitloadmon.xml</file>
|
24 |
+
</aitloadmon>
|
25 |
+
</updates>
|
26 |
+
</layout>
|
27 |
+
</adminhtml>
|
28 |
+
<global>
|
29 |
+
<models>
|
30 |
+
<aitloadmon>
|
31 |
+
<class>Aitoc_Aitloadmon_Model</class>
|
32 |
+
<resourceModel>aitloadmon_mysql4</resourceModel>
|
33 |
+
</aitloadmon>
|
34 |
+
<aitloadmon_mysql4>
|
35 |
+
<class>Aitoc_Aitloadmon_Model_Mysql4</class>
|
36 |
+
<entities>
|
37 |
+
<aitloadmon>
|
38 |
+
<table>aitloadmon</table>
|
39 |
+
</aitloadmon>
|
40 |
+
<dblog>
|
41 |
+
<table>log_url</table>
|
42 |
+
</dblog>
|
43 |
+
<calculator>
|
44 |
+
<table>aitloadmon_calculator</table>
|
45 |
+
</calculator>
|
46 |
+
</entities>
|
47 |
+
</aitloadmon_mysql4>
|
48 |
+
</models>
|
49 |
+
<resources>
|
50 |
+
<aitloadmon_setup>
|
51 |
+
<setup>
|
52 |
+
<module>Aitoc_Aitloadmon</module>
|
53 |
+
</setup>
|
54 |
+
<connection>
|
55 |
+
<use>core_setup</use>
|
56 |
+
</connection>
|
57 |
+
</aitloadmon_setup>
|
58 |
+
<aitloadmon_write>
|
59 |
+
<connection>
|
60 |
+
<use>core_write</use>
|
61 |
+
</connection>
|
62 |
+
</aitloadmon_write>
|
63 |
+
<aitloadmon_read>
|
64 |
+
<connection>
|
65 |
+
<use>core_read</use>
|
66 |
+
</connection>
|
67 |
+
</aitloadmon_read>
|
68 |
+
</resources>
|
69 |
+
<blocks>
|
70 |
+
<aitloadmon>
|
71 |
+
<class>Aitoc_Aitloadmon_Block</class>
|
72 |
+
</aitloadmon>
|
73 |
+
</blocks>
|
74 |
+
<helpers>
|
75 |
+
<aitloadmon>
|
76 |
+
<class>Aitoc_Aitloadmon_Helper</class>
|
77 |
+
</aitloadmon>
|
78 |
+
</helpers>
|
79 |
+
</global>
|
80 |
+
<crontab>
|
81 |
+
<jobs>
|
82 |
+
<aitloadmon_process_data>
|
83 |
+
<schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
|
84 |
+
<run><model>aitloadmon/observer::processData</model></run>
|
85 |
+
</aitloadmon_process_data>
|
86 |
+
<aitloadmon_compress_data>
|
87 |
+
<schedule><cron_expr>1 */1 * * *</cron_expr></schedule>
|
88 |
+
<run><model>aitloadmon/observer::compressData</model></run>
|
89 |
+
</aitloadmon_compress_data>
|
90 |
+
<aitloadmon_calc_send>
|
91 |
+
<schedule><cron_expr>1 4 * * *</cron_expr></schedule>
|
92 |
+
<run><model>aitloadmon/observer::sendToAitoc</model></run>
|
93 |
+
</aitloadmon_calc_send>
|
94 |
+
</jobs>
|
95 |
+
</crontab>
|
96 |
+
<default>
|
97 |
+
<system>
|
98 |
+
<aitloadmon>
|
99 |
+
<load_yellow>3</load_yellow>
|
100 |
+
<load_red>7</load_red>
|
101 |
+
<load_black>10</load_black>
|
102 |
+
<manage>a:4:{s:7:"enabled";i:1;s:4:"year";i:3;s:5:"month";i:2;s:3:"day";i:1;}</manage>
|
103 |
+
</aitloadmon>
|
104 |
+
</system>
|
105 |
+
</default>
|
106 |
+
</config>
|
107 |
+
<!--
|
108 |
+
/**
|
109 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
110 |
+
* @license License agreement could be found at the root folder of this package
|
111 |
+
*/
|
112 |
+
-->
|
app/code/local/Aitoc/Aitloadmon/etc/system.xml
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<sections>
|
4 |
+
<system>
|
5 |
+
<groups>
|
6 |
+
<aitloadmon translate="label" module="aitloadmon">
|
7 |
+
<label>Server Load Monitor</label>
|
8 |
+
<frontend_type>text</frontend_type>
|
9 |
+
<sort_order>1010</sort_order>
|
10 |
+
<show_in_default>1</show_in_default>
|
11 |
+
<show_in_website>0</show_in_website>
|
12 |
+
<show_in_store>0</show_in_store>
|
13 |
+
<fields>
|
14 |
+
<load_yellow translate="label">
|
15 |
+
<label>Yellow load level after</label>
|
16 |
+
<comment><![CDATA[Yellow load level means average server load (sec); default value is 3 sec (Green load level will be if the response time will be less or equal 3 sec that means minor server load)]]></comment>
|
17 |
+
<frontend_type>text</frontend_type>
|
18 |
+
<validate>validate-number</validate>
|
19 |
+
<sort_order>500</sort_order>
|
20 |
+
<show_in_default>1</show_in_default>
|
21 |
+
<show_in_website>0</show_in_website>
|
22 |
+
<show_in_store>0</show_in_store>
|
23 |
+
</load_yellow>
|
24 |
+
|
25 |
+
<load_red translate="label">
|
26 |
+
<label>Red load level after</label>
|
27 |
+
<comment><![CDATA[Red load level means peak server load (sec); default value is 7 sec]]></comment>
|
28 |
+
<frontend_type>text</frontend_type>
|
29 |
+
<validate>validate-number</validate>
|
30 |
+
<sort_order>600</sort_order>
|
31 |
+
<show_in_default>1</show_in_default>
|
32 |
+
<show_in_website>0</show_in_website>
|
33 |
+
<show_in_store>0</show_in_store>
|
34 |
+
</load_red>
|
35 |
+
|
36 |
+
|
37 |
+
<load_black translate="label">
|
38 |
+
<label>Black load level after</label>
|
39 |
+
<comment><![CDATA[Black load level means critical load or server failure (sec); default value is 10 sec]]></comment>
|
40 |
+
<frontend_type>text</frontend_type>
|
41 |
+
<validate>validate-number</validate>
|
42 |
+
<sort_order>700</sort_order>
|
43 |
+
<show_in_default>1</show_in_default>
|
44 |
+
<show_in_website>0</show_in_website>
|
45 |
+
<show_in_store>0</show_in_store>
|
46 |
+
</load_black>
|
47 |
+
|
48 |
+
<manage_link translate="label">
|
49 |
+
<label>Manage data compression</label>
|
50 |
+
<frontend_model>aitloadmon/adminhtml_aitlink</frontend_model>
|
51 |
+
<sort_order>800</sort_order>
|
52 |
+
<show_in_default>1</show_in_default>
|
53 |
+
<show_in_website>0</show_in_website>
|
54 |
+
<show_in_store>0</show_in_store>
|
55 |
+
</manage_link>
|
56 |
+
</fields>
|
57 |
+
</aitloadmon>
|
58 |
+
</groups>
|
59 |
+
</system>
|
60 |
+
</sections>
|
61 |
+
</config>
|
62 |
+
<!--
|
63 |
+
/**
|
64 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
65 |
+
* @license License agreement could be found at the root folder of this package
|
66 |
+
*/
|
67 |
+
-->
|
app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-install-1.0.0.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
$installer = $this;
|
7 |
+
|
8 |
+
$installer->startSetup();
|
9 |
+
|
10 |
+
$installer->run("
|
11 |
+
|
12 |
+
-- DROP TABLE IF EXISTS {$this->getTable('aitloadmon')};
|
13 |
+
CREATE TABLE {$this->getTable('aitloadmon')} (
|
14 |
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
15 |
+
`measure_time` datetime NOT NULL,
|
16 |
+
`load_time_avg` float NOT NULL,
|
17 |
+
`load_time_max` float NOT NULL,
|
18 |
+
`page_group_id` int(11) NOT NULL,
|
19 |
+
`page_views` int(11) NOT NULL,
|
20 |
+
`max_page_views_per_minute` int(11) NOT NULL,
|
21 |
+
PRIMARY KEY (`id`),
|
22 |
+
KEY `measure_time` (`measure_time`)
|
23 |
+
) ENGINE=MyISAM ;
|
24 |
+
|
25 |
+
");
|
26 |
+
|
27 |
+
$installer->run("
|
28 |
+
|
29 |
+
-- DROP TABLE IF EXISTS {$this->getTable('aitloadmon/calculator')};
|
30 |
+
CREATE TABLE {$this->getTable('aitloadmon/calculator')} (
|
31 |
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
32 |
+
`load_time_avg` float NOT NULL,
|
33 |
+
`max_page_views_per_minute` int(11) NOT NULL,
|
34 |
+
`pg1_avg_load` float NOT NULL,
|
35 |
+
`pg1_views` int(11) NOT NULL,
|
36 |
+
`pg2_avg_load` float NOT NULL,
|
37 |
+
`pg2_views` int(11) NOT NULL,
|
38 |
+
`pg3_avg_load` float NOT NULL,
|
39 |
+
`pg3_views` int(11) NOT NULL,
|
40 |
+
`pg4_avg_load` float NOT NULL,
|
41 |
+
`pg4_views` int(11) NOT NULL,
|
42 |
+
`pg5_avg_load` float NOT NULL,
|
43 |
+
`pg5_views` int(11) NOT NULL,
|
44 |
+
PRIMARY KEY (`id`)
|
45 |
+
) ENGINE=MyISAM ;
|
46 |
+
|
47 |
+
");
|
48 |
+
|
49 |
+
$installer->endSetup();
|
app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-uninstall-1.0.0.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
if(!Mage::registry('aitloadmon_forced_disabled'))
|
7 |
+
{
|
8 |
+
$moduleKey = 'Aitoc_Aitloadmon';
|
9 |
+
$moduleKeyPaid = 'Aitoc_Aitloadmonpaid';
|
10 |
+
$filename = Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.$moduleKey.'.xml';
|
11 |
+
$filenamePaid = Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.$moduleKeyPaid.'.xml';
|
12 |
+
$enable = Mage::app()->getRequest()->getParam('enable');
|
13 |
+
if(file_exists($filenamePaid) && simplexml_load_file($filenamePaid)->modules->$moduleKeyPaid->active == 'true' && isset($enable[$moduleKeyPaid]) && $enable[$moduleKeyPaid])
|
14 |
+
{
|
15 |
+
Mage::register('aitloadmon_forced_disabled',1);
|
16 |
+
Mage::getModel('aitsys/module')->loadByModuleFile($filenamePaid)->getInstall()->uninstall();
|
17 |
+
Mage::getModel('aitsys/module')->loadByModuleFile($filename)->getInstall()->uninstall();
|
18 |
+
header('Location: '.Mage::helper('adminhtml')->getUrl('aitsys/index/index'));
|
19 |
+
die();
|
20 |
+
}
|
21 |
+
}
|
app/code/local/Aitoc/Aitsys/install/Aitoc_Aitloadmon.phtml
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<h2 style="text-align:center; color:#FF6300;">AITOC, Inc. License Agreement<br />
|
2 |
+
for Server Load Monitor Extension for Magento.</h2>
|
3 |
+
<h3>1. General</h3>
|
4 |
+
<p>This is a legal Agreement between AITOC Inc. and Customer that covers Customer's purchase and use of Server Load Monitor Extension for Magento (the Product) developed by AITOC Inc. The extension comes in Paid and Free version.</p>
|
5 |
+
<p>By purchasing the Paid version of the Product or installing the Free version of the Product Customer is asserting with the below-stated Terms and Conditions of the present Agreement. Any violation of this Agreement will automatically deprive the Customer of the right to use the Product, thus the Customer must cease using it and terminate all copies and derivatives of the Product at Customer's disposal.</p>
|
6 |
+
<br />
|
7 |
+
<h3>2. License</h3>
|
8 |
+
<h4 style="padding-left:20px;">2.1. General Issues</h4>
|
9 |
+
<p>By purchasing the Paid version of the Product or installing the Free version of the Product Customer obtains a License which will remain valid until the Customer stops using the Product or until AITOC terminates this License because of Customer's failure to comply with any of its Terms and Conditions.</p>
|
10 |
+
<p>AITOC offers a Single Installation License for Magento extensions. Each license can be used only on one production Magento installation. It can also be used on unlimited number of test Magento installations, if the installation domains comply with the terms, described in the documentation that comes with the Product.</p>
|
11 |
+
<p>A sold License does not include ownership of any original works, part of thereof or any documentation or derivative works of the Product.</p>
|
12 |
+
<h4 style="padding-left:20px;">2.2. License Options</h4>
|
13 |
+
<p>The Paid version of the Product comes with different License Options. The Product's price depends on the number of Stores on Customer's Magento; this number is specified in the License option which is selected during the purchase.</p>
|
14 |
+
<p>The Product contains necessary controlling functionality which makes sure the Customer does not exceed the allowed number of stores. When reaching the stores limit, the Customer can extend the limitation by purchasing the License Upgrade.</p>
|
15 |
+
<p>Downgrades are not possible via standard License Upgrade functionality. For downgrades, please refer to AITOC, Inc. for a Refund. Please note that all Refunds, including downgrades, are only possible within the 30-day period from the initial purchase date.</p>
|
16 |
+
<p>Editing License file in any way other than via Administrator Control Panel User Interface will result in License revocation, Client's deprivation of right for a refund, Product update and License Upgrade, and in Product's incorrect operation. AITOC doesn't bear any responsibility for any personal or business data loss or damaging of site in case of Client's attempts to edit License functionality.</p>
|
17 |
+
<br />
|
18 |
+
<h3>3. Copyright</h3>
|
19 |
+
<p>Any unauthorized copying, renting, leasing, sublicensing, pledging, conveying, creating any Derivative Works, or disclosing of modification source codes in any way, porting of the Product to other platforms and content management systems without prior written approval from AITOC Inc. is prohibited.</p>
|
20 |
+
<p>Proofs of copyright infringement include, but are not limited to, similar code style and structures and containing similar to Product source code, layout and design. Customer is not allowed to remove the original AITOC Inc. copyright inscription from the source code of the Product. Modifications of the source code are allowed, but at own risk.</p>
|
21 |
+
<p>If revealed that the Product is used in breach of the above mentioned terms of use, AITOC, Inc. is authorized to suspend the license, advising the Customer on what actions are required to resolve the matter. In cases of a severe or repetitive violation where advice has been ignored, AITOC Inc. is authorized to revoke the License.</p>
|
22 |
+
<p>The source code and files are exclusively owned by AITOC Inc. and are subject to US Copyright Law and Copyright Laws of the State of Delaware, as well as international copyright treaty provisions. AITOC Inc. retains title to and ownership of the Product and all enhancements, modifications and updates of the Product.</p>
|
23 |
+
<p>The exclusive forum for disputes arising out of, or relating to, this Agreement shall be an appropriate federal or state court in the county of New Castle, Delaware.</p>
|
24 |
+
<br />
|
25 |
+
<h3>4. Installation</h3>
|
26 |
+
<p>Paid version of the Product package includes an automated Installer. The automated installation may depend on configuration of operational Magento solution. AITOC does not pledge for its installation module to operate successfully on modified as well as non-modified Magento solution.</p>
|
27 |
+
<p>Free version of the Product comes without the Installer.</p>
|
28 |
+
<p>The Customer may purchase installation service executed by AITOC's staff. To use the paid installation service the Customer is obliged to present correct web-site access information to AITOC support personnel, as well as valid Product License information. Installation service payments are non-refundable. AITOC will only provide paid installation services for AITOC products where the source code hasn't been modified by the Customer or any 3rd party. Failing to meet any of the above mentioned requirements deprives Customer of ability to use this service.</p>
|
29 |
+
<br />
|
30 |
+
<h3>5. Product Support Policy</h3>
|
31 |
+
<p>Free support period for the Paid version of the Product totals 6 months starting from the purchase date of the Product. The term of free support can be prolonged when a Product update is purchased. It is described in more detail in the Product Updates section.</p>
|
32 |
+
<p>License Upgrade does not prolong the terms of free support services.</p>
|
33 |
+
<p>Support team shall provide to Customer, without additional charge, all reasonably necessary written consultation requested in connection with use and operation of the Product or any problems therewith, within above-stated period of time.</p>
|
34 |
+
<p>Free support does not include achieving compatibility with third party solutions and is not provided if the Product has been customized. In cases when extraordinary support efforts will be required Customer will be offered paid support services.</p>
|
35 |
+
<p>Under extraordinary support efforts AITOC, Inc. supposes a request which probable cost to resolve may exceed the cost of the purchased Product. Support costs are calculated in accordance with average US market rates.</p>
|
36 |
+
<p>Support team preserves the right to ignore any appeals or requests, not falling under the present conditions.</p>
|
37 |
+
<p>Free version of the Product does not include free support. Any support services associated with the Free version of the Product will be paid. Support costs are calculated in accordance with average US market rates.</p>
|
38 |
+
<p>All information, acquired from AITOC, Inc. support team is advisory only and shall not create any warranty for AITOC Inc.</p>
|
39 |
+
<br />
|
40 |
+
<h3>6. Service Level Agreement</h3>
|
41 |
+
<p>AITOC, Inc. will provide support services via support tickets system on the products' pages Monday – Friday, 8 am - 5 pm GMT (3 am -12 pm EST).</p>
|
42 |
+
<br />
|
43 |
+
<h3>7. Product Updates</h3>
|
44 |
+
<p>AITOC will timely release the information about new updates in the Changelog tab on the Product pages. It is Customer's responsibility to check for updates availability. All updates can be used only as a replacement of a previously purchased Product, not as a separate copy of a Product.</p>
|
45 |
+
<p>AITOC reserves the right to determine which products will be updated and when. AITOC reserves the right to discontinue product updates.</p>
|
46 |
+
<p>Updates for the Paid version of the Product shall be available to the Customer free of charge for 6 months from the original purchase date. After that an update would cost 75% of the current product price. The discount is only applied to the same License option.</p>
|
47 |
+
<p>If needed, License Upgrade can be performed before or after the purchase of Product Update.</p>
|
48 |
+
<p>Paid update package includes: the latest version of the product, 6 extra months of free updates and support from the purchase date.</p>
|
49 |
+
<p>Customer is not obliged to purchase updates every 6 months. The decision about whether to purchase an update and when is solely Customer's right. Customer can continue using the Product after 6 months from the original purchase date and can contact AITOC for paid support services.</p>
|
50 |
+
<br />
|
51 |
+
<h3>8. Upgrade from the Free version to Paid version of the Product.</h3>
|
52 |
+
<p>There is no special mechanism for upgrading from the Free version to Paid version of the Product. The Customer who decides to switch to the Paid version of the Product may simply purchase the Paid version and install it as per the Installation Guide that comes with the product.</p>
|
53 |
+
<br />
|
54 |
+
<h3>9. Refunds</h3>
|
55 |
+
<p>Customer may demand a refund (full refund or License Downgrade) for the Paid version of the Product within a 30-day period from the date of purchase. Any clarification of Customer's refund claim within the 30-days period is optional. AITOC staff will check the compliance of all License information before
|
56 |
+
resolving money refund issue. AITOC Inc. reserves the right to deny money refund claimed within the stated period if Customer's License info is incomplete and/or incorrect.</p>
|
57 |
+
<p>Refund requests submitted after the expiration of the 30 days period shall not be accepted.</p>
|
58 |
+
<p>Refunds of money charged for custom installation service shall not be issued.</p>
|
59 |
+
<p>AITOC Inc. considers its Product refunded when the money has been withdrawn from its account. If no notification of non-acceptance has been received from client within 10 bank days, product is treated as refunded. The Customer is obliged to uninstall the product before requesting the refund and terminate all its copies and derivatives within the 5 bank days starting from the day of initiation of money refund process.</p>
|
60 |
+
<p>AITOC Inc. is not responsible for any damages neither with Magento running, nor with business profits or information occurring due to enforced manual deleting of refunded Product or its derivatives.</p>
|
61 |
+
<br />
|
62 |
+
<h3>10. Confidentiality</h3>
|
63 |
+
<p>Each party agrees that it shall not disclose any information concerning the customers, trade secrets, methods, processes or procedures or any other confidential, financial or business information of the other party, which it learns during the course of its performance of this Agreement to any third party, without the prior written consent of such other party. This obligation shall survive the cancellation or other termination of this Agreement or License. The Product contains trade secrets and proprietary know-how that belong to AITOC Inc. and it is being made available to Licensee in strict confidence.</p>
|
64 |
+
<p>AITOC, Inc. collects the information:</p>
|
65 |
+
<p>
|
66 |
+
<ul>
|
67 |
+
<li>• Server name;</li>
|
68 |
+
<li>• Server host name;</li>
|
69 |
+
<li>• Server address (IP);</li>
|
70 |
+
<li>• Magento installation version;</li>
|
71 |
+
<li>• Personal identification for the Magento installation, issued by AITOC server during purchase;</li>
|
72 |
+
<li>• Magento installation source code path;</li>
|
73 |
+
<li>• Magento default host domain name;</li>
|
74 |
+
<li>• Magento current host domain name;</li>
|
75 |
+
<li>• Magento admin area path;</li>
|
76 |
+
<li>• Module's key name;</li>
|
77 |
+
<li>• Module's version;</li>
|
78 |
+
<li>• Module's identification number in AITOC DB;</li>
|
79 |
+
<li>• License purchase identification number.</li>
|
80 |
+
</ul>
|
81 |
+
</p>
|
82 |
+
<p>This information is collected once, upon installation, and is mandatory to ensure the Product's valid purchase and exploitation.</p>
|
83 |
+
<br />
|
84 |
+
<p>Paid and Free versions of Server Load Monitor extension also collect the following information periodically in order to configure and recommend you better server settings:</p>
|
85 |
+
<p>
|
86 |
+
<ul>
|
87 |
+
<li>• Number of products in your Magento installation;</li>
|
88 |
+
<li>• Number of orders in your Magento installation;</li>
|
89 |
+
<li>• Number of customers;</li>
|
90 |
+
<li>• Number of quotes;</li>
|
91 |
+
<li>• Magento version;</li>
|
92 |
+
<li>• Server information:
|
93 |
+
<ul>
|
94 |
+
<li style="padding-left:20px;">• General information about server's CPU;</li>
|
95 |
+
<li style="padding-left:20px;">• Number of cores on your server's CPU;</li>
|
96 |
+
<li style="padding-left:20px;">• CPU frequency;</li>
|
97 |
+
<li style="padding-left:20px;">• Measurement of CPU speed made by the Linux kernel when it boots to calibrate an internal busy-loop;</li>
|
98 |
+
<li style="padding-left:20px;">• CPU name;</li>
|
99 |
+
<li style="padding-left:20px;">• Available RAM on your server;</li>
|
100 |
+
<li style="padding-left:20px;">• Type of your server (virtual or dedicated);</li>
|
101 |
+
<li style="padding-left:20px;">• Whether AITOC's Magento Booster extension is installed;</li>
|
102 |
+
</ul>
|
103 |
+
<li>• Statistic of number of visitors and page load time.</li>
|
104 |
+
</ul>
|
105 |
+
</p>
|
106 |
+
<p>This information will be impersonalized and will not be associated to any personal data that may allow AITOC or any 3d party to identify any particular Magento installation or host. This information will be used to analyze Magento performance under different conditions and suggest appropriate hardware that may improve Magento's performance. Paid version of the Product allows to disable sending this data to AITOC.</p>
|
107 |
+
<br />
|
108 |
+
<h3>11. Disclaimer of Responsibility</h3>
|
109 |
+
<p>AITOC Inc. Products are not stand-alone solutions and require Magento to be installed primarily with a valid Magento License. AITOC Inc. does not guarantee for its Product to operate correctly on any Magento solution, either modified or non-modified. AITOC Inc. does not bear any responsibility for damages or incorrect running of the Magento solution, occurred due to installation or utilizing of Module. AITOC Inc. disclaims any accountability for content of a site on which the Product is installed. Complaints received from any third party may result in License suspension or revocation if the matter cannot be resolved. License suspension action is at the sole discretion of AITOC Inc. and is intended to offer both parties time for settlement or advice. License reinstatement shall remain Vendor's exclusive privilege. AITOC Inc. is not liable to Customer or any third party for any damages including, but not limited to, loss of business or business profits, loss of business information due to using AITOC Inc. Products. By accepting this License Agreement Customer acknowledges to use the Product at own risk and has clear understanding of responsibility for any damage to own computer system and data.</p>
|
110 |
+
<br />
|
111 |
+
<h3>12. Changes in Conditions</h3>
|
112 |
+
<p>AITOC Inc. reserves the right to modify these agreement terms at any time. It is solely Customer's responsibility to inquire about any changes made to the present Agreement.</p>
|
app/design/adminhtml/default/default/layout/aitloadmon.xml
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<layout version="0.1.0">
|
3 |
+
<adminhtml_aitloadmon_index>
|
4 |
+
<reference name="head">
|
5 |
+
<action method="addJs"><script>aitoc/aitloadmon/raphael-min.js</script></action>
|
6 |
+
<action method="addJs"><script>aitoc/aitloadmon/grafico.min.js</script></action>
|
7 |
+
<action method="addJs"><script>aitoc/aitloadmon/grafico.line.custom.js</script></action>
|
8 |
+
<action method="addJs"><script>aitoc/aitloadmon/grafico.bar.custom.js</script></action>
|
9 |
+
</reference>
|
10 |
+
<reference name="content">
|
11 |
+
<block type="aitloadmon/adminhtml_aitloadmon" name="main_bl" template="aitloadmon/graph.phtml">
|
12 |
+
<block type="aitloadmon/adminhtml_aitloadmon_filter" name="aitload_filter" as="filter" />
|
13 |
+
<block type="aitloadmon/adminhtml_aitloadmon_lineGraph" name="aitload_lineGraph" as="lineGraph" template="aitloadmon/line.phtml" />
|
14 |
+
<block type="aitloadmon/adminhtml_aitloadmon_barGraph" name="aitload_barGraph" as="barGraph" template="aitloadmon/bar.phtml" />
|
15 |
+
<block type="core/template" name="aitload_quickFilter" as="quickFilter" template="aitloadmon/quick.phtml" />
|
16 |
+
</block>
|
17 |
+
<block type="core/template" name="system" as="system_block" template="aitloadmon/system.phtml"/>
|
18 |
+
</reference>
|
19 |
+
</adminhtml_aitloadmon_index>
|
20 |
+
<adminhtml_aitloadmon_manage>
|
21 |
+
<reference name="content">
|
22 |
+
<block type="core/template" name="back" as="back_button" template="aitloadmon/back.phtml"/>
|
23 |
+
<block type="aitloadmon/adminhtml_manage" name="manage" as="manage_data"/>
|
24 |
+
<block type="core/template" name="system" as="system_block" template="aitloadmon/system.phtml"/>
|
25 |
+
</reference>
|
26 |
+
</adminhtml_aitloadmon_manage>
|
27 |
+
<adminhtml_calculator_index>
|
28 |
+
<reference name="content">
|
29 |
+
<block type="core/template" name="sysInfo" as="sysInfo_block" template="aitloadmon/sysInfo.phtml"/>
|
30 |
+
<!--block type="aitloadmon/adminhtml_calculator" name="aitload_calculator" as="calculator" /-->
|
31 |
+
</reference>
|
32 |
+
</adminhtml_calculator_index>
|
33 |
+
<adminhtml_calculator_submit>
|
34 |
+
<reference name="content">
|
35 |
+
<block type="aitloadmon/adminhtml_calculatorResult" name="aitload_calculator_result" as="calculator_result" />
|
36 |
+
</reference>
|
37 |
+
</adminhtml_calculator_submit>
|
38 |
+
<default>
|
39 |
+
<reference name="content">
|
40 |
+
<block type="aitloadmon/adminhtml_indicator" name="aitloadmon_indicator" template="aitloadmon/indicator.phtml"/>
|
41 |
+
</reference>
|
42 |
+
</default>
|
43 |
+
|
44 |
+
</layout>
|
45 |
+
<!--
|
46 |
+
/**
|
47 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
48 |
+
* @license License agreement could be found at the root folder of this package
|
49 |
+
*/
|
50 |
+
-->
|
app/design/adminhtml/default/default/template/aitloadmon/back.phtml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<input type="button" class="form-button submit" title="Return to System Configuration" value="Return to System Configuration" id="return" onclick="document.location.href='<?php echo Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit',array('section'=>'system')); ?>'" style="float: right; margin-bottom: 10px;">
|
8 |
+
<div style="clear: both;"></div>
|
app/design/adminhtml/default/default/template/aitloadmon/bar.phtml
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<div class="entry-edit">
|
8 |
+
<div class="entry-edit-head">
|
9 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__('Avg Load / Max Load for the selected period by groups');?></h4>
|
10 |
+
</div>
|
11 |
+
<div class="fieldset">
|
12 |
+
<div id="graph2" style="height: 200px; width: 1000px;"></div>
|
13 |
+
</div>
|
14 |
+
</div>
|
15 |
+
<script type="text/javascript">
|
16 |
+
var graph2 = new Grafico.HorizontalBarGraphCustom($('graph2'), {
|
17 |
+
<?php echo $this->getBarGraphData(); ?>
|
18 |
+
},
|
19 |
+
{
|
20 |
+
labels: <?php echo $this->getBarLabels($this->getCompare()); ?>,
|
21 |
+
show_ticks: false,
|
22 |
+
compare_mode: <?php echo (int)$this->getCompare();?>,
|
23 |
+
vertical_label_unit : "s",
|
24 |
+
colors: {
|
25 |
+
max_load: '#A0151E',
|
26 |
+
avg_load: ['#877D1E',"#6016CA","#1680CA","#F5861A","#1B7B00"]
|
27 |
+
}
|
28 |
+
}
|
29 |
+
);
|
30 |
+
</script>
|
app/design/adminhtml/default/default/template/aitloadmon/graph.phtml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<ul class="messages">
|
8 |
+
<?php if(!Mage::getStoreConfig('system/aitloadmon/disable_calc_info_sending')):?>
|
9 |
+
<li class="notice-msg">
|
10 |
+
<p><?php echo Mage::helper('aitloadmon')->__('Please note that collected data of Server Load Monitor extension will be sent to AITOC’s Magento Server Configuration Calculator in order to configure and recommend you better server settings.');?></p>
|
11 |
+
</li>
|
12 |
+
<?php endif; ?>
|
13 |
+
<li class="notice-msg">
|
14 |
+
<p><?php echo Mage::helper('aitloadmon')->__('Please note that the server time is used instead of your local one.');?></p>
|
15 |
+
</li>
|
16 |
+
</ul>
|
17 |
+
<?php echo $this->getChildHtml('quickFilter'); ?>
|
18 |
+
<?php echo $this->getChildHtml('filter'); ?>
|
19 |
+
<?php if(!$this->isEnoughDataToBuildGraph($this->getCollection()) || ($this->getCompare() && !$this->isEnoughDataToBuildGraph($this->getCompareCollection()))):?>
|
20 |
+
<ul class="messages">
|
21 |
+
<li class="error-msg">
|
22 |
+
<p><?php echo Mage::helper('aitloadmon')->__('Sorry, there is not enough data for the selected period(s).');?></p>
|
23 |
+
</li>
|
24 |
+
</ul>
|
25 |
+
<?php else: ?>
|
26 |
+
<?php echo $this->getChildHtml('barGraph'); ?>
|
27 |
+
<?php echo $this->getChildHtml('lineGraph'); ?>
|
28 |
+
<?php endif;?>
|
app/design/adminhtml/default/default/template/aitloadmon/indicator.phtml
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<div style="position: fixed; top: 35px; right: 3px; background-color: #cccccc; height: 18px; margin: 0; padding: 0;" onmouseover="$('aitloadmon_notice').show();" onmouseout="$('aitloadmon_notice').hide();">
|
8 |
+
<div id="aitloadmon_notice" style="display:none; float: left;"> <?php echo Mage::helper('aitloadmon')->__('Current Server Load:');?> </div>
|
9 |
+
<a href="<?php echo Mage::helper("adminhtml")->getUrl('adminhtml/aitloadmon/index');?>">
|
10 |
+
<div style="background-color: <?php echo $this->getColor();?>; height: 16px; width: 16px; float: left; border: 1px solid #cccccc;"></div>
|
11 |
+
</a>
|
12 |
+
</div>
|
app/design/adminhtml/default/default/template/aitloadmon/line.phtml
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<style>
|
8 |
+
.linegraph_check
|
9 |
+
{
|
10 |
+
margin-right: 5px;
|
11 |
+
margin-left: 25px;
|
12 |
+
}
|
13 |
+
</style>
|
14 |
+
<div class="entry-edit">
|
15 |
+
<div class="entry-edit-head">
|
16 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__(($this->getType()=='max')?'MAXIMUM':'AVERAGE').Mage::helper('aitloadmon')->__(' LOAD for the selected period by groups and time');?></h4>
|
17 |
+
</div>
|
18 |
+
<div class="fieldset">
|
19 |
+
<div><?php echo Mage::helper('aitloadmon')->__('Show graphs for:'); ?><?php echo $this->getCheckBoxes(); ?></div>
|
20 |
+
<div id="graph1" style="height: 340px; width: 1000px;"></div>
|
21 |
+
<?php if($this->getCompare()):?><div id="graph1compare" style="height: 340px; width: 1000px;"></div><?php endif;?>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
<script type="text/javascript">
|
25 |
+
var lineGraphs = [];
|
26 |
+
function toggleLines(obj)
|
27 |
+
{
|
28 |
+
var graphId = $(obj).getAttribute('rel');
|
29 |
+
if(lineGraphs[graphId])
|
30 |
+
{
|
31 |
+
if(!$(obj).checked)
|
32 |
+
{
|
33 |
+
lineGraphs[graphId].each(function(element){element.hide()});
|
34 |
+
}
|
35 |
+
else
|
36 |
+
{
|
37 |
+
lineGraphs[graphId].each(function(element){element.show()});
|
38 |
+
}
|
39 |
+
}
|
40 |
+
}
|
41 |
+
<?php $lineGraph = $this->getLineGraphData(); ?>
|
42 |
+
var graph1 = new Grafico.LineGraphCustom($('graph1'),
|
43 |
+
{
|
44 |
+
<?php echo $lineGraph['data']; ?>
|
45 |
+
},
|
46 |
+
{
|
47 |
+
markers : "value",
|
48 |
+
grid : true,
|
49 |
+
draw_axis : true,
|
50 |
+
plot_padding : 0,
|
51 |
+
stroke_width : 2,
|
52 |
+
show_vertical_labels : true,
|
53 |
+
show_horizontal_labels : true,
|
54 |
+
vertical_label_unit: 's',
|
55 |
+
label_rotation : 0,
|
56 |
+
labels : <?php echo $lineGraph['labels']; ?>,
|
57 |
+
dot_labels : <?php echo $lineGraph['dot_labels']; ?>,
|
58 |
+
label_sizes : {<?php echo $lineGraph['dataSize']; ?>},
|
59 |
+
hover_color : "#000",
|
60 |
+
hover_text_color : "#fff",
|
61 |
+
opacity: 1,
|
62 |
+
colors: {
|
63 |
+
other: "#877D1E",
|
64 |
+
cms: "#6016CA",
|
65 |
+
checkout: "#1680CA",
|
66 |
+
catalogsearch: "#F5861A",
|
67 |
+
catalog: "#1B7B00"
|
68 |
+
},
|
69 |
+
datalabels : {
|
70 |
+
other: "Other pages",
|
71 |
+
cms: "CMS pages",
|
72 |
+
checkout: "Checkout pages",
|
73 |
+
catalogsearch: "Search pages",
|
74 |
+
catalog: "Catalog pages"
|
75 |
+
}
|
76 |
+
});
|
77 |
+
|
78 |
+
<?php if($this->getCompare()):?>
|
79 |
+
<?php $lineGraph = $this->getLineGraphDataCompared(); ?>
|
80 |
+
var graph1 = new Grafico.LineGraphCustom($('graph1compare'),
|
81 |
+
{
|
82 |
+
<?php echo $lineGraph['data']; ?>
|
83 |
+
},
|
84 |
+
{
|
85 |
+
markers : "value",
|
86 |
+
grid : true,
|
87 |
+
draw_axis : true,
|
88 |
+
plot_padding : 0,
|
89 |
+
stroke_width : 2,
|
90 |
+
show_vertical_labels : true,
|
91 |
+
show_horizontal_labels : true,
|
92 |
+
label_rotation : 0,
|
93 |
+
labels : <?php echo $lineGraph['labels']; ?>,
|
94 |
+
dot_labels : <?php echo $lineGraph['dot_labels']; ?>,
|
95 |
+
label_sizes : {<?php echo $lineGraph['dataSize']; ?>},
|
96 |
+
hover_color : "#000",
|
97 |
+
hover_text_color : "#fff",
|
98 |
+
opacity: 0.5,
|
99 |
+
colors: {
|
100 |
+
other: "#877D1E",
|
101 |
+
cms: "#6016CA",
|
102 |
+
checkout: "#1680CA",
|
103 |
+
catalogsearch: "#F5861A",
|
104 |
+
catalog: "#1B7B00"
|
105 |
+
},
|
106 |
+
datalabels : {
|
107 |
+
other: "Other pages",
|
108 |
+
cms: "CMS pages",
|
109 |
+
checkout: "Checkout pages",
|
110 |
+
catalogsearch: "Search pages",
|
111 |
+
catalog: "Catalog pages"
|
112 |
+
}
|
113 |
+
});
|
114 |
+
<?php endif;?>
|
115 |
+
</script>
|
app/design/adminhtml/default/default/template/aitloadmon/quick.phtml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<div class="entry-edit">
|
8 |
+
<div class="entry-edit-head">
|
9 |
+
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__('Basic Filter Options');?></h4>
|
10 |
+
</div>
|
11 |
+
<div class="fieldset">
|
12 |
+
<input type="button" class="form-button" title="Last Hour" value="Last Hour" id="qickfilter0" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-3600+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
|
13 |
+
<input type="button" class="form-button" title="Last 24h" value="Last 24h" id="qickfilter1" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
|
14 |
+
<input type="button" class="form-button" title="Last Week" value="Last Week" id="qickfilter2" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*7+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
|
15 |
+
<input type="button" class="form-button" title="Last Month" value="Last Month" id="qickfilter3" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*30+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
|
16 |
+
<input type="button" class="form-button" title="Last Year" value="Last Year" id="qickfilter4" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*365+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
|
17 |
+
</div>
|
18 |
+
</div>
|
19 |
+
<script type="text/javascript">
|
20 |
+
function quickFilter($start,$end)
|
21 |
+
{
|
22 |
+
$('starts').value = $start;
|
23 |
+
$('ends').value = $end;
|
24 |
+
$('compare').checked = false;
|
25 |
+
$('edit_form').submit();
|
26 |
+
|
27 |
+
}
|
28 |
+
</script>
|
app/design/adminhtml/default/default/template/aitloadmon/sysInfo.phtml
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<?php if($system = Mage::getModel('aitloadmon/sysInfo')->getSystem()): ?>
|
8 |
+
<div><?php echo $system;?></div>
|
9 |
+
<?php else:?>
|
10 |
+
<iframe src="<?php echo Mage::getModel('aitloadmon/sysInfo')->getSystemUrl();?>" style="width: 100%; border: medium none;"></iframe>
|
11 |
+
<?php endif;?>
|
app/design/adminhtml/default/default/template/aitloadmon/system.phtml
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
?>
|
7 |
+
<?php if($system = Mage::getModel('aitloadmon/system')->getSystem()): ?>
|
8 |
+
<div><?php echo $system;?></div>
|
9 |
+
<?php else:?>
|
10 |
+
<iframe src="<?php echo Mage::getModel('aitloadmon/system')->getSystemUrl();?>" style="width: 100%; border: medium none;"></iframe>
|
11 |
+
<?php endif;?>
|
app/etc/modules/Aitoc_Aitloadmon.xml
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Aitoc_Aitloadmon>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>local</codePool>
|
7 |
+
<self_name>Server Load Monitor Free</self_name>
|
8 |
+
</Aitoc_Aitloadmon>
|
9 |
+
</modules>
|
10 |
+
</config>
|
11 |
+
<!--
|
12 |
+
/**
|
13 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
14 |
+
* @license License agreement could be found at the root folder of this package
|
15 |
+
*/
|
16 |
+
-->
|
js/aitoc/aitloadmon/grafico.bar.custom.js
ADDED
@@ -0,0 +1,204 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
3 |
+
* @license License agreement could be found at the root folder of this package
|
4 |
+
*/
|
5 |
+
Grafico.HorizontalBarGraphCustom = Class.create(Grafico.BarGraph, {
|
6 |
+
chartDefaults: function () {
|
7 |
+
return {
|
8 |
+
bar : true,
|
9 |
+
horizontalbar : true,
|
10 |
+
plot_padding : 0,
|
11 |
+
horizontal_rounded : false,
|
12 |
+
bargraph_lastcolor : false
|
13 |
+
};
|
14 |
+
},
|
15 |
+
|
16 |
+
setChartSpecificOptions: function () {
|
17 |
+
// Approximate the width required by the labels
|
18 |
+
this.x_padding_left = 20 + this.longestLabel() * (this.options.font_size / 2);
|
19 |
+
this.bar_padding = 5;
|
20 |
+
this.bar_width = this.calculateBarHeight();
|
21 |
+
this.step = this.calculateStep();
|
22 |
+
this.graph_width = this.options.width - this.x_padding_right - this.x_padding_left;
|
23 |
+
},
|
24 |
+
|
25 |
+
normalise: function (value) {
|
26 |
+
var range = this.makeValueLabels(this.y_label_count);
|
27 |
+
range = range[range.length-1];
|
28 |
+
return ((value / range) * this.graph_width);
|
29 |
+
},
|
30 |
+
|
31 |
+
longestLabel: function () {
|
32 |
+
return $A(this.options.labels).sort(function (a, b) { return a.toString().length < b.toString().length; }).first().toString().length;
|
33 |
+
},
|
34 |
+
|
35 |
+
/* Height */
|
36 |
+
calculateBarHeight: function () {
|
37 |
+
return (this.graph_height / this.data_size) - this.bar_padding;
|
38 |
+
},
|
39 |
+
|
40 |
+
calculateStep: function () {
|
41 |
+
return (this.graph_height - (this.options.plot_padding * 2)) / this.data_size;
|
42 |
+
},
|
43 |
+
|
44 |
+
drawLines: function (label, color, data, datalabel, element, graphindex) {
|
45 |
+
var y = this.y_padding_top + (this.bar_padding / 2) -0.5,
|
46 |
+
offset = this.zero_value * (this.graph_width / this.y_label_count),
|
47 |
+
x = this.x_padding_left + offset - 0.5,
|
48 |
+
lastcolor = this.options.bargraph_lastcolor,
|
49 |
+
negativecolor = this.options.bargraph_negativecolor || color;
|
50 |
+
this.datalabel = datalabel;
|
51 |
+
$A(data).each(function (value, index) {
|
52 |
+
var color2,
|
53 |
+
horizontal_rounded = this.options.horizontal_rounded ? this.bar_width / 2 : 0,
|
54 |
+
bargraph;
|
55 |
+
|
56 |
+
if(this.options.compare_mode)
|
57 |
+
{
|
58 |
+
var opacity = (index%2)?0.5:1;
|
59 |
+
}
|
60 |
+
else
|
61 |
+
{
|
62 |
+
var opacity = 1;
|
63 |
+
}
|
64 |
+
|
65 |
+
if(color instanceof Array)
|
66 |
+
{
|
67 |
+
if(this.options.compare_mode)
|
68 |
+
{
|
69 |
+
tmp_index = Math.floor(index / 2);
|
70 |
+
}
|
71 |
+
else
|
72 |
+
{
|
73 |
+
tmp_index = index;
|
74 |
+
}
|
75 |
+
tmp_color = color[tmp_index];
|
76 |
+
}
|
77 |
+
else
|
78 |
+
{
|
79 |
+
tmp_color = color;
|
80 |
+
}
|
81 |
+
|
82 |
+
if (lastcolor && index === data.length-1) {
|
83 |
+
color2 = lastcolor;
|
84 |
+
} else {
|
85 |
+
color2 = value < 0 ? negativecolor : tmp_color;
|
86 |
+
}
|
87 |
+
|
88 |
+
value = value / this.graph_width * (this.graph_width - offset);
|
89 |
+
bargraph = this.paper.rect(x, y, value, this.bar_width, horizontal_rounded).attr({fill: color2, 'stroke-width': 0, stroke : color2, 'stroke-opacity' : 0, 'fill-opacity' : opacity});
|
90 |
+
|
91 |
+
if (value < 0) {
|
92 |
+
bargraph.attr({width: -bargraph.attrs.width}).translate(value, 0);
|
93 |
+
}
|
94 |
+
|
95 |
+
if (horizontal_rounded) {
|
96 |
+
var bargraphset = this.paper.set(),
|
97 |
+
bargraph2 = this.paper.rect(x, y, value - this.bar_width/2, this.bar_width).attr({fill: color2, 'stroke-width': 0, stroke : color2, 'stroke-opacity' : 0});
|
98 |
+
|
99 |
+
bargraphset.push(bargraph2, bargraph);
|
100 |
+
|
101 |
+
if (value < 0) {
|
102 |
+
bargraph2.attr({width: -bargraph2.attrs.width - this.bar_width}).translate(value + this.bar_width/2, 0);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
if (this.options.datalabels) {
|
107 |
+
var hover_color = this.options.hover_color || color2,
|
108 |
+
hoverSet = this.paper.set(),
|
109 |
+
datalabel = this.datalabel[index].toString(),
|
110 |
+
text = this.paper.text(offset + value + this.x_padding_left / 2, bargraph.attrs.y - (this.options.font_size * 1.5), datalabel)
|
111 |
+
.attr({'font-size': this.options.font_size, fill: this.options.hover_text_color, opacity: 1}),
|
112 |
+
hoverbar = this.paper.rect(
|
113 |
+
this.x_padding_left,
|
114 |
+
y,
|
115 |
+
this.graph_width,
|
116 |
+
this.bar_width).attr({fill: color2, 'stroke-width': 0, stroke: color2, opacity: 0}
|
117 |
+
),
|
118 |
+
textbox = text.getBBox();
|
119 |
+
|
120 |
+
if (value < 0) { text.translate(textbox.width, 0); }
|
121 |
+
|
122 |
+
var textpadding = 4,
|
123 |
+
roundRect = this.drawRoundRect(text, textbox, textpadding),
|
124 |
+
nib = this.drawNib(text, textbox, textpadding);
|
125 |
+
|
126 |
+
hoverSet.push(roundRect,nib,text).attr({opacity: 0});
|
127 |
+
this.checkHoverPos({rect: roundRect, set: hoverSet, nib: nib});
|
128 |
+
this.globalHoverSet.push(hoverSet);
|
129 |
+
this.globalBlockSet.push(hoverbar);
|
130 |
+
if (roundRect.attrs.y < 0) {
|
131 |
+
hoverSet.translate(0, 1 - roundRect.attrs.y);
|
132 |
+
}
|
133 |
+
|
134 |
+
hoverbar.hover(function (event) {
|
135 |
+
if (horizontal_rounded) {
|
136 |
+
bargraphset.animate({fill: hover_color, stroke: hover_color}, 200);
|
137 |
+
} else {
|
138 |
+
bargraph.animate({fill: hover_color, stroke: hover_color}, 200);
|
139 |
+
}
|
140 |
+
hoverSet.animate({opacity: 1}, 200);
|
141 |
+
}, function (event) {
|
142 |
+
if (horizontal_rounded) {
|
143 |
+
bargraphset.animate({fill: color2, stroke: color2}, 200);
|
144 |
+
} else {
|
145 |
+
bargraph.animate({fill: color2, stroke: color2}, 200);
|
146 |
+
}
|
147 |
+
hoverSet.animate({opacity: 0}, 200);
|
148 |
+
});
|
149 |
+
}
|
150 |
+
y = y + this.step;
|
151 |
+
}.bind(this));
|
152 |
+
},
|
153 |
+
|
154 |
+
/* Horizontal version */
|
155 |
+
drawFocusHint: function () {
|
156 |
+
var length = 5,
|
157 |
+
x = this.x_padding_left + length * 2,
|
158 |
+
y = this.options.height - this.y_padding_bottom - length / 2;
|
159 |
+
|
160 |
+
this.paper.path()
|
161 |
+
.attr({stroke: this.options.label_color, 'stroke-width': 2})
|
162 |
+
.moveTo(x, y)
|
163 |
+
.lineTo(x - length, y + length)
|
164 |
+
.moveTo(x - length, y)
|
165 |
+
.lineTo(x - (length * 2), y + length);
|
166 |
+
},
|
167 |
+
|
168 |
+
drawVerticalLabels: function () {
|
169 |
+
var y_start = (this.step / 2),
|
170 |
+
extra_options = this.options.label_rotation ? {"text-anchor": 'end', rotation:this.options.label_rotation, translation: "0 " + this.options.font_size/2} : {"text-anchor": 'end'},
|
171 |
+
labels = this.options.labels;
|
172 |
+
|
173 |
+
if (this.options.label_max_size) {
|
174 |
+
for (var i = 0; i < labels.length; i++) {
|
175 |
+
labels[i] = labels[i].truncate(this.options.label_max_size + 1, "тАж");
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
this.drawMarkers(this.options.labels.reverse(), [0, -1], this.step, y_start, [-8, -(this.options.font_size / 5)], extra_options);
|
180 |
+
},
|
181 |
+
|
182 |
+
drawHorizontalLabels: function () {
|
183 |
+
var x_step = this.graph_width / this.y_label_count,
|
184 |
+
x_labels = this.makeValueLabels(this.y_label_count);
|
185 |
+
|
186 |
+
if (this.options.vertical_label_unit) {
|
187 |
+
for (var i = 0; i < x_labels.length; i++) {
|
188 |
+
x_labels[i] += this.options.vertical_label_unit;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
this.drawMarkers(x_labels, [1, 0], x_step, x_step, [0, (this.options.font_size + 7) * -1]);
|
192 |
+
},
|
193 |
+
|
194 |
+
drawMeanLine: function (data) {
|
195 |
+
var offset = $A(data).inject(0, function (value, sum) { return sum + value; }) / data.length;
|
196 |
+
offset = this.options.bar ? offset + (this.zero_value * (this.graph_height / this.y_label_count)) : offset;
|
197 |
+
|
198 |
+
this.paper.path()
|
199 |
+
.attr(this.options.meanline)
|
200 |
+
.moveTo(this.x_padding_left - 1 + offset, this.y_padding_top).
|
201 |
+
lineTo(this.x_padding_left - 1 + offset, this.y_padding_top + this.graph_height);
|
202 |
+
}
|
203 |
+
});
|
204 |
+
|
js/aitoc/aitloadmon/grafico.line.custom.js
ADDED
@@ -0,0 +1,138 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
3 |
+
* @license License agreement could be found at the root folder of this package
|
4 |
+
*/
|
5 |
+
Grafico.LineGraphCustom = Class.create(Grafico.BaseGraph, {
|
6 |
+
chartDefaults: function () {
|
7 |
+
return {
|
8 |
+
line: true,
|
9 |
+
start_at_zero: true,
|
10 |
+
stroke_width: 5,
|
11 |
+
curve_amount: 10
|
12 |
+
};
|
13 |
+
},
|
14 |
+
|
15 |
+
setChartSpecificOptions: function () {
|
16 |
+
},
|
17 |
+
|
18 |
+
calculateStep: function () {
|
19 |
+
return (this.graph_width - (this.options.plot_padding * 2)) / (this.data_size - 1);
|
20 |
+
},
|
21 |
+
|
22 |
+
startPlot: function (cursor, x, y, color) {
|
23 |
+
cursor.moveTo(x, y);
|
24 |
+
cursor.attr({'stroke-opacity': this.options.opacity});
|
25 |
+
|
26 |
+
},
|
27 |
+
|
28 |
+
drawPlot: function (index, cursor, x, y, color, coords, datalabel, element, graphindex) {
|
29 |
+
|
30 |
+
if(typeof lineGraphs[graphindex+1] == 'undefined')lineGraphs[graphindex+1]=[];
|
31 |
+
|
32 |
+
if (this.options.markers === 'circle') {
|
33 |
+
this.drawGraphMarkers(index, x, y, color, datalabel, element);
|
34 |
+
} else if (this.options.markers === 'value') {
|
35 |
+
this.drawGraphValueMarkers(index, x, y, color, datalabel, element, graphindex);
|
36 |
+
}
|
37 |
+
|
38 |
+
if (index === 0) {
|
39 |
+
lineGraphs[graphindex+1].push(cursor);
|
40 |
+
return this.startPlot(cursor, x - 0.5, y, color);
|
41 |
+
}
|
42 |
+
if (this.options.curve_amount) {
|
43 |
+
ww = cursor.cplineTo(x, y, this.options.curve_amount);
|
44 |
+
} else {
|
45 |
+
ww = cursor.lineTo(x, y);
|
46 |
+
|
47 |
+
}
|
48 |
+
},
|
49 |
+
|
50 |
+
drawGraphMarkers: function (index, x, y, color, datalabel, element) {
|
51 |
+
var circle = this.paper.circle(x, y, this.options.marker_size),
|
52 |
+
old_marker_size = this.options.marker_size,
|
53 |
+
color2 = this.options.hover_color || color,
|
54 |
+
new_marker_size = parseInt(1.7 * old_marker_size, 10);
|
55 |
+
|
56 |
+
circle.attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color });
|
57 |
+
this.globalMarkerSet.push(circle);
|
58 |
+
|
59 |
+
circle.hover(function (event) {
|
60 |
+
circle.animate({r: new_marker_size, fill: color2}, 200);
|
61 |
+
}, function (event) {
|
62 |
+
circle.animate({r: old_marker_size, fill: color}, 200);
|
63 |
+
});
|
64 |
+
},
|
65 |
+
|
66 |
+
drawGraphValueMarkers: function (index, x, y, color, datalabel, element, graphindex) {
|
67 |
+
index += this.options.odd_horizontal_offset>1 ? this.options.odd_horizontal_offset : 0;
|
68 |
+
index -= this.options.stacked_fill || this.options.area ? 1 : 0;
|
69 |
+
|
70 |
+
if(!this.options.label_sizes[graphindex+1][index])
|
71 |
+
{
|
72 |
+
tmpsize = 1;
|
73 |
+
}
|
74 |
+
else
|
75 |
+
{
|
76 |
+
tmpsize = this.options.label_sizes[graphindex+1][index];
|
77 |
+
}
|
78 |
+
|
79 |
+
var circle = this.paper.circle(x, y, Math.log(tmpsize));
|
80 |
+
|
81 |
+
circle.attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color, 'fill-opacity': this.options.opacity});
|
82 |
+
this.globalMarkerSet.push(circle);
|
83 |
+
|
84 |
+
lineGraphs[graphindex+1].push(circle);
|
85 |
+
|
86 |
+
var currentset = this.options.stacked ? this.real_data : this.data_sets,
|
87 |
+
currentvalue = currentset.collect(function (data_set) { return data_set[1][index]; })[graphindex];
|
88 |
+
|
89 |
+
if (currentvalue) {
|
90 |
+
currentvalue = "" + currentvalue.toString().split('.');
|
91 |
+
if (currentvalue[1]) {
|
92 |
+
currentvalue[1] = currentvalue[1].truncate(3, '');
|
93 |
+
}
|
94 |
+
}
|
95 |
+
if (
|
96 |
+
(this.options.line||this.options.stacked) || //if the option is a line graph
|
97 |
+
((this.options.stacked_fill||this.options.area) && index != -1) && //if it's stacked or an area and it's not the first
|
98 |
+
typeof currentvalue != "undefined") { //if there is a current value
|
99 |
+
|
100 |
+
var rectx = x-(this.step/2),
|
101 |
+
recty = y-[this.options.stroke_width/2, this.options.hover_radius].max(),
|
102 |
+
rectw = this.step,
|
103 |
+
recth = [this.options.stroke_width, this.options.hover_radius*2].max(),
|
104 |
+
circle = this.paper.circle(x, y, this.options.marker_size == 0 ? [this.options.stroke_width*1.5, this.step].min() : this.options.marker_size).attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color,opacity:0}),
|
105 |
+
block = this.paper.rect(rectx, recty, rectw, recth).attr({fill:color, 'stroke-width': 0, stroke : color,opacity:0});
|
106 |
+
|
107 |
+
if (this.options.datalabels) {
|
108 |
+
if(typeof(datalabel) == 'function') {
|
109 |
+
datalabel = datalabel.call(this, index, currentvalue);
|
110 |
+
} else {
|
111 |
+
datalabel = datalabel + ": " + currentvalue + " s\r\n" + "Page views: " + this.options.label_sizes[graphindex+1][index] + "\r\n" + this.options.dot_labels[index];
|
112 |
+
}
|
113 |
+
} else {
|
114 |
+
datalabel = "" + currentvalue;
|
115 |
+
}
|
116 |
+
datalabel += this.options.vertical_label_unit ? " " + this.options.vertical_label_unit : "";
|
117 |
+
|
118 |
+
var hoverSet = this.paper.set(),
|
119 |
+
textpadding = 4,
|
120 |
+
text = this.paper.text(circle.attrs.cx, circle.attrs.cy - (this.options.font_size * 1.5) -2 * textpadding, datalabel).attr({'font-size': this.options.font_size, fill:this.options.hover_text_color, opacity: 1}),
|
121 |
+
textbox = text.getBBox(),
|
122 |
+
roundRect= this.drawRoundRect(text, textbox, textpadding),
|
123 |
+
nib = this.drawNib(text, textbox, textpadding);
|
124 |
+
|
125 |
+
hoverSet.push(circle,roundRect,nib,text).attr({opacity:0});
|
126 |
+
lineGraphs[graphindex+1].push(circle,roundRect,nib,text);
|
127 |
+
this.checkHoverPos({rect:roundRect,set:hoverSet,marker:circle,nib:nib,textpadding:textpadding});
|
128 |
+
this.globalHoverSet.push(hoverSet);
|
129 |
+
this.globalBlockSet.push(block);
|
130 |
+
|
131 |
+
block.hover(function (event) {
|
132 |
+
hoverSet.animate({opacity:1},200);
|
133 |
+
}, function (event) {
|
134 |
+
hoverSet.animate({opacity:0},200);
|
135 |
+
});
|
136 |
+
}
|
137 |
+
}
|
138 |
+
});
|
js/aitoc/aitloadmon/grafico.min.js
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var Grafico={Version:"0.9.1",Base:{},BaseGraph:{},Normaliser:{},LineGraph:{},AreaGraph:{},StackGraph:{},StreamGraph:{},BarGraph:{},StackedBarGraph:{},HorizontalBarGraph:{},SparkLine:{},SparkBar:{}};
|
2 |
+
Grafico.Base=Class.create({normaliseData:function(a){return $A(a).collect(function(a){return this.normalise(a)}.bind(this))},deepCopy:function(a){var b,c,d;if(Object.prototype.toString.call(a)==="[object Array]"){b=[];d=a.length;for(c=0;c<d;c++)b[c]=arguments.callee(a[c]);return b}if(typeof a==="object"){b={};for(c in a)b[c]=arguments.callee(a[c]);return b}return a}});
|
3 |
+
Grafico.Normaliser=Class.create({initialize:function(a,b){this.options={start_value:void 0,number_of_tickmarks:10};Object.extend(this.options,b||{});this.min=a.min();this.max=a.max();this.step=this.range=this.zero_value=this.start_value=void 0;if(this.options.start_value!==void 0)this.zero_value=this.start_value=this.options.start_value;this.min==0&&this.min==this.max?(this.zero_value=this.start_value=0,this.step=this.range=1):this.looseLabels(this.start_value!==void 0&&this.min>=0?this.start_value:
|
4 |
+
this.min,this.max)},looseLabels:function(a,b){var c=this.niceNumber((a==b?this.niceNumber(Math.abs(b),!1):this.niceNumber(b-a,!1))/(this.options.number_of_tickmarks-1),!0),d=[-Math.floor(Math.LOG10E*Math.log(c)),0].max(),e=this.floorToPrecision(a/c,d)*c,f=this.ceilToPrecision(b/c,d)*c,g=this.roundToPrecision(this.niceNumber(0.5*c,!0),d);this.step=this.roundToPrecision(c,d);this.max<=0?f=[f+g,0].min():f+=g;this.min<0?e-=g:e=[e-g,0].max();a!==b&&(e=this.roundToOrigin(e,1));this.range=this.roundToPrecision(Math.abs(this.ceilToPrecision(f,
|
5 |
+
d)-this.floorToPrecision(e,d)),d);this.start_value=this.floorToPrecision(e,d);this.zero_value=this.roundToPrecision(Math.abs(e)/this.step,d)},roundToPrecision:function(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c},floorToPrecision:function(a,b){var c=Math.pow(10,b);return Math.floor(a*c)/c},ceilToPrecision:function(a,b){var c=Math.pow(10,b);return Math.ceil(a*c)/c},niceNumber:function(a,b){var c=Math.floor(Math.LOG10E*Math.log(a)),d;c=c<0?parseFloat(Math.pow(10,c).toFixed(Math.abs(c))):Math.pow(10,
|
6 |
+
c);d=a/c;return(b?d<1.5?1:d<3?2:d<7?5:10:d<=1?1:d<=2?2:d<=5?5:10)*c},roundToOrigin:function(a,b){var c=a;c=Math.pow(10,-(b||1));c=Math.round(a*c)/c;return c>this.min?this.roundToOrigin(a-this.step):c}});
|
7 |
+
Grafico.BaseGraph=Class.create(Grafico.Base,{initialize:function(a,b,c){this.options={width:parseInt(a.getStyle("width"),10),height:parseInt(a.getStyle("height"),10),grid:!0,show_vertical_grid:!0,show_horizontal_grid:!0,plot_padding:10,font_size:10,show_horizontal_labels:!0,show_vertical_labels:!0,show_ticks:!0,vertical_label_unit:"",background_color:"#fff",label_color:"#000",grid_color:"#ccc",hover_text_color:"#fff",markers:!1,marker_size:5,meanline:!1,padding_top:20,draw_axis:!0,datalabels:"",hover_color:"",
|
8 |
+
hover_radius:15,watermark:!1,watermark_location:!1,hide_empty_label_grid:!1,left_padding:!1,right_padding:!1,label_rotation:0,label_max_size:!1,focus_hint:!0,min:0,max:null,normaliser:Grafico.Normaliser};Object.extend(this.options,this.chartDefaults()||{});Object.extend(this.options,c||{});this.element=a;this.data_sets=Object.isArray(b)?new Hash({one:b}):$H(b);if(this.chartDefaults().stacked===!0)this.real_data=this.deepCopy(this.data_sets),this.data_sets=this.stackData(this.data_sets);this.flat_data=
|
9 |
+
this.data_sets.collect(function(a){return a[1]}).flatten();if(this.hasBaseLine())this.flat_data.push(this.base_line),this.flat_data=this.flat_data.flatten();this.normaliser=new this.options.normaliser(this.flat_data,this.normaliserOptions());this.label_step=this.normaliser.step;this.range=this.normaliser.range;this.start_value=this.normaliser.start_value;this.zero_value=this.normaliser.zero_value;this.data_size=this.longestDataSetLength();if(c&&c.color)c.colors={},this.data_sets.keys().each(function(a){c.colors[a]=
|
10 |
+
c.color});this.options.colors=this.makeRandomColors();this.options.labels=$A($R(1,this.data_size));Object.extend(this.options,this.chartDefaults()||{});Object.extend(this.options,c||{});this.x_padding_left=10+this.paddingLeftOffset();this.x_padding_left+=this.options.vertical_label_unit?6:0;this.x_padding_left=this.options.left_padding?this.options.left_padding:this.x_padding_left;this.x_padding_right=this.options.right_padding||this.paddingRightOffset();this.x_padding=this.x_padding_left+this.x_padding_right;
|
11 |
+
this.y_padding_top=this.options.padding_top;this.y_padding_bottom=20+this.paddingBottomOffset();this.y_padding=this.y_padding_top+this.y_padding_bottom;this.graph_width=this.options.width-this.x_padding;this.graph_height=this.options.height-this.y_padding;this.step=this.calculateStep();this.y_label_count=(this.range/this.label_step).round();if(isNaN(this.y_label_count))this.y_label_count=1,this.options.show_vertical_labels=!1;this.normaliser.min+this.y_label_count*this.normaliser.step<this.normaliser.max&&
|
12 |
+
(this.y_label_count+=1);this.value_labels=this.makeValueLabels(this.y_label_count);this.top_value=this.value_labels.last();this.grid_start_offset=-1;this.paper=new Raphael(this.element,this.options.width,this.options.height);this.background=this.paper.rect(this.x_padding_left,this.y_padding_top,this.graph_width,this.graph_height);this.background.attr({fill:this.options.background_color,stroke:"none"});this.options.meanline=this.options.meanline===!0?{"stroke-width":"2px",stroke:"#BBBBBB"}:this.options.meanline;
|
13 |
+
this.globalMarkerSet=this.paper.set();this.globalHoverSet=this.paper.set();this.globalBlockSet=this.paper.set();this.globalAreaLineSet=this.paper.set();this.setChartSpecificOptions();this.draw();this.globalAreaLineSet.toFront();this.globalMarkerSet.toFront();this.globalHoverSet.toFront();this.globalBlockSet.toFront()},normaliserOptions:function(){return{graph_height:parseInt(this.element.getStyle("height"),10)}},hasBaseLine:function(){return!1},getNormalizedBaseLine:function(){if(this.normalized_base_line==
|
14 |
+
void 0)this.normalized_base_line=this.normaliseData(this.base_line);return this.normalized_base_line},getNormalizedRealData:function(){if(this.normalized_real_data==void 0)this.normalized_real_data=this.real_data.collect(function(a){return this.normaliseData(a[1])}.bind(this));return this.normalized_real_data},chartDefaults:function(){},drawPlot:function(){},calculateStep:function(){},getMousePos:function(a){var b=0,c=0;if(!a)a=window.event;if(a.pageX||a.pageY)b=a.pageX,c=a.pageY;else if(a.clientX||
|
15 |
+
a.clientY)b=a.clientX+document.body.scrollLeft-document.documentElement.scrollLeft,c=a.clientY+document.body.scrollTop-document.documentElement.scrollTop;return{x:b,y:c}},makeRandomColors:function(){var a={},b=1/this.data_sets.size(),c=Math.random();this.data_sets.each(function(d){a[d[0]]=Raphael.hsb2rgb(c,0.85,0.75).hex;c=(c+b)%1});return a},longestDataSetLength:function(){var a=0;this.data_sets.each(function(b){a=b[1].length>a?b[1].length:a});return a},roundValue:function(a,b){var c=Math.pow(10,
|
16 |
+
b);a*=c;return a=Math.round(a)/c},roundValues:function(a,b){return $A(a).collect(function(a){return this.roundValue(a,b)}.bind(this))},paddingLeftOffset:function(){var a=0;if(this.options.show_vertical_labels)a=this.flat_data,a=this.roundValues(a,2),a=$A(a).max(function(a){return a.toString().length}),a=(a>2?a-1:a)*this.options.font_size;return a},paddingRightOffset:function(){return 20},paddingBottomOffset:function(){return this.options.font_size},normalise:function(a){var b=this.start_value===0?
|
17 |
+
this.top_value:this.range;b===0&&(b=1);return a/b*this.graph_height},draw:function(){this.options.grid&&this.drawGrid();this.options.watermark&&this.drawWatermark();this.options.show_vertical_labels&&this.drawVerticalLabels();this.options.show_horizontal_labels&&this.drawHorizontalLabels();this.options.watermark||this.drawLinesInit(this);this.options.draw_axis&&this.drawAxis();this.start_value!==0&&this.options.focus_hint&&this.drawFocusHint();this.options.meanline&&this.drawMeanLine(this.normaliseData(this.flat_data))},
|
18 |
+
drawLinesInit:function(a){a.data_sets.each(function(b,c){a.drawLines(b[0],a.options.colors[b[0]],a.normaliseData(b[1]),a.options.datalabels[b[0]],a.element,c)}.bind(a))},drawWatermark:function(){var a=this.options.watermark,b=new Image,c=this;b.onload=function(){var a,e;c.options.watermark_location==="middle"?(a=(c.graph_width-b.width)/2+c.x_padding_left,e=(c.graph_height-b.height)/2+c.y_padding_top):(a=c.graph_width-b.width+c.x_padding_left-2,e=c.graph_height-b.height+c.y_padding_top-2);a=c.paper.image(b.src,
|
19 |
+
a,e,b.width,b.height).attr({opacity:"0.4"});c.drawLinesInit(c,c.data);(c.options.stacked_fill||c.options.area)&&a.toFront()};b.src=a.src||a},drawGrid:function(){var a=this.paper.path().attr({stroke:this.options.grid_color}),b,c,d;if(this.options.show_horizontal_grid){b=this.graph_height+this.y_padding_top;for(d=0;d<this.y_label_count+1;d++)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5),b-=this.graph_height/this.y_label_count}if(this.options.show_vertical_grid){b=
|
20 |
+
this.x_padding_left+this.options.plot_padding+this.grid_start_offset;c=this.options.labels.length;for(d=0;d<c;d++){if(this.options.hide_empty_label_grid===!0&&this.options.labels[d]!==""||this.options.hide_empty_label_grid===!1)a.moveTo(parseInt(b,10),this.y_padding_top),a.lineTo(parseInt(b,10),this.y_padding_top+this.graph_height);b+=this.step}}},drawLines:function(a,b,c,d,e,f){var g=this.calculateCoords(c),h=this.graph_height+this.y_padding_top,i,j,k;if(this.options.start_at_zero===!1)k=0,$A(g).each(function(a){if(a[1]===
|
21 |
+
h)k++;else throw $break;}),this.options.odd_horizontal_offset=k,this.options.odd_horizontal_offset>1&&g.splice(0,this.options.odd_horizontal_offset);this.options.stacked_fill||this.options.area?(this.options.area?(a=this.options.area_opacity?this.options.area_opacity:1.5/this.data_sets.collect(function(a){return a.length}).length,i=this.paper.path().attr({stroke:b,fill:b,"stroke-width":"0",opacity:a,"stroke-opacity":0})):i=this.paper.path().attr({stroke:b,fill:b,"stroke-width":"0"}),this.hasBaseLine()||
|
22 |
+
(g.unshift([g[0][0],h]),g.push([g[g.length-1][0],h]))):i=this.paper.path().attr({stroke:b,"stroke-width":this.options.stroke_width+"px"});$A(g).each(function(a,c){var h=a[0],j=a[1];b instanceof Array?this.drawPlot(c,i,h,j,b[c%b.length],g,d,e,f):this.drawPlot(c,i,h,j,b,g,d,e,f)}.bind(this));this.options.area&&this.options.stroke_width>0&&(j=this.paper.path().attr({stroke:b,"stroke-width":this.options.stroke_width+"px"}),g.remove(0),g.remove(-1),$A(g).each(function(a,c){this.drawPlot(c,j,a[0],a[1],
|
23 |
+
b,g,d,e,f,!0)}.bind(this)),this.globalAreaLineSet.push(j));this.options.datalabels&&this.options.draw_hovers&&(this.drawHover(i,d,e,b),this.globalHoverSet.toFront())},calculateCoords:function(a){var b=this.x_padding_left+this.options.plot_padding-this.step,c=this.graph_height+this.y_padding_top+this.normalise(this.start_value);a=$A(a).collect(function(a){b+=this.step;return[b,c-a]}.bind(this));if(!this.hasBaseLine())return a;b+=this.step;for(var d=this.getNormalizedBaseLine(),e=d.length-1;e>=0;e--)b-=
|
24 |
+
this.step,a.push([b,c-d[e]]);return a},drawFocusHint:function(){var a=this.x_padding_left+2.5-1,b=this.options.height-this.y_padding_bottom,c=this.paper.path().attr({stroke:this.options.label_color,"stroke-width":2});c.moveTo(a,b);c.lineTo(a-5,b-5);c.moveTo(a,b-5);c.lineTo(a-5,b-10)},drawMeanLine:function(a){var b=this.paper.path().attr(this.options.meanline);a=$A(a).inject(0,function(a,b){return b+a})/a.length-0.5;a=this.options.bar?a+this.zero_value*(this.graph_height/this.y_label_count):a;b.moveTo(this.x_padding_left-
|
25 |
+
1,this.options.height-this.y_padding_bottom-a).lineTo(this.graph_width+this.x_padding_left,this.options.height-this.y_padding_bottom-a)},drawAxis:function(){var a=this.paper.path().attr({stroke:this.options.label_color});a.moveTo(parseInt(this.x_padding_left,10)-0.5,this.options.height-parseInt(this.y_padding_bottom,10)+0.5);a.lineTo(parseInt(this.graph_width+this.x_padding_left,10)-0.5,this.options.height-parseInt(this.y_padding_bottom,10)+0.5);a.moveTo(parseInt(this.x_padding_left,10)-0.5,parseInt(this.options.height-
|
26 |
+
this.y_padding_bottom,10)+0.5);a.lineTo(parseInt(this.x_padding_left,10)-0.5,parseInt(this.y_padding_top,10))},makeValueLabels:function(a){for(var b=this.label_step,c=this.start_value,d=[],e=0;e<a;e++)c=this.roundValue(c+b,3),d.push(c);return d},drawMarkers:function(a,b,c,d,e,f){var g=parseInt(this.x_padding_left,10)-0.5+d*b[0],h=this.options.height-this.y_padding_bottom+d*b[1],i=this.paper.path().attr({stroke:this.options.label_color}),j={font:this.options.font_size+'px "Arial"',stroke:"none",fill:this.options.label_color};
|
27 |
+
Object.extend(j,f||{});a.each(function(a){if(this.options.draw_axis&&(this.options.hide_empty_label_grid===!0&&a!==""||this.options.hide_empty_label_grid===!1)&&this.options.show_ticks)i.moveTo(parseInt(g,10),parseInt(h,10)+0.5),i.lineTo(parseInt(g,10)+5*b[1],parseInt(h,10)+0.5+5*b[0]);a!==""&&this.paper.text(g+e[0],h-2-e[1],a.toString()).attr(j);g+=c*b[0];h+=c*b[1]}.bind(this))},drawVerticalLabels:function(){for(var a=this.graph_height/this.y_label_count,b=this.options.vertical_label_unit?" "+this.options.vertical_label_unit:
|
28 |
+
"",c=0;c<this.value_labels.length;c++)this.value_labels[c]+=b;this.drawMarkers(this.value_labels,[0,-1],a,a,[-8,-2],{"text-anchor":"end"})},drawHorizontalLabels:function(){var a=this.options.label_rotation?{rotation:this.options.label_rotation,translation:-this.options.font_size+" 0"}:{},b=this.options.labels;if(this.options.label_max_size)for(var c=0;c<b.length;c++)b[c]=b[c].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(b,[1,0],this.step,this.options.plot_padding,[0,(this.options.font_size+
|
29 |
+
7)*-1],a)},drawHover:function(a,b,c,d){var e=this,f=this.options.stacked_fill||this.options.area?"fill":"stroke",g=this.options.hover_color||d,h=this.paper.set();b=this.paper.text(a.attrs.x,a.attrs.y-this.options.font_size*1.5-4,b).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var i=b.getBBox(),j=this.drawRoundRect(b,i,4);h.push(j,b).attr({opacity:0});this.checkHoverPos({rect:j,set:h});this.globalHoverSet.push(h);a.hover(function(b){f==="fill"?a.animate({fill:g,
|
30 |
+
stroke:g},200):a.animate({stroke:g},200);b=e.getMousePos(b);h[0].attr({x:b.x-i.width/2-4-c.offsetLeft,y:b.y-i.height/2-e.options.font_size*1.5-4-c.offsetTop,opacity:1});h[1].attr({x:b.x-c.offsetLeft,y:b.y-e.options.font_size*1.5-c.offsetTop,opacity:1});a.mousemove(function(a){a=e.getMousePos(a);h[0].attr({x:a.x-i.width/2-4-c.offsetLeft,y:a.y-i.height/2-e.options.font_size*1.5-4-c.offsetTop,opacity:1});h[1].attr({x:a.x-c.offsetLeft,y:a.y-e.options.font_size*1.5-c.offsetTop,opacity:1});e.checkHoverPos(j,
|
31 |
+
h)})},function(){f==="fill"?a.animate({fill:d,stroke:d},200):a.animate({stroke:d},200);h.attr({opacity:0})})},checkHoverPos:function(a){var b,c,d,e,f,g;if(a.rect)c=a.rect,d=c.getBBox();if(a.set)e=a.set;if(a.marker)f=a.marker;if(a.nib)g=a.nib;if(a.textpadding)b=a.textpadding;if(c&&e){if(c.attrs.y<0)g&&f?(a=e.getBBox(),e.translate(0,a.height+b*2),f.translate(0,-a.height-b*2),g.translate(0,-d.height-b+1.5).scale(1,-1)):(b=c.attrs.y,e.translate(0,1-b));c.attrs.y+d.height>this.options.height&&(b=c.attrs.y+
|
32 |
+
d.height-this.options.height,e.translate(0,-b-1),f&&f.translate(0,b+1));if(c.attrs.x<0)b=c.attrs.x,e.translate(-b+1,0),g&&g.translate(b-1,0),f&&f.translate(b-1,0);c.attrs.x+d.width>this.options.width&&(b=c.attrs.x+d.width-this.options.width,e.translate(-b-1,0),g&&g.translate(b+1,0),f&&f.translate(b+1,0))}},drawNib:function(a,b,c){return this.paper.path().attr({fill:this.options.label_color,opacity:1,stroke:this.options.label_color,"stroke-width":"0px"}).moveTo(a.attrs.x-c,a.attrs.y+b.height/2+c-1).lineTo(a.attrs.x,
|
33 |
+
a.attrs.y+b.height/2+c*2).lineTo(a.attrs.x+c,a.attrs.y+b.height/2+c-1).andClose()},drawRoundRect:function(a,b,c){return this.paper.rect(a.attrs.x-b.width/2-c,a.attrs.y-b.height/2-c,b.width+c*2,b.height+c*2,c*1.5).attr({fill:this.options.label_color,opacity:1,stroke:this.options.label_color,"stroke-width":"0px"})}});Array.prototype.sum=function(){for(var a=0,b=0;a<this.length;b+=this[a++]);return b};
|
34 |
+
if(typeof Array.prototype.max==="undefined")Array.prototype.max=function(){return Math.max.apply({},this)};if(typeof Array.prototype.min==="undefined")Array.prototype.min=function(){return Math.min.apply({},this)};Array.prototype.mean=function(){return this.sum()/this.length};Array.prototype.variance=function(){for(var a=this.mean(),b=0,c=0;c<this.length;c++)b+=Math.pow(this[c]-a,2);return b/(this.length-1)};Array.prototype.standard_deviation=function(){return Math.sqrt(this.variance())};
|
35 |
+
Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};Raphael.el.isAbsolute=!0;Raphael.el.absolutely=function(){this.isAbsolute=1;return this};Raphael.el.relatively=function(){this.isAbsolute=0;return this};Raphael.el.moveTo=function(a,b){this._last={x:a,y:b};return this.attr({path:this.attrs.path+["m","M"][+this.isAbsolute]+parseFloat(a)+" "+parseFloat(b)})};
|
36 |
+
Raphael.el.lineTo=function(a,b){this._last={x:a,y:b};return this.attr({path:this.attrs.path+["l","L"][+this.isAbsolute]+parseFloat(a)+" "+parseFloat(b)})};Raphael.el.cplineTo=function(a,b,c){a>this._last.x?this.attr({path:this.attrs.path+["C",this._last.x+c,this._last.y,a-c,b,a,b]}):a==this._last.x?this.lineTo(a,b):this.attr({path:this.attrs.path+["C",this._last.x-c,this._last.y,a+c,b,a,b]});this._last={x:a,y:b};return this};Raphael.el.andClose=function(){return this.attr({path:this.attrs.path+"z"})};
|
37 |
+
Grafico.LineGraph=Class.create(Grafico.BaseGraph,{chartDefaults:function(){return{line:!0,start_at_zero:!0,stroke_width:5,curve_amount:10}},setChartSpecificOptions:function(){},calculateStep:function(){return(this.graph_width-this.options.plot_padding*2)/(this.data_size-1)},startPlot:function(a,b,c){a.moveTo(b,c)},drawPlot:function(a,b,c,d,e,f,g,h,i){if(a===0)return this.startPlot(b,c-0.5,d,e);this.options.curve_amount?b.cplineTo(c,d,this.options.curve_amount):b.lineTo(c,d);this.options.markers===
|
38 |
+
"circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&this.drawGraphValueMarkers(a,c,d,e,g,h,i)},drawGraphMarkers:function(a,b,c,d){var e=this.paper.circle(b,c,this.options.marker_size),f=this.options.marker_size,g=this.options.hover_color||d,h=parseInt(1.7*f,10);e.attr({"stroke-width":"1px",stroke:this.options.background_color,fill:d});this.globalMarkerSet.push(e);e.hover(function(){e.animate({r:h,fill:g},200)},function(){e.animate({r:f,fill:d},200)})},drawGraphValueMarkers:function(a,
|
39 |
+
b,c,d,e,f,g){a+=this.options.odd_horizontal_offset>1?this.options.odd_horizontal_offset:0;a-=this.options.stacked_fill||this.options.area?1:0;if(f=(this.options.stacked?this.real_data:this.data_sets).collect(function(b){return b[1][a]})[g])f=""+f.toString().split("."),f[1]&&(f[1]=f[1].truncate(3,""));if(this.options.line||this.options.stacked||(this.options.stacked_fill||this.options.area)&&a!=-1&&typeof f!="undefined"){g=b-this.step/2;var h=c-[this.options.stroke_width/2,this.options.hover_radius].max(),
|
40 |
+
i=this.step,j=[this.options.stroke_width,this.options.hover_radius*2].max();b=this.paper.circle(b,c,this.options.marker_size==0?[this.options.stroke_width*1.5,this.step].min():this.options.marker_size).attr({"stroke-width":"1px",stroke:this.options.background_color,fill:d,opacity:0});d=this.paper.rect(g,h,i,j).attr({fill:d,"stroke-width":0,stroke:d,opacity:0});e=this.options.datalabels?typeof e=="function"?e.call(this,a,f):e+": "+f:""+f;e+=this.options.vertical_label_unit?" "+this.options.vertical_label_unit:
|
41 |
+
"";var k=this.paper.set();e=this.paper.text(b.attrs.cx,b.attrs.cy-this.options.font_size*1.5-8,e).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});f=e.getBBox();c=this.drawRoundRect(e,f,4);f=this.drawNib(e,f,4);k.push(b,c,f,e).attr({opacity:0});this.checkHoverPos({rect:c,set:k,marker:b,nib:f,textpadding:4});this.globalHoverSet.push(k);this.globalBlockSet.push(d);d.hover(function(){k.animate({opacity:1},200)},function(){k.animate({opacity:0},200)})}}});
|
42 |
+
Grafico.AreaGraph=Class.create(Grafico.LineGraph,{chartDefaults:function(){return{area:!0,area_opacity:!1,stroke_width:0,curve_amount:10}},drawPlot:function(a,b,c,d,e,f,g,h,i,j){var k=this.options.area||this.options.stacked_fill;j||(k===!0?a!==0&&a!==f.length-1&&(this.options.markers==="circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&this.drawGraphValueMarkers(a,c,d,e,g,h,i)):this.options.markers==="circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&
|
43 |
+
this.drawGraphValueMarkers(a,c,d,e,g,h,i));c-=0.5;if(a===0)return this.startPlot(b,c,d,e);this.options.curve_amount&&a>1&&a<f.length-1?b.cplineTo(c,d,this.options.curve_amount):this.options.curve_amount&&!k?b.cplineTo(c,d,this.options.curve_amount):b.lineTo(c,d)}});
|
44 |
+
Grafico.StackGraph=Class.create(Grafico.AreaGraph,{chartDefaults:function(){return{stacked:!0,stacked_fill:!0,stroke_width:0,curve_amount:10}},setChartSpecificOptions:function(){if(!this.options.stacked_fill)this.options.stroke_width=5},stackData:function(a){for(var b=a.collect(function(a){return a[1]}),c=b.length-2;c>=0;c--)for(var d=0;d<b[0].length;d++)b[c][d]+=b[c+1][d];return a}});
|
45 |
+
Grafico.StreamGraph=Class.create(Grafico.StackGraph,{chartDefaults:function(){return{stacked:!0,stacked_fill:!0,stroke_width:5,grid:!1,draw_axis:!1,show_horizontal_labels:!1,show_vertical_labels:!1,stream:!0,stream_line_smoothing:!1,stream_smart_insertion:!1,curve_amount:4,stream_label_threshold:0}},hasBaseLine:function(){return!0},calcBaseLine:function(a){var b=a.collect(function(a){return a[1]});a=[];var c,d;for(d=0;d<b[0].length;d++){for(c=sum=0;c<b.length;c++)sum+=this.options.stream_line_smoothing==
|
46 |
+
!1?b[c][d]:(c+1)*b[c][d];a[d]=this.options.stream_line_smoothing==!1?-sum/2:-sum/(b.length+1)}b=a.min();for(c=0;c<a.length;c++)a[c]-=b;this.base_line=a},stackData:function(a){var b,c;if(this.options.stream_smart_insertion){a=$A(a);a.each(function(a){for(b=0;b<a[1].length&&a[1][b]<=1.0E-7;)b++;a[2]=b});var d=[],e=!1;a.sortBy(function(a){return a[2]}).each(function(a){e?d.push(a):d.unshift(a);e=!e});a=$H();d.each(function(b){a.set(b[0],b[1])})}this.real_data=this.deepCopy(a);this.calcBaseLine(a);var f=
|
47 |
+
a.collect(function(a){return a[1]});for(c=0;c<f[0].length;c++)f[f.length-1][c]+=this.base_line[c];for(b=f.length-2;b>=0;b--)for(c=0;c<f[0].length;c++)f[b][c]+=f[b+1][c];return a},drawPlot:function(a,b,c,d,e,f,g,h,i,j){if(this.options.datalabels&&!j){j=this.getNormalizedRealData();var k=this.bestMarkerPositions();a<f.length/2&&k[i]>=a&&k[i]<a+1&&this.drawStreamMarker(a+1,c+(k[i]-a)*this.step,d+j[i][a]/2,e,g,h)}c-=0.5;if(a===0)return this.startPlot(b,c,d,e);b.cplineTo(c,d,this.options.curve_amount)},
|
48 |
+
bestMarkerPositions:function(){if(this.best_marker_positions==void 0)this.best_marker_positions=this.real_data.collect(function(a){for(var b=-1,c=0,d=0,e=0;e<a[1].length;e++){var f=a[1][e];f>c&&f>=this.options.stream_label_threshold?(c=f,b=e,d=0):f==c&&c>0&&d++}return b+d/2}.bind(this));return this.best_marker_positions},drawStreamMarker:function(a,b,c,d,e){this.options.datalabels&&(a=this.paper.set(),b=this.paper.text(b,c-8+this.options.font_size/2,e).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,
|
49 |
+
opacity:1}),c=b.getBBox(),c=this.drawRoundRect(b,c,4),a.push(c,b),this.checkHoverPos({rect:c,set:a,textpadding:4}),this.globalHoverSet.push(a))}});
|
50 |
+
Grafico.BarGraph=Class.create(Grafico.BaseGraph,{chartDefaults:function(){return{bar:!0,plot_padding:0,bargraph_lastcolor:!1,bargraph_negativecolor:!1}},normaliserOptions:function(){return{start_value:0,bar:!0}},setChartSpecificOptions:function(){this.bar_padding=5;this.bar_width=this.calculateBarWidth();this.options.plot_padding=this.bar_width/2;this.step=this.calculateStep();this.grid_start_offset=this.bar_padding-1},calculateBarWidth:function(){return this.graph_width/this.data_size-this.bar_padding},
|
51 |
+
calculateStep:function(){this.data_size=this.data_size==1?2:this.data_size;return(this.graph_width-this.options.plot_padding*2-this.bar_padding*2)/(this.data_size-1)},longestDataSetLength:function(){var a=0;this.data_sets.each(function(b){a=b[1].length>a?b[1].length:a});return a},drawPlot:function(a,b,c,d,e,f,g){b=this.options.height-this.y_padding_bottom-this.zero_value*(this.graph_height/this.y_label_count);var h=this.options.bargraph_lastcolor,i=this.options.bargraph_negativecolor||e;c+=this.bar_padding;
|
52 |
+
d=b-d;e=h&&a===f.length-1?h:d<0?i:e;f=this.paper.rect(c-this.bar_width/2,b,this.bar_width,d).attr({fill:e,"stroke-width":this.options.stroke_width,stroke:e,"stroke-opacity":0});d<0?f.attr({height:-f.attrs.height}):f.translate(0,-d);this.options.datalabels&&this.drawGraphValueMarkers(c,a,f,g,e);this.options.count++},drawHorizontalLabels:function(){var a=this.bar_padding+this.options.plot_padding,b=this.options.label_rotation?{rotation:this.options.label_rotation,translation:-this.options.font_size+
|
53 |
+
" 0"}:{},c=this.options.labels;if(this.options.label_max_size)for(var d=0;d<c.length;d++)c[d]=c[d].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(this.options.labels,[1,0],this.step,a,[0,(this.options.font_size+7)*-1],b)},drawGrid:function(){var a=this.paper.path().attr({stroke:this.options.grid_color,"stroke-width":1}),b=this.graph_height+this.y_padding_top,c,d;if(this.options.horizontalbar)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-
|
54 |
+
0.5,parseInt(b,10)+0.5),b-=this.graph_height,a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5);else if(this.options.show_horizontal_grid)for(var e=0;e<this.y_label_count+1;e++)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5),b-=this.graph_height/this.y_label_count;if(this.options.horizontalbar){b=this.x_padding_left+this.options.plot_padding+this.grid_start_offset;
|
55 |
+
c=this.y_label_count;d=this.options.horizontalbar?this.graph_width/this.y_label_count:this.step;for(e=0;e<c;e++){if(this.options.hide_empty_label_grid===!0&&this.options.labels[e]!==""||this.options.hide_empty_label_grid===!1)a.moveTo(parseInt(b,10)+0.5,this.y_padding_top),a.lineTo(parseInt(b,10)+0.5,this.y_padding_top+this.graph_height);b+=d}}a.moveTo(parseInt(this.x_padding_left,10)-0.5,this.y_padding_top);a.lineTo(parseInt(this.x_padding_left,10)-0.5,this.y_padding_top+this.graph_height);a.moveTo(parseInt(this.x_padding_left+
|
56 |
+
this.graph_width,10)-0.5,this.y_padding_top);a.lineTo(parseInt(this.x_padding_left+this.graph_width,10)-0.5,this.y_padding_top+this.graph_height)},drawGraphValueMarkers:function(a,b,c,d,e){var f=this.options.hover_color||e,g=this.paper.set();a=this.paper.rect(a-this.bar_width/2,this.y_padding_top,this.bar_width,this.options.height).attr({fill:e,"stroke-width":0,stroke:e,opacity:0});if(d=d&&d[b]?d[b].toString():""){b=this.paper.text(c.attrs.x+this.bar_width/2,c.attrs.y-this.options.font_size*1.5,d);
|
57 |
+
b.attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var h=b.getBBox();d=this.drawRoundRect(b,h,4);h=this.drawNib(b,h,4);g.push(d,h,b).attr({opacity:0});this.checkHoverPos({rect:d,set:g,nib:h});this.globalHoverSet.push(g);this.globalBlockSet.push(a);d.attrs.y<0&&g.translate(0,1+d.attrs.y*-1);a.hover(function(){c.animate({fill:f,stroke:f},200);g.animate({opacity:1},200)},function(){c.animate({fill:e,stroke:e},200);g.animate({opacity:0},200)})}}});
|
58 |
+
Grafico.StackedBarGraph=Class.create(Grafico.BarGraph,{chartDefaults:function(){return{opacity:100,bar:!0,plot_padding:0,stacked:!0,stacked_fill:!0}},setChartSpecificOptions:function(){this.bar_padding=5;this.bar_width=this.calculateBarWidth();this.options.plot_padding=this.bar_width/2;this.step=this.calculateStep();this.grid_start_offset=this.bar_padding-1;this.options.stroke_width=1},stackData:function(a){for(var b=a.collect(function(a){return a[1]}),c=b.length-2;c>=0;c--)for(var d=0;d<b[0].length;d++)b[c][d]+=
|
59 |
+
b[c+1][d];return a},calculateCoords:function(a){var b=this.x_padding_left+this.options.plot_padding-this.step,c=this.graph_height+this.y_padding_top+this.normalise(this.start_value);a=$A(a).collect(function(a){b+=this.step;return[b,c-a]}.bind(this));b+=this.step;for(var d=this.getNormalizedBaseLine(),e=d.length-1;e>=0;e--)b-=this.step,a.push([b,c-d[e]]);return a},drawLines:function(a,b,c,d,e,f){var g=this.calculateCoords(c),h;h=this.paper.path().attr({stroke:b,"stroke-width":0});$A(g).each(function(a,
|
60 |
+
c){this.drawPlot(c,h,a[0],a[1],b,g,d,e,f)}.bind(this));this.options.datalabels&&this.options.draw_hovers&&(this.drawHover(h,d,e,b),this.globalHoverSet.toFront())},drawPlot:function(a,b,c,d,e,f,g){b=this.options.height-this.y_padding_bottom-this.zero_value*(this.graph_height/this.y_label_count);c+=this.bar_padding;d=this.options.height-this.y_padding_bottom-d-this.zero_value*(this.graph_height/this.y_label_count);f={fill:e,"stroke-width":0,stroke:this.options.color2,opacity:this.options.opacity};b=
|
61 |
+
this.paper.rect(c-this.bar_width/2,b,this.bar_width,d).attr(f);d<0?b.attr({height:-b.attrs.height}):b.translate(0,-d);this.options.datalabels&&this.drawGraphValueMarkers(c,a,b,g,e);this.options.count++},drawGraphValueMarkers:function(a,b,c,d,e){a-=this.bar_width/2;var f=c.attrs.y,g=this.bar_width,h=c.attrs.height,i=this.options.hover_color||e,j=this.paper.set();a=this.paper.rect(a,f,g,h);d=d&&d.length>b?d[b].toString():"";b=this.paper.text(c.attrs.x+this.bar_width/2,c.attrs.y-this.options.font_size*
|
62 |
+
1.5,d);a.attr({fill:e,"stroke-width":0,stroke:e,opacity:0});b.attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});f=b.getBBox();d=this.drawRoundRect(b,f,4);f=this.drawNib(b,f,4);j.push(d,f,b).attr({opacity:0});this.checkHoverPos({rect:d,set:j,nib:f});this.globalHoverSet.push(j);this.globalBlockSet.push(a);d.attrs.y<0&&j.translate(0,1+d.attrs.y*-1);a.hover(function(){c.animate({fill:i},200);j.animate({opacity:1},200)},function(){c.animate({fill:e},200);j.animate({opacity:0},
|
63 |
+
200)})}});
|
64 |
+
Grafico.HorizontalBarGraph=Class.create(Grafico.BarGraph,{chartDefaults:function(){return{bar:!0,horizontalbar:!0,plot_padding:0,horizontal_rounded:!1,bargraph_lastcolor:!1}},setChartSpecificOptions:function(){this.x_padding_left=20+this.longestLabel()*(this.options.font_size/2);this.bar_padding=5;this.bar_width=this.calculateBarHeight();this.step=this.calculateStep();this.graph_width=this.options.width-this.x_padding_right-this.x_padding_left},normalise:function(a){var b=this.makeValueLabels(this.y_label_count);b=
|
65 |
+
b[b.length-1];return a/b*this.graph_width},longestLabel:function(){return $A(this.options.labels).sort(function(a,b){return a.toString().length<b.toString().length}).first().toString().length},calculateBarHeight:function(){return this.graph_height/this.data_size-this.bar_padding},calculateStep:function(){return(this.graph_height-this.options.plot_padding*2)/this.data_size},drawLines:function(a,b,c,d){var e=this.y_padding_top+this.bar_padding/2-0.5,f=this.zero_value*(this.graph_width/this.y_label_count),
|
66 |
+
g=this.x_padding_left+f-0.5,h=this.options.bargraph_lastcolor,i=this.options.bargraph_negativecolor||b;this.datalabel=d;$A(c).each(function(a,d){var l,q=this.options.horizontal_rounded?this.bar_width/2:0,n;l=h&&d===c.length-1?h:a<0?i:b;a=a/this.graph_width*(this.graph_width-f);n=this.paper.rect(g,e,a,this.bar_width,q).attr({fill:l,"stroke-width":0,stroke:l,"stroke-opacity":0});a<0&&n.attr({width:-n.attrs.width}).translate(a,0);if(q){var t=this.paper.set(),m=this.paper.rect(g,e,a-this.bar_width/2,
|
67 |
+
this.bar_width).attr({fill:l,"stroke-width":0,stroke:l,"stroke-opacity":0});t.push(m,n);a<0&&m.attr({width:-m.attrs.width-this.bar_width}).translate(a+this.bar_width/2,0)}if(this.options.datalabels){var r=this.options.hover_color||l,o=this.paper.set();m=this.paper.text(f+a+this.x_padding_left/2,n.attrs.y-this.options.font_size*1.5,this.datalabel[d].toString()).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var u=this.paper.rect(this.x_padding_left,e,this.graph_width,
|
68 |
+
this.bar_width).attr({fill:l,"stroke-width":0,stroke:l,opacity:0}),p=m.getBBox();a<0&&m.translate(p.width,0);var s=this.drawRoundRect(m,p,4);p=this.drawNib(m,p,4);o.push(s,p,m).attr({opacity:0});this.checkHoverPos({rect:s,set:o,nib:p});this.globalHoverSet.push(o);this.globalBlockSet.push(u);s.attrs.y<0&&o.translate(0,1-s.attrs.y);u.hover(function(){q?t.animate({fill:r,stroke:r},200):n.animate({fill:r,stroke:r},200);o.animate({opacity:1},200)},function(){q?t.animate({fill:l,stroke:l},200):n.animate({fill:l,
|
69 |
+
stroke:l},200);o.animate({opacity:0},200)})}e+=this.step}.bind(this))},drawFocusHint:function(){var a=this.x_padding_left+10,b=this.options.height-this.y_padding_bottom-2.5;this.paper.path().attr({stroke:this.options.label_color,"stroke-width":2}).moveTo(a,b).lineTo(a-5,b+5).moveTo(a-5,b).lineTo(a-10,b+5)},drawVerticalLabels:function(){var a=this.step/2,b=this.options.label_rotation?{"text-anchor":"end",rotation:this.options.label_rotation,translation:"0 "+this.options.font_size/2}:{"text-anchor":"end"},
|
70 |
+
c=this.options.labels;if(this.options.label_max_size)for(var d=0;d<c.length;d++)c[d]=c[d].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(this.options.labels.reverse(),[0,-1],this.step,a,[-8,-(this.options.font_size/5)],b)},drawHorizontalLabels:function(){var a=this.graph_width/this.y_label_count,b=this.makeValueLabels(this.y_label_count);if(this.options.vertical_label_unit)for(var c=0;c<b.length;c++)b[c]+=this.options.vertical_label_unit;this.drawMarkers(b,[1,0],a,a,[0,(this.options.font_size+
|
71 |
+
7)*-1])},drawMeanLine:function(a){a=$A(a).inject(0,function(a,c){return c+a})/a.length;a=this.options.bar?a+this.zero_value*(this.graph_height/this.y_label_count):a;this.paper.path().attr(this.options.meanline).moveTo(this.x_padding_left-1+a,this.y_padding_top).lineTo(this.x_padding_left-1+a,this.y_padding_top+this.graph_height)}});
|
72 |
+
Grafico.SparkLine=Class.create(Grafico.Base,{initialize:function(a,b,c){this.element=a;this.data=b;this.options={highlight:!1,stroke_width:1,color:this.makeRandomcolor(),width:parseInt(a.getStyle("width"),10),height:parseInt(a.getStyle("height"),10),acceptable_range:!1,zeroline:!1};Object.extend(this.options,c||{});this.step=this.calculateStep();this.paper=new Raphael(this.element,this.options.width,this.options.height);this.drawBackground();this.draw()},drawBackground:function(){this.background=
|
73 |
+
this.options.acceptable_range?this.paper.rect(0,this.options.height-this.normalise(this.options.acceptable_range[1]),this.options.width,this.normalise(this.options.acceptable_range[1])-this.normalise(this.options.acceptable_range[0])):this.paper.rect(0,0,this.options.width,this.options.height);this.background.attr({fill:this.options.background_color,stroke:"none"})},calculateStep:function(){return this.options.width/(this.data.length-1)},makeRandomcolor:function(){return Raphael.hsb2rgb(Math.random(),
|
74 |
+
1,0.75).hex},normalise:function(a){var b=this.data.min()<0?this.data.max()-this.data.min():this.data.max();a-=this.data.min()<0?this.data.min():0;return a/b*this.options.height},draw:function(){var a=this.normaliseData(this.data),b;if(this.options.zeroline&&this.data.min()<0)this.options.zeroline=this.options.zeroline===!0?{"stroke-width":"1px",stroke:"#BBBBBB"}:this.options.zeroline,b=parseInt(this.options.height-this.normalise(0),10),this.paper.path().attr(this.options.zeroline).moveTo(0,b).lineTo(this.options.width,
|
75 |
+
b);this.drawLines(this.options.color,a);this.options.highlight&&this.showHighlight(a)},drawLines:function(a,b){var c=this.paper.path().attr({stroke:a,"stroke-width":this.options.stroke_width}).moveTo(0,this.options.height-b.first()),d=0,e=this.data.min()<0?this.options.stroke_width:0;b.slice(1).each(function(a){d+=this.step;c.lineTo(d,this.options.height-a-e)}.bind(this))},showHighlight:function(a){var b=1+this.options.stroke_width/2,c=this.options.width-b;a=a[this.options.highlight.index||a.length-
|
76 |
+
1]+(b/2).round();var d=this.options.highlight.color||"#f00";typeof this.options.highlight.index!=="undefined"&&(c=this.step*this.options.highlight.index);this.paper.circle(c,this.options.height-a+b/2,b).attr({stroke:!1,fill:d})}});
|
77 |
+
Grafico.SparkBar=Class.create(Grafico.SparkLine,{calculateStep:function(){return this.options.width/this.data.length},drawLines:function(a,b){var c=this.options.bargraph_lastcolor,d=this.step>2?this.step-1:this.step,e=d/2,f=this.normalise(0);b.each(function(g,h){var i,j;i=c&&h===b.length-1?c:a;j=this.paper.path().attr({stroke:i,"stroke-width":d});j.moveTo(e,this.options.height-g);j.lineTo(e,this.options.height-f);g<f&&j.attr({stroke:this.options.bargraph_negativecolor||i});e+=this.step}.bind(this))},
|
78 |
+
showHighlight:function(){}});
|
79 |
+
Grafico.SparkArea=Class.create(Grafico.SparkLine,{drawLines:function(a,b){var c=a,d=a,e=0.2,f=this.normalise(0);typeof a=="object"&&(c=a[1],d=a[0],e=1);var g=this.paper.path().attr({fill:c,stroke:c,"stroke-width":0,"stroke-opacity":0,opacity:e}).moveTo(0,this.options.height-f).lineTo(0,this.options.height-b.first()),h=this.paper.path().attr({stroke:d,"stroke-width":this.options.stroke_width}).moveTo(0,this.options.height-b.first()),i=0;b.slice(1).each(function(a){i+=this.step;g.lineTo(i,this.options.height-
|
80 |
+
a);h.lineTo(i,this.options.height-a)}.bind(this));g.lineTo(i,this.options.height-f)}});
|
js/aitoc/aitloadmon/raphael-min.js
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* Raphael 1.5.2 - JavaScript Vector Library
|
3 |
+
*
|
4 |
+
* Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
|
5 |
+
* Licensed under the MIT (http://raphaeljs.com/license.html) license.
|
6 |
+
*/
|
7 |
+
(function(){function a(){if(a.is(arguments[0],G)){var b=arguments[0],d=bV[m](a,b.splice(0,3+a.is(b[0],E))),e=d.set();for(var g=0,h=b[w];g<h;g++){var i=b[g]||{};c[f](i.type)&&e[L](d[i.type]().attr(i))}return e}return bV[m](a,arguments)}a.version="1.5.2";var b=/[, ]+/,c={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},d=/\{(\d+)\}/g,e="prototype",f="hasOwnProperty",g=document,h=window,i={was:Object[e][f].call(h,"Raphael"),is:h.Raphael},j=function(){this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in g,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v="join",w="length",x=r[e].toLowerCase,y=Math,z=y.max,A=y.min,B=y.abs,C=y.pow,D=y.PI,E="number",F="string",G="array",H="toString",I="fill",J=Object[e][H],K={},L="push",M=/^url\(['"]?([^\)]+?)['"]?\)$/i,N=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,O={"NaN":1,Infinity:1,"-Infinity":1},P=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,Q=y.round,R="setAttribute",S=parseFloat,T=parseInt,U=" progid:DXImageTransform.Microsoft",V=r[e].toUpperCase,W={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:"10px \"Arial\"","font-family":"\"Arial\"","font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},X={along:"along",blur:E,"clip-rect":"csv",cx:E,cy:E,fill:"colour","fill-opacity":E,"font-size":E,height:E,opacity:E,path:"path",r:E,rotation:"csv",rx:E,ry:E,scale:"csv",stroke:"colour","stroke-opacity":E,"stroke-width":E,translation:"csv",width:E,x:E,y:E},Y="replace",Z=/^(from|to|\d+%?)$/,$=/\s*,\s*/,_={hs:1,rg:1},ba=/,?([achlmqrstvxz]),?/gi,bb=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,bc=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,bd=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,be=function(a,b){return a.key-b.key};a.type=h.SVGAngle||g.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bf=g.createElement("div"),bg;bf.innerHTML="<v:shape adj=\"1\"/>";bg=bf.firstChild;bg.style.behavior="url(#default#VML)";if(!(bg&&typeof bg.adj=="object"))return a.type=null;bf=null}a.svg=!(a.vml=a.type=="VML");j[e]=a[e];k=j[e];a._id=0;a._oid=0;a.fn={};a.is=function(a,b){b=x.call(b);if(b=="finite")return!O[f](+a);return b=="null"&&a===null||b==typeof a||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||J.call(a).slice(8,-1).toLowerCase()==b};a.angle=function(b,c,d,e,f,g){{if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return((h<0)*180+y.atan(-i/-h)*180/D+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)}};a.rad=function(a){return a%360*D/180};a.deg=function(a){return a*180/D%360};a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,G)){var e=b.length;while(e--)if(B(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};function bh(){var a=[],b=0;for(;b<32;b++)a[b]=(~(~(y.random()*16)))[H](16);a[12]=4;a[16]=(a[16]&3|8)[H](16);return"r-"+a[v]("")}a.setWindow=function(a){h=a;g=h.document};var bi=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>");e.close();d=e.body}catch(a){d=createPopup().document.body}var f=d.createTextRange();bi=bm(function(a){try{d.style.color=r(a)[Y](c,p);var b=f.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b[H](16)).slice(-6)}catch(a){return"none"}})}else{var h=g.createElement("i");h.title="Rapha├лl Colour Picker";h.style.display="none";g.body[l](h);bi=bm(function(a){h.style.color=a;return g.defaultView.getComputedStyle(h,p).getPropertyValue("color")})}return bi(b)},bj=function(){return"hsb("+[this.h,this.s,this.b]+")"},bk=function(){return"hsl("+[this.h,this.s,this.l]+")"},bl=function(){return this.hex};a.hsb2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b){d=b.b;c=b.s;b=b.h;e=b.o}return a.hsl2rgb(b,c,d/2,e)};a.hsl2rgb=function(b,c,d,e){if(a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b){d=b.l;c=b.s;b=b.h}if(b>1||c>1||d>1){b/=360;c/=100;d/=100}var f={},g=["r","g","b"],h,i,j,k,l,m;if(c){d<0.5?h=d*(1+c):h=d+c-d*c;i=2*d-h;for(var n=0;n<3;n++){j=b+1/3*-(n-1);j<0&&j++;j>1&&j--;j*6<1?f[g[n]]=i+(h-i)*6*j:j*2<1?f[g[n]]=h:j*3<2?f[g[n]]=i+(h-i)*(2/3-j)*6:f[g[n]]=i}}else f={r:d,g:d,b:d};f.r*=255;f.g*=255;f.b*=255;f.hex="#"+(16777216|f.b|f.g<<8|f.r<<16).toString(16).slice(1);a.is(e,"finite")&&(f.opacity=e);f.toString=bl;return f};a.rgb2hsb=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=f;{if(g==f)return{h:0,s:0,b:f,toString:bj};var k=f-g;i=k/f;b==f?h=(c-d)/k:c==f?h=2+(d-b)/k:h=4+(b-c)/k;h/=6;h<0&&h++;h>1&&h--}return{h:h,s:i,b:j,toString:bj}};a.rgb2hsl=function(b,c,d){if(c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b){d=b.b;c=b.g;b=b.r}if(c==null&&a.is(b,F)){var e=a.getRGB(b);b=e.r;c=e.g;d=e.b}if(b>1||c>1||d>1){b/=255;c/=255;d/=255}var f=z(b,c,d),g=A(b,c,d),h,i,j=(f+g)/2,k;if(g==f)k={h:0,s:0,l:j};else{var l=f-g;i=j<0.5?l/(f+g):l/(2-f-g);b==f?h=(c-d)/l:c==f?h=2+(d-b)/l:h=4+(b-c)/l;h/=6;h<0&&h++;h>1&&h--;k={h:h,s:i,l:j}}k.toString=bk;return k};a._path2string=function(){return this.join(",")[Y](ba,"$1")};function bm(a,b,c){function d(){var g=Array[e].slice.call(arguments,0),h=g[v]("тЦ║"),i=d.cache=d.cache||{},j=d.count=d.count||[];if(i[f](h))return c?c(i[h]):i[h];j[w]>=1000&&delete i[j.shift()];j[L](h);i[h]=a[m](b,g);return c?c(i[h]):i[h]}return d}a.getRGB=bm(function(b){if(!b||!(!((b=r(b)).indexOf("-")+1)))return{r:-1,g:-1,b:-1,hex:"none",error:1};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none"};!(_[f](b.toLowerCase().substring(0,2))||b.charAt()=="#")&&(b=bi(b));var c,d,e,g,h,i,j,k=b.match(N);if(k){if(k[2]){g=T(k[2].substring(5),16);e=T(k[2].substring(3,5),16);d=T(k[2].substring(1,3),16)}if(k[3]){g=T((i=k[3].charAt(3))+i,16);e=T((i=k[3].charAt(2))+i,16);d=T((i=k[3].charAt(1))+i,16)}if(k[4]){j=k[4][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);k[1].toLowerCase().slice(0,4)=="rgba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100)}if(k[5]){j=k[5][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="┬░")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsba"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,g,h)}if(k[6]){j=k[6][s]($);d=S(j[0]);j[0].slice(-1)=="%"&&(d*=2.55);e=S(j[1]);j[1].slice(-1)=="%"&&(e*=2.55);g=S(j[2]);j[2].slice(-1)=="%"&&(g*=2.55);(j[0].slice(-3)=="deg"||j[0].slice(-1)=="┬░")&&(d/=360);k[1].toLowerCase().slice(0,4)=="hsla"&&(h=S(j[3]));j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,g,h)}k={r:d,g:e,b:g};k.hex="#"+(16777216|g|e<<8|d<<16).toString(16).slice(1);a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1}},a);a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||0.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=0.075;if(b.h>1){b.h=0;b.s-=0.2;b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})}return c.hex};a.getColor.reset=function(){delete this.start};a.parsePathString=bm(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,G)&&a.is(b[0],G)&&(d=bo(b));d[w]||r(b)[Y](bb,function(a,b,e){var f=[],g=x.call(b);e[Y](bc,function(a,b){b&&f[L](+b)});if(g=="m"&&f[w]>2){d[L]([b][n](f.splice(0,2)));g="l";b=b=="m"?"l":"L"}while(f[w]>=c[g]){d[L]([b][n](f.splice(0,c[g])));if(!c[g])break}});d[H]=a._path2string;return d});a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,l=C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h,m=a+2*i*(c-a)+i*i*(e-2*c+a),n=b+2*i*(d-b)+i*i*(f-2*d+b),o=c+2*i*(e-c)+i*i*(g-2*e+c),p=d+2*i*(f-d)+i*i*(h-2*f+d),q=(1-i)*a+i*c,r=(1-i)*b+i*d,s=(1-i)*e+i*g,t=(1-i)*f+i*h,u=90-y.atan((m-o)/(n-p))*180/D;(m>o||n<p)&&(u+=180);return{x:k,y:l,m:{x:m,y:n},n:{x:o,y:p},start:{x:q,y:r},end:{x:s,y:t},alpha:u}};var bn=bm(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bw(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a[w];g<h;g++){f=a[g];if(f[0]=="M"){b=f[1];c=f[2];d[L](b);e[L](c)}else{var i=bv(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x);e=e[n](i.min.y,i.max.y);b=f[5];c=f[6]}}var j=A[m](0,d),k=A[m](0,e);return{x:j,y:k,width:z[m](0,d)-j,height:z[m](0,e)-k}}),bo=function(b){var c=[];if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);for(var d=0,e=b[w];d<e;d++){c[d]=[];for(var f=0,g=b[d][w];f<g;f++)c[d][f]=b[d][f]}c[H]=a._path2string;return c},bp=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=b[0][1];e=b[0][2];f=d;g=e;h++;c[L](["M",d,e])}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=x.call(l[0])){k[0]=x.call(l[0]);switch(k[0]){case"a":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]-d).toFixed(3);k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1];g=l[2];default:for(var m=1,n=l[w];m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[];if(l[0]=="m"){f=l[1]+d;g=l[2]+e}for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o]}var q=c[i][w];switch(c[i][0]){case"z":d=f;e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2];e+=+c[i][q-1]}}c[H]=a._path2string;return c},0,bo),bq=bm(function(b){if(!a.is(b,G)||!a.is(b&&b[0],G))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;if(b[0][0]=="M"){d=+b[0][1];e=+b[0][2];f=d;g=e;h++;c[0]=["M",d,e]}for(var i=h,j=b[w];i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=V.call(l[0])){k[0]=V.call(l[0]);switch(k[0]){case"A":k[1]=l[1];k[2]=l[2];k[3]=l[3];k[4]=l[4];k[5]=l[5];k[6]=+(l[6]+d);k[7]=+(l[7]+e);break;case"V":k[1]=+l[1]+e;break;case"H":k[1]=+l[1]+d;break;case"M":f=+l[1]+d;g=+l[2]+e;default:for(var m=1,n=l[w];m<n;m++)k[m]=+l[m]+(m%2?d:e)}}else for(var o=0,p=l[w];o<p;o++)c[i][o]=l[o];switch(k[0]){case"Z":d=f;e=g;break;case"H":d=k[1];break;case"V":e=k[1];break;case"M":f=c[i][c[i][w]-2];g=c[i][c[i][w]-1];default:d=c[i][c[i][w]-2];e=c[i][c[i][w]-1]}}c[H]=a._path2string;return c},null,bo),br=function(a,b,c,d){return[a,b,c,d,c,d]},bs=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bt=function(a,b,c,d,e,f,g,h,i,j){var k=D*120/180,l=D/180*(+e||0),m=[],o,p=bm(function(a,b,c){var d=a*y.cos(c)-b*y.sin(c),e=a*y.sin(c)+b*y.cos(c);return{x:d,y:e}});if(j){G=j[0];H=j[1];E=j[2];F=j[3]}else{o=p(a,b,-l);a=o.x;b=o.y;o=p(h,i,-l);h=o.x;i=o.y;var q=y.cos(D/180*e),r=y.sin(D/180*e),t=(a-h)/2,u=(b-i)/2,x=t*t/(c*c)+u*u/(d*d);if(x>1){x=y.sqrt(x);c=x*c;d=x*d}var z=c*c,A=d*d,C=(f==g?-1:1)*y.sqrt(B((z*A-z*u*u-A*t*t)/(z*u*u+A*t*t))),E=C*c*u/d+(a+h)/2,F=C*-d*t/c+(b+i)/2,G=y.asin(((b-F)/d).toFixed(9)),H=y.asin(((i-F)/d).toFixed(9));G=a<E?D-G:G;H=h<E?D-H:H;G<0&&(G=D*2+G);H<0&&(H=D*2+H);g&&G>H&&(G=G-D*2);!g&&H>G&&(H=H-D*2)}var I=H-G;if(B(I)>k){var J=H,K=h,L=i;H=G+k*(g&&H>G?1:-1);h=E+c*y.cos(H);i=F+d*y.sin(H);m=bt(h,i,c,d,e,0,g,K,L,[H,J,E,F])}I=H-G;var M=y.cos(G),N=y.sin(G),O=y.cos(H),P=y.sin(H),Q=y.tan(I/4),R=4/3*c*Q,S=4/3*d*Q,T=[a,b],U=[a+R*N,b-S*M],V=[h+R*P,i-S*O],W=[h,i];U[0]=2*T[0]-U[0];U[1]=2*T[1]-U[1];{if(j)return[U,V,W][n](m);m=[U,V,W][n](m)[v]()[s](",");var X=[];for(var Y=0,Z=m[w];Y<Z;Y++)X[Y]=Y%2?p(m[Y-1],m[Y],l).y:p(m[Y],m[Y+1],l).x;return X}},bu=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:C(j,3)*a+C(j,2)*3*i*c+j*3*i*i*e+C(i,3)*g,y:C(j,3)*b+C(j,2)*3*i*d+j*3*i*i*f+C(i,3)*h}},bv=bm(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+y.sqrt(j*j-4*i*k))/2/i,n=(-j-y.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}i=f-2*d+b-(h-2*f+d);j=2*(d-b)-2*(f-d);k=b-d;l=(-j+y.sqrt(j*j-4*i*k))/2/i;n=(-j-y.sqrt(j*j-4*i*k))/2/i;B(l)>"1e12"&&(l=0.5);B(n)>"1e12"&&(n=0.5);if(l>0&&l<1){q=bu(a,b,c,d,e,f,g,h,l);p[L](q.x);o[L](q.y)}if(n>0&&n<1){q=bu(a,b,c,d,e,f,g,h,n);p[L](q.x);o[L](q.y)}return{min:{x:A[m](0,p),y:A[m](0,o)},max:{x:z[m](0,p),y:z[m](0,o)}}}),bw=bm(function(a,b){var c=bq(a),d=b&&bq(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1];b.Y=a[2];break;case"A":a=["C"][n](bt[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x));d=b.y+(b.y-(b.by||b.y));a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x));b.qy=b.y+(b.y-(b.qy||b.y));a=["C"][n](bs(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1];b.qy=a[2];a=["C"][n](bs(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](br(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](br(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](br(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](br(b.x,b.y,b.X,b.Y));break}return a},h=function(a,b){if(a[b][w]>7){a[b].shift();var e=a[b];while(e[w])a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1);k=z(c[w],d&&d[w]||0)}},i=function(a,b,e,f,g){if(a&&b&&a[g][0]=="M"&&b[g][0]!="M"){b.splice(g,0,["M",f.x,f.y]);e.bx=0;e.by=0;e.x=a[g][1];e.y=a[g][2];k=z(c[w],d&&d[w]||0)}};for(var j=0,k=z(c[w],d&&d[w]||0);j<k;j++){c[j]=g(c[j],e);h(c,j);d&&(d[j]=g(d[j],f));d&&h(d,j);i(c,d,e,f,j);i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l[w],q=d&&o[w];e.x=l[p-2];e.y=l[p-1];e.bx=S(l[p-4])||e.x;e.by=S(l[p-3])||e.y;f.bx=d&&(S(o[q-4])||f.x);f.by=d&&(S(o[q-3])||f.y);f.x=d&&o[q-2];f.y=d&&o[q-1]}return d?[c,d]:c},null,bo),bx=bm(function(b){var c=[];for(var d=0,e=b[w];d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex;g[2]&&(f.offset=g[2]+"%");c[L](f)}for(d=1,e=c[w]-1;d<e;d++){if(!c[d].offset){var h=S(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++){if(c[j].offset){i=c[j].offset;break}}if(!i){i=100;j=e}i=S(i);var k=(i-h)/(j-d+1);for(;d<j;d++){h+=k;c[d].offset=h+"%"}}}return c}),by=function(b,c,d,e){var f;if(a.is(b,F)||a.is(b,"object")){f=a.is(b,F)?g.getElementById(b):b;if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}}else return{container:1,x:b,y:c,width:d,height:e}},bz=function(a,b){var c=this;for(var d in b){if(b[f](d)&&!(d in a))switch(typeof b[d]){case"function":(function(b){a[d]=a===c?b:function(){return b[m](c,arguments)}})(b[d]);break;case"object":a[d]=a[d]||{};bz.call(this,a[d],b[d]);break;default:a[d]=b[d];break}}},bA=function(a,b){a==b.top&&(b.top=a.prev);a==b.bottom&&(b.bottom=a.next);a.next&&(a.next.prev=a.prev);a.prev&&(a.prev.next=a.next)},bB=function(a,b){if(b.top===a)return;bA(a,b);a.next=null;a.prev=b.top;b.top.next=a;b.top=a},bC=function(a,b){if(b.bottom===a)return;bA(a,b);a.next=b.bottom;a.prev=null;b.bottom.prev=a;b.bottom=a},bD=function(a,b,c){bA(a,c);b==c.top&&(c.top=a);b.next&&(b.next.prev=a);a.next=b.next;a.prev=b;b.next=a},bE=function(a,b,c){bA(a,c);b==c.bottom&&(c.bottom=a);b.prev&&(b.prev.next=a);a.prev=b.prev;b.prev=a;a.next=b},bF=function(a){return function(){throw new Error("Rapha├лl: you are calling to method тАЬ"+a+"тАЭ of removed object")}};a.pathToRelative=bp;if(a.svg){k.svgns="http://www.w3.org/2000/svg";k.xlink="http://www.w3.org/1999/xlink";Q=function(a){return+a+(~(~a)===a)*0.5};var bG=function(a,b){if(b)for(var c in b)b[f](c)&&a[R](c,r(b[c]));else{a=g.createElementNS(k.svgns,a);a.style.webkitTapHighlightColor="rgba(0,0,0,0)";return a}};a[H]=function(){return"Your browser supports SVG.\nYou are running Rapha├лl "+this.version};var bH=function(a,b){var c=bG("path");b.canvas&&b.canvas[l](c);var d=new bN(c,b);d.type="path";bK(d,{fill:"none",stroke:"#000",path:a});return d},bI=function(a,b,c){var d="linear",e=0.5,f=0.5,h=a.style;b=r(b)[Y](bd,function(a,b,c){d="radial";if(b&&c){e=S(b);f=S(c);var g=(f>0.5)*2-1;C(e-0.5,2)+C(f-0.5,2)>0.25&&(f=y.sqrt(0.25-C(e-0.5,2))*g+0.5)&&f!=0.5&&(f=f.toFixed(5)-0.00001*g)}return p});b=b[s](/\s*\-\s*/);if(d=="linear"){var i=b.shift();i=-S(i);if(isNaN(i))return null;var j=[0,0,y.cos(i*D/180),y.sin(i*D/180)],k=1/(z(B(j[2]),B(j[3]))||1);j[2]*=k;j[3]*=k;if(j[2]<0){j[0]=-j[2];j[2]=0}if(j[3]<0){j[1]=-j[3];j[3]=0}}var m=bx(b);if(!m)return null;var n=a.getAttribute(I);n=n.match(/^url\(#(.*)\)$/);n&&c.defs.removeChild(g.getElementById(n[1]));var o=bG(d+"Gradient");o.id=bh();bG(o,d=="radial"?{fx:e,fy:f}:{x1:j[0],y1:j[1],x2:j[2],y2:j[3]});c.defs[l](o);for(var q=0,t=m[w];q<t;q++){var u=bG("stop");bG(u,{offset:m[q].offset?m[q].offset:q?"100%":"0%","stop-color":m[q].color||"#fff"});o[l](u)}bG(a,{fill:"url(#"+o.id+")",opacity:1,"fill-opacity":1});h.fill=p;h.opacity=1;h.fillOpacity=1;return 1},bJ=function(b){var c=b.getBBox();bG(b.pattern,{patternTransform:a.format("translate({0},{1})",c.x,c.y)})},bK=function(c,d){var e={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},h=c.node,i=c.attrs,j=c.rotate(),k=function(a,b){b=e[x.call(b)];if(b){var c=a.attrs["stroke-width"]||"1",f=({round:c,square:c,butt:0})[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],i=b[w];while(i--)g[i]=b[i]*c+(i%2?1:-1)*f;bG(h,{"stroke-dasharray":g[v](",")})}};d[f]("rotation")&&(j=d.rotation);var m=r(j)[s](b);if(m.length-1){m[1]=+m[1];m[2]=+m[2]}else m=null;S(j)&&c.rotate(0,true);for(var n in d){if(d[f](n)){if(!W[f](n))continue;var o=d[n];i[n]=o;switch(n){case"blur":c.blur(o);break;case"rotation":c.rotate(o,true);break;case"href":case"title":case"target":var t=h.parentNode;if(x.call(t.tagName)!="a"){var u=bG("a");t.insertBefore(u,h);u[l](h);t=u}n=="target"&&o=="blank"?t.setAttributeNS(c.paper.xlink,"show","new"):t.setAttributeNS(c.paper.xlink,n,o);break;case"cursor":h.style.cursor=o;break;case"clip-rect":var y=r(o)[s](b);if(y[w]==4){c.clip&&c.clip.parentNode.parentNode.removeChild(c.clip.parentNode);var z=bG("clipPath"),A=bG("rect");z.id=bh();bG(A,{x:y[0],y:y[1],width:y[2],height:y[3]});z[l](A);c.paper.defs[l](z);bG(h,{"clip-path":"url(#"+z.id+")"});c.clip=A}if(!o){var B=g.getElementById(h.getAttribute("clip-path")[Y](/(^url\(#|\)$)/g,p));B&&B.parentNode.removeChild(B);bG(h,{"clip-path":p});delete c.clip}break;case"path":c.type=="path"&&bG(h,{d:o?i.path=bq(o):"M0,0"});break;case"width":h[R](n,o);if(i.fx){n="x";o=i.x}else break;case"x":i.fx&&(o=-i.x-(i.width||0));case"rx":if(n=="rx"&&c.type=="rect")break;case"cx":m&&(n=="x"||n=="cx")&&(m[1]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"height":h[R](n,o);if(i.fy){n="y";o=i.y}else break;case"y":i.fy&&(o=-i.y-(i.height||0));case"ry":if(n=="ry"&&c.type=="rect")break;case"cy":m&&(n=="y"||n=="cy")&&(m[2]+=o-i[n]);h[R](n,o);c.pattern&&bJ(c);break;case"r":c.type=="rect"?bG(h,{rx:o,ry:o}):h[R](n,o);break;case"src":c.type=="image"&&h.setAttributeNS(c.paper.xlink,"href",o);break;case"stroke-width":h.style.strokeWidth=o;h[R](n,o);i["stroke-dasharray"]&&k(c,i["stroke-dasharray"]);break;case"stroke-dasharray":k(c,o);break;case"translation":var C=r(o)[s](b);C[0]=+C[0]||0;C[1]=+C[1]||0;if(m){m[1]+=C[0];m[2]+=C[1]}cz.call(c,C[0],C[1]);break;case"scale":C=r(o)[s](b);c.scale(+C[0]||1,+C[1]||+C[0]||1,isNaN(S(C[2]))?null:+C[2],isNaN(S(C[3]))?null:+C[3]);break;case I:var D=r(o).match(M);if(D){z=bG("pattern");var E=bG("image");z.id=bh();bG(z,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});bG(E,{x:0,y:0});E.setAttributeNS(c.paper.xlink,"href",D[1]);z[l](E);var F=g.createElement("img");F.style.cssText="position:absolute;left:-9999em;top-9999em";F.onload=function(){bG(z,{width:this.offsetWidth,height:this.offsetHeight});bG(E,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);c.paper.safari()};g.body[l](F);F.src=D[1];c.paper.defs[l](z);h.style.fill="url(#"+z.id+")";bG(h,{fill:"url(#"+z.id+")"});c.pattern=z;c.pattern&&bJ(c);break}var G=a.getRGB(o);if(G.error)if((({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper)){i.gradient=o;i.fill="none";break}else{delete d.gradient;delete i.gradient;!a.is(i.opacity,"undefined")&&a.is(d.opacity,"undefined")&&bG(h,{opacity:i.opacity});!a.is(i["fill-opacity"],"undefined")&&a.is(d["fill-opacity"],"undefined")&&bG(h,{"fill-opacity":i["fill-opacity"]})}G[f]("opacity")&&bG(h,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=a.getRGB(o);h[R](n,G.hex);n=="stroke"&&G[f]("opacity")&&bG(h,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity});break;case"gradient":(({circle:1,ellipse:1})[f](c.type)||r(o).charAt()!="r")&&bI(h,o,c.paper);break;case"opacity":i.gradient&&!i[f]("stroke-opacity")&&bG(h,{"stroke-opacity":o>1?o/100:o});case"fill-opacity":if(i.gradient){var H=g.getElementById(h.getAttribute(I)[Y](/^url\(#|\)$/g,p));if(H){var J=H.getElementsByTagName("stop");J[J[w]-1][R]("stop-opacity",o)}break}default:n=="font-size"&&(o=T(o,10)+"px");var K=n[Y](/(\-.)/g,function(a){return V.call(a.substring(1))});h.style[K]=o;h[R](n,o);break}}}bM(c,d);m?c.rotate(m.join(q)):S(j)&&c.rotate(j,true)},bL=1.2,bM=function(b,c){if(b.type!="text"||!(c[f]("text")||c[f]("font")||c[f]("font-size")||c[f]("x")||c[f]("y")))return;var d=b.attrs,e=b.node,h=e.firstChild?T(g.defaultView.getComputedStyle(e.firstChild,p).getPropertyValue("font-size"),10):10;if(c[f]("text")){d.text=c.text;while(e.firstChild)e.removeChild(e.firstChild);var i=r(c.text)[s]("\n");for(var j=0,k=i[w];j<k;j++)if(i[j]){var m=bG("tspan");j&&bG(m,{dy:h*bL,x:d.x});m[l](g.createTextNode(i[j]));e[l](m)}}else{i=e.getElementsByTagName("tspan");for(j=0,k=i[w];j<k;j++)j&&bG(i[j],{dy:h*bL,x:d.x})}bG(e,{y:d.y});var n=b.getBBox(),o=d.y-(n.y+n.height/2);o&&a.is(o,"finite")&&bG(e,{y:d.y+o})},bN=function(b,c){var d=0,e=0;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.paper=c;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!c.bottom&&(c.bottom=this);this.prev=c.top;c.top&&(c.top.next=this);c.top=this;this.next=null},bO=bN[e];bN[e].rotate=function(c,d,e){if(this.removed)return this;if(c==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}var f=this.getBBox();c=r(c)[s](b);if(c[w]-1){d=S(c[1]);e=S(c[2])}c=S(c[0]);d!=null&&d!==false?this._.rt.deg=c:this._.rt.deg+=c;e==null&&(d=null);this._.rt.cx=d;this._.rt.cy=e;d=d==null?f.x+f.width/2:d;e=e==null?f.y+f.height/2:e;if(this._.rt.deg){this.transformations[0]=a.format("rotate({0} {1} {2})",this._.rt.deg,d,e);this.clip&&bG(this.clip,{transform:a.format("rotate({0} {1} {2})",-this._.rt.deg,d,e)})}else{this.transformations[0]=p;this.clip&&bG(this.clip,{transform:p})}bG(this.node,{transform:this.transformations[v](q)});return this};bN[e].hide=function(){!this.removed&&(this.node.style.display="none");return this};bN[e].show=function(){!this.removed&&(this.node.style.display="");return this};bN[e].remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);for(var a in this)delete this[a];this.removed=true};bN[e].getBBox=function(){if(this.removed)return this;if(this.type=="path")return bn(this.attrs.path);if(this.node.style.display=="none"){this.show();var a=true}var b={};try{b=this.node.getBBox()}catch(a){}finally{b=b||{}}if(this.type=="text"){b={x:b.x,y:Infinity,width:0,height:0};for(var c=0,d=this.node.getNumberOfChars();c<d;c++){var e=this.node.getExtentOfChar(c);e.y<b.y&&(b.y=e.y);e.y+e.height-b.y>b.height&&(b.height=e.y+e.height-b.y);e.x+e.width-b.x>b.width&&(b.width=e.x+e.width-b.x)}}a&&this.hide();return b};bN[e].attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,F)){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(c==null&&a.is(b,G)){var g={};for(var h=0,i=b.length;h<i;h++)g[b[h]]=this.attr(b[h]);return g}if(c!=null){var j={};j[b]=c}else b!=null&&a.is(b,"object")&&(j=b);for(var k in this.paper.customAttributes)if(this.paper.customAttributes[f](k)&&j[f](k)&&a.is(this.paper.customAttributes[k],"function")){var l=this.paper.customAttributes[k].apply(this,[][n](j[k]));this.attrs[k]=j[k];for(var m in l)l[f](m)&&(j[m]=l[m])}bK(this,j);return this};bN[e].toFront=function(){if(this.removed)return this;this.node.parentNode[l](this.node);var a=this.paper;a.top!=this&&bB(this,a);return this};bN[e].toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);bC(this,this.paper);var a=this.paper}return this};bN[e].insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode[l](this.node);bD(this,a,this.paper);return this};bN[e].insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;b.parentNode.insertBefore(this.node,b);bE(this,a,this.paper);return this};bN[e].blur=function(a){var b=this;if(+a!==0){var c=bG("filter"),d=bG("feGaussianBlur");b.attrs.blur=a;c.id=bh();bG(d,{stdDeviation:+a||1.5});c.appendChild(d);b.paper.defs.appendChild(c);b._blur=c;bG(b.node,{filter:"url(#"+c.id+")"})}else{if(b._blur){b._blur.parentNode.removeChild(b._blur);delete b._blur;delete b.attrs.blur}b.node.removeAttribute("filter")}};var bP=function(a,b,c,d){var e=bG("circle");a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"};f.type="circle";bG(e,f.attrs);return f},bQ=function(a,b,c,d,e,f){var g=bG("rect");a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"};h.type="rect";bG(g,h.attrs);return h},bR=function(a,b,c,d,e){var f=bG("ellipse");a.canvas&&a.canvas[l](f);var g=new bN(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"};g.type="ellipse";bG(f,g.attrs);return g},bS=function(a,b,c,d,e,f){var g=bG("image");bG(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"});g.setAttributeNS(a.xlink,"href",b);a.canvas&&a.canvas[l](g);var h=new bN(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b};h.type="image";return h},bT=function(a,b,c,d){var e=bG("text");bG(e,{x:b,y:c,"text-anchor":"middle"});a.canvas&&a.canvas[l](e);var f=new bN(e,a);f.attrs={x:b,y:c,"text-anchor":"middle",text:d,font:W.font,stroke:"none",fill:"#000"};f.type="text";bK(f,f.attrs);return f},bU=function(a,b){this.width=a||this.width;this.height=b||this.height;this.canvas[R]("width",this.width);this.canvas[R]("height",this.height);return this},bV=function(){var b=by[m](0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,h=b.height;if(!c)throw new Error("SVG container not found.");var i=bG("svg");d=d||0;e=e||0;f=f||512;h=h||342;bG(i,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:f,height:h});if(c==1){i.style.cssText="position:absolute;left:"+d+"px;top:"+e+"px";g.body[l](i)}else c.firstChild?c.insertBefore(i,c.firstChild):c[l](i);c=new j;c.width=f;c.height=h;c.canvas=i;bz.call(c,c,a.fn);c.clear();return c};k.clear=function(){var a=this.canvas;while(a.firstChild)a.removeChild(a.firstChild);this.bottom=this.top=null;(this.desc=bG("desc"))[l](g.createTextNode("Created with Rapha├лl"));a[l](this.desc);a[l](this.defs=bG("defs"))};k.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a)}}if(a.vml){var bW={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bX=/([clmz]),?([^clmz]*)/gi,bY=/ progid:\S+Blur\([^\)]+\)/g,bZ=/-?[^,\s-]+/g,b$=1000+q+1000,b_=10,ca={path:1,rect:1},cb=function(a){var b=/[ahqstv]/ig,c=bq;r(a).match(b)&&(c=bw);b=/[clmz]/g;if(c==bq&&!r(a).match(b)){var d=r(a)[Y](bX,function(a,b,c){var d=[],e=x.call(b)=="m",f=bW[b];c[Y](bZ,function(a){if(e&&d[w]==2){f+=d+bW[b=="m"?"l":"L"];d=[]}d[L](Q(a*b_))});return f+d});return d}var e=c(a),f,g;d=[];for(var h=0,i=e[w];h<i;h++){f=e[h];g=x.call(e[h][0]);g=="z"&&(g="x");for(var j=1,k=f[w];j<k;j++)g+=Q(f[j]*b_)+(j!=k-1?",":p);d[L](g)}return d[v](q)};a[H]=function(){return"Your browser doesnтАЩt support SVG. Falling down to VML.\nYou are running Rapha├лl "+this.version};bH=function(a,b){var c=cd("group");c.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";c.coordsize=b.coordsize;c.coordorigin=b.coordorigin;var d=cd("shape"),e=d.style;e.width=b.width+"px";e.height=b.height+"px";d.coordsize=b$;d.coordorigin=b.coordorigin;c[l](d);var f=new bN(d,c,b),g={fill:"none",stroke:"#000"};a&&(g.path=a);f.type="path";f.path=[];f.Path=p;bK(f,g);b.canvas[l](c);return f};bK=function(c,d){c.attrs=c.attrs||{};var e=c.node,h=c.attrs,i=e.style,j,k=(d.x!=h.x||d.y!=h.y||d.width!=h.width||d.height!=h.height||d.r!=h.r)&&c.type=="rect",m=c;for(var n in d)d[f](n)&&(h[n]=d[n]);if(k){h.path=cc(h.x,h.y,h.width,h.height,h.r);c.X=h.x;c.Y=h.y;c.W=h.width;c.H=h.height}d.href&&(e.href=d.href);d.title&&(e.title=d.title);d.target&&(e.target=d.target);d.cursor&&(i.cursor=d.cursor);"blur"in d&&c.blur(d.blur);if(d.path&&c.type=="path"||k)e.path=cb(h.path);d.rotation!=null&&c.rotate(d.rotation,true);if(d.translation){j=r(d.translation)[s](b);cz.call(c,j[0],j[1]);if(c._.rt.cx!=null){c._.rt.cx+=+j[0];c._.rt.cy+=+j[1];c.setBox(c.attrs,j[0],j[1])}}if(d.scale){j=r(d.scale)[s](b);c.scale(+j[0]||1,+j[1]||+j[0]||1,+j[2]||null,+j[3]||null)}if("clip-rect"in d){var o=r(d["clip-rect"])[s](b);if(o[w]==4){o[2]=+o[2]+ +o[0];o[3]=+o[3]+ +o[1];var q=e.clipRect||g.createElement("div"),t=q.style,u=e.parentNode;t.clip=a.format("rect({1}px {2}px {3}px {0}px)",o);if(!e.clipRect){t.position="absolute";t.top=0;t.left=0;t.width=c.paper.width+"px";t.height=c.paper.height+"px";u.parentNode.insertBefore(q,u);q[l](u);e.clipRect=q}}d["clip-rect"]||e.clipRect&&(e.clipRect.style.clip=p)}c.type=="image"&&d.src&&(e.src=d.src);if(c.type=="image"&&d.opacity){e.filterOpacity=U+".Alpha(opacity="+d.opacity*100+")";i.filter=(e.filterMatrix||p)+(e.filterOpacity||p)}d.font&&(i.font=d.font);d["font-family"]&&(i.fontFamily="\""+d["font-family"][s](",")[0][Y](/^['"]+|['"]+$/g,p)+"\"");d["font-size"]&&(i.fontSize=d["font-size"]);d["font-weight"]&&(i.fontWeight=d["font-weight"]);d["font-style"]&&(i.fontStyle=d["font-style"]);if(d.opacity!=null||d["stroke-width"]!=null||d.fill!=null||d.stroke!=null||d["stroke-width"]!=null||d["stroke-opacity"]!=null||d["fill-opacity"]!=null||d["stroke-dasharray"]!=null||d["stroke-miterlimit"]!=null||d["stroke-linejoin"]!=null||d["stroke-linecap"]!=null){e=c.shape||e;var v=e.getElementsByTagName(I)&&e.getElementsByTagName(I)[0],x=false;!v&&(x=v=cd(I));if("fill-opacity"in d||"opacity"in d){var y=((+h["fill-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+a.getRGB(d.fill).o+1||2)-1);y=A(z(y,0),1);v.opacity=y}d.fill&&(v.on=true);if(v.on==null||d.fill=="none")v.on=false;if(v.on&&d.fill){var B=d.fill.match(M);if(B){v.src=B[1];v.type="tile"}else{v.color=a.getRGB(d.fill).hex;v.src=p;v.type="solid";if(a.getRGB(d.fill).error&&(m.type in{circle:1,ellipse:1}||r(d.fill).charAt()!="r")&&bI(m,d.fill)){h.fill="none";h.gradient=d.fill}}}x&&e[l](v);var C=e.getElementsByTagName("stroke")&&e.getElementsByTagName("stroke")[0],D=false;!C&&(D=C=cd("stroke"));if(d.stroke&&d.stroke!="none"||d["stroke-width"]||d["stroke-opacity"]!=null||d["stroke-dasharray"]||d["stroke-miterlimit"]||d["stroke-linejoin"]||d["stroke-linecap"])C.on=true;(d.stroke=="none"||C.on==null||d.stroke==0||d["stroke-width"]==0)&&(C.on=false);var E=a.getRGB(d.stroke);C.on&&d.stroke&&(C.color=E.hex);y=((+h["stroke-opacity"]+1||2)-1)*((+h.opacity+1||2)-1)*((+E.o+1||2)-1);var F=(S(d["stroke-width"])||1)*0.75;y=A(z(y,0),1);d["stroke-width"]==null&&(F=h["stroke-width"]);d["stroke-width"]&&(C.weight=F);F&&F<1&&(y*=F)&&(C.weight=1);C.opacity=y;d["stroke-linejoin"]&&(C.joinstyle=d["stroke-linejoin"]||"miter");C.miterlimit=d["stroke-miterlimit"]||8;d["stroke-linecap"]&&(C.endcap=d["stroke-linecap"]=="butt"?"flat":d["stroke-linecap"]=="square"?"square":"round");if(d["stroke-dasharray"]){var G={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};C.dashstyle=G[f](d["stroke-dasharray"])?G[d["stroke-dasharray"]]:p}D&&e[l](C)}if(m.type=="text"){i=m.paper.span.style;h.font&&(i.font=h.font);h["font-family"]&&(i.fontFamily=h["font-family"]);h["font-size"]&&(i.fontSize=h["font-size"]);h["font-weight"]&&(i.fontWeight=h["font-weight"]);h["font-style"]&&(i.fontStyle=h["font-style"]);m.node.string&&(m.paper.span.innerHTML=r(m.node.string)[Y](/</g,"<")[Y](/&/g,"&")[Y](/\n/g,"<br>"));m.W=h.w=m.paper.span.offsetWidth;m.H=h.h=m.paper.span.offsetHeight;m.X=h.x;m.Y=h.y+Q(m.H/2);switch(h["text-anchor"]){case"start":m.node.style["v-text-align"]="left";m.bbx=Q(m.W/2);break;case"end":m.node.style["v-text-align"]="right";m.bbx=-Q(m.W/2);break;default:m.node.style["v-text-align"]="center";break}}};bI=function(a,b){a.attrs=a.attrs||{};var c=a.attrs,d,e="linear",f=".5 .5";a.attrs.gradient=b;b=r(b)[Y](bd,function(a,b,c){e="radial";if(b&&c){b=S(b);c=S(c);C(b-0.5,2)+C(c-0.5,2)>0.25&&(c=y.sqrt(0.25-C(b-0.5,2))*((c>0.5)*2-1)+0.5);f=b+q+c}return p});b=b[s](/\s*\-\s*/);if(e=="linear"){var g=b.shift();g=-S(g);if(isNaN(g))return null}var h=bx(b);if(!h)return null;a=a.shape||a.node;d=a.getElementsByTagName(I)[0]||cd(I);!d.parentNode&&a.appendChild(d);if(h[w]){d.on=true;d.method="none";d.color=h[0].color;d.color2=h[h[w]-1].color;var i=[];for(var j=0,k=h[w];j<k;j++)h[j].offset&&i[L](h[j].offset+q+h[j].color);d.colors&&(d.colors.value=i[w]?i[v]():"0% "+d.color);if(e=="radial"){d.type="gradientradial";d.focus="100%";d.focussize=f;d.focusposition=f}else{d.type="gradient";d.angle=(270-g)%360}}return 1};bN=function(b,c,d){var e=0,f=0,g=0,h=1;this[0]=b;this.id=a._oid++;this.node=b;b.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=c;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null};bO=bN[e];bO.rotate=function(a,c,d){if(this.removed)return this;if(a==null){if(this._.rt.cx)return[this._.rt.deg,this._.rt.cx,this._.rt.cy][v](q);return this._.rt.deg}a=r(a)[s](b);if(a[w]-1){c=S(a[1]);d=S(a[2])}a=S(a[0]);c!=null?this._.rt.deg=a:this._.rt.deg+=a;d==null&&(c=null);this._.rt.cx=c;this._.rt.cy=d;this.setBox(this.attrs,c,d);this.Group.style.rotation=this._.rt.deg;return this};bO.setBox=function(a,b,c){if(this.removed)return this;var d=this.Group.style,e=this.shape&&this.shape.style||this.node.style;a=a||{};for(var g in a)a[f](g)&&(this.attrs[g]=a[g]);b=b||this._.rt.cx;c=c||this._.rt.cy;var h=this.attrs,i,j,k,l;switch(this.type){case"circle":i=h.cx-h.r;j=h.cy-h.r;k=l=h.r*2;break;case"ellipse":i=h.cx-h.rx;j=h.cy-h.ry;k=h.rx*2;l=h.ry*2;break;case"image":i=+h.x;j=+h.y;k=h.width||0;l=h.height||0;break;case"text":this.textpath.v=["m",Q(h.x),", ",Q(h.y-2),"l",Q(h.x)+1,", ",Q(h.y-2)][v](p);i=h.x-Q(this.W/2);j=h.y-this.H/2;k=this.W;l=this.H;break;case"rect":case"path":if(this.attrs.path){var m=bn(this.attrs.path);i=m.x;j=m.y;k=m.width;l=m.height}else{i=0;j=0;k=this.paper.width;l=this.paper.height}break;default:i=0;j=0;k=this.paper.width;l=this.paper.height;break}b=b==null?i+k/2:b;c=c==null?j+l/2:c;var n=b-this.paper.width/2,o=c-this.paper.height/2,q;d.left!=(q=n+"px")&&(d.left=q);d.top!=(q=o+"px")&&(d.top=q);this.X=ca[f](this.type)?-n:i;this.Y=ca[f](this.type)?-o:j;this.W=k;this.H=l;if(ca[f](this.type)){e.left!=(q=-n*b_+"px")&&(e.left=q);e.top!=(q=-o*b_+"px")&&(e.top=q)}else if(this.type=="text"){e.left!=(q=-n+"px")&&(e.left=q);e.top!=(q=-o+"px")&&(e.top=q)}else{d.width!=(q=this.paper.width+"px")&&(d.width=q);d.height!=(q=this.paper.height+"px")&&(d.height=q);e.left!=(q=i-n+"px")&&(e.left=q);e.top!=(q=j-o+"px")&&(e.top=q);e.width!=(q=k+"px")&&(e.width=q);e.height!=(q=l+"px")&&(e.height=q)}};bO.hide=function(){!this.removed&&(this.Group.style.display="none");return this};bO.show=function(){!this.removed&&(this.Group.style.display="block");return this};bO.getBBox=function(){if(this.removed)return this;if(ca[f](this.type))return bn(this.attrs.path);return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};bO.remove=function(){if(this.removed)return;bA(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)delete this[a];this.removed=true};bO.attr=function(b,c){if(this.removed)return this;if(b==null){var d={};for(var e in this.attrs)this.attrs[f](e)&&(d[e]=this.attrs[e]);this._.rt.deg&&(d.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(d.scale=this.scale());d.gradient&&d.fill=="none"&&(d.fill=d.gradient)&&delete d.gradient;return d}if(c==null&&a.is(b,"string")){if(b=="translation")return cz.call(this);if(b=="rotation")return this.rotate();if(b=="scale")return this.scale();if(b==I&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;return this.attrs[b]}if(this.attrs&&c==null&&a.is(b,G)){var g,h={};for(e=0,g=b[w];e<g;e++)h[b[e]]=this.attr(b[e]);return h}var i;if(c!=null){i={};i[b]=c}c==null&&a.is(b,"object")&&(i=b);if(i){for(var j in this.paper.customAttributes)if(this.paper.customAttributes[f](j)&&i[f](j)&&a.is(this.paper.customAttributes[j],"function")){var k=this.paper.customAttributes[j].apply(this,[][n](i[j]));this.attrs[j]=i[j];for(var l in k)k[f](l)&&(i[l]=k[l])}i.text&&this.type=="text"&&(this.node.string=i.text);bK(this,i);i.gradient&&(({circle:1,ellipse:1})[f](this.type)||r(i.gradient).charAt()!="r")&&bI(this,i.gradient);(!ca[f](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};bO.toFront=function(){!this.removed&&this.Group.parentNode[l](this.Group);this.paper.top!=this&&bB(this,this.paper);return this};bO.toBack=function(){if(this.removed)return this;if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);bC(this,this.paper)}return this};bO.insertAfter=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[a.length-1]);a.Group.nextSibling?a.Group.parentNode.insertBefore(this.Group,a.Group.nextSibling):a.Group.parentNode[l](this.Group);bD(this,a,this.paper);return this};bO.insertBefore=function(a){if(this.removed)return this;a.constructor==cC&&(a=a[0]);a.Group.parentNode.insertBefore(this.Group,a.Group);bE(this,a,this.paper);return this};bO.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(bY,p);if(+b!==0){this.attrs.blur=b;c.filter=d+q+U+".Blur(pixelradius="+(+b||1.5)+")";c.margin=a.format("-{0}px 0 0 -{0}px",Q(+b||1.5))}else{c.filter=d;c.margin=0;delete this.attrs.blur}};bP=function(a,b,c,d){var e=cd("group"),f=cd("oval"),g=f.style;e.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";e.coordsize=b$;e.coordorigin=a.coordorigin;e[l](f);var h=new bN(f,e,a);h.type="circle";bK(h,{stroke:"#000",fill:"none"});h.attrs.cx=b;h.attrs.cy=c;h.attrs.r=d;h.setBox({x:b-d,y:c-d,width:d*2,height:d*2});a.canvas[l](e);return h};function cc(b,c,d,e,f){return f?a.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",b+f,c,d-f*2,f,-f,e-f*2,f*2-d,f*2-e):a.format("M{0},{1}l{2},0,0,{3},{4},0z",b,c,d,e,-d)}bQ=function(a,b,c,d,e,f){var g=cc(b,c,d,e,f),h=a.path(g),i=h.attrs;h.X=i.x=b;h.Y=i.y=c;h.W=i.width=d;h.H=i.height=e;i.r=f;i.path=g;h.type="rect";return h};bR=function(a,b,c,d,e){var f=cd("group"),g=cd("oval"),h=g.style;f.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";f.coordsize=b$;f.coordorigin=a.coordorigin;f[l](g);var i=new bN(g,f,a);i.type="ellipse";bK(i,{stroke:"#000"});i.attrs.cx=b;i.attrs.cy=c;i.attrs.rx=d;i.attrs.ry=e;i.setBox({x:b-d,y:c-e,width:d*2,height:e*2});a.canvas[l](f);return i};bS=function(a,b,c,d,e,f){var g=cd("group"),h=cd("image");g.style.cssText="position:absolute;left:0;top:0;width:"+a.width+"px;height:"+a.height+"px";g.coordsize=b$;g.coordorigin=a.coordorigin;h.src=b;g[l](h);var i=new bN(h,g,a);i.type="image";i.attrs.src=b;i.attrs.x=c;i.attrs.y=d;i.attrs.w=e;i.attrs.h=f;i.setBox({x:c,y:d,width:e,height:f});a.canvas[l](g);return i};bT=function(b,c,d,e){var f=cd("group"),g=cd("shape"),h=g.style,i=cd("path"),j=i.style,k=cd("textpath");f.style.cssText="position:absolute;left:0;top:0;width:"+b.width+"px;height:"+b.height+"px";f.coordsize=b$;f.coordorigin=b.coordorigin;i.v=a.format("m{0},{1}l{2},{1}",Q(c*10),Q(d*10),Q(c*10)+1);i.textpathok=true;h.width=b.width;h.height=b.height;k.string=r(e);k.on=true;g[l](k);g[l](i);f[l](g);var m=new bN(k,f,b);m.shape=g;m.textpath=i;m.type="text";m.attrs.text=e;m.attrs.x=c;m.attrs.y=d;m.attrs.w=1;m.attrs.h=1;bK(m,{font:W.font,stroke:"none",fill:"#000"});m.setBox();b.canvas[l](f);return m};bU=function(a,b){var c=this.canvas.style;a==+a&&(a+="px");b==+b&&(b+="px");c.width=a;c.height=b;c.clip="rect(0 "+a+" "+b+" 0)";return this};var cd;g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");cd=function(a){return g.createElement("<rvml:"+a+" class=\"rvml\">")}}catch(a){cd=function(a){return g.createElement("<"+a+" xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">")}}bV=function(){var b=by[m](0,arguments),c=b.container,d=b.height,e,f=b.width,h=b.x,i=b.y;if(!c)throw new Error("VML container not found.");var k=new j,n=k.canvas=g.createElement("div"),o=n.style;h=h||0;i=i||0;f=f||512;d=d||342;f==+f&&(f+="px");d==+d&&(d+="px");k.width=1000;k.height=1000;k.coordsize=b_*1000+q+b_*1000;k.coordorigin="0 0";k.span=g.createElement("span");k.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";n[l](k.span);o.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d);if(c==1){g.body[l](n);o.left=h+"px";o.top=i+"px";o.position="absolute"}else c.firstChild?c.insertBefore(n,c.firstChild):c[l](n);bz.call(k,k,a.fn);return k};k.clear=function(){this.canvas.innerHTML=p;this.span=g.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[l](this.span);this.bottom=this.top=null};k.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=bF(a);return true}}var ce=navigator.userAgent.match(/Version\\x2f(.*?)\s/);navigator.vendor=="Apple Computer, Inc."&&(ce&&ce[1]<4||navigator.platform.slice(0,2)=="iP")?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});h.setTimeout(function(){a.remove()})}:k.safari=function(){};var cf=function(){this.returnValue=false},cg=function(){return this.originalEvent.preventDefault()},ch=function(){this.cancelBubble=true},ci=function(){return this.originalEvent.stopPropagation()},cj=(function(){{if(g.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,g=function(e){if(o&&u[f](b))for(var g=0,h=e.targetTouches&&e.targetTouches.length;g<h;g++){if(e.targetTouches[g].target==a){var i=e;e=e.targetTouches[g];e.originalEvent=i;e.preventDefault=cg;e.stopPropagation=ci;break}}return c.call(d,e)};a.addEventListener(e,g,false);return function(){a.removeEventListener(e,g,false);return true}};if(g.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.event;a.preventDefault=a.preventDefault||cf;a.stopPropagation=a.stopPropagation||ch;return c.call(d,a)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return true};return f}}})(),ck=[],cl=function(a){var b=a.clientX,c=a.clientY,d=g.documentElement.scrollTop||g.body.scrollTop,e=g.documentElement.scrollLeft||g.body.scrollLeft,f,h=ck.length;while(h--){f=ck[h];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX;c=j.clientY;(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();b+=e;c+=d;f.move&&f.move.call(f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},cm=function(b){a.unmousemove(cl).unmouseup(cm);var c=ck.length,d;while(c--){d=ck[c];d.el._drag={};d.end&&d.end.call(d.end_scope||d.start_scope||d.move_scope||d.el,b)}ck=[]};for(var cn=t[w];cn--;)(function(b){a[b]=bN[e][b]=function(c,d){if(a.is(c,"function")){this.events=this.events||[];this.events.push({name:b,f:c,unbind:cj(this.shape||this.node||g,b,c,d||this)})}return this};a["un"+b]=bN[e]["un"+b]=function(a){var c=this.events,d=c[w];while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind();c.splice(d,1);!c.length&&delete this.events;return this}return this}})(t[cn]);bO.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)};bO.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};bO.drag=function(b,c,d,e,f,h){this._drag={};this.mousedown(function(i){(i.originalEvent||i).preventDefault();var j=g.documentElement.scrollTop||g.body.scrollTop,k=g.documentElement.scrollLeft||g.body.scrollLeft;this._drag.x=i.clientX+k;this._drag.y=i.clientY+j;this._drag.id=i.identifier;c&&c.call(f||e||this,i.clientX+k,i.clientY+j,i);!ck.length&&a.mousemove(cl).mouseup(cm);ck.push({el:this,move:b,end:d,move_scope:e,start_scope:f,end_scope:h})});return this};bO.undrag=function(b,c,d){var e=ck.length;while(e--)ck[e].el==this&&(ck[e].move==b&&ck[e].end==d)&&ck.splice(e++,1);!ck.length&&a.unmousemove(cl).unmouseup(cm)};k.circle=function(a,b,c){return bP(this,a||0,b||0,c||0)};k.rect=function(a,b,c,d,e){return bQ(this,a||0,b||0,c||0,d||0,e||0)};k.ellipse=function(a,b,c,d){return bR(this,a||0,b||0,c||0,d||0)};k.path=function(b){b&&!a.is(b,F)&&!a.is(b[0],G)&&(b+=p);return bH(a.format[m](a,arguments),this)};k.image=function(a,b,c,d,e){return bS(this,a||"about:blank",b||0,c||0,d||0,e||0)};k.text=function(a,b,c){return bT(this,a||0,b||0,r(c))};k.set=function(a){arguments[w]>1&&(a=Array[e].splice.call(arguments,0,arguments[w]));return new cC(a)};k.setSize=bU;k.top=k.bottom=null;k.raphael=a;function co(){return this.x+q+this.y}bO.resetScale=function(){if(this.removed)return this;this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};bO.scale=function(a,b,c,d){if(this.removed)return this;if(a==null&&b==null)return{x:this._.sx,y:this._.sy,toString:co};b=b||a;!(+b)&&(b=a);var e,f,g,h,i=this.attrs;if(a!=0){var j=this.getBBox(),k=j.x+j.width/2,l=j.y+j.height/2,m=B(a/this._.sx),o=B(b/this._.sy);c=+c||c==0?c:k;d=+d||d==0?d:l;var r=this._.sx>0,s=this._.sy>0,t=~(~(a/B(a))),u=~(~(b/B(b))),x=m*t,y=o*u,z=this.node.style,A=c+B(k-c)*x*(k>c==r?1:-1),C=d+B(l-d)*y*(l>d==s?1:-1),D=a*t>b*u?o:m;switch(this.type){case"rect":case"image":var E=i.width*m,F=i.height*o;this.attr({height:F,r:i.r*D,width:E,x:A-E/2,y:C-F/2});break;case"circle":case"ellipse":this.attr({rx:i.rx*m,ry:i.ry*o,r:i.r*D,cx:A,cy:C});break;case"text":this.attr({x:A,y:C});break;case"path":var G=bp(i.path),H=true,I=r?x:m,J=s?y:o;for(var K=0,L=G[w];K<L;K++){var M=G[K],N=V.call(M[0]);{if(N=="M"&&H)continue;H=false}if(N=="A"){M[G[K][w]-2]*=I;M[G[K][w]-1]*=J;M[1]*=m;M[2]*=o;M[5]=+(t+u?!(!(+M[5])):!(+M[5]))}else if(N=="H")for(var O=1,P=M[w];O<P;O++)M[O]*=I;else if(N=="V")for(O=1,P=M[w];O<P;O++)M[O]*=J;else for(O=1,P=M[w];O<P;O++)M[O]*=O%2?I:J}var Q=bn(G);e=A-Q.x-Q.width/2;f=C-Q.y-Q.height/2;G[0][1]+=e;G[0][2]+=f;this.attr({path:G});break}if(this.type in{text:1,image:1}&&(t!=1||u!=1))if(this.transformations){this.transformations[2]="scale("[n](t,",",u,")");this.node[R]("transform",this.transformations[v](q));e=t==-1?-i.x-(E||0):i.x;f=u==-1?-i.y-(F||0):i.y;this.attr({x:e,y:f});i.fx=t-1;i.fy=u-1}else{this.node.filterMatrix=U+".Matrix(M11="[n](t,", M12=0, M21=0, M22=",u,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}else if(this.transformations){this.transformations[2]=p;this.node[R]("transform",this.transformations[v](q));i.fx=0;i.fy=0}else{this.node.filterMatrix=p;z.filter=(this.node.filterMatrix||p)+(this.node.filterOpacity||p)}i.scale=[a,b,c,d][v](q);this._.sx=a;this._.sy=b}return this};bO.clone=function(){if(this.removed)return null;var a=this.attr();delete a.scale;delete a.translation;return this.paper[this.type]().attr(a)};var cp={},cq=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=cp[m],o,p;!n&&(cp[m]=n={data:[]});n.timer&&clearTimeout(n.timer);n.timer=setTimeout(function(){delete cp[m]},2000);if(j!=null){var q=cq(b,c,d,e,f,g,h,i);l=~(~q)*10}for(var r=0;r<l+1;r++){if(n.data[j]>r)p=n.data[r*l];else{p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l);n.data[r]=p}r&&(k+=C(C(o.x-p.x,2)+C(o.y-p.y,2),0.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cr=function(b,c){return function(d,e,f){d=bw(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M"){g=+i[1];h=+i[2]}else{j=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);k+=["C",m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k;k=["M",m.x,m.y+"C",m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]][v]();n+=j;g=+i[5];h=+i[6];continue}if(!b&&!c){m=cq(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j;g=+i[5];h=+i[6]}k+=i}l.end=k;m=b?n:c?l:a.findDotsAtSegment(g,h,i[1],i[2],i[3],i[4],i[5],i[6],1);m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},cs=cr(1),ct=cr(),cu=cr(0,1);bO.getTotalLength=function(){if(this.type!="path")return;if(this.node.getTotalLength)return this.node.getTotalLength();return cs(this.attrs.path)};bO.getPointAtLength=function(a){if(this.type!="path")return;return ct(this.attrs.path,a)};bO.getSubpath=function(a,b){if(this.type!="path")return;if(B(this.getTotalLength()-b)<"1e-6")return cu(this.attrs.path,a).end;var c=cu(this.attrs.path,b,1);return a?cu(c,a).end:c};a.easing_formulas={linear:function(a){return a},"<":function(a){return C(a,3)},">":function(a){return C(a-1,3)+1},"<>":function(a){a=a*2;if(a<1)return C(a,3)/2;a-=2;return(C(a,3)+2)/2},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==0||a==1)return a;var b=0.3,c=b/4;return C(2,-10*a)*y.sin((a-c)*(2*D)/b)+1},bounce:function(a){var b=7.5625,c=2.75,d;if(a<1/c)d=b*a*a;else if(a<2/c){a-=1.5/c;d=b*a*a+0.75}else if(a<2.5/c){a-=2.25/c;d=b*a*a+0.9375}else{a-=2.625/c;d=b*a*a+0.984375}return d}};var cv=[],cw=function(){var b=+(new Date);for(var c=0;c<cv[w];c++){var d=cv[c];if(d.stop||d.el.removed)continue;var e=b-d.start,g=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,n={},o;if(e<g){var r=h(e/g);for(var s in i)if(i[f](s)){switch(X[s]){case"along":o=r*g*j[s];k.back&&(o=k.len-o);var t=ct(k[s],o);m.translate(j.sx-j.x||0,j.sy-j.y||0);j.x=t.x;j.y=t.y;m.translate(t.x-j.sx,t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y);break;case E:o=+i[s]+r*g*j[s];break;case"colour":o="rgb("+[cy(Q(i[s].r+r*g*j[s].r)),cy(Q(i[s].g+r*g*j[s].g)),cy(Q(i[s].b+r*g*j[s].b))][v](",")+")";break;case"path":o=[];for(var u=0,x=i[s][w];u<x;u++){o[u]=[i[s][u][0]];for(var y=1,z=i[s][u][w];y<z;y++)o[u][y]=+i[s][u][y]+r*g*j[s][u][y];o[u]=o[u][v](q)}o=o[v](q);break;case"csv":switch(s){case"translation":var A=r*g*j[s][0]-l.x,B=r*g*j[s][1]-l.y;l.x+=A;l.y+=B;o=A+q+B;break;case"rotation":o=+i[s][0]+r*g*j[s][0];i[s][1]&&(o+=","+i[s][1]+","+i[s][2]);break;case"scale":o=[+i[s][0]+r*g*j[s][0],+i[s][1]+r*g*j[s][1],2 in k[s]?k[s][2]:p,3 in k[s]?k[s][3]:p][v](q);break;case"clip-rect":o=[];u=4;while(u--)o[u]=+i[s][u]+r*g*j[s][u];break}break;default:var C=[].concat(i[s]);o=[];u=m.paper.customAttributes[s].length;while(u--)o[u]=+C[u]+r*g*j[s][u];break}n[s]=o}m.attr(n);m._run&&m._run.call(m)}else{if(k.along){t=ct(k.along,k.len*!k.back);m.translate(j.sx-(j.x||0)+t.x-j.sx,j.sy-(j.y||0)+t.y-j.sy);k.rot&&m.rotate(j.r+t.alpha,t.x,t.y)}(l.x||l.y)&&m.translate(-l.x,-l.y);k.scale&&(k.scale+=p);m.attr(k);cv.splice(c--,1)}}a.svg&&m&&m.paper&&m.paper.safari();cv[w]&&setTimeout(cw)},cx=function(b,c,d,e,f){var g=d-e;c.timeouts.push(setTimeout(function(){a.is(f,"function")&&f.call(c);c.animate(b,g,b.easing)},e))},cy=function(a){return z(A(a,255),0)},cz=function(a,b){if(a==null)return{x:this._.tx,y:this._.ty,toString:co};this._.tx+=+a;this._.ty+=+b;switch(this.type){case"circle":case"ellipse":this.attr({cx:+a+this.attrs.cx,cy:+b+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+a+this.attrs.x,y:+b+this.attrs.y});break;case"path":var c=bp(this.attrs.path);c[0][1]+=+a;c[0][2]+=+b;this.attr({path:c});break}return this};bO.animateWith=function(a,b,c,d,e){for(var f=0,g=cv.length;f<g;f++)cv[f].el.id==a.id&&(b.start=cv[f].start);return this.animate(b,c,d,e)};bO.animateAlong=cA();bO.animateAlongBack=cA(1);function cA(b){return function(c,d,e,f){var g={back:b};a.is(e,"function")?f=e:g.rot=e;c&&c.constructor==bN&&(c=c.attrs.path);c&&(g.along=c);return this.animate(g,d,f)}}function cB(a,b,c,d,e,f){var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;function m(a){return((i*a+h)*a+g)*a}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(B(f)<b)return e;j=(3*i*e+2*h)*e+g;if(B(j)<0.000001)break;e=e-f/j}c=0;d=1;e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(B(f-a)<b)return e;a>f?c=e:d=e;e=(d-c)/2+c}return e}return n(a,1/(200*f))}bO.onAnimation=function(a){this._run=a||0;return this};bO.animate=function(c,d,e,g){var h=this;h.timeouts=h.timeouts||[];if(a.is(e,"function")||!e)g=e||null;if(h.removed){g&&g.call(h);return h}var i={},j={},k=false,l={};for(var m in c)if(c[f](m)){if(X[f](m)||h.paper.customAttributes[f](m)){k=true;i[m]=h.attr(m);i[m]==null&&(i[m]=W[m]);j[m]=c[m];switch(X[m]){case"along":var n=cs(c[m]),o=ct(c[m],n*!(!c.back)),p=h.getBBox();l[m]=n/d;l.tx=p.x;l.ty=p.y;l.sx=o.x;l.sy=o.y;j.rot=c.rot;j.back=c.back;j.len=n;c.rot&&(l.r=S(h.rotate())||0);break;case E:l[m]=(j[m]-i[m])/d;break;case"colour":i[m]=a.getRGB(i[m]);var q=a.getRGB(j[m]);l[m]={r:(q.r-i[m].r)/d,g:(q.g-i[m].g)/d,b:(q.b-i[m].b)/d};break;case"path":var t=bw(i[m],j[m]);i[m]=t[0];var u=t[1];l[m]=[];for(var v=0,x=i[m][w];v<x;v++){l[m][v]=[0];for(var y=1,z=i[m][v][w];y<z;y++)l[m][v][y]=(u[v][y]-i[m][v][y])/d}break;case"csv":var A=r(c[m])[s](b),B=r(i[m])[s](b);switch(m){case"translation":i[m]=[0,0];l[m]=[A[0]/d,A[1]/d];break;case"rotation":i[m]=B[1]==A[1]&&B[2]==A[2]?B:[0,A[1],A[2]];l[m]=[(A[0]-i[m][0])/d,0,0];break;case"scale":c[m]=A;i[m]=r(i[m])[s](b);l[m]=[(A[0]-i[m][0])/d,(A[1]-i[m][1])/d,0,0];break;case"clip-rect":i[m]=r(i[m])[s](b);l[m]=[];v=4;while(v--)l[m][v]=(A[v]-i[m][v])/d;break}j[m]=A;break;default:A=[].concat(c[m]);B=[].concat(i[m]);l[m]=[];v=h.paper.customAttributes[m][w];while(v--)l[m][v]=((A[v]||0)-(B[v]||0))/d;break}}}if(k){var G=a.easing_formulas[e];if(!G){G=r(e).match(P);if(G&&G[w]==5){var H=G;G=function(a){return cB(a,+H[1],+H[2],+H[3],+H[4],d)}}else G=function(a){return a}}cv.push({start:c.start||+(new Date),ms:d,easing:G,from:i,diff:l,to:j,el:h,t:{x:0,y:0}});a.is(g,"function")&&(h._ac=setTimeout(function(){g.call(h)},d));cv[w]==1&&setTimeout(cw)}else{var C=[],D;for(var F in c)if(c[f](F)&&Z.test(F)){m={value:c[F]};F=="from"&&(F=0);F=="to"&&(F=100);m.key=T(F,10);C.push(m)}C.sort(be);C[0].key&&C.unshift({key:0,value:h.attrs});for(v=0,x=C[w];v<x;v++)cx(C[v].value,h,d/100*C[v].key,d/100*(C[v-1]&&C[v-1].key||0),C[v-1]&&C[v-1].value.callback);D=C[C[w]-1].value.callback;D&&h.timeouts.push(setTimeout(function(){D.call(h)},d))}return this};bO.stop=function(){for(var a=0;a<cv.length;a++)cv[a].el.id==this.id&&cv.splice(a--,1);for(a=0,ii=this.timeouts&&this.timeouts.length;a<ii;a++)clearTimeout(this.timeouts[a]);this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};bO.translate=function(a,b){return this.attr({translation:a+" "+b})};bO[H]=function(){return"Rapha├лlтАЩs object"};a.ae=cv;var cC=function(a){this.items=[];this[w]=0;this.type="set";if(a)for(var b=0,c=a[w];b<c;b++){if(a[b]&&(a[b].constructor==bN||a[b].constructor==cC)){this[this.items[w]]=this.items[this.items[w]]=a[b];this[w]++}}};cC[e][L]=function(){var a,b;for(var c=0,d=arguments[w];c<d;c++){a=arguments[c];if(a&&(a.constructor==bN||a.constructor==cC)){b=this.items[w];this[b]=this.items[b]=a;this[w]++}}return this};cC[e].pop=function(){delete this[this[w]--];return this.items.pop()};for(var cD in bO)bO[f](cD)&&(cC[e][cD]=(function(a){return function(){for(var b=0,c=this.items[w];b<c;b++)this.items[b][a][m](this.items[b],arguments);return this}})(cD));cC[e].attr=function(b,c){if(b&&a.is(b,G)&&a.is(b[0],"object"))for(var d=0,e=b[w];d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items[w];f<g;f++)this.items[f].attr(b,c);return this};cC[e].animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items[w],g=f,h,i=this,j;e&&(j=function(){!(--f)&&e.call(i)});d=a.is(d,F)?d:j;h=this.items[--g].animate(b,c,d,j);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,b,c,d,j);return this};cC[e].insertAfter=function(a){var b=this.items[w];while(b--)this.items[b].insertAfter(a);return this};cC[e].getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items[w];e--;){var f=this.items[e].getBBox();a[L](f.x);b[L](f.y);c[L](f.x+f.width);d[L](f.y+f.height)}a=A[m](0,a);b=A[m](0,b);return{x:a,y:b,width:z[m](0,c)-a,height:z[m](0,d)-b}};cC[e].clone=function(a){a=new cC;for(var b=0,c=this.items[w];b<c;b++)a[L](this.items[b].clone());return a};a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[f](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c][L](b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=T(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[f](e)){var g=a.glyphs[e];b.glyphs[e]={w:g.w,k:{},d:g.d&&"M"+g.d[Y](/[mlcxtrv]/g,function(a){return({l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"})[a]||"M"})+"z"};if(g.k)for(var h in g.k)g[f](h)&&(b.glyphs[e].k[h]=g.k[h])}}return a};k.getFont=function(b,c,d,e){e=e||"normal";d=d||"normal";c=+c||({normal:400,bold:700,lighter:300,bolder:800})[c]||400;if(!a.fonts)return;var g=a.fonts[b];if(!g){var h=new RegExp("(^|\\s)"+b[Y](/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[f](i)){if(h.test(i)){g=a.fonts[i];break}}}var j;if(g)for(var k=0,l=g[w];k<l;k++){j=g[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j};k.print=function(c,d,e,f,g,h,i){h=h||"middle";i=z(A(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox.split(b),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k[w];u<v;u++){var x=u&&f.glyphs[k[u-1]]||{},y=f.glyphs[k[u]];l+=u?(x.w||f.w)+(x.k&&x.k[k[u]]||0)+f.w*i:0;y&&y.d&&j[L](this.path(y.d).attr({fill:"#000",stroke:"none",translation:[l,0]}))}j.scale(n,n,q,t).translate(c-q,d-t)}return j};a.format=function(b,c){var e=a.is(c,G)?[0][n](c):arguments;b&&a.is(b,F)&&e[w]-1&&(b=b[Y](d,function(a,b){return e[++b]==null?p:e[b]}));return b||p};a.ninja=function(){i.was?h.Raphael=i.is:delete Raphael;return a};a.el=bO;a.st=cC[e];i.was?h.Raphael=a:Raphael=a})()
|
lib/Aitoc/Aitloadmon/Adapter/Apc.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Adapter_Apc
|
7 |
+
{
|
8 |
+
private static $DATA_KEY = 'aitloadmon_data';
|
9 |
+
private static $DATA_NUM_KEY = 'aitloadmon_data_key';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Saves the data into storage
|
13 |
+
*
|
14 |
+
* @param array $params
|
15 |
+
*/
|
16 |
+
public function save($params)
|
17 |
+
{
|
18 |
+
if(!$index = apc_fetch(self::$DATA_NUM_KEY))
|
19 |
+
{
|
20 |
+
apc_add(self::$DATA_NUM_KEY, 1);
|
21 |
+
$index = 1;
|
22 |
+
}
|
23 |
+
|
24 |
+
while(!apc_add(self::$DATA_KEY.$index,$params))
|
25 |
+
{
|
26 |
+
$index++;
|
27 |
+
}
|
28 |
+
apc_delete(self::$DATA_NUM_KEY);
|
29 |
+
apc_add(self::$DATA_NUM_KEY, $index);
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Gets the data from the storage
|
35 |
+
*
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public function getData()
|
39 |
+
{
|
40 |
+
$data = array();
|
41 |
+
if($index = apc_fetch(self::$DATA_NUM_KEY))
|
42 |
+
{
|
43 |
+
for($i=1;$i<=$index;$i++)
|
44 |
+
{
|
45 |
+
if($element = apc_fetch(self::$DATA_KEY.$i))
|
46 |
+
{
|
47 |
+
$data = array_merge_recursive($data,$element);
|
48 |
+
apc_delete(self::$DATA_KEY.$i);
|
49 |
+
}
|
50 |
+
}
|
51 |
+
apc_delete(self::$DATA_NUM_KEY);
|
52 |
+
apc_add(self::$DATA_NUM_KEY, $i);
|
53 |
+
}
|
54 |
+
return $data;
|
55 |
+
}
|
56 |
+
}
|
lib/Aitoc/Aitloadmon/Adapter/File.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Adapter_File
|
7 |
+
{
|
8 |
+
const DS = DIRECTORY_SEPARATOR;
|
9 |
+
|
10 |
+
private static $_dataDir = 'data';
|
11 |
+
private static $_filename = 'data_';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Gets the path to the directory for the data files
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
private function _getDataDir()
|
19 |
+
{
|
20 |
+
return Aitoc_Aitloadmon_Collect::getTempDir().self::$_dataDir.self::DS;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Returns the file resource for writing
|
25 |
+
*
|
26 |
+
* @return resource
|
27 |
+
*/
|
28 |
+
private function _getCurrentFileHandle()
|
29 |
+
{
|
30 |
+
$i = 0;
|
31 |
+
$currentFileHandle = null;
|
32 |
+
if(!file_exists($this->_getDataDir()))
|
33 |
+
{
|
34 |
+
mkdir($this->_getDataDir());
|
35 |
+
}
|
36 |
+
$curFilePath = $this->_getDataDir().self::$_filename;
|
37 |
+
while(!$currentFileHandle)
|
38 |
+
{
|
39 |
+
$fileHandle = fopen($curFilePath.$i, 'a');
|
40 |
+
$locked = flock($fileHandle, LOCK_EX);
|
41 |
+
if($locked)
|
42 |
+
{
|
43 |
+
$currentFileHandle = $fileHandle;
|
44 |
+
}
|
45 |
+
$i++;
|
46 |
+
}
|
47 |
+
return $currentFileHandle;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Writes a string to file
|
52 |
+
*
|
53 |
+
* @param string $string
|
54 |
+
*/
|
55 |
+
private function _writeStringToFile($string)
|
56 |
+
{
|
57 |
+
$fileHandle = $this->_getCurrentFileHandle();
|
58 |
+
fwrite($fileHandle,$string."\r\n");
|
59 |
+
flock($fileHandle, LOCK_UN);
|
60 |
+
fclose($fileHandle);
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Saves the data into storage
|
65 |
+
*
|
66 |
+
* @param array $params
|
67 |
+
*/
|
68 |
+
public function save($params)
|
69 |
+
{
|
70 |
+
$this->_writeStringToFile(serialize($params));
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Gets the list of data files
|
75 |
+
*
|
76 |
+
* @return array
|
77 |
+
*/
|
78 |
+
private function _getDataFileList()
|
79 |
+
{
|
80 |
+
return scandir($this->_getDataDir());
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Gets the data from the storage
|
85 |
+
*
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
public function getData()
|
89 |
+
{
|
90 |
+
$dir = $this->_getDataDir();
|
91 |
+
$data = array();
|
92 |
+
foreach($this->_getDataFileList() as $fileName)
|
93 |
+
{
|
94 |
+
if($fileName != '.' && $fileName != '..')
|
95 |
+
{
|
96 |
+
$fileHandle = fopen($dir.$fileName, 'r');
|
97 |
+
$locked = null;
|
98 |
+
while(!$locked)
|
99 |
+
{
|
100 |
+
$locked = flock($fileHandle, LOCK_EX);
|
101 |
+
}
|
102 |
+
|
103 |
+
while($string = fgets($fileHandle))
|
104 |
+
{
|
105 |
+
$data = array_merge_recursive($data,unserialize($string));
|
106 |
+
}
|
107 |
+
flock($fileHandle, LOCK_UN);
|
108 |
+
fclose($fileHandle);
|
109 |
+
unlink($dir.$fileName);
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
return $data;
|
114 |
+
}
|
115 |
+
|
116 |
+
}
|
lib/Aitoc/Aitloadmon/Adapter/Memcached.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
4 |
+
* @license License agreement could be found at the root folder of this package
|
5 |
+
*/
|
6 |
+
class Aitoc_Aitloadmon_Adapter_Memcached
|
7 |
+
{
|
8 |
+
private static $DATA_KEY = 'aitloadmon_data';
|
9 |
+
private static $DATA_NUM_KEY = 'aitloadmon_data_key';
|
10 |
+
|
11 |
+
private $_cache;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Initiates the connection to memcache
|
15 |
+
*
|
16 |
+
* @param array $settings
|
17 |
+
*/
|
18 |
+
public function __construct($settings)
|
19 |
+
{
|
20 |
+
$this->_cache = new Memcache;
|
21 |
+
$this->_cache->connect($settings['host'], $settings['port']);
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Saves the data into storage
|
26 |
+
*
|
27 |
+
* @param array $params
|
28 |
+
*/
|
29 |
+
public function save($params)
|
30 |
+
{
|
31 |
+
if(!$index = $this->_cache->get(self::$DATA_NUM_KEY))
|
32 |
+
{
|
33 |
+
$this->_cache->set(self::$DATA_NUM_KEY, 1);
|
34 |
+
$index = 1;
|
35 |
+
}
|
36 |
+
|
37 |
+
while(!$this->_cache->add(self::$DATA_KEY.$index,$params))
|
38 |
+
{
|
39 |
+
$index++;
|
40 |
+
}
|
41 |
+
$this->_cache->set(self::$DATA_NUM_KEY, $index);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Gets the data from the storage
|
46 |
+
*
|
47 |
+
* @return array
|
48 |
+
*/
|
49 |
+
public function getData()
|
50 |
+
{
|
51 |
+
$data = array();
|
52 |
+
if($index = $this->_cache->get(self::$DATA_NUM_KEY))
|
53 |
+
{
|
54 |
+
for($i=1;$i<=$index;$i++)
|
55 |
+
{
|
56 |
+
if($element = $this->_cache->get(self::$DATA_KEY.$i))
|
57 |
+
{
|
58 |
+
$data = array_merge_recursive($data,$element);
|
59 |
+
$this->_cache->delete(self::$DATA_KEY.$i);
|
60 |
+
}
|
61 |
+
}
|
62 |
+
$this->_cache->set(self::$DATA_NUM_KEY, 1);
|
63 |
+
}
|
64 |
+
return $data;
|
65 |
+
}
|
66 |
+
}
|
lib/Aitoc/Aitloadmon/Collect.php
ADDED
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Aitoc_Aitloadmon_Collect
|
4 |
+
{
|
5 |
+
const DS = DIRECTORY_SEPARATOR;
|
6 |
+
|
7 |
+
private static $_tempDir = 'ait_loadmon';
|
8 |
+
private static $_settingsFilename = 'settings.ini';
|
9 |
+
private static $_loadLevelFilename = 'load_level';
|
10 |
+
|
11 |
+
private static $_adapter;
|
12 |
+
private static $_enabled;
|
13 |
+
private static $_loadLevel;
|
14 |
+
private static $_pathAddon;
|
15 |
+
private $_uniqueId;
|
16 |
+
private $_startWritten;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Gets the root path of Magento installation
|
20 |
+
*
|
21 |
+
* @return string
|
22 |
+
*/
|
23 |
+
private static function _getRootPath()
|
24 |
+
{//todo think of it
|
25 |
+
return dirname($_SERVER['SCRIPT_FILENAME']).self::$_pathAddon;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Returns whether the module is enabled
|
30 |
+
*
|
31 |
+
* @return bool
|
32 |
+
*/
|
33 |
+
public static function isModuleEnabled()
|
34 |
+
{
|
35 |
+
if(!isset(self::$_enabled))
|
36 |
+
{
|
37 |
+
self::$_enabled = false;
|
38 |
+
$config = simplexml_load_file(self::_getRootPath().self::DS.'app'.self::DS.'etc'.self::DS.'modules'.self::DS.'Aitoc_Aitloadmon.xml');
|
39 |
+
if ($config){
|
40 |
+
self::$_enabled = (string)$config->modules->Aitoc_Aitloadmon->active;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
return self::$_enabled;
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Checks if module is enabled and if it is writes the start data
|
49 |
+
*/
|
50 |
+
public function __construct($pathAddon = '')
|
51 |
+
{
|
52 |
+
self::$_pathAddon = $pathAddon;
|
53 |
+
if (!self::isModuleEnabled())
|
54 |
+
{
|
55 |
+
return;
|
56 |
+
}
|
57 |
+
$this->_startWritten = 0;
|
58 |
+
$this->_save();
|
59 |
+
register_shutdown_function(array($this,'shutdown'));
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Gets the unique id for storing purposes
|
64 |
+
*
|
65 |
+
* @return string
|
66 |
+
*/
|
67 |
+
private function _getUniqueId()
|
68 |
+
{
|
69 |
+
if(!isset($this->_uniqueId))
|
70 |
+
{
|
71 |
+
$this->_uniqueId = uniqid();
|
72 |
+
}
|
73 |
+
return $this->_uniqueId;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Gets the VAR folder of Magento
|
78 |
+
*
|
79 |
+
* @return string
|
80 |
+
*/
|
81 |
+
public static function getTempDir()
|
82 |
+
{
|
83 |
+
return self::_getRootPath().self::DS.'var'.self::DS.self::$_tempDir.self::DS;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Gets the full path of the settings file
|
88 |
+
*
|
89 |
+
* @return string
|
90 |
+
*/
|
91 |
+
private static function _getSettingsFilename()
|
92 |
+
{
|
93 |
+
return self::getTempDir().self::$_settingsFilename;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Saves the data
|
98 |
+
*/
|
99 |
+
private function _save()
|
100 |
+
{
|
101 |
+
if(!$this->_startWritten)
|
102 |
+
{
|
103 |
+
$saveData = array(
|
104 |
+
$this->_getUniqueId() => array(
|
105 |
+
'request_uri' => $_SERVER['REQUEST_URI'],
|
106 |
+
'start' => microtime(true),
|
107 |
+
)
|
108 |
+
);
|
109 |
+
}
|
110 |
+
else
|
111 |
+
{
|
112 |
+
$saveData = array(
|
113 |
+
$this->_getUniqueId() => array(
|
114 |
+
'end' => microtime(true),
|
115 |
+
)
|
116 |
+
);
|
117 |
+
}
|
118 |
+
self::_getAdapter()->save($saveData);
|
119 |
+
$this->_startWritten = 1;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Checks if module is enabled and if it is writes the finish data
|
124 |
+
*/
|
125 |
+
public function shutdown()/*__destruct()*/
|
126 |
+
{
|
127 |
+
if (!self::isModuleEnabled())
|
128 |
+
{
|
129 |
+
return;
|
130 |
+
}
|
131 |
+
$this->_save();
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Gets the data storage adapter
|
136 |
+
*
|
137 |
+
* @return Aitoc_Aitloadmon_Adapter_Memcached|Aitoc_Aitloadmon_Adapter_File|Aitoc_Aitloadmon_Adapter_Apc
|
138 |
+
* @throws Exception
|
139 |
+
*/
|
140 |
+
private static function _getAdapter()
|
141 |
+
{
|
142 |
+
if(!isset(self::$_adapter))
|
143 |
+
{
|
144 |
+
$settings = self::_getSettings();
|
145 |
+
|
146 |
+
if(!isset($settings['adapter']))
|
147 |
+
{
|
148 |
+
throw new Exception('No adapter specified in settings');
|
149 |
+
}
|
150 |
+
|
151 |
+
$adapterName = ucfirst(strtolower($settings['adapter']));
|
152 |
+
$adapterClassFile = self::_getRootPath().self::DS.'lib'.self::DS.'Aitoc'.self::DS.'Aitloadmon'.self::DS.'Adapter'.self::DS.$adapterName.'.php';
|
153 |
+
|
154 |
+
if(!file_exists($adapterClassFile))
|
155 |
+
{
|
156 |
+
throw new Exception('Adapter does not exists');
|
157 |
+
}
|
158 |
+
|
159 |
+
include_once($adapterClassFile);
|
160 |
+
|
161 |
+
$adapterClass = 'Aitoc_Aitloadmon_Adapter_'.$adapterName;
|
162 |
+
self::$_adapter = new $adapterClass($settings);
|
163 |
+
}
|
164 |
+
return self::$_adapter;
|
165 |
+
}
|
166 |
+
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Gets the settings array
|
170 |
+
*
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
private static function _getSettings()
|
174 |
+
{
|
175 |
+
if(!file_exists(self::_getSettingsFilename()))
|
176 |
+
{
|
177 |
+
|
178 |
+
$config = simplexml_load_file(self::_getRootPath().self::DS.'app'.self::DS.'etc'.self::DS.'local.xml');
|
179 |
+
$cacheEngine = null;
|
180 |
+
if ($config){
|
181 |
+
$cacheEngine = (string)$config->global->cache->backend;
|
182 |
+
}
|
183 |
+
switch($cacheEngine)
|
184 |
+
{
|
185 |
+
case 'memcached':
|
186 |
+
$settingsString = 'adapter = "memcached"'."\r\n".'host = "'.(string)$config->global->cache->memcached->servers->server->host.'"'."\r\n".'port = "'.(string)$config->global->cache->memcached->servers->server->port.'"';
|
187 |
+
break;
|
188 |
+
|
189 |
+
case 'apc':
|
190 |
+
$settingsString = 'adapter = "apc"';
|
191 |
+
break;
|
192 |
+
|
193 |
+
default:
|
194 |
+
$settingsString = 'adapter = "file"';
|
195 |
+
|
196 |
+
}
|
197 |
+
if(!file_exists(self::getTempDir()))
|
198 |
+
{
|
199 |
+
mkdir(self::getTempDir());
|
200 |
+
}
|
201 |
+
file_put_contents(self::_getSettingsFilename(),$settingsString);
|
202 |
+
|
203 |
+
}
|
204 |
+
|
205 |
+
$settings = parse_ini_file(self::_getSettingsFilename());
|
206 |
+
|
207 |
+
return $settings;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Gets the data that was collected and stored
|
212 |
+
*
|
213 |
+
* @return array
|
214 |
+
*/
|
215 |
+
public static function getData()
|
216 |
+
{
|
217 |
+
$adapter = self::_getAdapter();
|
218 |
+
$data = $adapter->getData();
|
219 |
+
return $data;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Gets the full path of a file with current load level
|
224 |
+
*
|
225 |
+
* @return string
|
226 |
+
*/
|
227 |
+
private static function _getLoadLevelFilename()
|
228 |
+
{
|
229 |
+
return self::getTempDir().self::$_loadLevelFilename;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Sets current load level
|
234 |
+
*
|
235 |
+
* @param int $loadLevel
|
236 |
+
*/
|
237 |
+
public static function setLoadLevel($loadLevel)
|
238 |
+
{
|
239 |
+
self::$_loadLevel = $loadLevel;
|
240 |
+
$filename = self::_getLoadLevelFilename();
|
241 |
+
file_put_contents($filename,$loadLevel);
|
242 |
+
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Gets current load level
|
247 |
+
*
|
248 |
+
* @return null|int
|
249 |
+
*/
|
250 |
+
public static function getLoadLevel()
|
251 |
+
{
|
252 |
+
if(!isset(self::$_loadLevel))
|
253 |
+
{
|
254 |
+
$filename = self::_getLoadLevelFilename();
|
255 |
+
if(file_exists($filename))
|
256 |
+
{
|
257 |
+
self::$_loadLevel = file_get_contents($filename);
|
258 |
+
}
|
259 |
+
else
|
260 |
+
{
|
261 |
+
self::$_loadLevel = null;
|
262 |
+
}
|
263 |
+
}
|
264 |
+
return self::$_loadLevel;
|
265 |
+
}
|
266 |
+
}
|
package.xml
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>ServerLoadMonitorFree</name>
|
4 |
+
<version>1.0.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://www.aitoc.com/en/aitdownloadablefiles/download/aitfile/aitfile_id/722/"> License - proprietary (can be found in module package) </license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>It’s quite frustrating to have your server overloaded or crashed when trade is brisk and sales are booming. Neither is it a good thing to happen to a fledging e-commerce company still busy building up credibility with customers. Crash prevention is a serious issue and a valid goal. And even if your server is powerful enough and properly customized it is still useful to keep an eye on it, monitor your Magento store traffic load page by page. 
|
10 |
+

|
11 |
+
Server Load Monitor is just the right extension to serve all the above mentioned purposes. It will provide you with a comprehensive overview of load-related processes essential for trouble-free performance of your Magento server. </summary>
|
12 |
+
<description>Description:
|
13 |
+

|
14 |
+
Server Load Monitor (free) features:
|
15 |
+

|
16 |
+
• Allows for monitoring the following: CMS, Checkout, Catalog, Catalog Search and other pages; 
|
17 |
+
• Divides server performance into four intuitive color-coded zones; 
|
18 |
+
• Allows for tracking Average and Max page load and load time for a selected time period;
|
19 |
+
• Displays load statistics in the form of easy and intuitive diagrams in the back-end;
|
20 |
+
• Displays color-coded live server load info in the Admin panel;
|
21 |
+
• Provides statistics for every minute; 
|
22 |
+
• Allows for comparing stats for different time periods;
|
23 |
+
• Load statistics are stored in a database;
|
24 |
+
• Compresses data automatically to avoid overloading the database. Default compression settings are optimized and recommended, but Admin is enabled to choose preferred compression settings as well as compress the data manually;
|
25 |
+
• Sends data to AITOC’s Server Calculator*; 
|
26 |
+
• Comes with a User Manual;
|
27 |
+
• The extension's functionality code is 100% Open Source.
|
28 |
+

|
29 |
+
* Please note that collected data will be sent to AITOC's Server Calculator in order to configure and recommend you better server settings. If you wish to disable sending data for Server Calculator stats, disable the ads, and get alerts about critical load peaks, please get the <a href=”http://aitoc.com/en/magentomods_ server_load_monitor_paid.htm”>paid version</a> of the extension. </description>
|
30 |
+
<notes>02.29.2013 - Extension release (Compatibility: CE 1.4.х-1.7.0.2)</notes>
|
31 |
+
<authors><author><name>AITOC</name><user>AITOC</user><email>aitoc-connect@aitoc.com</email></author></authors>
|
32 |
+
<date>2013-03-29</date>
|
33 |
+
<time>15:10:02</time>
|
34 |
+
<contents><target name="magelocal"><dir name="Aitoc"><dir name="Aitloadmon"><dir><dir name="Block"><dir name="Adminhtml"><file name="Aitlink.php" hash="4ea78c7a1d6f9e31aead66249a256a1d"/><dir name="Aitloadmon"><file name="BarGraph.php" hash="90e16b55a20987cdd214bc6da435ea6d"/><file name="Filter.php" hash="eade4a66c1a68f1a2334138fd4c33d3a"/><file name="LineGraph.php" hash="34eea0c6add4e36b0a37065cc9d87317"/></dir><file name="Aitloadmon.php" hash="5be3738e8cf84e5b85806701d6efbcd2"/><file name="Calculator.php" hash="4e08727116a1ac204bce97dab899b2e0"/><file name="CalculatorResult.php" hash="4524309b0433fd68ecc828b6a7fc8fc3"/><file name="Indicator.php" hash="9d1e87229cef34dafe0d2ec435f6bb9f"/><file name="Manage.php" hash="dbfdb4f6d788fba1469ab0a61fde9d9d"/></dir></dir><dir name="Helper"><file name="Data.php" hash="5249574ba1c636f4a2e5a59817011fb3"/></dir><dir name="Model"><file name="Aitloadmon.php" hash="8c7e29b4f586640975b8283688ab8bb7"/><file name="Analytics.php" hash="a223097ec56f7eea3329d43fe7e2956b"/><dir name="Calculator"><file name="Abstract.php" hash="2b04ac57b32c874dbb47ffd72292d29a"/><file name="Hardware.php" hash="1164c19b50d86b9a71da74f9629c2e1d"/><file name="Magento.php" hash="1ebcc5312a9e7991439e5ff05d1fb467"/><file name="Software.php" hash="1647fce4800569c1e33d839d9b0d83e8"/></dir><file name="Calculator.php" hash="726d6bc7cf5cd80b4d20cad5475b6da1"/><file name="CompressSource.php" hash="65b4aa585216893143d7ca28bfda6645"/><file name="Dblog.php" hash="4c134db8959a150f8031b71787ae2503"/><file name="LevelSource.php" hash="1937e32cc2b08ffbfc875d3a2f0d362b"/><file name="Manage.php" hash="6b06b0dbbb19d098b1414c6cd4a1bb8a"/><dir name="Mysql4"><dir name="Aitloadmon"><file name="Collection.php" hash="a59a1d250b177fa2175a8a6af21b738d"/></dir><file name="Aitloadmon.php" hash="1f4eddb6272e05d8463a82278cb2a854"/><dir name="Calculator"><file name="Collection.php" hash="15170dd43faeebdfc30e42ebd6270c28"/></dir><file name="Calculator.php" hash="7354931dd66342f5071f782b5de7401e"/><dir name="Dblog"><file name="Collection.php" hash="3dc0dcc5e9d3bb5951573d3d11a8e4dc"/></dir><file name="Dblog.php" hash="4f4e76036d37c170fdf4771f2669dce8"/><file name="UrlRewrite.php" hash="08aecaea96122e801cdb2f9793e22ddf"/></dir><file name="Observer.php" hash="a58aa407da9971ba9cc30afb5be41248"/><file name="Process.php" hash="02b5248392a16268f03fff3f0692dc6d"/><file name="Router.php" hash="9bf8663c8632cf9a410dd67a5393c954"/><file name="SysInfo.php" hash="a5c868f2ec1fa10cbbbca85c917a63f9"/><dir name="System"><file name="Abstract.php" hash="1cdc94c9f08d4507ef57fe766f30fe13"/></dir><file name="System.php" hash="6eeee453abc5efd3c35a24babe613609"/><file name="UrlRewrite.php" hash="ea3849ee4bedc6422b03bdb4be2535fd"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AitloadmonController.php" hash="0c5f48b6086679ccdb1334d3d9e1e2a4"/><file name="CalculatorController.php" hash="b7f9d6de9974ccb27e37f17ad7cd7515"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="a64ef461fcf678bc7bb28fe5b0e7cc3b"/><file name="config.xml" hash="1f003fc2b2b642537c76b3316ce5ba91"/><file name="system.xml" hash="4fc4ebb203b4a2943067696d7972c77b"/></dir><dir name="sql"><dir name="aitloadmon_setup"><file name="mysql4-install-1.0.0.php" hash="bb6d6c9aec69500be4a10d7944a82dfc"/><file name="mysql4-uninstall-1.0.0.php" hash="177151acef7c5d0c376f1d49bc5ce8c7"/></dir></dir></dir></dir><dir name="Aitsys"><dir><dir name="install"><file name="Aitoc_Aitloadmon.phtml" hash="9a81474e26aac8b23a5b2d2cdd6ab30d"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="aitloadmon.xml" hash="dde1da1952e5309e4125aaa6e328a8fa"/></dir><dir name="template"><dir name="aitloadmon"><file name="back.phtml" hash="ccc9f0ff80649046eddf0faa3b1b50c5"/><file name="bar.phtml" hash="2bd5dd221588543850d3f9a4f4a9e35e"/><file name="graph.phtml" hash="097408b5b89d48df6e80953d0c6a379a"/><file name="indicator.phtml" hash="f0dce9d5c49118b7f98573a91766c563"/><file name="line.phtml" hash="ea7b053633df4f7cdb23423225b8b34b"/><file name="quick.phtml" hash="b0eecb7f8296c293d7abff2cddc5aa5c"/><file name="sysInfo.phtml" hash="674767482f77361975c90c8bc412e4a5"/><file name="system.phtml" hash="b17117164a92d0fda7c99e9cf7027938"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Aitoc_Aitloadmon.xml" hash="bee30fb9fd78c808ab4ab7fdfa4c64dd"/></dir></target><target name="magelib"><dir name="Aitoc"><dir name="Aitloadmon"><dir><dir name="Adapter"><file name="Apc.php" hash="c67c74af65e094da996e39f0a8451d62"/><file name="File.php" hash="e440b9dc1c0792680043b8288d22f0a5"/><file name="Memcached.php" hash="b770d4016679b99e9dee9f82e28838a4"/></dir></dir><file name="Collect.php" hash="343f14897e2782418b97f156be2e4797"/></dir></dir></target><target name="mageweb"><dir name="js"><dir name="aitoc"><dir name="aitloadmon"><file name="grafico.bar.custom.js" hash="e54db4c61047afb27a56968a8eec9fc4"/><file name="grafico.line.custom.js" hash="545ece867845d3e46d9091d021013be4"/><file name="grafico.min.js" hash="cde1bec6859b10e4a179aadec3c7e232"/><file name="raphael-min.js" hash="bcbc57198142f86c2e251525b214149d"/></dir></dir></dir></target><target name="mage"><dir name="."><file name="readme.txt" hash="33729d5788f0da4048501c989079b42e"/><file name="License agreement Server Load Monitor.pdf" hash="2c37f69a12f4508aa13181f6cefd264b"/><file name="Server Load Monitor Manual.pdf" hash="21465278b287e1a35d900a92233b796a"/></dir></target></contents>
|
35 |
+
<compatible/>
|
36 |
+
<dependencies><required><php><min>5.2.0</min><max>5.4.13</max></php></required></dependencies>
|
37 |
+
</package>
|
readme.txt
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* @copyright Copyright (c) 2013 AITOC, Inc.
|
3 |
+
* @license License agreement could be found at the root folder of this package
|
4 |
+
*/
|
5 |
+
Thank you for choosing AITOC!
|
6 |
+
|
7 |
+
Please read Installation-Uninstallation Guide.pdf before starting the installation of the module. We also recommend to read the User Manual.
|
8 |
+
|
9 |
+
To open .pdf format, please download acrobat reader at http://www.adobe.com/products/acrobat/readstep2.html (free of charge).
|
10 |
+
|
11 |
+
|
12 |
+
IMPORTANT!
|
13 |
+
|
14 |
+
1. Free version of the extension has no automated installer. The extension downloaded from Magento Connect is already enabled. The extension downloaded from www.aitoc.com needs to be enabled manually in /app/etc/modules/Aitoc_Aitloadmonpaid.xml�
|
15 |
+
<modules>
|
16 |
+
��<Aitoc_Aitloadmonpaid>
|
17 |
+
�����<active>false</active>�//�set true
|
18 |
+
�����<codePool>local</codePool>
|
19 |
+
�����<self_name>Server�Load�Monitor�Paid</self_name>
|
20 |
+
��</Aitoc_Aitloadmonpaid>
|
21 |
+
</modules>
|
22 |
+
|
23 |
+
2. Paid version package includes an automated installer.
|
24 |
+
|
25 |
+
3. For both free and paid versions admin should add the following code to the beginning of your index.php to start monitoring:
|
26 |
+
|
27 |
+
include_once(dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'Aitoc'.DIRECTORY_SEPARATOR.'Aitloadmon'.DIRECTORY_SEPARATOR.'Collect.php');new Aitoc_Aitloadmon_Collect();
|
28 |
+
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
Best Regards,
|
33 |
+
AITOC team
|
34 |
+
www.aitoc.com
|