SMSNotifier - Version 1.1.2

Version Notes

Visit product homepage at:
http://www.artio.net/e-shop/magento-extensions/magento-sms-notifier

Download this release

Release Info

Developer Magento Core Team
Extension SMSNotifier
Version 1.1.2
Comparing to
See all releases


Code changes from version 1.1.0 to 1.1.2

app/code/community/Artio/SMSNotifier/Block/Adminhtml/Data/Form/Element/CustomerNumbers.php CHANGED
@@ -43,7 +43,7 @@ class Artio_SMSNotifier_Block_Adminhtml_Data_Form_Element_CustomerNumbers extend
43
  .$helper->__('Change this <a href="%s">here</a>.', $conurl).
44
  "</span></p>
45
  <div id=\"search_autocomplete\" class=\"search-autocomplete\" style=\"display:none;\"></div>
46
- <input type=\"hidden\" id=\"customer_numbers\" name=\"customer_numbers\" value=\"\" />
47
  <p id=\"table-numbers-empty-message\">
48
  <small>".$helper->__("Number list is empty. Enter phone number and click to suggest list, please.")."</small>
49
  </p>
43
  .$helper->__('Change this <a href="%s">here</a>.', $conurl).
44
  "</span></p>
45
  <div id=\"search_autocomplete\" class=\"search-autocomplete\" style=\"display:none;\"></div>
46
+ <input type=\"hidden\" id=\"customer_numbers\" name=\"customer_numbers\" class=\"required-entry\" value=\"\" />
47
  <p id=\"table-numbers-empty-message\">
48
  <small>".$helper->__("Number list is empty. Enter phone number and click to suggest list, please.")."</small>
49
  </p>
app/code/community/Artio/SMSNotifier/Block/Adminhtml/Send/Form.php CHANGED
@@ -45,9 +45,9 @@ class Artio_SMSNotifier_Block_Adminhtml_Send_Form extends Mage_Adminhtml_Block_W
45
  $fieldset->addField('customer_numbers', 'customer_numbers', array(
46
  'name' => 'customer_numbers',
47
  'label' => Mage::helper('smsnotify')->__('Telephone Number List')
48
- ));
49
 
50
- $fieldset->addField('admin', 'select', array(
51
  'name' => 'admin',
52
  'label' => Mage::helper('smsnotify')->__('Send to administrator'),
53
  'options' => Mage::getModel('smsnotify/system_config_source_sendToAdmin')->toOptions()
45
  $fieldset->addField('customer_numbers', 'customer_numbers', array(
46
  'name' => 'customer_numbers',
47
  'label' => Mage::helper('smsnotify')->__('Telephone Number List')
48
+ ));
49
 
50
+ $fieldset->addField('admin', 'selectex', array(
51
  'name' => 'admin',
52
  'label' => Mage::helper('smsnotify')->__('Send to administrator'),
53
  'options' => Mage::getModel('smsnotify/system_config_source_sendToAdmin')->toOptions()
app/code/community/Artio/SMSNotifier/Helper/Data.php CHANGED
@@ -31,17 +31,17 @@ class Artio_SMSNotifier_Helper_Data extends Mage_Core_Helper_Abstract
31
  */
32
  const EVENT_NEW_ORDER = 'new_order';
33
 
34
- /**
35
  * Code for event new invoice.
36
- * Code is related to config value, do not change it, please!
37
- * @var string
38
  */
39
  const EVENT_NEW_INVOICE = 'new_invoice';
40
 
41
- /**
42
  * Code for event new shipment.
43
- * Code is related to config value, do not change it, please!
44
- * @var string
45
  */
46
  const EVENT_NEW_SHIPMENT = 'new_shipment';
47
 
@@ -55,122 +55,160 @@ class Artio_SMSNotifier_Helper_Data extends Mage_Core_Helper_Abstract
55
  const SMS_MARK = 'STATUS_SMS';
56
 
57
 
58
- /**
59
- * Determie whether there is allowed to send message
60
- * for this event.
61
- *
62
- * @param string $type new_order|new_invoice|new_shipment
63
- * @param Mage_Core_Model_Abstract $object
64
- * @return bool
65
- */
66
- public function isEventAllowed($type, $object)
67
- {
68
- return $this->_getConfig()->isEventAllowed($type, $object->getStoreId());
69
- }
70
-
71
-
72
- /**
73
- * Get customer's number.
74
- *
75
- * @param string $type new_order|new_invoice|new_shipment
76
- * @param Mage_Core_Model_Abstract $object
77
- */
78
- public function getCustomerNumber($type, $object)
79
- {
80
- // no, we do not want to notify custoemr
81
- if (!$this->_getConfig()->getNotifyCustomerForEvent($type, $object->getStoreId()))
82
- return "";
83
-
84
- $address = $this->_getConfig()->getUsedAddress($object->getStoreId());
85
-
86
- $phone = '';
87
-
88
- if ($address == 'billing')
89
- {
90
- $primary = $object->getBillingAddress();
91
- $secondary = $object->getShippingAddress();
92
- }
93
- else
94
- {
95
- $primary = $object->getShippingAddress();
96
- $secondary = $object->getBillingAddress();
97
- }
98
-
99
- $phone = $primary->getTelephone();
100
-
101
- if (!$phone)
102
- $phone = $secondary->getTelephone();
103
-
104
- // add dial prefix if necessary
105
- if ($phone)
106
- $phone = $this->_getConfig()->sanitizeNumber($phone, $object->getStoreId());
107
-
108
- return $phone;
109
- }
110
-
111
-
112
- /**
113
- * Get country code.
114
- *
115
- * @param string $type new_order|new_invoice|new_shipment
116
- * @param Mage_Core_Model_Abstract $object
117
- */
118
- public function getCountryCode($type, $object)
119
- {
120
- $address = $this->_getConfig()->getUsedAddress($object->getStoreId());
121
-
122
- $country = '';
123
-
124
- if ($address == 'billing')
125
- {
126
- $primary = $object->getBillingAddress();
127
- $secondary = $object->getShippingAddress();
128
- }
129
- else
130
- {
131
- $primary = $object->getShippingAddress();
132
- $secondary = $object->getBillingAddress();
133
- }
134
-
135
- $country = $primary->getCountry();
136
-
137
- if (!$country)
138
- $country = $secondary->getCountry();
139
-
140
- return $country;
141
- }
142
-
143
-
144
- /**
145
- *
146
- * @param string $type new_order|new_invoice|new_shipment
147
- * @param Mage_Core_Model_Abstract $object
148
- */
149
- public function getAdminNumber($type, $object)
150
- {
151
- return $this->_getConfig()->getAdminNumberForEvent($type, $object->getStoreId());
152
- }
153
-
154
-
155
- /**
156
- *
157
- * @param string $type new_order|new_invoice|new_shipment
158
- * @param Mage_Core_Model_Abstract $object
159
- */
160
- public function getText($type, $object)
161
- {
162
- return $this->_getConfig()->getTextForEvent($type, $object->getStoreId());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  }
164
 
165
 
166
- /**
167
- * Get standard configuration model.
168
- *
169
- * @return Artio_SMSNotifier_Helper_Model_Config
170
- */
171
- protected function _getConfig()
172
- {
173
- return Mage::getSingleton('smsnotify/config');
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
 
176
  }
31
  */
32
  const EVENT_NEW_ORDER = 'new_order';
33
 
34
+ /**
35
  * Code for event new invoice.
36
+ * Code is related to config value, do not change it, please!
37
+ * @var string
38
  */
39
  const EVENT_NEW_INVOICE = 'new_invoice';
40
 
41
+ /**
42
  * Code for event new shipment.
43
+ * Code is related to config value, do not change it, please!
44
+ * @var string
45
  */
46
  const EVENT_NEW_SHIPMENT = 'new_shipment';
47
 
55
  const SMS_MARK = 'STATUS_SMS';
56
 
57
 
58
+ /**
59
+ * Determine whether there is allowed to send message
60
+ * for this event.
61
+ *
62
+ * @param string $type new_order|new_invoice|new_shipment
63
+ * @param Mage_Core_Model_Abstract $object
64
+ * @return bool
65
+ */
66
+ public function isEventAllowed($type, $object)
67
+ {
68
+ return $this->_getConfig()->isEventAllowed($type, $object->getStoreId());
69
+ }
70
+
71
+ /**
72
+ * Determine whethere there is allowed to send message
73
+ * for this event with bussines object with a shipping method.
74
+ *
75
+ * @param type $type
76
+ * @param type $object
77
+ */
78
+ public function isShippingMethodAllowed($type, $object)
79
+ {
80
+ $shippingCode = $this->getShippingMethodCode($type, $object);
81
+
82
+ return $this->_getConfig()->isShippingMethodAllowedForEvent($type, $shippingCode, $object->getStoreId());
83
+ }
84
+
85
+ /**
86
+ * Get customer's number.
87
+ *
88
+ * @param string $type new_order|new_invoice|new_shipment
89
+ * @param Mage_Core_Model_Abstract $object
90
+ */
91
+ public function getCustomerNumber($type, $object)
92
+ {
93
+ // no, we do not want to notify custoemr
94
+ if (!$this->_getConfig()->getNotifyCustomerForEvent($type, $object->getStoreId()))
95
+ return "";
96
+
97
+ $address = $this->_getConfig()->getUsedAddress($object->getStoreId());
98
+
99
+ $phone = '';
100
+
101
+ if ($address == 'billing')
102
+ {
103
+ $primary = $object->getBillingAddress();
104
+ $secondary = $object->getShippingAddress();
105
+ }
106
+ else
107
+ {
108
+ $primary = $object->getShippingAddress();
109
+ $secondary = $object->getBillingAddress();
110
+ }
111
+
112
+ $phone = $primary->getTelephone();
113
+
114
+ if (!$phone)
115
+ $phone = $secondary->getTelephone();
116
+
117
+ // add dial prefix if necessary
118
+ if ($phone)
119
+ $phone = $this->_getConfig()->sanitizeNumber($phone, $object->getStoreId());
120
+
121
+ return $phone;
122
+ }
123
+
124
+
125
+ /**
126
+ * Get country code.
127
+ *
128
+ * @param string $type new_order|new_invoice|new_shipment
129
+ * @param Mage_Core_Model_Abstract $object
130
+ */
131
+ public function getCountryCode($type, $object)
132
+ {
133
+ $address = $this->_getConfig()->getUsedAddress($object->getStoreId());
134
+
135
+ $country = '';
136
+
137
+ if ($address == 'billing')
138
+ {
139
+ $primary = $object->getBillingAddress();
140
+ $secondary = $object->getShippingAddress();
141
+ }
142
+ else
143
+ {
144
+ $primary = $object->getShippingAddress();
145
+ $secondary = $object->getBillingAddress();
146
+ }
147
+
148
+ $country = $primary->getCountry();
149
+
150
+ if (!$country)
151
+ $country = $secondary->getCountry();
152
+
153
+ return $country;
154
+ }
155
+
156
+ /**
157
+ * Get shipping code (first part) from $object.
158
+ *
159
+ * @param string $type new_order|new_invoice|new_shipment
160
+ * @param Mage_Core_Model_Abstract $object
161
+ * @return string
162
+ */
163
+ public function getShippingMethodCode($type, $object)
164
+ {
165
+ switch ($type)
166
+ {
167
+ case self::EVENT_NEW_INVOICE:
168
+ case self::EVENT_NEW_SHIPMENT:
169
+ $order = $object->getOrder();
170
+ break;
171
+
172
+ case self::EVENT_NEW_ORDER:
173
+ default:
174
+ $order = $object;
175
+ break;
176
+ }
177
+
178
+ return $order->getShippingMethod();
179
+ }
180
+
181
+
182
+ /**
183
+ *
184
+ * @param string $type new_order|new_invoice|new_shipment
185
+ * @param Mage_Core_Model_Abstract $object
186
+ */
187
+ public function getAdminNumber($type, $object)
188
+ {
189
+ return $this->_getConfig()->getAdminNumberForEvent($type, $object->getStoreId());
190
  }
191
 
192
 
193
+ /**
194
+ *
195
+ * @param string $type new_order|new_invoice|new_shipment
196
+ * @param Mage_Core_Model_Abstract $object
197
+ */
198
+ public function getText($type, $object)
199
+ {
200
+ return $this->_getConfig()->getTextForEvent($type, $object->getStoreId());
201
+ }
202
+
203
+
204
+ /**
205
+ * Get standard configuration model.
206
+ *
207
+ * @return Artio_SMSNotifier_Helper_Model_Config
208
+ */
209
+ protected function _getConfig()
210
+ {
211
+ return Mage::getSingleton('smsnotify/config');
212
  }
213
 
214
  }
app/code/community/Artio/SMSNotifier/Helper/SMSLog.php CHANGED
@@ -78,15 +78,4 @@ class Artio_SMSNotifier_Helper_SMSLog extends Mage_Core_Helper_Abstract
78
  $sms->getText());
79
  }
80
 
81
-
82
- /**
83
- * Get standard configuration model.
84
- *
85
- * @return Artio_SMSNotifier_Model_Config $config
86
- */
87
- protected function _getConfig()
88
- {
89
- Mage::getStoreConfig('smsnotify/config');
90
- }
91
-
92
  }
78
  $sms->getText());
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
app/code/community/Artio/SMSNotifier/Model/Config.php CHANGED
@@ -49,6 +49,33 @@ class Artio_SMSNotifier_Model_Config
49
  return (bool) Mage::getStoreConfig("smsnotify/$event/enabled", $storeId);
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  /**
54
  * Get message's text for an event.
@@ -60,9 +87,9 @@ class Artio_SMSNotifier_Model_Config
60
  * @param int $storeId
61
  * @return string
62
  */
63
- public function getTextForEvent($event, $storeId = null)
64
- {
65
- return (string) Mage::getStoreConfig("smsnotify/$event/sms_text", $storeId);
66
  }
67
 
68
 
@@ -73,9 +100,9 @@ class Artio_SMSNotifier_Model_Config
73
  * @param int $storeId
74
  * @return bool
75
  */
76
- public function getNotifyCustomerForEvent($event, $storeId = null)
77
- {
78
- return (bool) Mage::getStoreConfig("smsnotify/$event/to_customer", $storeId);
79
  }
80
 
81
 
@@ -115,11 +142,32 @@ class Artio_SMSNotifier_Model_Config
115
  */
116
  public function getAdminNumberByIndex($index, $storeId = null)
117
  {
118
- if ($index == 1)
119
- return $this->sanitizeNumber(Mage::getStoreConfig("smsnotify/general/primary_admin", $storeId));
120
- else if ($index == 2)
121
- return $this->sanitizeNumber(Mage::getStoreConfig("smsnotify/general/secondary_admin", $storeId));
122
- else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  return false;
124
  }
125
 
