mobile_assistant_connector - Version 1.4.0

Version Notes

Fixed:
- minor bugs
Added:
- multiple user accounts can be created
- user permission control is possible now
- device activity control is possible now, you can check all the devices connected to your store, activate/deactivate accounts, remove devices

Download this release

Release Info

Developer eMagicOne
Extension mobile_assistant_connector
Version 1.4.0
Comparing to
See all releases


Code changes from version 1.3.6 to 1.4.0

Files changed (67) hide show
  1. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/System/Config/Form/Qrcode.php +0 -15
  2. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/System/Config/Form/Qrconfig.php +0 -15
  3. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User.php +32 -0
  4. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit.php +129 -0
  5. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Action.php +66 -0
  6. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Currency.php +35 -0
  7. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Date.php +33 -0
  8. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Grid.php +239 -0
  9. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/MassAction.php +34 -0
  10. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/NewCustomer.php +31 -0
  11. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/NewOrder.php +31 -0
  12. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/OrdStatuses.php +55 -0
  13. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Store.php +45 -0
  14. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Form.php +41 -0
  15. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Devices.php +77 -0
  16. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Main.php +190 -0
  17. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Permissions.php +147 -0
  18. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tabs.php +70 -0
  19. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Grid.php +169 -0
  20. app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Renderer/Permissions.php +30 -0
  21. app/code/community/Emagicone/Mobassistantconnector/Helper/Access.php +130 -56
  22. app/code/community/Emagicone/Mobassistantconnector/Helper/Data.php +22 -146
  23. app/code/community/Emagicone/Mobassistantconnector/Helper/DeviceAndPushNotification.php +186 -0
  24. app/code/community/Emagicone/Mobassistantconnector/Helper/TableCheck.php +287 -0
  25. app/code/community/Emagicone/Mobassistantconnector/Helper/Test.php +0 -0
  26. app/code/community/Emagicone/Mobassistantconnector/Helper/UserPermissions.php +294 -0
  27. app/code/community/Emagicone/Mobassistantconnector/Model/Account.php +45 -0
  28. app/code/community/Emagicone/Mobassistantconnector/Model/Defpassword.php +0 -52
  29. app/code/community/Emagicone/Mobassistantconnector/Model/Device.php +51 -0
  30. app/code/community/Emagicone/Mobassistantconnector/Model/Observer.php +246 -177
  31. app/code/community/Emagicone/Mobassistantconnector/Model/Push.php +46 -0
  32. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Account.php +27 -0
  33. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Account/Collection.php +27 -0
  34. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Device.php +27 -0
  35. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Device/Collection.php +27 -0
  36. app/code/community/Emagicone/Mobassistantconnector/{controllers/adminhtml/IndexController.php → Model/Resource/Push.php} +26 -25
  37. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Push/Collection.php +27 -0
  38. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Sessions.php +2 -1
  39. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Sessions/Collection.php +2 -0
  40. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/User.php +27 -0
  41. app/code/community/Emagicone/Mobassistantconnector/Model/Resource/User/Collection.php +27 -0
  42. app/code/community/Emagicone/Mobassistantconnector/Model/Sessions.php +18 -1
  43. app/code/community/Emagicone/Mobassistantconnector/Model/User.php +43 -0
  44. app/code/community/Emagicone/Mobassistantconnector/controllers/Adminhtml/UserController.php +436 -0
  45. app/code/community/Emagicone/Mobassistantconnector/controllers/IndexController.php +418 -290
  46. app/code/community/Emagicone/Mobassistantconnector/data/em1_mob_setup/data-install-1.4.0.php +25 -0
  47. app/code/community/Emagicone/Mobassistantconnector/etc/adminhtml.xml +0 -26
  48. app/code/community/Emagicone/Mobassistantconnector/etc/config.xml +210 -130
  49. app/code/community/Emagicone/Mobassistantconnector/etc/system.xml +0 -116
  50. app/code/community/Emagicone/Mobassistantconnector/sql/{emagicone_mobassistantconnector_setup → em1_mob_setup}/install-1.2.1.php +14 -4
  51. app/code/community/Emagicone/Mobassistantconnector/sql/em1_mob_setup/install-1.4.0.php +197 -0
  52. app/code/community/Emagicone/Mobassistantconnector/sql/em1_setup/install-2.0.1.php +0 -60
  53. app/design/adminhtml/default/default/layout/mobassistantconnector.xml +41 -1
  54. app/design/adminhtml/default/default/template/mobassistantconnector/connect_qrcode.phtml +0 -8
  55. app/design/adminhtml/default/default/template/mobassistantconnector/jsinit.phtml +0 -132
  56. app/design/adminhtml/default/default/template/mobassistantconnector/permissions.phtml +142 -0
  57. app/design/frontend/base/default/template/emagicone/mobassistantconnector/qr_code.phtml +35 -0
  58. app/etc/modules/Emagicone_Mobassistantconnector.xml +8 -8
  59. js/emagicone/mobassistantconnector/jquery-2.2.2.min.js +4 -0
  60. js/emagicone/mobassistantconnector/qrcode.min.js +22 -0
  61. js/emagicone/mobassistantconnector/qrcode_app_user_edit.js +36 -0
  62. js/emagicone/mobassistantconnector/qrcode_app_user_index.js +36 -0
  63. js/emagicone/mobassistantconnector/user_edit.js +220 -0
  64. package.xml +10 -5
  65. skin/adminhtml/default/default/emagicone/mobassistantconnector/style.css +33 -0
  66. skin/adminhtml/default/default/images/emagicone/mobassistantconnector/no.png +0 -0
  67. skin/adminhtml/default/default/images/emagicone/mobassistantconnector/yes.png +0 -0
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/System/Config/Form/Qrcode.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- class Emagicone_Mobassistantconnector_Block_Adminhtml_System_Config_Form_Qrcode extends Mage_Adminhtml_Block_System_Config_Form_Field
3
- {
4
-
5
- protected function _construct()
6
- {
7
- parent::_construct();
8
- $this->setTemplate('mobassistantconnector/connect_qrcode.phtml');
9
- }
10
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
11
- {
12
- return $this->_toHtml();
13
- }
14
-
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/System/Config/Form/Qrconfig.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- class Emagicone_Mobassistantconnector_Block_Adminhtml_System_Config_Form_Qrconfig extends Mage_Adminhtml_Block_System_Config_Form_Field
3
- {
4
-
5
- protected function _construct()
6
- {
7
- parent::_construct();
8
- $this->setTemplate('mobassistantconnector/jsinit.phtml');
9
- }
10
- protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
11
- {
12
- return $this->_toHtml();
13
- }
14
-
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User extends Mage_Adminhtml_Block_Widget_Grid_Container
20
+ {
21
+
22
+ public function __construct()
23
+ {
24
+ $this->_blockGroup = 'mobassistantconnector';
25
+ $this->_controller = 'adminhtml_user';
26
+ $this->_headerText = Mage::helper('mobassistantconnector')->__('Users');
27
+ $this->_addButtonLabel = Mage::helper('mobassistantconnector')->__('Create New User');
28
+
29
+ parent::__construct();
30
+ }
31
+
32
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
20
+ {
21
+
22
+ public function __construct()
23
+ {
24
+ parent::__construct();
25
+
26
+ $this->_objectId = 'user_id';
27
+ $this->_blockGroup = 'mobassistantconnector';
28
+ $this->_controller = 'adminhtml_user';
29
+ $this->_mode = 'edit';
30
+
31
+ if ($this->_isAllowedAction('save')) {
32
+ $this->_updateButton('save', 'label', Mage::helper('mobassistantconnector')->__('Save User'));
33
+ $this->_addButton(
34
+ 'saveandcontinue',
35
+ array(
36
+ 'label' => Mage::helper('adminhtml')->__('Save and Continue Edit'),
37
+ 'onclick' => "saveAndContinueEdit('" . $this->_getSaveAndContinueUrl() . "')",
38
+ 'class' => 'save',
39
+ ),
40
+ -100
41
+ );
42
+ } else {
43
+ $this->_removeButton('save');
44
+ }
45
+
46
+ if ($this->_isAllowedAction('delete')) {
47
+ $this->_updateButton('delete', 'label', Mage::helper('mobassistantconnector')->__('Delete User'));
48
+ } else {
49
+ $this->_removeButton('delete');
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Retrieve text for header element depending on loaded page
55
+ *
56
+ * @return string
57
+ */
58
+ public function getHeaderText()
59
+ {
60
+ if (Mage::registry('mobassistantconnector_user')->getId()) {
61
+ return $this->escapeHtml(Mage::registry('mobassistantconnector_user')->getUsername());
62
+ } else {
63
+ return Mage::helper('mobassistantconnector')->__('New User');
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Check permission for passed action
69
+ *
70
+ * @param string $action
71
+ * @return bool
72
+ */
73
+ protected function _isAllowedAction($action)
74
+ {
75
+ return Mage::getSingleton('admin/session')->isAllowed('user/' . $action);
76
+ }
77
+
78
+ /**
79
+ * Getter of url for "Save and Continue" button
80
+ * tab_id will be replaced by desired by JS later
81
+ *
82
+ * @return string
83
+ */
84
+ protected function _getSaveAndContinueUrl()
85
+ {
86
+ return $this->getUrl(
87
+ '*/*/save',
88
+ array(
89
+ '_current' => true,
90
+ 'back' => 'edit',
91
+ 'active_tab' => '{{tab_id}}'
92
+ )
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Prepare layout
98
+ *
99
+ * @return Mage_Core_Block_Abstract
100
+ */
101
+ protected function _prepareLayout()
102
+ {
103
+ $tabsBlock = $this->getLayout()->getBlock('user_edit_tabs');
104
+
105
+ if ($tabsBlock) {
106
+ $tabsBlockJsObject = $tabsBlock->getJsObjectName();
107
+ $tabsBlockPrefix = $tabsBlock->getId() . '_';
108
+ } else {
109
+ $tabsBlockJsObject = 'user_tabsJsTabs';
110
+ $tabsBlockPrefix = 'user_tabs_';
111
+ }
112
+
113
+ $this->_formScripts[] = "
114
+ function saveAndContinueEdit(urlTemplate) {
115
+ var tabsIdValue = " . $tabsBlockJsObject . ".activeTab.id;
116
+ var tabsBlockPrefix = '" . $tabsBlockPrefix . "';
117
+ if (tabsIdValue.startsWith(tabsBlockPrefix)) {
118
+ tabsIdValue = tabsIdValue.substr(tabsBlockPrefix.length)
119
+ }
120
+ var template = new Template(urlTemplate, /(^|.|\\r|\\n)({{(\w+)}})/);
121
+ var url = template.evaluate({tab_id:tabsIdValue});
122
+ editForm.submit(url);
123
+ }
124
+ ";
125
+
126
+ return parent::_prepareLayout();
127
+ }
128
+
129
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Action.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Action extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Action
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $actions = array();
25
+ $status = (int)$row->getData('status');
26
+
27
+ if ($row->getData('account_email')) {
28
+ $actions[] = array(
29
+ 'caption' => $status == 1
30
+ ? Mage::helper('mobassistantconnector')->__('Disable&nbsp;Account')
31
+ : Mage::helper('mobassistantconnector')->__('Enable&nbsp;Account'),
32
+ 'url' => $this->getUrl(
33
+ '*/*/changeStatusAccount',
34
+ array(
35
+ 'push_id' => $row->getData('id'),
36
+ 'user_id' => $this->getRequest()->getParam('user_id'),
37
+ 'value' => $status == 1 ? 0: 1
38
+ )
39
+ ),
40
+ 'field' => 'id',
41
+ 'value' => $row->getData('account_id'),
42
+ 'data-column' => 'action'
43
+ );
44
+ }
45
+
46
+ $actions[] = array(
47
+ 'caption' => Mage::helper('mobassistantconnector')->__('Delete&nbsp;Row'),
48
+ 'url' => $this->getUrl(
49
+ '*/*/deleteDevice',
50
+ array(
51
+ 'push_id' => $row->getData('id'),
52
+ 'user_id' => $this->getRequest()->getParam('user_id')
53
+ )
54
+ ),
55
+ 'confirm' => Mage::helper('mobassistantconnector')
56
+ ->__('Are you sure you want to delete selected record?'),
57
+ 'field' => 'id',
58
+ 'data-column' => 'action'
59
+ );
60
+
61
+ $this->getColumn()->setData('actions', $actions);
62
+
63
+ return parent::render($row);
64
+ }
65
+
66
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Currency.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Currency extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $data = $row->getData($this->getColumn()->getIndex());
25
+
26
+ if (!$data) {
27
+ return '-';
28
+ } else if ($data == 'base_currency') {
29
+ return Mage::app()->getStore()->getBaseCurrencyCode();
30
+ }
31
+
32
+ return parent::render($row);
33
+ }
34
+
35
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Date.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Date extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Date
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $data = $row->getData($this->getColumn()->getIndex());
25
+
26
+ if (!$data || $data == '0000-00-00 00:00:00') {
27
+ return '-';
28
+ }
29
+
30
+ return parent::render($row);
31
+ }
32
+
33
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Grid.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Grid extends Mage_Adminhtml_Block_Widget_Grid
20
+ {
21
+
22
+ protected $_massactionBlockName = 'mobassistantconnector/adminhtml_user_edit_device_massAction';
23
+
24
+ public function __construct()
25
+ {
26
+ parent::__construct();
27
+
28
+ $this->setId('emagicone_mobassistantconnector_device_grid');
29
+ $this->setUseAjax(true);
30
+ $this->setDefaultSort('device_name');
31
+ $this->setDefaultDir('ASC');
32
+ $this->setSaveParametersInSession(false);
33
+ }
34
+
35
+ /**
36
+ * Retrieve collection class
37
+ *
38
+ * @return string
39
+ */
40
+ protected function _getCollectionClass()
41
+ {
42
+ return 'emagicone_mobassistantconnector/push_collection';
43
+ }
44
+
45
+ protected function _prepareCollection()
46
+ {
47
+ $userId = (int)$this->getRequest()->getParam('user_id');
48
+
49
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
50
+ $collection->getSelect()
51
+ ->joinLeft(
52
+ array('d' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/device')),
53
+ 'd.device_unique_id = main_table.device_unique_id',
54
+ array('device_name', 'last_activity', 'account_id')
55
+ )
56
+ ->joinLeft(
57
+ array('a' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/account')),
58
+ 'a.id = d.account_id',
59
+ array('account_email', 'status')
60
+ )
61
+ ->where("main_table.user_id = $userId");
62
+
63
+ $this->setCollection($collection);
64
+
65
+ return parent::_prepareCollection();
66
+ }
67
+
68
+ protected function _prepareColumns()
69
+ {
70
+
71
+ $this->addColumn(
72
+ 'device_name',
73
+ array(
74
+ 'header' => Mage::helper('mobassistantconnector')->__('Device Name'),
75
+ 'type' => 'text',
76
+ 'index' => 'device_name',
77
+ )
78
+ );
79
+
80
+ $this->addColumn(
81
+ 'account_email',
82
+ array(
83
+ 'header' => Mage::helper('mobassistantconnector')->__('Account Email'),
84
+ 'type' => 'text',
85
+ 'index' => 'account_email',
86
+ )
87
+ );
88
+
89
+ $this->addColumn(
90
+ 'last_activity',
91
+ array(
92
+ 'header' => Mage::helper('mobassistantconnector')->__('Last Activity'),
93
+ 'type' => 'date',
94
+ 'index' => 'last_activity',
95
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Date'
96
+ )
97
+ );
98
+
99
+ $this->addColumn(
100
+ 'app_connection_id',
101
+ array(
102
+ 'header' => Mage::helper('mobassistantconnector')->__('App Connection ID'),
103
+ 'type' => 'text',
104
+ 'index' => 'app_connection_id',
105
+ )
106
+ );
107
+
108
+ if (!Mage::app()->isSingleStoreMode()) {
109
+ $this->addColumn(
110
+ 'store_id',
111
+ array(
112
+ 'header' => Mage::helper('mobassistantconnector')->__('Store'),
113
+ 'index' => 'store_group_id',
114
+ 'filter' => false,
115
+ 'type' => 'text',
116
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Store'
117
+ )
118
+ );
119
+ }
120
+
121
+ $this->addColumn(
122
+ 'new_order',
123
+ array(
124
+ 'header' => Mage::helper('mobassistantconnector')->__('New Order'),
125
+ 'type' => 'text',
126
+ 'filter' => false,
127
+ 'index' => 'new_order',
128
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_NewOrder'
129
+ )
130
+ );
131
+
132
+ $this->addColumn(
133
+ 'new_customer',
134
+ array(
135
+ 'header' => Mage::helper('mobassistantconnector')->__('New Customer'),
136
+ 'type' => 'text',
137
+ 'filter' => false,
138
+ 'index' => 'new_customer',
139
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_NewCustomer'
140
+ )
141
+ );
142
+
143
+ $this->addColumn(
144
+ 'order_statuses',
145
+ array(
146
+ 'header' => Mage::helper('mobassistantconnector')->__('Order Statuses'),
147
+ 'type' => 'text',
148
+ 'filter' => false,
149
+ 'index' => 'order_statuses',
150
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_OrdStatuses'
151
+ )
152
+ );
153
+
154
+ $this->addColumn(
155
+ 'currency_code',
156
+ array(
157
+ 'header' => Mage::helper('mobassistantconnector')->__('Currency Code'),
158
+ 'type' => 'text',
159
+ 'filter' => false,
160
+ 'index' => 'currency_code',
161
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Currency'
162
+ )
163
+ );
164
+
165
+ $this->addColumn(
166
+ 'account_status',
167
+ array(
168
+ 'header' => Mage::helper('mobassistantconnector')->__('Status'),
169
+ 'index' => 'status',
170
+ 'type' => 'options',
171
+ 'options' => array(
172
+ 1 => Mage::helper('mobassistantconnector')->__('Enabled'),
173
+ 0 => Mage::helper('mobassistantconnector')->__('Disabled')
174
+ )
175
+ )
176
+ );
177
+
178
+ $this->addColumn(
179
+ 'action',
180
+ array(
181
+ 'header' => Mage::helper('mobassistantconnector')->__('Action'),
182
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Action',
183
+ 'type' => 'action',
184
+ 'filter' => false
185
+ )
186
+ );
187
+
188
+ return parent::_prepareColumns();
189
+ }
190
+
191
+ protected function _prepareMassaction()
192
+ {
193
+ $this->setMassactionIdField('id');
194
+ $this->getMassactionBlock()->setFormFieldName('push_ids');
195
+ $this->getMassactionBlock()->setUseSelectAll(false);
196
+
197
+ $this->getMassactionBlock()
198
+ ->addItem(
199
+ 'enable',
200
+ array(
201
+ 'label' => Mage::helper('mobassistantconnector')->__('Enable Accounts'),
202
+ 'url' => $this->getUrl(
203
+ '*/*/massChangeStatusAccount',
204
+ array('value' => 1, 'user_id' => $this->getRequest()->getParam('user_id'))
205
+ )
206
+ )
207
+ )
208
+ ->addItem(
209
+ 'disable',
210
+ array(
211
+ 'label' => Mage::helper('mobassistantconnector')->__('Disable Accounts'),
212
+ 'url' => $this->getUrl(
213
+ '*/*/massChangeStatusAccount',
214
+ array('value' => 0, 'user_id' => $this->getRequest()->getParam('user_id'))
215
+ )
216
+ )
217
+ )
218
+ ->addItem(
219
+ 'delete',
220
+ array(
221
+ 'label' => Mage::helper('mobassistantconnector')->__('Delete Rows'),
222
+ 'url' => $this->getUrl(
223
+ '*/*/massDeleteDevice',
224
+ array('user_id' => $this->getRequest()->getParam('user_id'))
225
+ ),
226
+ 'confirm' => Mage::helper('mobassistantconnector')
227
+ ->__('Are you sure you want to delete selected records?')
228
+ )
229
+ );
230
+
231
+ return $this;
232
+ }
233
+
234
+ public function getGridUrl()
235
+ {
236
+ return $this->getUrl('*/*/devices', array('_current' => true));
237
+ }
238
+
239
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/MassAction.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_MassAction extends Mage_Adminhtml_Block_Widget_Grid_Massaction_Abstract
20
+ {
21
+
22
+ public function getJavaScript()
23
+ {
24
+ return " {$this->getJsObjectName()} = new varienGridMassaction('{$this->getHtmlId()}', "
25
+ . "{$this->getGridJsObjectName()}, '{$this->getSelectedJson()}'"
26
+ . ", '{$this->getFormFieldNameInternal()}', '{$this->getFormFieldName()}');"
27
+ . "{$this->getJsObjectName()}.setItems({$this->getItemsJson()}); "
28
+ . "{$this->getJsObjectName()}.setGridIds('{$this->getGridIdsJson()}');"
29
+ . ($this->getUseAjax() ? "{$this->getJsObjectName()}.setUseAjax(true);" : '')
30
+ . ($this->getUseSelectAll() ? "{$this->getJsObjectName()}.setUseSelectAll(true);" : '')
31
+ . "{$this->getJsObjectName()}.errorText = '{$this->getErrorText()}';";
32
+ }
33
+
34
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/NewCustomer.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_NewCustomer extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $img = (int)$row->getData($this->getColumn()->getIndex()) == 1 ? 'yes.png' : 'no.png';
25
+ $out = "<div style='text-align: center; display: flex'><img style='margin: auto' src='" . $this->getSkinUrl()
26
+ . "images/emagicone/mobassistantconnector/$img'></div>";
27
+
28
+ return $out;
29
+ }
30
+
31
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/NewOrder.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_NewOrder extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $img = (int)$row->getData($this->getColumn()->getIndex()) == 1 ? 'yes.png' : 'no.png';
25
+ $out = "<div style='text-align: center; display: flex'><img style='margin: auto' src='" . $this->getSkinUrl()
26
+ . "images/emagicone/mobassistantconnector/$img'></div>";
27
+
28
+ return $out;
29
+ }
30
+
31
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/OrdStatuses.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_OrdStatuses extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Text
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $pushOrderStatuses = (string)$row->getData($this->getColumn()->getIndex());
25
+
26
+ if (empty($pushOrderStatuses)) {
27
+ return '-';
28
+ } else if ($pushOrderStatuses == '-1') {
29
+ return 'All';
30
+ }
31
+
32
+ $finalOrderStatuses = array();
33
+ $all = true;
34
+ $pushOrderStatuses = explode('|', $pushOrderStatuses);
35
+ $orderStatuses = Mage::getModel('sales/order_status')->getResourceCollection()->getData();
36
+ $countOrderStatuses = count($orderStatuses);
37
+
38
+ for ($i = 0; $i < $countOrderStatuses; $i++) {
39
+ if (in_array($orderStatuses[$i]['status'], $pushOrderStatuses)) {
40
+ $finalOrderStatuses[] = $orderStatuses[$i]['label'];
41
+ } else {
42
+ $all = false;
43
+ }
44
+ }
45
+
46
+ if ($all) {
47
+ return 'All';
48
+ } elseif (empty($finalOrderStatuses)) {
49
+ return '-';
50
+ }
51
+
52
+ return implode(', ', $finalOrderStatuses);
53
+ }
54
+
55
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Device/Store.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Device_Store extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Store
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $storeGroup = (int)$row->getData($this->getColumn()->getIndex());
25
+
26
+ if ($storeGroup == -1) {
27
+ return Mage::helper('mobassistantconnector')->__('All Stores');
28
+ } else if ($storeGroup < 1) {
29
+ return '-';
30
+ }
31
+
32
+ $out = '';
33
+ $data = $this->_getStoreModel()->getStoresStructure(false, [], [$storeGroup]);
34
+
35
+ foreach ($data as $website) {
36
+ $out .= $website['label'] . '<br/>';
37
+ foreach ($website['children'] as $group) {
38
+ $out .= str_repeat('&nbsp;', 3) . $group['label'] . '<br/>';
39
+ }
40
+ }
41
+
42
+ return $out;
43
+ }
44
+
45
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Form.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
20
+ {
21
+
22
+ protected function _prepareForm()
23
+ {
24
+ $model = Mage::registry('mobassistantconnector_user');
25
+
26
+ $form = new Varien_Data_Form(
27
+ array(
28
+ 'id' => 'edit_form',
29
+ 'action' => $this->getUrl('*/*/save', array('user_id' => $this->getRequest()->getParam('user_id'))),
30
+ 'method' => 'post'
31
+ )
32
+ );
33
+
34
+ $form->setValues($model->getData());
35
+ $form->setUseContainer(true);
36
+ $this->setForm($form);
37
+
38
+ return parent::_prepareForm();
39
+ }
40
+
41
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Devices.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Tab_Devices extends Mage_Adminhtml_Block_Widget_Grid /*implements Mage_Adminhtml_Block_Widget_Tab_Interface*/
20
+ {
21
+
22
+ /**
23
+ * Set grid params
24
+ *
25
+ */
26
+ /*public function __construct()
27
+ {
28
+ parent::__construct();
29
+
30
+ $this->setId('device.grid');
31
+ $this->setDefaultSort('device_name');
32
+ $this->setDefaultDir('DESC');
33
+ $this->setUseAjax(true);
34
+ $this->setSaveParametersInSession(false);
35
+ }*/
36
+
37
+ /**
38
+ * Return Tab label
39
+ *
40
+ * @return string
41
+ */
42
+ // public function getTabLabel()
43
+ // {
44
+ // TODO: Implement getTabLabel() method.
45
+ // }
46
+
47
+ /**
48
+ * Return Tab title
49
+ *
50
+ * @return string
51
+ */
52
+ // public function getTabTitle()
53
+ // {
54
+ // TODO: Implement getTabTitle() method.
55
+ // }
56
+
57
+ /**
58
+ * Can show tab in tabs
59
+ *
60
+ * @return boolean
61
+ */
62
+ // public function canShowTab()
63
+ // {
64
+ // TODO: Implement canShowTab() method.
65
+ // }
66
+
67
+ /**
68
+ * Tab is hidden
69
+ *
70
+ * @return boolean
71
+ */
72
+ // public function isHidden()
73
+ // {
74
+ // TODO: Implement isHidden() method.
75
+ // }
76
+
77
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Main.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Tab_Main extends Mage_Adminhtml_Block_Widget_Form implements Mage_Adminhtml_Block_Widget_Tab_Interface
20
+ {
21
+
22
+ protected function _prepareForm()
23
+ {
24
+ /* @var $model Emagicone_Mobassistantconnector_Model_User */
25
+ $model = Mage::registry('mobassistantconnector_user');
26
+ $data = array();
27
+
28
+ if ($model) {
29
+ $data = $model->getData();
30
+ }
31
+
32
+ /*
33
+ * Checking if user have permissions to save information
34
+ */
35
+ if ($this->_isAllowedAction('save')) {
36
+ $isElementDisabled = false;
37
+ } else {
38
+ $isElementDisabled = true;
39
+ }
40
+
41
+ $form = new Varien_Data_Form();
42
+
43
+ $fieldset = $form->addFieldset('base_fieldset', array('legend' => Mage::helper('mobassistantconnector')->__('User Information')));
44
+
45
+ if ($model->getId()) {
46
+ $fieldset->addField('user_id', 'hidden', array('name' => 'user_id',));
47
+ }
48
+
49
+ $fieldset->addField(
50
+ 'status',
51
+ 'select',
52
+ array(
53
+ 'label' => Mage::helper('mobassistantconnector')->__('Status'),
54
+ 'title' => Mage::helper('mobassistantconnector')->__('User Status'),
55
+ 'name' => 'status',
56
+ 'options' => $model->getStatuses(),
57
+ 'note' => 'If status is disabled user will not retrieve data in Magento Mobile Assistant App.',
58
+ 'disabled' => $isElementDisabled,
59
+ )
60
+ );
61
+
62
+ $fieldset->addField(
63
+ 'username',
64
+ 'text',
65
+ array(
66
+ 'name' => 'username',
67
+ 'label' => Mage::helper('mobassistantconnector')->__('Username'),
68
+ 'title' => Mage::helper('mobassistantconnector')->__('Username'),
69
+ 'required' => true,
70
+ 'note' => 'Login for accessing Mobile Assistant Connector from Magento Mobile Assistant App.',
71
+ 'disabled' => $isElementDisabled
72
+ )
73
+ );
74
+
75
+ $fieldset->addField(
76
+ 'password',
77
+ 'password',
78
+ array(
79
+ 'name' => 'password',
80
+ 'label' => Mage::helper('mobassistantconnector')->__('Password'),
81
+ 'title' => Mage::helper('mobassistantconnector')->__('Password'),
82
+ 'required' => true,
83
+ 'note' => 'Password for accessing Mobile Assistant Connector from Magento Mobile Assistant App.',
84
+ 'disabled' => $isElementDisabled
85
+ )
86
+ );
87
+
88
+ if ($model->getId()) {
89
+ $hash = (string)$model->getQrCodeHash();
90
+ // $baseUrl = $this->getBaseUrl();
91
+ // $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
92
+ $url = "{$this->getBaseUrl()}mobassistantconnector/index?call_function=get_qr_code&hash=$hash";
93
+ $fieldset->addField(
94
+ 'qr_code_data',
95
+ 'hidden',
96
+ array(
97
+ 'name' => 'qr_code_data',
98
+ 'value' => Mage::helper('mobassistantconnector/data')->getDataToQrCode(
99
+ Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB),
100
+ $model->getUsername(),
101
+ $model->getPassword()
102
+ )
103
+ )
104
+ );
105
+
106
+ $fieldset->addField(
107
+ 'qrcode_image',
108
+ 'label',
109
+ array(
110
+ 'label' => Mage::helper('mobassistantconnector')->__('QR-code'),
111
+ 'value' => '',
112
+ 'note' => 'Store URL and access details (login and password) for Mobile Assistant Connector are encoded
113
+ in this QR code. Scan it with special option available on connection settings page of Magento
114
+ Mobile Assistant App to autofill access settings and connect to your Magento store.',
115
+ 'disabled' => $isElementDisabled
116
+ )
117
+ );
118
+
119
+ $fieldset->addField(
120
+ 'qrcode_link',
121
+ 'link',
122
+ array(
123
+ 'label' => Mage::helper('mobassistantconnector')->__('QR-code link'),
124
+ 'href' => $url,
125
+ 'value' => 'Copy link to share QR-code',
126
+ 'target' => '_blank',
127
+ 'note' => 'QR-code can be got by this link only if status of user is active',
128
+ 'disabled' => $isElementDisabled
129
+ )
130
+ );
131
+
132
+ // $fieldset->addField('qrcode_hash', 'hidden', array('name' => 'qrcode_hash', 'value' => $hash));
133
+ }
134
+
135
+ $form->addValues($data);
136
+ $this->setForm($form);
137
+ }
138
+
139
+ /**
140
+ * Return Tab label
141
+ *
142
+ * @return string
143
+ */
144
+ public function getTabLabel()
145
+ {
146
+ return Mage::helper('mobassistantconnector')->__('User Information');
147
+ }
148
+
149
+ /**
150
+ * Return Tab title
151
+ *
152
+ * @return string
153
+ */
154
+ public function getTabTitle()
155
+ {
156
+ return Mage::helper('mobassistantconnector')->__('User Information');
157
+ }
158
+
159
+ /**
160
+ * Can show tab in tabs
161
+ *
162
+ * @return boolean
163
+ */
164
+ public function canShowTab()
165
+ {
166
+ return true;
167
+ }
168
+
169
+ /**
170
+ * Tab is hidden
171
+ *
172
+ * @return boolean
173
+ */
174
+ public function isHidden()
175
+ {
176
+ return false;
177
+ }
178
+
179
+ /**
180
+ * Check permission for passed action
181
+ *
182
+ * @param string $action
183
+ * @return bool
184
+ */
185
+ protected function _isAllowedAction($action)
186
+ {
187
+ return Mage::getSingleton('admin/session')->isAllowed('user/' . $action);
188
+ }
189
+
190
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tab/Permissions.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Tab_Permissions extends Mage_Adminhtml_Block_Widget_Form implements Mage_Adminhtml_Block_Widget_Tab_Interface
20
+ {
21
+
22
+ protected function _prepareForm()
23
+ {
24
+ /* @var $model Emagicone_Mobassistantconnector_Model_User */
25
+ $model = Mage::registry('mobassistantconnector_user');
26
+ $data = array();
27
+
28
+ if ($model) {
29
+ $data = $model->getData();
30
+ }
31
+
32
+ /*
33
+ * Checking if user have permissions to save information
34
+ */
35
+ $isElementDisabled = $this->_isAllowedAction('save') ? true : false;
36
+
37
+ $form = new Varien_Data_Form();
38
+
39
+ $fieldset = $form->addFieldset(
40
+ 'base_fieldset',
41
+ array('legend' => Mage::helper('mobassistantconnector')->__('Permissions'))
42
+ );
43
+ $userPermissionCodes = array();
44
+
45
+ if ($model->getId()) {
46
+ $fieldset->addField('user_id', 'hidden', array('name' => 'user_id',));
47
+ $userPermissionCodes = explode(';', $model->getAllowedActions());
48
+ }
49
+
50
+ $contentField = $fieldset->addField(
51
+ 'mass_checked',
52
+ 'hidden',
53
+ array('name' => 'mass_checked')
54
+ );
55
+ $renderer = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element')
56
+ ->setTemplate('mobassistantconnector/permissions.phtml');
57
+ $contentField->setRenderer($renderer);
58
+
59
+ $permissions = Mage::helper('mobassistantconnector/userPermissions')->getRestrictedActions();
60
+ $count = count($permissions);
61
+
62
+ for ($i = 0; $i < $count; $i++) {
63
+ $countChild = count($permissions[$i]['child']);
64
+ $values = array();
65
+ $checked = array();
66
+
67
+ for ($j = 0; $j < $countChild; $j++) {
68
+ if (in_array($permissions[$i]['child'][$j]['code'], $userPermissionCodes)) {
69
+ $checked[] = $permissions[$i]['child'][$j]['code'];
70
+ }
71
+
72
+ $values[] = array(
73
+ 'label' => $permissions[$i]['child'][$j]['name'],
74
+ 'value' => $permissions[$i]['child'][$j]['code'],
75
+ );
76
+ }
77
+
78
+ $fieldset->addField(
79
+ "permissions_$i",
80
+ 'checkboxes',
81
+ array(
82
+ 'name' => 'allowed_actions[]',
83
+ 'label' => $permissions[$i]['group_name'],
84
+ 'values' => $values,
85
+ 'value' => $checked,
86
+ 'class' => 'admin__control-checkbox',
87
+ 'disabled' => $isElementDisabled
88
+ )
89
+ );
90
+ }
91
+
92
+ $form->addValues($data);
93
+ $this->setForm($form);
94
+ }
95
+
96
+ /**
97
+ * Return Tab label
98
+ *
99
+ * @return string
100
+ */
101
+ public function getTabLabel()
102
+ {
103
+ return Mage::helper('mobassistantconnector')->__('Permissions');
104
+ }
105
+
106
+ /**
107
+ * Return Tab title
108
+ *
109
+ * @return string
110
+ */
111
+ public function getTabTitle()
112
+ {
113
+ return Mage::helper('mobassistantconnector')->__('Permissions');
114
+ }
115
+
116
+ /**
117
+ * Can show tab in tabs
118
+ *
119
+ * @return boolean
120
+ */
121
+ public function canShowTab()
122
+ {
123
+ return true;
124
+ }
125
+
126
+ /**
127
+ * Tab is hidden
128
+ *
129
+ * @return boolean
130
+ */
131
+ public function isHidden()
132
+ {
133
+ return false;
134
+ }
135
+
136
+ /**
137
+ * Check permission for passed action
138
+ *
139
+ * @param string $action
140
+ * @return bool
141
+ */
142
+ protected function _isAllowedAction($action)
143
+ {
144
+ return Mage::getSingleton('admin/session')->isAllowed('user/' . $action);
145
+ }
146
+
147
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Edit/Tabs.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
20
+ {
21
+
22
+ public function __construct()
23
+ {
24
+ parent::__construct();
25
+
26
+ $this->setId('user_tabs');
27
+ $this->setDestElementId('edit_form');
28
+ $this->setTitle($this->__('User Information'));
29
+ }
30
+
31
+ protected function _beforeToHtml()
32
+ {
33
+ /*$this->addTab(
34
+ 'main_section',
35
+ array(
36
+ 'label' => Mage::helper('mobassistantconnector')->__('User Information'),
37
+ 'title' => Mage::helper('mobassistantconnector')->__('User Information'),
38
+ 'content' => $this->getLayout()->createBlock('mobassistantconnector/adminhtml_user_edit_tab_main')
39
+ ->toHtml(),
40
+ )
41
+ );
42
+
43
+ $this->addTab(
44
+ 'permissions_section',
45
+ array(
46
+ 'label' => Mage::helper('mobassistantconnector')->__('Permissions'),
47
+ 'title' => Mage::helper('mobassistantconnector')->__('Permissions'),
48
+ 'content' => $this->getLayout()->createBlock('mobassistantconnector/adminhtml_user_edit_tab_permissions')
49
+ ->toHtml(),
50
+ )
51
+ );*/
52
+
53
+ if ($this->getRequest()->getParam('user_id', false)) {
54
+ $this->addTab(
55
+ 'devices_section',
56
+ array(
57
+ 'label' => Mage::helper('mobassistantconnector')->__('Devices'),
58
+ 'title' => Mage::helper('mobassistantconnector')->__('Devices'),
59
+ // 'content' => $this->getLayout()->createBlock('mobassistantconnector/adminhtml_user_edit_device_grid')
60
+ // ->toHtml(),
61
+ 'url' => $this->getUrl('*/*/devices', array('_current' => true)),
62
+ 'class' => 'ajax'
63
+ )
64
+ );
65
+ }
66
+
67
+ return parent::_beforeToHtml();
68
+ }
69
+
70
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Grid.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Grid extends Mage_Adminhtml_Block_Widget_Grid
20
+ {
21
+
22
+ public function __construct()
23
+ {
24
+ parent::__construct();
25
+ $this->setId('emagicone_mobassistantconnector_user_grid');
26
+ $this->setUseAjax(true);
27
+ $this->setDefaultSort('user_id');
28
+ $this->setDefaultDir('ASC');
29
+ $this->setSaveParametersInSession(true);
30
+ }
31
+
32
+ /**
33
+ * Retrieve collection class
34
+ *
35
+ * @return string
36
+ */
37
+ protected function _getCollectionClass()
38
+ {
39
+ return 'emagicone_mobassistantconnector/user_collection';
40
+ }
41
+
42
+ protected function _prepareCollection()
43
+ {
44
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
45
+ $this->setCollection($collection);
46
+ return parent::_prepareCollection();
47
+ }
48
+
49
+ protected function _prepareColumns()
50
+ {
51
+
52
+ $this->addColumn(
53
+ 'user_id',
54
+ array(
55
+ 'header' => Mage::helper('mobassistantconnector')->__('ID'),
56
+ 'type' => 'text',
57
+ 'index' => 'user_id',
58
+ 'width' => '80px'
59
+ )
60
+ );
61
+
62
+ $this->addColumn(
63
+ 'username',
64
+ array(
65
+ 'header' => Mage::helper('mobassistantconnector')->__('Username'),
66
+ 'type' => 'text',
67
+ 'index' => 'username',
68
+ )
69
+ );
70
+
71
+ $this->addColumn(
72
+ 'status',
73
+ array(
74
+ 'header' => Mage::helper('mobassistantconnector')->__('Status'),
75
+ 'width' => '100px',
76
+ 'index' => 'status',
77
+ 'type' => 'options',
78
+ 'options' => Emagicone_Mobassistantconnector_Model_User::getStatuses(),
79
+ )
80
+ );
81
+
82
+ $this->addColumn(
83
+ 'allowed_actions',
84
+ array(
85
+ 'header' => Mage::helper('mobassistantconnector')->__('Permissions'),
86
+ 'type' => 'text',
87
+ 'index' => 'allowed_actions',
88
+ 'renderer' => 'Emagicone_Mobassistantconnector_Block_Adminhtml_User_Renderer_Permissions',
89
+ 'filter' => false
90
+ )
91
+ );
92
+
93
+ $this->addColumn(
94
+ 'action',
95
+ array(
96
+ 'header' => Mage::helper('mobassistantconnector')->__('Action'),
97
+ 'width' => '100px',
98
+ 'type' => 'action',
99
+ 'getter' => 'getId',
100
+ 'actions' => array(
101
+ array(
102
+ 'caption' => Mage::helper('mobassistantconnector')->__('Edit'),
103
+ 'url' => array('base'=>'*/*/edit'),
104
+ 'field' => 'user_id',
105
+ 'data-column' => 'action',
106
+ ),
107
+ array(
108
+ 'caption' => Mage::helper('mobassistantconnector')->__('Delete'),
109
+ 'url' => array('base'=>'*/*/delete'),
110
+ 'field' => 'user_id',
111
+ 'data-column' => 'action',
112
+ 'confirm' => Mage::helper('mobassistantconnector')
113
+ ->__('Are you sure you want to delete selected user?')
114
+ )
115
+ ),
116
+ 'filter' => false,
117
+ 'sortable' => false,
118
+ 'is_system' => true,
119
+ )
120
+ );
121
+
122
+ return parent::_prepareColumns();
123
+ }
124
+
125
+ protected function _prepareMassaction()
126
+ {
127
+ $this->setMassactionIdField('user_id');
128
+ $this->getMassactionBlock()->setFormFieldName('user_ids');
129
+ $this->getMassactionBlock()->setUseSelectAll(false);
130
+
131
+ $this->getMassactionBlock()
132
+ ->addItem(
133
+ 'enable',
134
+ array(
135
+ 'label' => Mage::helper('mobassistantconnector')->__('Enable'),
136
+ 'url' => $this->getUrl('*/user/massEnable'),
137
+ )
138
+ )
139
+ ->addItem(
140
+ 'disable',
141
+ array(
142
+ 'label' => Mage::helper('mobassistantconnector')->__('Disable'),
143
+ 'url' => $this->getUrl('*/user/massDisable'),
144
+ )
145
+ )
146
+ ->addItem(
147
+ 'delete',
148
+ array(
149
+ 'label' => Mage::helper('mobassistantconnector')->__('Delete'),
150
+ 'url' => $this->getUrl('*/user/massDelete'),
151
+ 'confirm' => Mage::helper('mobassistantconnector')
152
+ ->__('Are you sure you want to delete selected users?')
153
+ )
154
+ );
155
+
156
+ return $this;
157
+ }
158
+
159
+ public function getGridUrl()
160
+ {
161
+ return $this->getUrl('*/*/grid', array('_current'=> true));
162
+ }
163
+
164
+ public function getRowUrl($row)
165
+ {
166
+ return $this->getUrl('*/*/edit', array('user_id' => $row->getId()));
167
+ }
168
+
169
+ }
app/code/community/Emagicone/Mobassistantconnector/Block/Adminhtml/User/Renderer/Permissions.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Block_Adminhtml_User_Renderer_Permissions extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
20
+ {
21
+
22
+ public function render(Varien_Object $row)
23
+ {
24
+ $data = $row->getData($this->getColumn()->getIndex());
25
+ $action_codes = !empty($data) ? explode(';', $data) : '';
26
+
27
+ return Emagicone_Mobassistantconnector_Helper_UserPermissions::getUserAllowedActionsAsString($action_codes);
28
+ }
29
+
30
+ }
app/code/community/Emagicone/Mobassistantconnector/Helper/Access.php CHANGED
@@ -27,117 +27,191 @@ class Emagicone_Mobassistantconnector_Helper_Access extends Mage_Core_Helper_Abs
27
  {
28
  $timestamp = time();
29
  $date = Mage::getStoreConfig('mobassistantconnectorinfosec/access/cl_date');
 
30
 
31
- if ($date === false || ($timestamp - (int)$date) > self::MAX_LIFETIME)
32
- {
33
- $sessions = Mage::getModel("emagicone_mobassistantconnector/sessions")->getCollection();
34
- $sessions->addFieldToFilter('date_added', array('lt' => ($timestamp - self::MAX_LIFETIME)));
35
  foreach ($sessions as $session) {
36
  $session->delete();
37
  }
38
 
39
- $attempts = Mage::getModel("emagicone_mobassistantconnector/failed")->getCollection();
40
- $attempts->addFieldToFilter('date_added', array('lt' => ($timestamp - self::MAX_LIFETIME)));
 
41
  foreach ($attempts as $attempt) {
42
  $attempt->delete();
43
  }
44
 
45
- Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/cl_date', $timestamp );
 
46
  }
47
  }
48
 
49
- public static function clearAllData()
50
  {
51
- $timestamp = time();
 
52
 
53
- $sessions = Mage::getModel("emagicone_mobassistantconnector/sessions")->getCollection();
54
- foreach ($sessions as $session) {
55
- $session->delete();
56
  }
57
 
58
- $attempts = Mage::getModel("emagicone_mobassistantconnector/failed")->getCollection();
59
- foreach ($attempts as $attempt) {
60
- $attempt->delete();
61
  }
62
 
63
- Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/cl_date', $timestamp );
 
64
  }
65
 
66
- public static function getSessionKey($hash)
67
  {
68
- $login = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/login');
69
- $password = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/password');
 
 
 
 
 
 
70
 
71
- if (hash(self::HASH_ALGORITHM, $login.$password) == $hash)
72
- return self::generateSessionKey($login);
73
- else
74
- self::addFailedAttempt();
75
 
 
76
  return false;
77
  }
78
 
79
- public static function checkSessionKey($key)
80
  {
81
- if(!empty($key)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- $timestamp = time();
 
84
 
85
- $sessions = Mage::getModel("emagicone_mobassistantconnector/sessions")->getCollection();
86
- $sessions->addFieldToFilter('date_added', array('gt' => ($timestamp - self::MAX_LIFETIME)));
87
- $sessions->addFieldToFilter('session_key', array('eq' => $key));
 
88
 
89
- if($sessions->getSize() > 0) {
90
- return true;
91
- } else {
92
- self::addFailedAttempt();
93
  }
94
  }
95
 
 
 
 
 
96
  return false;
97
  }
98
 
99
- public static function generateSessionKey($username)
100
  {
101
- $timestamp = time();
 
102
 
103
- $enc_key = (string)Mage::getConfig()->getNode('global/crypt/key');
 
 
104
 
105
- $key = hash(self::HASH_ALGORITHM, $enc_key.$username.$timestamp);
 
106
 
107
- $sessions = Mage::getModel("emagicone_mobassistantconnector/sessions");
108
- $sessions->setData(array('session_key' => $key, 'date_added' => $timestamp));
109
- $sessions->save();
110
 
111
- return $key;
112
  }
113
 
114
- public static function addFailedAttempt()
115
  {
116
- $timestamp = time();
 
117
 
118
- $attempts = Mage::getModel("emagicone_mobassistantconnector/failed");
119
- $attempts->setData(array('ip' => $_SERVER['REMOTE_ADDR'], 'date_added' => $timestamp));
120
- $attempts->save();
121
 
 
122
 
123
- $attempts = Mage::getModel("emagicone_mobassistantconnector/failed")->getCollection();
124
- $attempts->addFieldToFilter('date_added', array('gt' => ($timestamp - self::MAX_LIFETIME)));
125
- $attempts->addFieldToFilter('ip', array('eq' => $_SERVER['REMOTE_ADDR']));
126
- $count_failed_attempts = $attempts->getSize();
127
 
128
- self::setDelay((int)$count_failed_attempts);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
  private static function setDelay($count_attempts)
132
  {
133
- if ($count_attempts <= 10)
134
- sleep(2);
135
- elseif ($count_attempts <= 20)
136
  sleep(5);
137
- elseif ($count_attempts <= 50)
138
  sleep(10);
139
- else
140
  sleep(20);
 
141
  }
142
 
143
  }
27
  {
28
  $timestamp = time();
29
  $date = Mage::getStoreConfig('mobassistantconnectorinfosec/access/cl_date');
30
+ $dateDelete = $timestamp - self::MAX_LIFETIME;
31
 
32
+ if ($date === false || ($timestamp - (int)$date) > self::MAX_LIFETIME) {
33
+ // Delete old session keys
34
+ $sessions = Mage::getModel('emagicone_mobassistantconnector/sessions')->getCollection()
35
+ ->addFieldToFilter('date_added', array('lt' => $dateDelete));
36
  foreach ($sessions as $session) {
37
  $session->delete();
38
  }
39
 
40
+ // Delete old failed logins
41
+ $attempts = Mage::getModel('emagicone_mobassistantconnector/failed')->getCollection()
42
+ ->addFieldToFilter('date_added', array('lt' => $dateDelete));
43
  foreach ($attempts as $attempt) {
44
  $attempt->delete();
45
  }
46
 
47
+ // Update clearing date in core_config_data table
48
+ Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/cl_date', $timestamp);
49
  }
50
  }
51
 
52
+ public static function getSessionKey($hash, $user_id = false)
53
  {
54
+ if (!$user_id) {
55
+ $login_data = self::checkAuth($hash);
56
 
57
+ if ($login_data) {
58
+ $user_id = (int)$login_data['user_id'];
59
+ }
60
  }
61
 
62
+ if ($user_id) {
63
+ return self::generateSessionKey($user_id);
 
64
  }
65
 
66
+ self::addFailedAttempt();
67
+ return false;
68
  }
69
 
70
+ public static function checkSessionKey($key, $user_id = false)
71
  {
72
+ $sessions = Mage::getModel('emagicone_mobassistantconnector/sessions')
73
+ ->getCollection()
74
+ ->addFieldToFilter('date_added', array('gt' => (time() - self::MAX_LIFETIME)))
75
+ ->addFieldToFilter('session_key', array('eg' => $key));
76
+
77
+ if ($user_id) {
78
+ $sessions->addFieldToFilter('user_id', array('eg' => (int)$user_id));
79
+ }
80
 
81
+ if ($sessions->getSize() > 0) {
82
+ return true;
83
+ }
 
84
 
85
+ self::addFailedAttempt();
86
  return false;
87
  }
88
 
89
+ public static function generateSessionKey($user_id)
90
  {
91
+ $timestamp = time();
92
+ $sessions = Mage::getModel('emagicone_mobassistantconnector/sessions')
93
+ ->getCollection()
94
+ ->addFieldToFilter('date_added', array('gt' => ($timestamp - self::MAX_LIFETIME)))
95
+ ->addFieldToFilter('user_id', array('eg' => (int)$user_id));
96
+
97
+ foreach ($sessions as $session) {
98
+ return $session->getSessionKey();
99
+ }
100
+
101
+ $enc_key = (string)Mage::getConfig()->getNode('global/crypt/key');
102
+ $key = hash(self::HASH_ALGORITHM, $enc_key . $user_id . $timestamp);
103
+
104
+ Mage::getModel('emagicone_mobassistantconnector/sessions')
105
+ ->loadByUserId($user_id)
106
+ ->setData(array('user_id' => $user_id, 'session_key' => $key, 'date_added' => $timestamp))
107
+ ->save();
108
+
109
+ return $key;
110
+ }
111
+
112
+ public static function addFailedAttempt()
113
+ {
114
+ $timestamp = time();
115
+
116
+ // Add data to database
117
+ Mage::getModel('emagicone_mobassistantconnector/failed')
118
+ ->setData(array('ip' => $_SERVER['REMOTE_ADDR'], 'date_added' => $timestamp))
119
+ ->save();
120
+
121
+ // Get count of failed attempts for last time and set delay
122
+ $attempts = Mage::getModel('emagicone_mobassistantconnector/failed')->getCollection()
123
+ ->addFieldToFilter('date_added', array('gt' => ($timestamp - self::MAX_LIFETIME)))
124
+ ->addFieldToFilter('ip', array('eq' => $_SERVER['REMOTE_ADDR']));
125
+ $count_failed_attempts = $attempts->getSize();
126
 
127
+ self::setDelay((int)$count_failed_attempts);
128
+ }
129
 
130
+ public static function checkAuth($hash, $is_log = false)
131
+ {
132
+ $users = Mage::getModel('emagicone_mobassistantconnector/user')->getCollection()
133
+ ->addFieldToFilter('status', array('eq' => 1));
134
 
135
+ foreach ($users as $user) {
136
+ if (hash(self::HASH_ALGORITHM, $user->getUsername() . $user->getPassword()) == $hash) {
137
+ return $user->toArray();
 
138
  }
139
  }
140
 
141
+ if ($is_log) {
142
+ Mage::log('Hash accepted is incorrect', null, 'emagicone_mobassistantconnector.log');
143
+ }
144
+
145
  return false;
146
  }
147
 
148
+ public static function getAllowedActionsBySessionKey($key)
149
  {
150
+ $result = array();
151
+ $sessionKey = Mage::getModel('emagicone_mobassistantconnector/sessions')->load($key, 'session_key');
152
 
153
+ if (!$sessionKey->getId()) {
154
+ return $result;
155
+ }
156
 
157
+ $user = Mage::getModel('emagicone_mobassistantconnector/user')->load($sessionKey->getUserId());
158
+ $allowedActions = $user->getAllowedActions();
159
 
160
+ if (!empty($allowedActions)) {
161
+ $result = explode(';', $allowedActions);
162
+ }
163
 
164
+ return $result;
165
  }
166
 
167
+ public static function getAllowedActionsByUserId($user_id)
168
  {
169
+ $result = array();
170
+ $user = Mage::getModel('emagicone_mobassistantconnector/user')->load($user_id);
171
 
172
+ if (!$user->getId()) {
173
+ return $result;
174
+ }
175
 
176
+ $allowedActions = $user->getAllowedActions();
177
 
178
+ if (!empty($allowedActions)) {
179
+ $result = explode(';', $allowedActions);
180
+ }
 
181
 
182
+ return $result;
183
+ }
184
+
185
+ public static function getUserIdBySessionKey($key)
186
+ {
187
+ $user_id = false;
188
+ $users = Mage::getModel('emagicone_mobassistantconnector/user')->getCollection();
189
+ $users->getSelect()
190
+ ->joinLeft(
191
+ array('k' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/sessions')),
192
+ 'k.user_id = main_table.user_id'
193
+ )
194
+ ->where("k.session_key = '$key' AND main_table.`status` = 1");
195
+
196
+ foreach ($users as $user) {
197
+ $user_id = $user->getUserId();
198
+ break;
199
+ }
200
+
201
+ return $user_id;
202
  }
203
 
204
  private static function setDelay($count_attempts)
205
  {
206
+ if ($count_attempts > 3 && $count_attempts <= 10) {
207
+ sleep(1);
208
+ } elseif ($count_attempts <= 20) {
209
  sleep(5);
210
+ } elseif ($count_attempts <= 50) {
211
  sleep(10);
212
+ } else {
213
  sleep(20);
214
+ }
215
  }
216
 
217
  }
app/code/community/Emagicone/Mobassistantconnector/Helper/Data.php CHANGED
@@ -18,145 +18,6 @@
18
 
19
  class Emagicone_Mobassistantconnector_Helper_Data extends Mage_Core_Helper_Abstract
20
  {
21
- public function sendPushMessage($messageContent) {
22
- Mage::app()->cleanCache();
23
- $apiKey = Mage::getStoreConfig('mobassistantconnectorinfosec/access/api_key');
24
- $headers = array('Authorization: key=' . $apiKey, 'Content-Type: application/json');
25
-
26
- $ch = curl_init();
27
- curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send');
28
- curl_setopt($ch, CURLOPT_POST, true);
29
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
30
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
31
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
32
- //curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
33
- curl_setopt($ch, CURLOPT_POSTFIELDS, $messageContent);
34
- $result = curl_exec( $ch );
35
-
36
- if(curl_errno($ch)) {
37
- Mage::log(
38
- "Push message error while sending CURL request: {$result}",
39
- null,
40
- 'emagicone_mobassistantconnector.log'
41
- );
42
- }
43
-
44
- curl_close($ch);
45
-
46
- return $result;
47
- }
48
-
49
- public function pushSettingsUpgrade() {
50
- Mage::app()->getCacheInstance()->cleanType('config');
51
- $deviceIds = Mage::getStoreConfig('mobassistantconnectorinfosec/access/google_ids');
52
-
53
- if(strlen($deviceIds) > 0) {
54
- $deviceIds = unserialize($deviceIds);
55
- } else $deviceIds = array();
56
-
57
- foreach(array_keys($deviceIds) as $key) {
58
- if (!is_int($key)) {
59
- $deviceIds[$key]['push_device_id'] = $key;
60
- if(empty($deviceIds[$key]['push_store_group_id'])) {
61
- $deviceIds[$key]['push_store_group_id'] = -1;
62
- }
63
- if(empty($deviceIds[$key]['push_currency_code'])) {
64
- $deviceIds[$key]['push_currency_code'] = 'base_currency';
65
- }
66
- if(empty($deviceIds[$key]['app_connection_id'])) {
67
- $deviceIds[$key]['app_connection_id'] = -1;
68
- }
69
- array_push($deviceIds, $deviceIds[$key]);
70
- unset($deviceIds[$key]);
71
- }
72
- }
73
-
74
- //Check for duplicated records
75
- foreach ($deviceIds as $a1 => $firstDevice) {
76
- if(empty($firstDevice['push_currency_code'])) {
77
- $deviceIds[$a1]['push_currency_code'] = 'base_currency';
78
- }
79
- if(empty($deviceIds[$key]['app_connection_id'])) {
80
- $deviceIds[$key]['app_connection_id'] = -1;
81
- }
82
- foreach($deviceIds as $a2 => $secondDevice){
83
- if(($firstDevice === $secondDevice) && ($a1 != $a2)) {
84
- unset($deviceIds[$a1]);
85
- }
86
- }
87
- }
88
-
89
- return $deviceIds;
90
- }
91
-
92
- public function proceedGoogleResponse($response, $current_device) {
93
- if ($response) {
94
- $json = json_decode($response, true);
95
- if (function_exists('json_last_error')) {
96
- if (json_last_error() != JSON_ERROR_NONE) {
97
- $json = array();
98
- }
99
- // $d_r = Mage::helper('core')->jsonDecode($response, Zend_Json::TYPE_OBJECT);
100
- if (!empty($json)) {
101
- $json_response = var_export($json, true);
102
- Mage::log(
103
- "Google response: ({$json_response})",
104
- null,
105
- 'emagicone_mobassistantconnector.log'
106
- );
107
- }
108
- }
109
- }
110
- else {
111
- $json = array();
112
- }
113
- Mage::app(0);
114
-
115
- $deviceIdActions = Mage::helper('mobassistantconnector')->pushSettingsUpgrade();
116
-
117
- $currentDeviceId = $current_device['device_id'];
118
- $currentAppConnectionId = $current_device['app_connection_id'];
119
-
120
- $failure = isset($json['failure']) ? $json['failure'] : null;
121
-
122
- $canonicalIds = isset($json['canonical_ids']) ? $json['canonical_ids'] : null;
123
-
124
- if ($failure || $canonicalIds) {
125
- $result = isset($json['results'][0]) ? $json['results'][0] : array();
126
-
127
- $newRegId = isset($result['registration_id']) ? $result['registration_id'] : null;
128
- $error = isset($result['error']) ? $result['error'] : null;
129
- if ($newRegId) {
130
- // Need to update old deviceId
131
- if ($newRegId !== $currentDeviceId) {
132
- foreach ($deviceIdActions as $settingNum => $device) {
133
- // Delete duplicated push configs with new RegistrationId
134
- if ($device['app_connection'] == $currentAppConnectionId && $device['push_device_id'] == $newRegId) {
135
- unset($deviceIdActions[$settingNum]);
136
- // Renew push config with new RegistrationId
137
- } elseif ($device['push_device_id'] == $currentDeviceId) {
138
- $deviceIdActions[$settingNum]['push_device_id'] = $newRegId;
139
- }
140
- }
141
- }
142
- }
143
- else if ($error) {
144
- // Unset not registered device id
145
- if ($error == 'NotRegistered' || $error == 'InvalidRegistration') {
146
- foreach ($deviceIdActions as $settingNum => $device) {
147
- if($device['push_device_id'] == $currentDeviceId) {
148
- unset($deviceIdActions[$settingNum]);
149
- }
150
- }
151
- }
152
- }
153
- }
154
-
155
- Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/google_ids', serialize($deviceIdActions));
156
- Mage::app()->init('');
157
-
158
- return $deviceIdActions;
159
- }
160
 
161
  public function price_format($iso_code, $curr_format, $price, $convert_to, $force = false, $format = true) {
162
  $currency_symbol = '';
@@ -175,36 +36,35 @@ class Emagicone_Mobassistantconnector_Helper_Data extends Mage_Core_Helper_Abstr
175
  }
176
 
177
  $iso_code = $convert_to;
178
- } catch(Exception $e) {
179
  Mage::log(
180
  "Error while currency converting (". var_export($e->getMessage(), true). ")",
181
  null,
182
  'emagicone_mobassistantconnector.log'
183
  );
184
  }
185
-
186
  }
187
 
188
- if($format) {
189
  $price = number_format(floatval($price), 2, '.', ' ');
190
  }
191
 
192
  preg_match('/^[a-zA-Z]+$/', $iso_code, $matches);
193
 
194
- if(count($matches) > 0) {
195
- if(strlen($matches[0]) == 3) {
196
  $currency_symbol = Mage::app()->getLocale()->currency($iso_code)->getSymbol();
197
  }
198
  } else {
199
  $currency_symbol = $iso_code;
200
  }
201
 
202
- if($force) {
203
  return $currency_symbol;
204
  }
205
  // $sign = '<span>' . $currency_symbol . '</span>';
206
  $sign = $currency_symbol;
207
- if($curr_format == 1) {
208
  $price = $sign . $price;
209
  } elseif ($curr_format == 2) {
210
  $price = $price;
@@ -214,4 +74,20 @@ class Emagicone_Mobassistantconnector_Helper_Data extends Mage_Core_Helper_Abstr
214
 
215
  return $price;
216
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
18
 
19
  class Emagicone_Mobassistantconnector_Helper_Data extends Mage_Core_Helper_Abstract
20
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  public function price_format($iso_code, $curr_format, $price, $convert_to, $force = false, $format = true) {
23
  $currency_symbol = '';
36
  }
37
 
38
  $iso_code = $convert_to;
39
+ } catch (Exception $e) {
40
  Mage::log(
41
  "Error while currency converting (". var_export($e->getMessage(), true). ")",
42
  null,
43
  'emagicone_mobassistantconnector.log'
44
  );
45
  }
 
46
  }
47
 
48
+ if ($format) {
49
  $price = number_format(floatval($price), 2, '.', ' ');
50
  }
51
 
52
  preg_match('/^[a-zA-Z]+$/', $iso_code, $matches);
53
 
54
+ if (count($matches) > 0) {
55
+ if (strlen($matches[0]) == 3) {
56
  $currency_symbol = Mage::app()->getLocale()->currency($iso_code)->getSymbol();
57
  }
58
  } else {
59
  $currency_symbol = $iso_code;
60
  }
61
 
62
+ if ($force) {
63
  return $currency_symbol;
64
  }
65
  // $sign = '<span>' . $currency_symbol . '</span>';
66
  $sign = $currency_symbol;
67
+ if ($curr_format == 1) {
68
  $price = $sign . $price;
69
  } elseif ($curr_format == 2) {
70
  $price = $price;
74
 
75
  return $price;
76
  }
77
+
78
+ public static function getDataToQrCode($base_url, $username, $password)
79
+ {
80
+ $base_url = str_replace('http://', '', $base_url);
81
+ $base_url = str_replace('https://', '', $base_url);
82
+ preg_replace('/\/*$/i', '', $base_url);
83
+
84
+ $data = array(
85
+ 'url' => $base_url,
86
+ 'login' => $username,
87
+ 'password' => $password
88
+ );
89
+
90
+ return base64_encode($data = Mage::helper('core')->jsonEncode($data));
91
+ }
92
+
93
  }
app/code/community/Emagicone/Mobassistantconnector/Helper/DeviceAndPushNotification.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Helper_DeviceAndPushNotification extends Mage_Core_Helper_Abstract
20
+ {
21
+
22
+ public static function deletePushSettingByRegAndCon($registration_id, $app_connection_id)
23
+ {
24
+ $result = false;
25
+
26
+ $pushes = Mage::getModel('emagicone_mobassistantconnector/push')
27
+ ->getCollection()
28
+ ->addFieldToFilter(
29
+ array('device_id', 'app_connection_id'),
30
+ array(array('eq' => $registration_id), array('eq' => $app_connection_id))
31
+ );
32
+
33
+ foreach ($pushes as $push) {
34
+ try {
35
+ $push->delete();
36
+ $result = true;
37
+ } catch (Exception $e) {
38
+ $result = false;
39
+ Mage::log(
40
+ "Unable to delete push settings by reg_id and con_id ({$e->getMessage()}).",
41
+ null,
42
+ 'emagicone_mobassistantconnector.log'
43
+ );
44
+ }
45
+ }
46
+
47
+ return $result;
48
+ }
49
+
50
+ public static function deleteEmptyDevices()
51
+ {
52
+ $result = false;
53
+
54
+ $devices = Mage::getModel('emagicone_mobassistantconnector/device')->getCollection();
55
+ $devices->getSelect()->joinLeft(
56
+ array('p' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/push')),
57
+ 'main_table.`device_unique_id` = p.`device_unique_id`',
58
+ 'p.device_unique_id AS dev_id'
59
+ );
60
+ $devices->addFieldToFilter('p.device_unique_id', array('null' => true));
61
+
62
+ foreach ($devices as $device) {
63
+ try {
64
+ $device->delete();
65
+ $result = true;
66
+ } catch (Exception $e) {
67
+ $result = false;
68
+ Mage::log(
69
+ "Unable to delete device ({$e->getMessage()}).",
70
+ null,
71
+ 'emagicone_mobassistantconnector.log'
72
+ );
73
+ }
74
+ }
75
+
76
+ return $result;
77
+ }
78
+
79
+ public static function deleteEmptyAccounts()
80
+ {
81
+ $result = false;
82
+
83
+ $accounts = Mage::getModel('emagicone_mobassistantconnector/account')->getCollection();
84
+ $accounts->getSelect()->joinLeft(
85
+ array('d' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/device')),
86
+ 'main_table.`id` = d.`account_id`',
87
+ array()
88
+ );
89
+ $accounts->addFieldToFilter('d.account_id', array('null' => true));
90
+
91
+ foreach ($accounts as $account) {
92
+ try {
93
+ $account->delete();
94
+ $result = true;
95
+ } catch (Exception $e) {
96
+ $result = false;
97
+ Mage::log(
98
+ "Unable to delete account ({$e->getMessage()}).",
99
+ null,
100
+ 'emagicone_mobassistantconnector.log'
101
+ );
102
+ }
103
+ }
104
+
105
+ return $result;
106
+ }
107
+
108
+ public static function updateOldPushRegId($registration_id_old, $registration_id_new)
109
+ {
110
+ $result = true;
111
+
112
+ try {
113
+ $pushes = Mage::getModel('emagicone_mobassistantconnector/push')
114
+ ->getCollection()
115
+ ->addFieldToFilter('device_id', array('eq' => $registration_id_old));
116
+
117
+ foreach ($pushes as $push) {
118
+ $push->setData('device_id', $registration_id_new)->save();
119
+ }
120
+ } catch (Exception $e) {
121
+ $result = false;
122
+ Mage::log(
123
+ "Unable to update push notification ({$e->getMessage()}).",
124
+ null,
125
+ 'emagicone_mobassistantconnector.log'
126
+ );
127
+ }
128
+
129
+ return $result;
130
+ }
131
+
132
+ public static function addDevice($data)
133
+ {
134
+ $result = false;
135
+
136
+ if (!empty($data)) {
137
+ try {
138
+ $device = Mage::getModel('emagicone_mobassistantconnector/device')
139
+ ->loadByDeviceUniqueAndAccountId($data['device_unique'], $data['account_id'])
140
+ ->setData('device_name', $data['device_name'])
141
+ ->setData('last_activity', $data['last_activity'])
142
+ ->save();
143
+
144
+ $result = $device->getId();
145
+ } catch (Exception $e) {
146
+ Mage::log("Unable to insert device ({$e->getMessage()}).", null, 'emagicone_mobassistantconnector.log');
147
+ }
148
+ }
149
+
150
+ return $result;
151
+ }
152
+
153
+ public static function addPushNotification($data)
154
+ {
155
+ $result = true;
156
+
157
+ try {
158
+ $push = Mage::getModel('emagicone_mobassistantconnector/push')
159
+ ->loadByRegistrationIdAppConnectionId($data['device_id'], $data['app_connection_id'])
160
+ ->setData('device_unique_id', $data['device_unique_id'])
161
+ ->setData('user_id', $data['user_id'])
162
+ ->setData('store_group_id', $data['store_group_id'])
163
+ ->setData('currency_code', $data['currency_code']);
164
+
165
+ if (isset($data['new_order'])) {
166
+ $push->setData('new_order', $data['new_order']);
167
+ }
168
+
169
+ if (isset($data['new_customer'])) {
170
+ $push->setData('new_customer', $data['new_customer']);
171
+ }
172
+
173
+ if (isset($data['order_statuses'])) {
174
+ $push->setData('order_statuses', $data['order_statuses']);
175
+ }
176
+
177
+ $push->save();
178
+ } catch (Exception $e) {
179
+ $result = false;
180
+ Mage::log("Unable to add push notification ({$e->getMessage()}).", null, 'emagicone_mobassistantconnector.log');
181
+ }
182
+
183
+ return $result;
184
+ }
185
+
186
+ }
app/code/community/Emagicone/Mobassistantconnector/Helper/TableCheck.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Helper_TableCheck extends Mage_Core_Helper_Abstract
20
+ {
21
+
22
+ private function addUser($data)
23
+ {
24
+ $modelUsers = Mage::getModel('emagicone_mobassistantconnector/user');
25
+ $modelUsers->setData($data);
26
+ $modelUsers->save();
27
+ }
28
+
29
+ public function check($observer)
30
+ {
31
+ $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
32
+
33
+ // Create table emagicone_mobassistantconnector_sessions
34
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/sessions');
35
+ if (!$connection->isTableExists($tableName)) {
36
+ $table = $connection
37
+ ->newTable($tableName)
38
+ ->addColumn(
39
+ 'session_id',
40
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
41
+ null,
42
+ array(
43
+ 'identity' => true,
44
+ 'unsigned' => true,
45
+ 'nullable' => false,
46
+ 'primary' => true,
47
+ 'auto_increment' => true
48
+ ),
49
+ 'Session Id'
50
+ )
51
+ ->addColumn('session_key', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array('nullable' => false), 'Session Key')
52
+ ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'User Id')
53
+ ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Date Added');
54
+ $connection->createTable($table);
55
+ } elseif (!$connection->tableColumnExists($tableName, 'user_id')) {
56
+ try {
57
+ $connection->addColumn(
58
+ $tableName,
59
+ 'user_id',
60
+ array('type' => Varien_Db_Ddl_Table::TYPE_INTEGER, 'comment' => 'User Id')
61
+ );
62
+ } catch (Exception $e) {
63
+ Mage::log(
64
+ "Error adding column user_id to table emagicone_mobassistantconnector_sessions: {$e->getMessage()})",
65
+ null,
66
+ 'emagicone_mobassistantconnector.log'
67
+ );
68
+ }
69
+
70
+ $connection->resetDdlCache($tableName);
71
+ }
72
+
73
+ // Create table emagicone_mobassistantconnector_failed_login
74
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/failed');
75
+ if (!$connection->isTableExists($tableName)) {
76
+ $table = $connection
77
+ ->newTable($tableName)
78
+ ->addColumn(
79
+ 'attempt_id',
80
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
81
+ null,
82
+ array(
83
+ 'identity' => true,
84
+ 'unsigned' => true,
85
+ 'nullable' => false,
86
+ 'primary' => true,
87
+ 'auto_increment' => true
88
+ ),
89
+ 'Attempt Id'
90
+ )
91
+ ->addColumn('ip', Varien_Db_Ddl_Table::TYPE_VARCHAR, 20, array(), 'Ip')
92
+ ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Date Added');
93
+ $connection->createTable($table);
94
+ }
95
+
96
+ // Create table emagicone_mobassistantconnector_users
97
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/user');
98
+ if (!$connection->isTableExists($tableName)) {
99
+ $table = $connection
100
+ ->newTable($tableName)
101
+ ->addColumn(
102
+ 'user_id',
103
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
104
+ null,
105
+ array(
106
+ 'identity' => true,
107
+ 'unsigned' => true,
108
+ 'nullable' => false,
109
+ 'primary' => true,
110
+ 'auto_increment' => true
111
+ ),
112
+ 'User Id'
113
+ )
114
+ ->addColumn('username', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array('nullable' => false), 'Username')
115
+ ->addColumn('password', Varien_Db_Ddl_Table::TYPE_VARCHAR, 35, array('nullable' => false), 'Password')
116
+ ->addColumn('allowed_actions', Varien_Db_Ddl_Table::TYPE_VARCHAR, 1000, array(), 'Allowed Actions')
117
+ ->addColumn('qr_code_hash', Varien_Db_Ddl_Table::TYPE_VARCHAR, 70, array(), 'QR Code Hash')
118
+ ->addColumn('status', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'Status')
119
+ ->addIndex($connection->getIdxName($tableName, array('username')), array('username'));
120
+ $connection->createTable($table);
121
+
122
+ // Move user from table core_config_data or add default one
123
+ if (Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/login')) {
124
+ $this->moveUserToTable();
125
+ } else {
126
+ $this->addDefaultUser();
127
+ }
128
+ }
129
+
130
+ // Create table emagicone_mobassistantconnector_push_notifications
131
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/push');
132
+ if (!$connection->isTableExists($tableName)) {
133
+ $table = $connection
134
+ ->newTable($tableName)
135
+ ->addColumn(
136
+ 'id',
137
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
138
+ null,
139
+ array(
140
+ 'identity' => true,
141
+ 'unsigned' => true,
142
+ 'nullable' => false,
143
+ 'primary' => true,
144
+ 'auto_increment' => true
145
+ ),
146
+ 'Id'
147
+ )
148
+ ->addColumn('device_unique_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Device Unique Id')
149
+ ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'User Id')
150
+ ->addColumn('device_id', Varien_Db_Ddl_Table::TYPE_VARCHAR, 200, array(), 'Device Id')
151
+ ->addColumn('new_order', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'New Order')
152
+ ->addColumn('new_customer', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'New Customer')
153
+ ->addColumn('order_statuses', Varien_Db_Ddl_Table::TYPE_VARCHAR, 1000, array(), 'Order Statuses')
154
+ ->addColumn('app_connection_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'App Connection Id')
155
+ ->addColumn('store_group_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array('default' => -1), 'Store Group Id')
156
+ ->addColumn('currency_code', Varien_Db_Ddl_Table::TYPE_VARCHAR, 25, array(), 'Currency Code');
157
+ $connection->createTable($table);
158
+
159
+ // Move push data from core_config_data
160
+ $this->movePushesToTable();
161
+ }
162
+
163
+ // Create table emagicone_mobassistantconnector_devices
164
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/device');
165
+ if (!$connection->isTableExists($tableName)) {
166
+ $table = $connection->newTable($tableName)
167
+ ->addColumn(
168
+ 'device_unique_id',
169
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
170
+ null,
171
+ array(
172
+ 'identity' => true,
173
+ 'unsigned' => true,
174
+ 'nullable' => false,
175
+ 'primary' => true,
176
+ 'auto_increment' => true
177
+ ),
178
+ 'Device Unique Id'
179
+ )
180
+ ->addColumn('device_unique', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array(), 'Device Unique')
181
+ ->addColumn('account_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array('nullable' => true), 'Account Id')
182
+ ->addColumn('device_name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 150, array(), 'Device Name')
183
+ ->addColumn('last_activity', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array('nullable' => false), 'Last Activity')
184
+ ->addIndex(
185
+ $tableName->getIdxName($tableName, array('device_unique', 'account_id')), array('device_unique', 'account_id')
186
+ );
187
+ $connection->createTable($table);
188
+ }
189
+
190
+ // Create table emagicone_mobassistantconnector_accounts
191
+ $tableName = Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/account');
192
+ if (!$connection->isTableExists($tableName)) {
193
+ $table = $connection
194
+ ->newTable($tableName)
195
+ ->addColumn(
196
+ 'id',
197
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
198
+ null,
199
+ array(
200
+ 'identity' => true,
201
+ 'unsigned' => true,
202
+ 'nullable' => false,
203
+ 'primary' => true,
204
+ 'auto_increment' => true
205
+ ),
206
+ 'Id'
207
+ )
208
+ ->addColumn('account_email', Varien_Db_Ddl_Table::TYPE_VARCHAR, 150, array('nullable' => false), 'Account Email')
209
+ ->addColumn('status', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'Status');
210
+ $connection->createTable($table);
211
+ }
212
+ }
213
+
214
+ public function moveUserToTable()
215
+ {
216
+ $login = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/login');
217
+
218
+ if (!$login) {
219
+ return;
220
+ }
221
+
222
+ $this->addUser(
223
+ array(
224
+ 'username' => $login,
225
+ 'password' => Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/password'),
226
+ 'allowed_actions' => implode(';', Emagicone_Mobassistantconnector_Helper_UserPermissions::getActionsCodes()),
227
+ 'qr_code_hash' => hash('sha256', time()),
228
+ 'status' => 1
229
+ )
230
+ );
231
+ }
232
+
233
+ public function addDefaultUser()
234
+ {
235
+ $this->addUser(
236
+ array(
237
+ 'username' => '1',
238
+ 'password' => md5('1'),
239
+ 'allowed_actions' => implode(';', Emagicone_Mobassistantconnector_Helper_UserPermissions::getActionsCodes()),
240
+ 'qr_code_hash' => hash('sha256', time()),
241
+ 'status' => 1
242
+ )
243
+ );
244
+ }
245
+
246
+ public function movePushesToTable()
247
+ {
248
+ $pushes = Mage::getStoreConfig('mobassistantconnectorinfosec/access/google_ids');
249
+
250
+ if (!$pushes) {
251
+ return;
252
+ }
253
+
254
+ $pushes = unserialize($pushes);
255
+
256
+ if (!$pushes) {
257
+ return;
258
+ }
259
+
260
+ $modelPushes = Mage::getModel('emagicone_mobassistantconnector/push');
261
+
262
+ foreach ($pushes as $push) {
263
+ try {
264
+ $modelPushes->setData(
265
+ array(
266
+ 'device_id' => $push['push_device_id'],
267
+ 'new_order' => $push['push_new_order'],
268
+ 'new_customer' => $push['push_new_customer'],
269
+ 'order_statuses' => $push['push_order_statuses'],
270
+ 'app_connection_id' => $push['app_connection_id'],
271
+ 'store_group_id' => $push['push_store_group_id'],
272
+ 'currency_code' => $push['push_currency_code'],
273
+ )
274
+ );
275
+ $modelPushes->save();
276
+ $modelPushes->unsetData();
277
+ } catch (Exception $e) {
278
+ Mage::log(
279
+ 'Error occurred while moving push data from core_config_data: ' . $e->getMessage(),
280
+ null,
281
+ 'emagicone_mobassistantconnector.log'
282
+ );
283
+ }
284
+ }
285
+ }
286
+
287
+ }
app/code/community/Emagicone/Mobassistantconnector/Helper/Test.php DELETED
File without changes
app/code/community/Emagicone/Mobassistantconnector/Helper/UserPermissions.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Helper_UserPermissions extends Mage_Core_Helper_Abstract
20
+ {
21
+
22
+ /**
23
+ * Data are visible in back-end
24
+ * @return array
25
+ */
26
+ public static function getRestrictedActions()
27
+ {
28
+ $restricted_actions = array(
29
+ array(
30
+ 'group_name' => 'Push notification settings',
31
+ 'child' => array(
32
+ array(
33
+ 'code' => 'push_notification_settings_new_order',
34
+ 'name' => 'New order',
35
+ ),
36
+ array(
37
+ 'code' => 'push_notification_settings_new_customer',
38
+ 'name' => 'New customer',
39
+ ),
40
+ array(
41
+ 'code' => 'push_notification_settings_order_statuses',
42
+ 'name' => 'Order statuses',
43
+ ),
44
+ ),
45
+ ),
46
+ array(
47
+ 'group_name' => 'Store statistics',
48
+ 'child' => array(
49
+ array(
50
+ 'code' => 'store_stats',
51
+ 'name' => 'Store statistics',
52
+ ),
53
+ ),
54
+ ),
55
+ array(
56
+ 'group_name' => 'Products',
57
+ 'child' => array(
58
+ array(
59
+ 'code' => 'products_list',
60
+ 'name' => 'Product list',
61
+ ),
62
+ array(
63
+ 'code' => 'product_details',
64
+ 'name' => 'Product details',
65
+ ),
66
+ ),
67
+ ),
68
+ array(
69
+ 'group_name' => 'Customers',
70
+ 'child' => array(
71
+ array(
72
+ 'code' => 'customers_list',
73
+ 'name' => 'Customer list',
74
+ ),
75
+ array(
76
+ 'code' => 'customer_details',
77
+ 'name' => 'Customer details',
78
+ ),
79
+ ),
80
+ ),
81
+ array(
82
+ 'group_name' => 'Orders',
83
+ 'child' => array(
84
+ array(
85
+ 'code' => 'orders_list',
86
+ 'name' => 'Order list',
87
+ ),
88
+ array(
89
+ 'code' => 'order_details',
90
+ 'name' => 'Order details',
91
+ ),
92
+ array(
93
+ 'code' => 'order_details_pdf',
94
+ 'name' => 'Order details PDF',
95
+ ),
96
+ array(
97
+ 'code' => 'order_invoice',
98
+ 'name' => 'Invoice order',
99
+ ),
100
+ array(
101
+ 'code' => 'order_ship',
102
+ 'name' => 'Ship order',
103
+ ),
104
+ array(
105
+ 'code' => 'order_cancel',
106
+ 'name' => 'Cancel order',
107
+ ),
108
+ array(
109
+ 'code' => 'order_hold',
110
+ 'name' => 'Hold order',
111
+ ),
112
+ array(
113
+ 'code' => 'order_unhold',
114
+ 'name' => 'Unhold order',
115
+ ),
116
+ array(
117
+ 'code' => 'order_delete_track_number',
118
+ 'name' => 'Delete track number',
119
+ ),
120
+ ),
121
+ ),
122
+ array(
123
+ 'group_name' => 'Abandoned carts',
124
+ 'child' => array(
125
+ array(
126
+ 'code' => 'abandoned_carts_list',
127
+ 'name' => 'Abandoned cart list',
128
+ ),
129
+ array(
130
+ 'code' => 'abandoned_cart_details',
131
+ 'name' => 'Abandoned cart details',
132
+ ),
133
+ ),
134
+ ),
135
+ );
136
+
137
+ return $restricted_actions;
138
+ }
139
+
140
+ public static function getRestrictedActionsToFunctions()
141
+ {
142
+ $restricted_actions_to_functions = array(
143
+ 'push_notification_settings_new_order' => array(
144
+ 'push_notification_settings',
145
+ 'delete_push_config',
146
+ ),
147
+ 'push_notification_settings_new_customer' => array(
148
+ 'push_notification_settings',
149
+ 'delete_push_config',
150
+ ),
151
+ 'push_notification_settings_order_statuses' => array(
152
+ 'push_notification_settings',
153
+ 'delete_push_config',
154
+ ),
155
+ 'store_stats' => array(
156
+ 'get_store_stats',
157
+ 'get_data_graphs',
158
+ 'get_status_stats',
159
+ ),
160
+ 'products_list' => array(
161
+ 'search_products',
162
+ 'search_products_ordered',
163
+ ),
164
+ 'product_details' => array(
165
+ 'get_products_info',
166
+ 'get_products_descr',
167
+ ),
168
+ 'customers_list' => array(
169
+ 'get_customers',
170
+ ),
171
+ 'customer_details' => array(
172
+ 'get_customers_info',
173
+ ),
174
+ 'orders_list' => array(
175
+ 'get_orders',
176
+ ),
177
+ 'order_details' => array(
178
+ 'get_orders_info',
179
+ ),
180
+ 'order_details_pdf' => array(
181
+ 'get_order_pdf',
182
+ ),
183
+ 'order_invoice' => array(
184
+ 'set_order_action',
185
+ 'invoice_order',
186
+ ),
187
+ 'order_ship' => array(
188
+ 'set_order_action',
189
+ 'ship_order',
190
+ ),
191
+ 'order_cancel' => array(
192
+ 'set_order_action',
193
+ 'cancel_order',
194
+ ),
195
+ 'order_hold' => array(
196
+ 'set_order_action',
197
+ 'hold_order',
198
+ ),
199
+ 'order_unhold' => array(
200
+ 'set_order_action',
201
+ 'unhold_order',
202
+ ),
203
+ 'order_delete_track_number' => array(
204
+ 'set_order_action',
205
+ 'delete_track_number',
206
+ ),
207
+ 'abandoned_carts_list' => array(
208
+ 'get_abandoned_carts_list',
209
+ ),
210
+ 'abandoned_cart_details' => array(
211
+ 'get_abandoned_cart_details',
212
+ ),
213
+ );
214
+
215
+ return $restricted_actions_to_functions;
216
+ }
217
+
218
+ public static function getAlwaysAllowedFunctions()
219
+ {
220
+ $allowed_functions_always = array(
221
+ 'run_self_test',
222
+ 'get_stores',
223
+ 'get_currencies',
224
+ 'get_store_title',
225
+ 'get_orders_statuses',
226
+ 'get_carriers',
227
+ );
228
+
229
+ return $allowed_functions_always;
230
+ }
231
+
232
+ /**
233
+ * Return codes of all actions
234
+ * @return array
235
+ */
236
+ public static function getActionsCodes()
237
+ {
238
+ $actions = self::getRestrictedActions();
239
+ $result = array();
240
+ $groups_count = count($actions);
241
+
242
+ for ($i = 0; $i < $groups_count; $i++) {
243
+ $child_count = count($actions[$i]['child']);
244
+
245
+ for ($j = 0; $j < $child_count; $j++) {
246
+ $result[] = $actions[$i]['child'][$j]['code'];
247
+ }
248
+ }
249
+
250
+ return $result;
251
+ }
252
+
253
+ public static function getUserAllowedActionsAsString($action_codes)
254
+ {
255
+ $is_allowed_all = true;
256
+ $result = '';
257
+ $restricted_actions = self::getRestrictedActions();
258
+ $groups_count = count($restricted_actions);
259
+
260
+ for ($i = 0; $i < $groups_count; $i++) {
261
+ $child_count = count($restricted_actions[$i]['child']);
262
+ $tmp = '';
263
+
264
+ for ($j = 0; $j < $child_count; $j++) {
265
+ if (in_array($restricted_actions[$i]['child'][$j]['code'], $action_codes)) {
266
+ if (!empty($tmp)) {
267
+ $tmp .= ', ';
268
+ }
269
+
270
+ $tmp .= $restricted_actions[$i]['child'][$j]['name'];
271
+ } else {
272
+ $is_allowed_all = false;
273
+ }
274
+ }
275
+
276
+ if (!empty($tmp)) {
277
+ if (!empty($result)) {
278
+ $result .= ', ';
279
+ }
280
+
281
+ $result .= $restricted_actions[$i]['group_name'].' ('.$tmp.')';
282
+ }
283
+ }
284
+
285
+ if ($is_allowed_all) {
286
+ $result = 'All';
287
+ } elseif (empty($result)) {
288
+ $result = 'Nothing';
289
+ }
290
+
291
+ return $result;
292
+ }
293
+
294
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Account.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Account extends Mage_Core_Model_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/account');
25
+ }
26
+
27
+ /**
28
+ * Saves account if it is missing and return account object
29
+ *
30
+ * @param $accountEmail
31
+ * @return $this
32
+ */
33
+ public function saveAndGetAccountByEmail($accountEmail)
34
+ {
35
+ $matches = $this->getResourceCollection()
36
+ ->addFieldToFilter('account_email', $accountEmail);
37
+
38
+ foreach ($matches as $match) {
39
+ return $this->load($match->getId());
40
+ }
41
+
42
+ return $this->setData(array('account_email' => $accountEmail, 'status' => 1))->save();
43
+ }
44
+
45
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Defpassword.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- /**
3
- * This file is part of Mobile Assistant Connector.
4
- *
5
- * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
- */
18
-
19
- class Emagicone_Mobassistantconnector_Model_Defpassword extends Mage_Core_Model_Config_Data
20
- {
21
- public function toOptionArray()
22
- {
23
- Mage::app()->cleanCache();
24
-
25
- $tablePrefix = (string)Mage::getConfig()->getTablePrefix();
26
-
27
- $db = Mage::getSingleton('core/resource')->getConnection('core_write');
28
- if (!$db->showTableStatus($tablePrefix . 'emagicone_mobassistantconnector_sessions')) {
29
- $db->query("CREATE TABLE `" .
30
- $tablePrefix . "emagicone_mobassistantconnector_sessions` (
31
- `session_id` int(11) NOT NULL auto_increment,
32
- `session_key` varchar(100) NOT NULL default '',
33
- `date_added` int(11) NOT NULL,
34
- PRIMARY KEY (`session_id`)
35
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
36
- }
37
- if (!$db->showTableStatus($tablePrefix . 'emagicone_mobassistantconnector_failed_login')) {
38
- $db->query("CREATE TABLE `" .
39
- $tablePrefix . "emagicone_mobassistantconnector_failed_login` (
40
- `attempt_id` int(11) NOT NULL auto_increment,
41
- `ip` varchar(20) NOT NULL default '',
42
- `date_added` int(11) NOT NULL,
43
- PRIMARY KEY (`attempt_id`)
44
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
45
- }
46
-
47
- $password = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/password');
48
- if($password === 'c4ca4238a0b923820dcc509a6f75849b') {
49
- Mage::getSingleton('core/session')->addNotice(Mage::helper('mobassistantconnector/data')->__('<span style="color:green">Mobile Assistant Connector: </span> Default password is "1". Please change it because of security reasons!'));
50
- }
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emagicone/Mobassistantconnector/Model/Device.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Device extends Mage_Core_Model_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/device');
25
+ }
26
+
27
+ /**
28
+ * Check if data exist in table and load them or set new data
29
+ * @param $device_unique
30
+ * @param $account_id
31
+ * @return $this
32
+ */
33
+ public function loadByDeviceUniqueAndAccountId($device_unique, $account_id)
34
+ {
35
+ $matches = $this->getResourceCollection()
36
+ ->addFieldToFilter('device_unique', $device_unique);
37
+
38
+ if (!$account_id) {
39
+ $matches->addFieldToFilter('account_id', array(array('null' => true), array('eq' => '')));
40
+ } else {
41
+ $matches->addFieldToFilter('account_id', $account_id);
42
+ }
43
+
44
+ foreach ($matches as $match) {
45
+ return $this->load($match->getId());
46
+ }
47
+
48
+ return $this->setData(array('device_unique' => $device_unique, 'account_id' => $account_id));
49
+ }
50
+
51
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Observer.php CHANGED
@@ -18,217 +18,286 @@
18
 
19
  class Emagicone_Mobassistantconnector_Model_Observer
20
  {
21
- public function checkOrder($observer) {
22
-
23
- if(intval(Mage::getStoreConfig('mobassistantconnectorinfosec/emogeneral/status')) == 1) {
24
- $order = $observer->getEvent()->getOrder();
25
- $groupId = $_storeId = Mage::app()->getStore(intval($order->getStoreId()))->getGroupId();
26
- $state = $order->getState();
27
- // $state = $observer->getEvent()->getState();
28
- // $status = $observer->getEvent()->getStatus();
29
- $status = $order->getStatus();
30
- $comment = $observer->getEvent()->getComment();
31
- $statusLabel = $status;
32
- $statuses = array();
33
- $deviceIds = array();
34
- $deviceIdsByCCode = array();
35
- $deviceArResult = array();
36
- $type = '';
37
-
38
- $statuses = Mage::getModel('sales/order_status')->getResourceCollection()->getData();
39
- foreach($statuses as $st) {
40
- if($st['status'] == $status) {
41
- $statusLabel = $st['label'];
42
- }
43
- }
44
-
45
- $deviceIdActions = Mage::helper('mobassistantconnector')->pushSettingsUpgrade();
46
-
47
- if(count($deviceIdActions) > 0 && !is_null($state)) {
48
-
49
-
50
- foreach ($deviceIdActions as $settingNum => $deviceId) {
51
-
52
- Mage::log(
53
- "push_new_order: ". $deviceId['push_store_group_id'].
54
- "\n groupId: ". $groupId.
55
- "\n state: ". $state.
56
- "\n push_device_id: ". $deviceId['push_device_id']
57
- ,
58
- null,
59
- 'emagicone_mobassistantconnector.log'
60
- );
61
-
62
- // Get devices according to group_id
63
- if($deviceId['push_store_group_id'] == $groupId || $deviceId['push_store_group_id'] == -1) {
64
- // New order notification
65
- if(intval($deviceId['push_new_order']) == 1 /** && ( ($order->getCreatedAt() == $order->getUpdatedAt()) || $order->getCustomerIsGuest() == true) */ && $state == 'new' && !is_null($deviceId['push_device_id'])){
66
- if (!in_array($deviceId['push_device_id'], $deviceIds)) {
67
- $deviceId['setting_num'] = $settingNum;
68
- $deviceIds[$deviceId['push_device_id']] = $deviceId;
69
- // $deviceIdsByCCode[$deviceId['push_currency_code']][] = $deviceId['push_device_id'];
70
- $type = 'new_order';
71
- }
72
- }
73
- // New status notification
74
- if(strlen($deviceId['push_order_statuses']) > 0 && (!in_array($deviceId['push_device_id'], $deviceIds)) && !($order->getCreatedAt() == $order->getUpdatedAt()) ) {
75
- $statuses = explode('|', $deviceId['push_order_statuses']);
76
- if(in_array($status, $statuses) || intval($deviceId['push_order_statuses']) == -1) {
77
- if (!in_array($deviceId['push_device_id'], $deviceIds)) {
78
- $deviceId['setting_num'] = $settingNum;
79
- $deviceIds[$deviceId['push_device_id']] = $deviceId;
80
- // $deviceIdsByCCode[$deviceId['push_currency_code']][] = $deviceId['push_device_id'];
81
- // $deviceIdsByCCode[$deviceId['push_currency_code']]['push_device_id'][] = $deviceId['push_device_id'];
82
- // $deviceIdsByCCode[$deviceId['push_currency_code']]['app_connection_id'][] = $deviceId['app_connection_id'];
83
- $type = 'order_changed';
84
- }
85
- }
86
- }
87
- }
88
- }
89
-
90
- }
91
-
92
- Mage::log(
93
- "******* \n Push message: Type: {$type}; All ids: ". count($deviceIdActions). "; Accepted to current event: {". count($deviceIds). "}; ",
94
- null,
95
- 'emagicone_mobassistantconnector.log'
96
- );
97
-
98
- // foreach($deviceIdsByCCode as $deviceCurrencyCode => $deviceIds) {
99
- if(count($deviceIds) > 0) {
100
- foreach ($deviceIds as $key => $value) {
101
- $currency_code = $order->getGlobalCurrencyCode();
102
- $currency_symbol = Mage::app()->getLocale()->currency($currency_code)->getSymbol();
103
-
104
- $deviceCurrencyCode = $value['push_currency_code'];
105
- $app_connection_id = $value['app_connection_id'];
106
-
107
- // $total = $order->getSubtotalInclTax();
108
- $total = $order->getBaseGrandTotal();
109
- $total = number_format(floatval($total), 2, '.', ' ');
110
 
111
- if(empty($deviceCurrencyCode) || strval($deviceCurrencyCode) == 'base_currency') {
112
- $deviceCurrencyCode = $currency_code;
113
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
- $total = Mage::helper('mobassistantconnector')->price_format($currency_code, 1, $total, $deviceCurrencyCode, 0, true);
 
 
116
 
117
- $storeUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
118
- $storeUrl = str_replace('http://', '', $storeUrl);
119
- $storeUrl = str_replace('https://', '', $storeUrl);
120
- $storeUrl = rtrim($storeUrl, '/' );
121
 
122
- preg_replace('/\/*$/i', '', $storeUrl);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- $fields = array(
125
- 'registration_ids' => array(0 => $value['push_device_id']),
126
- 'data' => array( "message" => array("push_notif_type" => $type, "email" => $order->getCustomerEmail(), 'customer_name' => $order->getCustomerFirstname().' '.$order->getCustomerLastname(),
127
- "order_id" => $order->getId(), "total" => $total, "store_url" => $storeUrl, "new_status" => $statusLabel, "new_status_code" => $status, "group_id" => $groupId, 'app_connection_id' => $app_connection_id) ),
128
- );
129
 
130
- if($type === 'new_order') {
131
- unset($fields['data']['new_status']);
132
- unset($fields['data']['new_status_code']);
133
- }
134
 
135
- $fields_log = var_export($fields, true);
 
 
136
 
137
- $send_data = Mage::helper('core')->jsonEncode($fields['data']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
- Mage::log(
140
- "Push message: Type: {$type}; data: " . var_export(json_encode($fields), true) ,
141
- null,
142
- 'emagicone_mobassistantconnector.log'
143
- );
144
 
145
- $fields = Mage::helper('core')->jsonEncode($fields);
 
146
 
147
- $response = Mage::helper('mobassistantconnector')->sendPushMessage($fields);
 
 
148
 
149
- Mage::helper('mobassistantconnector')->proceedGoogleResponse($response, array('device_id' => $value['push_device_id'],
150
- 'app_connection_id' => $value['app_connection_id']));
 
 
 
 
 
 
151
 
152
- /* $d_r = Mage::helper('core')->jsonDecode($response, Zend_Json::TYPE_OBJECT);
 
 
153
 
154
- Mage::log(
155
- "Google response: (multicast_id = {$d_r->multicast_id}, success = {$d_r->success}, failure = {$d_r->failure}, canonical_ids = {$d_r->canonical_ids})",
156
- null,
157
- 'emagicone_mobassistantconnector.log'
158
- );*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  }
160
- // }
 
 
 
 
161
  }
162
  }
163
  }
164
 
165
- public function customerRegisterSuccess($observer) {
166
- $statuses = array();
167
- $deviceIds = array();
168
- $deviceArResult = array();
169
- $type = 'new_customer';
 
170
 
 
 
171
 
172
- $customer = $observer->getEvent()->getCustomer();
173
- $groupId = $_storeId = Mage::app()->getStore(intval($customer->getStoreId()))->getGroupId();
174
-
175
- Mage::app()->cleanCache();
176
- if(intval(Mage::getStoreConfig('mobassistantconnectorinfosec/emogeneral/status')) == 1) {
177
 
178
- $deviceIdActions = Mage::helper('mobassistantconnector')->pushSettingsUpgrade();
 
 
179
 
180
- if(count($deviceIdActions) > 0) {
181
- foreach ($deviceIdActions as $settingNum => $deviceId) {
182
- if(($groupId == $deviceId['push_store_group_id']) || $deviceId['push_store_group_id'] == -1) {
183
- if(intval($deviceId['push_new_customer'] == 1)) {
184
- $deviceId['setting_num'] = $settingNum;
185
- array_push($deviceIds, $deviceId);
186
- }
187
- }
188
- }
189
- }
190
 
191
- Mage::log(
192
- "******* \n Push message: Type: {$type}; All ids: ". count($deviceIdActions). "; Accepted to current event: {". count($deviceIds). "}; ",
193
- null,
194
- 'emagicone_mobassistantconnector.log'
195
- );
196
 
197
- if(count($deviceIds) > 0) {
198
- foreach ($deviceIds as $key => $value) {
199
- $fields = array(
200
- 'registration_ids' => array(0 => $value['push_device_id']),
201
- 'data' => array( "message" => array("push_notif_type" => $type, "email" => $customer->getEmail(), 'customer_name' => $customer->getFirstname().' '.$customer->getLastname(),
202
- "customer_id" => $customer->getId(), "store_url" => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB), "group_id" => $groupId, 'app_connection_id' => $value['app_connection_id']))
203
- );
204
 
205
- $send_data = Mage::helper('core')->jsonEncode($fields['data']);
206
- $fields = Mage::helper('core')->jsonEncode($fields);
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
 
209
- Mage::log(
210
- "Data: {$fields} ",
211
- null,
212
- 'emagicone_mobassistantconnector.log'
213
- );
214
 
215
- $response = Mage::helper('mobassistantconnector')->sendPushMessage($fields);
 
 
 
 
 
 
216
 
217
- // $success = true;
218
- Mage::helper('mobassistantconnector')->proceedGoogleResponse($response, array('device_id' => $value['push_device_id'],
219
- 'app_connection_id' => $value['app_connection_id']));
 
220
 
221
- // Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/google_ids', serialize($deviceArResult) );
 
 
 
 
 
 
222
 
223
- $d_r = Mage::helper('core')->jsonDecode($response, Zend_Json::TYPE_OBJECT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
- Mage::log(
226
- "Google response: (multicast_id = {$d_r->multicast_id}, success = {$d_r->success}, failure = {$d_r->failure}, canonical_ids = {$d_r->canonical_ids}, results = {$d_r->results})",
227
- null,
228
- 'emagicone_mobassistantconnector.log'
229
- );
230
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  }
232
  }
233
  }
 
234
  }
18
 
19
  class Emagicone_Mobassistantconnector_Model_Observer
20
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ private static function getActiveDevices()
23
+ {
24
+ $pushesCollection = Mage::getModel('emagicone_mobassistantconnector/push')->getCollection();
25
+ $pushesCollection->getSelect()
26
+ ->joinLeft(
27
+ array('d' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/device')),
28
+ 'main_table.`device_unique_id` = d.`device_unique_id`',
29
+ array()
30
+ )
31
+ ->joinLeft(
32
+ array('a' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/account')),
33
+ 'a.`id` = d.`account_id`',
34
+ array()
35
+ )
36
+ ->joinLeft(
37
+ array('u' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/user')),
38
+ 'u.`user_id` = main_table.`user_id`',
39
+ array()
40
+ )
41
+ ->where('a.`status` = 1 AND u.`status` = 1 OR main_table.`user_id` IS NULL');
42
+
43
+ return $pushesCollection;
44
+ }
45
 
46
+ private static function sendRequestAboutOrder($device, $type, $order, $statusLabel)
47
+ {
48
+ $currencyCode = $order->getGlobalCurrencyCode();
49
 
50
+ $deviceCurrencyCode = $device->getCurrencyCode();
51
+ if (empty($deviceCurrencyCode) || (string)$deviceCurrencyCode == 'base_currency') {
52
+ $deviceCurrencyCode = $currencyCode;
53
+ }
54
 
55
+ $total = $order->getBaseGrandTotal();
56
+ $total = number_format((float)$total, 2, '.', ' ');
57
+ $total = Mage::helper('mobassistantconnector')
58
+ ->price_format($currencyCode, 1, $total, $deviceCurrencyCode, 0, true);
59
+
60
+ $fields = array(
61
+ 'registration_ids' => array($device->getDeviceId()),
62
+ 'data' => array(
63
+ 'message' => array(
64
+ 'push_notif_type' => $type,
65
+ 'email' => $order->getCustomerEmail(),
66
+ 'customer_name' => "{$order->getCustomerFirstname()} {$order->getCustomerLastname()}",
67
+ 'order_id' => $order->getId(),
68
+ 'total' => $total,
69
+ 'store_url' => self::getBaseStoreUrl(),
70
+ 'group_id' => $order->getStore()->getGroupId(),
71
+ 'app_connection_id' => $device->getAppConnectionId()
72
+ )
73
+ )
74
+ );
75
+
76
+ if ($type == 'order_changed') {
77
+ $fields['data']['message']['new_status'] = $statusLabel;
78
+ }
79
 
80
+ self::sendPushMessage(Mage::helper('core')->jsonEncode($fields), $device->getDeviceId());
81
+ }
 
 
 
82
 
83
+ private static function sendPushMessage($data, $deviceRegistrationId)
84
+ {
85
+ $apiKey = Mage::getStoreConfig('mobassistantconnectorinfosec/access/api_key');
 
86
 
87
+ if (!$apiKey) {
88
+ return;
89
+ }
90
 
91
+ $headers = array("Authorization: key=$apiKey", 'Content-Type: application/json');
92
+ $result = false;
93
+
94
+ if (is_callable('curl_init')) {
95
+ $ch = curl_init();
96
+ curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send');
97
+ curl_setopt($ch, CURLOPT_POST, true);
98
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
99
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
100
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
101
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
102
+ $result = curl_exec($ch);
103
+
104
+ if (curl_errno($ch)) {
105
+ Mage::log(
106
+ "Push message error while sending CURL request: {$result}",
107
+ null,
108
+ 'emagicone_mobassistantconnector.log'
109
+ );
110
+ }
111
 
112
+ curl_close($ch);
113
+ }
 
 
 
114
 
115
+ self::proceedGoogleResponse($result, $deviceRegistrationId);
116
+ }
117
 
118
+ private static function proceedGoogleResponse($response, $deviceRegistrationId)
119
+ {
120
+ $json = array();
121
 
122
+ if ($response && strpos($response, '{') === 0) {
123
+ try {
124
+ $json = Mage::helper('core')->jsonDecode($response);
125
+ } catch (Exception $e) {
126
+ Mage::log('Error on json decoding', null, 'emagicone_mobassistantconnector.log');
127
+ return;
128
+ }
129
+ }
130
 
131
+ if (!$json || !is_array($json) || !isset($json['results'])) {
132
+ return;
133
+ }
134
 
135
+ foreach ($json['results'] as $result) {
136
+ if (
137
+ isset($result['registration_id']) && isset($json['canonical_ids']) && (int)$json['canonical_ids'] > 0 ||
138
+ isset($result['error']) &&
139
+ ($result['error'] == 'NotRegistered' || $result['error'] == 'InvalidRegistration')
140
+ ) {
141
+ $deviceCollection = Mage::getModel('emagicone_mobassistantconnector/push')
142
+ ->getCollection()
143
+ ->addFieldToFilter('device_id', $deviceRegistrationId);
144
+
145
+ if (
146
+ isset($result['registration_id']) && isset($json['canonical_ids']) && (int)$json['canonical_ids'] > 0
147
+ ) {
148
+ foreach ($deviceCollection as $device) {
149
+ $collection = Mage::getModel('emagicone_mobassistantconnector/push')
150
+ ->getCollection()
151
+ ->addFieldToFilter('device_id', $result['registration_id'])
152
+ ->addFieldToFilter('user_id', $device->getUserId())
153
+ ->addFieldToFilter('app_connection_id', $device->getAppConnectionId());
154
+
155
+ if ($collection->getSize() > 0) {
156
+ $device->delete();
157
+ } else {
158
+ $device->setDeviceId($result['registration_id']);
159
+ $device->save();
160
+ }
161
+ }
162
+ } else {
163
+ foreach ($deviceCollection as $device) {
164
+ $device->delete();
165
  }
166
+
167
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyDevices();
168
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyAccounts();
169
+ Mage::log("Google error response: {$response}", null, 'emagicone_mobassistantconnector.log');
170
+ }
171
  }
172
  }
173
  }
174
 
175
+ private static function getBaseStoreUrl()
176
+ {
177
+ $storeUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
178
+ $storeUrl = str_replace('http://', '', $storeUrl);
179
+ $storeUrl = str_replace('https://', '', $storeUrl);
180
+ $storeUrl = rtrim($storeUrl, '/');
181
 
182
+ return $storeUrl;
183
+ }
184
 
185
+ private static function isPushNotificationAllowed($userId, $code)
186
+ {
187
+ $userId = (int)$userId;
 
 
188
 
189
+ if ($userId < 1) {
190
+ return true;
191
+ }
192
 
193
+ $result = false;
194
+ $userModel = Mage::getModel('emagicone_mobassistantconnector/user')->load($userId);
195
+ $allowedActions = $userModel->getData('allowed_actions');
 
 
 
 
 
 
 
196
 
197
+ if ($allowedActions) {
198
+ $allowedActions = explode(';', $allowedActions);
 
 
 
199
 
200
+ if (!empty($allowedActions) && in_array($code, $allowedActions)) {
201
+ $result = true;
202
+ }
203
+ }
 
 
 
204
 
205
+ return $result;
206
+ }
207
 
208
+ public function checkOrder($observer)
209
+ {
210
+ $order = $observer->getEvent()->getOrder();
211
+ $oldStatus = $order->getOrigData('status');
212
+ $newStatus = $order->getStatus();
213
+
214
+ if ($oldStatus && $oldStatus != $newStatus) {
215
+ $type = 'order_changed';
216
+ } elseif (!$oldStatus) {
217
+ $type = 'new_order';
218
+ } else {
219
+ return;
220
+ }
221
 
222
+ $orderGroupId = $order->getStore()->getGroupId();
223
+ $statusLabel = $newStatus;
224
+ $devices = self::getActiveDevices();
 
 
225
 
226
+ $statuses = Mage::getModel('sales/order_status')->getResourceCollection()->getData();
227
+ foreach ($statuses as $st) {
228
+ if ($st['status'] == $newStatus) {
229
+ $statusLabel = $st['label'];
230
+ break;
231
+ }
232
+ }
233
 
234
+ foreach ($devices as $device) {
235
+ $deviceId = $device->getDeviceId();
236
+ $appConnectionId = (int)$device->getAppConnectionId();
237
+ $storeGroupId = (int)$device->getStoreGroupId();
238
 
239
+ $deviceOrderStatuses = $device->getOrderStatuses();
240
+ if (!empty($deviceOrderStatuses)) {
241
+ $deviceOrderStatuses = explode('|', $deviceOrderStatuses);
242
+ }
243
+ if (!is_array($deviceOrderStatuses)) {
244
+ $deviceOrderStatuses = array();
245
+ }
246
 
247
+ if (
248
+ $type == 'new_order' &&
249
+ !empty($deviceId) &&
250
+ (int)$device->getNewOrder() == 1 &&
251
+ $appConnectionId > 0 &&
252
+ ($storeGroupId == -1 || $storeGroupId == $orderGroupId) &&
253
+ self::isPushNotificationAllowed($device->getData('user_id'), 'push_notification_settings_new_order') ||
254
+ $type == 'order_changed' &&
255
+ !empty($deviceId) &&
256
+ (in_array('-1', $deviceOrderStatuses) || in_array($newStatus, $deviceOrderStatuses)) &&
257
+ $appConnectionId > 0 &&
258
+ ($storeGroupId == -1 || $storeGroupId == $orderGroupId) &&
259
+ self::isPushNotificationAllowed($device->getData('user_id'), 'push_notification_settings_order_statuses')
260
+ ) {
261
+ self::sendRequestAboutOrder($device, $type, $order, $statusLabel);
262
+ }
263
+ }
264
+ }
265
 
266
+ public function customerRegisterSuccess($observer)
267
+ {
268
+ $customer = $observer->getEvent()->getCustomer();
269
+ $devices = self::getActiveDevices();
270
+
271
+ foreach ($devices as $device) {
272
+ $deviceId = $device->getDeviceId();
273
+ $appConnectionId = (int)$device->getAppConnectionId();
274
+ $storeGroupId = (int)$device->getStoreGroupId();
275
+
276
+ if (
277
+ !empty($deviceId) &&
278
+ (int)$device->getNewCustomer() == 1 &&
279
+ $appConnectionId > 0 &&
280
+ ($storeGroupId == -1 || $storeGroupId == $customer->getGroupId()) &&
281
+ self::isPushNotificationAllowed($device->getData('user_id'), 'push_notification_settings_new_customer')
282
+ ) {
283
+ $fields = array(
284
+ 'registration_ids' => array($deviceId),
285
+ 'data' => array(
286
+ 'message' => array(
287
+ 'push_notif_type' => 'new_customer',
288
+ 'email' => $customer->getEmail(),
289
+ 'customer_name' => "{$customer->getFirstname()} {$customer->getLastname()}",
290
+ 'customer_id' => $customer->getId(),
291
+ 'store_url' => self::getBaseStoreUrl(),
292
+ 'group_id' => $storeGroupId,
293
+ 'app_connection_id' => $appConnectionId
294
+ )
295
+ )
296
+ );
297
+
298
+ self::sendPushMessage(Mage::helper('core')->jsonEncode($fields), $deviceId);
299
  }
300
  }
301
  }
302
+
303
  }
app/code/community/Emagicone/Mobassistantconnector/Model/Push.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Push extends Mage_Core_Model_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/push');
25
+ }
26
+
27
+ /**
28
+ * Check if data exist in table and load them or set new data
29
+ * @param $registration_id
30
+ * @param $app_connection_id
31
+ * @return $this
32
+ */
33
+ public function loadByRegistrationIdAppConnectionId($registration_id, $app_connection_id)
34
+ {
35
+ $matches = $this->getResourceCollection()
36
+ ->addFieldToFilter('device_id', $registration_id)
37
+ ->addFieldToFilter('app_connection_id', $app_connection_id);
38
+
39
+ foreach ($matches as $match) {
40
+ return $this->load($match->getId());
41
+ }
42
+
43
+ return $this->setData(array('device_id' => $registration_id, 'app_connection_id' => $app_connection_id));
44
+ }
45
+
46
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Account.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Account extends Mage_Core_Model_Resource_Db_Abstract
20
+ {
21
+
22
+ protected function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/account', 'id');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Account/Collection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Account_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/account');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Device.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Device extends Mage_Core_Model_Resource_Db_Abstract
20
+ {
21
+
22
+ protected function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/device', 'device_unique_id');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Device/Collection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Device_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/device');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/{controllers/adminhtml/IndexController.php → Model/Resource/Push.php} RENAMED
@@ -1,26 +1,27 @@
1
- <?php
2
- /**
3
- * This file is part of Mobile Assistant Connector.
4
- *
5
- * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License as published by
7
- * the Free Software Foundation, either version 3 of the License, or
8
- * (at your option) any later version.
9
- *
10
- * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
- */
18
-
19
- class Emagicone_Mobassistantconnector_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
20
- {
21
- public function indexAction()
22
- {
23
- $this->loadLayout();
24
- $this->renderLayout();
25
- }
 
26
  }
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Push extends Mage_Core_Model_Resource_Db_Abstract
20
+ {
21
+
22
+ protected function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/push', 'id');
25
+ }
26
+
27
  }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Push/Collection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_Push_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/push');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Sessions.php CHANGED
@@ -18,9 +18,10 @@
18
 
19
  class Emagicone_Mobassistantconnector_Model_Resource_Sessions extends Mage_Core_Model_Resource_Db_Abstract
20
  {
 
21
  public function _construct()
22
  {
23
- // parent::_construct();
24
  $this->_init('emagicone_mobassistantconnector/sessions', 'session_id');
25
  }
 
26
  }
18
 
19
  class Emagicone_Mobassistantconnector_Model_Resource_Sessions extends Mage_Core_Model_Resource_Db_Abstract
20
  {
21
+
22
  public function _construct()
23
  {
 
24
  $this->_init('emagicone_mobassistantconnector/sessions', 'session_id');
25
  }
26
+
27
  }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/Sessions/Collection.php CHANGED
@@ -18,8 +18,10 @@
18
 
19
  class Emagicone_Mobassistantconnector_Model_Resource_Sessions_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
  {
 
21
  public function _construct()
22
  {
23
  $this->_init('emagicone_mobassistantconnector/sessions');
24
  }
 
25
  }
18
 
19
  class Emagicone_Mobassistantconnector_Model_Resource_Sessions_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
  {
21
+
22
  public function _construct()
23
  {
24
  $this->_init('emagicone_mobassistantconnector/sessions');
25
  }
26
+
27
  }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/User.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_User extends Mage_Core_Model_Resource_Db_Abstract
20
+ {
21
+
22
+ protected function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/user', 'user_id');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Resource/User/Collection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_Resource_User_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
20
+ {
21
+
22
+ public function _construct()
23
+ {
24
+ $this->_init('emagicone_mobassistantconnector/user');
25
+ }
26
+
27
+ }
app/code/community/Emagicone/Mobassistantconnector/Model/Sessions.php CHANGED
@@ -18,9 +18,26 @@
18
 
19
  class Emagicone_Mobassistantconnector_Model_Sessions extends Mage_Core_Model_Abstract
20
  {
 
21
  public function _construct()
22
  {
23
- // parent::_construct();
24
  $this->_init('emagicone_mobassistantconnector/sessions');
25
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
18
 
19
  class Emagicone_Mobassistantconnector_Model_Sessions extends Mage_Core_Model_Abstract
20
  {
21
+
22
  public function _construct()
23
  {
 
24
  $this->_init('emagicone_mobassistantconnector/sessions');
25
  }
26
+
27
+ /**
28
+ * Check if data exist in table and load them or set new data
29
+ * @param $userId
30
+ * @return $this
31
+ */
32
+ public function loadByUserId($userId)
33
+ {
34
+ $matches = $this->getResourceCollection()->addFieldToFilter('user_id', (int)$userId);
35
+
36
+ foreach ($matches as $match) {
37
+ return $this->load($match->getId());
38
+ }
39
+
40
+ return $this;
41
+ }
42
+
43
  }
app/code/community/Emagicone/Mobassistantconnector/Model/User.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Model_User extends Mage_Core_Model_Abstract
20
+ {
21
+
22
+ const STATUS_ENABLED = 1;
23
+ const STATUS_DISABLED = 0;
24
+
25
+ protected function _construct()
26
+ {
27
+ $this->_init('emagicone_mobassistantconnector/user');
28
+ }
29
+
30
+ /**
31
+ * Retrieve option array
32
+ *
33
+ * @return array
34
+ */
35
+ public static function getStatuses()
36
+ {
37
+ return array(
38
+ self::STATUS_ENABLED => Mage::helper('mobassistantconnector')->__('Enabled'),
39
+ self::STATUS_DISABLED => Mage::helper('mobassistantconnector')->__('Disabled')
40
+ );
41
+ }
42
+
43
+ }
app/code/community/Emagicone/Mobassistantconnector/controllers/Adminhtml/UserController.php ADDED
@@ -0,0 +1,436 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ class Emagicone_Mobassistantconnector_Adminhtml_UserController extends Mage_Adminhtml_Controller_Action
20
+ {
21
+
22
+ private function changeUserStatus($status)
23
+ {
24
+ $userIds = $this->getRequest()->getPost('user_ids', array());
25
+ $count = count($userIds);
26
+
27
+ for ($i = 0; $i < $count; $i++) {
28
+ Mage::getModel('emagicone_mobassistantconnector/user')->load($userIds[$i])
29
+ ->setData('status', $status)
30
+ ->save();
31
+ }
32
+
33
+ $text = $status == 1
34
+ ? Mage::helper('mobassistantconnector')->__('%s user(s) have been enabled.', count($userIds))
35
+ : Mage::helper('mobassistantconnector')->__('%s user(s) have been disabled.', count($userIds));
36
+
37
+ $this->_getSession()->addSuccess($text);
38
+ $this->_redirect('*/*/');
39
+ }
40
+
41
+ private function deleteUser($userIds)
42
+ {
43
+ if (!$userIds || empty($userIds)) {
44
+ Mage::getSingleton('adminhtml/session')->addError(
45
+ Mage::helper('mobassistantconnector')->__('User ID is incorrect')
46
+ );
47
+ $this->_redirect('*/*/');
48
+ return;
49
+ }
50
+
51
+ $model = Mage::getModel('emagicone_mobassistantconnector/user');
52
+ $count = count($userIds);
53
+
54
+ try {
55
+ for ($i = 0; $i < $count; $i++) {
56
+ $model->load($userIds[$i])->delete();
57
+
58
+ // Delete session keys of user
59
+ $sessionKeyCollection = Mage::getModel('emagicone_mobassistantconnector/sessions')->getCollection()
60
+ ->addFieldToFilter('user_id', $userIds[$i]);
61
+ foreach ($sessionKeyCollection as $key) {
62
+ $key->delete();
63
+ }
64
+
65
+ // Delete push data of user
66
+ $pushCollection = Mage::getModel('emagicone_mobassistantconnector/push')->getCollection()
67
+ ->addFieldToFilter('user_id', $userIds[$i]);
68
+ foreach ($pushCollection as $push) {
69
+ $push->delete();
70
+ }
71
+
72
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyDevices();
73
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyAccounts();
74
+ }
75
+
76
+ $this->_getSession()->addSuccess($this->__('A total of %s user(s) have been deleted.', $count));
77
+ } catch (Exception $e) {
78
+ $this->_getSession()->addError($e->getMessage());
79
+ }
80
+
81
+ $this->_redirect('*/*/');
82
+ }
83
+
84
+ private function changeStatusAccount($pushIds)
85
+ {
86
+ if (empty($pushIds)) {
87
+ Mage::getSingleton('adminhtml/session')->addError(
88
+ Mage::helper('mobassistantconnector')->__('Nothing selected')
89
+ );
90
+ } else {
91
+ $i = 0;
92
+ $value = (int)$this->getRequest()->getParam('value');
93
+ $accountCollection = Mage::getModel('emagicone_mobassistantconnector/account')->getCollection();
94
+ $accountCollection->getSelect()
95
+ ->joinLeft(
96
+ array('d' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/device')),
97
+ 'd.account_id = main_table.id',
98
+ array()
99
+ )
100
+ ->joinLeft(
101
+ array('p' => Mage::getSingleton('core/resource')->getTableName('emagicone_mobassistantconnector/push')),
102
+ 'd.device_unique_id = p.device_unique_id',
103
+ array()
104
+ )
105
+ ->where('p.id IN (' . implode(',', $pushIds) . ')')
106
+ ->group('main_table.id');
107
+
108
+ foreach ($accountCollection as $account) {
109
+ $account->setData('status', $value)->save();
110
+ $i++;
111
+ }
112
+
113
+ Mage::getSingleton('adminhtml/session')->addSuccess(
114
+ Mage::helper('mobassistantconnector')->__('A total of %s account(s) have been updated.', $i)
115
+ );
116
+ }
117
+
118
+ $this->_redirect(
119
+ '*/*/edit',
120
+ array('user_id' => $this->getRequest()->getParam('user_id'), 'active_tab' => 'devices_section')
121
+ );
122
+ }
123
+
124
+ private function deleteDevice($pushIds)
125
+ {
126
+ if (empty($pushIds)) {
127
+ Mage::getSingleton('adminhtml/session')->addError(
128
+ Mage::helper('mobassistantconnector')->__('Nothing selected')
129
+ );
130
+ } else {
131
+ $pushCollection = Mage::getModel('emagicone_mobassistantconnector/push')->getCollection();
132
+ $pushCollection->getSelect()->where('main_table.id IN (' . implode(',', $pushIds) . ')');
133
+
134
+ try {
135
+ foreach ($pushCollection as $push) {
136
+ $push->delete();
137
+ }
138
+
139
+ Mage::getSingleton('adminhtml/session')->addSuccess(
140
+ Mage::helper('mobassistantconnector')->__('A total of %s record(s) have been deleted.', count($pushIds))
141
+ );
142
+
143
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyDevices();
144
+ Mage::helper('mobassistantconnector/deviceAndPushNotification')->deleteEmptyAccounts();
145
+ } catch (Exception $e) {
146
+ Mage::getSingleton('adminhtml/session')->addError('Could not delete records. ' . $e->getMessage());
147
+ }
148
+ }
149
+
150
+ $this->_redirect(
151
+ '*/*/edit',
152
+ array('user_id' => $this->getRequest()->getParam('user_id'), 'active_tab' => 'devices_section')
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Users grid
158
+ */
159
+ public function indexAction()
160
+ {
161
+ $this->_title($this->__('Users'))->_title($this->__('Manage Users'));
162
+
163
+ if ($this->getRequest()->getQuery('ajax')) {
164
+ $this->_forward('grid');
165
+ return;
166
+ }
167
+
168
+ $this->loadLayout();
169
+
170
+ /**
171
+ * Set active menu item
172
+ */
173
+ $this->_setActiveMenu('mobassistantconnector/mobassistantconnector_users');
174
+
175
+ /**
176
+ * Append customers block to content
177
+ */
178
+ $this->_addContent(
179
+ $this->getLayout()->createBlock('mobassistantconnector/adminhtml_user')
180
+ );
181
+
182
+ $this->getLayout()->getBlock('head')
183
+ ->addJs('emagicone/mobassistantconnector/jquery-2.2.2.min.js')
184
+ ->addJs('emagicone/mobassistantconnector/qrcode.min.js')
185
+ ->addJs('emagicone/mobassistantconnector/qrcode_app_user_index.js');
186
+
187
+ /**
188
+ * Add breadcrumb item
189
+ */
190
+ $this->_addBreadcrumb($this->__('Users'), $this->__('Users'));
191
+ $this->_addBreadcrumb($this->__('Manage Users'), $this->__('Manage Users'));
192
+
193
+ // Check if default user exists
194
+ $collection = Mage::getModel('emagicone_mobassistantconnector/user')->getCollection()
195
+ ->addFieldToFilter('username', '1')
196
+ ->addFieldToFilter('password', md5('1'));
197
+ if ($collection->getSize() > 0) {
198
+ Mage::getSingleton('adminhtml/session')->addWarning(
199
+ Mage::helper('mobassistantconnector')
200
+ ->__('Some user has default login and password are "1". Change them because of security reasons, please!')
201
+ );
202
+ }
203
+
204
+ $this->renderLayout();
205
+ }
206
+
207
+ public function gridAction()
208
+ {
209
+ $this->loadLayout();
210
+ $this->renderLayout();
211
+ }
212
+
213
+ public function newAction()
214
+ {
215
+ $this->_forward('edit');
216
+ }
217
+
218
+ /**
219
+ * Edit user
220
+ */
221
+ public function editAction()
222
+ {
223
+ $this->_title($this->__('Mobile Assistant Connector'))
224
+ ->_title($this->__('Manage Users'));
225
+
226
+ // 1. Get ID and create model
227
+ $id = $this->getRequest()->getParam('user_id');
228
+ $model = Mage::getModel('emagicone_mobassistantconnector/user');
229
+
230
+ // 2. Initial checking
231
+ if ($id) {
232
+ $model->load($id);
233
+
234
+ if (!$model->getId()) {
235
+ Mage::getSingleton('adminhtml/session')->addError(
236
+ Mage::helper('mobassistantconnector')->__('This user no longer exists.'));
237
+ $this->_redirect('*/*/');
238
+
239
+ return;
240
+ }
241
+ }
242
+
243
+ $this->_title($model->getId() ? $model->getUsername() : $this->__('New User'));
244
+
245
+ // 3. Set entered data if was error when we do save
246
+ $data = Mage::getSingleton('adminhtml/session')->getFormData(true);
247
+ if (!empty($data)) {
248
+ $model->setData($data);
249
+ }
250
+
251
+ // 4. Register model to use later in blocks
252
+ Mage::register('mobassistantconnector_user', $model);
253
+
254
+ $this->loadLayout();
255
+ $this->_setActiveMenu('mobassistantconnector/mobassistantconnector_users');
256
+ $this->renderLayout();
257
+ }
258
+
259
+ /**
260
+ * Save user action
261
+ */
262
+ public function saveAction()
263
+ {
264
+ $data = $this->getRequest()->getPost();
265
+
266
+ if (!$data) {
267
+ $this->_redirect('*/*/');
268
+ }
269
+
270
+ $model = Mage::getModel('emagicone_mobassistantconnector/user');
271
+
272
+ // Check if another user exists with the same username
273
+ $model->load($data['username'], 'username');
274
+ if (
275
+ $model->getData('username') == $data['username'] &&
276
+ (!isset($data['user_id']) || $data['user_id'] != $model->getId())
277
+ ) {
278
+ Mage::getSingleton('adminhtml/session')->addError(
279
+ Mage::helper('mobassistantconnector')
280
+ ->__("Another user exists with the same username '{$data['username']}'")
281
+ );
282
+
283
+ if (!isset($data['user_id'])) {
284
+ $this->_redirect('*/*/new', array('_current' => true));
285
+ } else {
286
+ $this->_redirect('*/*/edit', array('user_id' => $data['user_id'], '_current' => true));
287
+ }
288
+
289
+ return;
290
+ }
291
+
292
+ if ($id = $this->getRequest()->getParam('user_id')) {
293
+ $model->load($id);
294
+ }
295
+
296
+ if ($model->getData('username') != $data['username'] || $model->getData('password') != $data['password']) {
297
+ $model->setData('qr_code_hash', hash('sha256', time()));
298
+
299
+ if ($model->getData('password') != $data['password']) {
300
+ $model->setData('password', md5($data['password']));
301
+ }
302
+ }
303
+
304
+ $model->setData('status', $data['status']);
305
+ $model->setData('username', $data['username']);
306
+ $model->setData(
307
+ 'allowed_actions',
308
+ empty($data['allowed_actions']) ? '' : implode(';', $data['allowed_actions'])
309
+ );
310
+
311
+ try {
312
+ $model->save();
313
+
314
+ Mage::getSingleton('adminhtml/session')->addSuccess(
315
+ Mage::helper('mobassistantconnector')->__('The user has been saved.')
316
+ );
317
+
318
+ // clear previously saved data from session
319
+ Mage::getSingleton('adminhtml/session')->setFormData(false);
320
+
321
+ // check if 'Save and Continue'
322
+ if ($this->getRequest()->getParam('back')) {
323
+ $this->_redirect('*/*/edit', array('user_id' => $model->getId(), '_current' => true));
324
+ return;
325
+ }
326
+
327
+ // Go to grid
328
+ $this->_redirect('*/*/');
329
+ return;
330
+ } catch (Mage_Core_Exception $e) {
331
+ $this->_getSession()->addError($e->getMessage());
332
+ } catch (Exception $e) {
333
+ $this->_getSession()->addException(
334
+ $e,
335
+ Mage::helper('mobassistantconnector')->__('An error occurred while saving the user.')
336
+ );
337
+ }
338
+
339
+ $this->_getSession()->setFormData($data);
340
+ $this->_redirect('*/*/edit', array('user_id' => $this->getRequest()->getParam('user_id')));
341
+ }
342
+
343
+ /**
344
+ * Delete user action
345
+ */
346
+ public function deleteAction()
347
+ {
348
+ $this->deleteUser(array($this->getRequest()->getParam('user_id')));
349
+ }
350
+
351
+ /**
352
+ * Delete selected users action
353
+ */
354
+ public function massDeleteAction()
355
+ {
356
+ $this->deleteUser($this->getRequest()->getPost('user_ids', array()));
357
+ }
358
+
359
+ public function devicesAction()
360
+ {
361
+ $this->loadLayout();
362
+ $this->renderLayout();
363
+ }
364
+
365
+ /**
366
+ * Enable selected users
367
+ */
368
+ public function massEnableAction()
369
+ {
370
+ $this->changeUserStatus(1);
371
+ }
372
+
373
+ /**
374
+ * Disable selected users
375
+ */
376
+ public function massDisableAction()
377
+ {
378
+ $this->changeUserStatus(0);
379
+ }
380
+
381
+ /**
382
+ * Mass change status of selected accounts
383
+ */
384
+ public function massChangeStatusAccountAction()
385
+ {
386
+ $this->changeStatusAccount($this->getRequest()->getPost('push_ids', array()));
387
+ }
388
+
389
+ /**
390
+ * Change status of selected account
391
+ */
392
+ public function changeStatusAccountAction()
393
+ {
394
+ $this->changeStatusAccount(array($this->getRequest()->getParam('push_id')));
395
+ }
396
+
397
+ /**
398
+ * Mass delete selected push records
399
+ */
400
+ public function massDeleteDeviceAction()
401
+ {
402
+ $this->deleteDevice($this->getRequest()->getPost('push_ids', array()));
403
+ }
404
+
405
+ /**
406
+ * Delete push record
407
+ */
408
+ public function deleteDeviceAction()
409
+ {
410
+ $this->deleteDevice(array($this->getRequest()->getParam('push_id', array())));
411
+ }
412
+
413
+ /**
414
+ * Check the permission to run it
415
+ *
416
+ * @return boolean
417
+ */
418
+ protected function _isAllowed()
419
+ {
420
+ $action = strtolower($this->getRequest()->getActionName());
421
+
422
+ switch ($action) {
423
+ case 'new':
424
+ case 'save':
425
+ return Mage::getSingleton('admin/session')->isAllowed('user/save');
426
+ break;
427
+ case 'delete':
428
+ return Mage::getSingleton('admin/session')->isAllowed('user/delete');
429
+ break;
430
+ default:
431
+ return Mage::getSingleton('admin/session')->isAllowed('user');
432
+ break;
433
+ }
434
+ }
435
+
436
+ }
app/code/community/Emagicone/Mobassistantconnector/controllers/IndexController.php CHANGED
@@ -18,22 +18,39 @@
18
  */
19
  class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controller_Front_Action
20
  {
21
- public $CartClass = "";
22
  public $call_function;
23
  public $callback;
24
  public $hash = false;
25
  public $def_currency;
26
  public $currency_code;
27
  public $store_group_id = -1;
28
- private $hash_only;
29
  private $session_key;
30
- const GSM_URL = 'https://android.googleapis.com/gcm/send';
31
- const MB_VERSION = '98';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  public function indexAction()
34
  {
35
  // Mage::app()->cleanCache();
36
- if (intval(Mage::getStoreConfig('mobassistantconnectorinfosec/emogeneral/status')) != 1) $this->generate_output('module_disabled');
 
 
 
37
 
38
  // $this->loadLayout()->renderLayout();
39
 
@@ -42,121 +59,135 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
42
 
43
  Mage::helper('mobassistantconnector/access')->clearOldData();
44
 
45
- if ($this->getRequest()->has('callback') && (strlen($this->getRequest()->get('callback')) > 0))
46
  $this->callback = $this->getRequest()->get('callback');
47
- if ($this->getRequest()->has('call_function') && (strlen($this->getRequest()->get('call_function')) > 0)) {
 
 
48
  $this->call_function = $this->getRequest()->get('call_function');
49
  } else {
50
  $this->run_self_test();
51
  }
52
- if ($this->getRequest()->has('hash') && (strlen($this->getRequest()->get('hash')) > 0))
 
 
 
 
 
53
  $this->hash = $this->getRequest()->get('hash');
54
- if ($this->getRequest()->has('key') && (strlen($this->getRequest()->get('key')) > 0))
 
 
55
  $this->session_key = $this->getRequest()->get('key');
56
- if ($this->getRequest()->has('hash_only') && (strlen($this->getRequest()->get('hash_only')) > 0))
57
- $this->hash_only = $this->getRequest()->get('hash_only');
58
 
 
 
 
59
 
60
- if ($this->hash_only) {
61
- $this->generate_output('You should update Magento Mobile Assistant application.');
62
  }
63
- // if(!$this->check_auth()) {
64
- // $this->generate_output('auth_error');
65
- // }
66
 
67
- /******************************************/
68
- if ($this->getRequest()->has('call_function') && ($this->getRequest()->get('call_function') == 'get_version')) {
 
 
 
69
  $this->get_version();
70
  }
71
 
 
 
 
 
72
  if ($this->hash) {
73
- if (!$this->check_auth()) {
74
- Mage::helper('mobassistantconnector/access')->addFailedAttempt();
75
- Mage::log(
76
- "Hash accepted ({$this->hash}) is incorrect",
77
- null,
78
- 'emagicone_mobassistantconnector.log'
79
- );
80
  $this->generate_output('auth_error');
81
- } else {
82
- $this->session_key = Mage::helper('mobassistantconnector/access')->getSessionKey($this->hash);
83
- $this->generate_output(array('session_key' => $this->session_key));
84
  }
85
- } elseif ($this->session_key) {
 
 
86
  if (!Mage::helper('mobassistantconnector/access')->checkSessionKey($this->session_key)) {
87
- Mage::log(
88
- "Key accepted ({$this->session_key}) is incorrect",
89
- null,
90
- 'emagicone_mobassistantconnector.log'
91
- );
92
  $this->generate_output(array('bad_session_key' => true));
93
  }
94
  } else {
95
  Mage::helper('mobassistantconnector/access')->addFailedAttempt();
 
96
  $this->generate_output('auth_error');
97
  }
98
 
99
-
100
  $request_params = Mage::app()->getRequest()->getParams();
101
 
102
- $params = $this->validate_types($request_params, array(
103
- 'show' => 'INT',
104
- 'page' => 'INT',
105
- 'search_order_id' => 'STR',
106
- 'orders_from' => 'STR',
107
- 'orders_to' => 'STR',
108
- 'order_number' => 'STR',
109
- 'customers_from' => 'STR',
110
- 'customers_to' => 'STR',
111
- 'date_from' => 'STR',
112
- 'date_to' => 'STR',
113
- 'graph_from' => 'STR',
114
- 'graph_to' => 'STR',
115
- 'stats_from' => 'STR',
116
- 'stats_to' => 'STR',
117
- 'products_to' => 'STR',
118
- 'products_from' => 'STR',
119
- 'order_id' => 'INT',
120
- 'user_id' => 'INT',
121
- 'params' => 'STR',
122
- 'val' => 'STR',
123
- 'search_val' => 'STR',
124
- 'statuses' => 'STR',
125
- 'sort_by' => 'STR',
126
- 'order_by' => 'STR',
127
- 'last_order_id' => 'STR',
128
- 'product_id' => 'INT',
129
- 'get_statuses' => 'INT',
130
- 'cust_with_orders' => 'INT',
131
- 'data_for_widget' => 'INT',
132
- 'registration_id' => 'STR',
133
- 'registration_id_old' => 'STR',
134
- 'registration_id_new' => 'STR',
135
- 'api_key' => 'STR',
136
- 'tracking_number' => 'STR',
137
- 'tracking_title' => 'STR',
138
- 'action' => 'STR',
139
- 'carrier_code' => 'STR',
140
- 'custom_period' => 'INT',
141
- 'group_id' => 'INT',
142
- 'push_new_customer' => 'INT',
143
- 'push_new_order' => 'INT',
144
- 'push_currency_code' => 'STR',
145
- 'app_connection_id' => 'STR',
146
- 'push_store_group_id' => 'STR',
147
- 'push_order_statuses' => 'STR',
148
- 'currency_code' => 'STR',
149
- 'is_mail' => 'INT',
150
- 'store_group_id' => 'INT',
151
- 'carts_from' => 'STR',
152
- 'carts_to' => 'STR',
153
- 'cart_id' => 'STR',
154
- 'search_carts' => 'STR',
155
- 'param' => 'STR',
156
- 'new_value' => 'STR',
157
- 'group_by_product_id' => 'INT',
158
- 'show_unregistered_customers' => 'INT',
159
- ));
 
 
 
 
 
 
 
160
 
161
  foreach ($params as $k => $value) {
162
  $this->{$k} = $value;
@@ -166,20 +197,26 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
166
  $this->store_group_id = $this->group_id;
167
  }
168
 
169
- if (empty($this->currency_code) || strval($this->currency_code) == 'base_currency' || strval($this->currency_code) == 'not_set') {
 
 
 
 
170
  $this->currency_code = $this->def_currency;
171
  }
172
 
173
- if (empty($this->page)) {
174
- $this->page = 1;
175
- }
176
-
177
- if (empty($this->show)) {
178
- $this->show = 20;
179
- }
180
 
181
  if ($this->call_function == 'test_config') {
182
- $this->generate_output(array('test' => 1));
 
 
 
 
 
 
 
183
  }
184
 
185
  $locale = Mage::app()->getLocale()->getLocaleCode();
@@ -194,8 +231,9 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
194
  $this->generate_output('old_module');
195
  }
196
 
197
- $result = call_user_func(array($this, $this->call_function));
198
 
 
199
  $this->generate_output($result);
200
  }
201
 
@@ -243,53 +281,90 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
243
 
244
  }*/
245
 
246
- protected function generate_output($data)
247
  {
248
- if (!in_array($this->call_function, array("get_order_pdf"))) {
249
- $add_bridge_version = false;
250
- if (in_array($this->call_function, array('test_config', 'get_store_title', 'get_store_stats', 'get_data_graphs', 'get_version'))) {
251
- if (is_array($data) && $data != 'auth_error' && $data != 'connection_error' && $data != 'old_bridge') {
252
- $add_bridge_version = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  }
254
  }
 
255
 
256
- if (!is_array($data)) {
257
- $data = array($data);
258
- }
259
 
260
- if (is_array($data)) {
261
- array_walk_recursive($data, array($this, 'reset_null'));
 
 
 
 
 
262
  }
 
263
 
264
- if ($add_bridge_version) {
265
- $data['module_version'] = self::MB_VERSION;
266
- }
267
 
268
- // $data = $this->to_json($data);
269
- $data = Mage::helper('core')->jsonEncode($data);
 
270
 
271
- // $this->getResponse()->clearHeaders()->setHeader('Content-type', 'application/json');
272
- // $this->getResponse()->setBody($data);
273
- // $this->getResponse()->sendResponse();
274
- // die();
275
 
276
- if ($this->callback) {
277
- header('Content-Type: text/javascript;charset=utf-8');
278
- die($this->callback . '(' . $data . ');');
279
- } else {
280
- header('Content-Type: text/javascript;charset=utf-8');
281
- die($data);
282
- }
283
- if ($this->callback) {
284
- header('Content-Type: text/javascript;charset=utf-8');
285
- die($this->callback . '(' . $data . ');');
286
- } else {
287
- header('Content-Type: text/javascript;charset=utf-8');
288
- die($data);
289
- }
290
  }
 
291
 
292
- die($data);
293
  }
294
 
295
  protected function check_auth()
@@ -309,9 +384,27 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
309
  }
310
  }
311
 
312
- protected function get_version()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  {
314
- if ($this->hash ) {
315
  if ($this->check_auth()) {
316
  if (!Mage::helper('mobassistantconnector/access')->checkSessionKey($this->session_key)) {
317
  $this->session_key = Mage::helper('mobassistantconnector/access')->getSessionKey($this->hash);
@@ -334,11 +427,35 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
334
  if (!empty($this->session_key)) {
335
  $this->generate_output(array('session_key' => $this->session_key));
336
  }
337
- $this->generate_output(array());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
 
339
  }
340
 
341
- protected function run_self_test()
342
  {
343
  $html = '<h2>Mobile Assistant Connector v.' . Mage::getConfig()->getModuleConfig("Emagicone_Mobassistantconnector")->version->__toString() . ' </h2>';
344
 
@@ -352,164 +469,124 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
352
  /**
353
  * Delete push config by registration_id and app_connection_id
354
  */
355
- protected function delete_push_config() {
356
- if (isset($this->app_connection_id)
357
- && isset($this->registration_id)
358
- && strlen($this->registration_id) > 0
359
- && strlen($this->app_connection_id) > 0
360
- ) {
361
- $data_changed = false;
362
- $deviceIds = Mage::getStoreConfig('mobassistantconnectorinfosec/access/google_ids');
363
- if (strlen($deviceIds) > 0) {
364
- $deviceIds = unserialize($deviceIds);
365
- } else $deviceIds = array();
366
-
367
- foreach ($deviceIds as $id => $deviceId) {
368
- if ($deviceId['push_device_id'] == $this->registration_id && $deviceId['app_connection_id'] == $this->app_connection_id) {
369
- unset($deviceIds[$id]);
370
- $data_changed = true;
371
- }
372
- }
373
 
374
- if ($data_changed) {
375
- Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/google_ids', serialize($deviceIds));
376
- }
 
 
377
 
378
- $result = array('success' => 'true');
 
 
 
 
379
  } else {
380
  $result = array('error' => $this->__('Missing parameters'));
381
  }
382
 
 
 
 
383
  return $result;
384
  }
385
-
386
- protected function push_notification_settings()
387
  {
388
- $result = array();
389
- $statuses = array();
390
- $matched = false;
391
- $deviceActions = array('push_device_id' => '',
392
- 'push_new_order' => 0,
393
- 'push_order_statuses' => '',
394
- 'push_new_customer' => 0,
395
- 'app_connection_id' => -1,
396
- 'push_store_group_id' => -1,
397
- 'push_currency_code' => '');
398
-
399
- $deviceIds = Mage::getStoreConfig('mobassistantconnectorinfosec/access/google_ids');
400
- if (strlen($deviceIds) > 0) {
401
- $deviceIds = unserialize($deviceIds);
402
- } else $deviceIds = array();
403
-
404
- foreach (array_keys($deviceIds) as $key) {
405
- if (!is_int($key)) {
406
- $deviceIds[$key]['push_device_id'] = $key;
407
- if (empty($deviceIds[$key]['push_store_group_id'])) {
408
- $deviceIds[$key]['push_store_group_id'] = -1;
409
- }
410
- array_push($deviceIds, $deviceIds[$key]);
411
- unset($deviceIds[$key]);
412
- }
413
  }
414
 
415
- if (strlen($this->registration_id) > 0 && strlen($this->api_key) > 0) {
416
-
417
- if (strlen($this->registration_id) > 0) {
418
- $deviceActions['push_device_id'] = $this->registration_id;
419
- }
420
-
421
- if (strlen($this->push_new_order) > 0) {
422
- $deviceActions['push_new_order'] = $this->push_new_order;
423
- } else {
424
- $deviceActions['push_new_order'] = 0;
425
- }
426
 
427
- if (strlen($this->push_order_statuses) > 0) {
428
- $deviceActions['push_order_statuses'] = $this->push_order_statuses;
429
- } else {
430
- $deviceActions['push_order_statuses'] = '';
431
  }
432
 
433
- if (strlen($this->push_new_customer) > 0) {
434
- $deviceActions['push_new_customer'] = $this->push_new_customer;
435
- } else {
436
- $deviceActions['push_new_customer'] = 0;
437
  }
438
 
439
- if (!empty($this->store_group_id)) {
440
- $deviceActions['push_store_group_id'] = $this->store_group_id;
441
- } else {
442
- $deviceActions['push_store_group_id'] = -1;
443
  }
444
 
445
- if (!empty($this->app_connection_id)) {
446
- $deviceActions['app_connection_id'] = $this->app_connection_id;
447
- } else {
448
- $deviceActions['app_connection_id'] = -1;
449
- }
 
450
 
451
- if (strlen($this->push_currency_code) > 0) {
452
- $deviceActions['push_currency_code'] = $this->push_currency_code;
453
- } else if (strlen($this->currency_code) > 0) {
454
- $deviceActions['push_currency_code'] = $this->currency_code;
455
- } else {
456
- $deviceActions['push_currency_code'] = 'base_currency';
457
- }
458
 
459
  // Delete empty record
460
- if ((intval($this->push_new_order) == 0) && (strlen($this->push_order_statuses) == 0) && (intval($this->push_new_customer) == 0)) {
461
- foreach ($deviceIds as $settingNum => $deviceId) {
462
- if ($deviceId['push_device_id'] == $this->registration_id
463
- && (isset($deviceId['app_connection_id'])
464
- && $deviceId['app_connection_id'] == $deviceActions['app_connection_id'])
465
- ) {
466
- unset($deviceIds[$settingNum]);
467
- } else if ($deviceId['push_device_id'] == $this->registration_id
468
- && $deviceId['push_store_group_id'] == $this->store_group_id
469
- && (!isset($deviceId['app_connection_id']) || $deviceId['app_connection_id'] == -1)
470
- ) {
471
- unset($deviceIds[$settingNum]);
472
- }
 
 
 
 
 
 
 
 
 
 
 
473
  }
474
- } else {
475
- // renew old record
476
- foreach ($deviceIds as $settingNum => $deviceId) {
477
- if ($deviceId['push_device_id'] == $this->registration_id
478
- && (isset($deviceId['app_connection_id'])
479
- && $deviceId['app_connection_id'] == $deviceActions['app_connection_id'])
480
- ) {
481
- $deviceIds[$settingNum] = $deviceActions;
482
- $matched = true;
483
- } else if ($deviceId['push_device_id'] == $this->registration_id
484
- && $deviceId['push_store_group_id'] == $deviceActions['push_store_group_id']
485
- && !isset($deviceId['app_connection_id'])
486
- ) {
487
- $deviceIds[$settingNum] = $deviceActions;
488
- $matched = true;
489
- }
490
  }
491
- if (!$matched) {
492
- // add new record
493
- array_push($deviceIds, $deviceActions);
494
  }
495
- }
496
 
497
- // Delete old registration id
498
- if (isset($this->registration_id_old) && strlen($this->registration_id_old) > 0) {
499
- foreach ($deviceIds as $settingNum => $deviceId) {
500
- if ($deviceId['push_device_id'] == $this->registration_id_old) {
501
- unset($deviceIds[$settingNum]);
502
- }
503
  }
504
- }
505
 
506
- Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/google_ids', serialize($deviceIds));
 
507
 
508
  Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/api_key', $this->api_key);
509
 
510
- $result = array('success' => 'true');
511
- } else
512
- $result = array('error' => $this->__('Can not get configuration value'));
 
 
 
 
 
513
 
514
  return $result;
515
  }
@@ -1587,13 +1664,16 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
1587
  echo $e->getMessage();
1588
  }
1589
  } else {
1590
- return false;
 
1591
  }
1592
  } else {
1593
- return false;
 
1594
  }
1595
 
1596
- return Mage::app()->getResponse();
 
1597
  }
1598
 
1599
  protected function map_order_statuses($status)
@@ -2161,12 +2241,12 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
2161
  )
2162
  ->joinLeft(
2163
  array('a_price' => Mage::getConfig()->getTablePrefix() . 'eav_attribute'),
2164
- "a_price.entity_type_id = et_product.entity_type_id AND a_price.attribute_code = 'price'",
2165
  array()
2166
  )
2167
  ->joinLeft(
2168
  array('p_price' => Mage::getConfig()->getTablePrefix() . 'catalog_product_entity_decimal'),
2169
- "p_price.entity_id = e.entity_id AND p_price.attribute_id = a_price.attribute_id AND p_price.store_id = 0",
2170
  array('p_price.value AS price')
2171
  );
2172
 
@@ -2334,7 +2414,8 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
2334
  $salesItemCollection->getSelect()->columns(array(
2335
  'qty_ordered_product' => 'SUM(main_table.qty_ordered)',
2336
  'price_total' => 'SUM(main_table.base_price - main_table.base_discount_amount)',
2337
- 'orig_price' => 'SUM(main_table.base_price - main_table.base_discount_amount) * main_table.qty_ordered'
 
2338
  )
2339
  );
2340
  // $salesCollection->getSelect()->columns("SUM(main_table.qty_ordered)");
@@ -2730,34 +2811,43 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
2730
  unset($row['spec_price']);
2731
  }
2732
 
2733
- $images = array();
 
 
 
2734
  // $mediaGallery = Mage::getModel('catalog/product')->load($product->getId())->getMediaGalleryImages();
2735
  $mediaGallery = $product->getMediaGallery();
2736
  if (is_array($mediaGallery['images'])) {
2737
  foreach ($mediaGallery['images'] as $image) {
2738
- if ($image['disabled']) {
2739
  // continue;
2740
- }
2741
  $small = Mage::helper('catalog/image')->init($product, 'image', $image['file'])->resize(300)
2742
  ->keepAspectRatio(true)->constrainOnly(true)->keepFrame(false);
2743
  $small_image = $small->__toString();
2744
  $large = Mage::helper('catalog/image')->init($product, 'image', $image['file'])->resize(800)
2745
  ->keepAspectRatio(true)->constrainOnly(true)->keepFrame(false);
2746
  $large_image = $large->__toString();
2747
- $images[] = array('large' => $large_image,
2748
- 'small' => $small_image
2749
- );
 
 
 
2750
  }
2751
  }
2752
 
2753
- $row['images'] = $images;
 
2754
 
2755
  // For compatibility with old app version
2756
- if (count($images) > 0) {
2757
- $row['id_image'] = $images[0]['small'];
2758
- $row['id_image_large'] = $images[0]['large'];
 
 
 
2759
  }
2760
-
2761
  }
2762
 
2763
  return $row;
@@ -2964,6 +3054,7 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
2964
  $dir = $this->get_sort_direction('ASC');
2965
  // $quotes->getSelect()->order(array('main_table' . '.customer_firstname' . $dir));
2966
  $quotes->getSelect()->order(array('customer_name ' . $dir));
 
2967
  break;
2968
  case 'qty':
2969
  $dir = $this->get_sort_direction('ASC');
@@ -3005,10 +3096,10 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
3005
  $cart['email'] = $quote->getCustomerEmail();
3006
  $cart['customer'] = $quote->getCustomerFirstname() . ' ' . $quote->getCustomerLastname();
3007
 
3008
- if (!is_null($quote->getCustomer()->getId())) {
3009
  $cart['email'] = $quote->getCustomer()->getEmail();
3010
  $cart['customer'] = $quote->getCustomer()->getFirstname() . ' ' . $quote->getCustomer()->getLastname();
3011
- }
3012
 
3013
  if ($storeName = Mage::getModel('core/store')->load($quote->getStoreId())->getName())
3014
  $cart['shop_name'] = $storeName;
@@ -3246,6 +3337,44 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
3246
  );
3247
  }
3248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3249
  private function getStockOptions() {
3250
  $stockOptions = array();
3251
  $options = Mage::getSingleton('Mage_CatalogInventory_Model_Source_Stock')->toOptionArray();
@@ -3279,7 +3408,6 @@ class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controll
3279
  'emagicone_mobassistantconnector.log'
3280
  );
3281
  }
3282
-
3283
  }
3284
 
3285
  if ($format) {
18
  */
19
  class Emagicone_Mobassistantconnector_IndexController extends Mage_Core_Controller_Front_Action
20
  {
21
+ // public $CartClass = "";
22
  public $call_function;
23
  public $callback;
24
  public $hash = false;
25
  public $def_currency;
26
  public $currency_code;
27
  public $store_group_id = -1;
28
+ // private $hash_only;
29
  private $session_key;
30
+ private $device_unique_id;
31
+ private $registration_id;
32
+ private $account_email;
33
+ private $device_name;
34
+ private $check_permission;
35
+ private $app_connection_id;
36
+ private $api_key;
37
+ private $registration_id_old;
38
+ private $push_new_order;
39
+ private $push_order_statuses;
40
+ private $push_new_customer;
41
+ private $push_currency_code;
42
+ private $group_id;
43
+
44
+ // const GSM_URL = 'https://android.googleapis.com/gcm/send';
45
+ const MB_VERSION = '99';
46
 
47
  public function indexAction()
48
  {
49
  // Mage::app()->cleanCache();
50
+ // if (intval(Mage::getStoreConfig('mobassistantconnectorinfosec/emogeneral/status')) != 1) $this->generate_output('module_disabled');
51
+ if (!Mage::helper('core')->isModuleOutputEnabled('Emagicone_Mobassistantconnector')) {
52
+ $this->generate_output('module_disabled');
53
+ }
54
 
55
  // $this->loadLayout()->renderLayout();
56
 
59
 
60
  Mage::helper('mobassistantconnector/access')->clearOldData();
61
 
62
+ if ($this->getRequest()->has('callback')) {
63
  $this->callback = $this->getRequest()->get('callback');
64
+ }
65
+
66
+ if ($this->getRequest()->has('call_function')) {
67
  $this->call_function = $this->getRequest()->get('call_function');
68
  } else {
69
  $this->run_self_test();
70
  }
71
+
72
+ if ($this->getRequest()->has('hash_only')) {
73
+ $this->generate_output('You should update Magento Mobile Assistant application.');
74
+ }
75
+
76
+ if ($this->getRequest()->has('hash')) {
77
  $this->hash = $this->getRequest()->get('hash');
78
+ }
79
+
80
+ if ($this->getRequest()->has('key')) {
81
  $this->session_key = $this->getRequest()->get('key');
82
+ }
 
83
 
84
+ if ($this->getRequest()->has('device_unique_id')) {
85
+ $this->device_unique_id = $this->getRequest()->get('device_unique_id');
86
+ }
87
 
88
+ if ($this->getRequest()->has('registration_id')) {
89
+ $this->registration_id = $this->getRequest()->get('registration_id');
90
  }
 
 
 
91
 
92
+ $this->account_email = $this->getRequest()->has('account_email') ? $this->getRequest()->get('account_email') : null;
93
+
94
+ $this->updateDeviceLastActivity();
95
+
96
+ if ($this->call_function == 'get_version') {
97
  $this->get_version();
98
  }
99
 
100
+ if ($this->call_function == 'get_qr_code' && $this->hash) {
101
+ $this->getQrCode($this->hash);
102
+ }
103
+
104
  if ($this->hash) {
105
+ $key = Mage::helper('mobassistantconnector/access')->getSessionKey($this->hash);
106
+
107
+ if (!$key) {
108
+ Mage::log('Hash accepted is incorrect');
 
 
 
109
  $this->generate_output('auth_error');
 
 
 
110
  }
111
+
112
+ $this->generate_output(array('session_key' => $key));
113
+ } elseif ($this->session_key || $this->session_key === '') {
114
  if (!Mage::helper('mobassistantconnector/access')->checkSessionKey($this->session_key)) {
115
+ Mage::log('Key accepted is incorrect', null, 'emagicone_mobassistantconnector.log');
 
 
 
 
116
  $this->generate_output(array('bad_session_key' => true));
117
  }
118
  } else {
119
  Mage::helper('mobassistantconnector/access')->addFailedAttempt();
120
+ Mage::log('Authorization error', null, 'emagicone_mobassistantconnector.log');
121
  $this->generate_output('auth_error');
122
  }
123
 
 
124
  $request_params = Mage::app()->getRequest()->getParams();
125
 
126
+ $params = $this->validate_types(
127
+ $request_params,
128
+ array(
129
+ 'show' => 'INT',
130
+ 'page' => 'INT',
131
+ 'search_order_id' => 'STR',
132
+ 'orders_from' => 'STR',
133
+ 'orders_to' => 'STR',
134
+ 'order_number' => 'STR',
135
+ 'customers_from' => 'STR',
136
+ 'customers_to' => 'STR',
137
+ 'date_from' => 'STR',
138
+ 'date_to' => 'STR',
139
+ 'graph_from' => 'STR',
140
+ 'graph_to' => 'STR',
141
+ 'stats_from' => 'STR',
142
+ 'stats_to' => 'STR',
143
+ 'products_to' => 'STR',
144
+ 'products_from' => 'STR',
145
+ 'order_id' => 'INT',
146
+ 'user_id' => 'INT',
147
+ 'params' => 'STR',
148
+ 'val' => 'STR',
149
+ 'search_val' => 'STR',
150
+ 'statuses' => 'STR',
151
+ 'sort_by' => 'STR',
152
+ 'order_by' => 'STR',
153
+ 'last_order_id' => 'STR',
154
+ 'product_id' => 'INT',
155
+ 'get_statuses' => 'INT',
156
+ 'cust_with_orders' => 'INT',
157
+ 'data_for_widget' => 'INT',
158
+ 'registration_id' => 'STR',
159
+ 'registration_id_old' => 'STR',
160
+ 'registration_id_new' => 'STR',
161
+ 'api_key' => 'STR',
162
+ 'tracking_number' => 'STR',
163
+ 'tracking_title' => 'STR',
164
+ 'action' => 'STR',
165
+ 'carrier_code' => 'STR',
166
+ 'custom_period' => 'INT',
167
+ 'group_id' => 'INT',
168
+ 'push_new_customer' => 'INT',
169
+ 'push_new_order' => 'INT',
170
+ 'push_currency_code' => 'STR',
171
+ 'app_connection_id' => 'STR',
172
+ 'device_unique_id' => 'STR',
173
+ 'push_store_group_id' => 'STR',
174
+ 'push_order_statuses' => 'STR',
175
+ 'device_name' => 'STR',
176
+ 'account_email' => 'STR',
177
+ 'currency_code' => 'STR',
178
+ 'is_mail' => 'INT',
179
+ 'store_group_id' => 'INT',
180
+ 'carts_from' => 'STR',
181
+ 'carts_to' => 'STR',
182
+ 'cart_id' => 'STR',
183
+ 'search_carts' => 'STR',
184
+ 'param' => 'STR',
185
+ 'new_value' => 'STR',
186
+ 'group_by_product_id' => 'INT',
187
+ 'show_unregistered_customers' => 'INT',
188
+ 'check_permission' => 'STR',
189
+ )
190
+ );
191
 
192
  foreach ($params as $k => $value) {
193
  $this->{$k} = $value;
197
  $this->store_group_id = $this->group_id;
198
  }
199
 
200
+ if (
201
+ empty($this->currency_code)
202
+ || (string)$this->currency_code == 'base_currency'
203
+ || (string)$this->currency_code == 'not_set'
204
+ ) {
205
  $this->currency_code = $this->def_currency;
206
  }
207
 
208
+ $this->show = (empty($this->show) || $this->show < 1) ? 25 : $this->show;
209
+ $this->page = (empty($this->page) || $this->page < 1) ? 1 : $this->page;
 
 
 
 
 
210
 
211
  if ($this->call_function == 'test_config') {
212
+ $result = array('test' => 1);
213
+
214
+ if ($this->check_permission) {
215
+ $this->call_function = $this->check_permission;
216
+ $result['permission_granted'] = $this->isActionAllowed() ? '1' : '0';
217
+ }
218
+
219
+ $this->generate_output($result);
220
  }
221
 
222
  $locale = Mage::app()->getLocale()->getLocaleCode();
231
  $this->generate_output('old_module');
232
  }
233
 
234
+ $this->checkAllowedActions();
235
 
236
+ $result = call_user_func(array($this, $this->call_function));
237
  $this->generate_output($result);
238
  }
239
 
281
 
282
  }*/
283
 
284
+ private function checkAllowedActions()
285
  {
286
+ if (!$this->isActionAllowed()) {
287
+ $this->generate_output('action_forbidden');
288
+ }
289
+ }
290
+
291
+ private function isActionAllowed() {
292
+ $allowed_functions_always = Mage::helper('mobassistantconnector/userPermissions')->getAlwaysAllowedFunctions();
293
+
294
+ if (in_array($this->call_function, $allowed_functions_always)) {
295
+ return true;
296
+ }
297
+
298
+ $allowed_actions = Mage::helper('mobassistantconnector/access')->getAllowedActionsBySessionKey($this->session_key);
299
+ $restricted_actions_to_functions = Mage::helper('mobassistantconnector/userPermissions')
300
+ ->getRestrictedActionsToFunctions();
301
+ $is_allowed = false;
302
+
303
+ if ($this->call_function == 'set_order_action') {
304
+ if ($this->action == 'cancel' && in_array('order_cancel', $allowed_actions)) {
305
+ $is_allowed = true;
306
+ } elseif ($this->action == 'hold' && in_array('order_hold', $allowed_actions)) {
307
+ $is_allowed = true;
308
+ } elseif ($this->action == 'unhold' && in_array('order_unhold', $allowed_actions)) {
309
+ $is_allowed = true;
310
+ } elseif ($this->action == 'invoice' && in_array('order_invoice', $allowed_actions)) {
311
+ $is_allowed = true;
312
+ } elseif ($this->action == 'ship' && in_array('order_ship', $allowed_actions)) {
313
+ $is_allowed = true;
314
+ } elseif ($this->action == 'del_track' && in_array('order_delete_track_number', $allowed_actions)) {
315
+ $is_allowed = true;
316
+ }
317
+ } else {
318
+ foreach ($restricted_actions_to_functions as $key => $values) {
319
+ if (in_array($this->call_function, $values) && in_array($key, $allowed_actions)) {
320
+ $is_allowed = true;
321
+ break;
322
  }
323
  }
324
+ }
325
 
326
+ return $is_allowed;
327
+ }
 
328
 
329
+ protected function generate_output($data)
330
+ {
331
+ // if (!in_array($this->call_function, array("get_order_pdf"))) {
332
+ $add_bridge_version = false;
333
+ if (in_array($this->call_function, array('test_config', 'get_store_title', 'get_store_stats', 'get_data_graphs', 'get_version'))) {
334
+ if (is_array($data) && $data != 'auth_error' && $data != 'connection_error' && $data != 'old_bridge') {
335
+ $add_bridge_version = true;
336
  }
337
+ }
338
 
339
+ if (!is_array($data)) {
340
+ $data = array($data);
341
+ }
342
 
343
+ if (is_array($data)) {
344
+ array_walk_recursive($data, array($this, 'reset_null'));
345
+ }
346
 
347
+ if ($add_bridge_version) {
348
+ $data['module_version'] = self::MB_VERSION;
349
+ }
 
350
 
351
+ // $data = $this->to_json($data);
352
+ $data = Mage::helper('core')->jsonEncode($data);
353
+
354
+ // $this->getResponse()->clearHeaders()->setHeader('Content-type', 'application/json');
355
+ // $this->getResponse()->setBody($data);
356
+ // $this->getResponse()->sendResponse();
357
+ // die();
358
+ header('Content-Type: text/javascript;charset=utf-8');
359
+
360
+ if ($this->callback) {
361
+ die($this->callback . '(' . $data . ');');
362
+ } else {
363
+ die($data);
 
364
  }
365
+ // }
366
 
367
+ // die($data);
368
  }
369
 
370
  protected function check_auth()
384
  }
385
  }
386
 
387
+ private function updateDeviceLastActivity()
388
+ {
389
+ $account_id = null;
390
+
391
+ if ($this->account_email) {
392
+ $account = Mage::getModel('emagicone_mobassistantconnector/account')
393
+ ->saveAndGetAccountByEmail($this->account_email);
394
+ $account_id = $account->getId();
395
+ }
396
+
397
+ if ($this->device_unique_id) {
398
+ Mage::getModel('emagicone_mobassistantconnector/device')
399
+ ->loadByDeviceUniqueAndAccountId($this->device_unique_id, $account_id)
400
+ ->setData('last_activity', date('Y-m-d H:i:s'))
401
+ ->save();
402
+ }
403
+ }
404
+
405
+ private function get_version()
406
  {
407
+ /*if ($this->hash ) {
408
  if ($this->check_auth()) {
409
  if (!Mage::helper('mobassistantconnector/access')->checkSessionKey($this->session_key)) {
410
  $this->session_key = Mage::helper('mobassistantconnector/access')->getSessionKey($this->hash);
427
  if (!empty($this->session_key)) {
428
  $this->generate_output(array('session_key' => $this->session_key));
429
  }
430
+ $this->generate_output(array());*/
431
+
432
+ $session_key = '';
433
+ $helperAccess = Mage::helper('mobassistantconnector/access');
434
+
435
+ if ($this->hash) {
436
+ $user_data = $helperAccess->checkAuth($this->hash, true);
437
+
438
+ if ($user_data) {
439
+ if ($this->session_key) {
440
+ if ($helperAccess->checkSessionKey($this->session_key, $user_data['user_id'])) {
441
+ $session_key = $this->session_key;
442
+ } else {
443
+ $session_key = $helperAccess->getSessionKey($this->hash, $user_data['user_id']);
444
+ }
445
+ } else {
446
+ $session_key = $helperAccess->getSessionKey($this->hash, $user_data['user_id']);
447
+ }
448
+ } else {
449
+ $this->generate_output('auth_error');
450
+ }
451
+ } elseif ($this->session_key && $helperAccess->checkSessionKey($this->session_key)) {
452
+ $session_key = $this->session_key;
453
+ }
454
 
455
+ $this->generate_output(array('session_key' => $session_key));
456
  }
457
 
458
+ private function run_self_test()
459
  {
460
  $html = '<h2>Mobile Assistant Connector v.' . Mage::getConfig()->getModuleConfig("Emagicone_Mobassistantconnector")->version->__toString() . ' </h2>';
461
 
469
  /**
470
  * Delete push config by registration_id and app_connection_id
471
  */
472
+ private function delete_push_config() {
473
+ $helperDevice = Mage::helper('mobassistantconnector/deviceAndPushNotification');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
 
475
+ if ($this->registration_id && $this->app_connection_id) {
476
+ $result = $helperDevice->deletePushSettingByRegAndCon(
477
+ $this->registration_id,
478
+ $this->app_connection_id
479
+ );
480
 
481
+ if ($result) {
482
+ $result = array('success' => 'true');
483
+ } else {
484
+ $result = array('error' => $this->__('Could not delete data'));
485
+ }
486
  } else {
487
  $result = array('error' => $this->__('Missing parameters'));
488
  }
489
 
490
+ $helperDevice->deleteEmptyDevices();
491
+ $helperDevice->deleteEmptyAccounts();
492
+
493
  return $result;
494
  }
495
+
496
+ private function push_notification_settings()
497
  {
498
+ if ((int)$this->app_connection_id < 1) {
499
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
  }
501
 
502
+ $result = array('success' => 'true');
503
+ $account_id = null;
504
+ $device_name = '';
505
+ $date = date('Y-m-d H:i:s');
506
+ $helperDevice = Mage::helper('mobassistantconnector/deviceAndPushNotification');
 
 
 
 
 
 
507
 
508
+ if ($this->registration_id && $this->api_key && $this->device_unique_id) {
509
+ // Update old registration id
510
+ if ($this->registration_id_old) {
511
+ $result = $helperDevice->updateOldPushRegId($this->registration_id_old, $this->registration_id);
512
  }
513
 
514
+ if ($this->account_email) {
515
+ $account = Mage::getModel('emagicone_mobassistantconnector/account')
516
+ ->saveAndGetAccountByEmail($this->account_email);
517
+ $account_id = $account->getId();
518
  }
519
 
520
+ if ($this->device_name) {
521
+ $device_name = $this->device_name;
 
 
522
  }
523
 
524
+ $device = array(
525
+ 'device_unique' => $this->device_unique_id,
526
+ 'device_name' => $device_name,
527
+ 'last_activity' => $date,
528
+ 'account_id' => $account_id,
529
+ );
530
 
531
+ $device_id = (int)$helperDevice->addDevice($device);
532
+ $user_id = (int)Mage::helper('mobassistantconnector/access')
533
+ ->getUserIdBySessionKey($this->session_key);
534
+ $user_actions = Mage::helper('mobassistantconnector/access')->getAllowedActionsByUserId($user_id);
 
 
 
535
 
536
  // Delete empty record
537
+ if ($this->push_new_order == 0 && empty($this->push_order_statuses) && $this->push_new_customer == 0) {
538
+ $result = $helperDevice->deletePushSettingByRegAndCon($this->registration_id, $this->app_connection_id);
539
+ $helperDevice->deleteEmptyDevices();
540
+ $helperDevice->deleteEmptyAccounts();
541
+ } elseif (
542
+ !empty($user_actions)
543
+ && (
544
+ in_array('push_notification_settings_new_order', $user_actions)
545
+ || in_array('push_notification_settings_new_customer', $user_actions)
546
+ || in_array('push_notification_settings_order_statuses', $user_actions)
547
+ )
548
+ ) {
549
+ $push = array(
550
+ 'device_unique_id' => $device_id,
551
+ 'app_connection_id' => (int)$this->app_connection_id,
552
+ 'store_group_id' => -1,
553
+ 'currency_code' => 'base_currency',
554
+ 'order_statuses' => $this->push_order_statuses,
555
+ 'device_id' => $this->registration_id,
556
+ 'user_id' => $user_id,
557
+ );
558
+
559
+ if ($this->group_id) {
560
+ $push['store_group_id'] = $this->group_id;
561
  }
562
+
563
+ if ($this->push_currency_code) {
564
+ $push['currency_code'] = $this->push_currency_code;
565
+ } elseif ($this->currency_code) {
566
+ $push['currency_code'] = $this->currency_code;
 
 
 
 
 
 
 
 
 
 
 
567
  }
568
+
569
+ if (in_array('push_notification_settings_new_order', $user_actions)) {
570
+ $push['new_order'] = (int)$this->push_new_order;
571
  }
 
572
 
573
+ if (in_array('push_notification_settings_new_customer', $user_actions)) {
574
+ $push['new_customer'] = (int)$this->push_new_customer;
 
 
 
 
575
  }
 
576
 
577
+ $result = $helperDevice->addPushNotification($push);
578
+ }
579
 
580
  Mage::getModel('core/config')->saveConfig('mobassistantconnectorinfosec/access/api_key', $this->api_key);
581
 
582
+ if ($result) {
583
+ $result = array('success' => 'true');
584
+ } else {
585
+ $result = array('error' => $this->__('Could not update data'));
586
+ }
587
+ } else {
588
+ $result = array('error' => $this->__('Missing parameters'));
589
+ }
590
 
591
  return $result;
592
  }
1664
  echo $e->getMessage();
1665
  }
1666
  } else {
1667
+ // return false;
1668
+ return;
1669
  }
1670
  } else {
1671
+ // return false;
1672
+ return;
1673
  }
1674
 
1675
+ // return Mage::app()->getResponse();
1676
+ die(Mage::app()->getResponse());
1677
  }
1678
 
1679
  protected function map_order_statuses($status)
2241
  )
2242
  ->joinLeft(
2243
  array('a_price' => Mage::getConfig()->getTablePrefix() . 'eav_attribute'),
2244
+ "a_price.entity_type_id = et_product.entity_type_id AND a_price.attribute_code = 'price'",
2245
  array()
2246
  )
2247
  ->joinLeft(
2248
  array('p_price' => Mage::getConfig()->getTablePrefix() . 'catalog_product_entity_decimal'),
2249
+ "p_price.entity_id = e.entity_id AND p_price.attribute_id = a_price.attribute_id AND p_price.store_id = 0",
2250
  array('p_price.value AS price')
2251
  );
2252
 
2414
  $salesItemCollection->getSelect()->columns(array(
2415
  'qty_ordered_product' => 'SUM(main_table.qty_ordered)',
2416
  'price_total' => 'SUM(main_table.base_price - main_table.base_discount_amount)',
2417
+ // 'orig_price' => 'SUM(main_table.base_price - main_table.base_discount_amount) * main_table.qty_ordered'
2418
+ 'orig_price' => 'SUM(main_table.base_price * main_table.qty_ordered - main_table.base_discount_amount)'
2419
  )
2420
  );
2421
  // $salesCollection->getSelect()->columns("SUM(main_table.qty_ordered)");
2811
  unset($row['spec_price']);
2812
  }
2813
 
2814
+ $baseImage = $product->getImage();
2815
+ $baseImageData = array();
2816
+ $imagesExtra = array();
2817
+ // $images = array();
2818
  // $mediaGallery = Mage::getModel('catalog/product')->load($product->getId())->getMediaGalleryImages();
2819
  $mediaGallery = $product->getMediaGallery();
2820
  if (is_array($mediaGallery['images'])) {
2821
  foreach ($mediaGallery['images'] as $image) {
2822
+ // if ($image['disabled']) {
2823
  // continue;
2824
+ // }
2825
  $small = Mage::helper('catalog/image')->init($product, 'image', $image['file'])->resize(300)
2826
  ->keepAspectRatio(true)->constrainOnly(true)->keepFrame(false);
2827
  $small_image = $small->__toString();
2828
  $large = Mage::helper('catalog/image')->init($product, 'image', $image['file'])->resize(800)
2829
  ->keepAspectRatio(true)->constrainOnly(true)->keepFrame(false);
2830
  $large_image = $large->__toString();
2831
+
2832
+ if ($baseImage == $image['file']) {
2833
+ $baseImageData[] = array('large' => $large_image, 'small' => $small_image);
2834
+ } else {
2835
+ $imagesExtra[] = array('large' => $large_image, 'small' => $small_image);
2836
+ }
2837
  }
2838
  }
2839
 
2840
+ // $row['images'] = $images;
2841
+ $row['images'] = array_merge($baseImageData, $imagesExtra);
2842
 
2843
  // For compatibility with old app version
2844
+ if (!empty($baseImageData)) {
2845
+ $row['id_image'] = $baseImageData[0]['small'];
2846
+ $row['id_image_large'] = $baseImageData[0]['large'];
2847
+ } elseif (!empty($imagesExtra)) {
2848
+ $row['id_image'] = $imagesExtra[0]['small'];
2849
+ $row['id_image_large'] = $imagesExtra[0]['large'];
2850
  }
 
2851
  }
2852
 
2853
  return $row;
3054
  $dir = $this->get_sort_direction('ASC');
3055
  // $quotes->getSelect()->order(array('main_table' . '.customer_firstname' . $dir));
3056
  $quotes->getSelect()->order(array('customer_name ' . $dir));
3057
+ // $quotes->getSelect()->order(array("main_table.customer_firstname" . $dir));
3058
  break;
3059
  case 'qty':
3060
  $dir = $this->get_sort_direction('ASC');
3096
  $cart['email'] = $quote->getCustomerEmail();
3097
  $cart['customer'] = $quote->getCustomerFirstname() . ' ' . $quote->getCustomerLastname();
3098
 
3099
+ /*if (!is_null($quote->getCustomer()->getId())) {
3100
  $cart['email'] = $quote->getCustomer()->getEmail();
3101
  $cart['customer'] = $quote->getCustomer()->getFirstname() . ' ' . $quote->getCustomer()->getLastname();
3102
+ }*/
3103
 
3104
  if ($storeName = Mage::getModel('core/store')->load($quote->getStoreId())->getName())
3105
  $cart['shop_name'] = $storeName;
3337
  );
3338
  }
3339
 
3340
+ private function getQrCode($hash)
3341
+ {
3342
+ $user = Mage::getModel('emagicone_mobassistantconnector/user')->load($hash, 'qr_code_hash');
3343
+ $urlJs = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS);
3344
+
3345
+ if ((int)$user->getStatus() != 1) {
3346
+ $this->generate_output('auth_error');
3347
+ }
3348
+
3349
+ $data_to_qr = Mage::helper('mobassistantconnector/data')->getDataToQrCode(
3350
+ Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB),
3351
+ $user->getUsername(),
3352
+ $user->getPassword()
3353
+ );
3354
+
3355
+ include_once Mage::getDesign()->getBaseDir(
3356
+ array(
3357
+ '_package' => Mage_Core_Model_Design_Package::BASE_PACKAGE,
3358
+ '_theme' => Mage_Core_Model_Design_Package::DEFAULT_THEME,
3359
+ '_type' => 'template'
3360
+ )
3361
+ )
3362
+ . '/emagicone/mobassistantconnector/qr_code.phtml';
3363
+
3364
+ echo '<script type="text/javascript">
3365
+ (function() {
3366
+ var qrcode = new QRCode(document.getElementById("mobassistantconnector_qrcode_img"), {
3367
+ width : 300,
3368
+ height : 300
3369
+ });
3370
+ qrcode.makeCode("' . $data_to_qr . '");
3371
+ })();
3372
+
3373
+ </script>';
3374
+
3375
+ die();
3376
+ }
3377
+
3378
  private function getStockOptions() {
3379
  $stockOptions = array();
3380
  $options = Mage::getSingleton('Mage_CatalogInventory_Model_Source_Stock')->toOptionArray();
3408
  'emagicone_mobassistantconnector.log'
3409
  );
3410
  }
 
3411
  }
3412
 
3413
  if ($format) {
app/code/community/Emagicone/Mobassistantconnector/data/em1_mob_setup/data-install-1.4.0.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ if (Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/login')) {
20
+ Mage::helper('mobassistantconnector/tableCheck')->moveUserToTable();
21
+ } else {
22
+ Mage::helper('mobassistantconnector/tableCheck')->addDefaultUser();
23
+ }
24
+
25
+ Mage::helper('mobassistantconnector/tableCheck')->movePushesToTable();
app/code/community/Emagicone/Mobassistantconnector/etc/adminhtml.xml DELETED
@@ -1,26 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <acl>
4
- <resources>
5
- <all>
6
- <title>Allow Everything</title>
7
- </all>
8
- <admin>
9
- <children>
10
- <system>
11
- <children>
12
- <config>
13
- <children>
14
- <mobassistantconnectorinfosec translate="title">
15
- <title>An Example Section</title>
16
- <sort_order>100</sort_order>
17
- </mobassistantconnectorinfosec>
18
- </children>
19
- </config>
20
- </children>
21
- </system>
22
- </children>
23
- </admin>
24
- </resources>
25
- </acl>
26
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emagicone/Mobassistantconnector/etc/config.xml CHANGED
@@ -1,132 +1,154 @@
1
  <?xml version="1.0"?>
2
- <config>
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- <default>
5
- <mobassistantconnectorinfosec>
6
- <emogeneral>
7
- <status>0</status>
8
- </emogeneral>
9
- <emoaccess>
10
- <login>1</login>
11
- <password>c4ca4238a0b923820dcc509a6f75849b</password>
12
- </emoaccess>
13
- </mobassistantconnectorinfosec>
14
- </default>
15
 
16
- <modules>
17
- <Emagicone_Mobassistantconnector>
18
- <version>1.3.6</version>
19
- </Emagicone_Mobassistantconnector>
20
- </modules>
21
- <frontend>
22
- <routers>
23
- <mobassistantconnector>
24
- <use>standard</use>
25
- <args>
26
- <module>Emagicone_Mobassistantconnector</module>
27
- <frontName>mobassistantconnector</frontName>
28
- </args>
29
- </mobassistantconnector>
30
- </routers>
31
- <translate>
32
- <modules>
33
- <translations>
34
- <files>
35
- <default>Emagicone_Mobassistantconnector.csv</default>
36
- </files>
37
- </translations>
38
- </modules>
39
- </translate>
40
- </frontend>
41
 
42
- <admin>
43
- <routers>
44
- <adminhtml>
45
- <args>
46
- <modules>
47
- <mobassistantconnectoradmin before="Mage_Adminhtml">Emagicone_Mobassistantconnector_Adminhtml</mobassistantconnectoradmin>
48
- </modules>
49
- </args>
50
- </adminhtml>
51
- </routers>
52
- </admin>
 
53
 
54
- <global>
55
- <blocks>
56
- <mobassistantconnector>
57
- <class>Emagicone_Mobassistantconnector_Block</class>
58
- </mobassistantconnector>
59
- </blocks>
60
- <helpers>
61
- <mobassistantconnector>
62
- <class>Emagicone_Mobassistantconnector_Helper</class>
63
- </mobassistantconnector>
64
- </helpers>
65
-
66
- <models>
67
- <sales>
68
- <rewrite>
69
- <order>Emagicone_Mobassistantconnector_Model_Order</order>
70
- </rewrite>
71
- </sales>
72
- <emagiconemobassistantconnector>
73
- <class>Emagicone_Mobassistantconnector_Model</class>
74
- </emagiconemobassistantconnector>
75
- <emagicone_mobassistantconnector>
76
- <class>Emagicone_Mobassistantconnector_Model</class>
77
- <resourceModel>emagicone_mobassistantconnector_resource</resourceModel>
78
- </emagicone_mobassistantconnector>
79
- <emagicone_mobassistantconnector_resource>
80
- <class>Emagicone_Mobassistantconnector_Model_Resource</class>
81
- <entities>
82
- <sessions>
83
- <table>emagicone_mobassistantconnector_sessions</table>
84
- </sessions>
85
- <failed>
86
- <table>emagicone_mobassistantconnector_failed_login</table>
87
- </failed>
88
- </entities>
89
- </emagicone_mobassistantconnector_resource>
90
 
91
- </models>
 
 
 
 
92
 
93
- <resources>
94
- <emagicone_mobassistantconnector_setup>
95
- <setup>
96
- <module>Emagicone_Mobassistantconnector</module>
97
- </setup>
98
- </emagicone_mobassistantconnector_setup>
99
- </resources>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- <events>
102
- <sales_order_save_after>
103
- <observers>
104
- <emagicone_mobassistantconnector_order_change>
105
- <type>singleton</type>
106
- <class>Emagicone_Mobassistantconnector_Model_Observer</class>
107
- <method>checkOrder</method>
108
- </emagicone_mobassistantconnector_order_change>
109
- </observers>
110
- </sales_order_save_after>
111
- <customer_register_success>
112
- <observers>
113
- <emagicone_mobassistantconnector_customer_register_success>
114
- <type>model</type>
115
- <class>Emagicone_Mobassistantconnector_Model_Observer</class>
116
- <method>customerRegisterSuccess</method>
117
- </emagicone_mobassistantconnector_customer_register_success>
118
- </observers>
119
- </customer_register_success>
120
- </events>
121
- <!--<layout>-->
122
- <!--<updates>-->
123
- <!--<emagicone_mobassistantconnector>-->
124
- <!--<file>emagicone_mobassistantconnector.xml</file>-->
125
- <!--</emagicone_mobassistantconnector>-->
126
- <!--</updates>-->
127
- <!--</layout>-->
128
- </global>
129
-
130
  <adminhtml>
131
  <translate>
132
  <modules>
@@ -137,13 +159,71 @@
137
  </translations>
138
  </modules>
139
  </translate>
140
- <!--<layout>-->
141
- <!--<updates>-->
142
- <!--<mobassistantconnector>-->
143
- <!--<file>mobassistantconnector.xml</file>-->
144
- <!--</mobassistantconnector>-->
145
- <!--</updates>-->
146
- <!--</layout>-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  </adminhtml>
148
-
149
- </config>
1
  <?xml version="1.0"?>
2
+ <config>
3
+ <default>
4
+ <mobassistantconnectorinfosec>
5
+ <emogeneral>
6
+ <status>0</status>
7
+ </emogeneral>
8
+ <emoaccess>
9
+ <login>1</login>
10
+ <password>c4ca4238a0b923820dcc509a6f75849b</password>
11
+ </emoaccess>
12
+ </mobassistantconnectorinfosec>
13
+ </default>
14
 
15
+ <modules>
16
+ <Emagicone_Mobassistantconnector>
17
+ <version>1.4.0</version>
18
+ </Emagicone_Mobassistantconnector>
19
+ </modules>
 
 
 
 
 
 
20
 
21
+ <frontend>
22
+ <routers>
23
+ <mobassistantconnector>
24
+ <use>standard</use>
25
+ <args>
26
+ <module>Emagicone_Mobassistantconnector</module>
27
+ <frontName>mobassistantconnector</frontName>
28
+ </args>
29
+ </mobassistantconnector>
30
+ </routers>
31
+ <translate>
32
+ <modules>
33
+ <translations>
34
+ <files>
35
+ <default>Emagicone_Mobassistantconnector.csv</default>
36
+ </files>
37
+ </translations>
38
+ </modules>
39
+ </translate>
40
+ </frontend>
 
 
 
 
 
41
 
42
+ <admin>
43
+ <routers>
44
+ <adminhtml>
45
+ <args>
46
+ <modules>
47
+ <!--<mobassistantconnectoradmin before="Mage_Adminhtml">Emagicone_Mobassistantconnector_Adminhtml</mobassistantconnectoradmin>-->
48
+ <mobassistantconnector before="Mage_Adminhtml">Emagicone_Mobassistantconnector_Adminhtml</mobassistantconnector>
49
+ </modules>
50
+ </args>
51
+ </adminhtml>
52
+ </routers>
53
+ </admin>
54
 
55
+ <global>
56
+ <blocks>
57
+ <mobassistantconnector>
58
+ <class>Emagicone_Mobassistantconnector_Block</class>
59
+ </mobassistantconnector>
60
+ </blocks>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ <helpers>
63
+ <mobassistantconnector>
64
+ <class>Emagicone_Mobassistantconnector_Helper</class>
65
+ </mobassistantconnector>
66
+ </helpers>
67
 
68
+ <models>
69
+ <sales>
70
+ <rewrite>
71
+ <order>Emagicone_Mobassistantconnector_Model_Order</order>
72
+ </rewrite>
73
+ </sales>
74
+ <emagiconemobassistantconnector>
75
+ <class>Emagicone_Mobassistantconnector_Model</class>
76
+ </emagiconemobassistantconnector>
77
+ <emagicone_mobassistantconnector>
78
+ <class>Emagicone_Mobassistantconnector_Model</class>
79
+ <resourceModel>emagicone_mobassistantconnector_resource</resourceModel>
80
+ </emagicone_mobassistantconnector>
81
+ <emagicone_mobassistantconnector_resource>
82
+ <class>Emagicone_Mobassistantconnector_Model_Resource</class>
83
+ <entities>
84
+ <sessions>
85
+ <table>emagicone_mobassistantconnector_sessions</table>
86
+ </sessions>
87
+ <failed>
88
+ <table>emagicone_mobassistantconnector_failed_login</table>
89
+ </failed>
90
+ <user>
91
+ <table>emagicone_mobassistantconnector_users</table>
92
+ </user>
93
+ <push>
94
+ <table>emagicone_mobassistantconnector_push_notifications</table>
95
+ </push>
96
+ <device>
97
+ <table>emagicone_mobassistantconnector_devices</table>
98
+ </device>
99
+ <account>
100
+ <table>emagicone_mobassistantconnector_accounts</table>
101
+ </account>
102
+ </entities>
103
+ </emagicone_mobassistantconnector_resource>
104
+ </models>
105
+
106
+ <resources>
107
+ <em1_mob_setup>
108
+ <setup>
109
+ <module>Emagicone_Mobassistantconnector</module>
110
+ </setup>
111
+ </em1_mob_setup>
112
+ </resources>
113
+
114
+ <events>
115
+ <sales_order_save_after>
116
+ <observers>
117
+ <emagicone_mobassistantconnector_order_change>
118
+ <type>singleton</type>
119
+ <class>Emagicone_Mobassistantconnector_Model_Observer</class>
120
+ <method>checkOrder</method>
121
+ </emagicone_mobassistantconnector_order_change>
122
+ </observers>
123
+ </sales_order_save_after>
124
+ <customer_register_success>
125
+ <observers>
126
+ <emagicone_mobassistantconnector_customer_register_success>
127
+ <type>model</type>
128
+ <class>Emagicone_Mobassistantconnector_Model_Observer</class>
129
+ <method>customerRegisterSuccess</method>
130
+ </emagicone_mobassistantconnector_customer_register_success>
131
+ </observers>
132
+ </customer_register_success>
133
+ <adminhtml_controller_action_predispatch_start>
134
+ <observers>
135
+ <emagicone_mobassistantconnector_adminhtml_init_system_config>
136
+ <type>model</type>
137
+ <class>Emagicone_Mobassistantconnector_Helper_TableCheck</class>
138
+ <method>check</method>
139
+ </emagicone_mobassistantconnector_adminhtml_init_system_config>
140
+ </observers>
141
+ </adminhtml_controller_action_predispatch_start>
142
+ </events>
143
+ <!--<layout>
144
+ <updates>
145
+ <emagicone_mobassistantconnector>
146
+ <file>emagicone_mobassistantconnector.xml</file>
147
+ </emagicone_mobassistantconnector>
148
+ </updates>
149
+ </layout>-->
150
+ </global>
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  <adminhtml>
153
  <translate>
154
  <modules>
159
  </translations>
160
  </modules>
161
  </translate>
162
+
163
+ <layout>
164
+ <updates>
165
+ <mobassistantconnector>
166
+ <!--<file>customer.xml</file>-->
167
+ <file>mobassistantconnector.xml</file>
168
+ </mobassistantconnector>
169
+ </updates>
170
+ </layout>
171
+
172
+ <menu>
173
+ <mobassistantconnector translate="title" module="mobassistantconnector">
174
+ <title>Mobile Assistant Connector</title>
175
+ <sort_order>100</sort_order>
176
+ <children>
177
+ <!--<settings translate="title" module="mobassistantconnector">
178
+ <title>Configuration</title>
179
+ <action>adminhtml/system_config/edit/section/mobassistantconnectorinfosec</action>
180
+ <sort_order>0</sort_order>
181
+ </settings>-->
182
+ <mobassistantconnector_users translate="title" module="mobassistantconnector">
183
+ <title>Users</title>
184
+ <action>adminhtml/user</action>
185
+ <sort_order>1</sort_order>
186
+ </mobassistantconnector_users>
187
+ </children>
188
+ </mobassistantconnector>
189
+ </menu>
190
+
191
+ <acl>
192
+ <resources>
193
+ <all>
194
+ <title>Allow Everything</title>
195
+ </all>
196
+ <admin>
197
+ <children>
198
+ <system>
199
+ <children>
200
+ <config>
201
+ <children>
202
+ <mobassistantconnectorinfosec translate="title">
203
+ <title>Mobile Assistant Connector Section</title>
204
+ <sort_order>150</sort_order>
205
+ </mobassistantconnectorinfosec>
206
+ </children>
207
+ </config>
208
+ </children>
209
+ </system>
210
+ <mobassistantconnector translate="title" module="mobassistantconnector">
211
+ <title>Mobile Assistant Connector</title>
212
+ <sort_order>110</sort_order>
213
+ <children>
214
+ <settings>
215
+ <title>Settings</title>
216
+ <sort_order>0</sort_order>
217
+ </settings>
218
+ <mobassistantconnector_users>
219
+ <title>Users</title>
220
+ <sort_order>1</sort_order>
221
+ </mobassistantconnector_users>
222
+ </children>
223
+ </mobassistantconnector>
224
+ </children>
225
+ </admin>
226
+ </resources>
227
+ </acl>
228
  </adminhtml>
229
+ </config>
 
app/code/community/Emagicone/Mobassistantconnector/etc/system.xml DELETED
@@ -1,116 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <config>
3
- <tabs>
4
- <mobassistantconnectorinfo translate="label">
5
- <label>eMagicOne</label>
6
- <sort_order>100</sort_order>
7
- </mobassistantconnectorinfo>
8
- </tabs>
9
- <sections>
10
- <mobassistantconnectorinfosec translate="label">
11
- <label>Mobile Assistant Connector</label>
12
- <tab>mobassistantconnectorinfo</tab>
13
- <frontend_type>text</frontend_type>
14
- <sort_order>1000</sort_order>
15
- <show_in_default>1</show_in_default>
16
- <show_in_website>1</show_in_website>
17
- <show_in_store>1</show_in_store>
18
- <groups>
19
- <emogeneral translate="label comment">
20
- <label>General Settings</label>
21
- <sort_order>10</sort_order>
22
- <show_in_default>1</show_in_default>
23
- <show_in_website>1</show_in_website>
24
- <show_in_store>1</show_in_store>
25
- <fields>
26
- <status translate="label comment">
27
- <label>Enabled</label>
28
- <frontend_type>select</frontend_type>
29
- <source_model>
30
- adminhtml/system_config_source_enabledisable
31
- </source_model>
32
- <sort_order>10</sort_order>
33
- <show_in_default>1</show_in_default>
34
- <show_in_website>1</show_in_website>
35
- <show_in_store>0</show_in_store>
36
- </status>
37
- </fields>
38
- </emogeneral>
39
- <emoaccess translate="label">
40
- <label>Access Settings</label>
41
- <sort_order>20</sort_order>
42
- <show_in_default>1</show_in_default>
43
- <show_in_website>1</show_in_website>
44
- <show_in_store>1</show_in_store>
45
- <fields>
46
- <login translate="label comment">
47
- <label>Login</label>
48
- <frontend_type>text</frontend_type>
49
- <backend_model>emagiconemobassistantconnector/login</backend_model>
50
- <sort_order>10</sort_order>
51
- <show_in_default>1</show_in_default>
52
- <show_in_website>1</show_in_website>
53
- <show_in_store>1</show_in_store>
54
- <comment><![CDATA[Login for accessing Mobile Assistant Connector from Your mobile application.]]></comment>
55
- </login>
56
- <password translate="label comment">
57
- <label>Password</label>
58
- <frontend_type>password</frontend_type>
59
- <source_model>emagiconemobassistantconnector/defpassword</source_model>
60
- <backend_model>emagiconemobassistantconnector/password</backend_model>
61
- <sort_order>20</sort_order>
62
- <show_in_default>1</show_in_default>
63
- <show_in_website>1</show_in_website>
64
- <show_in_store>1</show_in_store>
65
- <comment><![CDATA[Password for accessing Mobile Assistant Connector from Your mobile application. Default password is '1'. Please change it to your own one.]]></comment>
66
- </password>
67
- </fields>
68
- </emoaccess>
69
- <emoqr translate="label comment">
70
- <expanded>1</expanded>
71
- <label>QR Code</label>
72
- <sort_order>30</sort_order>
73
- <show_in_default>1</show_in_default>
74
- <show_in_website>1</show_in_website>
75
- <show_in_store>1</show_in_store>
76
- <fields>
77
- <qrconfig translate="label comment">
78
- <label>QR Code for Config</label>
79
- <frontend_type>text</frontend_type>
80
- <frontend_model>mobassistantconnector/adminhtml_system_config_form_qrconfig</frontend_model>
81
- <!--<base_url type="media" scope_info="1">connect</base_url>-->
82
- <sort_order>10</sort_order>
83
- <show_in_default>1</show_in_default>
84
- <show_in_website>1</show_in_website>
85
- <show_in_store>1</show_in_store>
86
- <!--<comment>Store URL and access details (login and password) for Mobile Assistant Connector are encoded in this QR code. Scan it with special option available on connection settings page of Magento Mobile Assistant to autofill acess settings and connect to your Magento store.</comment>-->
87
- </qrconfig>
88
- </fields>
89
- </emoqr>
90
- <emoconnectqr translate="label comment">
91
- <expanded>1</expanded>
92
- <label>Get the App from Google Play</label>
93
- <sort_order>40</sort_order>
94
- <show_in_default>1</show_in_default>
95
- <show_in_website>1</show_in_website>
96
- <show_in_store>1</show_in_store>
97
- <fields>
98
- <qrconnect translate="label comment">
99
- <label>QR Code for Application</label>
100
- <frontend_type>text</frontend_type>
101
- <frontend_model>mobassistantconnector/adminhtml_system_config_form_qrcode</frontend_model>
102
- <!--<base_url type="media" scope_info="1">connect</base_url>-->
103
- <sort_order>10</sort_order>
104
- <show_in_default>1</show_in_default>
105
- <show_in_website>1</show_in_website>
106
- <show_in_store>1</show_in_store>
107
- <comment>Click or use your device camera to read the QR-code.</comment>
108
- </qrconnect>
109
- </fields>
110
- </emoconnectqr>
111
- <emoconnectorqr2>
112
- </emoconnectorqr2>
113
- </groups>
114
- </mobassistantconnectorinfosec>
115
- </sections>
116
- </config>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emagicone/Mobassistantconnector/sql/{emagicone_mobassistantconnector_setup → em1_mob_setup}/install-1.2.1.php RENAMED
@@ -1,9 +1,19 @@
1
  <?php
2
  /**
3
- * Created by PhpStorm.
4
- * User: jarchik
5
- * Date: 5/13/15
6
- * Time: 11:41 AM
 
 
 
 
 
 
 
 
 
 
7
  */
8
 
9
  $installer = $this;
1
  <?php
2
  /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
  */
18
 
19
  $installer = $this;
app/code/community/Emagicone/Mobassistantconnector/sql/em1_mob_setup/install-1.4.0.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ $installer = $this;
20
+ $connection = $installer->getConnection();
21
+
22
+ $installer->startSetup();
23
+
24
+ // Create table emagicone_mobassistantconnector_sessions
25
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/sessions');
26
+ if (!$connection->isTableExists($tableName)) {
27
+ $table = $connection
28
+ ->newTable($tableName)
29
+ ->addColumn(
30
+ 'session_id',
31
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
32
+ null,
33
+ array(
34
+ 'identity' => true,
35
+ 'unsigned' => true,
36
+ 'nullable' => false,
37
+ 'primary' => true,
38
+ 'auto_increment' => true
39
+ ),
40
+ 'Session Id'
41
+ )
42
+ ->addColumn('session_key', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array('nullable' => false), 'Session Key')
43
+ ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'User Id')
44
+ ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Date Added');
45
+ $connection->createTable($table);
46
+ } else {
47
+ $keysCollection = Mage::getModel('emagicone_mobassistantconnector/sessions')->getCollection();
48
+ try {
49
+ foreach ($keysCollection as $key) {
50
+ $key->delete();
51
+ }
52
+ } catch (Exception $e) {
53
+ Mage::log(
54
+ 'Error occurred while deleting session keys: ' . $e->getMessage(), null, 'emagicone_mobassistantconnector.log'
55
+ );
56
+ }
57
+
58
+ if (!$connection->tableColumnExists($tableName, 'user_id')) {
59
+ $connection->addColumn(
60
+ $tableName,
61
+ 'user_id',
62
+ array('type' => Varien_Db_Ddl_Table::TYPE_INTEGER, 'comment' => 'User Id')
63
+ );
64
+ $connection->resetDdlCache($tableName);
65
+ }
66
+ }
67
+
68
+ // Create table emagicone_mobassistantconnector_failed_login
69
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/failed');
70
+ if (!$connection->isTableExists($tableName)) {
71
+ $table = $connection
72
+ ->newTable($tableName)
73
+ ->addColumn(
74
+ 'attempt_id',
75
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
76
+ null,
77
+ array(
78
+ 'identity' => true,
79
+ 'unsigned' => true,
80
+ 'nullable' => false,
81
+ 'primary' => true,
82
+ 'auto_increment' => true
83
+ ),
84
+ 'Attempt Id'
85
+ )
86
+ ->addColumn('ip', Varien_Db_Ddl_Table::TYPE_VARCHAR, 20, array(), 'Ip')
87
+ ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Date Added');
88
+ $connection->createTable($table);
89
+ }
90
+
91
+ // Create table emagicone_mobassistantconnector_users
92
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/user');
93
+ if (!$connection->isTableExists($tableName)) {
94
+ $table = $connection
95
+ ->newTable($tableName)
96
+ ->addColumn(
97
+ 'user_id',
98
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
99
+ null,
100
+ array(
101
+ 'identity' => true,
102
+ 'unsigned' => true,
103
+ 'nullable' => false,
104
+ 'primary' => true,
105
+ 'auto_increment' => true
106
+ ),
107
+ 'User Id'
108
+ )
109
+ ->addColumn('username', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array('nullable' => false), 'Username')
110
+ ->addColumn('password', Varien_Db_Ddl_Table::TYPE_VARCHAR, 35, array('nullable' => false), 'Password')
111
+ ->addColumn('allowed_actions', Varien_Db_Ddl_Table::TYPE_VARCHAR, 1000, array(), 'Allowed Actions')
112
+ ->addColumn('qr_code_hash', Varien_Db_Ddl_Table::TYPE_VARCHAR, 70, array(), 'QR Code Hash')
113
+ ->addColumn('status', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'Status')
114
+ ->addIndex($installer->getIdxName($tableName, array('username')), array('username'));
115
+ $connection->createTable($table);
116
+ }
117
+
118
+ // Create table emagicone_mobassistantconnector_push_notifications
119
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/push');
120
+ if (!$connection->isTableExists($tableName)) {
121
+ $table = $connection
122
+ ->newTable($tableName)
123
+ ->addColumn(
124
+ 'id',
125
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
126
+ null,
127
+ array(
128
+ 'identity' => true,
129
+ 'unsigned' => true,
130
+ 'nullable' => false,
131
+ 'primary' => true,
132
+ 'auto_increment' => true
133
+ ),
134
+ 'Id'
135
+ )
136
+ ->addColumn('device_unique_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'Device Unique Id')
137
+ ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(), 'User Id')
138
+ ->addColumn('device_id', Varien_Db_Ddl_Table::TYPE_VARCHAR, 200, array(), 'Device Id')
139
+ ->addColumn('new_order', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'New Order')
140
+ ->addColumn('new_customer', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'New Customer')
141
+ ->addColumn('order_statuses', Varien_Db_Ddl_Table::TYPE_VARCHAR, 1000, array(), 'Order Statuses')
142
+ ->addColumn('app_connection_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'App Connection Id')
143
+ ->addColumn('store_group_id', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array('default' => -1), 'Store Group Id')
144
+ ->addColumn('currency_code', Varien_Db_Ddl_Table::TYPE_VARCHAR, 25, array(), 'Currency Code');
145
+ $connection->createTable($table);
146
+ }
147
+
148
+ // Create table emagicone_mobassistantconnector_devices
149
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/device');
150
+ if (!$connection->isTableExists($tableName)) {
151
+ $table = $connection->newTable($tableName)
152
+ ->addColumn(
153
+ 'device_unique_id',
154
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
155
+ null,
156
+ array(
157
+ 'identity' => true,
158
+ 'unsigned' => true,
159
+ 'nullable' => false,
160
+ 'primary' => true,
161
+ 'auto_increment' => true
162
+ ),
163
+ 'Device Unique Id'
164
+ )
165
+ ->addColumn('device_unique', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array(), 'Device Unique')
166
+ ->addColumn('account_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array('nullable' => true), 'Account Id')
167
+ ->addColumn('device_name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 150, array(), 'Device Name')
168
+ ->addColumn('last_activity', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array('nullable' => false), 'Last Activity')
169
+ ->addIndex(
170
+ $installer->getIdxName($tableName, array('device_unique', 'account_id')), array('device_unique', 'account_id')
171
+ );
172
+ $connection->createTable($table);
173
+ }
174
+
175
+ // Create table emagicone_mobassistantconnector_accounts
176
+ $tableName = $installer->getTable('emagicone_mobassistantconnector/account');
177
+ if (!$connection->isTableExists($tableName)) {
178
+ $table = $connection->newTable($tableName)
179
+ ->addColumn(
180
+ 'id',
181
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
182
+ null,
183
+ array(
184
+ 'identity' => true,
185
+ 'unsigned' => true,
186
+ 'nullable' => false,
187
+ 'primary' => true,
188
+ 'auto_increment' => true
189
+ ),
190
+ 'Id'
191
+ )
192
+ ->addColumn('account_email', Varien_Db_Ddl_Table::TYPE_VARCHAR, 150, array('nullable' => false), 'Account Email')
193
+ ->addColumn('status', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(), 'Status');
194
+ $connection->createTable($table);
195
+ }
196
+
197
+ $installer->endSetup();
app/code/community/Emagicone/Mobassistantconnector/sql/em1_setup/install-2.0.1.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- /**
3
- * Created by PhpStorm.
4
- * User: jarchik
5
- * Date: 5/13/15
6
- * Time: 11:41 AM
7
- */
8
-
9
- $installer = $this;
10
-
11
- $installer->startSetup();
12
-
13
- /*$table = $installer->getConnection()
14
- ->newTable($installer->getTable('emo_assistantconnector/sessions'))
15
- ->addColumn('key', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array(
16
- 'identity' => false,
17
- 'primary' => true,
18
- ), 'Key')
19
- ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
20
- 'nullable' => false,
21
- 'unsigned' => false,
22
- ), 'Date added');
23
- $installer->getConnection()->createTable($table);*/
24
-
25
- $installer->run("
26
- -- DROP TABLE IF EXISTS {$this->getTable('emagicone_mobassistantconnector_sessions')};
27
- CREATE TABLE IF NOT EXISTS {$this->getTable('emagicone_mobassistantconnector_sessions')} (
28
- `session_id` int(11) NOT NULL auto_increment,
29
- `session_key` varchar(100) NOT NULL default '',
30
- `date_added` int(11) NOT NULL,
31
- PRIMARY KEY (`session_id`)
32
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
33
- ");
34
-
35
-
36
-
37
- /*$table = $installer->getConnection()
38
- ->newTable($installer->getTable('emagicone_mobassistantconnector/failed'))
39
- ->addColumn('ip', Varien_Db_Ddl_Table::TYPE_VARCHAR, 100, array(
40
- 'identity' => false,
41
- 'primary' => true,
42
- ), 'Id')
43
- ->addColumn('date_added', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
44
- 'nullable' => false,
45
- 'unsigned' => false,
46
- ), 'Date added');
47
- $installer->getConnection()->createTable($table);*/
48
-
49
- $installer->run("
50
- -- DROP TABLE IF EXISTS {$this->getTable('emagicone_mobassistantconnector_failed_login')};
51
- CREATE TABLE IF NOT EXISTS {$this->getTable('emagicone_mobassistantconnector_failed_login')} (
52
- `attempt_id` int(11) NOT NULL auto_increment,
53
- `ip` varchar(20) NOT NULL default '',
54
- `date_added` int(11) NOT NULL,
55
- PRIMARY KEY (`attempt_id`)
56
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
57
- ");
58
-
59
-
60
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/layout/mobassistantconnector.xml CHANGED
@@ -2,7 +2,47 @@
2
  <layout>
3
  <adminhtml_system_config_edit>
4
  <reference name="content">
5
- <block type="core/template" name="mobassistantconnector" template="mobassistantconnector/jsinit.phtml"></block>
6
  </reference>
7
  </adminhtml_system_config_edit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  </layout>
2
  <layout>
3
  <adminhtml_system_config_edit>
4
  <reference name="content">
5
+ <block type="core/template" name="mobassistantconnector" template="mobassistantconnector/jsinit.phtml"/>
6
  </reference>
7
  </adminhtml_system_config_edit>
8
+
9
+ <adminhtml_user_grid>
10
+ <block type="core/text_list" name="root" output="toHtml">
11
+ <block type="mobassistantconnector/adminhtml_user_grid" name="user.grid"/>
12
+ </block>
13
+ </adminhtml_user_grid>
14
+
15
+ <adminhtml_user_devices>
16
+ <block type="core/text_list" name="root" output="toHtml">
17
+ <block type="mobassistantconnector/adminhtml_user_edit_device_grid" name="device.grid"/>
18
+ </block>
19
+ </adminhtml_user_devices>
20
+
21
+ <adminhtml_user_edit>
22
+ <update handle="editor"/>
23
+ <reference name="content">
24
+ <block type="mobassistantconnector/adminhtml_user_edit" name="user_edit"/>
25
+ </reference>
26
+ <reference name="head">
27
+ <action method="addCss"><file>emagicone/mobassistantconnector/style.css</file></action>
28
+ <action method="addJs"><file>emagicone/mobassistantconnector/jquery-2.2.2.min.js</file></action>
29
+ <action method="addJs"><file>emagicone/mobassistantconnector/qrcode.min.js</file></action>
30
+ <action method="addJs"><file>emagicone/mobassistantconnector/user_edit.js</file></action>
31
+ <action method="addJs"><file>emagicone/mobassistantconnector/qrcode_app_user_edit.js</file></action>
32
+ </reference>
33
+ <reference name="left">
34
+ <block type="mobassistantconnector/adminhtml_user_edit_tabs" name="user_edit_tabs">
35
+ <block type="mobassistantconnector/adminhtml_user_edit_tab_main" name="user_edit_tab_main"/>
36
+ <block type="mobassistantconnector/adminhtml_user_edit_tab_permissions" name="user_edit_tab_permissions"/>
37
+ <action method="addTab">
38
+ <name>main_section</name>
39
+ <block>user_edit_tab_main</block>
40
+ </action>
41
+ <action method="addTab">
42
+ <name>permissions_section</name>
43
+ <block>user_edit_tab_permissions</block>
44
+ </action>
45
+ </block>
46
+ </reference>
47
+ </adminhtml_user_edit>
48
  </layout>
app/design/adminhtml/default/default/template/mobassistantconnector/connect_qrcode.phtml DELETED
@@ -1,8 +0,0 @@
1
- <?php
2
-
3
- $url = 'https://goo.gl/B20FrE';
4
-
5
- ?>
6
- <div id="qr_app">
7
- <a href="https://goo.gl/B20FrE" onmouseover='this.style.background_color="white"' target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAACzY+a1AAAABmJLR0QA/wD/AP+gvaeTAAAC4ElEQVR4nO3dzU4DMQwAYRbx/q9cDhwaoUaNZTubgfmOqF2KRsHa316Px+NDZJ93fwBlmRDPhHgmxDMhngnxTIhnQjwT4pkQz4R4JsQzIZ4J8UyIZ0I8E+KZEM+EeCbEMyGeCfFMiGdCvK/CbV3XVbi1H+OVyuP2O34+0/13JbkK8UyIZ0K8ylk4yvyvn82e2TxbeW+Vjr8ryVWIZ0I8E+J1zcLRygyo2j+bbWdlH3Hn5ynkKsQzIZ4J8XbMwrtE5x+UqxDPhHgmxKPOwpX9v6ptHs5ViGdCPBPi7ZiFVTMmOv9Wfm/mmppDZqerEM+EeCbE65qFHcchV2ZVZrZFP8MhXIV4JsQzIV7lLOzeT+rYfnS+HshViGdCPBPi3Xl/Yeaaz6rzhZlrSqPXkXbsp364Cv8AE+KZEG/3/YXjPIjOnsz5v5nM/Ived9G0f+kqxDMhngnxrg0HAKvOsXXcFxF9Ts3svTdyFeKZEM+EeKfcU5HZj4xup2P+3TgvXYV4JsQzId7u84VVxxWjxz87ztutbH/DjHQV4pkQz4R4XcdIN5wne/t7R9F9vqrrgGafzVmoJxPimRBv9zHSjmtNV95bNf8yzwf32hm9ZkI8E+J1HSPNzJiVbc7eG515VfNv9vqR+4V6zYR4JsQ7/TrSqv22057N7SzUkwnxTIi3YxZW6T4HWXXvYPc1O7+4CvFMiGdCPNL32nd/P/DKe6OfYcM+qKsQz4R4JsQjfa999PV3fR/v5l1tVyGeCfFMiEf6Xvvu90avqRltPi46chXimRDPhHinPHdmRWauZF4fvQZn5eeeL9STCfFMiEeahVW677X3/kLFmBDPhHik77UfdTybu4PPI9V7JsQzIV7lPRXd15FGn1P6T2awqxDPhHgmxCPdX6iXXIV4JsQzIZ4J8UyIZ0I8E+KZEM+EeCbEMyGeCfFMiGdCPBPimRDPhHgmxDMhngnxTIhnQjwT4pkQ7xsK5W82Bs0v9gAAAABJRU5ErkJggg==" title="QR Code for Application" /></a>
8
- </div>
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/mobassistantconnector/jsinit.phtml DELETED
@@ -1,132 +0,0 @@
1
- <?php
2
- $password = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/password');
3
- $login = Mage::getStoreConfig('mobassistantconnectorinfosec/emoaccess/login');
4
- $store_url = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
5
- $store_url = str_replace('http://', '', $store_url);
6
- $store_url = str_replace('https://', '', $store_url);
7
- $store_url = rtrim($store_url, '/' );
8
- preg_replace('/\/*$/i', '', $store_url);
9
- $array['url'] = $store_url;
10
- $array['login'] = $login;
11
- $array['password'] = $password;
12
- $store_url = base64_encode(json_encode($array));
13
- $qr_url = "https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=" . $store_url . "&choe=UTF-8";
14
- ?>
15
-
16
- <script type="text/javascript">
17
- var password = "";
18
- var login = "";
19
- var password_changed = "";
20
- var login_changed = "";
21
-
22
- window.onload = function ()
23
- {
24
- var elem_div0 = document.createElement("div");
25
- var elem = document.createElement("img");
26
- var elem_div_main = document.createElement("div");
27
- var elem_p = document.createElement("p");
28
- var elem_p_span = document.createElement("span");
29
- var mobassistantconnectorinfosec_emoaccess_password = document.getElementById('mobassistantconnectorinfosec_emoaccess_password');
30
- var mobassistantconnectorinfosec_emoaccess_login = document.getElementById('mobassistantconnectorinfosec_emoaccess_login');
31
- var mobassistantconnectorinfosec_emoqr = document.getElementById("row_mobassistantconnectorinfosec_emoqr_qrconfig");
32
- var mobassistantconnectorinfosec_emoconnectorqr = document.getElementById("mobassistantconnectorinfosec_emoconnectorqr");
33
- var mobassistantconnectorinfosec_qr_app = document.getElementById("qr_app");
34
-
35
- // Get last td
36
- // var mytable = document.getElementById('tableid');
37
- var myrows = document.getElementById('row_mobassistantconnectorinfosec_emoqr_qrconfig');
38
- // var lastrow = myrows[myrows.length -1];
39
- var mycells = myrows.getElementsByTagName('td');
40
- var lastcell = mycells[mycells.length -3];
41
-
42
- mobassistantconnectorinfosec_emoqr = lastcell;
43
-
44
- window.password = mobassistantconnectorinfosec_emoaccess_password.value;
45
- window.login = mobassistantconnectorinfosec_emoaccess_login.value;
46
-
47
- mobassistantconnectorinfosec_emoaccess_password.setAttribute("onkeyup" , "changeQRCode()");
48
- mobassistantconnectorinfosec_emoaccess_login.setAttribute("onkeyup" , "changeQRCode()");
49
- mobassistantconnectorinfosec_qr_app.setAttribute("onmouseover" , "qrAppMouseOver()");
50
- mobassistantconnectorinfosec_qr_app.setAttribute("onmouseout" , "qrAppMouseOut()");
51
-
52
- elem_div0.setAttribute("id", "mobassistantconnectorinfosec_div0");
53
- mobassistantconnectorinfosec_emoqr.appendChild(elem_div0);
54
- var mobassistantconnectorinfosec_div0 = document.getElementById("mobassistantconnectorinfosec_div0");
55
- // mobassistantconnectorinfosec_div0.style.position="relative";
56
- // mobassistantconnectorinfosec_div0.style.width="300px";
57
- // mobassistantconnectorinfosec_div0.style.height="300px";
58
- // mobassistantconnectorinfosec_div0.style.zIndex="800";
59
-
60
- elem.src = "<?php echo $qr_url; ?>";
61
- elem.setAttribute("height", "300");
62
- elem.setAttribute("width", "300");
63
- elem.setAttribute("alt", "QR Code");
64
- elem.setAttribute("id", "mobassistantconnectorinfosec_qr_code");
65
- mobassistantconnectorinfosec_div0.appendChild(elem);
66
- mobassistantconnectorinfosec_div0.style.position="relative";
67
-
68
- elem_div_main.setAttribute("class", "form-list");
69
- elem_div_main.setAttribute("id", "mobassistantconnectorinfosec_div_main");
70
- mobassistantconnectorinfosec_emoqr.appendChild(elem_div_main);
71
- var mobassistantconnectorinfosec_div_main = document.getElementById("mobassistantconnectorinfosec_div_main");
72
-
73
- elem_p.setAttribute("id", "mobassistantconnectorinfosec_qr_p_note");
74
- elem_p.setAttribute("class", "note");
75
- // elem_p.style.paddingLeft="-125px";
76
- mobassistantconnectorinfosec_div_main.appendChild(elem_p);
77
- // mobassistantconnectorinfosec_div_main.style.paddingLeft="25px";
78
- mobassistantconnectorinfosec_div_main.style.marginTop="-5px";
79
-
80
- elem_p_span.setAttribute("id", "mobassistantconnectorinfosec_qr_p_span_note");
81
- document.getElementById("mobassistantconnectorinfosec_qr_p_note").appendChild(elem_p_span);
82
-
83
- document.getElementById("mobassistantconnectorinfosec_qr_p_span_note").innerHTML = 'Store URL and access details (login and password) for Mobile Assistant Connector are encoded in this QR code. Scan it with special option available on connection settings page of Magento Mobile Assistant to autofill acess settings and connect to your Magento store.';
84
- }
85
-
86
- function qrAppMouseOver() {
87
- var mobassistantconnectorinfosec_qr_app = document.getElementById("qr_app");
88
-
89
- mobassistantconnectorinfosec_qr_app.style.opacity = "0.7";
90
- }
91
-
92
- function qrAppMouseOut() {
93
- var mobassistantconnectorinfosec_qr_app = document.getElementById("qr_app");
94
-
95
- mobassistantconnectorinfosec_qr_app.style.opacity = "1";
96
- }
97
-
98
- function changeQRCode() {
99
- var elem_div_change = document.createElement("div");
100
- var mobassistantconnectorinfosec_qr_code = document.getElementById('mobassistantconnectorinfosec_qr_code');
101
- var mobassistantconnectorinfosec_elem_div_change = document.getElementById('mobassistantconnectorinfosec_elem_div_change');
102
- window.password_changed = document.getElementById('mobassistantconnectorinfosec_emoaccess_password').value;
103
- window.login_changed = document.getElementById('mobassistantconnectorinfosec_emoaccess_login').value;
104
-
105
- if (window.password == password_changed && window.login == login_changed) {
106
- mobassistantconnectorinfosec_qr_code.style.opacity = "1";
107
- mobassistantconnectorinfosec_elem_div_change.style.display = "none";
108
- } else {
109
- if (mobassistantconnectorinfosec_elem_div_change) {
110
- mobassistantconnectorinfosec_qr_code.style.opacity = "0.1";
111
- mobassistantconnectorinfosec_elem_div_change.style.display = "block";
112
- } else {
113
- mobassistantconnectorinfosec_qr_code.style.opacity = "0.1";
114
-
115
- elem_div_change.setAttribute("id", "mobassistantconnectorinfosec_elem_div_change");
116
- document.getElementById("mobassistantconnectorinfosec_div0").appendChild(elem_div_change);
117
- var mobassistantconnectorinfosec_elem_div_change = document.getElementById('mobassistantconnectorinfosec_elem_div_change');
118
- mobassistantconnectorinfosec_elem_div_change.innerHTML = "Login details have been changed. Save changes for code to be regenerated";
119
- mobassistantconnectorinfosec_elem_div_change.style.position="absolute";
120
- mobassistantconnectorinfosec_elem_div_change.style.width="150px";
121
- mobassistantconnectorinfosec_elem_div_change.style.top="35%";
122
- // mobassistantconnectorinfosec_elem_div_change.style.zIndex="1000";
123
- mobassistantconnectorinfosec_elem_div_change.style.left="25%";
124
- mobassistantconnectorinfosec_elem_div_change.style.color="red";
125
- mobassistantconnectorinfosec_elem_div_change.style.textAlign="center";
126
- mobassistantconnectorinfosec_elem_div_change.style.fontWeight="bold";
127
- mobassistantconnectorinfosec_elem_div_change.style.textShadow="0 0 1px #fff";
128
- mobassistantconnectorinfosec_elem_div_change.style.display = "block";
129
- }
130
- }
131
- }
132
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/mobassistantconnector/permissions.phtml ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ ?>
19
+ <div class="mobassistantconnector_permissions_mass_checked_class" style="text-align: right">
20
+ <button id="mobassistantconnector_permissions_btn_mass_checked_1" checked_all="false">Check All</button>
21
+ </div>
22
+ <script>
23
+ var $j = jQuery.noConflict();
24
+
25
+ $j(document).ready(function() {
26
+ var button = $j("#mobassistantconnector_permissions_btn_mass_checked_1");
27
+
28
+ setPermissionsButtonName(isPermissionsCheckedAll());
29
+
30
+ button.bind("click",function(e) {
31
+ var value = true;
32
+
33
+ if (button.attr('checked_all') == "true") {
34
+ value = false;
35
+ }
36
+
37
+ $j("[name='allowed_actions[]']").each(function() {
38
+ $j(this).prop('checked', value);
39
+ });
40
+
41
+ setPermissionsButtonName(value);
42
+ e.stopImmediatePropagation();
43
+
44
+ return false;
45
+ });
46
+
47
+ $j("[name='allowed_actions[]']").click(function() {
48
+ processClick($j(this));
49
+ });
50
+
51
+ function isPermissionsCheckedAll() {
52
+ var checkedAll = true;
53
+
54
+ $j("[name='allowed_actions[]']").each(function() {
55
+ if (!$j(this).prop('checked')) {
56
+ checkedAll = false;
57
+ }
58
+ });
59
+
60
+ return checkedAll;
61
+ }
62
+
63
+ function setPermissionsButtonName(isPermissionsCheckedAll) {
64
+ if (isPermissionsCheckedAll) {
65
+ button.html('Uncheck All');
66
+ button.attr('checked_all', "true");
67
+ } else {
68
+ button.html('Check All');
69
+ button.attr('checked_all', "false");
70
+ }
71
+ }
72
+
73
+ function processClick(element) {
74
+ var value_selected = element.val();
75
+ var id = element.attr('id');
76
+ var prefix = id.substring(0, id.lastIndexOf(value_selected));
77
+ var action_products_list = 'products_list';
78
+ var action_product_details = 'product_details';
79
+ var action_customers_list = 'customers_list';
80
+ var action_customer_details = 'customer_details';
81
+ var action_abandoned_carts_list = 'abandoned_carts_list';
82
+ var action_abandoned_cart_details = 'abandoned_cart_details';
83
+ var action_orders_list = 'orders_list';
84
+ var action_order_details = 'order_details';
85
+ var action_order_details_pdf = 'order_details_pdf';
86
+ var action_order_invoice = 'order_invoice';
87
+ var action_order_ship = 'order_ship';
88
+ var action_order_cancel = 'order_cancel';
89
+ var action_order_hold = 'order_hold';
90
+ var action_order_unhold = 'order_unhold';
91
+ var action_order_delete_track_number = 'order_delete_track_number';
92
+
93
+ if (element.is(':checked')) {
94
+ if (value_selected == action_product_details) {
95
+ $j("#" + prefix + action_products_list).prop("checked", true);
96
+ } else if (value_selected == action_customer_details) {
97
+ $j("#" + prefix + action_customers_list).prop("checked", true);
98
+ } else if (value_selected == action_abandoned_cart_details) {
99
+ $j("#" + prefix + action_abandoned_carts_list).prop("checked", true);
100
+ } else if (value_selected == action_order_details) {
101
+ $j("#" + prefix + action_orders_list).prop("checked", true);
102
+ } else if (
103
+ value_selected == action_order_details_pdf ||
104
+ value_selected == action_order_invoice ||
105
+ value_selected == action_order_ship ||
106
+ value_selected == action_order_cancel ||
107
+ value_selected == action_order_hold ||
108
+ value_selected == action_order_unhold ||
109
+ value_selected == action_order_delete_track_number
110
+ ) {
111
+ $j("#" + prefix + action_orders_list).prop("checked", true);
112
+ $j("#" + prefix + action_order_details).prop("checked", true);
113
+ }
114
+ } else {
115
+ if (value_selected == action_products_list) {
116
+ $j("#" + prefix + action_product_details).prop("checked", false);
117
+ } else if (value_selected == action_customers_list) {
118
+ $j("#" + prefix + action_customer_details).prop("checked", false);
119
+ } else if (value_selected == action_abandoned_carts_list) {
120
+ $j("#" + prefix + action_abandoned_cart_details).prop("checked", false);
121
+ } else if (value_selected == action_order_details) {
122
+ $j("#" + prefix + action_order_details_pdf).prop("checked", false);
123
+ $j("#" + prefix + action_order_invoice).prop("checked", false);
124
+ $j("#" + prefix + action_order_ship).prop("checked", false);
125
+ $j("#" + prefix + action_order_cancel).prop("checked", false);
126
+ $j("#" + prefix + action_order_hold).prop("checked", false);
127
+ $j("#" + prefix + action_order_unhold).prop("checked", false);
128
+ $j("#" + prefix + action_order_delete_track_number).prop("checked", false);
129
+ } else if (value_selected == action_orders_list) {
130
+ $j("#" + prefix + action_order_details).prop("checked", false);
131
+ $j("#" + prefix + action_order_details_pdf).prop("checked", false);
132
+ $j("#" + prefix + action_order_invoice).prop("checked", false);
133
+ $j("#" + prefix + action_order_ship).prop("checked", false);
134
+ $j("#" + prefix + action_order_cancel).prop("checked", false);
135
+ $j("#" + prefix + action_order_hold).prop("checked", false);
136
+ $j("#" + prefix + action_order_unhold).prop("checked", false);
137
+ $j("#" + prefix + action_order_delete_track_number).prop("checked", false);
138
+ }
139
+ }
140
+ }
141
+ });
142
+ </script>
app/design/frontend/base/default/template/emagicone/mobassistantconnector/qr_code.phtml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of Mobile Assistant Connector.
4
+ *
5
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU General Public License as published by
7
+ * the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+ ?>
19
+ <html>
20
+ <head>
21
+ <meta http-equiv="Pragma" content="no-cache">
22
+ <title>QR-code for Magento Mobile Assistant App</title>
23
+ <script type="text/javascript"
24
+ src="<?php echo isset($urlJs) ? $urlJs : '' ?>emagicone/mobassistantconnector/qrcode.min.js">
25
+ </script>
26
+ <style media="screen" type="text/css">
27
+ img {
28
+ margin: auto;
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <table width="100%"><tr><td id="mobassistantconnector_qrcode_img" style="padding: 30px"></td></tr></table>
34
+ </body>
35
+ </html>
app/etc/modules/Emagicone_Mobassistantconnector.xml CHANGED
@@ -1,9 +1,9 @@
1
  <?xml version = "1.0"?>
2
- <config>
3
- <modules>
4
- <Emagicone_Mobassistantconnector>
5
- <active>true</active>
6
- <codePool>community</codePool>
7
- </Emagicone_Mobassistantconnector>
8
- </modules>
9
- </config>
1
  <?xml version = "1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Emagicone_Mobassistantconnector>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Emagicone_Mobassistantconnector>
8
+ </modules>
9
+ </config>
js/emagicone/mobassistantconnector/jquery-2.2.2.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ /*! jQuery v2.2.2 | (c) jQuery Foundation | jquery.org/license */
2
+ !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.2",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c;
3
+ }catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=N.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&T.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var X=/^(?:checkbox|radio)$/i,Y=/<([\w:-]+)/,Z=/^$|\/(?:java|ecma)script/i,$={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||d,e=c.documentElement,f=c.body,a.pageX=b.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ea.test(f)?this.mouseHooks:da.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=d),3===a.target.nodeType&&(a.target=a.target.parentNode),h.filter?h.filter(a,g):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==ia()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===ia()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ga:ha):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:ha,isPropagationStopped:ha,isImmediatePropagationStopped:ha,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ga,a&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ga,a&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ga,a&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),n.fn.extend({on:function(a,b,c,d){return ja(this,a,b,c,d)},one:function(a,b,c,d){return ja(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ha),this.each(function(){n.event.remove(this,a,c,b)})}});var ka=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,la=/<script|<style|<link/i,ma=/checked\s*(?:[^=]|=\s*.checked.)/i,na=/^true\/(.*)/,oa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=wa[0].contentDocument,b.write(),b.close(),c=ya(a,b),wa.detach()),xa[a]=c),c}var Aa=/^margin/,Ba=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ca=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Ea=d.documentElement;!function(){var b,c,e,f,g=d.createElement("div"),h=d.createElement("div");if(h.style){h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,g.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",g.appendChild(h);function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",h.innerHTML="",Ea.appendChild(g);var d=a.getComputedStyle(h);b="1%"!==d.top,f="2px"===d.marginLeft,c="4px"===d.width,h.style.marginRight="50%",e="4px"===d.marginRight,Ea.removeChild(g)}n.extend(l,{pixelPosition:function(){return i(),b},boxSizingReliable:function(){return null==c&&i(),c},pixelMarginRight:function(){return null==c&&i(),e},reliableMarginLeft:function(){return null==c&&i(),f},reliableMarginRight:function(){var b,c=h.appendChild(d.createElement("div"));return c.style.cssText=h.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",h.style.width="1px",Ea.appendChild(g),b=!parseFloat(a.getComputedStyle(c).marginRight),Ea.removeChild(g),h.removeChild(c),b}})}}();function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Ba.test(g)&&Aa.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0!==g?g+"":g}function Ga(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Ha=/^(none|table(?!-c[ea]).+)/,Ia={position:"absolute",visibility:"hidden",display:"block"},Ja={letterSpacing:"0",fontWeight:"400"},Ka=["Webkit","O","Moz","ms"],La=d.createElement("div").style;function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ka.length;while(c--)if(a=Ka[c]+b,a in La)return a}function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Pa(b,c,e){var f=!0,g="width"===c?b.offsetWidth:b.offsetHeight,h=Ca(b),i="border-box"===n.css(b,"boxSizing",!1,h);if(d.msFullscreenElement&&a.top!==a&&b.getClientRects().length&&(g=Math.round(100*b.getBoundingClientRect()[c])),0>=g||null==g){if(g=Fa(b,c,h),(0>g||null==g)&&(g=b.style[c]),Ba.test(g))return g;f=i&&(l.boxSizingReliable()||g===b.style[c]),g=parseFloat(g)||0}return g+Oa(b,c,e||(i?"border":"content"),f,h)+"px"}function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=N.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=N.access(d,"olddisplay",za(d.nodeName)))):(e=V(d),"none"===c&&e||N.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Fa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=T.exec(c))&&e[1]&&(c=W(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Fa(a,b,d)),"normal"===e&&b in Ja&&(e=Ja[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Ha.test(n.css(a,"display"))&&0===a.offsetWidth?Da(a,Ia,function(){return Pa(a,b,d)}):Pa(a,b,d):void 0},set:function(a,c,d){var e,f=d&&Ca(a),g=d&&Oa(a,b,d,"border-box"===n.css(a,"boxSizing",!1,f),f);return g&&(e=T.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=n.css(a,b)),Na(a,c,g)}}}),n.cssHooks.marginLeft=Ga(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Fa(a,"marginLeft"))||a.getBoundingClientRect().left-Da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),n.cssHooks.marginRight=Ga(l.reliableMarginRight,function(a,b){return b?Da(a,{display:"inline-block"},Fa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Aa.test(a)||(n.cssHooks[a+b].set=Na)}),n.fn.extend({css:function(a,b){return K(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ca(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Qa(this,!0)},hide:function(){return Qa(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}n.Tween=Ra,Ra.prototype={constructor:Ra,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ra.propHooks[this.prop];return a&&a.get?a.get(this):Ra.propHooks._default.get(this)},run:function(a){var b,c=Ra.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ra.propHooks._default.set(this),this}},Ra.prototype.init.prototype=Ra.prototype,Ra.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},Ra.propHooks.scrollTop=Ra.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=Ra.prototype.init,n.fx.step={};var Sa,Ta,Ua=/^(?:toggle|show|hide)$/,Va=/queueHooks$/;function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&V(a),q=N.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?N.get(a,"olddisplay")||za(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Ua.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?za(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=N.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;N.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ya(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Sa||Wa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:Sa||Wa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for($a(k,j.opts.specialEasing);g>f;f++)if(d=_a.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,Ya,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(_a,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return W(c.elem,a,T.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],_a.tweeners[c]=_a.tweeners[c]||[],_a.tweeners[c].unshift(b)},prefilters:[Za],prefilter:function(a,b){b?_a.prefilters.unshift(a):_a.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=_a(this,n.extend({},a),f);(e||N.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=N.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Va.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=N.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Xa(b,!0),a,d,e)}}),n.each({slideDown:Xa("show"),slideUp:Xa("hide"),slideToggle:Xa("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Sa=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Sa=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ta||(Ta=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(Ta),Ta=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=d.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var ab,bb=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return K(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ab:void 0)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)}}),ab={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=bb[b]||n.find.attr;bb[b]=function(a,b,d){var e,f;return d||(f=bb[b],bb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,bb[b]=f),e}});var cb=/^(?:input|select|textarea|button)$/i,db=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return K(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,
4
+ e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):cb.test(a.nodeName)||db.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var eb=/[\t\r\n\f]/g;function fb(a){return a.getAttribute&&a.getAttribute("class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,fb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,fb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,fb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=fb(this),b&&N.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":N.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+fb(c)+" ").replace(eb," ").indexOf(b)>-1)return!0;return!1}});var gb=/\r/g,hb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(gb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(hb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(n.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var ib=/^(?:focusinfocus|focusoutblur)$/;n.extend(n.event,{trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!ib.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),l=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},f||!o.trigger||o.trigger.apply(e,c)!==!1)){if(!f&&!o.noBubble&&!n.isWindow(e)){for(j=o.delegateType||q,ib.test(j+q)||(h=h.parentNode);h;h=h.parentNode)p.push(h),i=h;i===(e.ownerDocument||d)&&p.push(i.defaultView||i.parentWindow||a)}g=0;while((h=p[g++])&&!b.isPropagationStopped())b.type=g>1?j:o.bindType||q,m=(N.get(h,"events")||{})[b.type]&&N.get(h,"handle"),m&&m.apply(h,c),m=l&&h[l],m&&m.apply&&L(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=q,f||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!L(e)||l&&n.isFunction(e[q])&&!n.isWindow(e)&&(i=e[l],i&&(e[l]=null),n.event.triggered=q,e[q](),n.event.triggered=void 0,i&&(e[l]=i)),b.result}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}}),n.fn.extend({trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),l.focusin="onfocusin"in a,l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=N.access(d,b);e||d.addEventListener(a,c,!0),N.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=N.access(d,b)-1;e?N.access(d,b,e):(d.removeEventListener(a,c,!0),N.remove(d,b))}}});var jb=a.location,kb=n.now(),lb=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var mb=/#.*$/,nb=/([?&])_=[^&]*/,ob=/^(.*?):[ \t]*([^\r\n]*)$/gm,pb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,qb=/^(?:GET|HEAD)$/,rb=/^\/\//,sb={},tb={},ub="*/".concat("*"),vb=d.createElement("a");vb.href=jb.href;function wb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function xb(a,b,c,d){var e={},f=a===tb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function yb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function zb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Ab(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:jb.href,type:"GET",isLocal:pb.test(jb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":ub,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?yb(yb(a,n.ajaxSettings),b):yb(n.ajaxSettings,a)},ajaxPrefilter:wb(sb),ajaxTransport:wb(tb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m=n.ajaxSetup({},c),o=m.context||m,p=m.context&&(o.nodeType||o.jquery)?n(o):n.event,q=n.Deferred(),r=n.Callbacks("once memory"),s=m.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,getResponseHeader:function(a){var b;if(2===v){if(!h){h={};while(b=ob.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===v?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return v||(a=u[c]=u[c]||a,t[a]=b),this},overrideMimeType:function(a){return v||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>v)for(b in a)s[b]=[s[b],a[b]];else x.always(a[x.status]);return this},abort:function(a){var b=a||w;return e&&e.abort(b),z(0,b),this}};if(q.promise(x).complete=r.add,x.success=x.done,x.error=x.fail,m.url=((b||m.url||jb.href)+"").replace(mb,"").replace(rb,jb.protocol+"//"),m.type=c.method||c.type||m.method||m.type,m.dataTypes=n.trim(m.dataType||"*").toLowerCase().match(G)||[""],null==m.crossDomain){j=d.createElement("a");try{j.href=m.url,j.href=j.href,m.crossDomain=vb.protocol+"//"+vb.host!=j.protocol+"//"+j.host}catch(y){m.crossDomain=!0}}if(m.data&&m.processData&&"string"!=typeof m.data&&(m.data=n.param(m.data,m.traditional)),xb(sb,m,c,x),2===v)return x;k=n.event&&m.global,k&&0===n.active++&&n.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!qb.test(m.type),f=m.url,m.hasContent||(m.data&&(f=m.url+=(lb.test(f)?"&":"?")+m.data,delete m.data),m.cache===!1&&(m.url=nb.test(f)?f.replace(nb,"$1_="+kb++):f+(lb.test(f)?"&":"?")+"_="+kb++)),m.ifModified&&(n.lastModified[f]&&x.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&x.setRequestHeader("If-None-Match",n.etag[f])),(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",m.contentType),x.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+ub+"; q=0.01":""):m.accepts["*"]);for(l in m.headers)x.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(o,x,m)===!1||2===v))return x.abort();w="abort";for(l in{success:1,error:1,complete:1})x[l](m[l]);if(e=xb(tb,m,c,x)){if(x.readyState=1,k&&p.trigger("ajaxSend",[x,m]),2===v)return x;m.async&&m.timeout>0&&(i=a.setTimeout(function(){x.abort("timeout")},m.timeout));try{v=1,e.send(t,z)}catch(y){if(!(2>v))throw y;z(-1,y)}}else z(-1,"No Transport");function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e=void 0,g=h||"",x.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(u=zb(m,x,d)),u=Ab(m,u,x,j),j?(m.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(n.lastModified[f]=w),w=x.getResponseHeader("etag"),w&&(n.etag[f]=w)),204===b||"HEAD"===m.type?y="nocontent":304===b?y="notmodified":(y=u.state,l=u.data,t=u.error,j=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),x.status=b,x.statusText=(c||y)+"",j?q.resolveWith(o,[l,y,x]):q.rejectWith(o,[x,y,t]),x.statusCode(s),s=void 0,k&&p.trigger(j?"ajaxSuccess":"ajaxError",[x,m,j?l:t]),r.fireWith(o,[x,y]),k&&(p.trigger("ajaxComplete",[x,m]),--n.active||n.event.trigger("ajaxStop")))}return x},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return!n.expr.filters.visible(a)},n.expr.filters.visible=function(a){return a.offsetWidth>0||a.offsetHeight>0||a.getClientRects().length>0};var Bb=/%20/g,Cb=/\[\]$/,Db=/\r?\n/g,Eb=/^(?:submit|button|image|reset|file)$/i,Fb=/^(?:input|select|textarea|keygen)/i;function Gb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Cb.test(a)?d(a,e):Gb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Gb(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Gb(c,a[c],b,e);return d.join("&").replace(Bb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Fb.test(this.nodeName)&&!Eb.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Db,"\r\n")}}):{name:b.name,value:c.replace(Db,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Hb={0:200,1223:204},Ib=n.ajaxSettings.xhr();l.cors=!!Ib&&"withCredentials"in Ib,l.ajax=Ib=!!Ib,n.ajaxTransport(function(b){var c,d;return l.cors||Ib&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Hb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=n("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Jb=[],Kb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Jb.pop()||n.expando+"_"+kb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Kb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Kb,"$1"+e):b.jsonp!==!1&&(b.url+=(lb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Jb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ca([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var Lb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Lb)return Lb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(g,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function Mb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(e=d.getBoundingClientRect(),c=Mb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ea})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;n.fn[a]=function(d){return K(this,function(a,d,e){var f=Mb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ga(l.pixelPosition,function(a,c){return c?(c=Fa(a,b),Ba.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return K(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)},size:function(){return this.length}}),n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Nb=a.jQuery,Ob=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Ob),b&&a.jQuery===n&&(a.jQuery=Nb),n},b||(a.jQuery=a.$=n),n});
js/emagicone/mobassistantconnector/qrcode.min.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file is part of Mobile Assistant Connector.
3
+ *
4
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ * @author eMagicOne <contact@emagicone.com>
18
+ * @copyright 2014-2015 eMagicOne
19
+ * @license http://www.gnu.org/licenses GNU General Public License
20
+ */
21
+
22
+ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c<a.length&&0==a[c];)c++;this.num=new Array(a.length-c+b);for(var d=0;d<a.length-c;d++)this.num[d]=a[d+c]}function j(a,b){this.totalCount=a,this.dataCount=b}function k(){this.buffer=[],this.length=0}function m(){return"undefined"!=typeof CanvasRenderingContext2D}function n(){var a=!1,b=navigator.userAgent;return/android/i.test(b)&&(a=!0,aMat=b.toString().match(/android ([0-9]\.[0-9])/i),aMat&&aMat[1]&&(a=parseFloat(aMat[1]))),a}function r(a,b){for(var c=1,e=s(a),f=0,g=l.length;g>=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d<this.moduleCount;d++){this.modules[d]=new Array(this.moduleCount);for(var e=0;e<this.moduleCount;e++)this.modules[d][e]=null}this.setupPositionProbePattern(0,0),this.setupPositionProbePattern(this.moduleCount-7,0),this.setupPositionProbePattern(0,this.moduleCount-7),this.setupPositionAdjustPattern(),this.setupTimingPattern(),this.setupTypeInfo(a,c),this.typeNumber>=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f<this.modules.length;f++)for(var g=f*e,h=0;h<this.modules[f].length;h++){var i=h*e,j=this.modules[f][h];j&&(d.beginFill(0,100),d.moveTo(i,g),d.lineTo(i+e,g),d.lineTo(i+e,g+e),d.lineTo(i,g+e),d.endFill())}return d},setupTimingPattern:function(){for(var a=8;a<this.moduleCount-8;a++)null==this.modules[a][6]&&(this.modules[a][6]=0==a%2);for(var b=8;b<this.moduleCount-8;b++)null==this.modules[6][b]&&(this.modules[6][b]=0==b%2)},setupPositionAdjustPattern:function(){for(var a=f.getPatternPosition(this.typeNumber),b=0;b<a.length;b++)for(var c=0;c<a.length;c++){var d=a[b],e=a[c];if(null==this.modules[d][e])for(var g=-2;2>=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g<a.length&&(j=1==(1&a[g]>>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h<d.length;h++){var i=d[h];g.put(i.mode,4),g.put(i.getLength(),f.getLengthInBits(i.mode,a)),i.write(g)}for(var l=0,h=0;h<e.length;h++)l+=e[h].dataCount;if(g.getLengthInBits()>8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j<b.length;j++){var k=b[j].dataCount,l=b[j].totalCount-k;d=Math.max(d,k),e=Math.max(e,l),g[j]=new Array(k);for(var m=0;m<g[j].length;m++)g[j][m]=255&a.buffer[m+c];c+=k;var n=f.getErrorCorrectPolynomial(l),o=new i(g[j],n.getLength()-1),p=o.mod(n);h[j]=new Array(n.getLength()-1);for(var m=0;m<h[j].length;m++){var q=m+p.getLength()-h[j].length;h[j][m]=q>=0?p.get(q):0}}for(var r=0,m=0;m<b.length;m++)r+=b[m].totalCount;for(var s=new Array(r),t=0,m=0;d>m;m++)for(var j=0;j<b.length;j++)m<g[j].length&&(s[t++]=g[j][m]);for(var m=0;e>m;m++)for(var j=0;j<b.length;j++)m<h[j].length&&(s[t++]=h[j][m]);return s};for(var c={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},d={L:1,M:0,Q:3,H:2},e={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},f={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:1335,G18:7973,G15_MASK:21522,getBCHTypeInfo:function(a){for(var b=a<<10;f.getBCHDigit(b)-f.getBCHDigit(f.G15)>=0;)b^=f.G15<<f.getBCHDigit(b)-f.getBCHDigit(f.G15);return(a<<10|b)^f.G15_MASK},getBCHTypeNumber:function(a){for(var b=a<<12;f.getBCHDigit(b)-f.getBCHDigit(f.G18)>=0;)b^=f.G18<<f.getBCHDigit(b)-f.getBCHDigit(f.G18);return a<<12|b},getBCHDigit:function(a){for(var b=0;0!=a;)b++,a>>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<<h;for(var h=8;256>h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;c<this.getLength();c++)for(var d=0;d<a.getLength();d++)b[c+d]^=g.gexp(g.glog(this.get(c))+g.glog(a.get(d)));return new i(b,0)},mod:function(a){if(this.getLength()-a.getLength()<0)return this;for(var b=g.glog(this.get(0))-g.glog(a.get(0)),c=new Array(this.getLength()),d=0;d<this.getLength();d++)c[d]=this.get(d);for(var d=0;d<a.getLength();d++)c[d]^=g.gexp(g.glog(a.get(d))+b);return new i(c,0).mod(a)}},j.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],j.getRSBlocks=function(a,b){var c=j.getRsBlockTable(a,b);if(void 0==c)throw new Error("bad rs block @ typeNumber:"+a+"/errorCorrectLevel:"+b);for(var d=c.length/3,e=[],f=0;d>f;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=['<table style="border:0;border-collapse:collapse;">'],h=0;d>h;h++){g.push("<tr>");for(var i=0;d>i;i++)g.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:'+e+"px;height:"+f+"px;background-color:"+(a.isDark(h,i)?b.colorDark:b.colorLight)+';"></td>');g.push("</tr>")}g.push("</table>"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}();
js/emagicone/mobassistantconnector/qrcode_app_user_edit.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file is part of Mobile Assistant Connector.
3
+ *
4
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ var $j = jQuery.noConflict();
19
+
20
+ $j(document).ready(function() {
21
+ var container = $j("#user_tabs");
22
+ container.parent().append("<div style='text-align: center'><div style='margin-top: 20px'>" +
23
+ "<div id='mobassistantconnector_qr_code_app_img' style='width: 67px; margin-left: auto; margin-right: auto'></div>" +
24
+ "<div style='margin-top: 10px'>" +
25
+ "Magento Mobile Assistant App</div></div></div>");
26
+ var qrcodeContainer = document.getElementById("mobassistantconnector_qr_code_app_img");
27
+
28
+ if (qrcodeContainer != null) {
29
+ var qrCode = new QRCode(qrcodeContainer, {
30
+ width : 66,
31
+ height : 66
32
+ });
33
+
34
+ qrCode.makeCode("https://goo.gl/6Wjxme");
35
+ }
36
+ });
js/emagicone/mobassistantconnector/qrcode_app_user_index.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file is part of Mobile Assistant Connector.
3
+ *
4
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ var $j = jQuery.noConflict();
19
+
20
+ $j(document).ready(function() {
21
+ var container = $j("#emagicone_mobassistantconnector_user_grid");
22
+ container.append("<div style='text-align: center'><div style='display: inline-flex; margin-top: 15px'>" +
23
+ "<div id='mobassistantconnector_qr_code_app_img'></div>" +
24
+ "<div style='display: flex; align-items: center; padding-left: 7px'>" +
25
+ "Magento Mobile Assistant App</div></div></div>");
26
+ var qrcodeContainer = document.getElementById("mobassistantconnector_qr_code_app_img");
27
+
28
+ if (qrcodeContainer != null) {
29
+ var qrCode = new QRCode(qrcodeContainer, {
30
+ width : 66,
31
+ height : 66
32
+ });
33
+
34
+ qrCode.makeCode("https://goo.gl/6Wjxme");
35
+ }
36
+ });
js/emagicone/mobassistantconnector/user_edit.js ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file is part of Mobile Assistant Connector.
3
+ *
4
+ * Mobile Assistant Connector is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * Mobile Assistant Connector is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with Mobile Assistant Connector. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ var $j = jQuery.noConflict();
19
+
20
+ $j(document).ready(function() {
21
+ var password = $j('#password');
22
+ var login = $j('#username');
23
+ var password_value_old = password.val();
24
+ var login_value_old = login.val();
25
+ var entryPoint = $j("#note_qrcode_image");
26
+ // var qrCodeLink = $j("#qrcode_link");
27
+
28
+ if (entryPoint.length > 0) {
29
+ entryPoint.parent().prepend(
30
+ "<div id='mobassistantconnector_qr_code_container'><div id='mobassistantconnector_qr_code_img'>" +
31
+ "</div></div>"
32
+ );
33
+
34
+ var qrcodeContainer = document.getElementById('mobassistantconnector_qr_code_img');
35
+ var qrCode = new QRCode(qrcodeContainer, {
36
+ width : 300,
37
+ height : 300
38
+ });
39
+
40
+ qrCode.makeCode($j('#qr_code_data').val());
41
+
42
+ $j("#mobassistantconnector_qr_code_container").append(
43
+ "<div id='mobassistantconnector_qrcode_changed'>Login details have been changed. Save changes for " +
44
+ "code to be regenerated</div>"
45
+ );
46
+ }
47
+
48
+ /*if (qrCodeLink.length > 0) {
49
+ qrCodeLink.parent().prepend("<div id='mobassistantconnector_qr_code_link_container'>" +
50
+ "<div id='mobassistantconnector_div_qr_code_link_hash'>" +
51
+ "<input id='mobassistantconnector_qr_code_link_hash' type='text' name='qr_code_hash' value='" +
52
+ $j("#qrcode_hash").val() + "' readonly></div>" +
53
+ "<div id='mobassistantconnector_qr_code_link_btn_regenerate'><button type='button'>" +
54
+ "Regenerate QR-code hash</button>" + "</div></div>" +
55
+ "<div id='mobassistantconnector_qr_code_link_save_data'>Save data to get new QR-code link</div>");
56
+ }*/
57
+
58
+ /*$j("#mobassistantconnector_qr_code_link_btn_regenerate").click(function() {
59
+ $j("#mobassistantconnector_qr_code_link_hash").val(SHA256("'" + $j.now() + "'"));
60
+ $j("#qrcode_link").hide();
61
+ $j("#mobassistantconnector_qr_code_link_save_data").show();
62
+ });*/
63
+
64
+ login.keyup(function() {
65
+ changeQRCode();
66
+ });
67
+
68
+ password.keyup(function() {
69
+ changeQRCode();
70
+ });
71
+
72
+ // Need to proceed saving data
73
+ /*$j("#saveandcontinue").click(function() {
74
+ removeClass($j("#deviceGrid_massaction-select"), "required-entry");
75
+ });
76
+ $j("#save").click(function() {
77
+ removeClass($j("#deviceGrid_massaction-select"), "required-entry");
78
+ });*/
79
+
80
+ function changeQRCode() {
81
+ var login_new = login.val();
82
+ var password_new = password.val();
83
+ var qrcode_changed = $j('#mobassistantconnector_qrcode_changed');
84
+ var qrcode_img = $j('#mobassistantconnector_qr_code_img');
85
+
86
+ if (login_value_old != login_new || password_value_old != password_new) {
87
+ $j(qrcode_changed).show('fast');
88
+ $j(qrcode_img).css('opacity', '0.1');
89
+ } else {
90
+ $j(qrcode_changed).hide('fast');
91
+ $j(qrcode_img).css('opacity', '1');
92
+ }
93
+ }
94
+
95
+ function removeClass(element, className) {
96
+ if (element.length > 0) {
97
+ element.removeClass(className);
98
+ }
99
+ }
100
+
101
+ /*function SHA256(s) {
102
+ var chrsz = 8;
103
+ var hexcase = 0;
104
+
105
+ function safe_add(x, y) {
106
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
107
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
108
+
109
+ return (msw << 16) | (lsw & 0xFFFF);
110
+ }
111
+
112
+ function S(X, n) { return ( X >>> n ) | (X << (32 - n)); }
113
+ function R(X, n) { return ( X >>> n ); }
114
+ function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
115
+ function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
116
+ function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
117
+ function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
118
+ function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
119
+ function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
120
+
121
+ function core_sha256 (m, l) {
122
+ var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
123
+ var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
124
+ var W = new Array(64);
125
+ var a, b, c, d, e, f, g, h, i, j;
126
+ var T1, T2;
127
+
128
+ m[l >> 5] |= 0x80 << (24 - l % 32);
129
+ m[((l + 64 >> 9) << 4) + 15] = l;
130
+
131
+ for (var i = 0; i < m.length; i += 16) {
132
+ a = HASH[0];
133
+ b = HASH[1];
134
+ c = HASH[2];
135
+ d = HASH[3];
136
+ e = HASH[4];
137
+ f = HASH[5];
138
+ g = HASH[6];
139
+ h = HASH[7];
140
+
141
+ for (var j = 0; j<64; j++) {
142
+ if (j < 16) W[j] = m[j + i];
143
+ else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
144
+
145
+ T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
146
+ T2 = safe_add(Sigma0256(a), Maj(a, b, c));
147
+
148
+ h = g;
149
+ g = f;
150
+ f = e;
151
+ e = safe_add(d, T1);
152
+ d = c;
153
+ c = b;
154
+ b = a;
155
+ a = safe_add(T1, T2);
156
+ }
157
+
158
+ HASH[0] = safe_add(a, HASH[0]);
159
+ HASH[1] = safe_add(b, HASH[1]);
160
+ HASH[2] = safe_add(c, HASH[2]);
161
+ HASH[3] = safe_add(d, HASH[3]);
162
+ HASH[4] = safe_add(e, HASH[4]);
163
+ HASH[5] = safe_add(f, HASH[5]);
164
+ HASH[6] = safe_add(g, HASH[6]);
165
+ HASH[7] = safe_add(h, HASH[7]);
166
+ }
167
+
168
+ return HASH;
169
+ }
170
+
171
+ function str2binb (str) {
172
+ var bin = Array();
173
+ var mask = (1 << chrsz) - 1;
174
+ for(var i = 0; i < str.length * chrsz; i += chrsz) {
175
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
176
+ }
177
+ return bin;
178
+ }
179
+
180
+ function Utf8Encode(string) {
181
+ string = string.replace(/\r\n/g,"\n");
182
+ var utftext = "";
183
+
184
+ for (var n = 0; n < string.length; n++) {
185
+
186
+ var c = string.charCodeAt(n);
187
+
188
+ if (c < 128) {
189
+ utftext += String.fromCharCode(c);
190
+ }
191
+ else if((c > 127) && (c < 2048)) {
192
+ utftext += String.fromCharCode((c >> 6) | 192);
193
+ utftext += String.fromCharCode((c & 63) | 128);
194
+ }
195
+ else {
196
+ utftext += String.fromCharCode((c >> 12) | 224);
197
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
198
+ utftext += String.fromCharCode((c & 63) | 128);
199
+ }
200
+
201
+ }
202
+
203
+ return utftext;
204
+ }
205
+
206
+ function binb2hex (binarray) {
207
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
208
+ var str = "";
209
+ for(var i = 0; i < binarray.length * 4; i++) {
210
+ str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
211
+ hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
212
+ }
213
+ return str;
214
+ }
215
+
216
+ s = Utf8Encode(s);
217
+ return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
218
+ }*/
219
+
220
+ });
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>mobile_assistant_connector</name>
4
- <version>1.3.6</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.gnu.org/licenses/gpl.html">GNU</license>
7
  <channel>community</channel>
@@ -9,11 +9,16 @@
9
  <summary>Mobile Assistant Connector</summary>
10
  <description>Mobile Assistant Connector</description>
11
  <notes>Fixed:&#xD;
12
- - some possible problems with rendering layout</notes>
 
 
 
 
 
13
  <authors><author><name>eMagicOne</name><user>mobile</user><email>mobile@emagicone.com</email></author></authors>
14
- <date>2016-04-07</date>
15
- <time>14:57:26</time>
16
- <contents><target name="magecommunity"><dir name="Emagicone"><dir name="Mobassistantconnector"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Form"><file name="Qrcode.php" hash="70dea8e46b446b780f11cd4ee6b198aa"/><file name="Qrconfig.php" hash="dbc08b9915140181ec59f9c625abef75"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Access.php" hash="c6f4c96ca225bbc72cb829c59f7808f1"/><file name="Data.php" hash="0f1f35e6ef831e6017a989f24d96341a"/><file name="Test.php" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir><dir name="Model"><file name="Defpassword.php" hash="921e5344ba325ddf1aaba6aeb2202696"/><file name="Failed.php" hash="7da654c3cf1e9a3f5a55da7f36192117"/><file name="Login.php" hash="bedbce507924854910524fbabe1c4948"/><file name="Observer.php" hash="a63058c84f6c29393ebd497e8ca657d3"/><file name="Order.php" hash="f3d5529e0504ea0265cb661e03f41109"/><file name="Password.php" hash="66e2050ecc7b56deb654b5476ac1746c"/><dir name="Resource"><dir name="Failed"><file name="Collection.php" hash="18980688d80660f6a663a2c4dce20f54"/></dir><file name="Failed.php" hash="a69ca1239d3400097fabc415ee02751b"/><dir name="Sessions"><file name="Collection.php" hash="397e9a6f637472b59abe42bca09ea616"/></dir><file name="Sessions.php" hash="4d9f6cdd340fd95549d287c6107285ac"/></dir><file name="Sessions.php" hash="e3a32e26446e4cd27032c99dde8d4cfa"/></dir><dir name="controllers"><file name="IndexController.php" hash="86fd5a1b2d6291597054c57db4ff0aeb"/><dir name="adminhtml"><file name="IndexController.php" hash="e8fc499b74daeef9dbf856e813cbefb8"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="333ed888c7f8a1e067821b6547e34340"/><file name="config.xml" hash="ffccb95ec082ab9dede5223bd833cb94"/><file name="system.xml" hash="97fbc5425f62367d796080d5e84ae20c"/></dir><dir name="sql"><dir name="em1_setup"><file name="install-2.0.1.php" hash="2394c0bf43b7c8f15fa83d957ed15ffd"/></dir><dir name="emagicone_mobassistantconnector_setup"><file name="install-1.2.1.php" hash="2394c0bf43b7c8f15fa83d957ed15ffd"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Emagicone_Mobassistantconnector.xml" hash="7bb654478173d96ad294000fc9625820"/></dir></target><target name="magelocale"><dir><dir name="en_GB"><file name="Emagicone_Mobassistantconnector.csv" hash="eaf733f81ff47627c4389d487c93709f"/></dir><dir name="en_US"><file name="Emagicone_Mobassistantconnector.csv" hash="510d79a25c0bfb7a096aab57d8c5b458"/></dir><dir name="es_ES"><file name="Emagicone_Mobassistantconnector.csv" hash="acc37c432dd8b4134844291931b70fbf"/></dir><dir name="fr_FR"><file name="Emagicone_Mobassistantconnector.csv" hash="76c48723a6bbd59534781fd3c7f6d86e"/></dir><dir name="ru_RU"><file name="Emagicone_Mobassistantconnector.csv" hash="2346397cbe029dcc724717b953a3f38c"/></dir><dir name="uk_UA"><file name="Emagicone_Mobassistantconnector.csv" hash="cad0e0c3ec7603e6b886d815357d1766"/></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mobassistantconnector.xml" hash="b5c4d423be8de0c5d73d64783dcb9a3c"/></dir><dir name="template"><dir name="mobassistantconnector"><file name="connect_qrcode.phtml" hash="0a7663b0e688bb0da172e256b79edac2"/><file name="jsinit.phtml" hash="0a462da90a18be15dd5b3305c02605b5"/></dir></dir></dir></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php><extension><name>curl</name><min>1.0</min><max>3.0</max></extension><extension><name>json</name><min>1.0</min><max>3.0</max></extension><extension><name>date</name><min>1.0</min><max>3.0</max></extension></required></dependencies>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>mobile_assistant_connector</name>
4
+ <version>1.4.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.gnu.org/licenses/gpl.html">GNU</license>
7
  <channel>community</channel>
9
  <summary>Mobile Assistant Connector</summary>
10
  <description>Mobile Assistant Connector</description>
11
  <notes>Fixed:&#xD;
12
+ - minor bugs&#xD;
13
+ Added:&#xD;
14
+ - multiple user accounts can be created&#xD;
15
+ - user permission control is possible now&#xD;
16
+ - device activity control is possible now, you can check all the devices connected to your store, activate/deactivate accounts, remove devices&#xD;
17
+ </notes>
18
  <authors><author><name>eMagicOne</name><user>mobile</user><email>mobile@emagicone.com</email></author></authors>
19
+ <date>2016-04-11</date>
20
+ <time>08:48:57</time>
21
+ <contents><target name="magecommunity"><dir name="Emagicone"><dir name="Mobassistantconnector"><dir name="Block"><dir name="Adminhtml"><dir name="User"><dir name="Edit"><dir name="Device"><file name="Action.php" hash="748ccfc5bfb27839fbbe5b7599403881"/><file name="Currency.php" hash="7ea09a23a1ea316deeed6c9c9ac80ea1"/><file name="Date.php" hash="346726345f8890bf67744c4f226908ff"/><file name="Grid.php" hash="2724427ef8a4fde14c65082d3cf28a4f"/><file name="MassAction.php" hash="d122d28a33235e0830d563edddd0e91f"/><file name="NewCustomer.php" hash="c7c20ace8b45db464067e21e536d61bf"/><file name="NewOrder.php" hash="70b744943beba3195b5b32843924e100"/><file name="OrdStatuses.php" hash="2bb02f497afcc92a94f926eab60e4123"/><file name="Store.php" hash="7bb0503bb18b4e0735a6a2aae3e4a6f6"/></dir><file name="Form.php" hash="cd6ff48abc2dd12f8ac891caf914bc19"/><dir name="Tab"><file name="Devices.php" hash="3d8d69c1365f6a9aed31a08e16d3483a"/><file name="Main.php" hash="15fdb52f7bacdbcde0ff14e28d0edab1"/><file name="Permissions.php" hash="6f935a5d3241fabbebafcc5160dd0752"/></dir><file name="Tabs.php" hash="acc0ef49c44ca68a0104543d47594600"/></dir><file name="Edit.php" hash="28f71e2e4f32f691d74a3a7c4057e1d1"/><file name="Grid.php" hash="c135641a83eb3d53060724390d73242a"/><dir name="Renderer"><file name="Permissions.php" hash="2e1fcff08869bc9c2ad57e0f0f4326d1"/></dir></dir><file name="User.php" hash="3c85641c28ca4f0b06f82f891d0dd5d9"/></dir></dir><dir name="Helper"><file name="Access.php" hash="a2817c796ef727bf4b454c38c53ff489"/><file name="Data.php" hash="b58c0457a0724d522472a25a769d4697"/><file name="DeviceAndPushNotification.php" hash="bae57bdc5f9be6bf999950404561a52d"/><file name="TableCheck.php" hash="5794c6de2b12b06fa5406d4ec910761a"/><file name="UserPermissions.php" hash="141e770d2417ea9568ebbe46b355468e"/></dir><dir name="Model"><file name="Account.php" hash="f77aaf7f0353b955a3fd329eadb9c442"/><file name="Device.php" hash="83de38ede2946fd212f9830c4986ac1b"/><file name="Failed.php" hash="7da654c3cf1e9a3f5a55da7f36192117"/><file name="Login.php" hash="bedbce507924854910524fbabe1c4948"/><file name="Observer.php" hash="d3087bda341c047cf8aaf1f56b3a90e1"/><file name="Order.php" hash="f3d5529e0504ea0265cb661e03f41109"/><file name="Password.php" hash="66e2050ecc7b56deb654b5476ac1746c"/><file name="Push.php" hash="6ea51508c9c0f286e823b3114ecc1574"/><dir name="Resource"><dir name="Account"><file name="Collection.php" hash="f2cca57921b1e4166adba6ec696019b2"/></dir><file name="Account.php" hash="7173f12167679683fd0d988486ac3194"/><dir name="Device"><file name="Collection.php" hash="ca73c4991e75291ae22e3da2001c2135"/></dir><file name="Device.php" hash="af556dc7a9219c8c2410644ebc0aa091"/><dir name="Failed"><file name="Collection.php" hash="18980688d80660f6a663a2c4dce20f54"/></dir><file name="Failed.php" hash="a69ca1239d3400097fabc415ee02751b"/><dir name="Push"><file name="Collection.php" hash="e6c30e6242b49968163445599376e1fb"/></dir><file name="Push.php" hash="f703f63c3e286dd8d130465f1496b421"/><dir name="Sessions"><file name="Collection.php" hash="f3d9c493b3b6a3ddfe518e583c7e5cdd"/></dir><file name="Sessions.php" hash="1b711092c3754a78968fc588b17a5b27"/><dir name="User"><file name="Collection.php" hash="571520e1040d4e02b7561a84cfdbd2d0"/></dir><file name="User.php" hash="6cc54e4e5d8e2a5e79d16fee72d0747c"/></dir><file name="Sessions.php" hash="5235ab4ee8c85e65b6a7acd3822a1f8e"/><file name="User.php" hash="88d00bbf3beba3e7f74f6856c3f6dcef"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="UserController.php" hash="a20cd0217cfe4582782b058fc4dcf5f6"/></dir><file name="IndexController.php" hash="5512954d6614d176cbecd674738d8f16"/></dir><dir name="data"><dir name="em1_mob_setup"><file name="data-install-1.4.0.php" hash="965122cdb3c3588b12b3183def522865"/></dir></dir><dir name="etc"><file name="config.xml" hash="634433a0d271709d5ec041e6b0357023"/></dir><dir name="sql"><dir name="em1_mob_setup"><file name="install-1.2.1.php" hash="47e6e1768eebf16f550bff703d07d6ed"/><file name="install-1.4.0.php" hash="b73da05de23bf5440a027f5848a6c537"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Emagicone_Mobassistantconnector.xml" hash="e2640b07fbf521ed2b46a7babc32c961"/></dir></target><target name="magelocale"><dir><dir name="en_GB"><file name="Emagicone_Mobassistantconnector.csv" hash="eaf733f81ff47627c4389d487c93709f"/></dir><dir name="en_US"><file name="Emagicone_Mobassistantconnector.csv" hash="510d79a25c0bfb7a096aab57d8c5b458"/></dir><dir name="es_ES"><file name="Emagicone_Mobassistantconnector.csv" hash="acc37c432dd8b4134844291931b70fbf"/></dir><dir name="fr_FR"><file name="Emagicone_Mobassistantconnector.csv" hash="76c48723a6bbd59534781fd3c7f6d86e"/></dir><dir name="ru_RU"><file name="Emagicone_Mobassistantconnector.csv" hash="2346397cbe029dcc724717b953a3f38c"/></dir><dir name="uk_UA"><file name="Emagicone_Mobassistantconnector.csv" hash="cad0e0c3ec7603e6b886d815357d1766"/></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mobassistantconnector.xml" hash="55e923f137ddebdc15388cd99fa49f84"/></dir><dir name="template"><dir name="mobassistantconnector"><file name="permissions.phtml" hash="4a5bec0a952e42b8217009c25d13e517"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="emagicone"><dir name="mobassistantconnector"><file name="qr_code.phtml" hash="ef2214ea50bcb16437f442560685fd5e"/></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="emagicone"><dir name="mobassistantconnector"><file name="style.css" hash="999f613ef0c69cdf66983287863d12c9"/></dir></dir><dir name="images"><dir name="emagicone"><dir name="mobassistantconnector"><file name="no.png" hash="75414819e41cc1416c0d822542000ade"/><file name="yes.png" hash="1f5f13694de74c249ab49f5f3d6594e5"/></dir></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="emagicone"><dir name="mobassistantconnector"><file name="jquery-2.2.2.min.js" hash="1d35678c5edbb639ab7aa5cce0856f57"/><file name="qrcode.min.js" hash="faf8005e4fd1a9ea39d4b6feb930bf09"/><file name="qrcode_app_user_edit.js" hash="360885156fbb459a3cef3f5ce2ff1e97"/><file name="qrcode_app_user_index.js" hash="5bb7797825387d3f7144315008218afc"/><file name="user_edit.js" hash="9e2dde14fb29bd9324c94fa0491a525d"/></dir></dir></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php><extension><name>curl</name><min>1.0</min><max>3.0</max></extension><extension><name>json</name><min>1.0</min><max>3.0</max></extension><extension><name>date</name><min>1.0</min><max>3.0</max></extension></required></dependencies>
24
  </package>
skin/adminhtml/default/default/emagicone/mobassistantconnector/style.css ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #mobassistantconnector_qr_code_container {
2
+ position: relative;
3
+ }
4
+
5
+ #mobassistantconnector_qrcode_changed {
6
+ position: absolute;
7
+ top: 47%;
8
+ width: 300px;
9
+ color: red;
10
+ text-align: center;
11
+ display: none;
12
+ }
13
+
14
+ #mobassistantconnector_qr_code_link_container {
15
+ display: flex;
16
+ }
17
+
18
+ #mobassistantconnector_div_qr_code_link_hash {
19
+ width: 100%;
20
+ }
21
+
22
+ #mobassistantconnector_qr_code_link_hash {
23
+ width: 450px;
24
+ }
25
+
26
+ #mobassistantconnector_qr_code_link_btn_regenerate {
27
+ margin-left: 14px;
28
+ }
29
+
30
+ #mobassistantconnector_qr_code_link_save_data {
31
+ display: none;
32
+ color: red;
33
+ }
skin/adminhtml/default/default/images/emagicone/mobassistantconnector/no.png ADDED
Binary file
skin/adminhtml/default/default/images/emagicone/mobassistantconnector/yes.png ADDED
Binary file