1<?php
2
3require_once 'PEAR.php';
4require_once 'Net/SMS/Exception.php';
5
6/**
7 * Net_SMS Class
8 *
9 * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
10 *
11 * See the enclosed file COPYING for license information (LGPL). If you
12 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
13 *
14 * $Horde: framework/Net_SMS/SMS.php,v 1.25 2009/01/06 17:49:34 jan Exp $
15 *
16 * @author  Marko Djukic <marko@oblo.com>
17 * @package Net_SMS
18 */
19class Net_SMS {
20
21    /**
22     * A hash containing any parameters for the current gateway driver.
23     *
24     * @var array
25     */
26    var $_params = array();
27
28    var $_auth = null;
29
30    /**
31     * Constructor
32     *
33     * @param array $params  Any parameters needed for this gateway driver.
34     */
35    public function __construct($params)
36    {
37        // Iterate over specified options, merging with defaults
38        if (!empty($params)) {
39            foreach ($params as $key => $value) {
40                $this->_params[$key] = $value;
41            }
42        }
43    }
44
45    /**
46     * Query the current Gateway object to find out if it supports the given
47     * capability.
48     *
49     * @param string $capability  The capability to test for.
50     *
51     * @return mixed  Whether or not the capability is supported or any other
52     *                value that the capability wishes to report.
53     */
54    function hasCapability($capability)
55    {
56        if (!empty($this->capabilities[$capability])) {
57            return $this->capabilities[$capability];
58        }
59        return false;
60    }
61
62    /**
63     * Authenticates against the gateway if required.
64     *
65     * @return mixed  True on success or PEAR Error on failure.
66     */
67    function authenticate()
68    {
69        /* Do authentication for this gateway if driver requires it. */
70        if ($this->hasCapability('auth')) {
71            $this->_auth = $this->_authenticate();
72            return $this->_auth;
73        }
74        return true;
75    }
76
77    /**
78     * Sends a message to one or more recipients. Hands off the actual sending
79     * to the gateway driver.
80     *
81     * @param array $message  The message to be sent, which is composed of:
82     *                        <pre>
83     *                          id   - A unique ID for the message;
84     *                          to   - An array of recipients;
85     *                          text - The text of the message;
86     *                        </pre>
87     *
88     *
89     * @return mixed  True on success or PEAR Error on failure.
90     */
91    public function send($message)
92    {
93        if (!is_array($message)) {
94            throw new InvalidArgumentException("Parameter message is expected to be an array/hash");
95        }
96
97        if (!isset($message['id'])) {
98            throw new InvalidArgumentException("Please specify message id, ie: array('id' => 1)");
99        }
100
101        if (!isset($message['to'])) {
102            throw new InvalidArgumentException("Please specify an array of recipients, ie: array('to' => array('phone1', 'phone2'))");
103        }
104
105        if (!isset($message['text'])) {
106            throw new InvalidArgumentException("Please specify message text, ie: array('text' => 'Hi!')");
107        }
108
109        /* Authenticate. */
110        if (is_a($this->authenticate(), 'PEAR_Error')) {
111            return $this->_auth;
112        }
113
114        /* Make sure the recipients are in an array. */
115        if (!is_array($message['to'])) {
116            $message['to'] = array($message['to']);
117        }
118
119        /* Array to store each send. */
120        $sends = array();
121
122        /* If gateway supports batch sending, preference is given to this
123         * method. */
124        if ($max_per_batch = $this->hasCapability('batch')) {
125            /* Split up the recipients in the max recipients per batch as
126             * supported by gateway. */
127            $iMax = count($message['to']);
128            $batches = ceil($iMax / $max_per_batch);
129
130            /* Loop through the batches and compose messages to be sent. */
131            for ($b = 0; $b < $batches; $b++) {
132                $recipients = array_slice($message['to'], ($b * $max_per_batch), $max_per_batch);
133                $response = $this->_send($message, $recipients);
134                foreach ($recipients as $recipient) {
135                    if (empty($response[$recipient])) {
136                        continue;
137                    }
138                    if ($response[$recipient][0] == 1) {
139                        /* Message was sent, store remote id. */
140                        $remote_id = $response[$recipient][1];
141                        $error = null;
142                    } else {
143                        /* Message failed, store error code. */
144                        $remote_id = null;
145                        $error = $response[$recipient][1];
146                    }
147
148                    /* Store the sends. */
149                    $sends[] = array('message_id' => $message['id'],
150                                     'remote_id'  => $remote_id,
151                                     'recipient'  => $recipient,
152                                     'error'      => $error);
153                }
154            }
155
156            return $sends;
157        }
158
159        /* No batch sending available, just loop through all recipients
160         * and send a message for each one. */
161        foreach ($message['to'] as $recipient) {
162            $response = $this->_send($message, $recipient);
163            if ($response[0] == 1) {
164                /* Message was sent, store remote id if any. */
165                $remote_id = (isset($response[1]) ? $response[1] : null);
166                $error = null;
167            } else {
168                /* Message failed, store error code. */
169                $remote_id = null;
170                $error = $response[1];
171            }
172
173            /* Store the sends. */
174            $sends[] = array('message_id' => $message['id'],
175                             'remote_id'  => $remote_id,
176                             'recipient'  => $recipient,
177                             'error'      => $error);
178        }
179
180        return $sends;
181    }
182
183    /**
184     * If the current driver has a credit capability, queries the gateway for
185     * a credit balance and returns the value.
186     *
187     * @return integer  Value indicating available credit or null if not
188     *                  supported.
189     */
190    function getBalance()
191    {
192        /* Authenticate. */
193        if (is_a($this->authenticate(), 'PEAR_Error')) {
194            return $this->_auth;
195        }
196
197        /* Check balance. */
198        if ($this->hasCapability('credit')) {
199            return $this->_getBalance();
200        } else {
201            return null;
202        }
203    }
204
205    /**
206     * This function does the actual sending of the message.
207     *
208     * @param array $message  The array containing the message and its send
209     *                        parameters.
210     * @param array $to       The recipients.
211     *
212     * @return array  An array with the success status and additional
213     *                information.
214     */
215    protected function _send($message, $to) {
216        return array();
217    }
218
219    /**
220     * Returns a string representation of an error code.
221     *
222     * @param integer $error  The error code to look up.
223     * @param string $text    An existing error text to use to raise a
224     *                        PEAR Error.
225     *
226     * @return mixed  A textual message corresponding to the error code or a
227     *                PEAR Error if passed an existing error text.
228     *
229     * @todo  Check which of these are actually required and trim down the
230     *        list.
231     */
232    public function getError($error, $error_text = '')
233    {
234    }
235}
236