@@ -159,7 +207,7 @@ class Artio_SMSNotifier_Model_Config
159
  Mage::log(__CLASS__.":".__METHOD__.": Invalid local country code: '$local'.", Zend_Log::WARN);
160
  return false;
161
  }
162
-
163
  return ($part[0] == $iso3);
164
 
165
  // we can send message everywhere
@@ -179,20 +227,26 @@ class Artio_SMSNotifier_Model_Config
179
 
180
 
181
  /**
182
- * Add dial prefix of local country if needed.
 
 
 
 
 
183
  *
184
  * @param string $number
185
  * @return string
186
  */
187
  public function sanitizeNumber($number, $storeId = null)
188
  {
189
- $length = Mage::getStoreConfig("smsnotify/general/min_length_with_prefix", $storeId);
190
- $local = Mage::getStoreConfig("smsnotify/general/local_country", $storeId);
 
191
 
192
  $prefix = $this->getDialPrefix($local);
193
 
194
- $number = trim($number);
195
- $number = ltrim($number, "+");
196
 
197
  if (strlen($number) <= $length)
198
  $number = $prefix.$number;
@@ -238,25 +292,25 @@ class Artio_SMSNotifier_Model_Config
238
  * @param int $storeId
239
  * @return bool
240
  */
241
- public function isAllowedLogSended($storeId = null)
242
- {
243
- return in_array((int)Mage::getStoreConfig("smsnotify/general/log"), array(0, 2));
244
  }
245
 
246
 
247
- /**
248
- * Extract dial prefix from $localCode.
249
- *
250
- * $localCode has format CODE,DIAL_PREFIX.
251
- *
252
- * @param string $localCode
253
- * @return string
254
- */
255
- public function getDialPrefix($localCode)
256
- {
257
- $parts = explode(',', $localCode);
258
-
259
- return (count($parts)==2) ? trim($parts[1]) : '';
260
  }
261
 
262
 
@@ -313,7 +367,7 @@ class Artio_SMSNotifier_Model_Config
313
 
314
  $number = str_pad($number, $maxLength, '0', STR_PAD_RIGHT);
315
 
316
- if (strcmp($from, $number) <= 0 && strcmp($number, $to) <= 0)
317
  return true;
318
  }
319
  // pattern
49
  return (bool) Mage::getStoreConfig("smsnotify/$event/enabled", $storeId);
50
  }
51
 
52
+ /**
53
+ * Determin whether there is allowed to send SMS for given shipping method
54
+ * and event.
55
+ *
56
+ * @param type $event
57
+ * @param type $shippingMethodCode
58
+ * @param type $storeId
59
+ */
60
+ public function isShippingMethodAllowedForEvent($event, $shippingMethodCode, $storeId = null)
61
+ {
62
+ $disallow = (bool) Mage::getStoreConfig("smsnotify/$event/dissallow_for_shipping_methods", $storeId);
63
+ $disallowedMethods = Mage::getStoreConfig("smsnotify/$event/disallowed_shipping_methods", $storeId);
64
+
65
+ if (!$disallow)
66
+ return true;
67
+
68
+ $disallowedMethodsArray = explode(',', $disallowedMethods);
69
+
70
+ foreach ($disallowedMethodsArray as $disallowMethod)
71
+ {
72
+ if (strpos($shippingMethodCode, $disallowMethod.'_') === 0)
73
+ return false;
74
+ }
75
+
76
+ return true;
77
+ }
78
+
79
 
80
  /**
81
  * Get message's text for an event.
87
  * @param int $storeId
88
  * @return string
89
  */
90
+ public function getTextForEvent($event, $storeId = null)
91
+ {
92
+ return (string) Mage::getStoreConfig("smsnotify/$event/sms_text", $storeId);
93
  }
94
 
95
 
100
  * @param int $storeId
101
  * @return bool
102
  */
103
+ public function getNotifyCustomerForEvent($event, $storeId = null)
104
+ {
105
+ return (bool) Mage::getStoreConfig("smsnotify/$event/to_customer", $storeId);
106
  }
107
 
108
 
142
  */
143
  public function getAdminNumberByIndex($index, $storeId = null)
144
  {
145
+ $number = $this->getPureAdminNumberByIndex($index, $storeId);
146
+
147
+ return (strlen($number) > 0) ? $this->sanitizeNumber($number) : false;
148
+ }
149
+
150
+ /**
151
+ * Get administrator's phone number by index.
152
+ *
153
+ * 1 - means primary phone number
154
+ * 2 - means secondary phone number
155
+ *
156
+ * on other values method returns false.
157
+ *
158
+ * Returned number IS NOT sanitizied.
159
+ *
160
+ * @param int $index
161
+ * @param int $storeId
162
+ * @return string|false
163
+ */
164
+ public function getPureAdminNumberByIndex($index, $storeId = null)
165
+ {
166
+ if ($index == 1)
167
+ return Mage::getStoreConfig("smsnotify/general/primary_admin", $storeId);
168
+ else if ($index == 2)
169
+ return Mage::getStoreConfig("smsnotify/general/secondary_admin", $storeId);
170
+ else
171
  return false;
172
  }
173
 
207
  Mage::log(__CLASS__.":".__METHOD__.": Invalid local country code: '$local'.", Zend_Log::WARN);
208
  return false;
209
  }
210
+
211
  return ($part[0] == $iso3);
212
 
213
  // we can send message everywhere
227
 
228
 
229
  /**
230
+ * Sanitize number.
231
+ *
232
+ * Add dial prefix of local country if needed (if local country
233
+ * is not specified there will be used country from general settings).
234
+ *
235
+ * Whitespaces in $number will be automaticaly removed.
236
  *
237
  * @param string $number
238
  * @return string
239
  */
240
  public function sanitizeNumber($number, $storeId = null)
241
  {
242
+ $length = Mage::getStoreConfig("smsnotify/general/min_length_with_prefix", $storeId);
243
+ $local = Mage::getStoreConfig("smsnotify/general/local_country", $storeId);
244
+ $trimzero = Mage::getStoreConfig("smsnotify/general/trim_zero", $storeId);
245
 
246
  $prefix = $this->getDialPrefix($local);
247
 
248
+ $number = str_replace(array(" ", "\t"), array("", ""), $number);
249
+ $number = ltrim($number, ($trimzero ? "+0" : "+"));
250
 
251
  if (strlen($number) <= $length)
252
  $number = $prefix.$number;
292
  * @param int $storeId
293
  * @return bool
294
  */
295
+ public function isAllowedLogSended($storeId = null)
296
+ {
297
+ return in_array((int)Mage::getStoreConfig("smsnotify/general/log"), array(0, 2));
298
  }
299
 
300
 
301
+ /**
302
+ * Extract dial prefix from $localCode.
303
+ *
304
+ * $localCode has format CODE,DIAL_PREFIX.
305
+ *
306
+ * @param string $localCode
307
+ * @return string
308
+ */
309
+ public function getDialPrefix($localCode)
310
+ {
311
+ $parts = explode(',', $localCode);
312
+
313
+ return (count($parts)==2) ? trim($parts[1]) : '';
314
  }
315
 
316
 
367
 
368
  $number = str_pad($number, $maxLength, '0', STR_PAD_RIGHT);
369
 
370
+ if (strcmp($from, $number) <= 0 && strcmp($number, $to) <= 0)
371
  return true;
372
  }
373
  // pattern
app/code/community/Artio/SMSNotifier/Model/Observer.php CHANGED
@@ -24,23 +24,23 @@
24
  class Artio_SMSNotifier_Model_Observer
25
  {
26
 
27
- /**
28
- *
29
- *
30
- * @param Varien_Event_Observer $observer
31
- * @return Artio_SMSNotifier_Model_Observer
32
- */
33
  public function beforeSaveAbstract($observer)
34
  {
35
  try
36
- {
37
- $event = $observer->getEvent();
38
- $object = $event->getData('object');
39
-
40
  if (
41
  ($object instanceof Mage_Sales_Model_Order)
42
  || ($object instanceof Mage_Sales_Model_Order_Invoice)
43
- || ($object instanceof Mage_Sales_Model_Order_Shipment))
44
  {
45
  if (!$object->getId())
46
  {
@@ -52,30 +52,30 @@ class Artio_SMSNotifier_Model_Observer
52
  {
53
  Mage::logException($e);
54
  Mage::log(__CLASS__.":".__METHOD__.":".$e->getMessage(), Zend_Log::ERR);
55
- }
56
-
57
- Mage::unregister('_helper/smsnotify/data');
58
-
59
- return $this;
60
- }
61
-
62
-
63
  /**
64
- *
65
- * @param Varien_Event_Observer $observer
66
- * @return Artio_SMSNotifier_Model_Observer
67
- */
68
  public function afterSaveAbstract($observer)
69
  {
70
  // get registered object (from beforeSaveAbstract)
71
  $registered = Mage::registry('smsnotify_object');
72
 
73
  // get saving object
74
- $event = $observer->getEvent();
75
  $object = $event->getData('object');
76
 
77
- // if this does not match then we do not check this object type
78
- if ($object != $registered)
79
  return $this;
80
 
81
  // flush registered object
@@ -83,98 +83,101 @@ class Artio_SMSNotifier_Model_Observer
83
 
84
  try
85
  {
86
- // get helper
87
  $helper = Mage::helper('smsnotify');
88
 
89
  // get event code by object type
90
  $eventCode = '';
91
-
92
- if ($object instanceof Mage_Sales_Model_Order)
93
- $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_ORDER;
94
-
95
- if ($object instanceof Mage_Sales_Model_Order_Invoice)
96
- $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_INVOICE;
97
-
98
- if ($object instanceof Mage_Sales_Model_Order_Shipment)
99
  $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_SHIPMENT;
100
 
101
  // unknow event?
102
  if (!$eventCode)
103
  return $this;
104
-
105
- // is there allowed send message?
106
- if (!$helper->isEventAllowed($eventCode, $object))
107
- return;
108
-
109
- // get configuration
110
- $text = $helper->getText($eventCode, $object);
111
- $customerNumber = $helper->getCustomerNumber($eventCode, $object);
 
 
 
112
  $adminNumber = $helper->getAdminNumber($eventCode, $object);
113
- $country = $helper->getCountryCode($eventCode, $object);
114
 
115
  // process text message
116
- if ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_ORDER)
117
- $text = Mage::getModel('smsnotify/sms_template')->setOrder($object)->process($text);
118
  elseif ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_INVOICE)
119
  $text = Mage::getModel('smsnotify/sms_template')->setInvoice($object)->process($text);
120
  elseif ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_SHIPMENT)
121
  $text = Mage::getModel('smsnotify/sms_template')->setShipment($object)->process($text);
122
 
123
- // prepare sms
124
- $sms = Mage::getModel('smsnotify/sms');
125
- $sms->setStoreId($object->getStoreId());
126
- $sms->setText($text);
127
- $sms->addCustomData($eventCode, $object);
128
 
129
- // send to customer
130
- if ($customerNumber)
131
- {
132
  $sms->setType(Artio_SMSNotifier_Model_Sms::TYPE_CUSTOMER);
133
- $sms->setCountry($country);
134
- $sms->setNumber($customerNumber);
135
- $this->_getService()->send($sms);
136
- }
137
-
138
- // send to admin
139
- if ($adminNumber)
140
- {
141
  $sms->setType(Artio_SMSNotifier_Model_Sms::TYPE_ADMIN);
142
- $sms->setCountry('');
143
- $sms->setNumber($adminNumber);
144
- $this->_getService()->send($sms);
145
  }
146
  }
147
  catch (Exception $e)
148
  {
149
- Mage::logException($e);
150
  Mage::log(__CLASS__.":".__METHOD__.":".$e->getMessage(), Zend_Log::ERR);
151
  }
152
-
153
- Mage::unregister('_helper/smsnotify/data');
154
-
155
- return $this;
156
  }
157
 
158
 
159
- /**
160
- * Get standard configuration model.
161
- *
162
- * @return Artio_SMSNotifier_Helper_Model_Config
163
- */
164
- protected function _getConfig()
165
- {
166
- return Mage::getSingleton('smsnotify/config');
167
- }
168
-
169
-
170
- /**
171
- * Get standard service.
172
- *
173
- * @return Artio_SMSNotifier_Model_Service
174
- */
175
- protected function _getService()
176
- {
177
- return Mage::getSingleton('smsnotify/service');
178
  }
179
 
180
  }
24
  class Artio_SMSNotifier_Model_Observer
