diff --git a/common/framework/drivers/sms/base.php b/common/framework/drivers/sms/base.php new file mode 100644 index 000000000..253f87b2b --- /dev/null +++ b/common/framework/drivers/sms/base.php @@ -0,0 +1,88 @@ +_config = $config; + } + + /** + * Create a new instance of the current mail driver, using the given settings. + * + * @param array $config + * @return void + */ + public static function getInstance(array $config) + { + return new static($config); + } + + /** + * Get the human-readable name of this mail driver. + * + * @return string + */ + public static function getName() + { + return class_basename(get_called_class()); + } + + /** + * Get the list of configuration fields required by this mail driver. + * + * @return array + */ + public static function getRequiredConfig() + { + return array(); + } + + /** + * Get the list of API types supported by this mail driver. + * + * @return array + */ + public static function getAPITypes() + { + return array(); + } + + /** + * Check if the current mail driver is supported on this server. + * + * This method returns true on success and false on failure. + * + * @return bool + */ + public static function isSupported() + { + return true; + } + + /** + * Send a message. + * + * This method returns true on success and false on failure. + * + * @param object $message + * @return bool + */ + public function send(\Rhymix\Framework\SMS $message) + { + return false; + } +} diff --git a/common/framework/drivers/sms/coolsms.php b/common/framework/drivers/sms/coolsms.php new file mode 100644 index 000000000..3ddcd2426 --- /dev/null +++ b/common/framework/drivers/sms/coolsms.php @@ -0,0 +1,121 @@ +getRecipientsWithCountry(); + foreach ($recipients as $recipient) + { + // Populate the options object. + $options = new \stdClass; + $options->from = $message->getFrom(); + $options->to = $recipient->number; + $options->text = $message->getContent(); + $options->charset = 'UTF-8'; + + // Determine the message type based on the length. + $options->type = $this->_isShort($options->text) ? 'SMS' : 'LMS'; + + // If the message has a subject, it must be an LMS. + if ($subject = $message->getSubject()) + { + $options->subject = $subject; + $options->type = 'LMS'; + } + + // If the message has an attachment, it must be an MMS. + if ($attachments = $message->getAttachments()) + { + $image = reset($attachments); + $options->image = $image->local_filename; + $options->type = 'MMS'; + } + + // If the recipient is not a Korean number, force SMS. + if ($recipient->country && $recipient->country != 82) + { + unset($options->subject); + unset($options->image); + $options->text = $this->_cutShort($options->text); + $options->type = 'SMS'; + } + + // Send the message. + $sender = new \Nurigo\Api\Message($this->_config['api_key'], $this->_config['api_secret']); + $result = $sender->send($options); + return (isset($result->success_count) && $result->success_count > 0) ? true : false; + } + } + catch (\Nurigo\Exceptions\CoolsmsException $e) + { + $message->errors[] = class_basename($e) . ': ' . $e->getMessage(); + return false; + } + } + + /** + * Check if a message is short enough to fit in an SMS. + * + * @param string $message + * @param int $maxlength (optional) + * @return bool + */ + protected function _isShort($message, $maxlength = 90) + { + $message = @iconv('UTF-8', 'CP949//IGNORE', $message); + return strlen($message) <= $maxlength; + } + + /** + * Cut a message to fit in an SMS. + * + * @param string $message + * @param int $maxlength (optional) + * @return string + */ + protected function _cutShort($message, $maxlength = 90) + { + $message = @iconv('UTF-8', 'CP949//IGNORE', $message); + while (strlen($message) > $maxlength) + { + $message = iconv_substr($message, 0, iconv_strlen($str, 'CP949') - 1, 'CP949'); + } + return iconv('CP949', 'UTF-8', $message); + } +} diff --git a/common/framework/drivers/smsinterface.php b/common/framework/drivers/smsinterface.php new file mode 100644 index 000000000..b9b1d0396 --- /dev/null +++ b/common/framework/drivers/smsinterface.php @@ -0,0 +1,57 @@ + $class_name::getName(), + 'required' => $class_name::getRequiredConfig(), + 'api_types' => $class_name::getAPITypes(), + ); + } + } + foreach (self::$custom_drivers as $driver) + { + if ($driver->isSupported()) + { + $result[strtolower(class_basename($driver))] = array( + 'name' => $driver->getName(), + 'required' => $driver->getRequiredConfig(), + 'api_types' => $driver->getAPITypes(), + ); + } + } + ksort($result); + return $result; + } + + /** + * The constructor. + */ + public function __construct() + { + $this->driver = self::getDefaultDriver(); + } + + /** + * Set the sender's phone number. + * + * @param string $number Phone number + * @return bool + */ + public function setFrom($number) + { + $this->from = preg_replace('/[^0-9]/', '', $number); + return true; + } + + /** + * Get the sender's phone number. + * + * @return string|null + */ + public function getFrom() + { + return $this->from; + } + + /** + * Add a recipient. + * + * @param string $number Phone number + * @param string $country Country code (optional) + * @return bool + */ + public function addTo($number, $country = null) + { + $this->to[] = (object)array( + 'number' => preg_replace('/[^0-9]/', '', $number), + 'country' => $country, + ); + return true; + } + + /** + * Get the list of recipients without country codes. + * + * @return array + */ + public function getRecipients() + { + return array_map(function($recipient) { + return $recipient->number; + }, $this->to); + } + + /** + * Get the list of recipients with country codes. + * + * @return array + */ + public function getRecipientsWithCountry() + { + return $this->to; + } + + /** + * Set the subject. + * + * @param string $subject + * @return bool + */ + public function setSubject($subject) + { + $this->subject = utf8_trim(utf8_clean($subject)); + return true; + } + + /** + * Get the subject. + * + * @return string + */ + public function getSubject() + { + return $this->subject; + } + + /** + * Set the subject (alias to setSubject). + * + * @param string $subject + * @return bool + */ + public function setTitle($subject) + { + return $this->setSubject($subject); + } + + /** + * Get the subject (alias to getSubject). + * + * @return string + */ + public function getTitle() + { + return $this->getSubject(); + } + + /** + * Set the content. + * + * @param string $content + * @return bool + */ + public function setBody($content) + { + $this->content = utf8_trim(utf8_clean($content)); + return true; + } + + /** + * Get the content. + * + * @return string + */ + public function getBody() + { + return $this->content; + } + + /** + * Set the content (alias to setBody). + * + * @param string $content + * @return void + */ + public function setContent($content) + { + return $this->setBody($content); + } + + /** + * Get the content (alias to getBody). + * + * @return string + */ + public function getContent() + { + return $this->getBody(); + } + + /** + * Attach a file. + * + * @param string $local_filename + * @param string $display_filename (optional) + * @return bool + */ + public function attach($local_filename, $display_filename = null) + { + if ($display_filename === null) + { + $display_filename = basename($local_filename); + } + if (!Storage::exists($local_filename)) + { + return false; + } + + $this->attachments[] = (object)array( + 'type' => 'mms', + 'local_filename' => $local_filename, + 'display_filename' => $display_filename, + 'cid' => null, + ); + return true; + } + + /** + * Get the list of attachments to this message. + * + * @return array + */ + public function getAttachments() + { + return $this->attachments; + } + + /** + * Send the email. + * + * @return bool + */ + public function send() + { + // Get caller information. + $backtrace = debug_backtrace(0); + if(count($backtrace) && isset($backtrace[0]['file'])) + { + $this->caller = $backtrace[0]['file'] . ($backtrace[0]['line'] ? (' line ' . $backtrace[0]['line']) : ''); + } + + $output = \ModuleHandler::triggerCall('sms.send', 'before', $this); + if(!$output->toBool()) + { + $this->errors[] = $output->getMessage(); + return false; + } + + try + { + if ($this->driver) + { + $this->sent = $this->driver->send($this) ? true : false; + } + else + { + $this->errors[] = 'No SMS driver selected'; + $this->sent = false; + } + } + catch(\Exception $e) + { + $this->errors[] = $e->getMessage(); + $this->sent = false; + } + + $output = \ModuleHandler::triggerCall('sms.send', 'after', $this); + if(!$output->toBool()) + { + $this->errors[] = $output->getMessage(); + } + + return $this->sent; + } + + /** + * Check if the message was sent. + * + * @return bool + */ + public function isSent() + { + return $this->sent; + } + + /** + * Get caller information. + * + * @return string + */ + public function getCaller() + { + return $this->caller; + } + + /** + * Get errors. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } +}