summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Duedal <hd@onlinecity.dk>2011-10-05 09:54:26 +0200
committerHans Duedal <hd@onlinecity.dk>2011-10-05 09:54:26 +0200
commit7664118079141be22a4beec5cdb9709ad4c132cd (patch)
tree1adeca487f227cfee4e0c4c177cc650b19438004
parent9f5b5ef788ab166fdc42b1561691df20ecb60558 (diff)
parent01bc959c53c3f1484c3eff2d147e2b3ace7a9b1a (diff)
downloadphp-smpp-7664118079141be22a4beec5cdb9709ad4c132cd.zip
php-smpp-7664118079141be22a4beec5cdb9709ad4c132cd.tar.gz
php-smpp-7664118079141be22a4beec5cdb9709ad4c132cd.tar.bz2
Merged QUERY_SM / queryStatus() feature from develop
-rw-r--r--smppclient.class.php75
1 files changed, 74 insertions, 1 deletions
diff --git a/smppclient.class.php b/smppclient.class.php
index 521ae97..0dcbb7d 100644
--- a/smppclient.class.php
+++ b/smppclient.class.php
@@ -140,6 +140,79 @@ class SmppClient
}
/**
+ * Parse a timestring as formatted by SMPP v3.4 section 7.1.
+ * Returns an unix timestamp if $newDates is false or DateTime/DateInterval is missing,
+ * otherwise an object of either DateTime or DateInterval is returned.
+ *
+ * @param string $input
+ * @param boolean $newDates
+ * @return mixed
+ */
+ public function parseSmppTime($input, $newDates=true)
+ {
+ // Check for support for new date classes
+ if (!class_exists('DateTime') || !class_exists('DateInterval')) $newDates = false;
+
+ $numMatch = preg_match('/^(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{1})(\\d{2})([R+-])$/',$input,$matches);
+ if (!$numMatch) return null;
+ list($whole, $y, $m, $d, $h, $i, $s, $t, $n, $p) = $matches;
+
+ // Use strtotime to convert relative time into a unix timestamp
+ if ($p == 'R') {
+ if ($newDates) {
+ $spec = "P";
+ if ($y) $spec .= $y.'Y';
+ if ($m) $spec .= $m.'M';
+ if ($d) $spec .= $d.'D';
+ if ($h || $i || $s) $spec .= 'T';
+ if ($h) $spec .= $h.'H';
+ if ($i) $spec .= $i.'M';
+ if ($s) $spec .= $s.'S';
+ return new DateInterval($spec);
+ } else {
+ return strtotime("+$y year +$m month +$d day +$h hour +$i minute $s +second");
+ }
+ } else {
+ $offsetHours = floor($n/4);
+ $offsetMinutes = ($n % 4)*15;
+ $time = sprintf("20%02s-%02s-%02sT%02s:%02s:%02s%s%02s:%02s",$y,$m,$d,$h,$i,$s,$p,$offsetHours,$offsetMinutes); // Not Y3K safe
+ if ($newDates) {
+ return new DateTime($time);
+ } else {
+ return strtotime($time);
+ }
+ }
+ }
+
+ /**
+ * Query the SMSC about current state/status of a previous sent SMS.
+ * You must specify the SMSC assigned message id and source of the sent SMS.
+ * Returns an associative array with elements: message_id, final_date, message_state and error_code.
+ * message_state would be one of the SMPP::STATE_* constants. (SMPP v3.4 section 5.2.28)
+ * error_code depends on the telco network, so could be anything.
+ *
+ * @param string $messageid
+ * @param SmppAddress $source
+ * @return array
+ */
+ public function queryStatus($messageid,SmppAddress $source)
+ {
+ $pduBody = pack('a'.(strlen($messageid)+1).'cca'.(strlen($source->value)+1),$messageid,$source->ton,$source->npi,$source->value);
+ $reply = $this->sendCommand(SMPP::QUERY_SM, $pduBody);
+ if (!$reply || $reply->status != SMPP::ESME_ROK) return null;
+
+ // Parse reply
+ $posId = strpos($reply->body,"\0",0);
+ $posDate = strpos($reply->body,"\0",$posId+1);
+ $data = array();
+ $data['message_id'] = substr($reply->body,0,$posId);
+ $data['final_date'] = substr($reply->body,$posId,$posDate-$posId);
+ $data['final_date'] = $data['final_date'] ? $this->parseSmppTime(trim($data['final_date'])) : null;
+ $status = unpack("cmessage_state/cerror_code",substr($reply->body,$posDate+1));
+ return array_merge($data,$status);
+ }
+
+ /**
* Read one SMS from SMSC. Can be executed only after bindReceiver() call.
* This method bloks. Method returns on socket timeout or enquire_link signal from SMSC.
* @return sms associative array or false when reading failed or no more sms.
@@ -1156,4 +1229,4 @@ class SmppTag
{
return pack('nn'.$this->type, $this->id, ($this->length ? $this->length : strlen($this->value)), $this->value);
}
-} \ No newline at end of file
+}