Update of /cvsroot/stack/stack-1-0/other/domit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17646/other/domit Added Files: changelog.txt docs.html domit.html domitBanner.gif license.txt php_file_utilities.php php_http_client_generic.php php_http_client_include.php php_http_connector.php php_http_exceptions.php php_http_proxy.php testing_domit.css testing_domit.php timer.php tutorial.html xml_domit_cache.php xml_domit_doctor.php xml_domit_getelementsbypath.php xml_domit_include.php xml_domit_lite_include.php xml_domit_lite_parser.php xml_domit_nodemaps.php xml_domit_nodetools.php xml_domit_parseattributes.php xml_domit_parser.php xml_domit_shared.php xml_domit_utilities.php xml_domit_xpath.php xml_saxy_lite_parser.php xml_saxy_parser.php xml_saxy_shared.php Log Message: Merging of Paul Kiddie's work into main STACK HEAD branch --- NEW FILE: xml_saxy_shared.php --- <?php /** * SAXY_Parser_Base is a base class for SAXY and SAXY Lite * @package saxy-xmlparser * @version 0.87 * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/saxy/ SAXY Home Page * SAXY is Free Software **/ /** the initial characters of a cdata section */ define('SAXY_SEARCH_CDATA', '![CDATA['); /** the length of the initial characters of a cdata section */ define('SAXY_CDATA_LEN', 8); /** the initial characters of a notation */ define('SAXY_SEARCH_NOTATION', '!NOTATION'); /** the initial characters of a doctype */ define('SAXY_SEARCH_DOCTYPE', '!DOCTYPE'); /** saxy parse state, just before parsing an attribute */ define('SAXY_STATE_ATTR_NONE', 0); /** saxy parse state, parsing an attribute key */ define('SAXY_STATE_ATTR_KEY', 1); /** saxy parse state, parsing an attribute value */ define('SAXY_STATE_ATTR_VALUE', 2); /** * The base SAX Parser class * * @package saxy-xmlparser * @author John Heinstein <joh...@nb...> */ class SAXY_Parser_Base { /** @var int The current state of the parser */ var $state; /** @var int A temporary container for parsed characters */ var $charContainer; /** @var Object A reference to the start event handler */ var $startElementHandler; /** @var Object A reference to the end event handler */ var $endElementHandler; /** @var Object A reference to the data event handler */ var $characterDataHandler; /** @var Object A reference to the CDATA Section event handler */ var $cDataSectionHandler = null; /** @var boolean True if predefined entities are to be converted into characters */ var $convertEntities = true; /** @var Array Translation table for predefined entities */ var $predefinedEntities = array('&' => '&', '<' => '<', '>' => '>', '"' => '"', ''' => "'"); /** @var Array User defined translation table for entities */ var $definedEntities = array(); /** @var boolean True if whitespace is to be preserved during parsing. NOT YET IMPLEMENTED! */ var $preserveWhitespace = false; /** * Constructor for SAX parser */ function SAXY_Parser_Base() { $this->charContainer = ''; } //SAXY_Parser_Base /** * Sets a reference to the handler for the start element event * @param mixed A reference to the start element handler */ function xml_set_element_handler($startHandler, $endHandler) { $this->startElementHandler = $startHandler; $this->endElementHandler = $endHandler; } //xml_set_element_handler /** * Sets a reference to the handler for the data event * @param mixed A reference to the data handler */ function xml_set_character_data_handler($handler) { $this->characterDataHandler =& $handler; } //xml_set_character_data_handler /** * Sets a reference to the handler for the CDATA Section event * @param mixed A reference to the CDATA Section handler */ function xml_set_cdata_section_handler($handler) { $this->cDataSectionHandler =& $handler; } //xml_set_cdata_section_handler /** * Sets whether predefined entites should be replaced with their equivalent characters during parsing * @param boolean True if entity replacement is to occur */ function convertEntities($truthVal) { $this->convertEntities = $truthVal; } //convertEntities /** * Appends an array of entity mappings to the existing translation table * * Intended mainly to facilitate the conversion of non-ASCII entities into equivalent characters * * @param array A list of entity mappings in the format: array('&' => '&'); */ function appendEntityTranslationTable($table) { $this->definedEntities = $table; } //appendEntityTranslationTable /** * Gets the nth character from the end of the string * @param string The text to be queried * @param int The index from the end of the string * @return string The found character */ function getCharFromEnd($text, $index) { $len = strlen($text); $char = $text{($len - 1 - $index)}; return $char; } //getCharFromEnd /** * Parses the attributes string into an array of key / value pairs * @param string The attribute text * @return Array An array of key / value pairs */ function parseAttributes($attrText) { $attrText = trim($attrText); $attrArray = array(); $maybeEntity = false; $total = strlen($attrText); $keyDump = ''; $valueDump = ''; $currentState = SAXY_STATE_ATTR_NONE; $quoteType = ''; for ($i = 0; $i < $total; $i++) { $currentChar = $attrText{$i}; if ($currentState == SAXY_STATE_ATTR_NONE) { if (trim($currentChar != '')) { $currentState = SAXY_STATE_ATTR_KEY; } } switch ($currentChar) { case "\t": if ($currentState == SAXY_STATE_ATTR_VALUE) { $valueDump .= $currentChar; } else { $currentChar = ''; } break; case "\x0B": //vertical tab case "\n": case "\r": $currentChar = ''; break; case '=': if ($currentState == SAXY_STATE_ATTR_VALUE) { $valueDump .= $currentChar; } else { $currentState = SAXY_STATE_ATTR_VALUE; $quoteType = ''; $maybeEntity = false; } break; case '"': if ($currentState == SAXY_STATE_ATTR_VALUE) { if ($quoteType == '') { $quoteType = '"'; } else { if ($quoteType == $currentChar) { if ($this->convertEntities && $maybeEntity) { $valueDump = strtr($valueDump, $this->predefinedEntities); $valueDump = strtr($valueDump, $this->definedEntities); } $keyDump = trim($keyDump); $attrArray[$keyDump] = $valueDump; $keyDump = $valueDump = $quoteType = ''; $currentState = SAXY_STATE_ATTR_NONE; } else { $valueDump .= $currentChar; } } } break; case "'": if ($currentState == SAXY_STATE_ATTR_VALUE) { if ($quoteType == '') { $quoteType = "'"; } else { if ($quoteType == $currentChar) { if ($this->convertEntities && $maybeEntity) { $valueDump = strtr($valueDump, $this->predefinedEntities); $valueDump = strtr($valueDump, $this->definedEntities); } $keyDump = trim($keyDump); $attrArray[$keyDump] = $valueDump; $keyDump = $valueDump = $quoteType = ''; $currentState = SAXY_STATE_ATTR_NONE; } else { $valueDump .= $currentChar; } } } break; case '&': //might be an entity $maybeEntity = true; $valueDump .= $currentChar; break; default: if ($currentState == SAXY_STATE_ATTR_KEY) { $keyDump .= $currentChar; } else { $valueDump .= $currentChar; } } } return $attrArray; } //parseAttributes /** * Parses character data * @param string The character data */ function parseBetweenTags($betweenTagText) { if (trim($betweenTagText) != ''){ $this->fireCharacterDataEvent($betweenTagText); } } //parseBetweenTags /** * Fires a start element event * @param string The start element tag name * @param Array The start element attributes */ function fireStartElementEvent($tagName, $attributes) { call_user_func($this->startElementHandler, $this, $tagName, $attributes); } //fireStartElementEvent /** * Fires an end element event * @param string The end element tag name */ function fireEndElementEvent($tagName) { call_user_func($this->endElementHandler, $this, $tagName); } //fireEndElementEvent /** * Fires a character data event * @param string The character data */ function fireCharacterDataEvent($data) { if ($this->convertEntities && ((strpos($data, "&") != -1))) { $data = strtr($data, $this->predefinedEntities); $data = strtr($data, $this->definedEntities); } call_user_func($this->characterDataHandler, $this, $data); } //fireCharacterDataEvent /** * Fires a CDATA Section event * @param string The CDATA Section data */ function fireCDataSectionEvent($data) { call_user_func($this->cDataSectionHandler, $this, $data); } //fireCDataSectionEvent } //SAXY_Parser_Base ?> --- NEW FILE: xml_domit_shared.php --- <?php /** * @package domit-xmlparser * @version 0.98 * @copyright (C) 2004 John Heinstein. All rights reserved * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page * DOMIT! is Free Software **/ if (!defined('DOMIT_INCLUDE_PATH')) { /* Path to DOMIT! files */ define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/")); } //Nodes /** DOM Element nodeType */ define('DOMIT_ELEMENT_NODE', 1); /** DOM Attr nodeType */ define('DOMIT_ATTRIBUTE_NODE', 2); /** DOM Text nodeType */ define('DOMIT_TEXT_NODE', 3); /** DOM CDATA Section nodeType */ define('DOMIT_CDATA_SECTION_NODE', 4); /** DOM Entity Reference nodeType */ define('DOMIT_ENTITY_REFERENCE_NODE', 5); /** DOM Entity nodeType */ define('DOMIT_ENTITY_NODE', 6); /** DOM Processing Instruction nodeType */ define('DOMIT_PROCESSING_INSTRUCTION_NODE', 7); /** DOM Comment nodeType */ define('DOMIT_COMMENT_NODE', 8); /** DOM Document nodeType */ define('DOMIT_DOCUMENT_NODE', 9); /** DOM DocType nodeType */ define('DOMIT_DOCUMENT_TYPE_NODE', 10); /** DOM Document Fragment nodeType */ define('DOMIT_DOCUMENT_FRAGMENT_NODE', 11); /** DOM Notation nodeType */ define('DOMIT_NOTATION_NODE', 12); //DOM Level 1 Exceptions /** DOM error: array index out of bounds */ define('DOMIT_INDEX_SIZE_ERR', 1); /** DOM error: text doesn't fit into a DOMString */ define('DOMIT_DOMSTRING_SIZE_ERR', 2); /** DOM error: node can't be inserted at this location */ define('DOMIT_HIERARCHY_REQUEST_ERR', 3); /** DOM error: node not a child of target document */ define('DOMIT_WRONG_DOCUMENT_ERR', 4); /** DOM error: invalid character specified */ define('DOMIT_INVALID_CHARACTER_ERR', 5); /** DOM error: data can't be added to current node */ define('DOMIT_NO_DATA_ALLOWED_ERR', 6); /** DOM error: node is read-only */ define('DOMIT_NO_MODIFICATION_ALLOWED_ERR', 7); /** DOM error: node can't be found in specified context */ define('DOMIT_NOT_FOUND_ERR', 8); /** DOM error: operation not supported by current implementation */ define('DOMIT_NOT_SUPPORTED_ERR', 9); /** DOM error: attribute currently in use elsewhere */ define('DOMIT_INUSE_ATTRIBUTE_ERR', 10); //DOM Level 2 Exceptions /** DOM error: attempt made to use an object that is no longer usable */ define('DOMIT_INVALID_STATE_ERR', 11); /** DOM error: invalid or illegal string specified */ define('DOMIT_SYNTAX_ERR', 12); /** DOM error: can't modify underlying type of node */ define('DOMIT_INVALID_MODIFICATION_ERR', 13); /** DOM error: attempt to change node in a way incompatible with namespaces */ define('DOMIT_NAMESPACE_ERR', 14); /** DOM error: operation unsupported by underlying object */ define('DOMIT_INVALID_ACCESS_ERR', 15); //DOMIT! Exceptions /** DOM error: attempt to instantiate abstract class */ define('DOMIT_ABSTRACT_CLASS_INSTANTIATION_ERR', 100); /** DOM error: attempt to call abstract method */ define('DOMIT_ABSTRACT_METHOD_INVOCATION_ERR', 101); /** DOM error: can't perform this action on or with Document Fragment */ define('DOMIT_DOCUMENT_FRAGMENT_ERR', 102); /** *@global Object Instance of the UIDGenerator class */ $GLOBALS['uidFactory'] = new UIDGenerator(); require_once(DOMIT_INCLUDE_PATH . 'xml_domit_nodemaps.php'); /** * Generates unique ids for each node * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class UIDGenerator { /** @var int A seed value for generating uids */ var $seed; /** @var int A tally of the number of uids generated */ var $counter = 0; /** * UIDGenerator constructor */ function UIDGenerator() { $this->seed = 'node' . time(); } //UIDGenerator /** * Generates a unique id * @return uid */ function generateUID() { return ($this->seed . $this->counter++); } //generateUID } //UIDGenerator /** * @global object Reference to custom error handler for DOMException class * * Made global to simulate a static variable in PHP 4 */ $GLOBALS['DOMIT_DOMException_errorHandler'] = null; /** * A DOMIT! exception handling class * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class DOMIT_DOMException { /** * Raises the specified exception * @param int The error number * @param string A string explanation of the error */ function raiseException($errorNum, $errorString) { if ($GLOBALS['DOMIT_DOMException_errorHandler'] != null) { call_user_func($GLOBALS['DOMIT_DOMException_errorHandler'], $errorNum, $errorString); } else { $errorMessage = 'Error: ' . $errorNum . "\n " . $errorString; if ((!isset($GLOBALS['DOMIT_ERROR_FORMATTING_HTML'])) || ($GLOBALS['DOMIT_ERROR_FORMATTING_HTML'] == true)) { $errorMessage = "<p><pre>" . $errorMessage . "</pre></p>"; } die($errorMessage); } } //raiseException /** * custom handler for DOM errors * @param object A reference to the custom error handler */ function setErrorHandler($method) { $GLOBALS['DOMIT_DOMException_errorHandler'] =& $method; } //setErrorHandler } //DOMIT_DOMException /** * A class representing the DOM Implementation node * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class DOMIT_DOMImplementation { function hasFeature($feature, $version = null) { if (strtoupper($feature) == 'XML') { if (($version == '1.0') || ($version == '2.0') || ($version == null)) { return true; } } return false; } //hasFeature /** * Creates a new DOMIT_Document node and appends a documentElement with the specified info * @param string The namespaceURI of the documentElement * @param string The $qualifiedName of the documentElement * @param Object A document type node * @return Object The new document fragment node */ function &createDocument($namespaceURI, $qualifiedName, &$docType) { $xmldoc =& new DOMIT_Document(); $documentElement =& $xmldoc->createElementNS($namespaceURI, $qualifiedName); $xmldoc->setDocumentElement($documentElement); if ($docType != null) { $xmldoc->doctype =& $docType; } return $xmldoc; } //createDocument /** * Creates a new DOMIT_DocumentType node (not yet implemented!) * @param string The $qualifiedName * @param string The $publicID * @param string The $systemID * @return Object The new document type node */ function &createDocumentType($qualifiedName, $publicID, $systemID) { //not yet implemented DOMIT_DOMException::raiseException(DOMIT_NOT_SUPPORTED_ERROR, ('Method createDocumentType is not yet implemented.')); } //createDocumentType } //DOMIT_DOMImplementation ?> --- NEW FILE: xml_domit_doctor.php --- <?php /** * DOMIT! Doctor is a set of utilities for repairing malformed XML * @package domit-xmlparser * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page * DOMIT! is Free Software **/ /** * A (static) class containing utilities for repairing malformed XML * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class domit_doctor { /** * Looks for illegal ampersands and converts them to entities * @param string The xml text to be repaired * @return string The repaired xml text */ function fixAmpersands($xmlText) { $xmlText = trim($xmlText); $startIndex = -1; $processing = true; $illegalChar = '&'; while ($processing) { $startIndex = strpos($xmlText, $illegalChar, ($startIndex + 1)); if ($startIndex !== false) { $xmlText = domit_doctor::evaluateCharacter($xmlText, $illegalChar, ($startIndex + 1)); } else { $processing = false; } } return $xmlText; } //fixAmpersands /** * Evaluates whether an ampersand should be converted to an entity, and performs the conversion * @param string The xml text * @param string The (ampersand) character * @param int The character index immediately following the ampersand in question * @return string The repaired xml text */ function evaluateCharacter($xmlText, $illegalChar, $startIndex) { $total = strlen($xmlText); $searchingForCDATASection = false; for ($i = $startIndex; $i < $total; $i++) { $currChar = substr($xmlText, $i, 1); if (!$searchingForCDATASection) { switch ($currChar) { case ' ': case "'": case '"': case "\n": case "\r": case "\t": case '&': case "]": $searchingForCDATASection = true; break; case ";": return $xmlText; break; } } else { switch ($currChar) { case '<': case '>': return (substr_replace($xmlText, '&', ($startIndex - 1) , 1)); break; case "]": return $xmlText; break; } } } return $xmlText; } //evaluateCharacter } //domit_doctor ?> --- NEW FILE: xml_domit_parser.php --- <?php /** * DOMIT! is a non-validating, but lightweight and fast DOM parser for PHP * @package domit-xmlparser * @subpackage domit-xmlparser-main * @version 1.0 * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page * DOMIT! is Free Software **/ if (!defined('DOMIT_INCLUDE_PATH')) { define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/")); } /** current version of DOMIT! */ define ('DOMIT_VERSION', '1.0'); [...3626 lines suppressed...] //make uri lower case because Expat forces it to upper case for some reason $this->xmlDoc->namespaceURIMap[strtolower($uri)] = $prefix; //set up a switch so when the target element arrives, namespaces can be mapped to it $this->waitingForElementToDeclareNamespaces = true; $this->tempNamespaceURIMap[strtolower($uri)] = $prefix; } //startNamespaceDeclaration /** * Catches an end namespace declaration event * @param Object A reference to the current SAX parser * @param string The namespace prefix */ function endNamespaceDeclaration(&$parser, $prefix) { //do nothing; could remove from map, but would hardly be optimal } //endNamespaceDeclaration } //DOMIT_Parser ?> --- NEW FILE: php_file_utilities.php --- <?php if (!defined('PHP_TEXT_CACHE_INCLUDE_PATH')) { define('PHP_TEXT_CACHE_INCLUDE_PATH', (dirname(__FILE__) . "/")); } class php_file_utilities { /** * Retrieves binary or text data from the specified file * @param string The file path * @param string The attributes for the read operation ('r' or 'rb' or 'rt') * @return mixed he text or binary data contained in the file */ function &getDataFromFile($filename, $readAttributes, $readSize = 8192) { $fileContents = null; $fileHandle = @fopen($filename, $readAttributes); if($fileHandle){ do { $data = fread($fileHandle, $readSize); if (strlen($data) == 0) { break; } $fileContents .= $data; } while (true); fclose($fileHandle); } return $fileContents; } //getDataFromFile /** * Writes the specified binary or text data to a file * @param string The file path * @param mixed The data to be written * @param string The attributes for the write operation ('w' or 'wb') */ function putDataToFile($fileName, &$data, $writeAttributes) { $fileHandle = @fopen($fileName, $writeAttributes); if ($fileHandle) { fwrite($fileHandle, $data); fclose($fileHandle); } } //putDataToFile } //php_file_utilities ?> --- NEW FILE: xml_domit_nodemaps.php --- <?php /** * DOMIT node maps are structures for storing and accessing collections of DOMIT_Nodes. * @package domit-xmlparser * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page * DOMIT! is Free Software **/ if (!defined('DOMIT_INCLUDE_PATH')) { define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/")); } /** * A DOM NodeList implementation * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class DOMIT_NodeList { /** @var Array A container for the nodes in the list */ var $arNodeList = array(); /** * Return the node at the specified index * @param int The index of the requested node * @return Object A reference to the requested node, or null */ function &item($index) { if ($index < $this->getLength()) { return $this->arNodeList[$index]; } return null; } //item /** * Returns the number of nodes in the list * @return int The number of nodes in the list */ function getLength() { return count($this->arNodeList); } //getLength /** * Appends a node to the list * @return Object The appended node */ function &appendNode(&$node) { $this->arNodeList[] =& $node; return $node; } //appendNode /** * Removes the specified node from the list * @param Object A reference to the node to be removed * @return Object A reference to the removed node */ function &removeNode(&$node) { $total = $this->getLength(); $returnNode = null; $found = false; for ($i = 0; $i < $total; $i++) { if (!$found) { if ($node->uid == $this->arNodeList[$i]->uid) { $found = true; $returnNode=& $node; } } if ($found) { if ($i == ($total - 1)) { unset($this->arNodeList[$i]); } else { $this->arNodeList[$i] =& $this->arNodeList[($i + 1)]; } } } return $returnNode; } //$removeNode /** * Formats a string for presentation as HTML * @param string The string to be formatted * @param boolean True if the string is to be sent directly to output * @return string The HTML formatted string */ function forHTML($str, $doPrint = false) { require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); return DOMIT_Utilities::forHTML($str, $doPrint); } //forHTML /** * Generates an array representation of the node and its children * @return Array A representation of the node and its children */ function toArray() { return $this->arNodeList; } //toArray /** * Copies a node and/or its children * @param boolean True if all child nodes are also to be cloned * @return Object A copy of the node and/or its children */ function &createClone($deep = false) { $className = get_class($this); $clone =& new $className(); foreach ($this->arNodeList as $key => $value) { $currNode =& $this->arNodeList[$key]; $clone->arNodeList[$key] =& $currNode->cloneNode($deep); } return $clone; } //createClone /** * Generates a string representation of the node and its children * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The string representation */ function toString($htmlSafe = false, $subEntities=false) { $result = ''; foreach ($this->arNodeList as $key => $value) { $currNode =& $this->arNodeList[$key]; $result .= $currNode->toString(false, $subEntities); } if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toString /** * Generates a normalized (formatted for readability) representation of the node collection * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The string representation */ function toNormalizedString($htmlSafe = false, $subEntities=false) { $result = ''; foreach ($this->arNodeList as $key => $value) { $currNode =& $this->arNodeList[$key]; $result .= $currNode->toNormalizedString(false, $subEntities); } if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toNormalizedString } //DOMIT_NodeList /** * A DOM NamedNodeMap implementation * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class DOMIT_NamedNodeMap { /** @var Array A container for the nodes in the map */ var $arNodeMap = array(); /** @var Array A numerical index to the keys of the mapped nodes */ var $indexedNodeMap = array(); /** @var boolean True if the list has been modified and $indexedNodeMap needs reindexing */ var $isDirty = true; /** * Gets a node with the specifed name * @param string The name of the node * @return mixed A reference to the requested node, or null */ function &getNamedItem($name) { if (isset($this->arNodeMap[$name])) { return $this->arNodeMap[$name]; } return null; } //getNamedItem /** * Reindexes the numerical index for the named node map */ function reindexNodeMap() { $this->indexedNodeMap = array(); foreach ($this->arNodeMap as $key => $value) { $this->indexedNodeMap[] = $key; } $this->isDirty = false; } //reindexNodeMap /** * Assigns a node to the list * @param Object A reference to the node to be assigned * @return Object A reference to the assigned node */ function &setNamedItem(&$arg) { $returnNode = null; if (isset($this->arNodeMap[$arg->nodeName])) { $returnNode =& $this->arNodeMap[$arg->nodeName]; } else { $this->isDirty = true; } $this->arNodeMap[$arg->nodeName] =& $arg; return $returnNode; } //setNamedItem /** * Removes a node from the list, by name * @param string The name of the node to be removed * @return mixed A reference to the removed node, or null */ function &removeNamedItem($name) { $returnNode = null; if (isset($this->arNodeMap[$name])) { $returnNode =& $this->arNodeMap[$name]; unset($this->arNodeMap[$name]); $this->isDirty = true; } return $returnNode; } //removeNamedItem /** * Gets a node with the specifed name, taking into account namespaces * @param string The namespaceURI of the node * @param string The localName of the node * @return mixed A reference to the requested node, or null */ function &getNamedItemNS($namespaceURI, $localName) { $key = $this->getKeyNS($namespaceURI, $localName); //check for explicit namespaces if (isset($this->arNodeMap[$key])) { return $this->arNodeMap[$key]; } //check for implicit namespaces too //URI will be on element, but not attribute if (isset($this->arNodeMap[$localName])) { //get element namespace $firstAttr =& $this->item(1); $ownerElem =& $firstAttr->ownerElement; if ($namespaceURI == $ownerElem->namespaceURI) { return $this->arNodeMap[$localName]; } } return null; } //getNamedItemNS /** * Assigns a node to the list, using its namespaceURI and localName * @param Object A reference to the node to be assigned * @return Object A reference to the assigned node */ function &setNamedItemNS(&$arg) { $returnNode = null; $key = $this->getKeyNS($arg->namespaceURI, $arg->localName); if (isset($this->arNodeMap[$key])) { $returnNode =& $this->arNodeMap[$key]; } else { $this->isDirty = true; } $this->arNodeMap[$key] =& $arg; return $returnNode; } //setNamedItemNS /** * Removes a node from the list, by name, by local name and namespace URI * @param string The namespaceURI of the node to be removed * @param string The localName of the node to be removed * @return mixed A reference to the removed node, or null */ function &removeNamedItemNS($namespaceURI, $localName) { $returnNode = null; $key = $this->getKeyNS($namespaceURI, $localName); if (isset($this->arNodeMap[$key])) { $returnNode =& $this->arNodeMap[$key]; unset($this->arNodeMap[$key]); $this->isDirty = true; } return $returnNode; } //removeNamedItemNS /** * Returns the key of the NamedNodeMap, given the namespaceURI and localName * @param string The namespaceURI of the node to be removed * @param string The localName of the node to be removed * @return string The key of the NamedNodeMap */ function getKeyNS($namespaceURI, $localName) { if ($namespaceURI != '') { return $namespaceURI . ":" . $localName; } return $localName; } //getKeyNS /** * Return the node at the specified index * @param int The index of the requested node * @return mixed A reference to the requested node, or null */ function &item($index) { if ($this->isDirty) $this->reindexNodeMap(); return $this->arNodeMap[$this->indexedNodeMap[$index]]; } //item /** * Returns the number of nodes in the map * @return int The number of nodes in the map */ function getLength() { return count($this->arNodeMap); } //getLength /** * Formats a string for presentation as HTML * @param string The string to be formatted * @param boolean True if the string is to be sent directly to output * @return string The HTML formatted string */ function forHTML($str, $doPrint = false) { require_once(DOMIT_INCLUDE_PATH . 'xml_domit_utilities.php'); return DOMIT_Utilities::forHTML($str, $doPrint); } //forHTML /** * Generates an array representation of the node and its children * @return Array A representation of the node and its children */ function toArray() { return $this->arNodeMap; } //toArray /** * Copies a node and/or its children * @param boolean True if all child nodes are also to be cloned * @return Object A copy of the node and/or its children */ function &createClone($deep = false) { $className = get_class($this); $clone =& new $className(); foreach ($this->arNodeMap as $key => $value) { $currNode =& $this->arNodeMap[$key]; $clone->arNodeMap[$key] =& $currNode->cloneNode($deep); } return $clone; } //createClone /** * Generates a string representation of the node and its children * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The string representation */ function toString($htmlSafe = false, $subEntities=false) { $result = ''; foreach ($this->arNodeMap as $key => $value) { $currNode =& $this->arNodeMap[$key]; $result .= $currNode->toString(false, $subEntities); } if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toString /** * Generates a normalized (formatted for readability) representation of the node collection * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The string representation */ function toNormalizedString($htmlSafe = false, $subEntities=false) { $result = ''; foreach ($this->arNodeMap as $key => $value) { $currNode =& $this->arNodeMap[$key]; $result .= $currNode->toNormalizedString(false, $subEntities); } if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toNormalizedString } //DOMIT_NamedNodeMap /** * A NamedNodeMap with specialized funtionality for Attribute nodes * * @package domit-xmlparser * @author John Heinstein <joh...@nb...> */ class DOMIT_NamedNodeMap_Attr extends DOMIT_NamedNodeMap { /** * Generates an array representation of the node and its children * @return Array A representation of the node and its children */ function toArray() { $arReturn = array(); foreach ($this->arNodeMap as $key => $value) { $arReturn[$key] = $this->arNodeMap[$key]->getValue(); } return $arReturn; } //toArray /** * Generates a string representation of the node and its children * @param boolean True if HTML readable output is desired * @param boolean True if illegal xml characters in text nodes and attributes should be converted to entities * @return string The string representation */ function toString($htmlSafe = false, $subEntities=false) { $result = ''; foreach ($this->arNodeMap as $key => $value) { $currNode =& $this->arNodeMap[$key]; $result .= $currNode->toString(false, $subEntities); } if ($htmlSafe) $result = $this->forHTML($result); return $result; } //toString } //DOMIT_NamedNodeMap_Attr ?> --- NEW FILE: tutorial.html --- <html> <head> <title>DOMIT! Documentation</title> </head> <frameset cols="300,*" frameborder="0" border="0"> <frame src="documentation/menu.html" name="menu" frameborder="0" noresize scrolling="yes" marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" bottommargin="0" rightmargin="0" /> <frame src="documentation/DOMIT_tutorial_000.html" name="classes" frameborder="0" noresize scrolling="yes" marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" bottommargin="0" rightmargin="0" /> <noframes> <body> Your browser does not support frames. </body> </noframes> </frameset> </html> --- NEW FILE: testing_domit.css --- body { color: #000000; background-color: #FFFFFF; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; font-family: Arial, Verdana, sans-serif; font-size: 12px; } pre { font-family: Arial, Verdana, sans-serif; font-size: 12px; font-style: bold; } body a:link { color: darkgreen; font-family: Arial, Verdana, sans-serif; } body a:visited { color: darkgreen; font-family: Arial, Verdana, sans-serif; } img { text-align: center; border: 0; } h2 { color: #000000; font-family: Arial, Verdana, sans-serif; font-size: 18px; font-style: bold; } .row0 { color: #000000; font-family: Arial, Verdana, sans-serif; font-size: 12px; font-style: bold; } .row1 { color: #000000; font-family: Arial, Verdana, sans-serif; font-size: 18px; font-style: bold; } --- NEW FILE: xml_domit_lite_include.php --- <?php /** * @package domit-xmlparser * @subpackage domit-xmlparser-lite * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/domit/ DOMIT! Home Page * DOMIT! is Free Software **/ /** The file system path to the domit library */ define('DOMIT_INCLUDE_PATH', (dirname(__FILE__) . "/")); require_once(DOMIT_INCLUDE_PATH . 'xml_domit_lite_parser.php'); ?> --- NEW FILE: docs.html --- <html> <head> <title>DOMIT! Documentation</title> </head> <frameset cols="300,*" frameborder="0" border="0"> <frame src="documentation/menu.html" name="menu" frameborder="0" noresize scrolling="yes" marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" bottommargin="0" rightmargin="0" /> <frame src="documentation/DOMIT.html" name="classes" frameborder="0" noresize scrolling="yes" marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" bottommargin="0" rightmargin="0" /> <noframes> <body> Your browser does not support frames. </body> </noframes> </frameset> </html> --- NEW FILE: xml_saxy_lite_parser.php --- <?php /** * SAXY Lite is a non-validating, but lightweight and fast SAX parser for PHP, modelled on the Expat parser * @package saxy-xmlparser * @subpackage saxy-xmlparser-lite * @version 0.17 * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/saxy/ SAXY Home Page * SAXY is Free Software **/ if (!defined('SAXY_INCLUDE_PATH')) { define('SAXY_INCLUDE_PATH', (dirname(__FILE__) . "/")); } /** current version of SAXY Lite */ define ('SAXY_LITE_VERSION', '0.17'); /** initial saxy lite parse state, before anything is encountered */ define('SAXY_STATE_NONE', 0); /** saxy lite parse state, processing main document */ define('SAXY_STATE_PARSING', 1); require_once(SAXY_INCLUDE_PATH . 'xml_saxy_shared.php'); /** * The SAX Parser class * * @package saxy-xmlparser * @subpackage saxy-xmlparser-lite * @author John Heinstein <joh...@nb...> */ class SAXY_Lite_Parser extends SAXY_Parser_Base { /** * Constructor for SAX parser */ function SAXY_Lite_Parser() { $this->SAXY_Parser_Base(); $this->state = SAXY_STATE_NONE; } //SAXY_Lite_Parser /** * Returns the current version of SAXY Lite * @return Object The current version of SAXY Lite */ function getVersion() { return SAXY_LITE_VERSION; } //getVersion /** * Processes the xml prolog, doctype, and any other nodes that exist outside of the main xml document * @param string The xml text to be processed * @return string The preprocessed xml text */ function preprocessXML($xmlText) { //strip prolog $xmlText = trim($xmlText); $total = strlen($xmlText); for ($i = 0; $i < $total; $i++) { if ($xmlText{$i} == '<') { switch ($xmlText{($i + 1)}) { case '?': case '!': break; default: $this->state = SAXY_STATE_PARSING; return (substr($xmlText, $i)); } } } } //preprocessXML /** * The controlling method for the parsing process * @param string The xml text to be processed * @return boolean True if parsing is successful */ function parse ($xmlText) { $xmlText = $this->preprocessXML($xmlText); $total = strlen($xmlText); for ($i = 0; $i < $total; $i++) { $currentChar = $xmlText{$i}; switch ($this->state) { case SAXY_STATE_PARSING: switch ($currentChar) { case '<': if (substr($this->charContainer, 0, SAXY_CDATA_LEN) == SAXY_SEARCH_CDATA) { $this->charContainer .= $currentChar; } else { $this->parseBetweenTags($this->charContainer); $this->charContainer = ''; } break; case '>': if ((substr($this->charContainer, 0, SAXY_CDATA_LEN) == SAXY_SEARCH_CDATA) && !(($this->getCharFromEnd($this->charContainer, 0) == ']') && ($this->getCharFromEnd($this->charContainer, 1) == ']'))) { $this->charContainer .= $currentChar; } else { $this->parseTag($this->charContainer); $this->charContainer = ''; } break; default: $this->charContainer .= $currentChar; } break; } } return true; } //parse /** * Parses an element tag * @param string The interior text of the element tag */ function parseTag($tagText) { $tagText = trim($tagText); $firstChar = $tagText{0}; $myAttributes = array(); switch ($firstChar) { case '/': $tagName = substr($tagText, 1); $this->fireEndElementEvent($tagName); break; case '!': $upperCaseTagText = strtoupper($tagText); if (strpos($upperCaseTagText, SAXY_SEARCH_CDATA) !== false) { //CDATA Section $total = strlen($tagText); $openBraceCount = 0; $textNodeText = ''; for ($i = 0; $i < $total; $i++) { $currentChar = $tagText{$i}; if (($currentChar == ']') && ($tagText{($i + 1)} == ']')) { break; } else if ($openBraceCount > 1) { $textNodeText .= $currentChar; } else if ($currentChar == '[') { //this won't be reached after the first open brace is found $openBraceCount ++; } } if ($this->cDataSectionHandler == null) { $this->fireCharacterDataEvent($textNodeText); } else { $this->fireCDataSectionEvent($textNodeText); } } else if (strpos($upperCaseTagText, SAXY_SEARCH_NOTATION) !== false) { //NOTATION node, discard return; } else if (substr($tagText, 0, 2) == '!-') { //comment node, discard return; } break; case '?': //Processing Instruction node, discard return; default: if ((strpos($tagText, '"') !== false) || (strpos($tagText, "'") !== false)) { $total = strlen($tagText); $tagName = ''; for ($i = 0; $i < $total; $i++) { $currentChar = $tagText{$i}; if (($currentChar == ' ') || ($currentChar == "\t") || ($currentChar == "\n") || ($currentChar == "\r") || ($currentChar == "\x0B")) { $myAttributes = $this->parseAttributes(substr($tagText, $i)); break; } else { $tagName .= $currentChar; } } if (strrpos($tagText, '/') == (strlen($tagText) - 1)) { //check $tagText, but send $tagName $this->fireStartElementEvent($tagName, $myAttributes); $this->fireEndElementEvent($tagName); } else { $this->fireStartElementEvent($tagName, $myAttributes); } } else { if (strpos($tagText, '/') !== false) { $tagText = trim(substr($tagText, 0, (strrchr($tagText, '/') - 1))); $this->fireStartElementEvent($tagText, $myAttributes); $this->fireEndElementEvent($tagText); } else { $this->fireStartElementEvent($tagText, $myAttributes); } } } } //parseTag /** * Returns the current error code (non-functional for SAXY Lite) * @return int The current error code */ function xml_get_error_code() { return -1; } //xml_get_error_code /** * Returns a textual description of the error code (non-functional for SAXY Lite) * @param int The error code * @return string The error message */ function xml_error_string($code) { return ""; } //xml_error_string } //SAXY_Lite_Parser ?> --- NEW FILE: php_http_client_generic.php --- <?php /** * PHP HTTP Tools is a library for working with the http protocol * php_http_client_generic represents a basic http client * @package php-http-tools * @version 0.2-pre * @copyright (C) 2004 John Heinstein. All rights reserved * @license http://www.gnu.org/copyleft/lesser.html LGPL License * @author John Heinstein <joh...@nb...> * @link http://www.engageinteractive.com/php_http_tools/ PHP HTTP Tools Home Page * PHP HTTP Tools are Free Software **/ if (!defined('PHP_HTTP_TOOLS_INCLUDE_PATH')) { define('PHP_HTTP_TOOLS_INCLUDE_PATH', (dirname(__FILE__) . "/")); } /** end-of-line character sequence as defined in HTTP spec */ define ('CRLF', "\r\n"); /** carriage return character */ define ('CR', "\r"); /** line feed character */ define ('LF', "\n"); //http read states for client /** beginning read state */ define('HTTP_READ_STATE_BEGIN', 1); /** state when reading headers */ define('HTTP_READ_STATE_HEADERS', 2); /** state when reading body of message */ define('HTTP_READ_STATE_BODY', 3); require_once(PHP_HTTP_TOOLS_INCLUDE_PATH . 'php_http_exceptions.php'); /** * An HTTP Request class * * @package php-http-tools * @author John Heinstein <joh...@nb...> */ class php_http_request { /** @var object A reference to the headers object */ var $headers = null; /** @var string The requested method, e.g. GET, POST, HEAD */ var $requestMethod = 'POST'; /** @var string The requested path */ var $requestPath = ''; /** @var string The requested protocol */ var $protocol = 'HTTP'; /** @var string The version of the requested protocol */ var $protocolVersion= '1.1'; /** * Returns the headers object * @return object The headers object */ function &getHeaders() { return $this->headers; } //getHeaders /** * Sets the header to the specified value * @param string The header name * @param string The header value * @param boolean True if multiple headers with the same name are allowed */ function setHeader($name, $value, $allowMultipleHeaders = false) { $this->headers->setHeader($name, $value, $allowMultipleHeaders); } //setHeader /** * Default method for setting headers; meant to be overridden in subclasses */ function setHeaders() { //you will want to override this method $this->setHeader('User-Agent', 'PHP-HTTP-Client(Generic)/0.1'); $this->setHeader('Connection', 'Close'); } //setHeaders /** * Sets the request method, e.g., GET * @param string The name of the request method * @return boolean True if the version number is valid */ function setRequestMethod($method) { $method = strtoupper($method); switch ($method) { case 'POST': case 'GET': case 'HEAD': case 'PUT': $this->requestMethod = $method; return true; break; } return false; } //setRequestMethod /** * Sets the request path, e.g., http://www.engageinteractive.com/domit/test.xml * @param string The request path */ function setRequestPath($path) { $this->requestPath = $path; } //setRequestPath /** * Sets the version number of the protocol * @param string The version number * @return boolean True if the version number is valid */ function setProtocolVersion($version) { if (($version == '1.0') || ($version == '1.1')) { $this->protocolVersion = $version; return true; } return false; } //setProtocolVersion /** * Specifies a user name and password for basic authentication * @param string The user name * @param string The password */ function setAuthorization($user, $password) { $encodedChallengeResponse = 'Basic ' . base64_encode($this->user . ':' . $this->password); $this->setHeader('Authorization', $encodedChallengeResponse); } //setAuthorization } //php_http_request class php_http_client_generic extends php_http_request { /** @var object A reference to the connection object */ var $connection; /** @var string True if response headers are to be generated as an object */ var $responseHeadersAsObject = false; /** @var object The http response */ var $response = null; /** @var string A list of event names that can be fired by the client */ var $events = array('onRequest' => null, 'onRead' => null, 'onResponse' => null, 'onResponseHeaders' => null, 'onResponseBody' => null); /** * HTTP Client constructor * @param string The client connection host name, with or without its protocol prefix * @param string The client connection path, not including the host name * @param int The port to establish the client connection on * @param int The timeout value for the client connection */ function php_http_client_generic($host = '', $path = '/', $port = 80, $timeout = 0) { $this->connection =& new php_http_connection($host, $path, $port, $timeout); $this->headers =& new php_http_headers(); $this->requestPath = $path; $this->response =& new php_http_response(); $this->setHeaders(); } //php_http_client_generic /** * Specifies that the response headers array should be generated * @param boolean True if the response headers array should be built */ function generateResponseHeadersAsObject($responseHeadersAsObject) { $this->responseHeadersAsObject = $responseHeadersAsObject; if ($responseHeadersAsObject) { $this->response->headers =& new php_http_headers(); } } //generateResponseHeadersAsObject /** * Fires an http event that has been registered * @param string The name of the event, e.g., onRead * @param string The data to be passed to the event */ function fireEvent($target, $data) { if ($this->events[$target] != null) { call_user_func($this->events[$target], $data); } } //fireEvent /** * Sets which http events are to be fired * @param string The http event option to be set * @param string True if the event is to be fired * @param object A reference to a custom handler for the http event data */ function setHTTPEvent($option, $truthVal, $customHandler = null) { if ($customHandler != null) { $handler =& $customHandler; } else { $handler = array(&$this, 'defaultHTTPEventHandler'); } switch($option) { case 'onRequest': case 'onRead': case 'onResponse': case 'onResponseHeaders': case 'onResponseBody': $truthVal ? ($this->events[$option] =& $handler) : ($this->events[$option] = null); break; } } //setHTTPEvent /** * Evaluates whether the specified http event option is active * @param string The http event option to evaluate * @return boolean True if the specified option is active */ function getHTTPEvent($option) { switch($option) { case 'onRequest': case 'onRead': case 'onResponse': case 'onResponseHeaders': case 'onResponseBody': return ($this->events[$option] != null); break; } } //getHTTPEvent /** * The default http event handler; fired if no custom handler has been registered * @param string The event data */ function defaultHTTPEventHandler($data) { $this->printHTML($data); } //defaultHTTPEventHandler /** * Prints the data to the browser as preformatted, htmlentified output * @param string The data to be printed */ function printHTML($html) { print('<pre>' . htmlentities($html) . '</pre>'); } //printHTML /** * Establishes a client connection */ function connect() { if (!$this->headers->headerExists('Host')) { $this->setHeader('Host', $this->connection->host); } return $this->connection->connect(); } //connect /** * Disconnects the current client connection if one exists */ function disconnect() { return $this->connection->disconnect(); } //disconnect /** * Evaluated whether the current client is connected * @return boolean True if a connection exists */ function isConnected() { return $this->connection->isOpen(); } //isConnected /** * Performs an HTTP GET * @param string The target url * @return object An HTTP response object */ function &get($url) { $this->setRequestMethod('GET'); $this->setRequestPath($url); $this->get_custom($url); $this->connect(); $result = $this->send(''); return $result; } //get /** * Handler for customizing the HTTP GET call * @param string The target url */ function get_custom($url) { //do nothing; meant to be overridden } //get_custom /** * Performs an HTTP POST * @param string The posted data * @return object An HTTP response object */ function &post($data) { $this->setRequestMethod('POST'); $this->setHeader('Content-Type', 'text/html'); $this->post_custom($data); $this->connect(); return $this->send($data); } //post /** * Handler for customizing the HTTP POST call * @param string The post data */ function post_custom($data) { //do nothing; meant to be overridden } //post_custom /** * Performs an HTTP HEAD * @param string The target url * @return object An HTTP response object */ function &head($url) { $this->setRequestMethod('HEAD'); $this->head_custom($url); $this->connect(); return $this->send(''); } //head /** * Handler for customizing the HTTP HEAD call * @param string The target url */ function head_custom($url) { //do nothing; meant to be overridden } //head_custom /** * Sends data through the client connection * @param string The message to be sent * @return string The http response */ function &send($message) { $conn =& $this->connection; if ($conn->isOpen()) { //build header info $request = $this->requestMethod . ' ' . $this->requestPath . ' ' . $this->protocol . '/' . $this->protocolVersion . CRLF; $request .= $this->headers->toString() . CRLF; $request .= $message; //init variables $response = $headers = $body = ''; $readState = HTTP_READ_STATE_BEGIN; $this->fireEvent('onRequest', $request); //send request $connResource =& $conn->connection; fputs ($connResource, $request); //read response while (!feof($connResource)) { $data = fgets($connResource, 4096); $this->fireEvent('onRead', $data); switch ($readState) { case HTTP_READ_STATE_BEGIN: $this->response->statusLine = $data; $readState = HTTP_READ_STATE_HEADERS; break; case HTTP_READ_STATE_HEADERS: if (trim($data) == '') { //end of headers is signalled by a blank line $readState = HTTP_READ_STATE_BODY; } else { if ($this->responseHeadersAsObject) { $this->response->setUnformattedHeader($data); } else { $this->response->headers .= $data; } } break; case HTTP_READ_STATE_BODY: $this->response->message .= $data; break; } } $this->normalizeResponseIfChunked(); $headerString = is_object($this->response->headers) ? $this->response->headers->toString() : $this->response->headers; $this->fireEvent('onResponseHeaders', $headerString); $this->fireEvent('onResponseBody', $this->response->message); $this->fireEvent('onResponse', $this->response->headers . $this->response->message); return $this->response; } else { HTTPExceptions::raiseException(HTTP_SOCKET_CONNECTION_ERR, ('HTTP Transport Error - Unable to establish connection to host ' . $conn->host)); } } //send /** * Determines if response data is transfer encoding chunked, then decodes */ function normalizeResponseIfChunked() { if (($this->protocolVersion = '1.1') && (!$this->response->isResponseChunkDecoded)) { if ($this->responseHeadersAsObject) { if ($this->response->headers->headerExists('Transfer-Encoding') && ($this->response->headers->getHeader('Transfer-Encoding') == 'chunked')) { $this->response->message = $this->decodeChunkedData($this->response->getResponse()); $this->response->isResponseChunkDecoded = true; } } else { if ((strpos($this->response->headers, 'Transfer-Encoding') !== false) && (strpos($this->response->headers, 'chunked') !== false)){ $this->response->message = $this->decodeChunkedData($this->response->getResponse()); $this->response->isResponseChunkDecoded = true; } } } } //normalizeResponseIfChunked /** * Decodes data if transfer encoding chunked * @param string The encoded data * @return string The decoded data */ function decodeChunkedData($data) { $chunkStart = $chunkEnd = strpos($data, CRLF) + 2; $chunkLengthInHex = substr($data, 0, $chunkEnd); $chunkLength = hexdec(trim($chunkLengthInHex)); $decodedData = ''; while ($chunkLength > 0) { $chunkEnd = strpos($data, CRLF, ($chunkStart + $chunkLength)); if (!$chunkEnd) { //if the trailing CRLF is missing, return all the remaining data $decodedData .= substr($data, $chunkStart); break; } $decodedData .= substr($data, $chunkStart, ($chunkEnd - $chunkStart)); $chunkStart = $chunkEnd + 2; $chunkEnd = strpos($data, CRLF, $chunkStart) + 2; if (!$chunkEnd) break; $chunkLengthInHex = substr($data, $chunkStart, ($chunkEnd - $chunkStart)); $chunkLength = hexdec(trim($chunkLengthInHex)); $chunkStart = $chunkEnd; } return $decodedData; } //decodeChunkedData } //php_http_client_generic /** * An HTTP Connection class * * @package php-http-tools * @author John Heinstein <joh...@nb...> */ class php_http_connection { /** @var object A reference to the current connection */ var $connection = null; /** @var string The host of the connection */ var $host; /** @var string The path of the connection */ var $path; /** @var int The port of the connection */ var $port; /** @var int The timeout value for the connection */ var $timeout; /** @var int The error number of the connection */ var $errorNumber = 0; /** @var string The error string of the connection */ var $errorString = ''; /** * HTTP Connection constructor * @param string The connection host name, with or without its protocol prefix * @param string The connection path, not including the host name * @param int The port to establish the client connection on * @param int The timeout value for the client connection */ function php_http_connection($host = '', $path = '/', $port = 80, $timeout = 0) { $this->host = $this->formatHost($host); $this->path = $this->formatPath($path); $this->port = $port; $this->timeout = $timeout; } //php_http_connection /** * Formats a host string by stripping off the http:// prefix * @param string The host name * @return string The formatted host name */ function formatHost($hostString) { $hasProtocol = (substr(strtoupper($hostString), 0, 7) == 'HTTP://'); if ($hasProtocol) { $hostString = substr($hostString, 7); } return $hostString; } //formatHost /** * Formats a path string * @param string The path * @return string The formatted path */ function formatPath($pathString) { if (($pathString == '') || ($pathString == null)) { $pathString = '/'; } return $pathString; } //formatPath /** * Establishes a socket connection * @return boolean True if the connection was successful */ function connect() { if ($this->timeout == 0) { $this->connection = @fsockopen($this->host, $this->port, $errorNumber, $errorString); } else { $this->connection = @fsockopen($this->host, $this->port, $errorNumber, $errorString, $this->timeout); } $this->errorNumber = $errorNumber; $this->errorString = $errorString; return is_resource($this->connection); } //connect /** * Determines whether the connection is still open * @return boolean True if the connection is still open */ function isOpen() { return (is_resource($this->connection) && (!feof($this->connection))); } //isOpen /** * Disconnects the current connection * @return boolean True if the connection has been disconnected */ function disconnect() { fclose($this->connection); $this->connection = null; return true; } //disconnect } //php_http_connection /** * An HTTP Headers class * * @package php-http-tools * @author John Heinstein <joh...@nb...> */ class php_http_headers { /** @var object An array of headers */ var $headers; /** * HTTP Headers constructor */ function php_http_headers() { $this->headers = array(); } //php_http_headers /** * Returns the specified header value * @param string The header name * @return mixed The header value, or an array of header values */ function &getHeader($name) { if ($this->headerExists($name)) { return $this->headers[$name]; } return false; } //getHeader /** * Sets the named header to the specified value * @param string The header name * @param string The header value * @param boolean True if multiple headers with the same name are allowed */ function setHeader($name, $value, $allowMultipleHeaders = false) { if ($allowMultipleHeaders) { if (isset($this->headers[$name])) { if (is_array($this->headers[$name])) { $this->headers[$name][count($this->headers)] = $value; } else { $tempVal = $this->headers[$name]; $this->headers[$name] = array($tempVal, $value); } } else { $this->headers[$name] = array(); $this->headers[$name][0] = $value; } } else { $this->headers[$name] = $value; } } //setHeader /** * Determines whether the specified header exists * @param string The header name * @return boolean True if the specified header exists */ function headerExists($name) { return isset($this->headers[$name]); } //headerExists /** * Removes the specified header * @param string The header name * @return boolean True if the specified header has been removed */ function removeHeader($name) { if ($this->headerExists($name)) { unset($this->headers[$name]); return true; } return false; } //removeHeader /** * Returns a reference to the headers array * @return array The headers array */ function getHeaders() { return $this->headers; } //getHeaders /** * Returns a list of existing headers names * @return array A list of existing header names */ function getHeaderList() { return array_keys($this->headers); } //getHeaderList /** * Returns a string representation of the headers array * @return string A string representation of the headers array */ function toString() { $retString = ''; foreach ($this->headers ... [truncated message content] |