HusseyCoding_Sirportly - Version 1.2.1

Version Notes

Added admin ticket creation and updating

Download this release

Release Info

Developer Hussey Coding
Extension HusseyCoding_Sirportly
Version 1.2.1
Comparing to
See all releases


Code changes from version 1.0.4 to 1.2.1

Files changed (45) hide show
  1. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets.php +73 -1
  2. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket.php +157 -0
  3. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket/Teams.php +74 -0
  4. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket/Users.php +45 -0
  5. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket.php +121 -0
  6. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket/Teams.php +57 -0
  7. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket/Users.php +54 -0
  8. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket.php +169 -0
  9. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Responses.php +29 -0
  10. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Teams.php +77 -0
  11. app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Users.php +74 -0
  12. app/code/community/HusseyCoding/Sirportly/Block/Permissions/User/Edit/AdminhtmlTabs.php +14 -0
  13. app/code/community/HusseyCoding/Sirportly/Block/Permissions/User/Edit/Tab/Sirportly.php +80 -0
  14. app/code/community/HusseyCoding/Sirportly/Helper/Data.php +555 -42
  15. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Department/OrderScreen.php +5 -0
  16. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Department/PaymentFailed.php +8 -0
  17. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Priority/OrderScreen.php +5 -0
  18. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Priority/PaymentFailed.php +8 -0
  19. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Sla/OrderScreen.php +8 -0
  20. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Status/OrderScreen.php +5 -0
  21. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Status/PaymentFailed.php +8 -0
  22. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Team/OrderScreen.php +5 -0
  23. app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Team/PaymentFailed.php +8 -0
  24. app/code/community/HusseyCoding/Sirportly/controllers/Sales/OrderController.php +178 -5
  25. app/code/community/HusseyCoding/Sirportly/etc/config.xml +16 -1
  26. app/code/community/HusseyCoding/Sirportly/etc/system.xml +116 -32
  27. app/code/community/HusseyCoding/Sirportly/sql/sirportly_setup/mysql4-upgrade-1.1.0-1.2.0.php +9 -0
  28. app/code/community/HusseyCoding/Sirportly/sql/sirportly_setup/mysql4-upgrade-1.2.0-1.2.1.php +8 -0
  29. app/design/adminhtml/default/default/layout/sirportly.xml +8 -0
  30. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets.phtml +90 -26
  31. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket.phtml +137 -0
  32. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket/teams.phtml +5 -0
  33. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket/users.phtml +5 -0
  34. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket.phtml +89 -0
  35. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket/teams.phtml +5 -0
  36. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket/users.phtml +5 -0
  37. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket.phtml +172 -0
  38. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/responses.phtml +5 -0
  39. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/teams.phtml +5 -0
  40. app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/users.phtml +5 -0
  41. package.xml +6 -6
  42. skin/adminhtml/default/default/sirportly/css/ordertickets.css +23 -1
  43. skin/adminhtml/default/default/sirportly/js/livepipe.js +181 -0
  44. skin/adminhtml/default/default/sirportly/js/ordertickets.js +335 -11
  45. skin/adminhtml/default/default/sirportly/js/window.js +947 -0
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets.php CHANGED
@@ -1,12 +1,23 @@
1
  <?php
2
  class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets extends Mage_Adminhtml_Block_Template implements Mage_Adminhtml_Block_Widget_Tab_Interface
3
  {
 
 
 
4
  public function _construct()
5
  {
6
  parent::_construct();
7
  $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets.phtml');
8
  }
9
 
 
 
 
 
 
 
 
 
10
  public function getOrder()
11
  {
12
  return Mage::registry('current_order');
@@ -49,7 +60,11 @@ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTicke
49
 
50
  public function getCustomerEmail()
51
  {
52
- return $this->getOrder()->getCustomerEmail();
 
 
 
 
53
  }
54
 
55
  public function getCustomerName()
@@ -61,4 +76,61 @@ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTicke
61
  {
62
  return Mage::helper('sirportly')->getTicketsByEmail($this->getCustomerEmail());
63
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
1
  <?php
2
  class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets extends Mage_Adminhtml_Block_Template implements Mage_Adminhtml_Block_Widget_Tab_Interface
3
  {
4
+ private $_customeremail;
5
+ private $_domain;
6
+
7
  public function _construct()
8
  {
9
  parent::_construct();
10
  $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets.phtml');
11
  }
12
 
13
+ protected function _prepareLayout()
14
+ {
15
+ $newticket = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket');
16
+ $this->setChild('order_tab_sirportly_newticket', $newticket);
17
+
18
+ return parent::_prepareLayout();
19
+ }
20
+
21
  public function getOrder()
22
  {
23
  return Mage::registry('current_order');
60
 
61
  public function getCustomerEmail()
62
  {
63
+ if (!isset($this->_customeremail)):
64
+ $this->_customeremail = $this->getOrder()->getCustomerEmail();
65
+ endif;
66
+
67
+ return $this->_customeremail;
68
  }
69
 
70
  public function getCustomerName()
76
  {
77
  return Mage::helper('sirportly')->getTicketsByEmail($this->getCustomerEmail());
78
  }
79
+
80
+ public function getSlaHtml($ticket)
81
+ {
82
+ $html = '';
83
+
84
+ if (!empty($ticket['sla']['name'])):
85
+ $html .= '<div>'. $ticket['sla']['name'] . '</div>';
86
+ $name = $ticket['sla']['name'];
87
+ $now = time();
88
+ $helper = Mage::helper('sirportly');
89
+ if (empty($ticket['resolution_time'])):
90
+ if (!empty($ticket['reply_due_at'])):
91
+ $due = strtotime($ticket['reply_due_at']);
92
+ if ($now > $due):
93
+ $html .= '<div class="ticket-update-overdue ticket-update-sla">Reply overdue</div><div class="ticket-update-sla">(' . $helper->getTimestamp($ticket['reply_due_at']) . ')</div>';
94
+ else:
95
+ $html .= '<div class="ticket-update-sla">Reply due at<br />' . $helper->getTimestamp($ticket['reply_due_at']) . '</div>';
96
+ endif;
97
+ endif;
98
+ if (!empty($ticket['resolution_due_at'])):
99
+ $due = strtotime($ticket['resolution_due_at']);
100
+ if ($now > $due):
101
+ $html .= '<div class="ticket-update-overdue ticket-update-sla">Resolution overdue</div><div class="ticket-update-sla">(' . $helper->getTimestamp($ticket['resolution_due_at']) . ')</div>';
102
+ else:
103
+ $html .= '<div class="ticket-update-sla">Resolution due at<br />' . $helper->getTimestamp($ticket['resolution_due_at']) . '</div>';
104
+ endif;
105
+ endif;
106
+ endif;
107
+ endif;
108
+
109
+ return $html;
110
+ }
111
+
112
+ public function canCreate()
113
+ {
114
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
115
+ if ($restrictions['permissions'] == 'full'):
116
+ return true;
117
+ endif;
118
+ endif;
119
+
120
+ return false;
121
+ }
122
+
123
+ public function getSirportlyDomain()
124
+ {
125
+ if (!isset($this->_domain)):
126
+ $this->_domain = false;
127
+ if ($domain = Mage::getStoreConfig('sirportly/general/domain')):
128
+ $domain = preg_replace('/http(s)?:\/\//', '', $domain);
129
+ $domain = trim($domain, '/');
130
+ if ($domain) $this->_domain = $domain;
131
+ endif;
132
+ endif;
133
+
134
+ return $this->_domain;
135
+ }
136
  }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_NewTicket extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/newticket.phtml');
8
+ }
9
+
10
+ protected function _prepareLayout()
11
+ {
12
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
13
+ ->setData(array(
14
+ 'label' => Mage::helper('sirportly')->__('Submit Ticket'),
15
+ 'class' => 'save'
16
+ ));
17
+ $this->setChild('submit_button', $button);
18
+
19
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket_teams');
20
+ $this->setChild('order_tab_sirportly_newticket_teams', $teams);
21
+
22
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket_users');
23
+ $this->setChild('order_tab_sirportly_newticket_users', $users);
24
+
25
+ return parent::_prepareLayout();
26
+ }
27
+
28
+ public function getStatuses()
29
+ {
30
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/statuses', false, '');
31
+
32
+ return $this->_addUseAdmin('status', $options);
33
+ }
34
+
35
+ public function getPriorities()
36
+ {
37
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/priorities', false, '');
38
+
39
+ return $this->_addUseAdmin('priority', $options);
40
+ }
41
+
42
+ public function getSlas()
43
+ {
44
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/slas', false, '');
45
+ array_unshift($options, array('value' => '', 'label' => 'None'));
46
+
47
+ return $this->_addUseAdmin('sla', $options);
48
+ }
49
+
50
+ public function getDepartments()
51
+ {
52
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/departments', 'brand', '');
53
+ if ($default = (int) Mage::getStoreConfig('sirportly/orderscreen/department')):
54
+ $label = '';
55
+ $break = false;
56
+ foreach ($options as $option):
57
+ if (!empty($option['label'])):
58
+ $partial = $option['label'] . ' &rarr; ';
59
+ if (!empty($option['value']) && is_array($option['value'])):
60
+ foreach ($option['value'] as $entry):
61
+ if (!empty($entry['value']) && $entry['value'] == $default):
62
+ if (!empty($entry['label'])):
63
+ $label = $partial . $entry['label'];
64
+ $break = true;
65
+ break;
66
+ endif;
67
+ endif;
68
+ endforeach;
69
+ if ($break) break;
70
+ endif;
71
+ endif;
72
+ endforeach;
73
+
74
+ if ($label):
75
+ array_unshift($options, array('value' => $default, 'label' => 'Default (' . $label . ')'));
76
+ endif;
77
+ endif;
78
+
79
+ if (!$this->canEditUser()):
80
+ $options = $this->filterDepartmentsByUser($options);
81
+ endif;
82
+
83
+ $option = reset($options);
84
+ if (!empty($option['value'])):
85
+ if (is_array($option['value'])):
86
+ foreach ($option['value'] as $department):
87
+ if (!empty($department['value'])):
88
+ $value = $department['value'];
89
+ break;
90
+ endif;
91
+ endforeach;
92
+ else:
93
+ $value = $option['value'];
94
+ endif;
95
+ if (!empty($value)):
96
+ $this->getChild('order_tab_sirportly_newticket_teams')->setDepartment($value);
97
+ endif;
98
+ endif;
99
+
100
+ return $options;
101
+ }
102
+
103
+ private function _addUseAdmin($config, $options)
104
+ {
105
+ if ($default = (int) Mage::getStoreConfig('sirportly/orderscreen/' . $config)):
106
+ $label = '';
107
+ foreach ($options as $option):
108
+ if (!empty($option['label']) && !empty($option['value']) && $option['value'] == $default):
109
+ $label = $option['label'];
110
+ break;
111
+ endif;
112
+ endforeach;
113
+
114
+ if ($label):
115
+ array_unshift($options, array('value' => $default, 'label' => 'Default (' . $label . ')'));
116
+ endif;
117
+ endif;
118
+
119
+ return $options;
120
+ }
121
+
122
+ public function verifyCredentials()
123
+ {
124
+ return Mage::helper('sirportly')->verifyCredentials();
125
+ }
126
+
127
+ public function getOrder()
128
+ {
129
+ return Mage::registry('current_order');
130
+ }
131
+
132
+ public function getCustomerEmail()
133
+ {
134
+ return $this->getOrder()->getCustomerEmail();
135
+ }
136
+
137
+ public function getCustomerName()
138
+ {
139
+ return $this->getOrder()->getCustomerName();
140
+ }
141
+
142
+ public function canEditUser()
143
+ {
144
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
145
+ if ($restrictions['user']):
146
+ return false;
147
+ endif;
148
+ endif;
149
+
150
+ return true;
151
+ }
152
+
153
+ public function filterDepartmentsByUser($options)
154
+ {
155
+ return Mage::helper('sirportly')->filterDepartmentsByUser($options);
156
+ }
157
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket/Teams.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_NewTicket_Teams extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/newticket/teams.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($department = Mage::app()->getRequest()->getPost('department')):
13
+ $this->setDepartment((int) $department);
14
+ endif;
15
+ }
16
+
17
+ public function getTeams()
18
+ {
19
+ $helper = Mage::helper('sirportly');
20
+ $options = $helper->getSelectOptions('/api/v2/objects/teams', false, '');
21
+ $options = $this->_addUseAdmin($options);
22
+ $options = $helper->filterTeamsByDepartment($options, $this->getDepartment());
23
+
24
+ if (!$this->canEditUser()):
25
+ $options = $this->filterTeamsByUser($options);
26
+ endif;
27
+
28
+ $option = reset($options);
29
+ if (!empty($option['value'])):
30
+ if ($parent = $this->getParentBlock()):
31
+ $this->getParentBlock()->getChild('order_tab_sirportly_newticket_users')->setTeam($option['value']);
32
+ else:
33
+ $this->setTeam($option['value']);
34
+ endif;
35
+ endif;
36
+
37
+ return $options;
38
+ }
39
+
40
+ private function _addUseAdmin($options)
41
+ {
42
+ if ($default = (int) Mage::getStoreConfig('sirportly/orderscreen/team')):
43
+ $label = '';
44
+ foreach ($options as $option):
45
+ if (!empty($option['label']) && !empty($option['value']) && $option['value'] == $default):
46
+ $label = $option['label'];
47
+ break;
48
+ endif;
49
+ endforeach;
50
+
51
+ if ($label):
52
+ array_unshift($options, array('value' => $default, 'label' => 'Default (' . $label . ')'));
53
+ endif;
54
+ endif;
55
+
56
+ return $options;
57
+ }
58
+
59
+ public function canEditUser()
60
+ {
61
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
62
+ if ($restrictions['user']):
63
+ return false;
64
+ endif;
65
+ endif;
66
+
67
+ return true;
68
+ }
69
+
70
+ public function filterTeamsByUser($options)
71
+ {
72
+ return Mage::helper('sirportly')->filterTeamsByUser($options);
73
+ }
74
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/NewTicket/Users.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_NewTicket_Users extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/newticket/users.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($team = Mage::app()->getRequest()->getPost('team')):
13
+ $this->setTeam((int) $team);
14
+ endif;
15
+ }
16
+
17
+ public function getUsers()
18
+ {
19
+ $helper = Mage::helper('sirportly');
20
+ $options = $helper->getSelectOptions('/api/v2/objects/users', false, '', array('id' => array('first_name', 'last_name')));
21
+ $options = $helper->filterUsersByTeam($options, $this->getTeam());
22
+
23
+ if (!$this->canEditUser()):
24
+ $options = $this->filterUsersByUser($options);
25
+ endif;
26
+
27
+ return $options;
28
+ }
29
+
30
+ public function canEditUser()
31
+ {
32
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
33
+ if ($restrictions['user']):
34
+ return false;
35
+ endif;
36
+ endif;
37
+
38
+ return true;
39
+ }
40
+
41
+ public function filterUsersByUser($options)
42
+ {
43
+ return Mage::helper('sirportly')->filterUsersByUser($options);
44
+ }
45
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_ReassignTicket extends Mage_Adminhtml_Block_Template
3
+ {
4
+ private $_order;
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/reassignticket.phtml');
10
+ }
11
+
12
+ protected function _prepareLayout()
13
+ {
14
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
15
+ ->setData(array(
16
+ 'label' => Mage::helper('sirportly')->__('Reassign'),
17
+ 'class' => 'save'
18
+ ));
19
+ $this->setChild('submit_button', $button);
20
+
21
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket_teams');
22
+ $this->setChild('order_tab_sirportly_reassignticket_teams', $teams);
23
+
24
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket_users');
25
+ $this->setChild('order_tab_sirportly_reassignticket_users', $users);
26
+
27
+ return parent::_prepareLayout();
28
+ }
29
+
30
+ public function _beforeToHtml()
31
+ {
32
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
33
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
34
+ if (!empty($data['department'])):
35
+ $this->setDepartment($data['department']);
36
+ endif;
37
+ if (!empty($data['sla'])):
38
+ $this->setSla($data['sla']);
39
+ else:
40
+ $this->setSla('');
41
+ endif;
42
+ endif;
43
+ }
44
+
45
+ public function getDepartments()
46
+ {
47
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/departments', 'brand', '');
48
+
49
+ $department = $this->getDepartment();
50
+ if (!empty($department)):
51
+ $break = false;
52
+ foreach ($options as $option):
53
+ foreach ($option['value'] as $item):
54
+ if ($item['value'] == $department):
55
+ array_unshift($options, array('value' => $department, 'label' => '--Unchanged--'));
56
+ $break = true;
57
+ break;
58
+ endif;
59
+ endforeach;
60
+ if ($break) break;
61
+ endforeach;
62
+ endif;
63
+
64
+ return $options;
65
+ }
66
+
67
+ public function verifyCredentials()
68
+ {
69
+ return Mage::helper('sirportly')->verifyCredentials();
70
+ }
71
+
72
+ public function getOrder()
73
+ {
74
+ if (!isset($this->_order)):
75
+ if ($orderid = (int) $this->getOrderId()):
76
+ $order = Mage::getModel('sales/order')->load($orderid);
77
+ if ($order->getId()):
78
+ $this->_order = $order;
79
+ endif;
80
+ endif;
81
+ endif;
82
+
83
+ return $this->_order;
84
+ }
85
+
86
+ public function getCustomerEmail()
87
+ {
88
+ return $this->getOrder()->getCustomerEmail();
89
+ }
90
+
91
+ public function getCustomerName()
92
+ {
93
+ return $this->getOrder()->getCustomerName();
94
+ }
95
+
96
+ public function getReference()
97
+ {
98
+ return parent::getReference();
99
+ }
100
+
101
+ public function getOrderId()
102
+ {
103
+ return parent::getOrderId();
104
+ }
105
+
106
+ public function getSubject()
107
+ {
108
+ return parent::getSubject();
109
+ }
110
+
111
+ public function canUpdate()
112
+ {
113
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
114
+ if ($restrictions['permissions'] == 'full'):
115
+ return true;
116
+ endif;
117
+ endif;
118
+
119
+ return false;
120
+ }
121
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket/Teams.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_ReassignTicket_Teams extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/reassignticket/teams.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($department = $this->getRequest()->getPost('department')):
13
+ $this->setDepartment((int) $department);
14
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
15
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
16
+ if (!empty($data['team'])):
17
+ $this->setTeam($data['team']);
18
+ endif;
19
+ endif;
20
+ elseif ($reference = Mage::app()->getRequest()->getPost('reference')):
21
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
22
+ if (!empty($data['department'])):
23
+ $this->setDepartment($data['department']);
24
+ endif;
25
+ if (!empty($data['team'])):
26
+ $this->setTeam($data['team']);
27
+ endif;
28
+ endif;
29
+ }
30
+
31
+ public function getTeams()
32
+ {
33
+ if ($this->getDepartment()):
34
+ $helper = Mage::helper('sirportly');
35
+ $options = $helper->getSelectOptions('/api/v2/objects/teams', false, '');
36
+
37
+ $options = $helper->filterTeamsByDepartment($options, $this->getDepartment());
38
+
39
+ $team = $this->getTeam();
40
+ if (!empty($team)):
41
+ foreach ($options as $option):
42
+ if ($option['value'] == $team):
43
+ array_unshift($options, array('value' => $team, 'label' => '--Unchanged--'));
44
+ break;
45
+ endif;
46
+ endforeach;
47
+ endif;
48
+
49
+ $option = reset($options);
50
+ if (!empty($option['value'])):
51
+ $this->setTeam($option['value']);
52
+ endif;
53
+
54
+ return $options;
55
+ endif;
56
+ }
57
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/ReassignTicket/Users.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_ReassignTicket_Users extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/reassignticket/users.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($team = $this->getRequest()->getPost('team')):
13
+ $this->setTeam((int) $team);
14
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
15
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
16
+ if (!empty($data['user'])):
17
+ $this->setUser($data['user']);
18
+ endif;
19
+ endif;
20
+ elseif ($reference = Mage::app()->getRequest()->getPost('reference')):
21
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
22
+ if (!$this->getTeam()):
23
+ if (!empty($data['team'])):
24
+ $this->setTeam($data['team']);
25
+ endif;
26
+ endif;
27
+ if (!empty($data['user'])):
28
+ $this->setUser($data['user']);
29
+ endif;
30
+ endif;
31
+ }
32
+
33
+ public function getUsers()
34
+ {
35
+ if ($this->getTeam()):
36
+ $helper = Mage::helper('sirportly');
37
+ $options = $helper->getSelectOptions('/api/v2/objects/users', false, '', array('id' => array('first_name', 'last_name')));
38
+
39
+ $options = $helper->filterUsersByTeam($options, $this->getTeam());
40
+
41
+ $user = $this->getUser();
42
+ if (!empty($user)):
43
+ foreach ($options as $option):
44
+ if ($option['value'] == $user):
45
+ array_unshift($options, array('value' => $user, 'label' => '--Unchanged--'));
46
+ break;
47
+ endif;
48
+ endforeach;
49
+ endif;
50
+
51
+ return $options;
52
+ endif;
53
+ }
54
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_UpdateTicket extends Mage_Adminhtml_Block_Template
3
+ {
4
+ private $_order;
5
+
6
+ public function _construct()
7
+ {
8
+ parent::_construct();
9
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/updateticket.phtml');
10
+ }
11
+
12
+ protected function _prepareLayout()
13
+ {
14
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
15
+ ->setData(array(
16
+ 'label' => Mage::helper('sirportly')->__('Submit Update'),
17
+ 'class' => 'save'
18
+ ));
19
+ $this->setChild('submit_button', $button);
20
+
21
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_teams');
22
+ $this->setChild('order_tab_sirportly_updateticket_teams', $teams);
23
+
24
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_users');
25
+ $this->setChild('order_tab_sirportly_updateticket_users', $users);
26
+
27
+ $responses = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_responses');
28
+ $this->setChild('order_tab_sirportly_updateticket_responses', $responses);
29
+
30
+ return parent::_prepareLayout();
31
+ }
32
+
33
+ public function _beforeToHtml()
34
+ {
35
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
36
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
37
+ if (!empty($data['department'])):
38
+ $this->setDepartment($data['department']);
39
+ endif;
40
+ if (!empty($data['sla'])):
41
+ $this->setSla($data['sla']);
42
+ endif;
43
+ endif;
44
+ }
45
+
46
+ public function getStatuses()
47
+ {
48
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/statuses', false, '--Unchanged--');
49
+ }
50
+
51
+ public function getPriorities()
52
+ {
53
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/priorities', false, '--Unchanged--');
54
+ }
55
+
56
+ public function getSlas()
57
+ {
58
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/slas', false, '');
59
+ array_unshift($options, array('value' => '', 'label' => 'None'));
60
+
61
+ $sla = $this->getSla();
62
+ if (!empty($sla)):
63
+ foreach ($options as $option):
64
+ if ($option['value'] == $sla):
65
+ array_unshift($options, array('value' => $sla, 'label' => '--Unchanged--'));
66
+ endif;
67
+ endforeach;
68
+ endif;
69
+
70
+ return $options;
71
+ }
72
+
73
+ public function getDepartments()
74
+ {
75
+ $options = Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/departments', 'brand', '');
76
+
77
+ $department = $this->getDepartment();
78
+ if (!empty($department)):
79
+ $break = false;
80
+ foreach ($options as $option):
81
+ foreach ($option['value'] as $item):
82
+ if ($item['value'] == $department):
83
+ array_unshift($options, array('value' => $department, 'label' => '--Unchanged--'));
84
+ $break = true;
85
+ break;
86
+ endif;
87
+ endforeach;
88
+ if ($break) break;
89
+ endforeach;
90
+ endif;
91
+
92
+ if (!$this->canEditUser()):
93
+ $options = $this->filterDepartmentsByUser($options);
94
+ endif;
95
+
96
+ return $options;
97
+ }
98
+
99
+ public function verifyCredentials()
100
+ {
101
+ return Mage::helper('sirportly')->verifyCredentials();
102
+ }
103
+
104
+ public function getOrder()
105
+ {
106
+ if (!isset($this->_order)):
107
+ if ($orderid = (int) $this->getOrderId()):
108
+ $order = Mage::getModel('sales/order')->load($orderid);
109
+ if ($order->getId()):
110
+ $this->_order = $order;
111
+ endif;
112
+ endif;
113
+ endif;
114
+
115
+ return $this->_order;
116
+ }
117
+
118
+ public function getCustomerEmail()
119
+ {
120
+ return $this->getOrder()->getCustomerEmail();
121
+ }
122
+
123
+ public function getCustomerName()
124
+ {
125
+ return $this->getOrder()->getCustomerName();
126
+ }
127
+
128
+ public function getReference()
129
+ {
130
+ return parent::getReference();
131
+ }
132
+
133
+ public function getOrderId()
134
+ {
135
+ return parent::getOrderId();
136
+ }
137
+
138
+ public function getSubject()
139
+ {
140
+ return parent::getSubject();
141
+ }
142
+
143
+ public function canUpdate()
144
+ {
145
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
146
+ if ($restrictions['permissions'] == 'full'):
147
+ return true;
148
+ endif;
149
+ endif;
150
+
151
+ return false;
152
+ }
153
+
154
+ public function canEditUser()
155
+ {
156
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
157
+ if ($restrictions['user']):
158
+ return false;
159
+ endif;
160
+ endif;
161
+
162
+ return true;
163
+ }
164
+
165
+ public function filterDepartmentsByUser($options)
166
+ {
167
+ return Mage::helper('sirportly')->filterDepartmentsByUser($options);
168
+ }
169
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Responses.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_UpdateTicket_Responses extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/updateticket/responses.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($department = $this->getRequest()->getPost('department')):
13
+ $this->setDepartment((int) $department);
14
+ elseif ($reference = Mage::app()->getRequest()->getPost('reference')):
15
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
16
+ if (!empty($data['department'])):
17
+ $this->setDepartment($data['department']);
18
+ endif;
19
+ endif;
20
+ }
21
+
22
+ public function getResponses()
23
+ {
24
+ if ($this->getDepartment()):
25
+ $helper = Mage::helper('sirportly');
26
+ return $helper->getResponses($this->getDepartment());
27
+ endif;
28
+ }
29
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Teams.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_UpdateTicket_Teams extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/updateticket/teams.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($department = $this->getRequest()->getPost('department')):
13
+ $this->setDepartment((int) $department);
14
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
15
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
16
+ if (!empty($data['team'])):
17
+ $this->setTeam($data['team']);
18
+ endif;
19
+ endif;
20
+ elseif ($reference = Mage::app()->getRequest()->getPost('reference')):
21
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
22
+ if (!empty($data['department'])):
23
+ $this->setDepartment($data['department']);
24
+ endif;
25
+ if (!empty($data['team'])):
26
+ $this->setTeam($data['team']);
27
+ endif;
28
+ endif;
29
+ }
30
+
31
+ public function getTeams()
32
+ {
33
+ if ($this->getDepartment()):
34
+ $helper = Mage::helper('sirportly');
35
+ $options = $helper->getSelectOptions('/api/v2/objects/teams', false, '');
36
+
37
+ $options = $helper->filterTeamsByDepartment($options, $this->getDepartment());
38
+
39
+ $team = $this->getTeam();
40
+ if (!empty($team)):
41
+ foreach ($options as $option):
42
+ if ($option['value'] == $team):
43
+ array_unshift($options, array('value' => $team, 'label' => '--Unchanged--'));
44
+ break;
45
+ endif;
46
+ endforeach;
47
+ endif;
48
+
49
+ if (!$this->canEditUser()):
50
+ $options = $this->filterTeamsByUser($options);
51
+ endif;
52
+
53
+ $option = reset($options);
54
+ if (!empty($option['value'])):
55
+ $this->setTeam($option['value']);
56
+ endif;
57
+
58
+ return $options;
59
+ endif;
60
+ }
61
+
62
+ public function canEditUser()
63
+ {
64
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
65
+ if ($restrictions['user']):
66
+ return false;
67
+ endif;
68
+ endif;
69
+
70
+ return true;
71
+ }
72
+
73
+ public function filterTeamsByUser($options)
74
+ {
75
+ return Mage::helper('sirportly')->filterTeamsByUser($options);
76
+ }
77
+ }
app/code/community/HusseyCoding/Sirportly/Block/Adminhtml/Sales/Order/View/Tab/SirportlyTickets/UpdateTicket/Users.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Adminhtml_Sales_Order_View_Tab_SirportlyTickets_UpdateTicket_Users extends Mage_Adminhtml_Block_Template
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->setTemplate('sirportly/sales/order/view/tab/sirportlytickets/updateticket/users.phtml');
8
+ }
9
+
10
+ public function _beforeToHtml()
11
+ {
12
+ if ($team = $this->getRequest()->getPost('team')):
13
+ $this->setTeam((int) $team);
14
+ if ($reference = Mage::app()->getRequest()->getPost('reference')):
15
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
16
+ if (!empty($data['user'])):
17
+ $this->setUser($data['user']);
18
+ endif;
19
+ endif;
20
+ elseif ($reference = Mage::app()->getRequest()->getPost('reference')):
21
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
22
+ if (!$this->getTeam()):
23
+ if (!empty($data['team'])):
24
+ $this->setTeam($data['team']);
25
+ endif;
26
+ endif;
27
+ if (!empty($data['user'])):
28
+ $this->setUser($data['user']);
29
+ endif;
30
+ endif;
31
+ }
32
+
33
+ public function getUsers()
34
+ {
35
+ if ($this->getTeam()):
36
+ $helper = Mage::helper('sirportly');
37
+ $options = $helper->getSelectOptions('/api/v2/objects/users', false, '', array('id' => array('first_name', 'last_name')));
38
+
39
+ $options = $helper->filterUsersByTeam($options, $this->getTeam());
40
+
41
+ $user = $this->getUser();
42
+ if (!empty($user)):
43
+ foreach ($options as $option):
44
+ if ($option['value'] == $user):
45
+ array_unshift($options, array('value' => $user, 'label' => '--Unchanged--'));
46
+ break;
47
+ endif;
48
+ endforeach;
49
+ endif;
50
+
51
+ if (!$this->canEditUser()):
52
+ $options = $this->filterUsersByUser($options);
53
+ endif;
54
+
55
+ return $options;
56
+ endif;
57
+ }
58
+
59
+ public function canEditUser()
60
+ {
61
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
62
+ if ($restrictions['user']):
63
+ return false;
64
+ endif;
65
+ endif;
66
+
67
+ return true;
68
+ }
69
+
70
+ public function filterUsersByUser($options)
71
+ {
72
+ return Mage::helper('sirportly')->filterUsersByUser($options);
73
+ }
74
+ }
app/code/community/HusseyCoding/Sirportly/Block/Permissions/User/Edit/AdminhtmlTabs.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Permissions_User_Edit_AdminhtmlTabs extends Mage_Adminhtml_Block_Permissions_User_Edit_Tabs
3
+ {
4
+ protected function _beforeToHtml()
5
+ {
6
+ $this->addTabAfter('sirportly_section', array(
7
+ 'label' => Mage::helper('adminhtml')->__('Sirportly'),
8
+ 'title' => Mage::helper('adminhtml')->__('Sirportly'),
9
+ 'content' => $this->getLayout()->createBlock('sirportly/permissions_user_edit_tab_sirportly')->toHtml()
10
+ ), 'roles_section');
11
+
12
+ parent::_beforeToHtml();
13
+ }
14
+ }
app/code/community/HusseyCoding/Sirportly/Block/Permissions/User/Edit/Tab/Sirportly.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Block_Permissions_User_Edit_Tab_Sirportly extends Mage_Adminhtml_Block_Widget_Form
3
+ {
4
+
5
+ protected function _prepareForm()
6
+ {
7
+ $model = Mage::registry('permissions_user');
8
+
9
+ $form = new Varien_Data_Form();
10
+
11
+ $form->setHtmlIdPrefix('user_');
12
+
13
+ $fieldset = $form->addFieldset('sirportly_fieldset', array('legend' => Mage::helper('sirportly')->__('User Restrictions')));
14
+
15
+ $fieldset->addField('sirportly_restrict', 'select', array(
16
+ 'name' => 'sirportly_restrict',
17
+ 'label' => Mage::helper('adminhtml')->__('User Permissions'),
18
+ 'id' => 'sirportly_restrict',
19
+ 'title' => Mage::helper('adminhtml')->__('User Permissions'),
20
+ 'values' => $this->_getRestrictionSelect()
21
+ ));
22
+
23
+ $fieldset->addField('sirportly_user', 'select', array(
24
+ 'name' => 'sirportly_user',
25
+ 'label' => Mage::helper('adminhtml')->__('Sirportly User'),
26
+ 'id' => 'sirportly_user',
27
+ 'title' => Mage::helper('adminhtml')->__('Sirportly User'),
28
+ 'values' => $this->_getUserSelect()
29
+ ));
30
+
31
+ $fieldset->addField('sirportly_view', 'select', array(
32
+ 'name' => 'sirportly_view',
33
+ 'label' => Mage::helper('adminhtml')->__('View Tickets'),
34
+ 'id' => 'sirportly_view',
35
+ 'title' => Mage::helper('adminhtml')->__('View Tickets'),
36
+ 'values' => $this->_getViewSelect()
37
+ ));
38
+
39
+
40
+ $data = $model->getData();
41
+
42
+ $form->setValues($data);
43
+
44
+ $this->setForm($form);
45
+
46
+ return parent::_prepareForm();
47
+ }
48
+
49
+ private function _getRestrictionSelect()
50
+ {
51
+ return array(
52
+ array(
53
+ 'value' => 0, 'label' => 'No Permissions'
54
+ ),
55
+ array(
56
+ 'value' => 1, 'label' => 'Read Only'
57
+ ),
58
+ array(
59
+ 'value' => 2, 'label' => 'Full Permissions'
60
+ )
61
+ );
62
+ }
63
+
64
+ private function _getUserSelect()
65
+ {
66
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/users', false, '--None--', array('id' => array('first_name', 'last_name')));
67
+ }
68
+
69
+ private function _getViewSelect()
70
+ {
71
+ return array(
72
+ array(
73
+ 'value' => 0, 'label' => 'Only Assigned to User'
74
+ ),
75
+ array(
76
+ 'value' => 1, 'label' => 'Assigned to Users Team(s)'
77
+ )
78
+ );
79
+ }
80
+ }
app/code/community/HusseyCoding/Sirportly/Helper/Data.php CHANGED
@@ -2,6 +2,12 @@
2
  class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
