Changeset View
Changeset View
Standalone View
Standalone View
externals/twilio-php/Services/Twilio/Twiml.php
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
<?php | |||||
/** | |||||
* Exception class for Services_Twilio_Twiml. | |||||
*/ | |||||
class Services_Twilio_TwimlException extends Exception {} | |||||
/** | |||||
* Twiml response generator. | |||||
* | |||||
* Author: Neuman Vong <neuman at ashmoremusic dot com> | |||||
* License: http://creativecommons.org/licenses/MIT/ MIT | |||||
*/ | |||||
class Services_Twilio_Twiml { | |||||
protected $element; | |||||
/** | |||||
* Constructs a Twiml response. | |||||
* | |||||
* :param SimpleXmlElement|array $arg: Can be any of | |||||
* | |||||
* - the element to wrap | |||||
* - attributes to add to the element | |||||
* - if null, initialize an empty element named 'Response' | |||||
*/ | |||||
public function __construct($arg = null) { | |||||
switch (true) { | |||||
case $arg instanceof SimpleXmlElement: | |||||
$this->element = $arg; | |||||
break; | |||||
case $arg === null: | |||||
$this->element = new SimpleXmlElement('<Response/>'); | |||||
break; | |||||
case is_array($arg): | |||||
$this->element = new SimpleXmlElement('<Response/>'); | |||||
foreach ($arg as $name => $value) { | |||||
$this->element->addAttribute($name, $value); | |||||
} | |||||
break; | |||||
default: | |||||
throw new TwimlException('Invalid argument'); | |||||
} | |||||
} | |||||
/** | |||||
* Converts method calls into Twiml verbs. | |||||
* | |||||
* A basic example: | |||||
* | |||||
* .. code-block:: php | |||||
* | |||||
* php> print $this->say('hello'); | |||||
* <Say>hello</Say> | |||||
* | |||||
* An example with attributes: | |||||
* | |||||
* .. code-block:: php | |||||
* | |||||
* print $this->say('hello', array('voice' => 'woman')); | |||||
* <Say voice="woman">hello</Say> | |||||
* | |||||
* You could even just pass in an attributes array, omitting the noun: | |||||
* | |||||
* .. code-block:: php | |||||
* | |||||
* print $this->gather(array('timeout' => '20')); | |||||
* <Gather timeout="20"/> | |||||
* | |||||
* :param string $verb: The Twiml verb. | |||||
* :param array $args: | |||||
* - (noun string) | |||||
* - (noun string, attributes array) | |||||
* - (attributes array) | |||||
* | |||||
* :return: A SimpleXmlElement | |||||
* :rtype: SimpleXmlElement | |||||
*/ | |||||
public function __call($verb, array $args) | |||||
{ | |||||
list($noun, $attrs) = $args + array('', array()); | |||||
if (is_array($noun)) { | |||||
list($attrs, $noun) = array($noun, ''); | |||||
} | |||||
/* addChild does not escape XML, while addAttribute does. This means if | |||||
* you pass unescaped ampersands ("&") to addChild, you will generate | |||||
* an error. | |||||
* | |||||
* Some inexperienced developers will pass in unescaped ampersands, and | |||||
* we want to make their code work, by escaping the ampersands for them | |||||
* before passing the string to addChild. (with htmlentities) | |||||
* | |||||
* However other people will know what to do, and their code | |||||
* already escapes ampersands before passing them to addChild. We don't | |||||
* want to break their existing code by turning their &'s into | |||||
* &amp; | |||||
* | |||||
* We also want to use numeric entities, not named entities so that we | |||||
* are fully compatible with XML | |||||
* | |||||
* The following lines accomplish the desired behavior. | |||||
*/ | |||||
$decoded = html_entity_decode($noun, ENT_COMPAT, 'UTF-8'); | |||||
$normalized = htmlspecialchars($decoded, ENT_COMPAT, 'UTF-8', false); | |||||
$child = empty($noun) | |||||
? $this->element->addChild(ucfirst($verb)) | |||||
: $this->element->addChild(ucfirst($verb), $normalized); | |||||
foreach ($attrs as $name => $value) { | |||||
/* Note that addAttribute escapes raw ampersands by default, so we | |||||
* haven't touched its implementation. So this is the matrix for | |||||
* addAttribute: | |||||
* | |||||
* & turns into & | |||||
* & turns into &amp; | |||||
*/ | |||||
if (is_bool($value)) { | |||||
$value = ($value === true) ? 'true' : 'false'; | |||||
} | |||||
$child->addAttribute($name, $value); | |||||
} | |||||
return new static($child); | |||||
} | |||||
/** | |||||
* Returns the object as XML. | |||||
* | |||||
* :return: The response as an XML string | |||||
* :rtype: string | |||||
*/ | |||||
public function __toString() | |||||
{ | |||||
$xml = $this->element->asXml(); | |||||
return str_replace( | |||||
'<?xml version="1.0"?>', | |||||
'<?xml version="1.0" encoding="UTF-8"?>', $xml); | |||||
} | |||||
} |