06.03 php saved
deizel
Tags add more
Component, clickatell, sms, test case and text  
Note
Component and test case for sending texts via the Clickatell XMP API. View test case for usage.
  1. // app/controllers/components/sms.php
  2.  
  3. <?php
  4. class SmsComponent extends Object {
  5.  
  6.     /**
  7.      * API product ID for Clickatell XML connection
  8.      *
  9.      * @var string
  10.      */
  11.     public $api_id = '';
  12.  
  13.     /**
  14.      * Username of Clickatell account
  15.      *
  16.      * @var string
  17.      */
  18.     public $user = '';
  19.  
  20.     /**
  21.      * Password for Clickatell account
  22.      *
  23.      * @var string
  24.      */
  25.     public $password = '';
  26.  
  27.     /**
  28.      * Session ID
  29.      *
  30.      * The session ID from the 'auth' command.
  31.      *
  32.      * @var string This is an MD5 hash (ie. a 32 digit hexadecimal number).
  33.      */
  34.     public $session_id = null;
  35.  
  36.     /**
  37.      * Destination address
  38.      *
  39.      * The number of the handset to which the message must be delivered.
  40.      * The number should be in international number format.
  41.      *
  42.      * @var string No '00' prefix or leading "+" symbol should be used.
  43.      */
  44.     public $to = null;
  45.  
  46.     /**
  47.      * Text
  48.      *
  49.      * The text content of the message.
  50.      * Note that some characters stake up two characters because of GSM encoding standards
  51.      *
  52.      * @var string http://support.clickatell.com/faq.php?mode=view_entry&kbid=121&kbcat=26
  53.      */
  54.     public $text = null;
  55.  
  56.     /**
  57.      * Source address
  58.      *
  59.      * The source/sender address that the message will appear to come from also known as “Sender ID”.
  60.      * These must be registered within your online account and approved by us before they may be used.
  61.      * MO numbers rented from us do not require approval.
  62.      *
  63.      * @var string A valid international format number between 1 and 16 characters long, or an 11 character alphanumeric string.
  64.      * @default gateway assigned number
  65.      */
  66.     public $from = null;
  67.  
  68.     /**
  69.      * Enable callback
  70.      *
  71.      * Enables you to receive message delivery statuses via an HTTP callback which is posted to a URL of yours using the GET or POST method.
  72.      * This is done every time a message status is updated.
  73.      *
  74.      * @var integer 0,1,2,3
  75.      * @default 0
  76.      */
  77.     public $callback = null;
  78.  
  79.     /**
  80.      * Delivery time
  81.      *
  82.      * Delays delivery of SMS to mobile device in minutes relative to the time at which the SMS was received by our gateway.
  83.      * This should be greater than 10 minutes for best effect.
  84.      * Smaller time frames may be delivered too soon.
  85.      *
  86.      * @var integer Minutes. The upper limit is 10080 minutes (7 days).
  87.      */
  88.     public $deliv_time = null;
  89.  
  90.     /**
  91.      * Delivery acknowledgment
  92.      *
  93.      * In order to determine whether an SMS has been received by a handset or not,
  94.      * we request delivery acknowledgement for every message we send.
  95.      * The ability to receive reliable delivery acknowledgements varies between mobile networks.
  96.      * Please test to a specific mobile network first,
  97.      * before assuming that you will receive handset acknowledgments for messages that are delivered.
  98.      * GSM handsets that are off will only be reported once a user has switched their phone back on.
  99.      * If the validity period is exceeded, the Clickatell gateway will return a message status of 7, “Error with message”.
  100.      * A delivery acknowledgment can be monitored via the callback URL or online reports.
  101.      *
  102.      * @var boolean?
  103.      */
  104.     public $deliv_ack = null;
  105.  
  106.     /**
  107.      * Concatenation
  108.      *
  109.      * Enables you to send messages longer than a standard message.
  110.      *
  111.      * @var integer 1,2,3,n. The number of SMS messages a message can span. A maximum of no more than 3 is recommended.
  112.      * @default 1
  113.      */
  114.     public $concat = null;
  115.  
  116.     /**
  117.      * Maximum credits
  118.      *
  119.      * Overrides the maximum charge specified online in “profiles”.
  120.      * It works within the bounds of the profiles.
  121.      * In other words a profile must exist for the maximum credit that you set.
  122.      *
  123.      * @var float 0.8,1,1.5,2,2.5,3
  124.      * @default As per profile
  125.      */
  126.     public $max_credits = null;
  127.  
  128.     /**
  129.      * Required features
  130.      *
  131.      * Some parameters and features are not set as “required” by default, and may be dropped if the least-cost route does not support them.
  132.      * This parameter allows you to ensure that the features set when an SMS is sent are supported by the gateway used.
  133.      * This could increase the cost per message if a more expensive gateway is used.
  134.      *
  135.      * @var string TODO
  136.      */
  137.     public $req_feat = null;
  138.  
  139.     /**
  140.      * Delivery queue
  141.      *
  142.      * Delivers the message through one of three queues assigned to each client account.
  143.      * Messages in the highest priority queue will be delivered first.
  144.      *
  145.      * @var integer 1,2,3 (1 is highest priority)
  146.      * @default 3
  147.      */
  148.     public $queue = null;
  149.  
  150.     /**
  151.      * Gateway escalation
  152.      *
  153.      * Prompts an escalation to an alternative delivery gateway, should the message be delayed for a set length of time.
  154.      *
  155.      * @var integer 0 = off, 1 = Escalate immediately to an alternative route if messages are queued on the least-cost route.
  156.      * @default 0
  157.      */
  158.     public $escalate = null;
  159.  
  160.     /**
  161.      * Mobile originated
  162.      *
  163.      * We route via a pre-defined carrier to enable the ability for a reply to be received back.
  164.      * This is only applicable to clients that have subscribed to a two-way messaging service.
  165.      *
  166.      * @var integer mo 0 = off (use our normal routing rules), 1 = enable reply
  167.      * @default 0
  168.      */
  169.     public $mo = null;
  170.  
  171.     /**
  172.      * Client message ID defined by user for message tracking.
  173.      *
  174.      * @var string Up to 32 alphanumeric characters. No spaces.
  175.      */
  176.     public $cliMsgId = null;
  177.  
  178.     /**
  179.      * API message ID
  180.      *
  181.      * API message ID defined by Clickatell for message tracking.
  182.      *
  183.      * @var string API message ID to lookup in API call
  184.      */
  185.     public $apiMsgId = null;
  186.  
  187.     /**
  188.      * Unicode message
  189.      *
  190.      * Two digit language code. Convert your text to Unicode [UCS-2 encoding]. See http://www.Unicode.org/.
  191.      *
  192.      * @var integer 0 = no Unicode, 1 = send as Unicode.
  193.      * @default 0
  194.      */
  195.     public $Unicode = null;
  196.  
  197.     /**
  198.      * Message type
  199.      *
  200.      * Optional parameter which must be set to send specially formatted messages; e.g. logos and ringtones.
  201.      *
  202.      * @var string SMS_TEXT, SMS_FLASH, SMS_NOKIA_OLOGO, SMS_NOKIA_GLOGO, SMS_NOKIA_PICTURE, SMS_NOKIA_RINGTONE, SMS_NOKIA_RTTL, SMS_NOKIA_CLEAN, SMS_NOKIA_VCARD, SMS_NOKIA_VCAL
  203.      * @default SMS_TEXT
  204.      */
  205.     public $msg_type = null;
  206.  
  207.     /**
  208.      * User data header
  209.      *
  210.      * Allows you to set your own message types. Do not use if you set the message type parameter.
  211.      * When set, Clickatell assumes the data is 8 bit. See 8 bit messaging for more information.
  212.      *
  213.      * @var string Set UDH data manually.
  214.      */
  215.     public $udh = null;
  216.  
  217.     /**
  218.      * Data
  219.      *
  220.      * @var string The data content of a message, if the UDH component is set manually.
  221.      */
  222.     public $data = null;
  223.  
  224.     /**
  225.      * Validity period
  226.      *
  227.      * The validity period in minutes relative to the time at which the SMS was received by our gateway.
  228.      * The message will not be delivered if it is still queued on our gateway after this time period.
  229.      *
  230.      * @var integer Set value in X minutes from 1 – 1440 minutes.
  231.      */
  232.     public $validity = null;
  233.  
  234.     /**
  235.      * Sequence number
  236.      *
  237.      * @var string WTF is this?
  238.      */
  239.     public $sequence_no = null;
  240.  
  241.     /**
  242.      * Debugging enabled?
  243.      *
  244.      * @var boolean
  245.      */
  246.     public $debug = false;
  247.  
  248.     /**
  249.      * URL of gateway for Clickatell XML connection
  250.      *
  251.      * This gateway responds to case-sensitive XML submitted as an HTTP form post
  252.      *
  253.      * @var string
  254.      */
  255.     const API_XML_URL = 'http://api.clickatell.com/xml/xml/';
  256.  
  257.     /**
  258.      * Authenticate with Clickatell API
  259.      *
  260.      * Session expires after 15 minutes. Use ping() to keep session ID live
  261.      *
  262.      * @param string $api_id API ID for Clickatell XML connection
  263.      * @param string $user Username of Clickatell account
  264.      * @param string $password Password for Clickatell account
  265.      * @return mixed Array with session_id or fault, and sequence_no (if set)
  266.      * @access public
  267.      */
  268.     public function auth($api_id = null, $user = null, $password = null, $sequence_no = null) {
  269.         if ($api_id) {
  270.             $this->api_id = $api_id;
  271.         }
  272.  
  273.         if ($user) {
  274.             $this->user = $user;
  275.         }
  276.  
  277.         if ($password) {
  278.             $this->password = $password;
  279.         }
  280.  
  281.         if ($sequence_no) {
  282.             $this->sequence_no = $sequence_no;
  283.         }
  284.  
  285.         $tag = 'auth';
  286.         $params = array(
  287.             'api_id'        => $this->api_id,
  288.             'user'      => $this->user,
  289.             'password'    => $this->password,
  290.             'sequence_no'   => $this->sequence_no);
  291.  
  292.         return $this->__send($tag, $params);
  293.     }
  294.  
  295.     /**
  296.      * Ping the Clickatell API
  297.      *
  298.      * Prevents the session ID from expiring during periods of inactivity.
  299.      * The session ID is set to expire after 15 minutes of inactivity.
  300.      *
  301.      * @param string $session_id Session ID of Clickatell API session to ping
  302.      * @param string $sequence_no
  303.      * @return mixed Array with ok or fault, and sequence_no (if set)
  304.      * @access public
  305.      */
  306.     public function ping($session_id = null, $sequence_no = null) {
  307.         if ($session_id) {
  308.             $this->session_id = $session_id;
  309.         }
  310.  
  311.         if ($sequence_no) {
  312.             $this->sequence_no = $sequence_no;
  313.         }
  314.  
  315.         $tag = 'ping';
  316.         $params = array(
  317.             'session_id'    => $this->session_id,
  318.             'sequence_no'   => $this->sequence_no);
  319.  
  320.         return $this->__send($tag, $params);
  321.     }
  322.  
  323.     /**
  324.      * Send an SMS text message
  325.      *
  326.      * Prevents the session ID from expiring during periods of inactivity.
  327.      * The session ID is set to expire after 15 minutes of inactivity.
  328.      *
  329.      * @param string session_id Session ID of Clickatell API session to use
  330.      * @param string to
  331.      * @param string text
  332.      * @return mixed Array with apiMsgId or fault, and sequence_no (if set)
  333.      * @access public
  334.      */
  335.     public function sendMsg($session_id = null, $to = null, $text = null, $sequence_no = null) {
  336.         if ($session_id) {
  337.             $this->session_id = $session_id;
  338.         }
  339.  
  340.         if ($to) {
  341.             $this->to = $to;
  342.         }
  343.  
  344.         if ($text) {
  345.             $this->text = $text;
  346.         }
  347.  
  348.         if ($sequence_no) {
  349.             $this->sequence_no = $sequence_no;
  350.         }
  351.  
  352.         $tag = 'sendMsg';
  353.         $params = array(
  354.             'session_id'    => $this->session_id,
  355.             'to'            => $this->to,
  356.             'text'      => $this->text,
  357.             'callback'    => $this->callback,
  358.             'cliMsgId'    => $this->cliMsgId,
  359.             'concat'        => $this->concat,
  360.             'deliv_ack'  => $this->deliv_ack,
  361.             'deliv_time'    => $this->deliv_time,
  362.             'from'      => $this->from,
  363.             'msg_type'    => $this->msg_type,
  364.             'udh'         => $this->udh,
  365.             'Unicode'      => $this->Unicode,
  366.             'validity'    => $this->validity,
  367.             'req_feat'    => $this->req_feat,
  368.             'max_credits'   => $this->max_credits,
  369.             'queue'   => $this->queue,
  370.             'escalate'    => $this->escalate,
  371.             'sequence_no'   => $this->sequence_no);
  372.  
  373.         return $this->__send($tag, $params);
  374.     }
  375.  
  376.     /**
  377.      * Query a message
  378.      *
  379.      * This tag returns the status of a message.
  380.      * You can query the status with either the apimsgid or climsgid.
  381.      * The API message ID (apimsgid) is the message ID returned by the gateway when a message has been successfully submitted.
  382.      * If you specified your own unique client message ID (climsgid) on submission, you may query the message status using this value.
  383.      *
  384.      * @param string session_id Session ID of Clickatell API session to use
  385.      * @param string apiMsgId API message ID (if passing this, don't set cliMsgId)
  386.      * @param string cliMsgId Client message ID (if passing this, don't set apiMsgId)
  387.      * @param string sequence_no
  388.      * @return mixed Array with apiMsgId, status or fault, and sequence_no (if set)
  389.      * @access public
  390.      */
  391.     public function queryMsg($session_id = null, $apiMsgId = null, $cliMsgId = null, $sequence_no = null) {
  392.         if ($session_id) {
  393.             $this->session_id = $session_id;
  394.         }
  395.  
  396.         if ($apiMsgId) {
  397.             $this->apiMsgId = $apiMsgId;
  398.         }
  399.  
  400.         if ($cliMsgId) {
  401.             $this->cliMsgId = $cliMsgId;
  402.         }
  403.  
  404.         if ($sequence_no) {
  405.             $this->sequence_no = $sequence_no;
  406.         }
  407.  
  408.         $tag = 'queryMsg';
  409.         $params = array(
  410.             'session_id'    => $this->session_id,
  411.             'apiMsgId'    => $this->apiMsgId,
  412.             'cliMsgId'    => $this->cliMsgId,
  413.             'sequence_no'   => $this->sequence_no);
  414.  
  415.         return $this->__send($tag, $params);
  416.     }
  417.  
  418.     /**
  419.      * Delete/Stop message
  420.      *
  421.      * Enables you to stop the delivery of a particular message.
  422.      * Can only stop messages which may be queued within Clickatell router,
  423.      * and not messages which have already been delivered to a SMSC.
  424.      * This command is therefore only really useful for messages with deferred delivery times.
  425.      *
  426.      * @param string session_id Session ID of Clickatell API session to use
  427.      * @param string apiMsgId API message ID (if passing this, don't set cliMsgId)
  428.      * @param string cliMsgId Client message ID (if passing this, don't set apiMsgId)
  429.      * @param string $sequence_no
  430.      * @return mixed Array with apiMsgId or fault, and sequence_no (if set)
  431.      * @access public
  432.      */
  433.     public function delMsg($session_id = null, $apiMsgId = null, $cliMsgId = null, $sequence_no = null) {
  434.         if ($session_id) {
  435.             $this->session_id = $session_id;
  436.         }
  437.  
  438.         if ($apiMsgId) {
  439.             $this->apiMsgId = $apiMsgId;
  440.         }
  441.  
  442.         if ($cliMsgId) {
  443.             $this->cliMsgId = $cliMsgId;
  444.         }
  445.  
  446.         if ($sequence_no) {
  447.             $this->sequence_no = $sequence_no;
  448.         }
  449.  
  450.         $tag = 'delMsg';
  451.         $params = array(
  452.             'session_id' => $this->session_id,
  453.             'apiMsgId' => $this->apiMsgId,
  454.             'cliMsgId' => $this->cliMsgId,
  455.             'sequence_no' => $this->sequence_no);
  456.  
  457.         return $this->__send($tag, $params);
  458.     }
  459.  
  460.     /**
  461.      * Query balance
  462.      *
  463.      * This will return the number of credits available on this particular account.
  464.      * The account balance is returned as a floating point value.
  465.      *
  466.      * @param string session_id Session ID of Clickatell API session to use
  467.      * @param string $sequence_no
  468.      * @return mixed Array with ok or fault, and sequence_no (if set)
  469.      * @access public
  470.      */
  471.     public function getBalance($session_id = null, $sequence_no = null) {
  472.         if ($session_id) {
  473.             $this->session_id = $session_id;
  474.         }
  475.  
  476.         if ($sequence_no) {
  477.             $this->sequence_no = $sequence_no;
  478.         }
  479.  
  480.         $tag = 'getBalance';
  481.         $params = array(
  482.             'session_id' => $this->session_id,
  483.             'sequence_no' => $this->sequence_no);
  484.  
  485.         return $this->__send($tag, $params);
  486.     }
  487.  
  488.     /**
  489.      * Coverage query
  490.      *
  491.      * This command enables you to check our coverage of a network or number,
  492.      * without sending a message to that number.
  493.      * This call should NOT be used before sending each message.
  494.      *
  495.      * @param string session_id Session ID of Clickatell API session to use
  496.      * @param string to MSISDN of number to check coverage for
  497.      * @param string $sequence_no
  498.      * @return mixed Array with ok or fault, charge and sequence_no (if set)
  499.      * @access public
  500.      */
  501.     public function routeCoverage($session_id = null, $to = null, $sequence_no = null) {
  502.  
  503.         if ($session_id) {
  504.             $this->session_id = $session_id;
  505.         }
  506.  
  507.         if ($to) {
  508.             $this->to = $to;
  509.         }
  510.  
  511.         if ($sequence_no) {
  512.             $this->sequence_no = $sequence_no;
  513.         }
  514.  
  515.         $tag = 'routeCoverage';
  516.         $params = array(
  517.             'session_id' => $this->session_id,
  518.             'msisdn' => $this->to,
  519.             'sequence_no' => $this->sequence_no);
  520.  
  521.         return $this->__send($tag, $params);
  522.     }
  523.  
  524.     /**
  525.      * Get message status from status number
  526.      *
  527.      * Use this to get a human readable status message
  528.      *
  529.      * @param string status_no Error code returned by API
  530.      * @return mixed Array with description and detail
  531.      * @access public
  532.      */
  533.      public function getError($error_code) {
  534.         $status_detail = '';
  535.         switch ($error_code) {
  536.             case 001:
  537.                 $status_description = 'Authentication failed';
  538.                 break;
  539.             case 002:
  540.                 $status_description = 'Unknown username or password';
  541.                 break;
  542.             case 003:
  543.                 $status_description = 'Session ID expired';
  544.                 break;
  545.             case 004:
  546.                 $status_description = 'Account frozen';
  547.                 break;
  548.             case 005:
  549.                 $status_description = 'Missing session ID';
  550.                 break;
  551.             case 007:
  552.                 $status_description = 'IP Lockdown violation';
  553.                 $status_detail = 'You have locked down the API instance to a specific IP address and then sent from an IP address different to the one you set.';
  554.                 break;
  555.             case 101:
  556.                 $status_description = 'Invalid or missing parameters';
  557.                 break;
  558.             case 102:
  559.                 $status_description = 'Invalid user data header';
  560.                 break;
  561.             case 103:
  562.                 $status_description = 'Unknown API message ID';
  563.                 break;
  564.             case 104:
  565.                 $status_description = 'Unknown client message ID';
  566.                 break;
  567.             case 105:
  568.                 $status_description = 'Invalid destination address';
  569.                 break;
  570.             case 106:
  571.                 $status_description = 'Invalid source address';
  572.                 break;
  573.             case 107:
  574.                 $status_description = 'Empty message';
  575.                 break;
  576.             case 108:
  577.                 $status_description = 'Invalid or missing API ID';
  578.                 break;
  579.             case 109:
  580.                 $status_description = 'Missing message ID';
  581.                 $status_detail = 'This can be either a client message ID or API message ID. For example when using the del_msg command.';
  582.                 break;
  583.             case 110:
  584.                 $status_description = 'Error with email message';
  585.                 break;
  586.             case 111:
  587.                 $status_description = 'Invalid protocol';
  588.                 break;
  589.             case 112:
  590.                 $status_description = 'Invalid message type';
  591.                 break;
  592.             case 113:
  593.                 $status_description = 'Maximum message parts exceeded';
  594.                 $status_detail = 'The text message component of the message is greater than the permitted 160 characters (70 Unicode characters). Select concat equal to 1,2,3-N to overcome this by splitting the message across multiple messages.';
  595.                 break;
  596.             case 114:
  597.                 $status_description = 'Cannot route message';
  598.                 $status_detail = 'This implies that the gateway is not currently routing messages to this network prefix. Please email support@clickatell.com with the mobile number in question.';
  599.                 break;
  600.             case 115:
  601.                 $status_description = 'Message expired';
  602.                 break;
  603.             case 116:
  604.                 $status_description = 'Invalid Unicode data';
  605.                 break;
  606.             case 120:
  607.                 $status_description = 'Invalid delivery time';
  608.                 break;
  609.             case 121:
  610.                 $status_description = 'Destination mobile number blocked';
  611.                 $status_detail = 'This number is not allowed to receive messages from us and has been put on our block list.';
  612.                 break;
  613.             case 122:
  614.                 $status_description = 'Destination mobile opted out';
  615.                 break;
  616.             case 201:
  617.                 $status_description = 'Invalid batch ID';
  618.                 break;
  619.             case 202:
  620.                 $status_description = 'No batch template';
  621.                 break;
  622.             case 301:
  623.                 $status_description = 'No credit left';
  624.                 break;
  625.             case 302:
  626.                 $status_description = 'Max allowed credit';
  627.                 break;
  628.             default:
  629.                 $status_description = 'Unknown status';
  630.                 $status_detail = 'This status number is unknown';
  631.                 break;
  632.         }
  633.         return array('description' => $status_description, 'detail' => $status_detail);
  634.     }
  635.  
  636.     /**
  637.      * Get message status from status number
  638.      *
  639.      * Use this to get a human readable status message
  640.      *
  641.      * @param string status_no Status returned by queryMsg()
  642.      * @return mixed Array with description and detail
  643.      * @access public
  644.      */
  645.      public function getMessageStatus($status_no) {
  646.         switch ($status_no) {
  647.             case 1:
  648.                 $status_description = 'Message unknown';
  649.                 $status_detail = 'The message ID is incorrect or reporting is delayed.';
  650.                 break;
  651.             case 2:
  652.                 $status_description = 'Message queued';
  653.                 $status_detail = 'The message could not be delivered and has been queued for attempted redelivery.';
  654.                 break;
  655.             case 3:
  656.                 $status_description = 'Delivered to gateway';
  657.                 $status_detail = 'Delivered to the upstream gateway or network (delivered to the recipient).';
  658.                 break;
  659.             case 4:
  660.                 $status_description = 'Received by recipient';
  661.                 $status_detail = 'Confirmation of receipt on the handset of the recipient.';
  662.                 break;
  663.             case 5:
  664.                 $status_description = 'Error with message';
  665.                 $status_detail = 'There was an error with the message, probably caused by the content of the message itself.';
  666.                 break;
  667.             case 6:
  668.                 $status_description = 'User cancelled message delivery';
  669.                 $status_detail = 'The message was terminated by an internal mechanism.';
  670.                 break;
  671.             case 7:
  672.                 $status_description = 'Error delivering message';
  673.                 $status_detail = 'An error occurred delivering the message to the handset.';
  674.                 break;
  675.             case 8:
  676.                 $status_description = 'OK';
  677.                 $status_detail = 'Message received by gateway.';
  678.                 break;
  679.             case 9:
  680.                 $status_description = 'Routing error';
  681.                 $status_detail = 'The routing gateway or network has had an error routing the message.';
  682.                 break;
  683.             case 10:
  684.                 $status_description = 'Message expired';
  685.                 $status_detail = 'Message has expired before we were able to deliver it to the upstream gateway. No charge applies.';
  686.                 break;
  687.             case 11:
  688.                 $status_description = 'Message queued for later delivery';
  689.                 $status_detail = 'Message has been queued at the gateway for delivery at a later time (delayed delivery).';
  690.                 break;
  691.             case 12:
  692.                 $status_description = 'Out of credit';
  693.                 $status_detail = 'The message cannot be delivered due to a lack of funds in account. Please wait for us to re-purchase credits.';
  694.                 break;
  695.             default:
  696.                 $status_description = 'Unknown status';
  697.                 $status_detail = 'This status number is unknown';
  698.                 break;
  699.         }
  700.         return array('description' => $status_description, 'detail' => $status_detail);
  701.     }
  702.  
  703.     /**
  704.      * Send an XML request to Clickatell API and extract response
  705.      *
  706.      * @param string tag Name of the API function (tag) to call
  707.      * @param object params Associative array of each parameter and value for call
  708.      * @return object Associative array holding the response values from the API call
  709.      * @access private
  710.      */
  711.     private function __send($tag, $params) {
  712.         $xmlRequest = $this->__createXML($tag, $params);
  713.         $xmlResponse = $this->__postXML($xmlRequest);
  714.         $response = $this->__getResponseFromXML($tag, $xmlResponse);
  715.         return $response;
  716.     }
  717.  
  718.     /**
  719.      * Create well-formed XML request for use with Clickatell API
  720.      *
  721.      * @param string tag Name of the API function (tag) to call
  722.      * @param object params Associative array of each parameter and value for call
  723.      * @return string Well-formed XML request
  724.      * @access private
  725.      */
  726.     private function __createXML($tag, $params) {
  727.         $xml = new SimpleXMLElement('<clickAPI></clickAPI>');
  728.         $tag = $xml->addChild($tag);
  729.         foreach ($params as $key => $value) {
  730.             if ($value) {
  731.                 $tag->addChild($key, $value);
  732.             }
  733.         }
  734.         $xmlRequest = $xml->asXML();
  735.         if ($this->debug) {
  736.             echo 'XML request for ' . $tag;
  737.             pr('<xmp>' . $xmlRequest . '</xmp>');
  738.         }
  739.         return $xmlRequest;
  740.     }
  741.  
  742.     /**
  743.      * Post the XML request to the Clickatell API gateway
  744.      *
  745.      * @param string Well-formed XML request for Clickatell's API gateway
  746.      * @return string Well-formed XML response from Clickatell's API gateway
  747.      * @access private
  748.      */
  749.     private function __postXML($xmlRequest) {
  750.         if (function_exists('curl_init')) {
  751.             $ch = curl_init();
  752.             $options = array(
  753.                 CURLOPT_POSTFIELDS => 'data=' . $xmlRequest,
  754.                 //CURLOPT_PROXY => '128.127.111.111',
  755.                 //CURLOPT_PROXYPORT => '8080',
  756.                 CURLOPT_RETURNTRANSFER => true,
  757.                 CURLOPT_URL => self::API_XML_URL);
  758.             curl_setopt_array($ch, $options);
  759.             $xmlResponse = curl_exec($ch);
  760.             curl_close($ch);
  761.             if ($this->debug) {
  762.                 echo 'XML response';
  763.                 pr('<xmp>' . $xmlResponse . '</xmp>');
  764.             }
  765.             return $xmlResponse;
  766.         } else {
  767.             die('PHP CURL library not enabled. (Uncomment extension=php_curl.dll in php.ini)');
  768.         }
  769.     }
  770.  
  771.     /**
  772.      * Extract serialized response from Clickatell XML response
  773.      *
  774.      * @param string tag Name of the API function (tag) to call
  775.      * @param string xmlResponse Well-formed XML response from Clickatell's API gateway
  776.      * @return object Associative array holding the response values from the API call
  777.      * @access private
  778.      */
  779.     private function __getResponseFromXML($tag, $xmlResponse) {
  780.         $xml = new SimpleXMLElement($xmlResponse);
  781.         return $xml->{$tag . 'Resp'};
  782.     }
  783. }
  784. ?>
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795. // app/tests/cases/components/sms.test.php
  796.  
  797. <?php
  798. App::import('Component', 'Sms');
  799.  
  800. class SmsTestController extends Controller {
  801.  
  802.     public $name = 'SmsTest';
  803.     public $uses = null;
  804.     public $components = array('Sms');
  805.  
  806. }
  807.  
  808. class SmsTest extends CakeTestCase {
  809.  
  810.     public $name = 'Sms';
  811.    
  812.     private $testNum = '1234567890';
  813.  
  814.     function setUp() {
  815.         $this->Controller =& new SmsTestController();
  816.         restore_error_handler();
  817.         @$this->Controller->_initComponents();
  818.         set_error_handler('simpleTestErrorHandler');
  819.         //$this->Controller->Sms->startup($this->Controller);
  820.         ClassRegistry::addObject('view', new View($this->Controller));
  821.         $this->Controller->Sms->debug = true;
  822.     }
  823.  
  824.     function testAuth() {
  825.         echo '<h3>auth()</h3>';
  826.         $response = $this->Controller->Sms->auth();
  827.         $this->assertTrue(isset($response->session_id));
  828.         $this->session_id = $response->session_id;
  829.     }
  830.  
  831.     function testPing() {
  832.         echo '<h3>ping()</h3>';
  833.         $response = $this->Controller->Sms->ping($this->session_id);
  834.         $this->assertTrue(isset($response->ok));
  835.         $this->assertTrue($response->ok);
  836.     }
  837.  
  838.     // this should only cost money if the telephone number is recognized..
  839.     /*
  840.     function testSendMsg() {
  841.         echo '<h3>sendMsg()</h3>';
  842.         $response = $this->Controller->Sms->sendMsg($this->session_id, $this->testNum, 'This is a test SMS.');
  843.         $this->assertTrue(isset($response->apiMsgId));
  844.         $this->assertTrue($response->apiMsgId);
  845.     }
  846.     */
  847.  
  848.     function testQueryMsg() {
  849.         echo '<h3>queryMsg()</h3>';
  850.         $response = $this->Controller->Sms->queryMsg($this->session_id, '265895850416d42561e745ba62e3fed0');
  851.         //$this->assertTrue(isset($response->apiMsgId));
  852.         //$this->assertTrue($response->apiMsgId);
  853.     }
  854.  
  855.     function testGetBalance() {
  856.         echo '<h3>getBalance()</h3>';
  857.         $response = $this->Controller->Sms->getBalance($this->session_id);
  858.         $this->assertTrue(isset($response->ok));
  859.         $this->assertTrue($response->ok);
  860.     }</