Download DOAP
Please be aware and take note of the following:DOAP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation, either version 3 of the Licence, or (at your option) any later version.
DOAP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more details.
Download Package
Download Current Version: doap-0.01.zipView Code Online
Below is the code for each of the three components; doap.inc.php (DOAP Server PHP library), xmlcreate.inc.php (Support XML Library) and doap.js (DOAP Client JavaScript library).DOAP Server PHP Library (doap.inc.php)
<?php /* ------------------------------------------------------------- This file is part of DOAP (Dave's Own Access Protocol) DOAP is (C) Copyright 2011 PurplePixie Systems DOAP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. DOAP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DOAP. If not, see www.gnu.org/licenses For more information see http://www.purplepixie.org/doap -------------------------------------------------------------- */ /** * DOAP Server Module - Dave's Own Access Protocol * @author David Cutting * @package DOAP * @copyright 2010 PurplePixie Systems * @version 0.01 **/ // First we check for xmlCreate and try to include it if not found if (!class_exists("XMLCreate")) { $tryfile = dirname(__FILE__)."/"."xmlcreate.inc.php"; if (file_exists($tryfile)) include_once($tryfile); } /** * DOAP Server Class * @package DOAP **/ class DOAP_Server { /** * Keep list of registered functions and associated data **/ private $functions = array(); /** * Register a function * @param string $funcname Name of function to register * @param int $param_min Minimum parameters for function (optional, default not enforced) * @param int $param_max Maximum parameters for function (optional, default not enforced) **/ function Register($funcname,$param_min=-1, $param_max=-1) { $this->functions[$funcname]['name']=$funcname; $this->functions[$funcname]['min']=$param_min; $this->functions[$funcname]['max']=$param_max; } /** * Generate a DOAP Error in XML * @param int $code Error Code Number * @param string $desc Error Description * @param bool $outputxml Output XML to Screen (as well as return) (optional, default false) * @return string XML output **/ function Error($code,$desc,$outputxml=true) { $xml = new XMLCreate(); $xml -> startElement("ERROR"); $xml -> charElement("CODE",$code,0,false,true); $xml -> charElement("DESC",$desc,0,false,true); $xml -> endElement("ERROR"); if ($outputxml) { @header("Content-type: text/xml"); echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n"; echo $xml->xml; } return $xml -> xml; } /** * Add an array to the XML output (may be called recursively for arrays in an array object) * @param array $array Array to parse * @param string &$xml Pointer to output XML **/ function AddArray($array,&$xml) { $xml -> startElement("ARRAY"); foreach($array as $element) { if (!is_array($element)) $xml->charElement("ELEMENT",$element,0,false,true); else $this->AddArray($element,$xml); } $xml->endElement("ARRAY"); } /** * Process any DOAP Requests * @param bool $outputxml Output XML to the screen (optional, default true) * @return string DOAP XML Output **/ function Process($outputxml=true) { if (!class_exists("xmlCreate")) { $xml="<ERROR>\n <CODE>208</CODE>\n <DESC>xmlCreate Library Not Found</DESC>\n</ERROR>\n"; if ($outputxml) { @header("Content-type: text/xml"); echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n"; echo $xml; } return $xml; } if (isset($_REQUEST['f'])) $func=$_REQUEST['f']; else return $this->Error(200,"No function specified",$outputxml); if (!isset($this->functions[$func])) return $this->Error(201,"Illegal function specified: ".$func,$outputxml); if (isset($_REQUEST['p'])) $params=$_REQUEST['p']; else $params=array(); if (!is_array($params)) $params=array($params); if (!function_exists($func)) return $this->Error(202,"Non-existant function specified: ".$func,$outputxml); if ( ($this->functions[$func]['min']>0) && (sizeof($params)<$this->functions[$func]['min']) ) return $this->Error(203,"Too few parameters for function ".$func." (needs ".$this->functions[$func]['min'].")",$outputxml); if ( ($this->functions[$func]['max']>=0) && (sizeof($params)>$this->functions[$func]['max']) ) return $this->Error(203,"Too many parameters for function ".$func." (max ".$this->functions[$func]['max'].")",$outputxml); switch(sizeof($params)) // Oh dear so messy but without using eval() and the performance hit the only way I think { case 0: $res = $func(); break; case 1: $res = $func($params[0]); break; case 2: $res = $func($params[0],$params[1]); break; case 3: $res = $func($params[0],$params[1],$params[2]); break; case 4: $res = $func($params[0],$params[1],$params[2],$params[3]); break; case 5: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4]); break; case 6: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4], $params[5]); break; case 7: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4], $params[5], $params[6]); break; case 8: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4], $params[5], $params[6], $params[7]); break; case 9: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4], $params[5], $params[6], $params[7], $params[8]); break; case 10: $res = $func($params[0],$params[1],$params[2],$params[3],$params[4], $params[5], $params[6], $params[7], $params[8], $params[9]); break; default: return $this->Error(204,"Parameters in excess of DOAP Limit (10)",$outputxml); } $xml = new xmlCreate(); if (!is_array($res)) $xml->charElement("RESULT",$res,0,false,true); else $this->AddArray($res,$xml); if ($outputxml) { @header("Content-type: text/xml"); echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n"; echo $xml->xml; } return $xml->xml; } } ?>
xmlCreator PHP Library (xmlcreate.inc.php)
<?php /** * xmlCreate PHP Utility * @version 0.01 * @author David Cutting * @package xmlCreate */ /** * Main xmlCreate class object */ class xmlCreate { /** * Contains XML Output */ var $xml = ""; /** * Contains open tags * Not yet implemented */ var $open_tags = array(); /** * Contains Depth of Elements */ var $depth = 0; /** * Control the depth (variance) * @param integer $varience What to alter the depth by */ function setDepth($varience) { $this->depth += $varience; } /** * Pad to depth */ function pad() { if ($this->depth<1) return ""; return str_pad("",$this->depth," "); } /** * Start building an open-ended XML element * @param string $element Name of the element * @param array $vars Optional array of key values to use (or int 0 to skip) * @param boolean $single Optional indicator of single element if true * @param boolean $newline Optional insert newline at the end */ function startElement($element,$vars=0,$single=false,$newline=true) { $this->xml.=$this->pad(); $this->xml.="<".$element; if ( ($vars!=0) && (is_array($vars)) ) { foreach($vars as $key => $val) { $this->xml.=" ".$key."=\"".$val."\""; } } if ($single) $this->xml.=" /"; $this->xml.=">"; if ($newline) $this->xml.="\n"; if (!$single) $this->setDepth(1); } /** * End an open-ended XML element * @param string $element Name of the element * @param boolean $pad Optional use padding (default true) */ function endElement($element,$pad=true) { $this->setDepth(-1); if ($pad) $this->xml.=$this->pad(); $this->xml.="</".$element.">\n"; } /** * Insert data (textual/char data) * @param string $data Actual data to insert * @param boolean $cdata Wrap with CDATA (optional, default NO) * @param boolean $htmlcode Use HTML special characters (optional, default NO) * @param boolean $newline Insert newline after data (optional, default YES) */ function charData($data, $cdata=false, $htmlcode=false, $newline=true) { $dataline=""; if ($cdata) $dataline.="<![CDATA["; if ($htmlcode) $data=htmlspecialchars($data); $dataline.=$data; if ($cdata) $dataline.="]]>"; if ($newline) $dataline.="\n"; $this->xml.=$dataline; } /** * Single element wrapper for (@link startElement) * @param string $element Element Name * @param array $vars Optional variable array */ function singleElement($element,$vars=0) { $this->startElement($element,$vars,true); } /** * Single char-element wrapper * @param string $element Element Name * @param string $data Element Data Content * @param array $vars Optional array element variables (int 0 to skip) * @param boolean $htmlchars Optional convert data to html special chars (default false) * @param boolean $cdata Optional enclose char data in CDATA block (default false) */ function charElement($element,$data,$vars=0,$htmlchars=false,$cdata=false) { $this->startElement($element,$vars,false,false); $this->charData($data,$cdata,$htmlchars,false); $this->endElement($element,false); } /** * Returns XML Buffer * @return string XML Buffer */ function getXML() { return $this->xml; } /** * Writes XML Buffer to Screen * @param boolean $html Convert to HTML-friendly output (optional, default NO) * @param boolean $header Show an xml header (optional, default NO) * @param string $head_version XML Header version if shown (optional, default 1.0) * @param string $head_encode XML encoding in header if shown (optional, default utf-8) */ function echoXML($html=false,$header=false,$head_version="1.0",$head_encode="utf-8") { $out=""; if ($header) $out.="<?xml version=\"".$head_version."\" encoding=\"".$head_encode."\"?>\n"; $out.=$this->xml; if ($html) $out=nl2br(htmlspecialchars($out)); echo $out; } } ?>
DOAP Client JavaScript Library (doap.js)
/* ------------------------------------------------------------- This file is part of DOAP (Dave's Own Access Protocol) DOAP is (C) Copyright 2011 PurplePixie Systems DOAP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. DOAP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DOAP. If not, see www.gnu.org/licenses For more information see http://www.purplepixie.org/doap -------------------------------------------------------------- */ function DOAP_Error(code, desc) { this.code = code; this.desc = desc; } function DOAP_xmlhttp() { this.xmlhttp = null; if (window.XMLHttpRequest) { this.xmlhttp = new XMLHttpRequest; if (this.xmlhttp.overrideMimeType) this.xmlhttp.overrideMimeType("text/xml"); } else if (window.ActiveXObject) { try { this.xmlhttp = new ActiveXObject("Msxml2.HTTP"); } catch(e) { try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { // Give Up Now } } } if (this.xmlhttp == null) { var error = new DOAP_Error(100,"Failed to Create XMLHTTP Object"); throw error; } else return true; } function DOAP_randomstring( len ) { if (!len) var len = 32; var allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var rstring = ""; for (var i=0; i<len; i++) { var rchar = Math.floor(Math.random() * allowed.length); rstring += allowed.substring(rchar, rchar+1); } return rstring; } function DOAP_call( func, params ) { var callurl = this.url + "?f=" + func; if (!params) params = Array(); else if (!params instanceof Array) params = Array(params); for (var i=0; i<params.length; i++) { callurl = callurl + "&p["+i+"]="+encodeURIComponent(params[i]); } if (this.nocache) { callurl += ("&nc=" + this.makerandomstring()); } if (this.xmlhttp == null) this.makexmlhttp(); if ( this.async && (this.callback != null) ) // async - CAREFUL! { this.xmlhttp.doap = this; this.xmlhttp.open('GET', callurl, true); this.xmlhttp.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) { if (this.responseXML == null) { alert("null data"); var error = new DOAP_Error(102, "XML Result Null (Blank, Invalid or Corrupt)"); throw error; } else { this.doap.callback(this.doap.process(this.responseXML)); } } else { var error = new DOAP_Error(101, "HTTP Result Not 200 ("+this.xmlhttp.status+")"); throw error; } } } this.xmlhttp.send(); } else // non-sync { this.xmlhttp.open('GET', callurl, false); this.xmlhttp.send(null); if (this.xmlhttp.status == 200) { if (this.xmlhttp.responseXML == null) { var error = new DOAP_Error(102, "XML Result Null (Blank, Invalid or Corrupt)"); throw error; } else return this.process(this.xmlhttp.responseXML); } else { var error = new DOAP_Error(101, "HTTP Result Not 200 ("+this.xmlhttp.status+")"); throw error; } } } function DOAP_array( arrxml ) { var arr = Array(); for (var i=0; i<arrxml.childNodes.length; i++) { var ename = arrxml.childNodes[i].tagName; if (ename == "ELEMENT") arr.push(arrxml.childNodes[i].firstChild.nodeValue); else if (ename == "ARRAY") { arr.push(this.processarray(arrxml.childNodes[i])); } else { // unknown element type in array return } } return arr; } function DOAP_process( xml ) { if (xml.documentElement.tagName == "ERROR") { var code = xml.getElementsByTagName("CODE")[0].firstChild.nodeValue; var desc = xml.getElementsByTagName("DESC")[0].firstChild.nodeValue; var error = new DOAP_Error(code, desc); throw error; } else if (xml.documentElement.tagName == "RESULT") { var result = xml.getElementsByTagName("RESULT")[0]; if (result==null) { var error = new DOAP_Error(105,"Result Block not in XML"); throw error; } var data = result.firstChild.nodeValue; } else if (xml.documentElement.tagName == "ARRAY") { var arrdata = xml.getElementsByTagName("ARRAY")[0]; var data = this.processarray(arrdata); } else { var error=new DOAP_Error(106,"Unknown XML Response Type: "+xml.documentElement.tagName); throw error; } return data; } function DOAP() { this.xmlhttp = null; this.url = ""; this.nocache = true; this.async = false; this.callback = null; this.makexmlhttp = DOAP_xmlhttp; this.makerandomstring = DOAP_randomstring; this.call = DOAP_call; this.process = DOAP_process; this.processarray = DOAP_array; }