1: <?php
2:
3: namespace tschiemer\Aspsms;
4:
5:
6: /**
7: * Simple interface combining all possible drivers.
8: *
9: * Has an internal mapping of request names to drivers, thus drivers are loaded
10: * lazily as required.
11: *
12: * @version 1.1.0
13: * @package aspsms
14: * @license LGPL v3 http://www.gnu.org/licenses/lgpl-3.0.txt
15: * @copyright 2013 Philip Tschiemer, <tschiemer@filou.se>
16: * @link https://github.com/tschiemer/aspsms-php
17: */
18: class SimpleClient extends AbstractSimpleClient
19: {
20: /**
21: * Loaded drivers
22: *
23: * @var AbstractClient[]
24: */
25: var $drivers = NULL;
26:
27: /**
28: * Driver options to use when instantiating drivers
29: * .
30: * @var array
31: * @see HttpClient, SoapClient, XmlClient
32: */
33: var $driverOptions = array(
34: 'soap' => array(),
35: 'http' => array(),
36: 'xml' => array()
37: );
38:
39: /**
40: * Mapping of request names to driver names
41: *
42: * @var string[]
43: */
44: var $requestMap = array(
45:
46: 'getVersion' => 'http', // Soap|Http
47: 'getCredits' => 'http', // Xml|Soap|Http
48: 'getStatusCodeDescription' => 'http', // Soap|Http
49:
50: 'checkOriginator' => 'http', // Xml|Soap|Http
51: 'sendOriginatorCode' => 'http', // Xml|Soap|Http
52: 'unlockOriginator' => 'http', // Xml|Soap|Http
53:
54: 'sendText' => 'http', // Xml|Soap|Http
55: 'sendWapPush' => 'http', // Xml|Soap|Http
56: 'sendToken' => 'http', // Soap|Http
57: 'verifyToken' => 'http', // Soap|Http
58: 'sendPicture' => 'xml', // Xml
59: 'sendLogo' => 'xml', // Xml
60: 'sendGroupLogo' => 'xml', // Xml
61: 'sendRingtone' => 'xml', // Xml
62: 'sendVCard' => 'xml', // Xml
63: 'sendBinaryData' => 'xml', // Xml
64: 'getDeliveryStatus' => 'http', // Xml|Soap|Http
65:
66: );
67:
68:
69: /**
70: * Constructor
71: *
72: * Sets up simple client and prepare for driver instantiation.
73: *
74: * Driver options are passed as fields with names 'soapclient','httpclient','xmlclient' respectively.
75: *
76: * The default request mapping can be changed when passing
77: *
78: * @param array $options
79: *
80: * @see AbstractSimpleClient::__construct()
81: * @see SoapClient::__construct()
82: * @see HttpClient::__construct()
83: * @see XmlClient::__construct()
84: */
85: public function __construct($options = array())
86: {
87: parent::__construct($options);
88:
89: // Which are the valid drivers?
90: $validDrivers = array_keys($this->driverOptions);
91:
92: // Set any driver options
93: foreach($validDrivers as $d)
94: {
95: if (isset($options[$d.'client']))
96: {
97: foreach($options[$d.'client'] as $k => $v)
98: {
99: $this->driverOptions[$d][$k] = $v;
100: }
101: }
102: }
103:
104: // change the default request to driver mapping if so wanted
105: if (isset($options['requestMap']))
106: {
107: foreach($options['requestMap'] as $k => $v)
108: {
109: if ( ! array_key_exists($k, $this->requestMap))
110: {
111: throw new ServiceException('Request not recognized in setup: '. $k);
112: }
113:
114: if ( ! in_array($v,$validDrivers))
115: {
116: throw new ServiceException('Invalid driver passed: '.$v);
117: }
118:
119: $this->requestMap[$k] = $v;
120: }
121: }
122:
123: $this->drivers = new \stdClass();
124: }
125:
126: /**
127: * Loads and returns the correct driver for the assigned request type.
128: *
129: * @param Request $requestType
130: * @return AbstractClient
131: * @throw ServiceExceptionon
132: */
133: public function driver(&$request)
134: {
135: $requestName = $request->getRequestName();
136:
137: if ( ! isset($this->requestMap[$requestName]))
138: {
139: throw new ServiceException('Request type not recognized: '.$requestName);
140: }
141:
142: // Get driver name
143: $obj_name = strtolower($this->requestMap[$requestName]);
144:
145: // If driver not loaded, well, load.
146: if ( ! isset($this->drivers->obj_name))
147: {
148: $this->drivers->$obj_name = $this->loadDriver($obj_name, FALSE);
149: }
150:
151: return $this->drivers->$obj_name;
152: }
153:
154: /**
155: * Instantiates driver with internal options.
156: *
157: * @param string $obj_name Driver name
158: * @return \Aspsms\class Instance of driver
159: * @throw ServiceException
160: */
161: public function loadDriver($obj_name)
162: {
163: // if ( ! isset($this->drivers->$obj_name))
164: {
165: // Look for class XyzClient in file Xyz/XyzClient.php
166: $className = __NAMESPACE__ . '\\' . ucfirst($obj_name) . '\\' . ucfirst($obj_name) . 'Client';
167: // $namespace = __NAMESPACE__ . '\\' . ucfirst($obj_name);
168:
169: // $path = dirname(__FILE__) . '/' . ucfirst($obj_name) . '/'.$class.'.php';
170: //
171: // if ( ! file_exists($path))
172: // {
173: // throw new AspsmsException('Could not load driver file '.$path.' for driver '.$d);
174: // }
175: //
176: // // Load file
177: // require_once $path;
178:
179: // Are there any options
180: if (isset($this->options[$obj_name]))
181: {
182: $options = $this->options[$obj_name];
183: }
184: else
185: {
186: $options = array();
187: }
188:
189: // $class = __NAMESPACE__ . '\\' . $class;
190:
191: return new $className($options);
192: }
193: }
194:
195:
196: /**
197: * Request: Get Soap or Http Service version (depends on assigned driver to use)
198: *
199: * @return array Associative array with fields 'all','version','build' and corresponding meaning.
200: */
201: public function getVersion()
202: {
203: return $this->send(array(
204: 'RequestName' => 'getVersion'
205: ));
206: }
207:
208:
209: /**
210: * Request: Get description to given status code.
211: *
212: * @param string|int $statusCode
213: * @return string
214: */
215: public function getStatusDescription($statusCode)
216: {
217: return $this->send(array(
218: 'RequestName' => 'getStatusCodeDescription',
219: 'StatusCode' => $statusCode
220: ));
221: }
222:
223:
224: /**
225: * Request: Send a token a predefined token to recipients.
226: *
227: * Official doc:
228: *
229: * If MessageData is set, the placeholder <VERIFICATIONCODE> will be
230: * substituted with the verification code. If MessageData is not defined,
231: * or if MessageData does not contain the placeholder <VERIFICATIONCODE>,
232: * only the verification code is sent.
233: *
234: * @param string $phoneNr Recipient phone number
235: * @param string $reference Your reference number
236: * @param string $verificationCode Required verification code to send
237: * @param string $message Message to send code with.
238: * @param int $minutes Validity of token in minutes (default 5)
239: * @param boolean $case_sensitive Is given code case sensitive?
240: * @return boolean Request success?
241: */
242: public function sendMyToken($phoneNr,$reference,$verificationCode,$message='',$minutes=5, $case_sensitive=0)
243: {
244: return $this->send(array(
245: 'RequestName' => 'sendToken',
246: 'Recipients' => $phoneNr,
247: 'TokenReference' => $reference,
248: 'VerificationCode' => $verificationCode,
249: 'MessageData' => $message,
250: 'TokenValidity' => $minutes,
251: 'TokenCaseSensitive'=> $case_sensitive
252: ));
253: }
254:
255: /**
256: * Request: Send a token as generated by ASPSMS.COM, optionally give token mask.
257: *
258: * Official doc:
259: *
260: * If MessageData is set, the placeholder <VERIFICATIONCODE> will be
261: * substituted with the verification code. If MessageData is not defined,
262: * or if MessageData does not contain the placeholder <VERIFICATIONCODE>,
263: * only the verification code is sent.
264: *
265: * Official doc:
266: *
267: * Used to have the ASPSMS generate a verification code by mask. The mask can contain the following special characters:
268: *
269: * # : a digit
270: * A : an alphabetic character
271: * N : an alphanumeric character
272: *
273: * All other characters are taken literally. If not specified, the Mask is "NNNN" by default.
274: *
275: *
276: * @param string $phoneNr Recipient phone number
277: * @param string $reference Your reference number
278: * @param string $message Message to send code with.
279: * @param string $mask Token code mask to use (# -> number, A -> Alphabetical)
280: * @param int $minutes Validity of token in minutes (default 5)
281: * @param boolean $case_sensitive Is given code case sensitive?
282: * @return boolean Request success?
283: */
284: public function sendGeneratedToken($phoneNr,$reference,$message='',$mask='######',$minutes=5, $case_sensitive=0)
285: {
286: return $this->send(array(
287: 'RequestName' => 'sendToken',
288: 'Recipients' => $phoneNr,
289: 'TokenReference' => $reference,
290: 'TokenMask' => $mask,
291: 'MessageData' => $message,
292: 'TokenValidity' => $minutes,
293: 'TokenCaseSensitive'=> $case_sensitive
294: ));
295: }
296:
297: /**
298: * Request: attempt to validate token.
299: *
300: * NOTE: If a token have been successfully validated, any future attempts (no matter the
301: * verification code use) succeed.
302: *
303: * @param string $phoneNr Recipient phone number
304: * @param string $reference Your reference number
305: * @param string $verificationCode Required verification code to validate
306: * @return boolean Is given verification code for use valid?
307: */
308: public function validateToken($phoneNr,$reference,$verificationCode)
309: {
310: return $this->send(array(
311: 'RequestName' => 'verifyToken',
312: 'PhoneNumber' => $phoneNr,
313: 'TokenReference' => $reference,
314: 'VerificationCode' => $verificationCode
315: ));
316: }
317:
318:
319: /**
320: * Send VCARD (name + telephone nr) to designated recipients.
321: *
322: * String Format:
323: * ("<RECIPIENT_NR>" + {":<TRACKING_NR>"} ";" .. )+
324: * Eg:
325: * 00417777777
326: * 00417777777;00417777777;004177777777
327: * 00417777777:84612004;00417777777:74183874783
328: *
329: * Array Format:
330: * <TRACKING_NR> => <RECIPIENT_NR>
331: *
332: * @param array,string $recipients
333: * @param string $name Name of VCARD
334: * @param string $phoneNr Phone number of VCARD
335: * @return boolean Request submitted successfully? (not delivery)
336: * @see \Aspsms\AbstractSimpleClient::getDeliveryStatus()
337: */
338: public function sendVCard($recipients, $name, $phoneNr)
339: {
340: return $this->send(array(
341: 'RequestName' => 'sendVCard',
342: 'Recipients' => $recipients,
343: 'VCard' => array(
344: 'name' => $name,
345: 'phoneNr' => $phoneNr
346: )
347: ));
348: }
349:
350: /**
351: *
352: * @todo TESTING
353: *
354: * @param type $recipients
355: * @param type $url
356: * @return type
357: */
358: public function sendRingtone($recipients,$url)
359: {
360: return $this->send(array(
361: 'RequestName' => 'sendVCard',
362: 'Recipients' => $recipients,
363: 'URLBinaryFile' => $url
364: ));
365: }
366: }