4
  private $_verified;
 
 
 
 
 
 
5
 
6
  public function verifyCredentials($token = null, $secret = null)
7
  {
@@ -16,14 +22,16 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
16
  public function createTicket(array $data, $config = 'ticketassign')
17
  {
18
  if ($this->_canSend($data)):
19
- $status = $this->_getConfig($config, 'status');
20
- $priority = $this->_getConfig($config, 'priority');
21
- $team = $this->_getConfig($config, 'team');
22
- $department = $this->_getConfig($config, 'department');
23
 
24
  $params = array(
25
- 'name' => $data['name'],
26
- 'email' => $data['email'],
 
 
27
  'subject' => $data['subject'],
28
  'status' => $status,
29
  'priority' => $priority,
@@ -31,26 +39,127 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
31
  'department' => $department
32
  );
33
 
34
- if (!empty($data['html_body']) && !empty($data['html_safe'])):
35
- $client = $this->_getRequestObject('/api/v2/tickets/submit', $params);
36
- if ($result = $this->_sendRequest($client, true)):
37
- if (!empty($result['reference'])):
38
- $params = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  $params['html_body'] = $data['html_body'];
40
  $params['html_safe'] = $data['html_safe'];
41
  $params['message'] = $data['comment'];
42
  $params['ticket'] = $result['reference'];
43
  $client = $this->_getRequestObject('/api/v2/tickets/post_update', $params);
44
- return $this->_sendRequest($client);
 
 
 
45
  endif;
 
 
46
  endif;
47
- else:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  $params['message'] = $data['comment'];
49
- $client = $this->_getRequestObject('/api/v2/tickets/submit', $params);
50
- return $this->_sendRequest($client);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  endif;
52
  endif;
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  return false;
55
  }
56
 
@@ -116,7 +225,7 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
116
  return $sendbody ? $body : true;
117
  }
118
 