25
  {
26
 
27
+ /**
28
+ *
29
+ *
30
+ * @param Varien_Event_Observer $observer
31
+ * @return Artio_SMSNotifier_Model_Observer
32
+ */
33
  public function beforeSaveAbstract($observer)
34
  {
35
  try
36
+ {
37
+ $event = $observer->getEvent();
38
+ $object = $event->getData('object');
39
+
40
  if (
41
  ($object instanceof Mage_Sales_Model_Order)
42
  || ($object instanceof Mage_Sales_Model_Order_Invoice)
43
+ || ($object instanceof Mage_Sales_Model_Order_Shipment))
44
  {
45
  if (!$object->getId())
46
  {
52
  {
53
  Mage::logException($e);
54
  Mage::log(__CLASS__.":".__METHOD__.":".$e->getMessage(), Zend_Log::ERR);
55
+ }
56
+
57
+ Mage::unregister('_helper/smsnotify/data');
58
+
59
+ return $this;
60
+ }
61
+
62
+
63
  /**
64
+ *
65
+ * @param Varien_Event_Observer $observer
66
+ * @return Artio_SMSNotifier_Model_Observer
67
+ */
68
  public function afterSaveAbstract($observer)
69
  {
70
  // get registered object (from beforeSaveAbstract)
71
  $registered = Mage::registry('smsnotify_object');
72
 
73
  // get saving object
74
+ $event = $observer->getEvent();
75
  $object = $event->getData('object');
76
 
77
+ // if this does not match then we do not check this object type
78
+ if ($object != $registered)
79
  return $this;
80
 
81
  // flush registered object
83
 
84
  try
85
  {
86
+ // get helper
87
  $helper = Mage::helper('smsnotify');
88
 
89
  // get event code by object type
90
  $eventCode = '';
91
+
92
+ if ($object instanceof Mage_Sales_Model_Order)
93
+ $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_ORDER;
94
+
95
+ if ($object instanceof Mage_Sales_Model_Order_Invoice)
96
+ $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_INVOICE;
97
+
98
+ if ($object instanceof Mage_Sales_Model_Order_Shipment)
99
  $eventCode = Artio_SMSNotifier_Helper_Data::EVENT_NEW_SHIPMENT;
100
 
101
  // unknow event?
102
  if (!$eventCode)
103
  return $this;
104
+
105
+ // is there allowed send message?
106
+ if (!$helper->isEventAllowed($eventCode, $object))
107
+ return;
108
+
109
+ if (!$helper->isShippingMethodAllowed($eventCode, $object))
110
+ return;
111
+
112
+ // get configuration
113
+ $text = $helper->getText($eventCode, $object);
114
+ $customerNumber = $helper->getCustomerNumber($eventCode, $object);
115
  $adminNumber = $helper->getAdminNumber($eventCode, $object);
116
+ $country = $helper->getCountryCode($eventCode, $object);
117
 
118
  // process text message
119
+ if ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_ORDER)
120
+ $text = Mage::getModel('smsnotify/sms_template')->setOrder($object)->process($text);
121
  elseif ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_INVOICE)
122
  $text = Mage::getModel('smsnotify/sms_template')->setInvoice($object)->process($text);
123
  elseif ($eventCode == Artio_SMSNotifier_Helper_Data::EVENT_NEW_SHIPMENT)
124
  $text = Mage::getModel('smsnotify/sms_template')->setShipment($object)->process($text);
125
 
126
+ // prepare sms
127
+ $sms = Mage::getModel('smsnotify/sms');
128
+ $sms->setStoreId($object->getStoreId());
129
+ $sms->setText($text);
130
+ $sms->addCustomData($eventCode, $object);
131
 
132
+ // send to customer
133
+ if ($customerNumber)
134
+ {
135
  $sms->setType(Artio_SMSNotifier_Model_Sms::TYPE_CUSTOMER);
136
+ $sms->setCountry($country);
137
+ $sms->setNumber($customerNumber);
138
+ $this->_getService()->send($sms);
139
+ }
140
+
141
+ // send to admin
142
+ if ($adminNumber)
143
+ {
144
  $sms->setType(Artio_SMSNotifier_Model_Sms::TYPE_ADMIN);
145
+ $sms->setCountry('');
146
+ $sms->setNumber($adminNumber);
147
+ $this->_getService()->send($sms);
148
  }
149
  }
150
  catch (Exception $e)
151
  {
152
+ Mage::logException($e);
153
  Mage::log(__CLASS__.":".__METHOD__.":".$e->getMessage(), Zend_Log::ERR);
154
  }
155
+
156
+ Mage::unregister('_helper/smsnotify/data');
157
+
158
+ return $this;
159
  }
160
 
161
 
162
+ /**
163
+ * Get standard configuration model.
164
+ *
165
+ * @return Artio_SMSNotifier_Helper_Model_Config
166
+ */
167
+ protected function _getConfig()
168
+ {
169
+ return Mage::getSingleton('smsnotify/config');
170
+ }
171
+
172
+
173
+ /**
174
+ * Get standard service.
175
+ *
176
+ * @return Artio_SMSNotifier_Model_Service
177
+ */
178
+ protected function _getService()
179
+ {
180
+ return Mage::getSingleton('smsnotify/service');
181
  }
182
 
183
  }
app/code/community/Artio/SMSNotifier/Model/Service.php CHANGED
@@ -61,16 +61,16 @@ class Artio_SMSNotifier_Model_Service
61
 
62
  if (!$username)
63
  {
64
- $sms->addCustomData('error_message', $this->_helper()->__('API Username is not set. Check it in the configuration, please.'));
65
- Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
66
  return false;
67
  }
68
 
69
- if (!$apikey)
70
- {
71
- $sms->addCustomData('error_message', $this->_helper()->__('API Key is not set. Check it in the configuration, please.'));
72
- Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
73
- return false;
74
  }
75
 
76
  if (!$sms->getNumber())
@@ -89,16 +89,16 @@ class Artio_SMSNotifier_Model_Service
89
 
90
  if (!$this->_getConfig()->isNumberAllowed($sms->getNumber(), $sms->getStoreId()))
91
  {
92
- $sms->addCustomData('error_message', $this->_helper()->__("It is forbidden to send SMS to number '%s'. If you think that it is bad then check your number filters definitions in the configuration of SMSNotifyForMagento, please.", $sms->getNumber()));
93
- Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
94
  return false;
95
  }
96
 
97
- if (!$this->_getConfig()->isCountryAllowed($sms->getCountry(), $sms->getStoreId()))
98
- {
99
- $sms->addCustomData('error_message', $this->_helper()->__("It is forbidden to send SMS to country '%s'. If you think that it is bad then check your country filter definitions in the configuration of SMSNotifyForMagento, please.", $sms->getCountry()));
100
- Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
101
- return false;
102
  }
103
 
104
  $allowUnicode = $this->_getConfig()->isUnicodeAllowed($sms->getStoreId());
@@ -131,15 +131,15 @@ class Artio_SMSNotifier_Model_Service
131
  public function testCredentials()
132
  {
133
  $username = $this->getUsername();
134
- $apikey = $this->getApikey();
135
-
136
- if (!$username)
137
- return $this->_helper()->__('API Username is not set.');
138
-
139
- if (!$apikey)
140
- return $this->_helper()->__('API Key is not set.');
141
-
142
- $service = ASmsService::getInstance();
143
  $result = $service->getCreditInfo($username, $apikey);
144
 
145
  if (!$result)
@@ -160,27 +160,27 @@ class Artio_SMSNotifier_Model_Service
160
  $username = $this->getUsername();
161
  $apikey = $this->getApikey();
162
 
163
- $service = ASmsService::getInstance();
164
  $result = $service->getCreditInfo($username, $apikey);
165
 
166
  return $result;
167
  }
168
 
169
 
170
- /**
171
- * Loads and returns the array of available credit amounts for purchase and the purchase URL
172
- *
173
- * @return array Associative array of [creditValues] => Credit amounts available for purchase ([value] => text)
174
- * [link] => Purchase URL
175
  */
176
  public function getCreditPurchaseInfo()
177
  {
178
- $username = $this->getUsername();
179
- $apikey = $this->getApikey();
180
-
181
- $service = ASmsService::getInstance();
182
- $result = $service->getCreditPurchaseInfo($username, $apikey);
183
-
184
  return $result;
185
  }
186
 
@@ -203,14 +203,14 @@ class Artio_SMSNotifier_Model_Service
203
  }
204
 
205
 
206
- /**
207
- * Get standard config.
208
- *
209
- * @return Artio_SMSNotifier_Model_Config
210
- */
211
- protected function _getConfig()
212
- {
213
- return Mage::getSingleton('smsnotify/config');
214
  }
215
 
216
 
61
 
62
  if (!$username)
63
  {
64
+ $sms->addCustomData('error_message', $this->_helper()->__('API Username is not set. Check it in the configuration, please.'));
65
+ Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
66
  return false;
67
  }
68
 
69
+ if (!$apikey)
70
+ {
71
+ $sms->addCustomData('error_message', $this->_helper()->__('API Key is not set. Check it in the configuration, please.'));
72
+ Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
73
+ return false;
74
  }
75
 
76
  if (!$sms->getNumber())
89
 
90
  if (!$this->_getConfig()->isNumberAllowed($sms->getNumber(), $sms->getStoreId()))
91
  {
92
+ $sms->addCustomData('error_message', $this->_helper()->__("It is forbidden to send SMS to number '%s'. If you think that it is bad then check your number filters definitions in the configuration of SMSNotifyForMagento, please.", $sms->getNumber()));
93
+ Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
94
  return false;
95
  }
96
 
97
+ if (!$this->_getConfig()->isCountryAllowed($sms->getCountry(), $sms->getStoreId()))
98
+ {
99
+ $sms->addCustomData('error_message', $this->_helper()->__("It is forbidden to send SMS to country '%s'. If you think that it is bad then check your country filter definitions in the configuration of SMSNotifyForMagento, please.", $sms->getCountry()));
100
+ Mage::dispatchEvent('smsnotifier_error', array('sms' => $sms));
101
+ return false;
102
  }
103
 
104
  $allowUnicode = $this->_getConfig()->isUnicodeAllowed($sms->getStoreId());
131
  public function testCredentials()
132
  {
133
  $username = $this->getUsername();
134
+ $apikey = $this->getApikey();
135
+
136
+ if (!$username)
137
+ return $this->_helper()->__('API Username is not set.');
138
+
139
+ if (!$apikey)
140
+ return $this->_helper()->__('API Key is not set.');
141
+
142
+ $service = ASmsService::getInstance();
143
  $result = $service->getCreditInfo($username, $apikey);
144
 
145
  if (!$result)
160
  $username = $this->getUsername();
161
  $apikey = $this->getApikey();
162
 
163
+ $service = ASmsService::getInstance();
164
  $result = $service->getCreditInfo($username, $apikey);
165
 
166
  return $result;
167
  }
168
 
169
 
170
+ /**
171
+ * Loads and returns the array of available credit amounts for purchase and the purchase URL
172
+ *
173
+ * @return array Associative array of [creditValues] => Credit amounts available for purchase ([value] => text)
174
+ * [link] => Purchase URL
175
  */
176
  public function getCreditPurchaseInfo()
177
  {
178
+ $username = $this->getUsername();
179
+ $apikey = $this->getApikey();
180
+
181
+ $service = ASmsService::getInstance();
182
+ $result = $service->getCreditPurchaseInfo($username, $apikey);
183
+
184
  return $result;
185
  }
186
 
203
  }
204
 
205
 
206
+ /**
207
+ * Get standard config.
208
+ *
209
+ * @return Artio_SMSNotifier_Model_Config
210
+ */
211
+ protected function _getConfig()
212
+ {
213
+ return Mage::getSingleton('smsnotify/config');
214
  }
215
 
216
 
app/code/community/Artio/SMSNotifier/Model/Source/ShippingMethods.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SMS Notifier
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * It is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ *
11
+ * @category Artio
12
+ * @package Artio_SMSNotifier
13
+ * @copyright Copyright (c) 2013 Artio (http://www.artio.net)
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ */
16
+
17
+ /**
18
+ * SMS Model
19
+ *
20
+ * @category Artio
21
+ * @package Artio_SMSNotifier
22
+ * @author Artio Magento Team <info@artio.net>
23
+ */
24
+ class Artio_SMSNotifier_Model_Source_ShippingMethods
25
+ {
26
+
27
+ /**
28
+ * @return array
29
+ */
30
+ public function toOptionArray()
31
+ {
32
+ $options = array();
33
+
34
+ foreach (Mage::app()->getStore()->getConfig('carriers') as $code => $carrier)
35
+ {
36
+ if (isset($carrier['title']))
37
+ {
38
+ $options[] = array(
39
+ 'value' => $code,
40
+ 'label' => $carrier['title']
41
+ );
42
+ }
43
+ }
44
+ return $options;
45
+ }
46
+
47
+ }
app/code/community/Artio/SMSNotifier/Model/System/Config/Source/SendToAdmin.php CHANGED
@@ -32,11 +32,7 @@ class Artio_SMSNotifier_Model_System_Config_Source_SendToAdmin
32
  */
33
  public function toOptionArray()
34
  {
35
- return array(
36
- array('value' => '0', 'label' => Mage::helper('smsnotify')->__('No')),
37
- array('value' => '1', 'label' => Mage::helper('smsnotify')->__('Primary number')),
38
- array('value' => '2', 'label' => Mage::helper('smsnotify')->__('Secondary number'))
39
- );
40
  }
41
 
42
 
@@ -51,19 +47,50 @@ class Artio_SMSNotifier_Model_System_Config_Source_SendToAdmin
51
 
52
  $options = array();
53
 
54
- foreach ($this->toOptionArray() as $item)
55
- $options[$item['value']] = $item['label'];
56
-
57
- $primary = Mage::getStoreConfig("smsnotify/general/primary_admin");
58
- $secondary = Mage::getStoreConfig("smsnotify/general/secondary_admin");
59
 
60
- $prmary = $config->sanitizeNumber($primary);
61
- $secondary = $config->sanitizeNumber($secondary);
62
 
63
  if ($primary)
64
- $options[1] = $options[1]." ($primary)";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  if ($secondary)
66
- $options[2] = $options[2]." ($secondary)";
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  return $options;
69
  }
32
  */
33
  public function toOptionArray()
34
  {
35
+ return $this->toOptions();
 
 
 
 
36
  }
37
 
38
 
47
 
48
  $options = array();
49
 
50
+ // No option
51
+ $options[] = array(
52
+ 'value' => '0',
53
+ 'label' => Mage::helper('smsnotify')->__('No')
54
+ );
55
 
56
+ // Primary admin option
57
+ $primary = $config->getPureAdminNumberByIndex(1);
58
 
59
  if ($primary)
60
+ {
61
+ $options[] = array(
62
+ 'value' => '1',
63
+ 'label' => Mage::helper('smsnotify')->__('Primary number (%s)', $config->sanitizeNumber($primary))
64
+ );
65
+ }
66
+ else
67
+ {
68
+ $options[] = array(
69
+ 'value' => '1',
70
+ 'label' => Mage::helper('smsnotify')->__('Primary number (not set)'),
71
+ 'disabled' => 'disabled'
72
+ );
73
+ }
74
+
75
+
76
+ // Secondary admin option
77
+ $secondary = $config->getPureAdminNumberByIndex(2);
78
+
79
  if ($secondary)
80
+ {
81
+ $options[] = array(
82
+ 'value' => '2',
83
+ 'label' => Mage::helper('smsnotify')->__('Secondary number (%s)', $config->sanitizeNumber($secondary))
84
+ );
85
+ }
86
+ else
87
+ {
88
+ $options[] = array(
89
+ 'value' => '2',
90
+ 'label' => Mage::helper('smsnotify')->__('Secondary number (not set)'),
91
+ 'disabled' => 'disabled'
92
+ );
93
+ }
94
 
95
  return $options;
96
  }
app/code/community/Artio/SMSNotifier/controllers/AdminhtmlController.php CHANGED
@@ -250,8 +250,6 @@ class Artio_SMSNotifier_AdminhtmlController extends Mage_Adminhtml_Controller_Ac
250
 
251
  if ($query)
