%PDF- %PDF-
| Direktori : /usr/local/prospamfilter/library/Cpanel/Query/ |
| Current File : //usr/local/prospamfilter/library/Cpanel/Query/Object.php |
<?php
/**
* Cpanel_Query_Object
*
* Copyright (c) 2011, cPanel, Inc.
* All rights reserved.
* http://cpanel.net
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of cPanel, Inc. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category Cpanel
* @package Cpanel_Query
* @author David Neimeyer <david.neimeyer@cpanel.net>
* @copyright Copyright (c) 2011, cPanel, Inc., All rights Reserved. (http://cpanel.net)
* @license http://sdk.cpanel.net/license/bsd.html BSD License
* @version 0.1.0
* @link http://sdk.cpanel.net
* @since 0.1.0
*/
/**
* Query and response object class
*
* This class works as both a request (or query) and response object in the
* since of most PHP frameworks. There are two containers for these
* responsibilities (query and response). Internally they are '_query' and
* '_response' but can be accessed externally simply by fetching
* $rObj->getQuery() or $rObj->getResponse(). Alternatively, there's a shortcut
* for fetching individual key/value pairs within those containers. If
* $rObj->key is called, $key will be fetched out of the response container. If
* $rObj->query->key is called, $key will be fetched from the query container.
* Setting values works in the same manner.
*
* @class Cpanel_Query_Object
* @category Cpanel
* @package Cpanel_Query
* @author David Neimeyer <david.neimeyer@cpanel.net>
* @copyright Copyright (c) 2011, cPanel, Inc., All rights Reserved. (http://cpanel.net)
* @license http://sdk.cpanel.net/license/bsd.html BSD License
* @version 0.1.0
* @link http://sdk.cpanel.net
* @since 0.1.0
*/
class Cpanel_Query_Object extends Cpanel_Core_Object
{
/**
* Container space for query data
*/
private $_query;
/**
* Container space for server response data
*/
private $_response;
/**
* Raw server response string
*/
private $_rawResponse = null;
/**
* Generic Parser interface for parse object validation
*/
private $_pinterface;
/**
* Input format
*/
private $_inputFormat;
/**
* Default output format
*/
private $_defaultOutputFormat = 'Cpanel_Core_Object';
/**
* Output format
*/
private $_outputFormat;
/**
* Response format type (RFT)
*/
private $_responseFormat;
/**
* Parser object
*/
private $_responseParser;
/**
* Error container
*/
private $_responseErrors = array();
/**
* Prefix for error message
*/
const ERROR_RESPONSE = 'Response Error: ';
/**
* Generic error message
*/
const ERROR_PARSE = 'Could not parse.';
/**
* Constructor
*
* @param arrays $optsArray Optional configuration data
*
* @return Cpanel_Query_Object
*/
public function __construct($optsArray = array())
{
parent::__construct($optsArray);
$this->_query = new Cpanel_Core_Object();
//TODO: make response an arrayobject with magic accessors?
$this->_response = new Cpanel_Core_Object();
//@todo make meths of this?
$this->_pinterface = 'Cpanel_Parser_Interface';
$this->_outputFormat = $this->_defaultOutputFormat;
return $this;
}
/**
* Set server expected input format
*
* @param string $type Input format type
*
* @return Cpanel_Query_Object
*/
public function setInputFormatType($type)
{
$this->_inputFormat = $type;
return $this;
}
/**
* Retrieve input format type
*
* @return string Input format type
*/
public function getInputFormatType()
{
return $this->_inputFormat;
}
/**
* Set response format type
*
* The response format type (RFT) is the format of the server response. This
* value is propagated to the stored parser object (generating a new parser
* object if one was not previous instantiated)
*
* @param string $type Response format type
* @param bool $reinit Force a new parser object instantiation prior to
* setting RFT
*
* @return Cpanel_Query_Object
* @throws Exception If parser object does not implement the defined parser
* interface
* @throws Exception If parser object can not parse the requested RFT
*/
public function setResponseFormatType($type, $reinit = false)
{
$this->_responseFormat = $type;
$p = $this->_responseParser;
if (!$p || $reinit) {
$this->setResponseParser($this->getValidParser($type));
} else {
if (!($p instanceof $this->_pinterface)) {
throw new Exception('Response parser must implement' . $this->_pinterface);
}
if (!$p->canParse($type)) {
$c = get_class($p);
throw new Exception("$c cannot parse response type $type");
}
}
return $this;
}
/**
* Instantiate a parser object.
*
* This method expects $type to coorelate to a Cpanel parser class located
* within Cpanel_Library. If a Cpane parser class cannot be found, $type
* will be treated as a custom class that has previously been defined (or
* available via the autoload stack). Custom parser classes must implement
* Cpanel_Parser_Interface
*
* @param string $type Name of parser to instantiate
*
* @return mixed Parser object which implements Cpanel_Parser_Interface
* @throws Exception If $type cannot be tranlated to a valid classname for
* instantiation
* @throws Exception If instantiated parser object does not implement
* Cpanel_Parser_Interface
*/
public function getValidParser($type)
{
$class = "Cpanel_Parser_{$type}";
/**
* Depending on the autoloader, class_exist may issue a warning however
* we loose alot of flexibility if we don't call __autoload, if you find
* this a problem, alter your error reporting function accordingly
*/
if (class_exists($class)) {
$c = $class;
} elseif (class_exists($type)) {
$c = $type;
} else {
throw new Exception(
"{$type} is an invalid parser and class is not defined"
);
}
$parserOptions = $this->parserOptions;
$parserOptions = (empty($parserOptions)) ? array() : $parserOptions;
$p = new $c($parserOptions);
if (!($p instanceof $this->_pinterface)) {
throw new Exception("{$c} must implement {$this->_pinterface}");
}
return $p;
}
/**
* Store a parser object
*
* @param object $obj Parser object that implements Cpanel_Parser_Interface
*
* @return Cpanel_Query_Object
*/
public function setResponseParser($obj)
{
if (!($obj instanceof $this->_pinterface)) {
throw new Exception(
'Response parser must implement ' . $this->_pinterface
);
}
$this->_responseParser = $obj;
return $this;
}
/**
* Retrieve the stored parser object
*
* @return mixed Object that implements Cpanel_Parser_Interface
*/
public function getResponseParser()
{
return $this->_responseParser;
}
/**
* Retrieve the response format type defined in this object
*
* @return string
*/
public function getResponseFormatType()
{
return $this->_responseFormat;
}
/**
* Set oupt format for this object
*
* @param string $type Output format type
*
* @return Cpanel_Query_Object
*/
public function setOutputFormatType($type)
{
$this->_outputFormat = $type;
return $this;
}
/**
* Retrieve this object's output format type
*
* @return string Output format type
*/
public function getOutputFormatType()
{
return $this->_outputFormat;
}
/**
* Retrieve a representation of the server response as requested by $type
*
* The method, by default will return the response container, a
* Cpanel_CpanelObject which is an iterable object. Other options include:
* 'array' - An deeply nested array representation of the server response
* "$type" - Where $type is an RFT for which a parser can be instantiated,
* i.e. 'JSON' or 'XML', etc.
*
* @param string $type Response format type to return
*
* @return mixed String, array, or object as requested by $type
*/
public function getResponse($type = '')
{
$type = ($type) ? $type : $this->getOutputFormatType();
if ($type == $this->_defaultOutputFormat) {
return $this;
} elseif (strtolower($type) == 'array') {
return $this->_response->getAllDataRecursively();
} elseif ($type == $this->getResponseFormatType()) {
return $this->getRawResponse();
} else {
$parser = $this->getValidParser($type);
// TODO: consider try/catch and pushing into error stack, similar
// to a $parser::parse()
return $parser->encodeQueryObject($this);
}
}
/**
* Store error in internal error stack
*
* @param string|array $err Error message string or array of such strings
*
* @return Cpanel_Query_Object
*/
protected function setResponseError($err)
{
if (is_string($err)) {
array_push($this->_responseErrors, $err);
} elseif (is_array($err) && count($err)) {
foreach ($err as $e) {
array_push($this->_responseErrors, $e);
}
}
return $this;
}
/**
* Check if parser object reported errors
*
* @return bool Whether the parser object was able to parser server response
*/
public function validResponse()
{
if (!empty($this->_responseErrors)) {
return false;
}
return true;
}
/**
* Retrieve all error reported by parser
*
* @param bool $flush Flush internal error stack. Default is FALSE.
*
* @return array|void An array of error string, otherwise null if no errors
* were reported by the parser object
*/
public function getResponseErrors($flush = false)
{
$r = $this->_responseErrors;
if (empty($r)) {
$r = null;
} else {
if ($flush) {
$this->_responseErrors = array();
}
}
return $r;
}
/**
* Set multiple key/value pairs in the query container
*
* @param array $obj An array of key/value pairs to set
*
* @return Cpanel_Query_Object
*/
public function setQuery($obj)
{
$this->_query->setOptions($obj);
return $this;
}
/**
* Retrieve the query container
*
* @return Cpanel_Core_Object
*/
public function getQuery()
{
return $this->_query;
}
/**
* Parse and store a raw response
*
* This method is responsible for receiving a raw server response, storing
* it, passing the raw response to the parser object and finally storing
* the parse response. If parsing errors occur, the value of the response
* contain will be empty and errors can be collected via
* {@link getResponseErrors()}
*
* @param string $raw The raw response string from the server
*
* @see getResponseErrors()
*
* @return Cpanel_Core_Object
*/
public function parse($raw)
{
$this->setRawResponse($raw);
if ($this->_query->directURL === true) {
$parsedResponse = array();
} else {
$parsedResponse = $this->_parseWithParser();
if (!is_array($parsedResponse)) {
if ($parsedResponse === false) {
//@codeCoverageIgnoreStart
$this->setResponseError(
self::ERROR_RESPONSE . self::ERROR_PARSE
);
//@codeCoverageIgnoreEnd
} elseif (is_string($parsedResponse)) {
$this->setResponseError(
self::ERROR_RESPONSE . $parsedResponse
);
}
$parsedResponse = array();
}
}
$this->setResponse($parsedResponse);
return $this->getResponse();
}
/**
* Trigger parser object's parse() against server's raw response
*
* @return array|string Array representation of raw response, otherwise a
* string denoting error observed by parser
* @throws Exception If parser object does not implement
* Cpanel_Parser_Interface
*/
private function _parseWithParser()
{
$raw = $this->getRawResponse();
$p = $this->getResponseParser();
if (!$p || !($p instanceof $this->_pinterface)) {
throw new Exception('Invalid response parser');
}
return $p->parse($raw);
}
/**
* Store key/value pairs in response container
*
* @param array $obj Array of key/value pairs to set
*
* @return Cpanel_Query_Object
*/
public function setResponse($obj)
{
$this->_response->setOptions($obj);
return $this;
}
/**
* Retrieve raw server response
*
* @return string Raw server response string
*/
public function getRawResponse()
{
return $this->_rawResponse;
}
/**
* Store raw server response
*
* @param string $str String to store as the raw server response
*
* @return Cpanel_Query_Object
*/
public function setRawResponse($str = null)
{
$listner = $this->getOption('listner');
if ($listner) {
$listner->log('debug', "Storing RawResponse:\n$str");
}
$this->_rawResponse = $str;
return $this;
}
/**
* Magic get accessor
*
* If $key is 'query', the query container is returned. This allows for
* effective chain calls like $rObj->query->ulitamteKeyDesired in calling
* scripts. Otherwise, $key will source from the response container
*
* @param string $key Key to search for
*
* @return mixed Value sourced for $key within the response container, or
* the query container if $key is 'query'
*/
public function __get($key)
{
if ($key == 'query') {
return $this->_query;
} else {
return $this->_response->getOption($key);
}
}
/**
* Magic set accessor
*
* The method will store key/value pairs within the response container. If
* storage to the query contain is desired, use {@link setQuery()} or a
* combination of magic {@__get()} methods, i.e. $rObj->query->key = value
*
* @param string $key Key for storage
* @param mixed $value Value to associate with $key
*
* @return void
*/
public function __set($key, $value)
{
$this->setResponse(
array(
$key => $value
)
);
}
/**
* Magic toString method
*
* This method will return a formatted representation of the response
* container (i.e. a print_r style string) when this object is referenced as
* or cased to a string
*
* @return string String representation of the response container object
*/
public function __toString()
{
$str = print_r($this->_response, true);
return $str;
}
}
?>