119
- public function getSelectOptions($url, $optgroup = false, $empty = '--Please Select--')
120
  {
121
  if (!$this->verifyCredentials()):
122
  return array(
@@ -133,13 +242,27 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
133
  foreach ($result as $option):
134
  if (!empty($option['name']) && !empty($option['id'])):
135
  $return[] = array('value' => $option['id'], 'label' => $option['name']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  endif;
137
  endforeach;
138
  endif;
139
  endif;
140
 
141
  if ($return):
142
- array_unshift($return, array('value' => '', 'label' => $this->__($empty)));
143
  return $return;
144
  endif;
145
  endif;
@@ -150,6 +273,81 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
150
  endif;
151
  }
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  private function _getOptGroups($options, $optgroup)
154
  {
155
  $groups = array();
@@ -177,7 +375,18 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
177
  private function _canSend($data)
178
  {
179
  if (!empty($data['name']) && !empty($data['email']) && !empty($data['subject'])):
180
- if (Mage::getStoreConfig('sirportly/ticketassign/status') && Mage::getStoreConfig('sirportly/ticketassign/priority') && Mage::getStoreConfig('sirportly/ticketassign/team') && Mage::getStoreConfig('sirportly/ticketassign/department')):
 
 
 
 
 
 
 
 
 
 
 
181
  return true;
182
  endif;
183
  endif;
@@ -185,6 +394,47 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
185
  return false;
186
  }
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  private function _getConfig($config, $field)
189
  {
190
  $return = Mage::getStoreConfig('sirportly/' . $config . '/' . $field);
@@ -193,32 +443,52 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
193
 
194
  public function getTicketsByEmail($email)
195
  {
196
- if ($id = $this->_getContactIdByEmail($email)):
197
- $params = array('contact' => $id, 'sort_by' => 'updated_at', 'order' => 'desc');
198
- $client = $this->_getRequestObject('/api/v2/tickets/contact', $params);
199
- $result = $this->_sendRequest($client, true);
200
-
201
- if (!empty($result['records'])):
202
- $tickets = $result['records'];
203
- $pages = (int) $result['pagination']['pages'];
204
- if ($pages > 1):
205
- $current = 1;
206
- while ($pages >= $current):
207
- $current++;
208
- $params = array('contact' => $id, 'sort_by' => 'updated_at', 'order' => 'desc', 'page' => $current);
209
- $client = $this->_getRequestObject('/api/v2/tickets/contact', $params);
210
- $result = $this->_sendRequest($client, true);
211
- if (!empty($result['records'])):
212
- $tickets = array_merge($tickets, $result['records']);
213
- endif;
214
-
215
- if ($current >= 10 || empty($result['records'])):
216
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  endif;
218
- endwhile;
 
 
219
  endif;
220
-
221
- return $tickets;
222
  endif;
223
  endif;
224
 
@@ -242,6 +512,249 @@ class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
242
  {
243
  $params = array('ticket' => $reference);
244
  $client = $this->_getRequestObject('/api/v2/ticket_updates/all', $params);
 
 
 
 
 
 
 
 
 
 
245
  return $this->_sendRequest($client, true);
246
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
2
  class HusseyCoding_Sirportly_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
4
  private $_verified;
5
+ private $_canchange;
6
+ private $_adminuser;
7
+ private $_userdata;
8
+ private $_restrictions;
9
+ private $_isconfigured;
10
+
11
 
12
  public function verifyCredentials($token = null, $secret = null)
13
  {
22
  public function createTicket(array $data, $config = 'ticketassign')
23
  {
24
  if ($this->_canSend($data)):
25
+ $status = !empty($data['status']) ? $data['status'] : $this->_getConfig($config, 'status');
26
+ $priority = !empty($data['priority']) ? $data['priority'] : $this->_getConfig($config, 'priority');
27
+ $team = !empty($data['team']) ? $data['team'] : $this->_getConfig($config, 'team');
28
+ $department = !empty($data['department']) ? $data['department'] : $this->_getConfig($config, 'department');
29
 
30
  $params = array(
31
+ 'contact_name' => $data['name'],
32
+ 'contact_method_type' => 'email',
33
+ 'contact_method_data' => $data['email'],
34
+ 'contact_email' => $data['email'],
35
  'subject' => $data['subject'],
36
  'status' => $status,
37
  'priority' => $priority,
39
  'department' => $department
40
  );
41
 
42
+ if (!empty($data['sla'])) $params['sla'] = $data['sla'];
43
+
44
+ $client = $this->_getRequestObject('/api/v2/tickets/submit', $params);
45
+ if ($result = $this->_sendRequest($client, true)):
46
+ if (!empty($result['reference'])):
47
+ $params = array();
48
+
49
+ if (!empty($data['notify']) && $data['notify'] == 'on'):
50
+ $client = $this->_getRequestObject('/api/v2/objects/email_addresses', array('department' => $department));
51
+ $departments = $this->_sendRequest($client, true);
52
+
53
+ if (!empty($departments['department']) && is_array($departments['department'])):
54
+ foreach ($departments['department'] as $item):
55
+ if (!empty($item['address'])):
56
+ $params['outgoing'] = $item['address'];
57
+ $params['user'] = $data['user'];
58
+ endif;
59
+ endforeach;
60
+ endif;
61
+ endif;
62
+
63
+ if (!empty($data['html_body']) && !empty($data['html_safe'])):
64
  $params['html_body'] = $data['html_body'];
65
  $params['html_safe'] = $data['html_safe'];
66
  $params['message'] = $data['comment'];
67
  $params['ticket'] = $result['reference'];
68
  $client = $this->_getRequestObject('/api/v2/tickets/post_update', $params);
69
+ else:
70
+ $params['ticket'] = $result['reference'];
71
+ $params['message'] = $data['comment'];
72
+ $client = $this->_getRequestObject('/api/v2/tickets/post_update', $params);
73
  endif;
74
+
75
+ return $this->_sendRequest($client);
76
  endif;
77
+ endif;
78
+ endif;
79
+
80
+ return false;
81
+ }
82
+
83
+ public function addUpdate(array $data)
84
+ {
85
+ $change = false;
86
+ $update = false;
87
+ if ($this->_canUpdate($data) || $this->_canChange($data)):
88
+ if ($params = $this->_canChange($data)):
89
+ $client = $this->_getRequestObject('/api/v2/tickets/update', $params);
90
+ $change = $this->_sendRequest($client);
91
+ endif;
92
+ if ($this->_canUpdate($data)):
93
+ $params = array();
94
+ $params['ticket'] = $data['ticket'];
95
  $params['message'] = $data['comment'];
96
+ $params['parse_ticket_variables'] = true;
97
+ $params['user'] = $data['user'];
98
+ if (!empty($data['subject'])) $params['subject'] = $data['subject'];
99
+ if (!empty($data['private'])) $params['private'] = true;
100
+
101
+ if (!empty($data['notify']) && $data['notify'] == 'on'):
102
+ $client = $this->_getRequestObject('/api/v2/objects/email_addresses', array('department' => $data['department']));
103
+ $result = $this->_sendRequest($client, true);
104
+
105
+ if (!empty($result['department']) && is_array($result['department'])):
106
+ foreach ($result['department'] as $department):
107
+ if (!empty($department['address'])):
108
+ $params['outgoing'] = $department['address'];
109
+ endif;
110
+ endforeach;
111
+ endif;
112
+ endif;
113
+
114
+ $client = $this->_getRequestObject('/api/v2/tickets/post_update', $params);
115
+ $update = $this->_sendRequest($client);
116
  endif;
117
  endif;
118
 
119
+ if (($this->_canChange($data) && $change) || ($this->_canUpdate($data) && $update)):
120
+ return true;
121
+ elseif ($this->_canChange($data) || $this->_canUpdate($data)):
122
+ return false;
123
+ endif;
124
+
125
+ return 'empty';
126
+ }
127
+
128
+ public function reassignTicket(array $data)
129
+ {
130
+ if ($restrictions = $this->getUserRestrictions()):
131
+ if ($restrictions['user'] && $restrictions['permissions'] == 'full'):
132
+ $change = false;
133
+ $update = false;
134
+ if ($params = $this->_canChange($data)):
135
+ $client = $this->_getRequestObject('/api/v2/tickets/update', $params);
136
+ $change = $this->_sendRequest($client);
137
+ endif;
138
+
139
+ if ($this->_canChange($data) && $change):
140
+ return true;
141
+ elseif ($this->_canChange($data)):
142
+ return false;
143
+ endif;
144
+
145
+ return 'empty';
146
+ endif;
147
+ endif;
148
+
149
+ return false;
150
+ }
151
+
152
+ public function deleteUpdate(array $data)
153
+ {
154
+ if (!empty($data['ticket']) && !empty($data['update'])):
155
+ $params = array();
156
+ $params['ticket'] = $data['ticket'];
157
+ $params['update'] = $data['update'];
158
+ $client = $this->_getRequestObject('/api/v2/ticket_updates/destroy', $params);
159
+
160
+ return $this->_sendRequest($client);
161
+ endif;
162
+
163
  return false;
164
  }
165
 
225
  return $sendbody ? $body : true;
226
  }
227
 
228
+ public function getSelectOptions($url, $optgroup = false, $empty = '--Please Select--', $keys = false)
229
  {
230
  if (!$this->verifyCredentials()):
231
  return array(
242
  foreach ($result as $option):
243
  if (!empty($option['name']) && !empty($option['id'])):
244
  $return[] = array('value' => $option['id'], 'label' => $option['name']);
245
+ elseif ($keys && is_array($keys)):
246
+ foreach ($keys as $key => $values):
247
+ if (!is_array($values)) $values = array($values);
248
+ $data = '';
249
+ foreach ($values as $value):
250
+ if (!empty($option[$value])):
251
+ $data .= $option[$value] . ' ';
252
+ endif;
253
+ endforeach;
254
+ $data = trim($data);
255
+ if ($data && $option[$key]):
256
+ $return[] = array('value' => $option[$key], 'label' => $data);
257
+ endif;
258
+ endforeach;
259
  endif;
260
  endforeach;
261
  endif;
262
  endif;
263
 
264
  if ($return):
265
+ if ($empty) array_unshift($return, array('value' => '', 'label' => $this->__($empty)));
266
  return $return;
267
  endif;
268
  endif;
273
  endif;
274
  }
275
 
276
+ public function filterUsersByTeam($options, $selectedteam)
277
+ {
278
+ $users = array();
279
+ $validusers = array();
280
+ foreach ($options as $user):
281
+ if (!empty($user['value'])) $users[] = $user['value'];
282
+ endforeach;
283
+ if ($users):
284
+ $client = $this->_getRequestObject('/api/v2/objects/teams');
285
+ if ($result = $this->_sendRequest($client, true)):
286
+ foreach ($result as $team):
287
+ if ($team['id'] == $selectedteam):
288
+ foreach ($team['users'] as $user):
289
+ $validusers[] = $user['id'];
290
+ endforeach;
291
+ break;
292
+ endif;
293
+ endforeach;
294
+ endif;
295
+
296
+ if ($validusers):
297
+ foreach ($options as $key => $user):
298
+ if (!in_array($user['value'], $validusers)):
299
+ unset($options[$key]);
300
+ endif;
301
+ endforeach;
302
+ endif;
303
+ endif;
304
+
305
+ return $options;
306
+ }
307
+
308
+ public function filterTeamsByDepartment($options, $selecteddepartment)
309
+ {
310
+ $teams = array();
311
+ $validteams = array();
312
+ foreach ($options as $team):
313
+ if (!empty($team['value'])) $teams[] = $team['value'];
314
+ endforeach;
315
+ if ($teams):
316
+ $client = $this->_getRequestObject('/api/v2/objects/departments');
317
+ if ($result = $this->_sendRequest($client, true)):
318
+ $break = false;
319
+ foreach ($result as $department):
320
+ if ($department['id'] == $selecteddepartment):
321
+ $selectedpath = $department['escalation_path']['id'];
322
+ $client = $this->_getRequestObject('/api/v2/objects/escalation_paths');
323
+ if ($result = $this->_sendRequest($client, true)):
324
+ foreach ($result as $path):
325
+ if ($path['id'] == $selectedpath):
326
+ foreach ($path['teams'] as $team):
327
+ $validteams[] = $team['id'];
328
+ endforeach;
329
+ $break = true;
330
+ break;
331
+ endif;
332
+ endforeach;
333
+ endif;
334
+ endif;
335
+ if ($break) break;
336
+ endforeach;
337
+ endif;
338
+
339
+ if ($validteams):
340
+ foreach ($options as $key => $team):
341
+ if (!in_array($team['value'], $validteams)):
342
+ unset($options[$key]);
343
+ endif;
344
+ endforeach;
345
+ endif;
346
+ endif;
347
+
348
+ return $options;
349
+ }
350
+
351
  private function _getOptGroups($options, $optgroup)
352
  {
353
  $groups = array();
375
  private function _canSend($data)
376
  {
377
  if (!empty($data['name']) && !empty($data['email']) && !empty($data['subject'])):
378
+ if ($this->_isConfigured()):
379
+ return true;
380
+ endif;
381
+ endif;
382
+
383
+ return false;
384
+ }
385
+
386
+ private function _canUpdate($data)
387
+ {
388
+ if (!empty($data['ticket']) && !empty($data['comment']) && !empty($data['user']) && !empty($data['department'])):
389
+ if ($this->_isConfigured()):
390
  return true;
391
  endif;
392
  endif;
394
  return false;
395
  }
396
 
397
+ private function _canChange($data)
398
+ {
399
+ if (!isset($this->_canchange)):
400
+ $this->_canchange = false;
401
+ $canchange = !empty($data['status']) || !empty($data['priority']) || !empty($data['department']) || !empty($data['team']) || !empty($data['user']) || !empty($data['subject']);
402
+ if (!empty($data['ticket']) && $canchange):
403
+ if ($detail = $this->getTicketDetail($data['ticket'])):
404
+ $status = !empty($data['status']) && $data['status'] != $detail['status']['id'] ? true : false;
405
+ $priority = !empty($data['priority']) && $data['priority'] != $detail['priority']['id'] ? true : false;
406
+ $department = !empty($data['department']) && $data['department'] != $detail['department']['id'] ? true : false;
407
+ $team = !empty($data['team']) && $data['team'] != $detail['team']['id'] ? true : false;
408
+ $currentsla = !empty($detail['sla']['id']) ? $detail['sla']['id'] : false;
409
+ $newsla = !empty($data['sla']) ? $data['sla'] : false;
410
+ if ($currentsla != $newsla):
411
+ $sla = true;
412
+ else:
413
+ $sla = false;
414
+ endif;
415
+ $user = !empty($data['user']) && $data['user'] != $detail['user']['id'] ? true : false;
416
+ $subject = !empty($data['subject']);
417
+ if ($status || $priority || $department || $team || $sla || $user || $subject):
418
+ $return = array();
419
+ $return['ticket'] = $data['ticket'];
420
+ if ($status) $return['status'] = $data['status'];
421
+ if ($priority) $return['priority'] = $data['priority'];
422
+ if ($department) $return['department'] = $data['department'];
423
+ if ($team) $return['team'] = $data['team'];
424
+ if ($sla) $return['sla'] = $data['sla'];
425
+ if ($user) $return['user'] = $data['user'];
426
+ if ($subject) $return['subject'] = $data['subject'];
427
+ if ($this->_isConfigured()):
428
+ $this->_canchange = $return;
429
+ endif;
430
+ endif;
431
+ endif;
432
+ endif;
433
+ endif;
434
+
435
+ return $this->_canchange;
436
+ }
437
+
438
  private function _getConfig($config, $field)
439
  {
440
  $return = Mage::getStoreConfig('sirportly/' . $config . '/' . $field);
443
 
444
  public function getTicketsByEmail($email)
445
  {
446
+ $restrictions = $this->getUserRestrictions();
447
+ if ($restrictions['permissions'] != 'none'):
448
+ if ($id = $this->_getContactIdByEmail($email)):
449
+ $params = array('contact' => $id, 'sort_by' => 'updated_at', 'order' => 'desc');
450
+ $client = $this->_getRequestObject('/api/v2/tickets/contact', $params);
451
+ $result = $this->_sendRequest($client, true);
452
+
453
+ if (!empty($result['records'])):
454
+ $tickets = $result['records'];
455
+ $pages = (int) $result['pagination']['pages'];
456
+ if ($pages > 1):
457
+ $current = 1;
458
+ while ($pages >= $current):
459
+ $current++;
460
+ $params = array('contact' => $id, 'sort_by' => 'updated_at', 'order' => 'desc', 'page' => $current);
461
+ $client = $this->_getRequestObject('/api/v2/tickets/contact', $params);
462
+ $result = $this->_sendRequest($client, true);
463
+ if (!empty($result['records'])):
464
+ $tickets = array_merge($tickets, $result['records']);
465
+ endif;
466
+
467
+ if ($current >= 10 || empty($result['records'])):
468
+ break;
469
+ endif;
470
+ endwhile;
471
+ endif;
472
+
473
+ if ($user = $restrictions['user']):
474
+ if ($restrictions['view'] == 'user'):
475
+ foreach ($tickets as $key => $ticket):
476
+ if (empty($ticket['user']['id']) || $ticket['user']['id'] != $user):
477
+ unset($tickets[$key]);
478
+ endif;
479
+ endforeach;
480
+ else:
481
+ $userdata = $this->_getUserData($user);
482
+ foreach ($tickets as $key => $ticket):
483
+ if (empty($ticket['team']['id']) || !in_array($ticket['team']['id'], $userdata['teams'])):
484
+ unset($tickets[$key]);
485
+ endif;
486
+ endforeach;
487
  endif;
488
+ endif;
489
+
490
+ return $tickets;
491
  endif;
 
 
492
  endif;
493
  endif;
494
 
512
  {
513
  $params = array('ticket' => $reference);
514
  $client = $this->_getRequestObject('/api/v2/ticket_updates/all', $params);
515
+ $result = $this->_sendRequest($client, true);
516
+
517
+ return array_reverse($result);
518
+ }
519
+
520
+ public function getTicketDetail($reference)
521
+ {
522
+ $params = array();
523
+ $params['ticket'] = $reference;
524
+ $client = $this->_getRequestObject('/api/v2/tickets/ticket', $params);
525
  return $this->_sendRequest($client, true);
526
  }
527
+
528
+ public function getTicketTeamUserDepartmentSla($reference)
529
+ {
530
+ $result = $this->getTicketDetail($reference);
531
+
532
+ $return = array();
533
+ if (!empty($result['team']['id'])):
534
+ $return['team'] = (int) $result['team']['id'];
535
+ endif;
536
+ if (!empty($result['user']['id'])):
537
+ $return['user'] = (int) $result['user']['id'];
538
+ endif;
539
+ if (!empty($result['department']['id'])):
540
+ $return['department'] = (int) $result['department']['id'];
541
+ endif;
542
+ if (!empty($result['sla']['id'])):
543
+ $return['sla'] = (int) $result['sla']['id'];
544
+ if (!empty($result['reply_due_at'])):
545
+ $return['reply'] = $this->getTimestamp($result['reply_due_at']);
546
+ endif;
547
+ if (!empty($result['resolution_due_at'])):
548
+ $return['resolution'] = $this->getTimestamp($result['resolution_due_at']);
549
+ endif;
550
+ endif;
551
+
552
+ return $return;
553
+ }
554
+
555
+ public function getTimestamp($time)
556
+ {
557
+ $time = strtotime($time);
558
+ return date('jS M, g.ia', $time);
559
+ }
560
+
561
+ public function getUserRestrictions()
562
+ {
563
+ if (!isset($this->_restrictions)):
564
+ $user = $this->_getAdminUser();
565
+ $permissions = $user->getSirportlyRestrict();
566
+ $view = $user->getSirportlyView();
567
+ $user = $user->getSirportlyUser();
568
+
569
+ $restrictions = array();
570
+
571
+ if (!empty($permissions)):
572
+ if ($permissions == 2):
573
+ $restrictions['permissions'] = 'full';
574
+ elseif ($permissions == 1):
575
+ $restrictions['permissions'] = 'read';
576
+ endif;
577
+ else:
578
+ $restrictions['permissions'] = 'none';
579
+ endif;
580
+
581
+ if (!empty($user)):
582
+ $restrictions['user'] = $user;
583
+ else:
584
+ $restrictions['user'] = false;
585
+ endif;
586
+
587
+ if (!empty($view) && $view):
588
+ $restrictions['view'] = 'team';
589
+ else:
590
+ $restrictions['view'] = 'user';
591
+ endif;
592
+
593
+ $this->_restrictions = $restrictions;
594
+ endif;
595
+
596
+ return $this->_restrictions;
597
+ }
598
+
599
+ private function _getAdminUser()
600
+ {
601
+ if (!isset($this->_adminuser)):
602
+ $user = Mage::getSingleton('admin/session')->getUser();
603
+ if ($user->getId()):
604
+ $this->_adminuser = Mage::getSingleton('admin/session')->getUser();
605
+ endif;
606
+ endif;
607
+
608
+ return $this->_adminuser;
609
+ }
610
+
611
+ private function _getUserData($userid)
612
+ {
613
+ if (!isset($this->_userdata)):
614
+ $client = $this->_getRequestObject('/api/v2/users/info', array('user' => $userid));
615
+ $user = $this->_sendRequest($client, true);
616
+ $client = $this->_getRequestObject('/api/v2/objects/escalation_paths');
617
+ $paths = $this->_sendRequest($client, true);
618
+ $client = $this->_getRequestObject('/api/v2/objects/departments');
619
+ $departments = $this->_sendRequest($client, true);
620
+
621
+ $userdata = array();
622
+ $userdata['teams'] = array();
623
+ $userdata['departments'] = array();
624
+
625
+ if (!empty($user['teams']) && is_array($user['teams'])):
626
+ foreach ($user['teams'] as $team):
627
+ $userdata['teams'][] = (int) $team['id'];
628
+ endforeach;
629
+ endif;
630
+
631
+ $validpaths = array();
632
+ foreach ($paths as $path):
633
+ if (!empty($path['teams']) && is_array($path['teams'])):
634
+ foreach ($path['teams'] as $team):
635
+ if (in_array($team['id'], $userdata['teams'])):
636
+ $validpaths[] = (int) $path['id'];
637
+ endif;
638
+ endforeach;
639
+ endif;
640
+ endforeach;
641
+
642
+ foreach ($departments as $department):
643
+ if (!empty($department['escalation_path']['id']) && in_array($department['escalation_path']['id'], $validpaths)):
644
+ $userdata['departments'][] = (int) $department['id'];
645
+ endif;
646
+ endforeach;
647
+
648
+ $this->_userdata = $userdata;
649
+ endif;
650
+
651
+ return $this->_userdata;
652
+ }
653
+
654
+ public function filterDepartmentsByUser($options)
655
+ {
656
+ if ($restrictions = $this->getUserRestrictions()):
657
+ if ($restrictions['user']):
658
+ $userdata = $this->_getUserData($restrictions['user']);
659
+ foreach ($options as $key => $option):
660
+ if (is_array($option['value'])):
661
+ foreach ($option['value'] as $k => $o):
662
+ if (!in_array($o['value'], $userdata['departments'])):
663
+ unset($options[$key]['value'][$k]);
664
+ endif;
665
+ endforeach;
666
+ if (empty($options[$key]['value'])):
667
+ unset($options[$key]);
668
+ endif;
669
+ else:
670
+ if (!in_array($option['value'], $userdata['departments'])):
671
+ unset($options[$key]);
672
+ endif;
673
+ endif;
674
+ endforeach;
675
+ endif;
676
+ endif;
677
+
678
+ return $options;
679
+ }
680
+
681
+ public function filterTeamsByUser($options)
682
+ {
683
+ if ($restrictions = $this->getUserRestrictions()):
684
+ if ($restrictions['user']):
685
+ $userdata = $this->_getUserData($restrictions['user']);
686
+ foreach ($options as $key => $option):
687
+ if (!in_array($option['value'], $userdata['teams'])):
688
+ unset($options[$key]);
689
+ endif;
690
+ endforeach;
691
+ endif;
692
+ endif;
693
+
694
+ return $options;
695
+ }
696
+
697
+ public function filterUsersByUser($options)
698
+ {
699
+ if ($restrictions = $this->getUserRestrictions()):
700
+ if ($restrictions['user']):
701
+ foreach ($options as $key => $option):
702
+ if ($option['value'] != $restrictions['user']):
703
+ unset($options[$key]);
704
+ endif;
705
+ endforeach;
706
+ endif;
707
+ endif;
708
+
709
+ return $options;
710
+ }
711
+
712
+ private function _isConfigured()
713
+ {
714
+ if (!isset($this->_isconfigured)):
715
+ $configs = array('status' => false, 'priority' => false, 'team' => false, 'department' => false);
716
+ foreach (Mage::app()->getStores() as $store):
717
+ foreach ($configs as $config => $configured):
718
+ if (!$configured):
719
+ if (Mage::getStoreConfig('sirportly/ticketassign/' . $config, $store)):
720
+ $configs[$config] = true;
721
+ endif;
722
+ endif;
723
+ endforeach;
724
+ endforeach;
725
+
726
+ $this->_isconfigured = $configs['status'] && $configs['priority'] && $configs['team'] && $configs['department'];
727
+ endif;
728
+
729
+ return $this->_isconfigured;
730
+ }
731
+
732
+ public function getResponses($department)
733
+ {
734
+ if (!$this->verifyCredentials()):
735
+ return array(
736
+ array('value' => '', 'label' => $this->__('Invalid API Credentials'))
737
+ );
738
+ else:
739
+ $client = $this->_getRequestObject('/api/v2/objects/responses', array('department' => $department));
740
+ $return = array();
741
+ if ($responses = $this->_sendRequest($client, true)):
742
+ foreach ($responses as $area):
743
+ foreach ($area as $r):
744
+ $return[] = array('value' => $r['id'], 'label' => $r['name']);
745
+ endforeach;
746
+ endforeach;
747
+
748
+ if ($return):
749
+ array_unshift($return, array('value' => '', 'label' => $this->__('--Select to Insert--')));
750
+
751
+ return $return;
752
+ endif;
753
+ endif;
754
+
755
+ return array(
756
+ array('value' => '', 'label' => $this->__('No Options Found'))
757
+ );
758
+ endif;
759
+ }
760
  }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Department/OrderScreen.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Department_OrderScreen extends HusseyCoding_Sirportly_Model_System_Config_Source_Department
3
+ {
4
+
5
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Department/PaymentFailed.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Department_PaymentFailed
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/departments', 'brand', 'Use ticket default');
7
+ }
8
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Priority/OrderScreen.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Priority_OrderScreen extends HusseyCoding_Sirportly_Model_System_Config_Source_Priority
3
+ {
4
+
5
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Priority/PaymentFailed.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Priority_PaymentFailed
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/priorities', false, 'Use ticket default');
7
+ }
8
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Sla/OrderScreen.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Sla_OrderScreen
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/slas');
7
+ }
8
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Status/OrderScreen.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Status_OrderScreen extends HusseyCoding_Sirportly_Model_System_Config_Source_Status
3
+ {
4
+
5
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Status/PaymentFailed.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Status_PaymentFailed
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/statuses', false, 'Use ticket default');
7
+ }
8
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Team/OrderScreen.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Team_OrderScreen extends HusseyCoding_Sirportly_Model_System_Config_Source_Team
3
+ {
4
+
5
+ }
app/code/community/HusseyCoding/Sirportly/Model/System/Config/Source/Team/PaymentFailed.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class HusseyCoding_Sirportly_Model_System_Config_Source_Team_PaymentFailed
3
+ {
4
+ public function toOptionArray()
5
+ {
6
+ return Mage::helper('sirportly')->getSelectOptions('/api/v2/objects/teams', false, 'Use ticket default');
7
+ }
8
+ }
app/code/community/HusseyCoding/Sirportly/controllers/Sales/OrderController.php CHANGED
@@ -16,15 +16,59 @@ class HusseyCoding_Sirportly_Sales_OrderController extends Mage_Adminhtml_Sales_
16
  public function sirportlyUpdatesAction()
17
  {
18
  $result = 'failed';
19
- $updates = false;
 
 
20
  if ($reference = $this->getRequest()->getParam('reference')):
21
- if ($updates = Mage::helper('sirportly')->getTicketUpdates($reference)):
22
- $result = 'success';
23
- $updates = $this->_buildUpdateHtml($updates);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  endif;
25
  endif;
26
 
27
- $this->getResponse()->setBody(Zend_Json::encode(array('result' => $result, 'updates' => $updates)));
28
  }
29
 
30
  private function _buildUpdateHtml($updates)
@@ -44,9 +88,138 @@ class HusseyCoding_Sirportly_Sales_OrderController extends Mage_Adminhtml_Sales_
44
  endif;
45
  $return[$count]['subject'] = $update['subject'];
46
  $return[$count]['message'] = nl2br($update['message']);
 
 
 
47
  $count++;
48
  endforeach;
49
 
50
  return $return;
51
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
16
  public function sirportlyUpdatesAction()
17
  {
18
  $result = 'failed';
19
+ $html = false;
20
+ $reference = false;
21
+ $orderid = false;
22
  if ($reference = $this->getRequest()->getParam('reference')):
23
+ if ($orderid = $this->getRequest()->getParam('orderid')):
24
+ if ($updates = Mage::helper('sirportly')->getTicketUpdates($reference)):
25
+ $result = 'success';
26
+ $updates = $this->_buildUpdateHtml($updates);
27
+
28
+ $html = '';
29
+ $subject = '';
30
+ if ($this->_canUpdate()):
31
+ $html .= '<a id="sirportly-ticket-update-' . $reference . '" href="#sirportly-ticket-update-popup-' . $reference . '">Update ticket</a>';
32
+ if ($this->_canReassign()):
33
+ $html .= '<a class="ticket-reassign" id="sirportly-ticket-reassign-' . $reference . '" href="#sirportly-ticket-reassign-popup-' . $reference . '">Reassign ticket</a>';
34
+ endif;
35
+ endif;
36
+ foreach ($updates as $update):
37
+ $html .= '<div class="ticket-update ticket-update-timestamp"><span>Timestamp:</span>' . $update['timestamp'] . '</div>';
38
+ $html .= '<div class="ticket-update ticket-update-name"><span>Author:</span>' . $update['name'] . '</div>';
39
+ $html .= '<div class="ticket-update ticket-update-subject"><span>Subject:</span>' . $update['subject'] . '</div>';
40
+ $html .= '<div class="ticket-update ticket-update-message">' . $update['message'] . '</div>';
41
+ if ($update['private'] && $update['id']):
42
+ $html .= '<div class="ticket-update-private">This is a private update</div>';
43
+ if ($this->_canUpdate()):
44
+ $html .= '<a href="javascript:void(0)" id="' . $reference . '_' . $update['id'] . '" class="ticket-update-delete">Delete</a>';
45
+ endif;
46
+ endif;
47
+ if ($update['delivered']):
48
+ $html .= '<div class="ticket-update-delivered">Delivered to customer</div>';
49
+ endif;
50
+ $subject = $update['subject'];
51
+ endforeach;
52
+
53
+ if ($this->_canUpdate()):
54
+ $updateticket = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket');
55
+ $updateticket->setReference($reference);
56
+ $updateticket->setOrderId($orderid);
57
+ $updateticket->setSubject($subject);
58
+ $html .= $updateticket->toHtml();
59
+ if ($this->_canReassign()):
60
+ $reassignticket = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket');
61
+ $reassignticket->setReference($reference);
62
+ $reassignticket->setOrderId($orderid);
63
+ $reassignticket->setSubject($subject);
64
+ $html .= $reassignticket->toHtml();
65
+ endif;
66
+ endif;
67
+ endif;
68
  endif;
69
  endif;
70
 
71
+ $this->getResponse()->setBody(Zend_Json::encode(array('result' => $result, 'html' => $html)));
72
  }
73
 
74
  private function _buildUpdateHtml($updates)
88
  endif;
89
  $return[$count]['subject'] = $update['subject'];
90
  $return[$count]['message'] = nl2br($update['message']);
91
+ $return[$count]['private'] = $update['private'];
92
+ $return[$count]['id'] = $update['id'];
93
+ $return[$count]['delivered'] = !empty($update['delivered']) && $update['delivered'] ? true : false;
94
  $count++;
95
  endforeach;
96
 
97
  return $return;
98
  }
99
+
100
+ public function sirportlyNewTicketAction()
101
+ {
102
+ if (Mage::helper('sirportly')->createTicket($this->getRequest()->getPost())):
103
+ $response = Zend_Json::encode(array('status' => 'success'));
104
+ else:
105
+ $response = Zend_Json::encode(array('status' => 'failed'));
106
+ endif;
107
+
108
+ $this->getResponse()->setBody($response);
109
+ }
110
+
111
+ public function sirportlyUpdateTicketAction()
112
+ {
113
+ $result = Mage::helper('sirportly')->addUpdate($this->getRequest()->getPost());
114
+ if ($result === 'empty'):
115
+ $response = Zend_Json::encode(array('status' => 'empty'));
116
+ elseif ($result):
117
+ $response = Zend_Json::encode(array('status' => 'success'));
118
+ else:
119
+ $response = Zend_Json::encode(array('status' => 'failed'));
120
+ endif;
121
+
122
+ $this->getResponse()->setBody($response);
123
+ }
124
+
125
+ public function sirportlyReassignTicketAction()
126
+ {
127
+ $result = Mage::helper('sirportly')->reassignTicket($this->getRequest()->getPost());
128
+ if ($result === 'empty'):
129
+ $response = Zend_Json::encode(array('status' => 'empty'));
130
+ elseif ($result):
131
+ $response = Zend_Json::encode(array('status' => 'success'));
132
+ else:
133
+ $response = Zend_Json::encode(array('status' => 'failed'));
134
+ endif;
135
+
136
+ $this->getResponse()->setBody($response);
137
+ }
138
+
139
+ public function sirportlyTeamsAction()
140
+ {
141
+ $type = $this->getRequest()->getPost("type");
142
+ if ($type == "new"):
143
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket_teams');
144
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket_users');
145
+ elseif ($type == "reassign"):
146
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket_teams');
147
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket_users');
148
+ else:
149
+ $teams = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_teams');
150
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_users');
151
+ $responses = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_responses');
152
+ endif;
153
+
154
+ $teamshtml = $teams->toHtml();
155
+ $users->setTeam($teams->getTeam());
156
+ $usershtml = $users->toHtml();
157
+
158
+ $return = array('teamshtml' => $teamshtml, 'usershtml' => $usershtml);
159
+
160
+ if (isset($responses)):
161
+ $responseshtml = $responses->toHtml();
162
+ $return['responseshtml'] = $responseshtml;
163
+ endif;
164
+
165
+ $response = Zend_Json::encode($return);
166
+
167
+ $this->getResponse()->setBody($response);
168
+ }
169
+
170
+ public function sirportlyUsersAction()
171
+ {
172
+ $type = $this->getRequest()->getPost("type");
173
+ if ($type == "new"):
174
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_newTicket_users');
175
+ elseif ($type == "reassign"):
176
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_reassignTicket_users');
177
+ else:
178
+ $users = $this->getLayout()->createBlock('sirportly/adminhtml_sales_order_view_tab_sirportlyTickets_updateTicket_users');
179
+ endif;
180
+
181
+ $this->getResponse()->setBody($users->toHtml());
182
+ }
183
+
184
+ public function sirportlyDeleteUpdateAction()
185
+ {
186
+ $result = Mage::helper('sirportly')->deleteUpdate($this->getRequest()->getPost());
187
+ if ($result):
188
+ $response = Zend_Json::encode(array('status' => 'success'));
189
+ else:
190
+ $response = Zend_Json::encode(array('status' => 'failed'));
191
+ endif;
192
+
193
+ $this->getResponse()->setBody($response);
194
+ }
195
+
196
+ private function _canUpdate()
197
+ {
198
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
199
+ if ($restrictions['permissions'] == 'full'):
200
+ return true;
201
+ endif;
202
+ endif;
203
+
204
+ return false;
205
+ }
206
+
207
+ private function _canReassign()
208
+ {
209
+ if ($restrictions = Mage::helper('sirportly')->getUserRestrictions()):
210
+ if ($restrictions['user']):
211
+ if ($restrictions['view'] == 'user'):
212
+ return true;
213
+ else:
214
+ $reference = $this->getRequest()->getParam('reference');
215
+ $data = Mage::helper('sirportly')->getTicketTeamUserDepartmentSla($reference);
216
+ if (!empty($data['user']) && $data['user'] == $restrictions['user']):
217
+ return true;
218
+ endif;
219
+ endif;
220
+ endif;
221
+ endif;
222
+
223
+ return false;
224
+ }
225
  }
app/code/community/HusseyCoding/Sirportly/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <HusseyCoding_Sirportly>
5
- <version>1.0.4</version>
6
  </HusseyCoding_Sirportly>
7
  </modules>
8
  <global>
@@ -25,7 +25,22 @@
25
  <sirportly>
26
  <class>HusseyCoding_Sirportly_Block</class>
27
  </sirportly>
 
 
 
 
 
28
  </blocks>
 
 
 
 
 
 
 
 
 
 
29
  </global>
30
  <frontend>
31
  <routers>
2
  <config>
3
  <modules>
4
  <HusseyCoding_Sirportly>
5
+ <version>1.2.1</version>
6
  </HusseyCoding_Sirportly>
7
  </modules>
8
  <global>
25
  <sirportly>
26
  <class>HusseyCoding_Sirportly_Block</class>
27
  </sirportly>
28
+ <adminhtml>
29
+ <rewrite>
30
+ <permissions_user_edit_tabs>HusseyCoding_Sirportly_Block_Permissions_User_Edit_AdminhtmlTabs</permissions_user_edit_tabs>
31
+ </rewrite>
32
+ </adminhtml>
33
  </blocks>
34
+ <resources>
35
+ <sirportly_setup>
36
+ <setup>
37
+ <module>HusseyCoding_Sirportly</module>
38
+ </setup>
39
+ <connection>
40
+ <use>core_setup</use>
41
+ </connection>
42
+ </sirportly_setup>
43
+ </resources>
44
  </global>
45
  <frontend>
46
  <routers>
app/code/community/HusseyCoding/Sirportly/etc/system.xml CHANGED
@@ -39,14 +39,33 @@
39
  </secret>
40
  </fields>
41
  </api>
42
- <ticketassign translate="label">
43
- <label>Ticket Defaults</label>
44
  <frontend_type>text</frontend_type>
45
  <sort_order>2</sort_order>
46
  <show_in_default>1</show_in_default>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  <show_in_website>1</show_in_website>
48
  <show_in_store>1</show_in_store>
49
- <comment>Here you can define a status, priority, team and department to assign new tickets to in Sirportly.</comment>
50
  <fields>
51
  <status>
52
  <label>Status</label>
@@ -68,32 +87,32 @@
68
  <source_model>sirportly/system_config_source_priority</source_model>
69
  <comment>Required</comment>
70
  </priority>
71
- <team>
72
- <label>Team</label>
73
  <frontend_type>select</frontend_type>
74
  <sort_order>3</sort_order>
75
  <show_in_default>1</show_in_default>
76
  <show_in_website>1</show_in_website>
77
  <show_in_store>1</show_in_store>
78
- <source_model>sirportly/system_config_source_team</source_model>
79
  <comment>Required</comment>
80
- </team>
81
- <department>
82
- <label>Department</label>
83
  <frontend_type>select</frontend_type>
84
  <sort_order>4</sort_order>
85
  <show_in_default>1</show_in_default>
86
  <show_in_website>1</show_in_website>
87
  <show_in_store>1</show_in_store>
88
- <source_model>sirportly/system_config_source_department</source_model>
89
  <comment>Required</comment>
90
- </department>
91
  </fields>
92
  </ticketassign>
93
  <contact translate="label">
94
- <label>Contact Form Integration</label>
95
  <frontend_type>text</frontend_type>
96
- <sort_order>3</sort_order>
97
  <show_in_default>1</show_in_default>
98
  <show_in_website>1</show_in_website>
99
  <show_in_store>1</show_in_store>
@@ -126,30 +145,30 @@
126
  <show_in_store>1</show_in_store>
127
  <source_model>sirportly/system_config_source_priority_contact</source_model>
128
  </priority>
129
- <team>
130
- <label>Team</label>
131
  <frontend_type>select</frontend_type>
132
  <sort_order>4</sort_order>
133
  <show_in_default>1</show_in_default>
134
  <show_in_website>1</show_in_website>
135
  <show_in_store>1</show_in_store>
136
- <source_model>sirportly/system_config_source_team_contact</source_model>
137
- </team>
138
- <department>
139
- <label>Department</label>
140
  <frontend_type>select</frontend_type>
141
  <sort_order>5</sort_order>
142
  <show_in_default>1</show_in_default>
143
  <show_in_website>1</show_in_website>
144
  <show_in_store>1</show_in_store>
145
- <source_model>sirportly/system_config_source_department_contact</source_model>
146
- </department>
147
  </fields>
148
  </contact>
149
  <paymentfailed translate="label">
150
- <label>Payment Failed Integration</label>
151
  <frontend_type>text</frontend_type>
152
- <sort_order>4</sort_order>
153
  <show_in_default>1</show_in_default>
154
  <show_in_website>1</show_in_website>
155
  <show_in_store>1</show_in_store>
@@ -190,7 +209,7 @@
190
  <show_in_default>1</show_in_default>
191
  <show_in_website>1</show_in_website>
192
  <show_in_store>1</show_in_store>
193
- <source_model>sirportly/system_config_source_status_contact</source_model>
194
  </status>
195
  <priority>
196
  <label>Priority</label>
@@ -199,28 +218,93 @@
199
  <show_in_default>1</show_in_default>
200
  <show_in_website>1</show_in_website>
201
  <show_in_store>1</show_in_store>
202
- <source_model>sirportly/system_config_source_priority_contact</source_model>
203
  </priority>
 
 
 
 
 
 
 
 
 
204
  <team>
205
  <label>Team</label>
206
  <frontend_type>select</frontend_type>
207
- <sort_order>6</sort_order>
208
  <show_in_default>1</show_in_default>
209
  <show_in_website>1</show_in_website>
210
  <show_in_store>1</show_in_store>
211
- <source_model>sirportly/system_config_source_team_contact</source_model>
212
  </team>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  <department>
214
  <label>Department</label>
215
  <frontend_type>select</frontend_type>
216
- <sort_order>7</sort_order>
217
  <show_in_default>1</show_in_default>
218
- <show_in_website>1</show_in_website>
219
- <show_in_store>1</show_in_store>
220
- <source_model>sirportly/system_config_source_department_contact</source_model>
221
  </department>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  </fields>
223
- </paymentfailed>
 
 
 
 
 
 
 
 
 
224
  </groups>
225
  </sirportly>
226
  </sections>
39
  </secret>
40
  </fields>
41
  </api>
42
+ <general translate="label">
43
+ <label>General Settings</label>
44
  <frontend_type>text</frontend_type>
45
  <sort_order>2</sort_order>
46
  <show_in_default>1</show_in_default>
47
+ <show_in_website>0</show_in_website>
48
+ <show_in_store>0</show_in_store>
49
+ <fields>
50
+ <domain>
51
+ <label>Sirportly Domain</label>
52
+ <frontend_type>text</frontend_type>
53
+ <sort_order>1</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>0</show_in_website>
56
+ <show_in_store>0</show_in_store>
57
+ <comment>Enter your Sirportly domain here to enable clickable links when viewing tickets e.g. domain.sirportly.com</comment>
58
+ </domain>
59
+ </fields>
60
+ </general>
61
+ <ticketassign translate="label">
62
+ <label>Frontend Ticket Defaults</label>
63
+ <frontend_type>text</frontend_type>
64
+ <sort_order>3</sort_order>
65
+ <show_in_default>1</show_in_default>
66
  <show_in_website>1</show_in_website>
67
  <show_in_store>1</show_in_store>
68
+ <comment>Here you can define a default status, priority, team and department for new Sirportly tickets which are automatically created on the frontend.</comment>
69
  <fields>
70
  <status>
71
  <label>Status</label>
87
  <source_model>sirportly/system_config_source_priority</source_model>
88
  <comment>Required</comment>
89
  </priority>
90
+ <department>
91
+ <label>Department</label>
92
  <frontend_type>select</frontend_type>
93
  <sort_order>3</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
+ <source_model>sirportly/system_config_source_department</source_model>
98
  <comment>Required</comment>
99
+ </department>
100
+ <team>
101
+ <label>Team</label>
102
  <frontend_type>select</frontend_type>
103
  <sort_order>4</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
+ <source_model>sirportly/system_config_source_team</source_model>
108
  <comment>Required</comment>
109
+ </team>
110
  </fields>
111
  </ticketassign>
112
  <contact translate="label">
113
+ <label>Frontend Contact Form Integration</label>
114
  <frontend_type>text</frontend_type>
115
+ <sort_order>4</sort_order>
116
  <show_in_default>1</show_in_default>
117
  <show_in_website>1</show_in_website>
118
  <show_in_store>1</show_in_store>
145
  <show_in_store>1</show_in_store>
146
  <source_model>sirportly/system_config_source_priority_contact</source_model>
147
  </priority>
148
+ <department>
149
+ <label>Department</label>
150
  <frontend_type>select</frontend_type>
151
  <sort_order>4</sort_order>
152
  <show_in_default>1</show_in_default>
153
  <show_in_website>1</show_in_website>
154
  <show_in_store>1</show_in_store>
155
+ <source_model>sirportly/system_config_source_department_contact</source_model>
156
+ </department>
157
+ <team>
158
+ <label>Team</label>
159
  <frontend_type>select</frontend_type>
160
  <sort_order>5</sort_order>
161
  <show_in_default>1</show_in_default>
162
  <show_in_website>1</show_in_website>
163
  <show_in_store>1</show_in_store>
164
+ <source_model>sirportly/system_config_source_team_contact</source_model>
165
+ </team>
166
  </fields>
167
  </contact>
168
  <paymentfailed translate="label">
169
+ <label>Frontend Payment Failed Integration</label>
170
  <frontend_type>text</frontend_type>
171
+ <sort_order>5</sort_order>
172
  <show_in_default>1</show_in_default>
173
  <show_in_website>1</show_in_website>
174
  <show_in_store>1</show_in_store>
209
  <show_in_default>1</show_in_default>
210
  <show_in_website>1</show_in_website>
211
  <show_in_store>1</show_in_store>
212
+ <source_model>sirportly/system_config_source_status_paymentFailed</source_model>
213
  </status>
214
  <priority>
215
  <label>Priority</label>
218
  <show_in_default>1</show_in_default>
219
  <show_in_website>1</show_in_website>
220
  <show_in_store>1</show_in_store>
221
+ <source_model>sirportly/system_config_source_priority_paymentFailed</source_model>
222
  </priority>
223
+ <department>
224
+ <label>Department</label>
225
+ <frontend_type>select</frontend_type>
226
+ <sort_order>6</sort_order>
227
+ <show_in_default>1</show_in_default>
228
+ <show_in_website>1</show_in_website>
229
+ <show_in_store>1</show_in_store>
230
+ <source_model>sirportly/system_config_source_department_paymentFailed</source_model>
231
+ </department>
232
  <team>
233
  <label>Team</label>
234
  <frontend_type>select</frontend_type>
235
+ <sort_order>7</sort_order>
236
  <show_in_default>1</show_in_default>
237
  <show_in_website>1</show_in_website>
238
  <show_in_store>1</show_in_store>
239
+ <source_model>sirportly/system_config_source_team_paymentFailed</source_model>
240
  </team>
241
+ </fields>
242
+ </paymentfailed>
243
+ <orderscreen translate="label">
244
+ <label>Admin Order Screen Ticket Defaults</label>
245
+ <frontend_type>text</frontend_type>
246
+ <sort_order>6</sort_order>
247
+ <show_in_default>1</show_in_default>
248
+ <show_in_website>0</show_in_website>
249
+ <show_in_store>0</show_in_store>
250
+ <comment>These settings apply when creating a new ticket and can be overridden.</comment>
251
+ <fields>
252
+ <status>
253
+ <label>Status</label>
254
+ <frontend_type>select</frontend_type>
255
+ <sort_order>1</sort_order>
256
+ <show_in_default>1</show_in_default>
257
+ <show_in_website>0</show_in_website>
258
+ <show_in_store>0</show_in_store>
259
+ <source_model>sirportly/system_config_source_status_orderScreen</source_model>
260
+ </status>
261
+ <priority>
262
+ <label>Priority</label>
263
+ <frontend_type>select</frontend_type>
264
+ <sort_order>2</sort_order>
265
+ <show_in_default>1</show_in_default>
266
+ <show_in_website>0</show_in_website>
267
+ <show_in_store>0</show_in_store>
268
+ <source_model>sirportly/system_config_source_priority_orderScreen</source_model>
269
+ </priority>
270
  <department>
271
  <label>Department</label>
272
  <frontend_type>select</frontend_type>
273
+ <sort_order>3</sort_order>
274
  <show_in_default>1</show_in_default>
275
+ <show_in_website>0</show_in_website>
276
+ <show_in_store>0</show_in_store>
277
+ <source_model>sirportly/system_config_source_department_orderScreen</source_model>
278
  </department>
279
+ <team>
280
+ <label>Team</label>
281
+ <frontend_type>select</frontend_type>
282
+ <sort_order>4</sort_order>
283
+ <show_in_default>1</show_in_default>
284
+ <show_in_website>0</show_in_website>
285
+ <show_in_store>0</show_in_store>
286
+ <source_model>sirportly/system_config_source_team_orderScreen</source_model>
287
+ </team>
288
+ <sla>
289
+ <label>SLA</label>
290
+ <frontend_type>select</frontend_type>
291
+ <sort_order>5</sort_order>
292
+ <show_in_default>1</show_in_default>
293
+ <show_in_website>0</show_in_website>
294
+ <show_in_store>0</show_in_store>
295
+ <source_model>sirportly/system_config_source_sla_orderScreen</source_model>
296
+ </sla>
297
  </fields>
298
+ </orderscreen>
299
+ <restrict translate="label">
300
+ <label>User Restriction</label>
301
+ <frontend_type>text</frontend_type>
302
+ <sort_order>7</sort_order>
303
+ <show_in_default>1</show_in_default>
304
+ <show_in_website>0</show_in_website>
305
+ <show_in_store>0</show_in_store>
306
+ <comment><![CDATA[<p>Associate Magento admin users to Sirportly users to restrict actions when creating or updating tickets. Restricted users can only create and update tickets as themselves.</p><p>Restricting a user can be done from the Sirportly tab when editing a user under System &rarr; Permissions &rarr; Users.</p>]]></comment>
307
+ </restrict>
308
  </groups>
309
  </sirportly>
310
  </sections>
app/code/community/HusseyCoding/Sirportly/sql/sirportly_setup/mysql4-upgrade-1.1.0-1.2.0.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+
4
+ $installer->startSetup();
5
+
6
+ $installer->getConnection()->addColumn($this->getTable('admin/user'), 'sirportly_restrict', 'TEXT NULL');
7
+ $installer->getConnection()->addColumn($this->getTable('admin/user'), 'sirportly_user', 'TEXT NULL');
8
+
9
+ $installer->endSetup();
app/code/community/HusseyCoding/Sirportly/sql/sirportly_setup/mysql4-upgrade-1.2.0-1.2.1.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+
4
+ $installer->startSetup();
5
+
6
+ $installer->getConnection()->addColumn($this->getTable('admin/user'), 'sirportly_view', 'TEXT NULL');
7
+
8
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/sirportly.xml CHANGED
@@ -8,6 +8,14 @@
8
  </action>
9
  </reference>
10
  <reference name="head">
 
 
 
 
 
 
 
 
11
  <action method="addItem">
12
  <type>skin_js</type>
13
  <name>sirportly/js/ordertickets.js</name>
8
  </action>
9
  </reference>
10
  <reference name="head">
11
+ <action method="addItem">
12
+ <type>skin_js</type>
13
+ <name>sirportly/js/livepipe.js</name>
14
+ </action>
15
+ <action method="addItem">
16
+ <type>skin_js</type>
17
+ <name>sirportly/js/window.js</name>
18
+ </action>
19
  <action method="addItem">
20
  <type>skin_js</type>
21
  <name>sirportly/js/ordertickets.js</name>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets.phtml CHANGED
@@ -5,39 +5,103 @@
5
  </h4>
6
  </div>
7
  <fieldset>
8
- <table cellspacing="10" width="100%">
9
- <colgroup>
10
- <col width="100">
11
- <col width="100">
12
- </colgroup>
13
- <thead>
14
- <tr>
15
- <th>Status</th>
16
- <th>Priority</th>
17
- <th>Subject</th>
18
- </tr>
19
- </thead>
20
- <tbody>
21
- <?php $count = 0; ?>
22
- <?php foreach ($this->getTicketsByEmail() as $ticket): ?>
23
- <?php $count++; ?>
24
- <tr class="sirportly-ticket-click" onclick="thisordertickets.getUpdates('<?php echo $ticket['reference']; ?>')">
25
- <td><?php echo $ticket['status']['name']; ?></td>
26
- <td><?php echo $ticket['priority']['name']; ?></td>
27
- <td><?php echo $ticket['subject']; ?></td>
28
  </tr>
29
- <tr id="target-<?php echo $ticket['reference']; ?>" class="sirportly-ticket-target">
30
- <td colspan="3"></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  </tr>
32
- <?php endforeach; ?>
33
- </tbody>
34
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  </fieldset>
36
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  <script type="text/javascript">
38
  //<![CDATA[
39
  var thisordertickets = new ordertickets();
40
- thisordertickets.hideTargets();
41
  thisordertickets.updateurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUpdates'); ?>";
 
 
 
 
 
 
 
 
42
  //]]>
43
  </script>
5
  </h4>
6
  </div>
7
  <fieldset>
8
+ <?php if ($this->canCreate()): ?>
9
+ <table cellspacing="10" width="100%">
10
+ <tbody>
11
+ <tr>
12
+ <td>
13
+ <a id="sirportly-ticket-new" href="#sirportly-ticket-new-popup">Create new ticket</a>
14
+ </td>
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  </tr>
16
+ </tbody>
17
+ </table>
18
+ <?php endif; ?>
19
+ <?php $tickets = $this->getTicketsByEmail(); ?>
20
+ <?php if (count($tickets)): ?>
21
+ <table cellspacing="12" width="100%">
22
+ <colgroup>
23
+ <col width="75" />
24
+ <col width="100" />
25
+ <col width="75" />
26
+ <col />
27
+ <col width="100" />
28
+ <col width="150" />
29
+ <col width="100" />
30
+ <col width="100" />
31
+ </colgroup>
32
+ <thead>
33
+ <tr class="sirportly-ticket-headings">
34
+ <th>Ticket</th>
35
+ <th>Status</th>
36
+ <th>Priority</th>
37
+ <th>Subject</th>
38
+ <th>Team</th>
39
+ <th>Department</th>
40
+ <th>User</th>
41
+ <th>SLA</th>
42
  </tr>
43
+ </thead>
44
+ <tbody>
45
+ <?php $count = 0; ?>
46
+ <?php foreach ($tickets as $ticket): ?>
47
+ <?php $count++; ?>
48
+ <tr class="sirportly-ticket-click" onclick="thisordertickets.getUpdates('<?php echo $ticket['reference']; ?>')">
49
+ <?php if ($domain = $this->getSirportlyDomain()): ?>
50
+ <td><a href="https://<?php echo $domain; ?>/staff/tickets/<?php echo $ticket['reference']; ?>" target="_blank"><?php echo $ticket['reference']; ?></a></td>
51
+ <?php else: ?>
52
+ <td><?php echo $ticket['reference']; ?></td>
53
+ <?php endif; ?>
54
+ <td><?php echo $ticket['status']['name']; ?></td>
55
+ <td><?php echo $ticket['priority']['name']; ?></td>
56
+ <td><?php echo $ticket['subject']; ?></td>
57
+ <td><?php echo !empty($ticket['team']['name']) ? $ticket['team']['name'] : ''; ?></td>
58
+ <td><?php echo !empty($ticket['department']['brand']['name']) && !empty($ticket['department']['name']) ? $ticket['department']['brand']['name'] . '&rarr;' . $ticket['department']['name'] : ''; ?></td>
59
+ <td><?php echo !empty($ticket['user']['first_name']) && !empty($ticket['user']['last_name']) ? $ticket['user']['first_name'] . ' ' . $ticket['user']['last_name'] : ''; ?></td>
60
+ <td><?php echo !empty($ticket['sla']['name']) ? $this->getSlaHtml($ticket) : ''; ?></td>
61
+ </tr>
62
+ <tr id="target-<?php echo $ticket['reference']; ?>" class="sirportly-ticket-target">
63
+ <td colspan="8"></td>
64
+ </tr>
65
+ <?php endforeach; ?>
66
+ </tbody>
67
+ </table>
68
+ <?php else: ?>
69
+ <table cellspacing="10" width="100%">
70
+ <tbody>
71
+ <tr>
72
+ <td>No tickets found for this customer.</td>
73
+ </tr>
74
+ </tbody>
75
+ </table>
76
+ <?php endif; ?>
77
  </fieldset>
78
  </div>
79
+ <?php if ($this->canCreate()): ?>
80
+ <div id="sirportly-ticket-new-popup">
81
+ <form id="sirportly-ticket-new-form" method="post" action="<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyNewTicket'); ?>">
82
+ <div class="entry-edit">
83
+ <div class="entry-edit-head">
84
+ <h4>New ticket for <?php echo $this->getCustomerName(); ?> (<?php echo $this->getCustomerEmail(); ?>)</h4>
85
+ <span class="sirportly-ticket-new-popup-close">
86
+ <a href="javascript:void(0)" onclick="Control.Modal.close()">close</a>
87
+ </span>
88
+ </div>
89
+ <fieldset><?php echo $this->getChildHtml('order_tab_sirportly_newticket') ?></fieldset>
90
+ </div>
91
+ </form>
92
+ </div>
93
+ <?php endif; ?>
94
  <script type="text/javascript">
95
  //<![CDATA[
96
  var thisordertickets = new ordertickets();
 
97
  thisordertickets.updateurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUpdates'); ?>";
98
+ thisordertickets.usersurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUsers'); ?>";
99
+ thisordertickets.teamsurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyTeams'); ?>";
100
+ thisordertickets.submitnewurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyNewTicket'); ?>";
101
+ thisordertickets.submitupdateurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUpdateTicket'); ?>";
102
+ thisordertickets.deleteupdateurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyDeleteUpdate'); ?>";
103
+ thisordertickets.reassignurl = "<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyReassignTicket'); ?>";
104
+ thisordertickets.orderid = "<?php echo Mage::registry('current_order')->getId(); ?>";
105
+ thisordertickets.afterInit();
106
  //]]>
107
  </script>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket.phtml ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table class="form-list">
2
+ <tbody>
3
+ <tr>
4
+ <td class="label">
5
+ <label for="sirportly_status">Status</label>
6
+ </td>
7
+ <td class="value">
8
+ <select id="sirportly_status" name="status">
9
+ <?php foreach ($this->getStatuses() as $status): ?>
10
+ <?php if (!empty($status['label'])): ?>
11
+ <option value="<?php echo $status['value']; ?>"><?php echo $status['label']; ?></option>
12
+ <?php endif; ?>
13
+ <?php endforeach; ?>
14
+ </select>
15
+ </td>
16
+ </tr>
17
+ <tr>
18
+ <td class="label">
19
+ <label for="sirportly_priority">Priority</label>
20
+ </td>
21
+ <td class="value">
22
+ <select id="sirportly_priority" name="priority">
23
+ <?php foreach ($this->getPriorities() as $priority): ?>
24
+ <?php if (!empty($priority['label'])): ?>
25
+ <option value="<?php echo $priority['value']; ?>"><?php echo $priority['label']; ?></option>
26
+ <?php endif; ?>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </td>
30
+ </tr>
31
+ <tr>
32
+ <td class="label">
33
+ <label for="sirportly_department">Department</label>
34
+ </td>
35
+ <td class="value">
36
+ <select id="sirportly_department" name="department" class="select">
37
+ <?php foreach ($this->getDepartments() as $department): ?>
38
+ <?php if (!empty($department['value']) && is_array($department['value']) && !empty($department['label'])): ?>
39
+ <optgroup label="<?php echo $department['label']; ?>">
40
+ <?php foreach ($department['value'] as $entry): ?>
41
+ <?php if (!empty($entry['label']) && !empty($entry['value'])): ?>
42
+ <option value="<?php echo $entry['value']; ?>"><?php echo $entry['label']; ?></option>
43
+ <?php endif; ?>
44
+ <?php endforeach; ?>
45
+ </optgroup>
46
+ <?php elseif (!empty($department['label'])): ?>
47
+ <option value="<?php echo $department['value']; ?>"><?php echo $department['label']; ?></option>
48
+ <?php endif; ?>
49
+ <?php endforeach; ?>
50
+ </select>
51
+ </td>
52
+ </tr>
53
+ <tr>
54
+ <td class="label">
55
+ <label for="sirportly_team">Team</label>
56
+ </td>
57
+ <td class="value">
58
+ <select id="sirportly_team" name="team">
59
+ <?php echo $this->getChildHtml('order_tab_sirportly_newticket_teams'); ?>
60
+ </select>
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <td class="label">
65
+ <label for="sirportly_user">User</label>
66
+ </td>
67
+ <td class="value">
68
+ <select id="sirportly_user" name="user" class="select">
69
+ <?php echo $this->getChildHtml('order_tab_sirportly_newticket_users'); ?>
70
+ </select>
71
+ </td>
72
+ </tr>
73
+ <tr>
74
+ <td class="label">
75
+ <label for="sirportly_sla">SLA</label>
76
+ </td>
77
+ <td class="value">
78
+ <select id="sirportly_sla" name="sla">
79
+ <?php foreach ($this->getSlas() as $sla): ?>
80
+ <?php if (!empty($sla['label'])): ?>
81
+ <option value="<?php echo $sla['value']; ?>"><?php echo $sla['label']; ?></option>
82
+ <?php endif; ?>
83
+ <?php endforeach; ?>
84
+ </select>
85
+ </td>
86
+ </tr>
87
+ <tr>
88
+ <td class="label">
89
+ <label for="sirportly_name">Customer Name</label>
90
+ </td>
91
+ <td class="value">
92
+ <input id="sirportly_name" type="hidden" name="name" value="<?php echo $this->getCustomerName(); ?>" />
93
+ <span><?php echo $this->getCustomerName(); ?></span>
94
+ </td>
95
+ </tr>
96
+ <tr>
97
+ <td class="label">
98
+ <label for="sirportly_email">Email Address</label>
99
+ </td>
100
+ <td class="value">
101
+ <input id="sirportly_email" type="hidden" name="email" value="<?php echo $this->getCustomerEmail(); ?>" />
102
+ <span><?php echo $this->getCustomerEmail(); ?></span>
103
+ </td>
104
+ </tr>
105
+ <tr>
106
+ <td class="label">
107
+ <label for="sirportly_subject">Subject</label>
108
+ </td>
109
+ <td class="value">
110
+ <input id="sirportly_subject" class="input-text" type="text" name="subject" />
111
+ </td>
112
+ </tr>
113
+ <tr>
114
+ <td class="label">
115
+ <label for="sirportly_comment">Comment</label>
116
+ </td>
117
+ <td class="value">
118
+ <textarea id="sirportly_comment" cols="15" rows="2" name="comment"></textarea>
119
+ </td>
120
+ </tr>
121
+ <tr>
122
+ <td class="label">
123
+ <label for="sirportly_notify">Notify Customer</label>
124
+ </td>
125
+ <td class="value">
126
+ <input id="sirportly_nootify" type="checkbox" name="notify" checked="" />
127
+ </td>
128
+ </tr>
129
+ <?php if ($this->verifyCredentials()): ?>
130
+ <tr>
131
+ <td colspan="2">
132
+ <span class="sirportly-ticket-new-popup-submit"><?php echo $this->getChildHtml('submit_button'); ?></span>
133
+ </td>
134
+ </tr>
135
+ <?php endif; ?>
136
+ </tbody>
137
+ </table>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket/teams.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getTeams() as $team): ?>
2
+ <?php if (!empty($team['label'])): ?>
3
+ <option value="<?php echo $team['value']; ?>"><?php echo $team['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/newticket/users.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getUsers() as $user): ?>
2
+ <?php if (!empty($user['label'])): ?>
3
+ <option value="<?php echo $user['value']; ?>"><?php echo $user['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket.phtml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ($this->canUpdate()): ?>
2
+ <div id="sirportly-ticket-reassign-popup-<?php echo $this->getReference(); ?>" class="sirportly-ticket-reassign-popup">
3
+ <form id="sirportly-ticket-reassign-form-<?php echo $this->getReference(); ?>" method="post" action="<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUpdateTicket'); ?>">
4
+ <div class="entry-edit">
5
+ <div class="entry-edit-head">
6
+ <h4>Reassign ticket "<?php echo $this->getSubject(); ?>"</h4>
7
+ <span class="sirportly-ticket-reassign-popup-close">
8
+ <a href="javascript:void(0)" onclick="Control.Modal.close()">close</a>
9
+ </span>
10
+ </div>
11
+ <input type="hidden" name="ticket" value="<?php echo $this->getReference(); ?>" />
12
+ <input type="hidden" name="sla" value="<?php echo $this->getSla(); ?>" />
13
+ <fieldset>
14
+ <table class="form-list">
15
+ <tbody>
16
+ <tr>
17
+ <td class="label">
18
+ <label for="sirportly_department_reassign-<?php echo $this->getReference(); ?>">Department</label>
19
+ </td>
20
+ <td class="value">
21
+ <select id="sirportly_department_reassign-<?php echo $this->getReference(); ?>" name="department" class="select">
22
+ <?php foreach ($this->getDepartments() as $department): ?>
23
+ <?php if (!empty($department['value']) && is_array($department['value']) && !empty($department['label'])): ?>
24
+ <optgroup label="<?php echo $department['label']; ?>">
25
+ <?php foreach ($department['value'] as $entry): ?>
26
+ <?php if (!empty($entry['label']) && !empty($entry['value'])): ?>
27
+ <option value="<?php echo $entry['value']; ?>"><?php echo $entry['label']; ?></option>
28
+ <?php endif; ?>
29
+ <?php endforeach; ?>
30
+ </optgroup>
31
+ <?php elseif (!empty($department['label'])): ?>
32
+ <option value="<?php echo $department['value']; ?>"><?php echo $department['label']; ?></option>
33
+ <?php endif; ?>
34
+ <?php endforeach; ?>
35
+ </select>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <td class="label">
40
+ <label for="sirportly_team_reassign-<?php echo $this->getReference(); ?>">Team</label>
41
+ </td>
42
+ <td class="value">
43
+ <select id="sirportly_team_reassign-<?php echo $this->getReference(); ?>" name="team">
44
+ <?php echo $this->getChildHtml('order_tab_sirportly_reassignticket_teams'); ?>
45
+ </select>
46
+ </td>
47
+ </tr>
48
+ <tr>
49
+ <td class="label">
50
+ <label for="sirportly_user_reassign-<?php echo $this->getReference(); ?>">User</label>
51
+ </td>
52
+ <td class="value">
53
+ <select id="sirportly_user_reassign-<?php echo $this->getReference(); ?>" name="user" class="select">
54
+ <?php echo $this->getChildHtml('order_tab_sirportly_reassignticket_users'); ?>
55
+ </select>
56
+ </td>
57
+ </tr>
58
+ <tr>
59
+ <td class="label">
60
+ <label for="sirportly_name_reassign-<?php echo $this->getReference(); ?>">Customer Name</label>
61
+ </td>
62
+ <td class="value">
63
+ <input id="sirportly_name_reassign-<?php echo $this->getReference(); ?>" type="hidden" name="name" value="<?php echo $this->getCustomerName(); ?>" />
64
+ <span><?php echo $this->getCustomerName(); ?></span>
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td class="label">
69
+ <label for="sirportly_email_reassign-<?php echo $this->getReference(); ?>">Email Address</label>
70
+ </td>
71
+ <td class="value">
72
+ <input id="sirportly_email_reassign-<?php echo $this->getReference(); ?>" type="hidden" name="email" value="<?php echo $this->getCustomerEmail(); ?>" />
73
+ <span><?php echo $this->getCustomerEmail(); ?></span>
74
+ </td>
75
+ </tr>
76
+ <?php if ($this->verifyCredentials()): ?>
77
+ <tr>
78
+ <td colspan="2">
79
+ <span class="sirportly-ticket-reassign-popup-submit sirportly-ticket-reassign-popup-submit-<?php echo $this->getReference(); ?>"><?php echo $this->getChildHtml('submit_button'); ?></span>
80
+ </td>
81
+ </tr>
82
+ <?php endif; ?>
83
+ </tbody>
84
+ </table>
85
+ </fieldset>
86
+ </div>
87
+ </form>
88
+ </div>
89
+ <?php endif; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket/teams.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getTeams() as $team): ?>
2
+ <?php if (!empty($team['label'])): ?>
3
+ <option value="<?php echo $team['value']; ?>"><?php echo $team['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/reassignticket/users.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getUsers() as $user): ?>
2
+ <?php if (!empty($user['label'])): ?>
3
+ <option value="<?php echo $user['value']; ?>"><?php echo $user['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket.phtml ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ($this->canUpdate()): ?>
2
+ <div id="sirportly-ticket-update-popup-<?php echo $this->getReference(); ?>" class="sirportly-ticket-update-popup">
3
+ <form id="sirportly-ticket-update-form-<?php echo $this->getReference(); ?>" method="post" action="<?php echo Mage::helper('adminhtml')->getUrl('sirportly/sales_order/sirportlyUpdateTicket'); ?>">
4
+ <div class="entry-edit">
5
+ <div class="entry-edit-head">
6
+ <h4>Ticket update for "<?php echo $this->getSubject(); ?>"</h4>
7
+ <span class="sirportly-ticket-update-popup-close">
8
+ <a href="javascript:void(0)" onclick="Control.Modal.close()">close</a>
9
+ </span>
10
+ </div>
11
+ <input type="hidden" name="ticket" value="<?php echo $this->getReference(); ?>" />
12
+ <fieldset>
13
+ <table class="form-list">
14
+ <tbody>
15
+ <tr>
16
+ <td class="label">
17
+ <label for="sirportly_status-<?php echo $this->getReference(); ?>">Status</label>
18
+ </td>
19
+ <td class="value">
20
+ <select id="sirportly_status-<?php echo $this->getReference(); ?>" name="status">
21
+ <?php foreach ($this->getStatuses() as $status): ?>
22
+ <?php if (!empty($status['label'])): ?>
23
+ <option value="<?php echo $status['value']; ?>"><?php echo $status['label']; ?></option>
24
+ <?php endif; ?>
25
+ <?php endforeach; ?>
26
+ </select>
27
+ </td>
28
+ </tr>
29
+ <tr>
30
+ <td class="label">
31
+ <label for="sirportly_priority-<?php echo $this->getReference(); ?>">Priority</label>
32
+ </td>
33
+ <td class="value">
34
+ <select id="sirportly_priority-<?php echo $this->getReference(); ?>" name="priority">
35
+ <?php foreach ($this->getPriorities() as $priority): ?>
36
+ <?php if (!empty($priority['label'])): ?>
37
+ <option value="<?php echo $priority['value']; ?>"><?php echo $priority['label']; ?></option>
38
+ <?php endif; ?>
39
+ <?php endforeach; ?>
40
+ </select>
41
+ </td>
42
+ </tr>
43
+ <tr>
44
+ <td class="label">
45
+ <label for="sirportly_department-<?php echo $this->getReference(); ?>">Department</label>
46
+ </td>
47
+ <td class="value">
48
+ <select id="sirportly_department-<?php echo $this->getReference(); ?>" name="department" class="select">
49
+ <?php foreach ($this->getDepartments() as $department): ?>
50
+ <?php if (!empty($department['value']) && is_array($department['value']) && !empty($department['label'])): ?>
51
+ <optgroup label="<?php echo $department['label']; ?>">
52
+ <?php foreach ($department['value'] as $entry): ?>
53
+ <?php if (!empty($entry['label']) && !empty($entry['value'])): ?>
54
+ <option value="<?php echo $entry['value']; ?>"><?php echo $entry['label']; ?></option>
55
+ <?php endif; ?>
56
+ <?php endforeach; ?>
57
+ </optgroup>
58
+ <?php elseif (!empty($department['label'])): ?>
59
+ <option value="<?php echo $department['value']; ?>"><?php echo $department['label']; ?></option>
60
+ <?php endif; ?>
61
+ <?php endforeach; ?>
62
+ </select>
63
+ </td>
64
+ </tr>
65
+ <tr>
66
+ <td class="label">
67
+ <label for="sirportly_team-<?php echo $this->getReference(); ?>">Team</label>
68
+ </td>
69
+ <td class="value">
70
+ <select id="sirportly_team-<?php echo $this->getReference(); ?>" name="team">
71
+ <?php echo $this->getChildHtml('order_tab_sirportly_updateticket_teams'); ?>
72
+ </select>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <td class="label">
77
+ <label for="sirportly_user-<?php echo $this->getReference(); ?>">User</label>
78
+ </td>
79
+ <td class="value">
80
+ <select id="sirportly_user-<?php echo $this->getReference(); ?>" name="user" class="select">
81
+ <?php echo $this->getChildHtml('order_tab_sirportly_updateticket_users'); ?>
82
+ </select>
83
+ </td>
84
+ </tr>
85
+ <tr>
86
+ <td class="label">
87
+ <label for="sirportly_sla-<?php echo $this->getReference(); ?>">SLA</label>
88
+ </td>
89
+ <td class="value">
90
+ <select id="sirportly_sla-<?php echo $this->getReference(); ?>" name="sla">
91
+ <?php foreach ($this->getSlas() as $sla): ?>
92
+ <?php if (!empty($sla['label'])): ?>
93
+ <option value="<?php echo $sla['value']; ?>"><?php echo $sla['label']; ?></option>
94
+ <?php endif; ?>
95
+ <?php endforeach; ?>
96
+ </select>
97
+ </td>
98
+ </tr>
99
+ <tr>
100
+ <td class="label">
101
+ <label for="sirportly_name-<?php echo $this->getReference(); ?>">Customer Name</label>
102
+ </td>
103
+ <td class="value">
104
+ <input id="sirportly_name-<?php echo $this->getReference(); ?>" type="hidden" name="name" value="<?php echo $this->getCustomerName(); ?>" />
105
+ <span><?php echo $this->getCustomerName(); ?></span>
106
+ </td>
107
+ </tr>
108
+ <tr>
109
+ <td class="label">
110
+ <label for="sirportly_email-<?php echo $this->getReference(); ?>">Email Address</label>
111
+ </td>
112
+ <td class="value">
113
+ <input id="sirportly_email-<?php echo $this->getReference(); ?>" type="hidden" name="email" value="<?php echo $this->getCustomerEmail(); ?>" />
114
+ <span><?php echo $this->getCustomerEmail(); ?></span>
115
+ </td>
116
+ </tr>
117
+ <tr>
118
+ <td class="label">
119
+ <label for="sirportly_subject-<?php echo $this->getReference(); ?>">Subject (optional)</label>
120
+ </td>
121
+ <td class="value">
122
+ <input id="sirportly_subject-<?php echo $this->getReference(); ?>" class="input-text" type="text" name="subject" value="" />
123
+ </td>
124
+ </tr>
125
+ <tr>
126
+ <td class="label">
127
+ <label for="sirportly_response-<?php echo $this->getReference(); ?>">Pre-defined Response</label>
128
+ </td>
129
+ <td class="value">
130
+ <select id="sirportly_response-<?php echo $this->getReference(); ?>" name="response" class="select">
131
+ <?php echo $this->getChildHtml('order_tab_sirportly_updateticket_responses'); ?>
132
+ </select>
133
+ </td>
134
+ </tr>
135
+ <tr>
136
+ <td class="label">
137
+ <label for="sirportly_comment-<?php echo $this->getReference(); ?>">Comment</label>
138
+ </td>
139
+ <td class="value">
140
+ <textarea id="sirportly_comment-<?php echo $this->getReference(); ?>" cols="15" rows="2" name="comment"></textarea>
141
+ </td>
142
+ </tr>
143
+ <tr>
144
+ <td class="label">
145
+ <label for="sirportly_notify-<?php echo $this->getReference(); ?>">Notify Customer</label>
146
+ </td>
147
+ <td class="value">
148
+ <input id="sirportly_notify-<?php echo $this->getReference(); ?>" type="checkbox" name="notify" checked="" />
149
+ </td>
150
+ </tr>
151
+ <tr>
152
+ <td class="label">
153
+ <label for="sirportly_private-<?php echo $this->getReference(); ?>">Private Update</label>
154
+ </td>
155
+ <td class="value">
156
+ <input id="sirportly_private-<?php echo $this->getReference(); ?>" type="checkbox" name="private" />
157
+ </td>
158
+ </tr>
159
+ <?php if ($this->verifyCredentials()): ?>
160
+ <tr>
161
+ <td colspan="2">
162
+ <span class="sirportly-ticket-update-popup-submit sirportly-ticket-update-popup-submit-<?php echo $this->getReference(); ?>"><?php echo $this->getChildHtml('submit_button'); ?></span>
163
+ </td>
164
+ </tr>
165
+ <?php endif; ?>
166
+ </tbody>
167
+ </table>
168
+ </fieldset>
169
+ </div>
170
+ </form>
171
+ </div>
172
+ <?php endif; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/responses.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getResponses() as $response): ?>
2
+ <?php if (!empty($response['label'])): ?>
3
+ <option value="<?php echo $response['value']; ?>"><?php echo $response['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/teams.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getTeams() as $team): ?>
2
+ <?php if (!empty($team['label'])): ?>
3
+ <option value="<?php echo $team['value']; ?>"><?php echo $team['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
app/design/adminhtml/default/default/template/sirportly/sales/order/view/tab/sirportlytickets/updateticket/users.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php foreach ($this->getUsers() as $user): ?>
2
+ <?php if (!empty($user['label'])): ?>
3
+ <option value="<?php echo $user['value']; ?>"><?php echo $user['label'] ?></option>
4
+ <?php endif; ?>
5
+ <?php endforeach; ?>
package.xml CHANGED
@@ -1,18 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HusseyCoding_Sirportly</name>
4
- <version>1.0.4</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Magento to Sirportly integration.</summary>
10
- <description>Create Sirportly helpdesk tickets via the Magento contact form, and when payments fail. Also view customer tickets on the admin order view page.</description>
11
- <notes>Checked 1.8.1.0 CE compatibility, fixed contact form ticket creation when using store code in URL's</notes>
12
  <authors><author><name>Hussey Coding</name><user>husseycoding</user><email>info@husseycoding.co.uk</email></author></authors>
13
- <date>2013-12-18</date>
14
- <time>13:32:45</time>
15
- <contents><target name="magecommunity"><dir name="HusseyCoding"><dir name="Sirportly"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="View"><dir name="Tab"><file name="SirportlyTickets.php" hash="9a4bdbc45f0b1fe4fbd8de88db5bbb1a"/></dir></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Sales"><file name="OrderController.php" hash="4fdf8bd73ce40473934063ec68207328"/></dir><file name="TicketController.php" hash="c3e74986c4d7c79a02a0a8df2564e174"/></dir><dir name="etc"><file name="adminhtml.xml" hash="31ce0056778c58c2430b0b2cccb9b1a5"/><file name="config.xml" hash="54ef89e676c474e6fc85f4f3ec0a501d"/><file name="system.xml" hash="af6f7f8ac461ac21ada683270f124ad9"/></dir><dir name="Helper"><file name="CheckoutData.php" hash="08531cf50917af39a587802e3876a5f3"/><file name="Data.php" hash="f1eed8b19d4b368faf1021d6be35dc5a"/></dir><dir name="Model"><file name="Observer.php" hash="a14e57ea58ba025f62483efd650b55fa"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Department"><file name="Contact.php" hash="681e7d40a46fec9fc43690b298fc18d6"/></dir><file name="Department.php" hash="f8a708f2e042365bd892bfd1f392fec3"/><dir name="Priority"><file name="Contact.php" hash="3415f060eac9c459afc1b0cef7b0a028"/></dir><file name="Priority.php" hash="682065ee3cdcab991e5fd252730c8640"/><dir name="Status"><file name="Contact.php" hash="47d7f3976f25eff30a2ef816a6682e26"/></dir><file name="Status.php" hash="60fd06d1743463ad345afa2cb1827e9d"/><dir name="Team"><file name="Contact.php" hash="d851dd72b7278cf1b755c8bfba869bcc"/></dir><file name="Team.php" hash="1b1fc5cfb6c50a74a57aba2252f43874"/></dir></dir></dir></dir></dir><dir name="Common"><dir name="etc"><file name="system.xml" hash="6c9ba9f227b9adfc9abf97f17b46fdbf"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="HusseyCoding_Sirportly.xml" hash="a92236145783da6931bf04a2028ae285"/><file name="HusseyCoding_Common.xml" hash="31e82d3d9b3179c2fa9e002f9669da47"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="sirportly.xml" hash="60e4095bd8f1dcf51c3ae0c2daa70147"/></dir><dir name="template"><dir name="sirportly"><file name="contact.phtml" hash="6ccfad5b873caa4801fbc8196ec23ee8"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="sirportly.xml" hash="9a18dd5ee50b5fcefd4fcd0d8429df82"/></dir><dir name="template"><dir name="sirportly"><dir name="sales"><dir name="order"><dir name="view"><dir name="tab"><file name="sirportlytickets.phtml" hash="5cb478d71bc9c8a086372725f815ccc2"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><file name="sirportlysubmit.js" hash="879ecd9e6065fb6dc062d5af452d0832"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="sirportly"><dir name="css"><file name="ordertickets.css" hash="4cb89484b761ab95958207f29cc1e689"/></dir><dir name="js"><file name="ordertickets.js" hash="d040a67d7bb5e9b0f69a1b85c56be2e4"/></dir></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>HusseyCoding_Sirportly</name>
4
+ <version>1.2.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Magento to Sirportly integration.</summary>
10
+ <description>Manage Sirportly ticketing directly from the admin sales page. Create and update ticket, grant permissions to Magento users, create tickets via the contact form, and when payments fail. </description>
11
+ <notes>Added admin ticket creation and updating</notes>
12
  <authors><author><name>Hussey Coding</name><user>husseycoding</user><email>info@husseycoding.co.uk</email></author></authors>
13
+ <date>2014-02-11</date>
14
+ <time>18:26:55</time>
15
+ <contents><target name="magecommunity"><dir name="HusseyCoding"><dir name="Sirportly"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="View"><dir name="Tab"><dir name="SirportlyTickets"><dir name="NewTicket"><file name="Teams.php" hash="f7a7f65e8625cf3b9058445bf0d8f3e3"/><file name="Users.php" hash="d7a716593560c6878eb66fc430c42235"/></dir><file name="NewTicket.php" hash="f8518605ca4e2be3d016c81758134aef"/><dir name="ReassignTicket"><file name="Teams.php" hash="f3111cf57e6cb963551b9d472274ef68"/><file name="Users.php" hash="1a93cc06137c1a8aae950f997780fdc7"/></dir><file name="ReassignTicket.php" hash="929da4c55aaedae15016910d041a8ed3"/><dir name="UpdateTicket"><file name="Responses.php" hash="0ad06db1985f628f3068abd0f3687f7a"/><file name="Teams.php" hash="57d50af8d240bb61a5f9510b31e471e0"/><file name="Users.php" hash="aee610ed1f056a3f024c3c30e6c92f13"/></dir><file name="UpdateTicket.php" hash="074fa76c1bbe0620b978d9c522da21c9"/></dir><file name="SirportlyTickets.php" hash="0258475df4adf2bfd750d0815c7fc558"/></dir></dir></dir></dir></dir><dir name="Permissions"><dir name="User"><dir name="Edit"><file name="AdminhtmlTabs.php" hash="b4ff2343bfcc9f0a0c23bc00b6907dcc"/><dir name="Tab"><file name="Sirportly.php" hash="7962c4aaaf22b2bc7af482c39ee058f8"/></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Sales"><file name="OrderController.php" hash="df9f32c2cf4c72807866e1413aa1c1ed"/></dir><file name="TicketController.php" hash="c3e74986c4d7c79a02a0a8df2564e174"/></dir><dir name="etc"><file name="adminhtml.xml" hash="31ce0056778c58c2430b0b2cccb9b1a5"/><file name="config.xml" hash="7d52651aecdd4c810ff22e05f0ca98ad"/><file name="system.xml" hash="a8681fcf0fdaa93cc7c853e65d3bd751"/></dir><dir name="Helper"><file name="CheckoutData.php" hash="08531cf50917af39a587802e3876a5f3"/><file name="Data.php" hash="8567dd97865170fde4c2858d0201e49f"/></dir><dir name="Model"><file name="Observer.php" hash="a14e57ea58ba025f62483efd650b55fa"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Department"><file name="Contact.php" hash="681e7d40a46fec9fc43690b298fc18d6"/><file name="OrderScreen.php" hash="8366770dddb56bbeaf601ed9dc5ba8d5"/><file name="PaymentFailed.php" hash="3b575ab12bb25c32aec4c62fef6febcd"/></dir><file name="Department.php" hash="f8a708f2e042365bd892bfd1f392fec3"/><dir name="Priority"><file name="Contact.php" hash="3415f060eac9c459afc1b0cef7b0a028"/><file name="OrderScreen.php" hash="bba6bc6ce4a79e95feb1470ea7455665"/><file name="PaymentFailed.php" hash="9b251fc35bc2bbc3299a8c1cfc8109c7"/></dir><file name="Priority.php" hash="682065ee3cdcab991e5fd252730c8640"/><dir name="Sla"><file name="OrderScreen.php" hash="1c3dd6fcca20564d2b6f869c723fc936"/></dir><dir name="Status"><file name="Contact.php" hash="47d7f3976f25eff30a2ef816a6682e26"/><file name="OrderScreen.php" hash="f29f5c9314e4e26fbabced9573c2e822"/><file name="PaymentFailed.php" hash="8d625f92c1b5c5119017443b5ad42ff4"/></dir><file name="Status.php" hash="60fd06d1743463ad345afa2cb1827e9d"/><dir name="Team"><file name="Contact.php" hash="d851dd72b7278cf1b755c8bfba869bcc"/><file name="OrderScreen.php" hash="6fdf9a9fe1ab6b6ff3124763012d0845"/><file name="PaymentFailed.php" hash="a54aff316e6f9357c7bc8c1e283cf306"/></dir><file name="Team.php" hash="1b1fc5cfb6c50a74a57aba2252f43874"/></dir></dir></dir></dir><dir name="sql"><dir name="sirportly_setup"><file name="mysql4-upgrade-1.1.0-1.2.0.php" hash="d6e621d7c0bbc250d42637fcc96749c5"/><file name="mysql4-upgrade-1.2.0-1.2.1.php" hash="b936b0b9063cf18faa50cfea6b29ffad"/></dir></dir></dir><dir name="Common"><dir name="etc"><file name="system.xml" hash="6c9ba9f227b9adfc9abf97f17b46fdbf"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="HusseyCoding_Sirportly.xml" hash="a92236145783da6931bf04a2028ae285"/><file name="HusseyCoding_Common.xml" hash="31e82d3d9b3179c2fa9e002f9669da47"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="sirportly.xml" hash="60e4095bd8f1dcf51c3ae0c2daa70147"/></dir><dir name="template"><dir name="sirportly"><file name="contact.phtml" hash="6ccfad5b873caa4801fbc8196ec23ee8"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="sirportly.xml" hash="b0818879173a4b0b7fc94d9a790a42ab"/></dir><dir name="template"><dir name="sirportly"><dir name="sales"><dir name="order"><dir name="view"><dir name="tab"><dir name="sirportlytickets"><dir name="newticket"><file name="teams.phtml" hash="ee72d305c9a0f2a1c24b9cd170b647f3"/><file name="users.phtml" hash="c7517e0a90187ecda3d6283b20cb35f5"/></dir><file name="newticket.phtml" hash="154b6063eee86a3f81e9f2d2260476c2"/><dir name="reassignticket"><file name="teams.phtml" hash="ee72d305c9a0f2a1c24b9cd170b647f3"/><file name="users.phtml" hash="c7517e0a90187ecda3d6283b20cb35f5"/></dir><file name="reassignticket.phtml" hash="be508dc8e0cab5cde8af3ed3ca4d3478"/><dir name="updateticket"><file name="responses.phtml" hash="5728d3cc7ac676b23fab4009d5c69eb3"/><file name="teams.phtml" hash="ee72d305c9a0f2a1c24b9cd170b647f3"/><file name="users.phtml" hash="c7517e0a90187ecda3d6283b20cb35f5"/></dir><file name="updateticket.phtml" hash="d5cb94378bedc6b6c85d765c3de1fe71"/></dir><file name="sirportlytickets.phtml" hash="18699fd5f0ec829f1e9198783375602e"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><file name="sirportlysubmit.js" hash="879ecd9e6065fb6dc062d5af452d0832"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="sirportly"><dir name="css"><file name="ordertickets.css" hash="c67409ea88574c5213fa0885fba6dab6"/></dir><dir name="js"><file name="livepipe.js" hash="417ba064736fed2772778641f66555c0"/><file name="ordertickets.js" hash="66e78fc30ae7e40141474b8502446b8d"/><file name="window.js" hash="f6eba488d6a80e05f59d97a0cef59730"/></dir></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
skin/adminhtml/default/default/sirportly/css/ordertickets.css CHANGED
@@ -2,4 +2,26 @@
2
  .sirportly-ticket-target td { padding:15px; border:1px solid #e3e3e3; }
3
  .sirportly-ticket-target .ticket-update span { font-weight:bold; width:100px; display:inline-block; }
4
  .sirportly-ticket-target .ticket-update-subject { margin-bottom:5px; }
5
- .sirportly-ticket-target .ticket-update-message { margin-bottom:10px; padding-bottom:10px; border-bottom:1px solid #e3e3e3; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  .sirportly-ticket-target td { padding:15px; border:1px solid #e3e3e3; }
3
  .sirportly-ticket-target .ticket-update span { font-weight:bold; width:100px; display:inline-block; }
4
  .sirportly-ticket-target .ticket-update-subject { margin-bottom:5px; }
5
+ .sirportly-ticket-target .ticket-update-timestamp { margin-top:10px; padding-top:10px; border-top:1px solid #e3e3e3; }
6
+ .sirportly-ticket-target .ticket-update-private { color:#d40707; margin-top:5px; }
7
+ .sirportly-ticket-target .ticket-update-delivered { color:#3d6611; margin-top:5px; }
8
+ .sirportly-ticket-target .ticket-update-delete { margin-top:5px; }
9
+ .sirportly-ticket-target .ticket-reassign { margin-left:20px; }
10
+ .sirportly-ticket-click .ticket-update-sla { font-size:0.9em; margin-top:2px; }
11
+ .sirportly-ticket-click .ticket-update-overdue { color:#d40707; }
12
+ #sirportly-ticket-new-popup { background-color:#fff; border:1px solid #000; padding:10px; }
13
+ #sirportly-ticket-new-popup fieldset { margin:0; }
14
+ #sirportly-ticket-new-popup .sirportly-ticket-new-popup-close { float:right; }
15
+ #sirportly-ticket-new-popup .sirportly-ticket-new-popup-submit { float:right; padding-top:10px; }
16
+ .sirportly-ticket-update-popup { background-color:#fff; border:1px solid #000; padding:10px; }
17
+ .sirportly-ticket-update-popup fieldset { margin:0; }
18
+ .sirportly-ticket-update-popup .sirportly-ticket-update-popup-close { float:right; }
19
+ .sirportly-ticket-update-popup .sirportly-ticket-update-popup-submit { float:right; padding-top:10px; }
20
+ .sirportly-ticket-target .sirportly-ticket-update-popup td { border-width:0; padding:0; }
21
+ .sirportly-ticket-reassign-popup { background-color:#fff; border:1px solid #000; padding:10px; }
22
+ .sirportly-ticket-reassign-popup fieldset { margin:0; }
23
+ .sirportly-ticket-reassign-popup .sirportly-ticket-reassign-popup-close { float:right; }
24
+ .sirportly-ticket-reassign-popup .sirportly-ticket-reassign-popup-submit { float:right; padding-top:10px; }
25
+ .sirportly-ticket-target .sirportly-ticket-reassign-popup td { border-width:0; padding:0; }
26
+ #control_overlay { background-color:#000; }
27
+ #loading-mask { z-index:11000; }
skin/adminhtml/default/default/sirportly/js/livepipe.js ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author Ryan Johnson <http://syntacticx.com/>
3
+ * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
4
+ * @package LivePipe UI
5
+ * @license MIT
6
+ * @url http://livepipe.net/core
7
+ * @require prototype.js
8
+ */
9
+
10
+ if(typeof(Control) == 'undefined')
11
+ Control = {};
12
+
13
+ var $proc = function(proc){
14
+ return typeof(proc) == 'function' ? proc : function(){return proc};
15
+ };
16
+
17
+ var $value = function(value){
18
+ return typeof(value) == 'function' ? value() : value;
19
+ };
20
+
21
+ Object.Event = {
22
+ extend: function(object){
23
+ object._objectEventSetup = function(event_name){
24
+ this._observers = this._observers || {};
25
+ this._observers[event_name] = this._observers[event_name] || [];
26
+ };
27
+ object.observe = function(event_name,observer){
28
+ if(typeof(event_name) == 'string' && typeof(observer) != 'undefined'){
29
+ this._objectEventSetup(event_name);
30
+ if(!this._observers[event_name].include(observer))
31
+ this._observers[event_name].push(observer);
32
+ }else
33
+ for(var e in event_name)
34
+ this.observe(e,event_name[e]);
35
+ };
36
+ object.stopObserving = function(event_name,observer){
37
+ this._objectEventSetup(event_name);
38
+ if(event_name && observer)
39
+ this._observers[event_name] = this._observers[event_name].without(observer);
40
+ else if(event_name)
41
+ this._observers[event_name] = [];
42
+ else
43
+ this._observers = {};
44
+ };
45
+ object.observeOnce = function(event_name,outer_observer){
46
+ var inner_observer = function(){
47
+ outer_observer.apply(this,arguments);
48
+ this.stopObserving(event_name,inner_observer);
49
+ }.bind(this);
50
+ this._objectEventSetup(event_name);
51
+ this._observers[event_name].push(inner_observer);
52
+ };
53
+ object.notify = function(event_name){
54
+ this._objectEventSetup(event_name);
55
+ var collected_return_values = [];
56
+ var args = $A(arguments).slice(1);
57
+ try{
58
+ for(var i = 0; i < this._observers[event_name].length; ++i)
59
+ collected_return_values.push(this._observers[event_name][i].apply(this,args) || null);
60
+ }catch(e){
61
+ if(e == $break)
62
+ return false;
63
+ else
64
+ throw e;
65
+ }
66
+ return collected_return_values;
67
+ };
68
+ if(object.prototype){
69
+ object.prototype._objectEventSetup = object._objectEventSetup;
70
+ object.prototype.observe = object.observe;
71
+ object.prototype.stopObserving = object.stopObserving;
72
+ object.prototype.observeOnce = object.observeOnce;
73
+ object.prototype.notify = function(event_name){
74
+ if(object.notify){
75
+ var args = $A(arguments).slice(1);
76
+ args.unshift(this);
77
+ args.unshift(event_name);
78
+ object.notify.apply(object,args);
79
+ }
80
+ this._objectEventSetup(event_name);
81
+ var args = $A(arguments).slice(1);
82
+ var collected_return_values = [];
83
+ try{
84
+ if(this.options && this.options[event_name] && typeof(this.options[event_name]) == 'function')
85
+ collected_return_values.push(this.options[event_name].apply(this,args) || null);
86
+ var callbacks_copy = this._observers[event_name]; // since original array will be modified after observeOnce calls
87
+ for(var i = 0; i < callbacks_copy.length; ++i)
88
+ collected_return_values.push(callbacks_copy[i].apply(this,args) || null);
89
+ }catch(e){
90
+ if(e == $break)
91
+ return false;
92
+ else
93
+ throw e;
94
+ }
95
+ return collected_return_values;
96
+ };
97
+ }
98
+ }
99
+ };
100
+
101
+ /* Begin Core Extensions */
102
+
103
+ //Element.observeOnce
104
+ Element.addMethods({
105
+ observeOnce: function(element,event_name,outer_callback){
106
+ var inner_callback = function(){
107
+ outer_callback.apply(this,arguments);
108
+ Element.stopObserving(element,event_name,inner_callback);
109
+ };
110
+ Element.observe(element,event_name,inner_callback);
111
+ }
112
+ });
113
+
114
+ //mouse:wheel
115
+ (function(){
116
+ function wheel(event){
117
+ var delta, element, custom_event;
118
+ // normalize the delta
119
+ if (event.wheelDelta) { // IE & Opera
120
+ delta = event.wheelDelta / 120;
121
+ } else if (event.detail) { // W3C
122
+ delta =- event.detail / 3;
123
+ }
124
+ if (!delta) { return; }
125
+ element = Event.extend(event).target;
126
+ element = Element.extend(element.nodeType === Node.TEXT_NODE ? element.parentNode : element);
127
+ custom_event = element.fire('mouse:wheel',{ delta: delta });
128
+ if (custom_event.stopped) {
129
+ Event.stop(event);
130
+ return false;
131
+ }
132
+ }
133
+ document.observe('mousewheel',wheel);
134
+ document.observe('DOMMouseScroll',wheel);
135
+ })();
136
+
137
+ /* End Core Extensions */
138
+
139
+ //from PrototypeUI
140
+ var IframeShim = Class.create({
141
+ initialize: function() {
142
+ this.element = new Element('iframe',{
143
+ style: 'position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);display:none',
144
+ src: 'javascript:void(0);',
145
+ frameborder: 0
146
+ });
147
+ $(document.body).insert(this.element);
148
+ },
149
+ hide: function() {
150
+ this.element.hide();
151
+ return this;
152
+ },
153
+ show: function() {
154
+ this.element.show();
155
+ return this;
156
+ },
157
+ positionUnder: function(element) {
158
+ var element = $(element);
159
+ var offset = element.cumulativeOffset();
160
+ var dimensions = element.getDimensions();
161
+ this.element.setStyle({
162
+ left: offset[0] + 'px',
163
+ top: offset[1] + 'px',
164
+ width: dimensions.width + 'px',
165
+ height: dimensions.height + 'px',
166
+ zIndex: element.getStyle('zIndex') - 1
167
+ }).show();
168
+ return this;
169
+ },
170
+ setBounds: function(bounds) {
171
+ for(prop in bounds)
172
+ bounds[prop] += 'px';
173
+ this.element.setStyle(bounds);
174
+ return this;
175
+ },
176
+ destroy: function() {
177
+ if(this.element)
178
+ this.element.remove();
179
+ return this;
180
+ }
181
+ });
skin/adminhtml/default/default/sirportly/js/ordertickets.js CHANGED
@@ -1,4 +1,21 @@
1
  var ordertickets = Class.create({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  showTarget: function(reference) {
3
  $("target-" + reference).show();
4
  },
@@ -19,15 +36,20 @@ var ordertickets = Class.create({
19
  },
20
  getUpdates: function(reference) {
21
  if (this.shouldUpdate(reference)) {
22
- var parameters = {reference:reference};
23
  new Ajax.Request(this.updateurl, {
24
  parameters: parameters,
25
  onSuccess: function(response) {
26
  var contentarray = response.responseText.evalJSON();
27
  if (typeof(contentarray) == "object") {
28
  if (contentarray.result == "success") {
29
- var updates = contentarray.updates;
30
- this.updateTicket(reference, updates);
 
 
 
 
 
31
  } else {
32
  alert("Failed to get updates!")
33
  }
@@ -38,15 +60,317 @@ var ordertickets = Class.create({
38
  this.hideTarget(reference);
39
  }
40
  },
41
- updateTicket: function(reference, updates) {
42
- var html = "";
43
- updates.each(function(e) {
44
- html += "<div class=\"ticket-update ticket-update-timestamp\"><span>Timestamp:</span>" + e.timestamp + "</div>";
45
- html += "<div class=\"ticket-update ticket-update-name\"><span>Author:</span>" + e.name + "</div>";
46
- html += "<div class=\"ticket-update ticket-update-subject\"><span>Subject:</span>" + e.subject + "</div>";
47
- html += "<div class=\"ticket-update ticket-update-message\">" + e.message + "</div>";
48
- }.bind(this));
49
  $("target-" + reference).down().update(html);
50
  this.showTarget(reference);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
  });
1
  var ordertickets = Class.create({
2
+ initialize: function() {
3
+ this.currentreference = '';
4
+ this.hideTargets();
5
+ if ($("sirportly-ticket-new")) {
6
+ this.createNewModal();
7
+ this.addNewLinkListener();
8
+ this.addDepartmentListener("new");
9
+ this.addTeamListener("new");
10
+ this.addSubmitNewListener();
11
+ this.addSubjectListener();
12
+ this.addCommentListener();
13
+ this.disableSubmit();
14
+ }
15
+ },
16
+ afterInit: function() {
17
+ this.openTicket();
18
+ },
19
  showTarget: function(reference) {
20
  $("target-" + reference).show();
21
  },
36
  },
37
  getUpdates: function(reference) {
38
  if (this.shouldUpdate(reference)) {
39
+ var parameters = { reference:reference, orderid:this.orderid };
40
  new Ajax.Request(this.updateurl, {
41
  parameters: parameters,
42
  onSuccess: function(response) {
43
  var contentarray = response.responseText.evalJSON();
44
  if (typeof(contentarray) == "object") {
45
  if (contentarray.result == "success") {
46
+ var html = contentarray.html;
47
+ this.updateTicket(reference, html);
48
+ this.createUpdateModal(reference);
49
+ this.createReassignModal(reference);
50
+ this.currentreference = "-" + reference;
51
+ this.addUpdateListeners(reference);
52
+ this.addReassignListeners(reference);
53
  } else {
54
  alert("Failed to get updates!")
55
  }
60
  this.hideTarget(reference);
61
  }
62
  },
63
+ updateTicket: function(reference, html) {
 
 
 
 
 
 
 
64
  $("target-" + reference).down().update(html);
65
  this.showTarget(reference);
66
+ },
67
+ createNewModal: function() {
68
+ new Control.Modal($("sirportly-ticket-new"), {
69
+ overlayOpacity:0.2,
70
+ position:"relative",
71
+ fade:true,
72
+ closeOnClick:false,
73
+ draggable:"sirportly-ticket-new-popup"
74
+ });
75
+ },
76
+ createUpdateModal: function(reference) {
77
+ if ($("sirportly-ticket-update-" + reference)) {
78
+ new Control.Modal($("sirportly-ticket-update-" + reference), {
79
+ overlayOpacity:0.2,
80
+ position:"relative",
81
+ fade:true,
82
+ closeOnClick:false,
83
+ draggable:"sirportly-ticket-update-popup"
84
+ });
85
+ }
86
+ },
87
+ createReassignModal: function(reference) {
88
+ if ($("sirportly-ticket-reassign-" + reference)) {
89
+ new Control.Modal($("sirportly-ticket-reassign-" + reference), {
90
+ overlayOpacity:0.2,
91
+ position:"relative",
92
+ fade:true,
93
+ closeOnClick:false,
94
+ draggable:"sirportly-ticket-reassign-popup"
95
+ });
96
+ }
97
+ },
98
+ addDepartmentListener: function(type, reassign) {
99
+ if (reassign) {
100
+ var append = "_reassign";
101
+ } else {
102
+ var append = "";
103
+ }
104
+ $("sirportly_department" + append + this.currentreference).observe("change", function(e) {
105
+ e.target.disable();
106
+ var reference = this.currentreference.substring(1);
107
+ var parameters = { department:e.target.value, reference:reference, type:type };
108
+ $("sirportly_team" + append + this.currentreference).disable();
109
+ $("sirportly_user" + append + this.currentreference).disable();
110
+ if ($("sirportly_response" + append + this.currentreference)) {
111
+ $("sirportly_response" + append + this.currentreference).disable();
112
+ }
113
+ this.disableSubmit(reassign);
114
+ new Ajax.Request(this.teamsurl, {
115
+ parameters: parameters,
116
+ onSuccess: function(response) {
117
+ var contentarray = response.responseText.evalJSON();
118
+ if (contentarray.teamshtml) {
119
+ $("sirportly_team" + append + this.currentreference).update(contentarray.teamshtml);
120
+ $("sirportly_team" + append + this.currentreference).enable();
121
+ }
122
+ if (contentarray.usershtml) {
123
+ $("sirportly_user" + append + this.currentreference).update(contentarray.usershtml);
124
+ $("sirportly_user" + append + this.currentreference).enable();
125
+ }
126
+ if (contentarray.responseshtml) {
127
+ $("sirportly_response" + this.currentreference).update(contentarray.responseshtml);
128
+ $("sirportly_response" + this.currentreference).enable();
129
+ $("sirportly_comment" + this.currentreference).clear();
130
+ }
131
+ this.enableSubmit(reassign);
132
+ e.target.enable();
133
+ }.bind(this)
134
+ });
135
+ }.bind(this));
136
+ },
137
+ addTeamListener: function(type, reassign) {
138
+ if (reassign) {
139
+ var append = "_reassign";
140
+ } else {
141
+ var append = "";
142
+ }
143
+ $("sirportly_team" + append + this.currentreference).observe("change", function(e) {
144
+ e.target.disable();
145
+ var reference = this.currentreference.substring(1);
146
+ var parameters = { team:e.target.value, reference:reference, type:type };
147
+ $("sirportly_user" + append + this.currentreference).disable();
148
+ this.disableSubmit(true);
149
+ new Ajax.Request(this.usersurl, {
150
+ parameters: parameters,
151
+ onSuccess: function(response) {
152
+ $("sirportly_user" + append + this.currentreference).update(response.responseText);
153
+ $("sirportly_user" + append + this.currentreference).enable();
154
+ this.enableSubmit(true);
155
+ e.target.enable();
156
+ }.bind(this)
157
+ });
158
+ }.bind(this));
159
+ },
160
+ addSubmitNewListener: function() {
161
+ $$("span.sirportly-ticket-new-popup-submit")[0].down().observe("click", function(e) {
162
+ this.disableSubmit();
163
+ var parameters = $("sirportly-ticket-new-form").serialize(true);
164
+ new Ajax.Request(this.submitnewurl, {
165
+ parameters: parameters,
166
+ onSuccess: function(response) {
167
+ var contentarray = response.responseText.evalJSON();
168
+ if (typeof(contentarray) == "object") {
169
+ if (contentarray.status == "success") {
170
+ this.enableSubmit();
171
+ this.clearForm();
172
+ Control.Modal.close()
173
+ varienTabs.prototype.showTabContent($("sales_order_view_tabs_sirportly_tickets"));
174
+ } else {
175
+ this.enableSubmit();
176
+ alert("Failed to create ticket!")
177
+ }
178
+ }
179
+ }.bind(this)
180
+ });
181
+ }.bind(this));
182
+ },
183
+ addSubmitUpdateListener: function() {
184
+ $$("span.sirportly-ticket-update-popup-submit" + this.currentreference)[0].down().observe("click", function(e) {
185
+ this.disableSubmit();
186
+ var parameters = $("sirportly-ticket-update-form" + this.currentreference).serialize(true);
187
+ new Ajax.Request(this.submitupdateurl, {
188
+ parameters: parameters,
189
+ onSuccess: function(response) {
190
+ var contentarray = response.responseText.evalJSON();
191
+ if (typeof(contentarray) == "object") {
192
+ if (contentarray.status == "success") {
193
+ this.enableSubmit();
194
+ this.clearForm();
195
+ Control.Modal.close();
196
+ window.ticketreference = this.currentreference.substring(1);
197
+ varienTabs.prototype.showTabContent($("sales_order_view_tabs_sirportly_tickets"));
198
+ } else {
199
+ this.enableSubmit();
200
+ if (contentarray.status == 'empty') {
201
+ alert("Nothing to update!");
202
+ } else {
203
+ alert("Failed to update ticket!");
204
+ }
205
+ }
206
+ }
207
+ }.bind(this)
208
+ });
209
+ }.bind(this));
210
+ },
211
+ addSubmitReassignListener: function() {
212
+ $$("span.sirportly-ticket-reassign-popup-submit" + this.currentreference)[0].down().observe("click", function(e) {
213
+ this.disableSubmit(true);
214
+ var parameters = $("sirportly-ticket-reassign-form" + this.currentreference).serialize(true);
215
+ new Ajax.Request(this.reassignurl, {
216
+ parameters: parameters,
217
+ onSuccess: function(response) {
218
+ var contentarray = response.responseText.evalJSON();
219
+ if (typeof(contentarray) == "object") {
220
+ if (contentarray.status == "success") {
221
+ this.enableSubmit(true);
222
+ Control.Modal.close();
223
+ window.ticketreference = this.currentreference.substring(1);
224
+ varienTabs.prototype.showTabContent($("sales_order_view_tabs_sirportly_tickets"));
225
+ } else {
226
+ this.enableSubmit(true);
227
+ if (contentarray.status == 'empty') {
228
+ alert("Selections unchanged, cannot reassign!");
229
+ } else {
230
+ alert("Failed to reassign ticket!");
231
+ }
232
+ }
233
+ }
234
+ }.bind(this)
235
+ });
236
+ }.bind(this));
237
+ },
238
+ addSubjectListener: function() {
239
+ $("sirportly_subject").observe("keyup", function(e) {
240
+ this.enableSubmit();
241
+ }.bind(this));
242
+ },
243
+ addCommentListener: function() {
244
+ $("sirportly_comment" + this.currentreference).observe("keyup", function(e) {
245
+ this.enableSubmit();
246
+ }.bind(this));
247
+ },
248
+ disableSubmit: function(reassign) {
249
+ if (this.currentreference) {
250
+ if (reassign) {
251
+ var submit = $$("span.sirportly-ticket-reassign-popup-submit" + this.currentreference)[0].down();
252
+ } else {
253
+ var submit = $$("span.sirportly-ticket-update-popup-submit" + this.currentreference)[0].down();
254
+ }
255
+ } else {
256
+ var submit = $$("span.sirportly-ticket-new-popup-submit")[0].down();
257
+ }
258
+ submit.disable();
259
+ submit.setOpacity(0.5);
260
+ },
261
+ enableSubmit: function(reassign) {
262
+ if (this.currentreference) {
263
+ if (reassign) {
264
+ var submit = $$("span.sirportly-ticket-reassign-popup-submit" + this.currentreference)[0].down();
265
+ } else {
266
+ var submit = $$("span.sirportly-ticket-update-popup-submit" + this.currentreference)[0].down();
267
+ }
268
+ submit.enable();
269
+ submit.setOpacity(1);
270
+ } else {
271
+ if ($("sirportly_subject").value && $("sirportly_comment").value) {
272
+ var submit = $$("span.sirportly-ticket-new-popup-submit" + this.currentreference)[0].down();
273
+ submit.enable();
274
+ submit.setOpacity(1);
275
+ } else {
276
+ this.disableSubmit();
277
+ }
278
+ }
279
+ },
280
+ clearForm: function() {
281
+ $("sirportly_subject" + this.currentreference).value = "";
282
+ $("sirportly_comment" + this.currentreference).value = "";
283
+ },
284
+ addUpdateListeners: function(reference) {
285
+ if ($("sirportly-ticket-update-" + reference)) {
286
+ this.addDepartmentListener("update");
287
+ this.addTeamListener("update");
288
+ this.addSubmitUpdateListener();
289
+ this.addCommentListener();
290
+ this.addUpdateLinkListener(reference);
291
+ this.addUpdateDeleteListener();
292
+ this.addPrivateCheckboxListener();
293
+ this.addResponseListener();
294
+ }
295
+ },
296
+ addReassignListeners: function(reference) {
297
+ if ($("sirportly-ticket-reassign-" + reference)) {
298
+ this.addDepartmentListener("reassign", true);
299
+ this.addTeamListener("reassign", true);
300
+ this.addSubmitReassignListener();
301
+ this.addReassignLinkListener(reference);
302
+ }
303
+ },
304
+ addUpdateLinkListener: function(reference) {
305
+ $("sirportly-ticket-update-" + reference).observe("click", function(e) {
306
+ var reference = e.target.id;
307
+ reference = reference.replace("sirportly-ticket-update", "");
308
+ this.currentreference = reference;
309
+ }.bind(this));
310
+ },
311
+ addReassignLinkListener: function(reference) {
312
+ $("sirportly-ticket-reassign-" + reference).observe("click", function(e) {
313
+ var reference = e.target.id;
314
+ reference = reference.replace("sirportly-ticket-reassign", "");
315
+ this.currentreference = reference;
316
+ }.bind(this));
317
+ },
318
+ addUpdateDeleteListener: function() {
319
+ $$("a.ticket-update-delete").each(function(el) {
320
+ el.observe("click", function(e) {
321
+ if (confirm("Are you sure?")) {
322
+ var ticket = e.target.id.split("_");
323
+ var update = ticket.pop();
324
+ ticket = ticket.pop();
325
+ var parameters = { ticket:ticket, update:update };
326
+ new Ajax.Request(this.deleteupdateurl, {
327
+ parameters: parameters,
328
+ onSuccess: function(response) {
329
+ var contentarray = response.responseText.evalJSON();
330
+ if (typeof(contentarray) == "object") {
331
+ if (contentarray.status == "success") {
332
+ this.hideTarget(ticket);
333
+ this.getUpdates(ticket);
334
+ } else {
335
+ alert("Failed to delete update!");
336
+ }
337
+ }
338
+ }.bind(this)
339
+ });
340
+ }
341
+ }.bind(this));
342
+ }.bind(this));
343
+ },
344
+ addNewLinkListener: function() {
345
+ $("sirportly-ticket-new").observe("click", function(e) {
346
+ this.currentreference = "";
347
+ }.bind(this));
348
+ },
349
+ openTicket: function() {
350
+ if (window.ticketreference) {
351
+ if ($("target-" + window.ticketreference)) {
352
+ this.getUpdates(window.ticketreference);
353
+ }
354
+ window.ticketreference = null;
355
+ }
356
+ },
357
+ addPrivateCheckboxListener: function() {
358
+ $("sirportly_private" + this.currentreference).observe("change", function(e) {
359
+ if (e.target.checked) {
360
+ var notify = $("sirportly_notify" + this.currentreference);
361
+ notify.checked = false;
362
+ notify.disable();
363
+ } else {
364
+ $("sirportly_notify" + this.currentreference).enable();
365
+ }
366
+ }.bind(this));
367
+ },
368
+ addResponseListener: function() {
369
+ $("sirportly_response" + this.currentreference).observe("change", function(e) {
370
+ if (e.target.value) {
371
+ $("sirportly_comment" + this.currentreference).value += "{{response." + e.target.value + "}}";
372
+ e.target.clear();
373
+ }
374
+ }.bind(this));
375
  }
376
  });
skin/adminhtml/default/default/sirportly/js/window.js ADDED
@@ -0,0 +1,947 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * @author Ryan Johnson <http://syntacticx.com/>
3
+ * @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
4
+ * @package LivePipe UI
5
+ * @license MIT
6
+ * @url http://livepipe.net/control/window
7
+ * @require prototype.js, effects.js, draggable.js, resizable.js, livepipe.js
8
+ */
9
+
10
+ //adds onDraw and constrainToViewport option to draggable
11
+ if(typeof(Draggable) != 'undefined'){
12
+ //allows the point to be modified with an onDraw callback
13
+ Draggable.prototype.draw = function(point) {
14
+ var pos = Position.cumulativeOffset(this.element);
15
+ if(this.options.ghosting) {
16
+ var r = Position.realOffset(this.element);
17
+ pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
18
+ }
19
+
20
+ var d = this.currentDelta();
21
+ pos[0] -= d[0]; pos[1] -= d[1];
22
+
23
+ if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
24
+ pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
25
+ pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
26
+ }
27
+
28
+ var p = [0,1].map(function(i){
29
+ return (point[i]-pos[i]-this.offset[i])
30
+ }.bind(this));
31
+
32
+ if(this.options.snap) {
33
+ if(typeof this.options.snap == 'function') {
34
+ p = this.options.snap(p[0],p[1],this);
35
+ } else {
36
+ if(this.options.snap instanceof Array) {
37
+ p = p.map( function(v, i) {return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
38
+ } else {
39
+ p = p.map( function(v) {return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
40
+ }
41
+ }
42
+ }
43
+
44
+ if(this.options.onDraw)
45
+ this.options.onDraw.bind(this)(p);
46
+ else{
47
+ var style = this.element.style;
48
+ if(this.options.constrainToViewport){
49
+ var viewport_dimensions = document.viewport.getDimensions();
50
+ var container_dimensions = this.element.getDimensions();
51
+ var margin_top = parseInt(this.element.getStyle('margin-top'));
52
+ var margin_left = parseInt(this.element.getStyle('margin-left'));
53
+ var boundary = [[
54
+ 0 - margin_left,
55
+ 0 - margin_top
56
+ ],[
57
+ (viewport_dimensions.width - container_dimensions.width) - margin_left,
58
+ (viewport_dimensions.height - container_dimensions.height) - margin_top
59
+ ]];
60
+ if((!this.options.constraint) || (this.options.constraint=='horizontal')){
61
+ if((p[0] >= boundary[0][0]) && (p[0] <= boundary[1][0]))
62
+ this.element.style.left = p[0] + "px";
63
+ else
64
+ this.element.style.left = ((p[0] < boundary[0][0]) ? boundary[0][0] : boundary[1][0]) + "px";
65
+ }
66
+ if((!this.options.constraint) || (this.options.constraint=='vertical')){
67
+ if((p[1] >= boundary[0][1] ) && (p[1] <= boundary[1][1]))
68
+ this.element.style.top = p[1] + "px";
69
+ else
70
+ this.element.style.top = ((p[1] <= boundary[0][1]) ? boundary[0][1] : boundary[1][1]) + "px";
71
+ }
72
+ }else{
73
+ if((!this.options.constraint) || (this.options.constraint=='horizontal'))
74
+ style.left = p[0] + "px";
75
+ if((!this.options.constraint) || (this.options.constraint=='vertical'))
76
+ style.top = p[1] + "px";
77
+ }
78
+ if(style.visibility=="hidden")
79
+ style.visibility = ""; // fix gecko rendering
80
+ }
81
+ };
82
+ }
83
+
84
+ if(typeof(Prototype) == "undefined")
85
+ throw "Control.Window requires Prototype to be loaded.";
86
+ if(typeof(IframeShim) == "undefined")
87
+ throw "Control.Window requires IframeShim to be loaded.";
88
+ if(typeof(Object.Event) == "undefined")
89
+ throw "Control.Window requires Object.Event to be loaded.";
90
+ /*
91
+ known issues:
92
+ - when iframe is clicked is does not gain focus
93
+ - safari can't open multiple iframes properly
94
+ - constrainToViewport: body must have no margin or padding for this to work properly
95
+ - iframe will be mis positioned during fade in
96
+ - document.viewport does not account for scrollbars (this will eventually be fixed in the prototype core)
97
+ notes
98
+ - setting constrainToViewport only works when the page is not scrollable
99
+ - setting draggable: true will negate the effects of position: center
100
+ */
101
+ Control.Window = Class.create({
102
+ initialize: function(container,options){
103
+ Control.Window.windows.push(this);
104
+
105
+ //attribute initialization
106
+ this.container = false;
107
+ this.isOpen = false;
108
+ this.href = false;
109
+ this.sourceContainer = false; //this is optionally the container that will open the window
110
+ this.ajaxRequest = false;
111
+ this.remoteContentLoaded = false; //this is set when the code to load the remote content is run, onRemoteContentLoaded is fired when the connection is closed
112
+ this.numberInSequence = Control.Window.windows.length + 1; //only useful for the effect scoping
113
+ this.indicator = false;
114
+ this.effects = {
115
+ fade: false,
116
+ appear: false
117
+ };
118
+ this.indicatorEffects = {
119
+ fade: false,
120
+ appear: false
121
+ };
122
+
123
+ //options
124
+ this.options = Object.extend({
125
+ //lifecycle
126
+ beforeOpen: Prototype.emptyFunction,
127
+ afterOpen: Prototype.emptyFunction,
128
+ beforeClose: Prototype.emptyFunction,
129
+ afterClose: Prototype.emptyFunction,
130
+ //dimensions and modes
131
+ height: null,
132
+ width: null,
133
+ className: false,
134
+ position: 'center', //'center', 'center_once', 'relative', [x,y], [function(){return x;},function(){return y;}]
135
+ offsetLeft: 0, //available only for anchors opening the window, or windows set to position: hover
136
+ offsetTop: 0, //""
137
+ iframe: false, //if the window has an href, this will display the href as an iframe instead of requesting the url as an an Ajax.Request
138
+ hover: false, //element object to hover over, or if "true" only available for windows with sourceContainer (an anchor or any element already on the page with an href attribute)
139
+ indicator: false, //element to show or hide when ajax requests, images and iframes are loading
140
+ closeOnClick: false, //does not work with hover,can be: true (click anywhere), 'container' (will refer to this.container), or element (a specific element)
141
+ iframeshim: true, //whether or not to position an iFrameShim underneath the window
142
+ //effects
143
+ fade: false,
144
+ fadeDuration: 0.75,
145
+ //draggable
146
+ draggable: false,
147
+ onDrag: Prototype.emptyFunction,
148
+ //resizable
149
+ resizable: false,
150
+ minHeight: false,
151
+ minWidth: false,
152
+ maxHeight: false,
153
+ maxWidth: false,
154
+ onResize: Prototype.emptyFunction,
155
+ //draggable and resizable
156
+ constrainToViewport: false,
157
+ //ajax
158
+ method: 'post',
159
+ parameters: {},
160
+ onComplete: Prototype.emptyFunction,
161
+ onSuccess: Prototype.emptyFunction,
162
+ onFailure: Prototype.emptyFunction,
163
+ onException: Prototype.emptyFunction,
164
+ //any element with an href (image,iframe,ajax) will call this after it is done loading
165
+ onRemoteContentLoaded: Prototype.emptyFunction,
166
+ insertRemoteContentAt: false //false will set this to this.container, can be string selector (first returned will be selected), or an Element that must be a child of this.container
167
+ },options || {});
168
+
169
+ //container setup
170
+ this.indicator = this.options.indicator ? $(this.options.indicator) : false;
171
+ if(container){
172
+ if(typeof(container) == "string" && container.match(Control.Window.uriRegex))
173
+ this.href = container;
174
+ else{
175
+ this.container = $(container);
176
+ //need to create the container now for tooltips (or hover: element with no container already on the page)
177
+ //second call made below will not create the container since the check is done inside createDefaultContainer()
178
+ this.createDefaultContainer(container);
179
+ //if an element with an href was passed in we use it to activate the window
180
+ if(this.container && ((this.container.readAttribute('href') && this.container.readAttribute('href') != '') || (this.options.hover && this.options.hover !== true))){
181
+ if(this.options.hover && this.options.hover !== true)
182
+ this.sourceContainer = $(this.options.hover);
183
+ else{
184
+ this.sourceContainer = this.container;
185
+ this.href = this.container.readAttribute('href');
186
+ var rel = this.href.match(/^#(.+)$/);
187
+ if(rel && rel[1]){
188
+ this.container = $(rel[1]);
189
+ this.href = false;
190
+ }else
191
+ this.container = false;
192
+ }
193
+ //hover or click handling
194
+ this.sourceContainerOpenHandler = function(event){
195
+ this.open(event);
196
+ event.stop();
197
+ return false;
198
+ }.bindAsEventListener(this);
199
+ this.sourceContainerCloseHandler = function(event){
200
+ this.close(event);
201
+ }.bindAsEventListener(this);
202
+ this.sourceContainerMouseMoveHandler = function(event){
203
+ this.position(event);
204
+ }.bindAsEventListener(this);
205
+ if(this.options.hover){
206
+ this.sourceContainer.observe('mouseenter',this.sourceContainerOpenHandler);
207
+ this.sourceContainer.observe('mouseleave',this.sourceContainerCloseHandler);
208
+ if(this.options.position == 'mouse')
209
+ this.sourceContainer.observe('mousemove',this.sourceContainerMouseMoveHandler);
210
+ }else
211
+ this.sourceContainer.observe('click',this.sourceContainerOpenHandler);
212
+ }
213
+ }
214
+ }
215
+ this.createDefaultContainer(container);
216
+ if(this.options.insertRemoteContentAt === false)
217
+ this.options.insertRemoteContentAt = this.container;
218
+ var styles = {
219
+ margin: 0,
220
+ position: 'absolute',
221
+ zIndex: Control.Window.initialZIndexForWindow()
222
+ };
223
+ if(this.options.width)
224
+ styles.width = $value(this.options.width) + 'px';
225
+ if(this.options.height)
226
+ styles.height = $value(this.options.height) + 'px';
227
+ this.container.setStyle(styles);
228
+ if(this.options.className)
229
+ this.container.addClassName(this.options.className);
230
+ this.positionHandler = this.position.bindAsEventListener(this);
231
+ this.outOfBoundsPositionHandler = this.ensureInBounds.bindAsEventListener(this);
232
+ this.bringToFrontHandler = this.bringToFront.bindAsEventListener(this);
233
+ this.container.observe('mousedown',this.bringToFrontHandler);
234
+ this.container.hide();
235
+ this.closeHandler = this.close.bindAsEventListener(this);
236
+ //iframeshim setup
237
+ if(this.options.iframeshim){
238
+ this.iFrameShim = new IframeShim();
239
+ this.iFrameShim.hide();
240
+ }
241
+ //resizable support
242
+ this.applyResizable();
243
+ //draggable support
244
+ this.applyDraggable();
245
+
246
+ //makes sure the window can't go out of bounds
247
+ Event.observe(window,'resize',this.outOfBoundsPositionHandler);
248
+
249
+ this.notify('afterInitialize');
250
+ },
251
+ open: function(event){
252
+ if(this.isOpen){
253
+ this.bringToFront();
254
+ return false;
255
+ }
256
+ if(this.notify('beforeOpen') === false)
257
+ return false;
258
+ //closeOnClick
259
+ if(this.options.closeOnClick){
260
+ if(this.options.closeOnClick === true)
261
+ this.closeOnClickContainer = $(document.body);
262
+ else if(this.options.closeOnClick == 'container')
263
+ this.closeOnClickContainer = this.container;
264
+ else if (this.options.closeOnClick == 'overlay'){
265
+ Control.Overlay.load();
266
+ this.closeOnClickContainer = Control.Overlay.container;
267
+ }else
268
+ this.closeOnClickContainer = $(this.options.closeOnClick);
269
+ this.closeOnClickContainer.observe('click',this.closeHandler);
270
+ }
271
+ if(this.href && !this.options.iframe && !this.remoteContentLoaded){
272
+ //link to image
273
+ this.remoteContentLoaded = true;
274
+ if(this.href.match(/\.(jpe?g|gif|png|tiff?)$/i)){
275
+ var img = new Element('img');
276
+ img.observe('load',function(img){
277
+ this.getRemoteContentInsertionTarget().insert(img);
278
+ this.position();
279
+ if(this.notify('onRemoteContentLoaded') !== false){
280
+ if(this.options.indicator)
281
+ this.hideIndicator();
282
+ this.finishOpen();
283
+ }
284
+ }.bind(this,img));
285
+ img.writeAttribute('src',this.href);
286
+ }else{
287
+ //if this is an ajax window it will only open if the request is successful
288
+ if(!this.ajaxRequest){
289
+ if(this.options.indicator)
290
+ this.showIndicator();
291
+ this.ajaxRequest = new Ajax.Request(this.href,{
292
+ method: this.options.method,
293
+ parameters: this.options.parameters,
294
+ onComplete: function(request){
295
+ this.notify('onComplete',request);
296
+ this.ajaxRequest = false;
297
+ }.bind(this),
298
+ onSuccess: function(request){
299
+ this.getRemoteContentInsertionTarget().insert(request.responseText);
300
+ this.notify('onSuccess',request);
301
+ if(this.notify('onRemoteContentLoaded') !== false){
302
+ if(this.options.indicator)
303
+ this.hideIndicator();
304
+ this.finishOpen();
305
+ }
306
+ }.bind(this),
307
+ onFailure: function(request){
308
+ this.notify('onFailure',request);
309
+ if(this.options.indicator)
310
+ this.hideIndicator();
311
+ }.bind(this),
312
+ onException: function(request,e){
313
+ this.notify('onException',request,e);
314
+ if(this.options.indicator)
315
+ this.hideIndicator();
316
+ }.bind(this)
317
+ });
318
+ }
319
+ }
320
+ return true;
321
+ }else if(this.options.iframe && !this.remoteContentLoaded){
322
+ //iframe
323
+ this.remoteContentLoaded = true;
324
+ if(this.options.indicator)
325
+ this.showIndicator();
326
+ this.getRemoteContentInsertionTarget().insert(Control.Window.iframeTemplate.evaluate({
327
+ href: this.href
328
+ }));
329
+ var iframe = this.container.down('iframe');
330
+ iframe.onload = function(){
331
+ this.notify('onRemoteContentLoaded');
332
+ if(this.options.indicator)
333
+ this.hideIndicator();
334
+ iframe.onload = null;
335
+ }.bind(this);
336
+ }
337
+ this.finishOpen(event);
338
+ return true
339
+ },
340
+ close: function(event){ //event may or may not be present
341
+ if(!this.isOpen || this.notify('beforeClose',event) === false)
342
+ return false;
343
+ if(this.options.closeOnClick)
344
+ this.closeOnClickContainer.stopObserving('click',this.closeHandler);
345
+ if(this.options.fade){
346
+ this.effects.fade = new Effect.Fade(this.container,{
347
+ queue: {
348
+ position: 'front',
349
+ scope: 'Control.Window' + this.numberInSequence
350
+ },
351
+ from: 1,
352
+ to: 0,
353
+ duration: this.options.fadeDuration / 2,
354
+ afterFinish: function(){
355
+ if(this.iFrameShim)
356
+ this.iFrameShim.hide();
357
+ this.isOpen = false;
358
+ this.notify('afterClose');
359
+ }.bind(this)
360
+ });
361
+ }else{
362
+ this.container.hide();
363
+ if(this.iFrameShim)
364
+ this.iFrameShim.hide();
365
+ }
366
+ if(this.ajaxRequest)
367
+ this.ajaxRequest.transport.abort();
368
+ if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
369
+ Event.stopObserving(window,'resize',this.positionHandler);
370
+ if(!this.options.draggable && this.options.position == 'center')
371
+ Event.stopObserving(window,'scroll',this.positionHandler);
372
+ if(this.options.indicator)
373
+ this.hideIndicator();
374
+ if(!this.options.fade){
375
+ this.isOpen = false;
376
+ this.notify('afterClose');
377
+ }
378
+ return true;
379
+ },
380
+ position: function(event){
381
+ //this is up top for performance reasons
382
+ if(this.options.position == 'mouse'){
383
+ var xy = [Event.pointerX(event),Event.pointerY(event)];
384
+ this.container.setStyle({
385
+ top: xy[1] + $value(this.options.offsetTop) + 'px',
386
+ left: xy[0] + $value(this.options.offsetLeft) + 'px'
387
+ });
388
+ return;
389
+ }
390
+ var container_dimensions = this.container.getDimensions();
391
+ var viewport_dimensions = document.viewport.getDimensions();
392
+ Position.prepare();
393
+ var offset_left = (Position.deltaX + Math.floor((viewport_dimensions.width - container_dimensions.width) / 2));
394
+ var offset_top = (Position.deltaY + ((viewport_dimensions.height > container_dimensions.height) ? Math.floor((viewport_dimensions.height - container_dimensions.height) / 2) : 0));
395
+ if(this.options.position == 'center' || this.options.position == 'center_once'){
396
+ this.container.setStyle({
397
+ top: (container_dimensions.height <= viewport_dimensions.height) ? ((offset_top != null && offset_top > 0) ? offset_top : 0) + 'px' : 0,
398
+ left: (container_dimensions.width <= viewport_dimensions.width) ? ((offset_left != null && offset_left > 0) ? offset_left : 0) + 'px' : 0
399
+ });
400
+ }else if(this.options.position == 'relative'){
401
+ var xy = this.sourceContainer.cumulativeOffset();
402
+ var top = xy[1] + $value(this.options.offsetTop);
403
+ var left = xy[0] + $value(this.options.offsetLeft);
404
+ this.container.setStyle({
405
+ top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
406
+ left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
407
+ });
408
+ }else if(this.options.position.length){
409
+ var top = $value(this.options.position[1]) + $value(this.options.offsetTop);
410
+ var left = $value(this.options.position[0]) + $value(this.options.offsetLeft);
411
+ this.container.setStyle({
412
+ top: (container_dimensions.height <= viewport_dimensions.height) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.height - (container_dimensions.height),top)) : top) + 'px' : 0,
413
+ left: (container_dimensions.width <= viewport_dimensions.width) ? (this.options.constrainToViewport ? Math.max(0,Math.min(viewport_dimensions.width - (container_dimensions.width),left)) : left) + 'px' : 0
414
+ });
415
+ }
416
+ if(this.iFrameShim)
417
+ this.updateIFrameShimZIndex();
418
+ },
419
+ ensureInBounds: function(){
420
+ if(!this.isOpen)
421
+ return;
422
+ var viewport_dimensions = document.viewport.getDimensions();
423
+ var container_offset = this.container.cumulativeOffset();
424
+ var container_dimensions = this.container.getDimensions();
425
+ if(container_offset.left + container_dimensions.width > viewport_dimensions.width){
426
+ this.container.setStyle({
427
+ left: (Math.max(0,viewport_dimensions.width - container_dimensions.width)) + 'px'
428
+ });
429
+ }
430
+ if(container_offset.top + container_dimensions.height > viewport_dimensions.height){
431
+ this.container.setStyle({
432
+ top: (Math.max(0,viewport_dimensions.height - container_dimensions.height)) + 'px'
433
+ });
434
+ }
435
+ },
436
+ bringToFront: function(){
437
+ Control.Window.bringToFront(this);
438
+ this.notify('bringToFront');
439
+ },
440
+ destroy: function(){
441
+ this.container.stopObserving('mousedown',this.bringToFrontHandler);
442
+ if(this.draggable){
443
+ Draggables.removeObserver(this.container);
444
+ this.draggable.handle.stopObserving('mousedown',this.bringToFrontHandler);
445
+ this.draggable.destroy();
446
+ }
447
+ if(this.resizable){
448
+ Resizables.removeObserver(this.container);
449
+ this.resizable.handle.stopObserving('mousedown',this.bringToFrontHandler);
450
+ this.resizable.destroy();
451
+ }
452
+ if(this.container && !this.sourceContainer)
453
+ this.container.remove();
454
+ if(this.sourceContainer){
455
+ if(this.options.hover){
456
+ this.sourceContainer.stopObserving('mouseenter',this.sourceContainerOpenHandler);
457
+ this.sourceContainer.stopObserving('mouseleave',this.sourceContainerCloseHandler);
458
+ if(this.options.position == 'mouse')
459
+ this.sourceContainer.stopObserving('mousemove',this.sourceContainerMouseMoveHandler);
460
+ }else
461
+ this.sourceContainer.stopObserving('click',this.sourceContainerOpenHandler);
462
+ }
463
+ if(this.iFrameShim)
464
+ this.iFrameShim.destroy();
465
+ Event.stopObserving(window,'resize',this.outOfBoundsPositionHandler);
466
+ Control.Window.windows = Control.Window.windows.without(this);
467
+ this.notify('afterDestroy');
468
+ },
469
+ //private
470
+ applyResizable: function(){
471
+ if(this.options.resizable){
472
+ if(typeof(Resizable) == "undefined")
473
+ throw "Control.Window requires resizable.js to be loaded.";
474
+ var resizable_handle = null;
475
+ if(this.options.resizable === true){
476
+ resizable_handle = new Element('div',{
477
+ className: 'resizable_handle'
478
+ });
479
+ this.container.insert(resizable_handle);
480
+ }else
481
+ resizable_handle = $(this.options.resziable);
482
+ this.resizable = new Resizable(this.container,{
483
+ handle: resizable_handle,
484
+ minHeight: this.options.minHeight,
485
+ minWidth: this.options.minWidth,
486
+ maxHeight: this.options.constrainToViewport ? function(element){
487
+ //viewport height - top - total border height
488
+ return (document.viewport.getDimensions().height - parseInt(element.style.top || 0)) - (element.getHeight() - parseInt(element.style.height || 0));
489
+ } : this.options.maxHeight,
490
+ maxWidth: this.options.constrainToViewport ? function(element){
491
+ //viewport width - left - total border width
492
+ return (document.viewport.getDimensions().width - parseInt(element.style.left || 0)) - (element.getWidth() - parseInt(element.style.width || 0));
493
+ } : this.options.maxWidth
494
+ });
495
+ this.resizable.handle.observe('mousedown',this.bringToFrontHandler);
496
+ Resizables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
497
+ if(this.iFrameShim)
498
+ this.updateIFrameShimZIndex();
499
+ this.notify('onResize');
500
+ }.bind(this)));
501
+ }
502
+ },
503
+ applyDraggable: function(){
504
+ if(this.options.draggable){
505
+ if(typeof(Draggables) == "undefined")
506
+ throw "Control.Window requires dragdrop.js to be loaded.";
507
+ var draggable_handle = null;
508
+ if(this.options.draggable === true){
509
+ draggable_handle = new Element('div',{
510
+ className: 'draggable_handle'
511
+ });
512
+ this.container.insert(draggable_handle);
513
+ }else
514
+ draggable_handle = $(this.options.draggable);
515
+ this.draggable = new Draggable(this.container,{
516
+ handle: draggable_handle,
517
+ constrainToViewport: this.options.constrainToViewport,
518
+ zindex: this.container.getStyle('z-index'),
519
+ starteffect: function(){
520
+ if(Prototype.Browser.IE){
521
+ this.old_onselectstart = document.onselectstart;
522
+ document.onselectstart = function(){
523
+ return false;
524
+ };
525
+ }
526
+ }.bind(this),
527
+ endeffect: function(){
528
+ document.onselectstart = this.old_onselectstart;
529
+ }.bind(this)
530
+ });
531
+ this.draggable.handle.observe('mousedown',this.bringToFrontHandler);
532
+ Draggables.addObserver(new Control.Window.LayoutUpdateObserver(this,function(){
533
+ if(this.iFrameShim)
534
+ this.updateIFrameShimZIndex();
535
+ this.notify('onDrag');
536
+ }.bind(this)));
537
+ }
538
+ },
539
+ createDefaultContainer: function(container){
540
+ if(!this.container){
541
+ //no container passed or found, create it
542
+ this.container = new Element('div',{
543
+ id: 'control_window_' + this.numberInSequence
544
+ });
545
+ $(document.body).insert(this.container);
546
+ if(typeof(container) == "string" && $(container) == null && !container.match(/^#(.+)$/) && !container.match(Control.Window.uriRegex))
547
+ this.container.update(container);
548
+ }
549
+ },
550
+ finishOpen: function(event){
551
+ this.bringToFront();
552
+ if(this.options.fade){
553
+ if(typeof(Effect) == "undefined")
554
+ throw "Control.Window requires effects.js to be loaded."
555
+ if(this.effects.fade)
556
+ this.effects.fade.cancel();
557
+ this.effects.appear = new Effect.Appear(this.container,{
558
+ queue: {
559
+ position: 'end',
560
+ scope: 'Control.Window.' + this.numberInSequence
561
+ },
562
+ from: 0,
563
+ to: 1,
564
+ duration: this.options.fadeDuration / 2,
565
+ afterFinish: function(){
566
+ if(this.iFrameShim)
567
+ this.updateIFrameShimZIndex();
568
+ this.isOpen = true;
569
+ this.notify('afterOpen');
570
+ }.bind(this)
571
+ });
572
+ }else
573
+ this.container.show();
574
+ this.position(event);
575
+ if(!(this.options.draggable || this.options.resizable) && this.options.position == 'center')
576
+ Event.observe(window,'resize',this.positionHandler,false);
577
+ if(!this.options.draggable && this.options.position == 'center')
578
+ Event.observe(window,'scroll',this.positionHandler,false);
579
+ if(!this.options.fade){
580
+ this.isOpen = true;
581
+ this.notify('afterOpen');
582
+ }
583
+ return true;
584
+ },
585
+ showIndicator: function(){
586
+ this.showIndicatorTimeout = window.setTimeout(function(){
587
+ if(this.options.fade){
588
+ this.indicatorEffects.appear = new Effect.Appear(this.indicator,{
589
+ queue: {
590
+ position: 'front',
591
+ scope: 'Control.Window.indicator.' + this.numberInSequence
592
+ },
593
+ from: 0,
594
+ to: 1,
595
+ duration: this.options.fadeDuration / 2
596
+ });
597
+ }else
598
+ this.indicator.show();
599
+ }.bind(this),Control.Window.indicatorTimeout);
600
+ },
601
+ hideIndicator: function(){
602
+ if(this.showIndicatorTimeout)
603
+ window.clearTimeout(this.showIndicatorTimeout);
604
+ this.indicator.hide();
605
+ },
606
+ getRemoteContentInsertionTarget: function(){
607
+ return typeof(this.options.insertRemoteContentAt) == "string" ? this.container.down(this.options.insertRemoteContentAt) : $(this.options.insertRemoteContentAt);
608
+ },
609
+ updateIFrameShimZIndex: function(){
610
+ if(this.iFrameShim)
611
+ this.iFrameShim.positionUnder(this.container);
612
+ }
613
+ });
614
+ //class methods
615
+ Object.extend(Control.Window,{
616
+ windows: [],
617
+ baseZIndex: 9999,
618
+ indicatorTimeout: 250,
619
+ iframeTemplate: new Template('<iframe src="#{href}" width="100%" height="100%" frameborder="0"></iframe>'),
620
+ uriRegex: /^(\/|\#|https?\:\/\/|[\w]+\/)/,
621
+ bringToFront: function(w){
622
+ Control.Window.windows = Control.Window.windows.without(w);
623
+ Control.Window.windows.push(w);
624
+ Control.Window.windows.each(function(w,i){
625
+ var z_index = Control.Window.baseZIndex + i;
626
+ w.container.setStyle({
627
+ zIndex: z_index
628
+ });
629
+ if(w.isOpen){
630
+ if(w.iFrameShim)
631
+ w.updateIFrameShimZIndex();
632
+ }
633
+ if(w.options.draggable)
634
+ w.draggable.options.zindex = z_index;
635
+ });
636
+ },
637
+ open: function(container,options){
638
+ var w = new Control.Window(container,options);
639
+ w.open();
640
+ return w;
641
+ },
642
+ //protected
643
+ initialZIndexForWindow: function(w){
644
+ return Control.Window.baseZIndex + (Control.Window.windows.length - 1);
645
+ }
646
+ });
647
+ Object.Event.extend(Control.Window);
648
+
649
+ //this is the observer for both Resizables and Draggables
650
+ Control.Window.LayoutUpdateObserver = Class.create({
651
+ initialize: function(w,observer){
652
+ this.w = w;
653
+ this.element = $(w.container);
654
+ this.observer = observer;
655
+ },
656
+ onStart: Prototype.emptyFunction,
657
+ onEnd: function(event_name,instance){
658
+ if(instance.element == this.element && this.iFrameShim)
659
+ this.w.updateIFrameShimZIndex();
660
+ },
661
+ onResize: function(event_name,instance){
662
+ if(instance.element == this.element)
663
+ this.observer(this.element);
664
+ },
665
+ onDrag: function(event_name,instance){
666
+ if(instance.element == this.element)
667
+ this.observer(this.element);
668
+ }
669
+ });
670
+
671
+ //overlay for Control.Modal
672
+ Control.Overlay = {
673
+ id: 'control_overlay',
674
+ loaded: false,
675
+ container: false,
676
+ lastOpacity: 0,
677
+ getStyles: function() {
678
+ return {
679
+ position: 'fixed',
680
+ top: 0,
681
+ left: 0,
682
+ width: '100%',
683
+ height: '100%',
684
+ zIndex: Control.Window.baseZIndex - 1
685
+ };
686
+ },
687
+ getIeStyles: function() {
688
+ return {
689
+ position: 'absolute',
690
+ top: 0,
691
+ left: 0,
692
+ zIndex: Control.Window.baseZIndex - 1
693
+ };
694
+ },
695
+ effects: {
696
+ fade: false,
697
+ appear: false
698
+ },
699
+ load: function(){
700
+ if(Control.Overlay.loaded)
701
+ return false;
702
+ Control.Overlay.loaded = true;
703
+ Control.Overlay.container = new Element('div',{
704
+ id: Control.Overlay.id
705
+ });
706
+ $(document.body).insert(Control.Overlay.container);
707
+ if(Prototype.Browser.IE){
708
+ Control.Overlay.container.setStyle(Control.Overlay.getIeStyles());
709
+ Event.observe(window,'scroll',Control.Overlay.positionOverlay);
710
+ Event.observe(window,'resize',Control.Overlay.positionOverlay);
711
+ Control.Overlay.observe('beforeShow',Control.Overlay.positionOverlay);
712
+ }else
713
+ Control.Overlay.container.setStyle(Control.Overlay.getStyles());
714
+ Control.Overlay.iFrameShim = new IframeShim();
715
+ Control.Overlay.iFrameShim.hide();
716
+ Event.observe(window,'resize',Control.Overlay.positionIFrameShim);
717
+ Control.Overlay.container.hide();
718
+ return true;
719
+ },
720
+ unload: function(){
721
+ if(!Control.Overlay.loaded)
722
+ return false;
723
+ Event.stopObserving(window,'resize',Control.Overlay.positionOverlay);
724
+ Control.Overlay.stopObserving('beforeShow',Control.Overlay.positionOverlay);
725
+ Event.stopObserving(window,'resize',Control.Overlay.positionIFrameShim);
726
+ Control.Overlay.iFrameShim.destroy();
727
+ Control.Overlay.container.remove();
728
+ Control.Overlay.loaded = false;
729
+ return true;
730
+ },
731
+ show: function(opacity,fade){
732
+ if(Control.Overlay.notify('beforeShow') === false)
733
+ return false;
734
+ Control.Overlay.lastOpacity = opacity;
735
+ Control.Overlay.positionIFrameShim();
736
+ Control.Overlay.iFrameShim.show();
737
+ if(fade){
738
+ if(typeof(Effect) == "undefined")
739
+ throw "Control.Window requires effects.js to be loaded."
740
+ if(Control.Overlay.effects.fade)
741
+ Control.Overlay.effects.fade.cancel();
742
+ Control.Overlay.effects.appear = new Effect.Appear(Control.Overlay.container,{
743
+ queue: {
744
+ position: 'end',
745
+ scope: 'Control.Overlay'
746
+ },
747
+ afterFinish: function(){
748
+ Control.Overlay.notify('afterShow');
749
+ },
750
+ from: 0,
751
+ to: Control.Overlay.lastOpacity,
752
+ duration: (fade === true ? 0.75 : fade) / 2
753
+ });
754
+ }else{
755
+ Control.Overlay.container.setStyle({
756
+ opacity: opacity || 1
757
+ });
758
+ Control.Overlay.container.show();
759
+ Control.Overlay.notify('afterShow');
760
+ }
761
+ return true;
762
+ },
763
+ hide: function(fade){
764
+ if(Control.Overlay.notify('beforeHide') === false)
765
+ return false;
766
+ if(Control.Overlay.effects.appear)
767
+ Control.Overlay.effects.appear.cancel();
768
+ Control.Overlay.iFrameShim.hide();
769
+ if(fade){
770
+ Control.Overlay.effects.fade = new Effect.Fade(Control.Overlay.container,{
771
+ queue: {
772
+ position: 'front',
773
+ scope: 'Control.Overlay'
774
+ },
775
+ afterFinish: function(){
776
+ Control.Overlay.notify('afterHide');
777
+ },
778
+ from: Control.Overlay.lastOpacity,
779
+ to: 0,
780
+ duration: (fade === true ? 0.75 : fade) / 2
781
+ });
782
+ }else{
783
+ Control.Overlay.container.hide();
784
+ Control.Overlay.notify('afterHide');
785
+ }
786
+ return true;
787
+ },
788
+ positionIFrameShim: function(){
789
+ if(Control.Overlay.container.visible())
790
+ Control.Overlay.iFrameShim.positionUnder(Control.Overlay.container);
791
+ },
792
+ //IE only
793
+ positionOverlay: function(){
794
+ Control.Overlay.container.setStyle({
795
+ width: document.body.clientWidth + 'px',
796
+ height: document.body.clientHeight + 'px'
797
+ });
798
+ }
799
+ };
800
+ Object.Event.extend(Control.Overlay);
801
+
802
+ Control.ToolTip = Class.create(Control.Window,{
803
+ initialize: function($super,container,tooltip,options){
804
+ $super(tooltip,Object.extend(Object.extend(Object.clone(Control.ToolTip.defaultOptions),options || {}),{
805
+ position: 'mouse',
806
+ hover: container
807
+ }));
808
+ }
809
+ });
810
+ Object.extend(Control.ToolTip,{
811
+ defaultOptions: {
812
+ offsetLeft: 10
813
+ }
814
+ });
815
+
816
+ Control.Modal = Class.create(Control.Window,{
817
+ initialize: function($super,container,options){
818
+ Control.Modal.InstanceMethods.beforeInitialize.bind(this)();
819
+ $super(container,Object.extend(Object.clone(Control.Modal.defaultOptions),options || {}));
820
+ },
821
+ closeWithoutOverlay: function(){
822
+ this.keepOverlay = true;
823
+ this.close();
824
+ }
825
+ });
826
+ Object.extend(Control.Modal,{
827
+ defaultOptions: {
828
+ overlayOpacity: 0.5,
829
+ closeOnClick: 'overlay'
830
+ },
831
+ current: false,
832
+ open: function(container,options){
833
+ var modal = new Control.Modal(container,options);
834
+ modal.open();
835
+ return modal;
836
+ },
837
+ close: function(){
838
+ if(Control.Modal.current)
839
+ Control.Modal.current.close();
840
+ },
841
+ InstanceMethods: {
842
+ beforeInitialize: function(){
843
+ Control.Overlay.load();
844
+ this.observe('beforeOpen',Control.Modal.Observers.beforeOpen.bind(this));
845
+ this.observe('afterOpen',Control.Modal.Observers.afterOpen.bind(this));
846
+ this.observe('afterClose',Control.Modal.Observers.afterClose.bind(this));
847
+ }
848
+ },
849
+ Observers: {
850
+ beforeOpen: function(){
851
+ Control.Window.windows.without(this).each(function(w){
852
+ if(w.closeWithoutOverlay && w.isOpen){
853
+ w.closeWithoutOverlay();
854
+ }else{
855
+ w.close();
856
+ }
857
+ });
858
+ if(!Control.Overlay.overlayFinishedOpening){
859
+ Control.Overlay.observeOnce('afterShow',function(){
860
+ Control.Overlay.overlayFinishedOpening = true;
861
+ this.open();
862
+ }.bind(this));
863
+ Control.Overlay.show(this.options.overlayOpacity,this.options.fade ? this.options.fadeDuration : false);
864
+ throw $break;
865
+ }
866
+ },
867
+ afterOpen: function(){
868
+ Control.Overlay.show(this.options.overlayOpacity);
869
+ Control.Overlay.overlayFinishedOpening = true;
870
+ Control.Modal.current = this;
871
+ },
872
+ afterClose: function(){
873
+ if(!this.keepOverlay){
874
+ Control.Overlay.hide(this.options.fade ? this.options.fadeDuration : false);
875
+ Control.Overlay.overlayFinishedOpening = false;
876
+ }
877
+ this.keepOverlay = false;
878
+ Control.Modal.current = false;
879
+ }
880
+ }
881
+ });
882
+
883
+ Control.LightBox = Class.create(Control.Window,{
884
+ initialize: function($super,container,options){
885
+ this.allImagesLoaded = false;
886
+ if(options.modal){
887
+ var options = Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {});
888
+ options = Object.extend(Object.clone(Control.Modal.defaultOptions),options);
889
+ options = Control.Modal.InstanceMethods.beforeInitialize.bind(this)(options);
890
+ $super(container,options);
891
+ }else
892
+ $super(container,Object.extend(Object.clone(Control.LightBox.defaultOptions),options || {}));
893
+ this.hasRemoteContent = this.href && !this.options.iframe;
894
+ if(this.hasRemoteContent)
895
+ this.observe('onRemoteContentLoaded',Control.LightBox.Observers.onRemoteContentLoaded.bind(this));
896
+ else
897
+ this.applyImageObservers();
898
+ this.observe('beforeOpen',Control.LightBox.Observers.beforeOpen.bind(this));
899
+ },
900
+ applyImageObservers:function(){
901
+ var images = this.getImages();
902
+ this.numberImagesToLoad = images.length;
903
+ this.numberofImagesLoaded = 0;
904
+ images.each(function(image){
905
+ image.observe('load',function(image){
906
+ ++this.numberofImagesLoaded;
907
+ if(this.numberImagesToLoad == this.numberofImagesLoaded){
908
+ this.allImagesLoaded = true;
909
+ this.onAllImagesLoaded();
910
+ }
911
+ }.bind(this,image));
912
+ image.hide();
913
+ }.bind(this));
914
+ },
915
+ onAllImagesLoaded: function(){
916
+ this.getImages().each(function(image){
917
+ this.showImage(image);
918
+ }.bind(this));
919
+ if(this.hasRemoteContent){
920
+ if(this.options.indicator)
921
+ this.hideIndicator();
922
+ this.finishOpen();
923
+ }else
924
+ this.open();
925
+ },
926
+ getImages: function(){
927
+ return this.container.select(Control.LightBox.imageSelector);
928
+ },
929
+ showImage: function(image){
930
+ image.show();
931
+ }
932
+ });
933
+ Object.extend(Control.LightBox,{
934
+ imageSelector: 'img',
935
+ defaultOptions: {},
936
+ Observers: {
937
+ beforeOpen: function(){
938
+ if(!this.hasRemoteContent && !this.allImagesLoaded)
939
+ throw $break;
940
+ },
941
+ onRemoteContentLoaded: function(){
942
+ this.applyImageObservers();
943
+ if(!this.allImagesLoaded)
944
+ throw $break;
945
+ }
946
+ }
947
+ });