252
  {
253
- $whereCond = "%".mysql_real_escape_string($query)."%";
254
-
255
  $custTable = Mage::getModel('core/resource')->getTableName('customer/entity');
256
 
257
  $customerAddressCollection = Mage::getModel('customer/address')
@@ -270,23 +268,21 @@ class Artio_SMSNotifier_AdminhtmlController extends Mage_Adminhtml_Controller_Ac
270
 
271
  if ($version['minor'] < 6) // magento 1.6.0.0 and higher use another alias table
272
  {
273
- $customerAddressCollection->getSelect()->where("
274
- `_table_firstname`.`value` LIKE '$whereCond'
275
- OR `_table_lastname`.`value` LIKE '$whereCond'
276
- OR `_table_c_firstname`.`value` LIKE '$whereCond'
277
- OR `_table_c_lastname`.`value` LIKE '$whereCond'
278
- OR `email` LIKE '$whereCond'
279
- ");
280
  }
281
  else
282
  {
283
- $customerAddressCollection->getSelect()->where("
284
- `at_firstname`.`value` LIKE '$whereCond'
285
- OR `at_lastname`.`value` LIKE '$whereCond'
286
- OR `at_c_firstname`.`value` LIKE '$whereCond'
287
- OR `at_c_lastname`.`value` LIKE '$whereCond'
288
- OR `email` LIKE '$whereCond'
289
- ");
290
  }
291
 
292
  foreach ($customerAddressCollection as $address)
@@ -299,6 +295,10 @@ class Artio_SMSNotifier_AdminhtmlController extends Mage_Adminhtml_Controller_Ac
299
 
300
  }
301
 
 
 
 
 
302
  // if user enters number then we have to suggest it
303
  if (preg_match('/^[0-9]+$/', $query))
304
  array_unshift($result, $this->_buildLiElement("", "", $query, ""));
250
 
251
  if ($query)
252
  {
 
 
253
  $custTable = Mage::getModel('core/resource')->getTableName('customer/entity');
254
 
255
  $customerAddressCollection = Mage::getModel('customer/address')
268
 
269
  if ($version['minor'] < 6) // magento 1.6.0.0 and higher use another alias table
270
  {
271
+ $customerAddressCollection->getSelect()
272
+ ->where("`_table_firstname`.`value` LIKE ?", "%$query%")
273
+ ->orWhere("`_table_lastname`.`value` LIKE ?", "%$query%")
274
+ ->orWhere("`_table_c_firstname`.`value` LIKE ?", "%$query%")
275
+ ->orWhere("`_table_c_lastname`.`value` LIKE ?", "%$query%")
276
+ ->orWhere("`email` LIKE ?", "%$query%");
 
277
  }
278
  else
279
  {
280
+ $customerAddressCollection->getSelect()
281
+ ->where("`at_firstname`.`value` LIKE ?", "%$query%")
282
+ ->orWhere("`at_lastname`.`value` LIKE ?", "%$query%")
283
+ ->orWhere("`at_c_firstname`.`value` LIKE ?", "%$query%")
284
+ ->orWhere("`at_c_lastname`.`value` LIKE ?", "%$query%")
285
+ ->orWhere("`email` LIKE ?", "%$query%");
 
286
  }
287
 
288
  foreach ($customerAddressCollection as $address)
295
 
296
  }
297
 
298
+ // if user enters number with spaces we trim spaces
299
+ if (preg_match('/^[0-9\t ]+$/', $query))
300
+ $query = str_replace(array(' ', '\t'), array('', ''), $query);
301
+
302
  // if user enters number then we have to suggest it
303
  if (preg_match('/^[0-9]+$/', $query))
304
  array_unshift($result, $this->_buildLiElement("", "", $query, ""));
app/code/community/Artio/SMSNotifier/etc/config.xml CHANGED
@@ -18,7 +18,7 @@
18
  <config>
19
  <modules>
20
  <Artio_SMSNotifier>
21
- <version>1.1.0</version>
22
  </Artio_SMSNotifier>
23
  </modules>
24
  <admin>
@@ -95,6 +95,15 @@
95
  </events>
96
  </global>
97
  <adminhtml>
 
 
 
 
 
 
 
 
 
98
  <layout>
99
  <updates>
100
  <smsnotify>
@@ -139,6 +148,7 @@
139
  <unicode>0</unicode>
140
  <min_length_with_prefix>9</min_length_with_prefix>
141
  <used_addresses>billing</used_addresses>
 
142
  <log>0</log>
143
  </general>
144
  <country_filter>
18
  <config>
19
  <modules>
20
  <Artio_SMSNotifier>
21
+ <version>1.1.2</version>
22
  </Artio_SMSNotifier>
23
  </modules>
24
  <admin>
95
  </events>
96
  </global>
97
  <adminhtml>
98
+ <translate>
99
+ <modules>
100
+ <Artio_SMSNotifier>
101
+ <files>
102
+ <default>Artio_SMSNotify.csv</default>
103
+ </files>
104
+ </Artio_SMSNotifier>
105
+ </modules>
106
+ </translate>
107
  <layout>
108
  <updates>
109
  <smsnotify>
148
  <unicode>0</unicode>
149
  <min_length_with_prefix>9</min_length_with_prefix>
150
  <used_addresses>billing</used_addresses>
151
+ <trim_zero>0</trim_zero>
152
  <log>0</log>
153
  </general>
154
  <country_filter>
app/code/community/Artio/SMSNotifier/etc/system.xml CHANGED
@@ -126,6 +126,16 @@
126
  <show_in_website>1</show_in_website>
127
  <show_in_store>1</show_in_store>
128
  </min_length_with_prefix>
 
 
 
 
 
 
 
 
 
 
129
  <used_addresses translate="label comment" module="smsnotify">
130
  <label>Customer's phone numbers primarily get from</label>
131
  <comment>If you choose billing address then SMS will be sent to numbers from a billing address and if phone number was not present there then would be used phone numbers from a shipping address and vice versa. If customer's phone number was not found then SMS would not be sent.</comment>
@@ -235,7 +245,7 @@
235
  </to_customer>
236
  <to_admin translate="label comment" module="smsnotify">
237
  <label>Notify admin</label>
238
- <frontend_type>select</frontend_type>
239
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
240
  <sort_order>30</sort_order>
241
  <show_in_default>1</show_in_default>
@@ -252,6 +262,29 @@
252
  <show_in_store>1</show_in_store>
253
  <depends><enabled>1</enabled></depends>
254
  </sms_text>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  </fields>
256
  </new_order>
257
  <new_invoice translate="label comment" module="smsnotify">
@@ -283,7 +316,7 @@
283
  </to_customer>
284
  <to_admin translate="label comment" module="smsnotify">
285
  <label>Notify admin</label>
286
- <frontend_type>select</frontend_type>
287
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
288
  <sort_order>30</sort_order>
289
  <show_in_default>1</show_in_default>
@@ -300,6 +333,29 @@
300
  <show_in_store>1</show_in_store>
301
  <depends><enabled>1</enabled></depends>
302
  </sms_text>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  </fields>
304
  </new_invoice>
305
  <new_shipment translate="label comment" module="smsnotify">
@@ -331,7 +387,7 @@
331
  </to_customer>
332
  <to_admin translate="label comment" module="smsnotify">
333
  <label>Notify admin</label>
334
- <frontend_type>select</frontend_type>
335
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
336
  <sort_order>30</sort_order>
337
  <show_in_default>1</show_in_default>
@@ -348,6 +404,29 @@
348
  <show_in_store>1</show_in_store>
349
  <depends><enabled>1</enabled></depends>
350
  </sms_text>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  </fields>
352
  </new_shipment>
353
  </groups>
126
  <show_in_website>1</show_in_website>
127
  <show_in_store>1</show_in_store>
128
  </min_length_with_prefix>
129
+ <trim_zero translate="label comment" module="smsnotify">
130
+ <label>Remove zero digits from start of the numbers</label>
131
+ <comment>If you enable this then number 00824108740 with country code 27 will be transformed to 27824108740, i.e. the zero digits at start will be removed before adding country code (otherwise number would be 2700824108740).</comment>
132
+ <frontend_type>select</frontend_type>
133
+ <source_model>adminhtml/system_config_source_yesno</source_model>
134
+ <sort_order>40</sort_order>
135
+ <show_in_default>1</show_in_default>
136
+ <show_in_website>1</show_in_website>
137
+ <show_in_store>1</show_in_store>
138
+ </trim_zero>
139
  <used_addresses translate="label comment" module="smsnotify">
140
  <label>Customer's phone numbers primarily get from</label>
141
  <comment>If you choose billing address then SMS will be sent to numbers from a billing address and if phone number was not present there then would be used phone numbers from a shipping address and vice versa. If customer's phone number was not found then SMS would not be sent.</comment>
245
  </to_customer>
246
  <to_admin translate="label comment" module="smsnotify">
247
  <label>Notify admin</label>
248
+ <frontend_type>selectex</frontend_type>
249
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
250
  <sort_order>30</sort_order>
251
  <show_in_default>1</show_in_default>
262
  <show_in_store>1</show_in_store>
263
  <depends><enabled>1</enabled></depends>
264
  </sms_text>
265
+ <dissallow_for_shipping_methods translate="label" module="smsnotify">
266
+ <label>Disallow sending SMS for shipping specific methods</label>
267
+ <frontend_type>select</frontend_type>
268
+ <source_model>adminhtml/system_config_source_yesno</source_model>
269
+ <sort_order>50</sort_order>
270
+ <show_in_default>1</show_in_default>
271
+ <show_in_website>1</show_in_website>
272
+ <show_in_store>1</show_in_store>
273
+ <depends><enabled>1</enabled></depends>
274
+ </dissallow_for_shipping_methods>
275
+ <disallowed_shipping_methods>
276
+ <label>Disallowed shipping methods</label>
277
+ <frontend_type>multiselect</frontend_type>
278
+ <sort_order>60</sort_order>
279
+ <source_model>smsnotify/source_shippingMethods</source_model>
280
+ <show_in_default>1</show_in_default>
281
+ <show_in_website>1</show_in_website>
282
+ <show_in_store>1</show_in_store>
283
+ <depends>
284
+ <enabled>1</enabled>
285
+ <dissallow_for_shipping_methods>1</dissallow_for_shipping_methods>
286
+ </depends>
287
+ </disallowed_shipping_methods>
288
  </fields>
289
  </new_order>
290
  <new_invoice translate="label comment" module="smsnotify">
316
  </to_customer>
317
  <to_admin translate="label comment" module="smsnotify">
318
  <label>Notify admin</label>
319
+ <frontend_type>selectex</frontend_type>
320
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
321
  <sort_order>30</sort_order>
322
  <show_in_default>1</show_in_default>
333
  <show_in_store>1</show_in_store>
334
  <depends><enabled>1</enabled></depends>
335
  </sms_text>
336
+ <dissallow_for_shipping_methods translate="label" module="smsnotify">
337
+ <label>Disallow sending SMS for shipping specific methods</label>
338
+ <frontend_type>select</frontend_type>
339
+ <source_model>adminhtml/system_config_source_yesno</source_model>
340
+ <sort_order>50</sort_order>
341
+ <show_in_default>1</show_in_default>
342
+ <show_in_website>1</show_in_website>
343
+ <show_in_store>1</show_in_store>
344
+ <depends><enabled>1</enabled></depends>
345
+ </dissallow_for_shipping_methods>
346
+ <disallowed_shipping_methods>
347
+ <label>Disallowed shipping methods</label>
348
+ <frontend_type>multiselect</frontend_type>
349
+ <sort_order>60</sort_order>
350
+ <source_model>smsnotify/source_shippingMethods</source_model>
351
+ <show_in_default>1</show_in_default>
352
+ <show_in_website>1</show_in_website>
353
+ <show_in_store>1</show_in_store>
354
+ <depends>
355
+ <enabled>1</enabled>
356
+ <dissallow_for_shipping_methods>1</dissallow_for_shipping_methods>
357
+ </depends>
358
+ </disallowed_shipping_methods>
359
  </fields>
360
  </new_invoice>
361
  <new_shipment translate="label comment" module="smsnotify">
387
  </to_customer>
388
  <to_admin translate="label comment" module="smsnotify">
389
  <label>Notify admin</label>
390
+ <frontend_type>selectex</frontend_type>
391
  <source_model>smsnotify/system_config_source_sendToAdmin</source_model>
392
  <sort_order>30</sort_order>
393
  <show_in_default>1</show_in_default>
404
  <show_in_store>1</show_in_store>
405
  <depends><enabled>1</enabled></depends>
406
  </sms_text>
407
+ <dissallow_for_shipping_methods translate="label" module="smsnotify">
408
+ <label>Disallow sending SMS for shipping specific methods</label>
409
+ <frontend_type>select</frontend_type>
410
+ <source_model>adminhtml/system_config_source_yesno</source_model>
411
+ <sort_order>50</sort_order>
412
+ <show_in_default>1</show_in_default>
413
+ <show_in_website>1</show_in_website>
414
+ <show_in_store>1</show_in_store>
415
+ <depends><enabled>1</enabled></depends>
416
+ </dissallow_for_shipping_methods>
417
+ <disallowed_shipping_methods>
418
+ <label>Disallowed shipping methods</label>
419
+ <frontend_type>multiselect</frontend_type>
420
+ <sort_order>60</sort_order>
421
+ <source_model>smsnotify/source_shippingMethods</source_model>
422
+ <show_in_default>1</show_in_default>
423
+ <show_in_website>1</show_in_website>
424
+ <show_in_store>1</show_in_store>
425
+ <depends>
426
+ <enabled>1</enabled>
427
+ <dissallow_for_shipping_methods>1</dissallow_for_shipping_methods>
428
+ </depends>
429
+ </disallowed_shipping_methods>
430
  </fields>
431
  </new_shipment>
432
  </groups>
js/artio/numberfilters.js ADDED
@@ -0,0 +1,1385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Setup select.
3
+ */
4
+ document.observe('dom:loaded', function(event) {
5
+ var select = $('smsnotify_general_local_country');
6
+ var hidden = $('smsnotify_general_local_country-hidden');
7
+
8
+ if (select && hidden)
9
+ {
10
+ select.childElements().each(function(option, index) {
11
+ if (option.value == hidden.value)
12
+ select.selectedIndex = index;
13
+ });
14
+ }
15
+
16
+ var select = $('smsnotify_general_min_length_with_prefix');
17
+ var hidden = $('smsnotify_general_min_length_with_prefix-hidden');
18
+
19
+ if (select && hidden)
20
+ {
21
+ select.childElements().each(function(option, index) {
22
+ if (option.value == hidden.value)
23
+ select.selectedIndex = index;
24
+ });
25
+ }
26
+ });
27
+
28
+
29
+ /**
30
+ * Number Filters Util
31
+ * Library of some useful functions which is missing
32
+ * in the standard JavaScript.
33
+ */
34
+ NFU = {
35
+
36
+
37
+ /**
38
+ * Function walks through all element's in the list and calls
39
+ * callback whith item and index as arguments.
40
+ *
41
+ * If list or callback is not specifie function
42
+ * does nothing.
43
+ */
44
+ each: function(list, callback)
45
+ {
46
+ if (!list || !callback)
47
+ return;
48
+
49
+ for (var i=0; i<list.length; i++)
50
+ callback(list[i], i);
51
+ },
52
+
53
+
54
+ /**
55
+ * Function returns first item of a list which satisfies a condition.
56
+ * Condition is a function which returns a bool value (true/false).
57
+ *
58
+ * If the condition is not defined function returns first
59
+ * item of array.
60
+ *
61
+ * If list is not specified or any child does not satisfy
62
+ * the condition then function returns null.
63
+ */
64
+ first: function(list, condition)
65
+ {
66
+ if (!list)
67
+ return null;
68
+
69
+ if (!condition)
70
+ condition = function() { return true; }
71
+
72
+ for (var i=0; i<list.length; i++)
73
+ if (condition(list[i]))
74
+ return list[i];
75
+
76
+ return null;
77
+ },
78
+
79
+
80
+ /**
81
+ * Function returns last item of a list which satisfies a condition.
82
+ *
83
+ * If the condition is not defined then function returns last
84
+ * item of array.
85
+ *
86
+ * If the list is not specified or any child does not satisfy
87
+ * the condition then function returns null.
88
+ */
89
+ last: function(list, condition)
90
+ {
91
+ if (!list)
92
+ return null;
93
+
94
+ if (!condition)
95
+ condition = function() { return true; }
96
+
97
+ var lastsatisfy = null;
98
+
99
+ for (var i=0; i<list.length; i++)
100
+ if (condition(list[i]))
101
+ lastsatisfy = list[i];
102
+
103
+ return lastsatisfy;
104
+ },
105
+
106
+
107
+ /**
108
+ * Function walk through all chars in a string and
109
+ * call a callback on each.
110
+ *
111
+ * You can walk forward (reverse = false) or
112
+ * backward (reverse = true).
113
+ *
114
+ * If string or the callback is not defined function
115
+ * does nothing.
116
+ */
117
+ eachChars: function(string, reverse, callback)
118
+ {
119
+ if (!string || !callback)
120
+ return;
121
+
122
+ var start = reverse ? string.length-1 : 0;
123
+ var end = reverse ? 0 : string.length;
124
+ var step = reverse ? -1 : +1;
125
+
126
+ for (i=start; i!=end; i=i+step) {
127
+ callback(string.charAt(i), i);
128
+ }
129
+ },
130
+
131
+
132
+ /**
133
+ * Function walks through all childs of an element
134
+ * with specified a tagNam and call a callable
135
+ * on each.
136
+ *
137
+ * Callable is a function.
138
+ *
139
+ * If tagName is not specified function walks
140
+ * through all chidls (include text nodes).
141
+ *
142
+ * If the element or the callable is not specified
143
+ * function does nothing.
144
+ */
145
+ eachChilds: function(element, tagName, callable)
146
+ {
147
+ if (!element || !callable)
148
+ return;
149
+
150
+ var childs = NFU.getChilds(element, tagName);
151
+ NFU.each(childs, callable);
152
+ },
153
+
154
+
155
+ /**
156
+ * Function get first element with tagName which
157
+ * satisfy a condition.
158
+ *
159
+ * If tagName is not specified function returns
160
+ * any first element which satisfy a condition.
161
+ *
162
+ * If the condition is not defined function returns
163
+ * first element withot testing.
164
+ *
165
+ * If element is not specified function does nothing.
166
+ */
167
+ firstChild: function(element, tagName, condition)
168
+ {
169
+ var childs = NFU.getChilds(element, tagName);
170
+ return NFU.first(childs, condition);
171
+ },
172
+
173
+
174
+ /**
175
+ * Function get last element with tagName which
176
+ * satisfy a condition.
177
+ *
178
+ * If tagName is not specified function returns
179
+ * any last element which satisfy a condition.
180
+ *
181
+ * If the condition is not defined function returns
182
+ * last element withot testing.
183
+ *
184
+ * If element is not specified function does nothing.
185
+ */
186
+ lastChild: function(element, tagName, condition)
187
+ {
188
+ var childs = NFU.getChilds(element, tagName);
189
+ return NFU.last(childs, condition);
190
+ },
191
+
192
+
193
+ /**
194
+ * Function get first parent with tagName.
195
+ *
196
+ * If element is not define or there is no
197
+ * parent with specified tagName function returns
198
+ * null.
199
+ *
200
+ * If tagName is not specified method retruns
201
+ * first parent no matter tagName.
202
+ */
203
+ firstParent: function(element, tagName)
204
+ {
205
+ if (!element)
206
+ return null;
207
+
208
+ var parent = element.parentNode;
209
+
210
+ while (parent && tagName && parent.tagName != tagName)
211
+ parent = parent.parentNode;
212
+
213
+ if (parent && tagName && parent.tagName == tagName)
214
+ return parent;
215
+ else
216
+ return null;
217
+ },
218
+
219
+
220
+ /**
221
+ * Function rerurns all element's childrens.
222
+ *
223
+ * Note searching is non-recursive there are returned only
224
+ * childrens in the first "generations".
225
+ *
226
+ * You can restrict visited childrens by tag name.
227
+ *
228
+ * If tag name is not specified function returns all
229
+ * childrens (e.g: text nodes)
230
+ *
231
+ * If element is not specifie function
232
+ * does nothing.
233
+ */
234
+ getChilds: function(element, tagName)
235
+ {
236
+ if (!element)
237
+ return;
238
+
239
+ var result = [];
240
+
241
+ for (var i=0; i<element.childNodes.length; i++)
242
+ {
243
+ if (!tagName || (element.childNodes[i].tagName == tagName))
244
+ {
245
+ result.push(element.childNodes[i]);
246
+ }
247
+ }
248
+
249
+ return result;
250
+ },
251
+
252
+
253
+ /**
254
+ * Function rerurns all element's childrens.
255
+ *
256
+ * Note searching is recursive (deep) there are returned all
257
+ * childrens.
258
+ *
259
+ * You can restrict visited childrens by tag name.
260
+ *
261
+ * If tag name is not specified function returns all
262
+ * childrens (e.g: text nodes)
263
+ *
264
+ * If element is not specifie function
265
+ * does nothing.
266
+ */
267
+ getChildsRecursively: function(element, tagName)
268
+ {
269
+ if (!element)
270
+ return;
271
+
272
+ var result = [];
273
+
274
+ for (var i=0; i<element.childNodes.length; i++)
275
+ {
276
+ if (!tagName || (element.childNodes[i].tagName == tagName))
277
+ {
278
+ result.push(element.childNodes[i]);
279
+ }
280
+
281
+ NFU.each(NFU.getChildsRecursively(element.childNodes[i], tagName), function(child) {
282
+ result.push(child);
283
+ });
284
+ }
285
+
286
+ return result;
287
+ },
288
+
289
+
290
+ /**
291
+ * Function returns all element which satisfy className
292
+ * and tagName.
293
+ *
294
+ * Argument className is mandatory, if missing function
295
+ * returns empty array.
296
+ *
297
+ * Argument tagName is optional.
298
+ */
299
+ getElementsByClassName: function(className, tagName)
300
+ {
301
+ if (!className)
302
+ return [];
303
+
304
+ if (!tagName)
305
+ tagName = '*';
306
+
307
+ var result = [];
308
+
309
+ var elements = document.getElementsByTagName(tagName);
310
+
311
+ for (var i=0; i<elements.length; i++)
312
+ if (NFU.hasClassName(elements[i], className))
313
+ result.push(elements[i]);
314
+
315
+ return result;
316
+ },
317
+
318
+
319
+ /**
320
+ * Function determines whether element's attribute
321
+ * "className" contains a className or not
322
+ *
323
+ * element - tested element
324
+ * className - tested className
325
+ *
326
+ * Function returns true when element's attribute "className"
327
+ * contains className, otherwise function returns false.
328
+ *
329
+ * If element or className is not defined function returns false.
330
+ */
331
+ hasClassName: function(element, className)
332
+ {
333
+ if (!element || !className)
334
+ return false;
335
+
336
+ var reg = new RegExp("(^|\\s)" + className + "(\\s|$)");
337
+
338
+ return reg.test(element.className);
339
+ },
340
+
341
+
342
+ /**
343
+ * Function remove a className from the class attribute
344
+ * of an element.
345
+ *
346
+ * If element or className is not specified function
347
+ * does nothing.
348
+ */
349
+ removeClassName: function(element, className)
350
+ {
351
+ if (!element || !className)
352
+ return;
353
+
354
+ element.className = element.className.replace(className, '');
355
+ },
356
+
357
+
358
+ /**
359
+ * Function add a className to an element.
360
+ *
361
+ * If element or className is not specified or element
362
+ * already has className function does nothing.
363
+ */
364
+ addClassName: function(element, className)
365
+ {
366
+ if (!element || !className)
367
+ return false;
368
+
369
+ if (!NFU.hasClassName(element, className))
370
+ element.className = element.className + " " + className;
371
+ }
372
+
373
+
374
+ };
375
+
376
+
377
+ /**
378
+ *
379
+ */
380
+ function FilterTable(id, filters)
381
+ {
382
+ /* this instance */
383
+ var self = this;
384
+
385
+
386
+ /* if of element TABLE represented this filters */
387
+ this.id = id;
388
+
389
+
390
+ /* instance of ancestor object */
391
+ this.filters = filters;
392
+
393
+
394
+ /* TABLE element represented this filters */
395
+ this.table = document.getElementById(id);
396
+ /* ROW element which is template for making another rows */
397
+ this.template_row = document.getElementById(id+'-template');
398
+ /* INPUT fields where are stored serialized values */
399
+ this.field = document.getElementById(id+'-field');
400
+ /* SELECT element with countries (you can switch the lists of filters by this) */
401
+ this.country_select = document.getElementById(this.id+'-country');
402
+
403
+
404
+ /**
405
+ * Internal data.
406
+ * Here are stored rows for all countries. This is important
407
+ * because there may be filters for not selected country.
408
+ *
409
+ * {
410
+ * country1 => [row1, row2, ...],
411
+ * country2 => [row1, row2, ...]
412
+ * ...
413
+ * }
414
+ */
415
+ this.data = {};
416
+
417
+
418
+ /**
419
+ * Add filter to table for a country. If the country
420
+ * is not specified function gets current displayed country.
421
+ *
422
+ * This function makes a TR element for filter and
423
+ * insert it to internal this.data.
424
+ *
425
+ * If there is displayed the country which is
426
+ * the inserted filter assigned for then the row
427
+ * is appended to table.
428
+ *
429
+ * Function does not validate filter.
430
+ * Function does not check the duplicity.
431
+ */
432
+ this.addFilter = function(filter, country)
433
+ {
434
+ // country is not specified, get current displayed
435
+ if (!country)
436
+ country = this.getCurrentCountry();
437
+
438
+ // create new row by template
439
+ var newrow = this.template_row.cloneNode(true);
440
+
441
+ // clear some attributes
442
+ newrow.id = "";
443
+ newrow.style.display = "";
444
+
445
+ // fill data
446
+ NFU.each(NFU.getChildsRecursively(newrow, 'SPAN'), function(span) {
447
+ if (NFU.hasClassName(span, 'value'))
448
+ span.innerHTML = filter;
449
+ if (NFU.hasClassName(span, 'prefix'))
450
+ span.innerHTML = self.filters.getDialingCode(country);
451
+ });
452
+
453
+ // assign new row to data
454
+ if (this.data[country])
455
+ this.data[country].push(newrow);
456
+ else
457
+ this.data[country] = [newrow];
458
+
459
+ // display row immediatly for current country
460
+ if (country == this.getCurrentCountry())
461
+ this.table.appendChild(newrow);
462
+
463
+ // update input field with serialized data
464
+ this.updateField();
465
+ };
466
+
467
+
468
+ /**
469
+ * Update existed row by a new filter value.
470
+ *
471
+ * Function expected exactly TR element (they
472
+ * are stored in this.data).
473
+ */
474
+ this.updateFilter = function(element, filter)
475
+ {
476
+ // search span 'value' and update them
477
+ NFU.each(NFU.getChildsRecursively(element, 'SPAN'), function(span) {
478
+ if (NFU.hasClassName(span, 'value'))
479
+ span.innerHTML = filter;
480
+ });
481
+
482
+ // update input field with serialized data
483
+ this.updateField();
484
+ };
485
+
486
+
487
+ /**
488
+ * Remove a filter specified by its TR tag or some of
489
+ * its children (row).
490
+ *
491
+ * If TR tag is not found function does nothing
492
+ */
493
+ this.removeFilter = function(row)
494
+ {
495
+ // search parent TR
496
+ if (row.tagName != 'TR')
497
+ row = NFU.firstParent(row, 'TR');
498
+ if (row.tagName != 'TR')
499
+ return;
500
+
501
+ // remove row from internal data
502
+ for (var country in this.data) {
503
+ var index = this.data[country].indexOf(row);
504
+ if (index != -1)
505
+ this.data[country].splice(index, 1);
506
+ }
507
+
508
+ // remove from table immediatly
509
+ row.parentNode.removeChild(row);
510
+ // update input field with serialized data
511
+ this.updateField();
512
+ };
513
+
514
+
515
+ /**
516
+ * Extract the filter value from a row.
517
+ *
518
+ * This function works for all instances same way.
519
+ */
520
+ this.getValueByRow = function(row)
521
+ {
522
+ var val = "";
523
+
524
+ // search value as HTML of SPAN 'value'
525
+ NFU.each(NFU.getChildsRecursively(row, 'SPAN'), function(span) {
526
+ if (NFU.hasClassName(span, 'value')) {
527
+ val = span.innerHTML;
528
+ }
529
+ });
530
+
531
+ return val;
532
+ };
533
+
534
+
535
+ /**
536
+ * Get current the displayed country.
537
+ * Value is get from this.country_select.
538
+ */
539
+ this.getCurrentCountry = function()
540
+ {
541
+ return this.country_select.options[this.country_select.selectedIndex].value;
542
+ };
543
+
544
+
545
+ /**
546
+ * Change country. This function is an event handler of
547
+ * event "change" of this.country_select.
548
+ *
549
+ * Function removes all rows from TABLE (not from this.data)
550
+ * and again add all rows for new country.
551
+ */
552
+ this.changeCountry = function()
553
+ {
554
+ // get current displayed country
555
+ var country = this.getCurrentCountry();
556
+ // remove all TR from table
557
+ this.removeAllRows();
558
+
559
+ // walk through internal data and add rows
560
+ // for the new displayed country
561
+ if (this.data[country]) {
562
+ NFU.each(this.data[country], function(row) {
563
+ self.addExistedRow(row);
564
+ });
565
+ }
566
+
567
+ // set class name for table
568
+ if (this.data[country])
569
+ NFU.removeClassName(this.filters.div, 'empty-filter');
570
+ else
571
+ NFU.addClassName(this.filters.div, 'empty-filter');
572
+ };
573
+
574
+
575
+ /**
576
+ * Function removes all TR elements from TABLE
577
+ * (except template row).
578
+ *
579
+ * Function removes only TR elements not rows
580
+ * from this.data.
581
+ */
582
+ this.removeAllRows = function()
583
+ {
584
+ NFU.eachChilds(this.table, 'TR', function(row) {
585
+ if (!NFU.hasClassName(row, this.id+'-template'))
586
+ row.parentNode.removeChild(row);
587
+ });
588
+ };
589
+
590
+
591
+ /**
592
+ * Function adds an existed row (TR) element
593
+ * to TABLE.
594
+ */
595
+ this.addExistedRow = function(row)
596
+ {
597
+ this.table.appendChild(row);
598
+ };
599
+
600
+
601
+ /**
602
+ * Function updates INPUT fields with serialized values
603
+ * from this.data values.
604
+ *
605
+ * Function also adds className 'has-filter' to OPTIONs of this.country_select
606
+ * whih have some filters and removes this className from OPTIONs without filters.
607
+ *
608
+ * Filters will be sorted so that countries with filters preceeds the countries
609
+ * without filters.
610
+ *
611
+ * Format:
612
+ *
613
+ * COUNTRY_CODE1,DIAL1,FILTER1;COUNTRY_CODE2,DIAL2,FILTER2;COUNTRY_CODE3,DIAL3,FILTER3 ...
614
+ */
615
+ this.updateField = function()
616
+ {
617
+ var vals = [];
618
+
619
+ // get values for each country
620
+ for (var country in this.data) {
621
+ NFU.each(this.data[country], function(row) {
622
+ vals.push(country+','+self.getValueByRow(row));
623
+ });
624
+ }
625
+
626
+ // set serialized values
627
+ this.field.value = vals.join(';');
628
+
629
+ // remember selected countries
630
+ var selected = '';
631
+
632
+ NFU.eachChilds(this.country_select, 'OPTION', function(option)
633
+ {
634
+ if (option.selected)
635
+ selected = option.value;
636
+ });
637
+
638
+ var with_filters = [];
639
+ var without_filters = [];
640
+
641
+ // remove filters
642
+ NFU.eachChilds(this.country_select, 'OPTION', function(option)
643
+ {
644
+ if (self.data[option.value] && self.data[option.value].length > 0)
645
+ with_filters.push(option);
646
+ else
647
+ without_filters.push(option);
648
+
649
+ self.country_select.removeChild(option);
650
+ });
651
+
652
+ // sort both lists
653
+ var sort_func = function sort(i1, i2) {
654
+ return i1.innerHTML < i2.innerHTML ? -1 : i1.innerHTML > i2.innerHTML
655
+ };
656
+
657
+ with_filters.sort(sort_func);
658
+ without_filters.sort(sort_func);
659
+
660
+ // append countries with filters
661
+ NFU.each(with_filters, function(option) {
662
+ NFU.addClassName(option, 'has-filter');
663
+ if (option.value == selected)
664
+ option.selected = true;
665
+ self.country_select.appendChild(option);
666
+ });
667
+
668
+ // append countries without filters
669
+ NFU.each(without_filters, function(option) {
670
+ NFU.removeClassName(option, 'has-filter');
671
+ self.country_select.appendChild(option);
672
+ });
673
+
674
+ // select
675
+ NFU.eachChilds(this.country_select, 'OPTION', function(option, index) {
676
+ if (option.value == selected)
677
+ self.country_select.selectedIndex = index;
678
+ });
679
+
680
+ // set class name for table
681
+ if (this.field.value)
682
+ NFU.removeClassName(this.filters.div, 'empty-filter');
683
+ else
684
+ NFU.addClassName(this.filters.div, 'empty-filter');
685
+ };
686
+
687
+
688
+ /**
689
+ * Function get value from this.field and parses it
690
+ * and fills the filter rows by this.
691
+ *
692
+ * Format:
693
+ *
694
+ * COUNTRY_CODE1,DIAL1,FILTER1;COUNTRY_CODE2,DIAL2,FILTER2;COUNTRY_CODE3,DIAL3,FILTER3 ...
695
+ */
696
+ this.loadValue = function()
697
+ {
698
+ // get value
699
+ var val = this.field.value;
700
+
701
+ // set class name for table
702
+ if (val)
703
+ NFU.removeClassName(this.filters.div, 'empty-filter');
704
+ else
705
+ NFU.addClassName(this.filters.div, 'empty-filter');
706
+
707
+ // if there is no value does nothing
708
+ if (!val)
709
+ return;
710
+
711
+ // clear internal data
712
+ this.data = {};
713
+ // remove all TR elements
714
+ this.removeAllRows();
715
+
716
+ // validator for filter pattern
717
+ var validator = new RegExp('^[0-9\?]{0,15}[0-9\?*](-[0-9\?]{0,15}[0-9\?*])?$');
718
+
719
+ var vals = val.split(';');
720
+
721
+ // walk through all rows
722
+ NFU.each(vals, function(val) {
723
+
724
+ // split to parts
725
+ var parts = val.split(',');
726
+
727
+ // if number of parts does not corespond skip row
728
+ if (parts.length != 3)
729
+ return;
730
+
731
+ // extract values
732
+ var country = parts[0];
733
+ var dial = parts[1];
734
+ var filter = parts[2];
735
+
736
+ // test filter
737
+ if (!validator.test(filter))
738
+ return;
739
+
740
+ // all is right, add filter
741
+ self.addFilter(filter, country+','+dial);
742
+ });
743
+ };
744
+ };
745
+
746
+
747
+ /**
748
+ *
749
+ */
750
+ function FilterDialog(id, filters) {
751
+
752
+ /* this instance */
753
+ var self = this;
754
+
755
+
756
+ /* if of element TABLE represented this filters */
757
+ this.id = id;
758
+
759
+
760
+ /* instance of ancestor object */
761
+ this.filters = filters;
762
+
763
+ /* DIV dialog */
764
+ this.div = document.getElementById(id);
765
+ /* DIV with digits in first row (pattern, left side of interval) */
766
+ this.digits1 = document.getElementById(this.id+'-digits-1');
767
+ /* DIV with digits in second row (right side of interval) */
768
+ this.digits2 = document.getElementById(this.id+'-digits-2');
769
+ /* INPUT radio for PATTERN */
770
+ this.type1 = document.getElementById(this.id+'-type-1');
771
+ /* INPUT radio for RANGE */
772
+ this.type2 = document.getElementById(this.id+'-type-2');
773
+
774
+
775
+ /**
776
+ * Set a fliter value to dialog.
777
+ *
778
+ * Function setup radiobuttons and set digits.
779
+ *
780
+ * If filter is not specified then there will be used
781
+ * '*' value.
782
+ */
783
+ this.setValue = function(filter)
784
+ {
785
+ if (!filter)
786
+ filter = '*';
787
+
788
+ this.clear();
789
+
790
+ // parse filter value
791
+ var parts = filter.split('-');
792
+ var isRange = parts.length == 2;
793
+
794
+ this.setType(isRange);
795
+ this.setDigits(this.digits1, parts[0]);
796
+
797
+ if (isRange)
798
+ this.setDigits(this.digits2, parts[1]);
799
+ };
800
+
801
+
802
+ /**
803
+ * Clear dialog (analogy set to '*').
804
+ */
805
+ this.clear = function()
806
+ {
807
+ this.setType(false);
808
+ this.setDigits(this.digits1, '*');
809
+ this.setDigits(this.digits2, '*');
810
+ };
811
+
812
+
813
+ /**
814
+ * Set filter type (RANGE or PATTERN).
815
+ *
816
+ * Function set radion buttons and show/hide
817
+ * the div with second digits (right side of inteval).
818
+ */
819
+ this.setType = function(isRange)
820
+ {
821
+ if (isRange) {
822
+ this.type1.checked = "";
823
+ this.type2.checked = "checked";
824
+ this.digits2.style.display = 'block';
825
+ } else {
826
+ this.type1.checked = "checked";
827
+ this.type2.checked = "";
828
+ this.digits2.style.display = 'none';
829
+ }
830
+ };
831
+
832
+
833
+ /**
834
+ * Set digits.
835
+ */
836
+ this.setDigits = function(digits, value)
837
+ {
838
+ // set first digit to '*', it also removes
839
+ // all followed digits
840
+ var firstSelect = NFU.firstChild(digits, 'SELECT');
841
+ firstSelect.selectedIndex = 0;
842
+ self.selectDigit(firstSelect);
843
+
844
+ // now walk through filter value and select
845
+ // correspond digits
846
+ NFU.eachChars(value, false, function(char) {
847
+ lastSelect = NFU.lastChild(digits, 'SELECT');
848
+ // 0 - *, 1-10 - digits [0-9], 11 - ?
849
+ lastSelect.selectedIndex = (char == '?') ? 11 : new Number(char)+1;
850
+ self.selectDigit(lastSelect);
851
+ });
852
+ };
853
+
854
+
855
+ /**
856
+ * Select single digit. Elem is SELECT represented
857
+ * the position for the digit.
858
+ */
859
+ this.selectDigit = function(elem)
860
+ {
861
+ // get parent element for adding/removing digits
862
+ var parent = elem.parentNode;
863
+ // count of digits helps to determine whether
864
+ // selected digits is last or not
865
+ var count_select = NFU.getChilds(parent, 'SELECT').length;
866
+
867
+ // get last child and last select
868
+ // last child may be a text node i.e last child != last select
869
+ var lastChild = NFU.lastChild(parent);
870
+ var lastSelect = NFU.lastChild(parent, 'SELECT');
871
+
872
+ // user choose '*' and there is a digit (SELECT)
873
+ // so we have to remove all followed digits (SELECTs)
874
+ if (elem.value == '*' && count_select > 0) {
875
+ while (lastChild && lastChild != elem) {
876
+ parent.removeChild(lastChild);
877
+ lastChild = NFU.lastChild(parent);
878
+ }
879
+ // user choose a digit or ? for non-last select
880
+ // (there is max 16 digits because phone numbers)
881
+ // so we have to add next digits
882
+ } else if (elem == lastSelect && count_select < 16) {
883
+ var select = document.createElement('SELECT');
884
+ this.filters.initOptions(select, this.filters.digits, '*');
885
+ select.onclick = function() { self.selectDigit(select); };
886
+ parent.appendChild(select);
887
+ }
888
+ };
889
+
890
+
891
+ /**
892
+ * Get completely value.
893
+ */
894
+ this.getValue = function()
895
+ {
896
+ // is selected range or pattern
897
+ var isRange = this.type2.checked;
898
+
899
+ // build serialize digits
900
+ var val1 = "";
901
+ var val2 = "";
902
+
903
+ NFU.eachChilds(this.digits1, 'SELECT', function(select) {
904
+ NFU.eachChilds(select, 'OPTION', function(option) {
905
+ if (option.selected)
906
+ val1 += option.innerHTML;
907
+ });
908
+ });
909
+
910
+ if (isRange)
911
+ {
912
+ NFU.eachChilds(this.digits2, 'SELECT', function(select) {
913
+ NFU.eachChilds(select, 'OPTION', function(option) {
914
+ if (option.selected)
915
+ val2 += option.innerHTML;
916
+ });
917
+ });
918
+ }
919
+
920
+ // validate interval
921
+ if (isRange)
922
+ {
923
+ // first remove '*' from text
924
+ // then chang '?' to '0' for left side and to '9' for right side
925
+ var vval1 = val1.replace('*', '').replace('?', '0');
926
+ var vval2 = val2.replace('*', '').replace('?', '9');
927
+
928
+ // provide that both values have same sizes
929
+ if (vval1.length > vval2.length)
930
+ while (vval1.length > vval2.length)
931
+ vval2 = vval2 + '9';
932
+
933
+ if (vval2.length > vval1.length)
934
+ while (vval2.length > vval1.length)
935
+ vval1 = vval1 + '0';
936
+
937
+ // cast to number
938
+ var num1 = new Number(vval1);
939
+ var num2 = new Number(vval2);
940
+
941
+ // test
942
+ if (num1 >= num2)
943
+ {
944
+ alert('Inccorect inteval. Left side ('+val1+') is greater than right side ('+val2+')');
945
+ return false;
946
+ }
947
+ }
948
+
949
+ return isRange ? val1 + '-' + val2 : val1;
950
+ };
951
+
952
+
953
+ /**
954
+ * Function shows dialog.
955
+ */
956
+ this.show = function() {
957
+ this.div.style.display = 'block';
958
+ };
959
+
960
+
961
+ /**
962
+ * Function hides dialog
963
+ */
964
+ this.hide = function() {
965
+ this.div.style.display = 'none';
966
+ };
967
+
968
+ };
969
+
970
+
971
+ /**
972
+ */
973
+ function NumberFilters(id)
974
+ {
975
+ /* this instance */
976
+ var self = this;
977
+
978
+
979
+ /* prefix id */
980
+ this.prefix_id = id;
981
+
982
+ /* */
983
+ this.div = document.getElementById(id);
984
+
985
+ /* TABLE with include filters */
986
+ this.filterTable = new FilterTable(id+'-filterTable', this);
987
+ /* TABLE with exclude filters */
988
+ //this.exclude = new FilterTable(id+'-exclude', this);
989
+ /* DIALOG for set/edit filter */
990
+ this.dialog = new FilterDialog(id+'-dialog', this);
991
+
992
+ /* filter table current edited in dialog */
993
+ this.openFilter = null;
994
+ /* filter table row current edited in dialog */
995
+ this.openRow = null;
996
+
997
+
998
+ /**
999
+ *
1000
+ */
1001
+ this.openDialog = function(filterTable, row)
1002
+ {
1003
+ if (row)
1004
+ row = NFU.firstParent(row, 'TR');
1005
+
1006
+ this.openFilter = filterTable;
1007
+ this.openRow = row;
1008
+
1009
+ var value = row ? filterTable.getValueByRow(row) : '*';
1010
+
1011
+ this.dialog.setValue(value);
1012
+ this.dialog.show();
1013
+ };
1014
+
1015
+
1016
+ /**
1017
+ * Save dialog. User confirms his choice.
1018
+ */
1019
+ this.saveDialog = function()
1020
+ {
1021
+ var value = this.dialog.getValue();
1022
+
1023
+ if (!value)
1024
+ return;
1025
+
1026
+ if (this.openRow)
1027
+ this.openFilter.updateFilter(this.openRow, value);
1028
+ else
1029
+ this.openFilter.addFilter(value);
1030
+
1031
+ this.openRow = null;
1032
+ this.openFilter = null;
1033
+
1034
+ this.dialog.hide();
1035
+ };
1036
+
1037
+
1038
+ /**
1039
+ * Close dialog without saving.
1040
+ * This does only hide the dialog.
1041
+ */
1042
+ this.closeDialog = function()
1043
+ {
1044
+ this.dialog.hide();
1045
+ };
1046
+
1047
+
1048
+ /**
1049
+ * Load values froh hidden INPUTs to filter table.
1050
+ */
1051
+ this.loadValues = function()
1052
+ {
1053
+ this.filterTable.loadValue();
1054
+
1055
+ this.filterTable.country_select.selectedIndex = 0;
1056
+ this.filterTable.changeCountry();
1057
+
1058
+ //this.include.loadValue();
1059
+ //this.exclude.loadValue();
1060
+ };
1061
+
1062
+
1063
+ /**
1064
+ * Init SELECT from sources.
1065
+ */
1066
+ this.initSelects = function(className, sources, defaultValue, label_callback)
1067
+ {
1068
+ var self = this;
1069
+ var selects = NFU.getElementsByClassName(className, 'SELECT');
1070
+
1071
+ NFU.each(selects, function(select) {
1072
+ if (select.options.length == 0) {
1073
+ self.initOptions(select, sources, defaultValue, label_callback);
1074
+ }
1075
+ });
1076
+ };
1077
+
1078
+
1079
+ /**
1080
+ *
1081
+ */
1082
+ this.initOptions = function(select, sources, defaultValue, label_callback)
1083
+ {
1084
+ NFU.each(sources, function(source) {
1085
+ var parts = source.split(':');
1086
+ var index = parts[0];
1087
+ var value = parts[1];
1088
+ var label = (label_callback) ? label_callback(index, value) : value;
1089
+
1090
+ var option = new Option(label, index);
1091
+ if (defaultValue == index)
1092
+ option.selected = true;
1093
+ select.options[select.options.length] = option;
1094
+ });
1095
+ };
1096
+
1097
+
1098
+ /**
1099
+ * Function returns dialing codes for a country.
1100
+ */
1101
+ this.getDialingCode = function(country)
1102
+ {
1103
+ var parts = country.split(',');
1104
+ return parts[1];
1105
+ };
1106
+
1107
+
1108
+ this.country_codes = [
1109
+ 'AFG,93:Afghanistan',
1110
+ 'ALB,355:Albania',
1111
+ 'DZA,213:Algeria',
1112
+ 'ASM,1684:American Samoa',
1113
+ 'AND,376:Andorra',
1114
+ 'AGO,244:Angola',
1115
+ 'AIA,1264:Anguilla',
1116
+ 'ATA,672:Antarctica',
1117
+ 'ATG,1268:Antigua and Barbuda',
1118
+ 'ARG,54:Argentina',
1119
+ 'ARM,374:Armenia',
1120
+ 'ABW,297:Aruba',
1121
+ 'AUS,61:Australia',
1122
+ 'AUT,43:Austria',
1123
+ 'AZE,994:Azerbaijan',
1124
+ 'BHS,1242:Bahamas',
1125
+ 'BHR,973:Bahrain',
1126
+ 'BGD,880:Bangladesh',
1127
+ 'BRB,1246:Barbados',
1128
+ 'BLR,375:Belarus',
1129
+ 'BEL,32:Belgium',
1130
+ 'BLZ,501:Belize',
1131
+ 'BEN,229:Benin',
1132
+ 'BMU,1441:Bermuda',
1133
+ 'BTN,975:Bhutan',
1134
+ 'BOL,591:Bolivia',
1135
+ 'BIH,387:Bosnia and Herzegovina',
1136
+ 'BWA,267:Botswana',
1137
+ 'BRA,55:Brazil',
1138
+ 'VGB,1284:British Virgin Islands',
1139
+ 'BRN,673:Brunei',
1140
+ 'BGR,359:Bulgaria',
1141
+ 'BFA,226:Burkina Faso',
1142
+ 'MMR,95:Burma (Myanmar)',
1143
+ 'BDI,257:Burundi',
1144
+ 'KHM,855:Cambodia',
1145
+ 'CMR,237:Cameroon',
1146
+ 'CAN,1:Canada',
1147
+ 'CPV,238:Cape Verde',
1148
+ 'CYM,1345:Cayman Islands',
1149
+ 'CAF,236:Central African Republic',
1150
+ 'TCD,235:Chad',
1151
+ 'CHL,56:Chile',
1152
+ 'CHN,86:China',
1153
+ 'CXR,61:Christmas Island',
1154
+ 'CCK,61:Cocos (Keeling) Islands',
1155
+ 'COL,57:Colombia',
1156
+ 'COM,269:Comoros',
1157
+ 'COK,682:Cook Islands',
1158
+ 'CRC,506:Costa Rica',
1159
+ 'HRV,385:Croatia',
1160
+ 'CUB,53:Cuba',
1161
+ 'CYP,357:Cyprus',
1162
+ 'CZE,420:Czech Republic',
1163
+ 'COD,243:Democratic Republic of the Congo',
1164
+ 'DNK,45:Denmark',
1165
+ 'DJI,253:Djibouti',
1166
+ 'DMA,1767:Dominica',
1167
+ 'DOM,1809:Dominican Republic',
1168
+ 'ECU,593:Ecuador',
1169
+ 'EGY,20:Egypt',
1170
+ 'SLV,503:El Salvador',
1171
+ 'GNQ,240:Equatorial Guinea',
1172
+ 'ERI,291:Eritrea',
1173
+ 'EST,372:Estonia',
1174
+ 'ETH,251:Ethiopia',
1175
+ 'FLK,500:Falkland Islands',
1176
+ 'FRO,298:Faroe Islands',
1177
+ 'FJI,679:Fiji',
1178
+ 'FIN,358:Finland',
1179
+ 'FRA,33:France',
1180
+ 'PYF,689:French Polynesia',
1181
+ 'GAB,241:Gabon',
1182
+ 'GMB,220:Gambia',
1183
+ 'GEO,995:Georgia',
1184
+ 'DEU,49:Germany',
1185
+ 'GHA,233:Ghana',
1186
+ 'GIB,350:Gibraltar',
1187
+ 'GRC,30:Greece',
1188
+ 'GRL,299:Greenland',
1189
+ 'GRD,1473:Grenada',
1190
+ 'GUM,1671:Guam',
1191
+ 'GTM,502:Guatemala',
1192
+ 'GIN,224:Guinea',
1193
+ 'GNB,245:Guinea-Bissau',
1194
+ 'GUY,592:Guyana',
1195
+ 'HTI,509:Haiti',
1196
+ 'VAT,39:Holy See (Vatican City)',
1197
+ 'HND,504:Honduras',
1198
+ 'HKG,852:Hong Kong',
1199
+ 'HUN,36:Hungary',
1200
+ 'IS,354:Iceland',
1201
+ 'IND,91:India',
1202
+ 'IDN,62:Indonesia',
1203
+ 'IRN,98:Iran',
1204
+ 'IRQ,964:Iraq',
1205
+ 'IRL,353:Ireland',
1206
+ 'IMN,44:Isle of Man',
1207
+ 'ISR,972:Israel',
1208
+ 'ITA,39:Italy',
1209
+ 'CIV,225:Ivory Coast',
1210
+ 'JAM,1876:Jamaica',
1211
+ 'JPN,81:Japan',
1212
+ 'JOR,962:Jordan',
1213
+ 'KAZ,7:Kazakhstan',
1214
+ 'KEN,254:Kenya',
1215
+ 'KIR,686:Kiribati',
1216
+ 'KWT,965:Kuwait',
1217
+ 'KGZ,996:Kyrgyzstan',
1218
+ 'LAO,856:Laos',
1219
+ 'LVA,371:Latvia',
1220
+ 'LBN,961:Lebanon',
1221
+ 'LSO,266:Lesotho',
1222
+ 'LBR,231:Liberia',
1223
+ 'LBY,218:Libya',
1224
+ 'LIE,423:Liechtenstein',
1225
+ 'LTU,370:Lithuania',
1226
+ 'LUX,352:Luxembourg',
1227
+ 'MAC,853:Macau',
1228
+ 'MKD,389:Macedonia',
1229
+ 'MDG,261:Madagascar',
1230
+ 'MWI,265:Malawi',
1231
+ 'MYS,60:Malaysia',
1232
+ 'MDV,960:Maldives',
1233
+ 'MLI,223:Mali',
1234
+ 'MLT,356:Malta',
1235
+ 'MHL,692:Marshall Islands',
1236
+ 'MRT,222:Mauritania',
1237
+ 'MUS,230:Mauritius',
1238
+ 'MYT,262:Mayotte',
1239
+ 'MEX,52:Mexico',
1240
+ 'FSM,691:Micronesia',
1241
+ 'MDA,373:Moldova',
1242
+ 'MCO,377:Monaco',
1243
+ 'MNG,976:Mongolia',
1244
+ 'MNE,382:Montenegro',
1245
+ 'MSR,1664:Montserrat',
1246
+ 'MAR,212:Morocco',
1247
+ 'MOZ,258:Mozambique',
1248
+ 'NAM,264:Namibia',
1249
+ 'NRU,674:Nauru',
1250
+ 'NPL,977:Nepal',
1251
+ 'NLD,31:Netherlands',
1252
+ 'ANT,599:Netherlands Antilles',
1253
+ 'NCL,687:New Caledonia',
1254
+ 'NZL,64:New Zealand',
1255
+ 'NIC,505:Nicaragua',
1256
+ 'NER,227:Niger',
1257
+ 'NGA,234:Nigeria',
1258
+ 'NIU,683:Niue',
1259
+ 'NFK,672:Norfolk Island',
1260
+ 'PRK,850:North Korea',
1261
+ 'MNP,1670:Northern Mariana Islands',
1262
+ 'NOR,47:Norway',
1263
+ 'OMN,968:Oman',
1264
+ 'PAK,92:Pakistan',
1265
+ 'PLW,680:Palau',
1266
+ 'PAN,507:Panama',
1267
+ 'PNG,675:Papua New Guinea',
1268
+ 'PRY,595:Paraguay',
1269
+ 'PER,51:Peru',
1270
+ 'PHL,63:Philippines',
1271
+ 'PCN,870:Pitcairn Islands',
1272
+ 'POL,48:Poland',
1273
+ 'PRT,351:Portugal',
1274
+ 'PRI,1:Puerto Rico',
1275
+ 'QAT,974:Qatar',
1276
+ 'COG,242:Republic of the Congo',
1277
+ 'ROU,40:Romania',
1278
+ 'RUS,7:Russia',
1279
+ 'RWA,250:Rwanda',
1280
+ 'BLM,590:Saint Barthelemy',
1281
+ 'SHN,290:Saint Helena',
1282
+ 'KNA,1869:Saint Kitts and Nevis',
1283
+ 'LCA,1758:Saint Lucia',
1284
+ 'MAF,1599:Saint Martin',
1285
+ 'SPM,508:Saint Pierre and Miquelon',
1286
+ 'VCT,1784:Saint Vincent and the Grenadines',
1287
+ 'WSM,685:Samoa',
1288
+ 'SMR,378:San Marino',
1289
+ 'STP,239:Sao Tome and Principe',
1290
+ 'SAU,966:Saudi Arabia',
1291
+ 'SEN,221:Senegal',
1292
+ 'SRB,381:Serbia',
1293
+ 'SYC,248:Seychelles',
1294
+ 'SLE,232:Sierra Leone',
1295
+ 'SGP,65:Singapore',
1296
+ 'SVK,421:Slovakia',
1297
+ 'SVN,386:Slovenia',
1298
+ 'SLB,677:Solomon Islands',
1299
+ 'SOM,252:Somalia',
1300
+ 'ZAF,27:South Africa',
1301
+ 'KOR,82:South Korea',
1302
+ 'ESP,34:Spain',
1303
+ 'LKA,94:Sri Lanka',
1304
+ 'SDN,249:Sudan',
1305
+ 'SUR,597:Suriname',
1306
+ 'SWZ,268:Swaziland',
1307
+ 'SWE,46:Sweden',
1308
+ 'CHE,41:Switzerland',
1309
+ 'SYR,963:Syria',
1310
+ 'TWN,886:Taiwan',
1311
+ 'TJK,992:Tajikistan',
1312
+ 'TZA,255:Tanzania',
1313
+ 'THA,66:Thailand',
1314
+ 'TLS,670:Timor-Leste',
1315
+ 'TGO,228:Togo',
1316
+ 'TKL,690:Tokelau',
1317
+ 'TON,676:Tonga',
1318
+ 'TTO,1868:Trinidad and Tobago',
1319
+ 'TUN,216:Tunisia',
1320
+ 'TUR,90:Turkey',
1321
+ 'TKM,993:Turkmenistan',
1322
+ 'TCA,1649:Turks and Caicos Islands',
1323
+ 'TUV,688:Tuvalu',
1324
+ 'UGA,256:Uganda',
1325
+ 'UKR,380:Ukraine',
1326
+ 'ARE,971:United Arab Emirates',
1327
+ 'GBR,44:United Kingdom',
1328
+ 'USA,1:United States',
1329
+ 'URY,598:Uruguay',
1330
+ 'VIR,1340:US Virgin Islands',
1331
+ 'UZB,998:Uzbekistan',
1332
+ 'VUT,678:Vanuatu',
1333
+ 'VEN,58:Venezuela',
1334
+ 'VNM,84:Vietnam',
1335
+ 'WLF,681:Wallis and Futuna',
1336
+ 'YEM,967:Yemen',
1337
+ 'ZMB,260:Zambia',
1338
+ 'ZWE,263:Zimbabwe'
1339
+ ];
1340
+
1341
+ this.max_digits_without_prefix = [
1342
+ "0:0",
1343
+ "1:1",
1344
+ "2:2",
1345
+ "3:3",
1346
+ "4:4",
1347
+ "5:5",
1348
+ "6:6",
1349
+ "7:7",
1350
+ "8:8",
1351
+ "9:9",
1352
+ "10:10",
1353
+ "11:11",
1354
+ "12:12",
1355
+ "13:13",
1356
+ "14:14",
1357
+ "15:15"
1358
+ ];
1359
+
1360
+ this.digits = [
1361
+ "*:*", // any digit (a number of)
1362
+ "0:0",
1363
+ "1:1",
1364
+ "2:2",
1365
+ "3:3",
1366
+ "4:4",
1367
+ "5:5",
1368
+ "6:6",
1369
+ "7:7",
1370
+ "8:8",
1371
+ "9:9",
1372
+ "?:?" // any digit (single)
1373
+ ];
1374
+
1375
+
1376
+ // intialize procedure
1377
+ this.initSelects('max-number-for-prefix', this.max_digits_without_prefix, 9);
1378
+ this.initSelects('digits', this.digits, '*');
1379
+ this.initSelects('country-codes', this.country_codes, null, function(code, country_name) {
1380
+ return country_name + " ("+self.getDialingCode(code)+")";
1381
+ });
1382
+
1383
+ this.loadValues();
1384
+
1385
+ };
lib/Artio/SMSService/smsservice.php CHANGED
@@ -105,8 +105,8 @@ class ASmsService
105
 
106
  // Return the credit
107
  $result = array(
108
- 'credit' => (float)$data->credit,
109
- 'exhaustion' => (int)$data->exhaustion
110
  );
111
 
112
  return $result;
105
 
106
  // Return the credit
107
  $result = array(
108
+ 'credit' => $data->credit,
109
+ 'exhaustion' => $data->exhaustion
110
  );
111
 
112
  return $result;
lib/Varien/Data/Form/Element/Accountinfo.php CHANGED
@@ -47,8 +47,8 @@ class Varien_Data_Form_Element_Accountinfo extends Varien_Data_Form_Element_Abst
47
  $purchaseLabel = $helper->__('Purchase');
48
  $purchaseText = $helper->__('Purchase credit now');
49
 
50
- $credit = $info['credit'];
51
- $exhaus = $info['exhaustion'] ? $info['exhaustion'].' h' : $helper->__('No data for computation');
52
 
53
  $opts = $purchase['creditValues'];
54
  $link = $purchase['link'];
@@ -79,6 +79,39 @@ class Varien_Data_Form_Element_Accountinfo extends Varien_Data_Form_Element_Abst
79
  return $html;
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  /**
84
  * Get Javascript code for wokring this controls.
47
  $purchaseLabel = $helper->__('Purchase');
48
  $purchaseText = $helper->__('Purchase credit now');
49
 
50
+ $credit = $this->_formatPrice($info['credit']);
51
+ $exhaus = $info['exhaustion'] ? $this->_formatTime($info['exhaustion']) : '<small>'.$helper->__('No data for computation').'</small>';
52
 
53
  $opts = $purchase['creditValues'];
54
  $link = $purchase['link'];
79
  return $html;
80
  }
81
 
82
+ /**
83
+ * Convert price in format XXX,XXX.XX to Magento standard format.
84
+ *
85
+ * @param string $price
86
+ * @return string
87
+ */
88
+ protected function _formatPrice($price)
89
+ {
90
+ $price = str_replace(',', '', $price);
91
+ $price = (float) $price;
92
+
93
+ return Mage::helper('core')->formatPrice($price, false);
94
+ }
95
+
96
+ /**
97
+ * Convert number of hours in format XXX,XXX.XX to human readable format.
98
+ *
99
+ * @param string $hours
100
+ * @return string
101
+ */
102
+ protected function _formatTime($hours)
103
+ {
104
+ if (!$hours)
105
+ return "";
106
+
107
+ $hours = str_replace(',', '', $hours);
108
+ $hours = (int) $hours;
109
+
110
+ $days = floor($hours / 24);
111
+ $hours = $hours % 24;
112
+
113
+ return ($days > 0) ? sprintf("%sd %sh", $days, $hours) : sprintf("%sh", $hours);
114
+ }
115
 
116
  /**
117
  * Get Javascript code for wokring this controls.
lib/Varien/Data/Form/Element/Selectex.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SMS Notifier
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * It is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/afl-3.0.php
10
+ *
11
+ * @category Artio
12
+ * @package Artio_SMSNotifier
13
+ * @copyright Copyright (c) 2013 Artio (http://www.artio.net)
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ */
16
+
17
+ /**
18
+ * Enhanced select
19
+ *
20
+ * @category Artio
21
+ * @package Artio_SMSNotifier
22
+ * @author Artio Magento Team (info@artio.net)
23
+ */
24
+ class Varien_Data_Form_Element_Selectex extends Varien_Data_Form_Element_Select
25
+ {
26
+ /* public function __construct($attributes=array())
27
+ {
28
+ parent::__construct($attributes);
29
+ $this->setType('select');
30
+ $this->setExtType('combobox');
31
+ $this->_prepareOptions();
32
+ }*/
33
+
34
+ public function getElementHtml()
35
+ {
36
+ $this->addClass('select');
37
+ $html = '<select id="'.$this->getHtmlId().'" name="'.$this->getName().'" '.$this->serialize($this->getHtmlAttributes()).'>'."\n";
38
+
39
+ $value = $this->getValue();
40
+ if (!is_array($value)) {
41
+ $value = array($value);
42
+ }
43
+
44
+ if ($values = $this->getValues()) {
45
+ foreach ($values as $key => $option) {
46
+ if (is_array($option['value'])) {
47
+ $html.='<optgroup label="'.$option['label'].'">'."\n";
48
+ foreach ($option['value'] as $groupItem) {
49
+ $html.= $this->_optionToHtml($groupItem, $value);
50
+ }
51
+ $html.='</optgroup>'."\n";
52
+ }
53
+ else {
54
+ $html.= $this->_optionToHtml($option, $value);
55
+ }
56
+ }
57
+ }
58
+
59
+ $html.= '</select>'."\n";
60
+ $html.= $this->getAfterElementHtml();
61
+ return $html;
62
+ }
63
+
64
+ protected function _optionToHtml($option, $selected)
65
+ {
66
+ if (is_array($option['value'])) {
67
+ $html ='<optgroup label="'.$option['label'].'">'."\n";
68
+ foreach ($option['value'] as $groupItem) {
69
+ $html .= $this->_optionToHtml($groupItem, $selected);
70
+ }
71
+ $html .='</optgroup>'."\n";
72
+ }
73
+ else {
74
+ $html = '<option value="'.$this->_escape($option['value']).'"';
75
+ $html.= isset($option['title']) ? 'title="'.$this->_escape($option['title']).'"' : '';
76
+ $html.= isset($option['style']) ? 'style="'.$option['style'].'"' : '';
77
+ $html.= isset($option['disabled']) ? 'disabled="'.$option['disabled'].'"' : '';
78
+ if (in_array($option['value'], $selected)) {
79
+ $html.= ' selected="selected"';
80
+ }
81
+ $html.= '>'.$this->_escape($option['label']). '</option>'."\n";
82
+ }
83
+ return $html;
84
+ }
85
+
86
+ protected function _prepareOptions()
87
+ {
88
+ $values = $this->getValues();
89
+ if (empty($values)) {
90
+ $options = $this->getOptions();
91
+
92
+ if (is_array($options)) {
93
+ $values = array();
94
+ foreach ($options as $value => $label) {
95
+ $values[] = $label;
96
+ }
97
+ } elseif (is_string($options)) {
98
+ $values = array( array('value' => $options, 'label' => $options) );
99
+ }
100
+ $this->setValues($values);
101
+ }
102
+ }
103
+
104
+ public function getHtmlAttributes()
105
+ {
106
+ return array('title', 'class', 'style', 'onclick', 'onchange', 'disabled', 'readonly', 'tabindex');
107
+ }
108
+ }
package.xml CHANGED
@@ -1,9 +1,9 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SMSNotifier</name>
4
- <version>1.1.0</version>
5
  <stability>stable</stability>
6
- <license uri="http://www.artio.net/general/legal-documents">Copyright 2013, ARTIO s.r.o. All rights reserved.</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>SMS Notifier</summary>
@@ -11,9 +11,9 @@
11
  <notes>Visit product homepage at:
12
  http://www.artio.net/e-shop/magento-extensions/magento-sms-notifier</notes>
13
  <authors><author><name>Luk&#xE1;&#x161; Bialo&#x148;</name><user>auto-converted</user><email>lukas.bialon@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
14
- <date>2014-01-23</date>
15
- <time>09:02:30</time>
16
- <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="smsnotify.xml" hash="cb8f765f6a7df728764119b3c87f2308"/></dir><dir name="template"><dir name="smsnotify"><dir name="order"><dir name="view"><file name="history.phtml" hash="9fd5457941b5060da17515447fda18e0"/></dir><dir name="comments"><file name="view.phtml" hash="86154a1c4129198fa576e921fbbb2941"/></dir></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Artio"><dir name="SMSNotifier"><dir name="controllers"><file name="AdminhtmlController.php" hash="6c3d49b006a3d28b94f0924aeb222429"/></dir><dir name="Model"><dir name="Sms"><file name="Template.php" hash="64b5b81c69552307af66b3c209a15bc4"/><file name="Observer.php" hash="c628c7295e8ead74d8616e475f194d0c"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="CountryFilter.php" hash="cface077f87945702f0f88a1dad54f4c"/><file name="Log.php" hash="c1663898225e6ef2fc73a5b9782b8b75"/><file name="Gateway.php" hash="d450d78264a43dd10f71f218c45d9a5c"/><file name="SendToAdmin.php" hash="30a23357c183f0aa8c098653178dbcd3"/><file name="Addresses.php" hash="506541d6d422a7a4a2e361766c3c2a7b"/></dir></dir></dir><file name="Sms.php" hash="063984eb94351f9aedc0d1eca8d0a09e"/><file name="Service.php" hash="79c0a46250c92dd3749807fa3c9e1bce"/><file name="Config.php" hash="9ef157e8684122347d3e4365d8fd3458"/><file name="Observer.php" hash="790f88d23ba35b832d32458d0afd098b"/></dir><dir name="Block"><dir name="Adminhtml"><dir name="Send"><file name="Form.php" hash="2e6010c3cfa73d728e87558d9f54269a"/></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="CustomerNumbers.php" hash="67f188d1f0d0d2da7e819ed224bbd43f"/></dir></dir></dir><file name="Send.php" hash="56cb701ea7ae77b039f566f24d3d2944"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="3621cf3a577a2ca0a59443ffe7e740cb"/><file name="system.xml" hash="9b896b3e432097dc7e43262d946281d4"/><file name="config.xml" hash="f34907a8d879ffffca7df080bbcb658c"/></dir><dir name="Helper"><file name="Data.php" hash="2ea5d0ff331938c387a0b0ae3c2726d4"/><file name="SMSLog.php" hash="e889508e6eea7a5577429d206ac55a6e"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_SMSNotifyForMagento.xml" hash="7389e8a15b874b39a1b6a22800939b32"/></dir></target><target name="mage"><dir name="js"><dir name="artio"><file name="numberfilters.js" hash=""/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><file name="entry_edit_head_arrow_x.gif" hash="3c49e7bbb6de956a903e6a018ca78477"/><file name="ico_mobil.png" hash="f69f028a51e391f1762bbfe150db8dd9"/></dir><file name="smsnotify.css" hash="8df1c8c5beea2c5b4c2bb062b00eb892"/></dir></dir></dir></target><target name="magelib"><dir name="Varien"><dir name="Data"><dir name="Form"><dir name="Element"><file name="Numberfilters.php" hash="3a0837438a7ecb3b782560fe6a57596e"/><file name="Selectdynamic.php" hash="b525c625719d6489c09d87eb5a7025df"/><file name="Smstextarea.php" hash="a1c9570808342efc3726d8a4a6032068"/><file name="Accountinfo.php" hash="e3c6c03d33875c4e01c0427e18abcd65"/></dir></dir></dir></dir><dir name="Artio"><dir name="SMSService"><file name="smsservice.php" hash="49bcb6edd9f6fb4253867420d5e8b01b"/><file name="httphelper.php" hash="dea608b37e266a8e0ce1fee336d7a36c"/></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies/>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>SMSNotifier</name>
4
+ <version>1.1.2</version>
5
  <stability>stable</stability>
6
+ <license uri="http://www.artio.net/general/legal-documents">Commercial</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>SMS Notifier</summary>
11
  <notes>Visit product homepage at:
12
  http://www.artio.net/e-shop/magento-extensions/magento-sms-notifier</notes>
13
  <authors><author><name>Luk&#xE1;&#x161; Bialo&#x148;</name><user>auto-converted</user><email>lukas.bialon@artio.net</email></author><author><name>Ji&#x159;&#xED; Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
14
+ <date>2015-03-18</date>
15
+ <time>14:38:45</time>
16
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="smsnotify"><dir name="order"><dir name="view"><file name="history.phtml" hash="9fd5457941b5060da17515447fda18e0"/></dir><dir name="comments"><file name="view.phtml" hash="86154a1c4129198fa576e921fbbb2941"/></dir></dir></dir></dir><dir name="layout"><file name="smsnotify.xml" hash="cb8f765f6a7df728764119b3c87f2308"/></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Artio"><dir name="SMSNotifier"><dir name="Helper"><file name="Data.php" hash="2eb45c1793306466d75b3edbe3c5d787"/><file name="SMSLog.php" hash="96acf7dc6e09c0a04a1c8395ce0da506"/></dir><dir name="etc"><file name="adminhtml.xml" hash="3621cf3a577a2ca0a59443ffe7e740cb"/><file name="system.xml" hash="5bba29945c7c4ace974f7cd638e6441b"/><file name="config.xml" hash="401b3ad132c91e5fbad25efa6126be20"/></dir><dir name="Block"><dir name="Adminhtml"><dir name="Send"><file name="Form.php" hash="2306630b1ad2ab93220269c88142696c"/></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="CustomerNumbers.php" hash="ab3284cded868f4e3611a3b91b59e890"/></dir></dir></dir><file name="Send.php" hash="56cb701ea7ae77b039f566f24d3d2944"/></dir></dir><dir name="controllers"><file name="AdminhtmlController.php" hash="177185c5ecca49385ad2bbb05ff7caa5"/></dir><dir name="Model"><dir name="Source"><file name="ShippingMethods.php" hash="f50be75988d786d43b5ef7b2b4b809aa"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Gateway.php" hash="d450d78264a43dd10f71f218c45d9a5c"/><file name="SendToAdmin.php" hash="bd17f440197ffc6ce2cec74aaed42123"/><file name="Addresses.php" hash="506541d6d422a7a4a2e361766c3c2a7b"/><file name="CountryFilter.php" hash="cface077f87945702f0f88a1dad54f4c"/><file name="Log.php" hash="c1663898225e6ef2fc73a5b9782b8b75"/></dir></dir></dir><dir name="Sms"><file name="Observer.php" hash="c628c7295e8ead74d8616e475f194d0c"/><file name="Template.php" hash="64b5b81c69552307af66b3c209a15bc4"/></dir><file name="Sms.php" hash="063984eb94351f9aedc0d1eca8d0a09e"/><file name="Config.php" hash="25150a06d172d12c663058ccdec82b20"/><file name="Service.php" hash="81ee577b162e7538923a64072cd6cdfe"/><file name="Observer.php" hash="65f185426014051e20168166a0f6baf7"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_SMSNotifyForMagento.xml" hash="7389e8a15b874b39a1b6a22800939b32"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><file name="ico_mobil.png" hash="f69f028a51e391f1762bbfe150db8dd9"/><file name="entry_edit_head_arrow_x.gif" hash="3c49e7bbb6de956a903e6a018ca78477"/></dir><file name="smsnotify.css" hash="8df1c8c5beea2c5b4c2bb062b00eb892"/></dir></dir></dir></target><target name="magelib"><dir name="Varien"><dir name="Data"><dir name="Form"><dir name="Element"><file name="Selectdynamic.php" hash="b525c625719d6489c09d87eb5a7025df"/><file name="Smstextarea.php" hash="a1c9570808342efc3726d8a4a6032068"/><file name="Selectex.php" hash="83fed4994c4447e42407b2fee1b3e08c"/><file name="Numberfilters.php" hash="3a0837438a7ecb3b782560fe6a57596e"/><file name="Accountinfo.php" hash="75b8ef5af325b20828693ea2dd082e4c"/></dir></dir></dir></dir><dir name="Artio"><dir name="SMSService"><file name="smsservice.php" hash="fd473a55ecb852b4ccde26483fb6e6de"/><file name="httphelper.php" hash="dea608b37e266a8e0ce1fee336d7a36c"/></dir></dir></target><target name="mageweb"><dir name="js"><dir name="artio"><file name="numberfilters.js" hash="e93f1c0ac0a0c160574524465571a9b2"/></dir></dir></target></contents>
17
  <compatible/>
18
  <dependencies/>
19
  </package>