diff options
Diffstat (limited to 'library')
-rwxr-xr-x | library/SSRS/Object/Abstract.php | 60 | ||||
-rwxr-xr-x | library/SSRS/Object/ArrayIterator.php | 41 | ||||
-rwxr-xr-x | library/SSRS/Object/CatalogItem.php | 10 | ||||
-rwxr-xr-x | library/SSRS/Object/CatalogItems.php | 29 | ||||
-rwxr-xr-x | library/SSRS/Object/ExecutionInfo.php | 103 | ||||
-rwxr-xr-x | library/SSRS/Object/ExecutionParameters.php | 52 | ||||
-rwxr-xr-x | library/SSRS/Object/Extension.php | 10 | ||||
-rwxr-xr-x | library/SSRS/Object/Extensions.php | 26 | ||||
-rwxr-xr-x | library/SSRS/Object/ItemDefinition.php | 22 | ||||
-rw-r--r-- | library/SSRS/Object/Properties.php | 58 | ||||
-rwxr-xr-x | library/SSRS/Object/RenderStream.php | 22 | ||||
-rwxr-xr-x | library/SSRS/Object/ReportOutput.php | 28 | ||||
-rwxr-xr-x | library/SSRS/Object/ReportParameter.php | 120 | ||||
-rw-r--r-- | library/SSRS/Object/ReportParameter/ValidValue.php | 20 | ||||
-rwxr-xr-x | library/SSRS/Report.php | 436 | ||||
-rwxr-xr-x | library/SSRS/Report/Exception.php | 3 | ||||
-rwxr-xr-x | library/SSRS/Soap/Exception.php | 15 | ||||
-rwxr-xr-x | library/SSRS/Soap/NTLM.php | 175 | ||||
-rw-r--r-- | library/SSRS/Soap/ServerException.php | 29 |
19 files changed, 1259 insertions, 0 deletions
diff --git a/library/SSRS/Object/Abstract.php b/library/SSRS/Object/Abstract.php new file mode 100755 index 0000000..4658b48 --- /dev/null +++ b/library/SSRS/Object/Abstract.php @@ -0,0 +1,60 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ +class SSRS_Object_Abstract { + + public $data = array(); + + public function __construct($data = null) { + $this->init(); + $this->setData($data); + } + + public function init() { + + } + + public function setData($data) { + $clean = $this->_sanitizeData($data); + + if (is_array($clean)) { + foreach ($clean AS $key => $value) { + $this->$key = $value; + } + } + + return $this; + } + + public function __set($key, $value) { + $methodName = 'set' . ucfirst($key); + if (method_exists($this, $methodName)) { + $this->$methodName($value); + } else { + $this->data[$key] = $value; + } + } + + protected function _sanitizeData($data, $recursive = false) { + if (is_object($data)) { + $data = get_object_vars($data); + } + + if ($recursive && is_array($data)) { + foreach ($data AS $key => $value) { + $data[$key] = $this->_sanitizeData($value); + } + } + + return $data; + } + + public function __get($key) { + return isset($this->data[$key]) ? $this->data[$key] : null; + } + +}
\ No newline at end of file diff --git a/library/SSRS/Object/ArrayIterator.php b/library/SSRS/Object/ArrayIterator.php new file mode 100755 index 0000000..ad53ad5 --- /dev/null +++ b/library/SSRS/Object/ArrayIterator.php @@ -0,0 +1,41 @@ +<?php + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * Description of Iterator + * + * @author andrew + */ +class SSRS_Object_ArrayIterator extends SSRS_Object_Abstract implements Iterator { + + public $iteratorKey = 'Array'; + + public function next() { + return next($this->data[$this->iteratorKey]); + } + + public function prev() { + return prev($this->data[$this->iteratorKey]); + } + + public function key() { + return key($this->data[$this->iteratorKey]); + } + + public function current() { + return current($this->data[$this->iteratorKey]); + } + + public function valid() { + return isset($this->data[$this->iteratorKey][$this->key()]); + } + + public function rewind() { + return reset($this->data[$this->iteratorKey]); + } + +}
\ No newline at end of file diff --git a/library/SSRS/Object/CatalogItem.php b/library/SSRS/Object/CatalogItem.php new file mode 100755 index 0000000..cf0e25d --- /dev/null +++ b/library/SSRS/Object/CatalogItem.php @@ -0,0 +1,10 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ +class SSRS_Object_CatalogItem extends SSRS_Object_Abstract { + +} diff --git a/library/SSRS/Object/CatalogItems.php b/library/SSRS/Object/CatalogItems.php new file mode 100755 index 0000000..ac16f77 --- /dev/null +++ b/library/SSRS/Object/CatalogItems.php @@ -0,0 +1,29 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ + +require_once('ArrayIterator.php'); + +class SSRS_Object_CatalogItems extends SSRS_Object_ArrayIterator { + + public $iteratorKey = 'CatalogItems'; + + public function init() { + $this->data['CatalogItems'] = array(); + } + + public function setCatalogItems(stdClass $items) { + foreach ($items->CatalogItem AS $item) { + $this->addCatalogItem(new SSRS_Object_CatalogItem($item)); + } + } + + public function addCatalogItem(SSRS_Object_CatalogItem $item) { + $this->data['CatalogItems'][] = $item; + } + +} diff --git a/library/SSRS/Object/ExecutionInfo.php b/library/SSRS/Object/ExecutionInfo.php new file mode 100755 index 0000000..1087e3f --- /dev/null +++ b/library/SSRS/Object/ExecutionInfo.php @@ -0,0 +1,103 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ +class SSRS_Object_ExecutionInfo extends SSRS_Object_Abstract { + + /** + * Copy of self for backwards compatibility + * + * @var SSRS_Object_ExecutionInfo + */ + public $executionInfo; + + public function __construct(stdClass $info = null) { + if ($info) { + $this->setData($info->executionInfo); + } + + $this->executionInfo = $this; + } + + public function getExecutionId() { + return empty($this->data['ExecutionID']) ? null : $this->data['ExecutionID']; + } + + public function getExpirationTimestamp() { + return strtotime($this->data['ExpirationDateTime']); + } + + public function setParameters(stdClass $params) { + return $this->setReportParameters($params); + } + + public function setReportParameters($reportParameters) { + $parameters = array(); + + if ($reportParameters instanceof stdClass) { + $reportParameters = isset($reportParameters->ReportParameter) ? $reportParameters->ReportParameter : array(); + $reportParameters = is_array($reportParameters) ? $reportParameters : array($reportParameters); + } + + foreach ($reportParameters AS $reportParam) { + if (is_object($reportParam)) { + $data = array( + 'name' => $reportParam->Name, + 'value' => isset($reportParam->Value) ? $reportParam->Value : null + ); + } else { + $data = $reportParam; + } + + $parameter = new SSRS_Object_ReportParameter($data['name'], $data['value']); + $parameter->setData($reportParam); + + $parameters[] = $parameter; + } + + $this->data['ReportParameters'] = $parameters; + return $this; + } + + public function getReportPath() { + return $this->data['ReportPath']; + } + + /** + * Returns all report parameters in an array + * + * @return array parameters + * + */ + public function getReportParameters() { + return $this->data['ReportParameters']; + } + + public function getReportParameter($name) { + $parameters = $this->getReportParameters(); + foreach ($parameters AS $parameter) { + if ($parameter->name === $name) { + return $parameter; + } + } + + return null; + } + + public function __sleep() { + $this->executionInfo = null; + return array('data'); + } + + public function __wakeup() { + //$this->executionInfo = $this; + } + + public function getPageCount() { + return isset($this->data['NumPages']) ? $this->data['NumPages'] : 1; + } + +}
\ No newline at end of file diff --git a/library/SSRS/Object/ExecutionParameters.php b/library/SSRS/Object/ExecutionParameters.php new file mode 100755 index 0000000..bf3b819 --- /dev/null +++ b/library/SSRS/Object/ExecutionParameters.php @@ -0,0 +1,52 @@ +<?php + +/** + * Description of ExecutionParameters + * + * @author andrew + */ +class SSRS_Object_ExecutionParameters extends SSRS_Object_ArrayIterator { + + public $iteratorKey = 'Parameters'; + + public function __construct(array $parameters = array()) { + parent::__construct(null); + $this->setParameters($parameters); + } + + public function init() { + $this->data['Parameters'] = array(); + } + + public function setParameters(array $parameters) { + $this->data['Parameters'] = array(); + + foreach ($parameters AS $key => $parameter) { + if (($parameter instanceof SSRS_Object_ReportParameter) === false) { + $values = (array) $parameter; + foreach ($values AS $value) { + $this->data['Parameters'][] = new SSRS_Object_ReportParameter($key, $value); + } + } else { + $this->data['Parameters'][] = $parameter; + } + } + } + + public function getParameters() { + return $this->data['Parameters']; + } + + public function getParameterArrayForSoapCall() { + $execParams = array(); + foreach ($this->getParameters() AS $parameter) { + $execParams[] = array( + 'Name' => $parameter->name, + 'Value' => $parameter->value, + ); + } + + return $execParams; + } + +} diff --git a/library/SSRS/Object/Extension.php b/library/SSRS/Object/Extension.php new file mode 100755 index 0000000..efae2dd --- /dev/null +++ b/library/SSRS/Object/Extension.php @@ -0,0 +1,10 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ +class SSRS_Object_Extension extends SSRS_Object_Abstract { + +} diff --git a/library/SSRS/Object/Extensions.php b/library/SSRS/Object/Extensions.php new file mode 100755 index 0000000..786c1b6 --- /dev/null +++ b/library/SSRS/Object/Extensions.php @@ -0,0 +1,26 @@ +<?php + +/** + * SSRS_Object_Abstract + * + * @author arron + */ +class SSRS_Object_Extensions extends SSRS_Object_ArrayIterator { + + public $iteratorKey = 'Extension'; + + public function init() { + $this->data['Extension'] = array(); + } + + public function setExtensions(stdClass $items) { + foreach ($items->Extension AS $item) { + $this->addExtension(new SSRS_Object_Extension($item)); + } + } + + public function addExtension(SSRS_Object_Extension $item) { + $this->data['Extension'][] = $item; + } + +} diff --git a/library/SSRS/Object/ItemDefinition.php b/library/SSRS/Object/ItemDefinition.php new file mode 100755 index 0000000..f63d57e --- /dev/null +++ b/library/SSRS/Object/ItemDefinition.php @@ -0,0 +1,22 @@ +<?php + +/** + * Description of ExecutionParameters + * + * @author andrew + */ +class SSRS_Object_ItemDefinition extends SSRS_Object_Abstract { + + public function getXMLString() { + return $this->Definition; + } + + public function getSimpleXML() { + return new SimpleXMLElement($this->getXMLString()); + } + + public function __toString() { + return $this->getXMLString(); + } + +} diff --git a/library/SSRS/Object/Properties.php b/library/SSRS/Object/Properties.php new file mode 100644 index 0000000..6765450 --- /dev/null +++ b/library/SSRS/Object/Properties.php @@ -0,0 +1,58 @@ +<?php + +class SSRS_Object_Properties { + + protected $_properties = array(); + + public function __construct($properties = array()) { + $this->addProperties($properties); + } + + public function __get($name){ + return $this->getProperty($name); + } + + /** + * + * @param array $properties + */ + public function addProperties(array $properties) { + foreach ($properties AS $key => $value) { + if (is_object($value) && isset($value->Name)) { + $key = $value->Name; + $value = isset($value->Value)? $value->Value : null; + } + + $this->addProperty($key, $value); + } + } + + /** + * + * @param string $key + * @param mixed $value + * @return \SSRS_Object_Properties + */ + public function addProperty($key, $value) { + $this->_properties[$key] = $value; + return $this; + } + + /** + * + * @return array + */ + public function getProperties() { + return $this->_properties; + } + + /** + * + * @param string $key + * @return mixed + */ + public function getProperty($key) { + return array_key_exists($key, $this->_properties) ? $this->_properties[$key] : null; + } + +}
\ No newline at end of file diff --git a/library/SSRS/Object/RenderStream.php b/library/SSRS/Object/RenderStream.php new file mode 100755 index 0000000..a1027f8 --- /dev/null +++ b/library/SSRS/Object/RenderStream.php @@ -0,0 +1,22 @@ +<?php + +/** + * SSRS_Object_RenderStream + * + * @author arron + */ +class SSRS_Object_RenderStream extends SSRS_Object_Abstract { + + public $Result; + public $MimeType; + + public function __construct(stdClass $stream) { + $this->Result = $stream->Result; + $this->MimeType = $stream->MimeType; + } + + public function __toString() { + return $this->Result; + } + +}
\ No newline at end of file diff --git a/library/SSRS/Object/ReportOutput.php b/library/SSRS/Object/ReportOutput.php new file mode 100755 index 0000000..208a638 --- /dev/null +++ b/library/SSRS/Object/ReportOutput.php @@ -0,0 +1,28 @@ +<?php + +/** + * Description of ExecutionParameters + * + * @author andrew + */ +class SSRS_Object_ReportOutput extends SSRS_Object_Abstract { + + public function download($filename) { + header("Cache-control: max-age=3600, must-revalidate"); + header("Pragma: public"); + header("Expires: -1"); + header("Content-Description: File Transfer"); + header('Content-Disposition: attachment; filename="' . $filename . '"'); + header("Content-Type: " . $this->MimeType); + header("Content-Transfer-Encoding: binary"); + header("Content-Length: " . strlen($this->Result)); + + echo($this->Result); + exit(0); + } + + public function __toString() { + return (string) $this->Result; + } + +} diff --git a/library/SSRS/Object/ReportParameter.php b/library/SSRS/Object/ReportParameter.php new file mode 100755 index 0000000..9f1e77e --- /dev/null +++ b/library/SSRS/Object/ReportParameter.php @@ -0,0 +1,120 @@ +<?php + +/** + * Description of ExecutionParameters + * + * @author andrew + */ +class SSRS_Object_ReportParameter extends SSRS_Object_Abstract { + + public function __construct($name, $value) { + $this->name = $name; + $this->value = $value; + } + + public $name; + public $value; + + /** + * + * @return array + */ + public function getDefaultValue() { + $defaults = array(); + + if (key_exists('DefaultValues', $this->data) && isset($this->data['DefaultValues']->Value)) { + $defaults = (array) $this->data['DefaultValues']->Value; + } + + if ($this->isSelect()) { + $validValues = array(); + foreach ($this->getValidValues() AS $validValue) { + $validValues[] = $validValue->Value; + } + + $defaults = array_intersect($defaults, $validValues); + } + + return $defaults; + } + + public function setValidValues($validValues) { + if ($validValues instanceof stdClass && isset($validValues->ValidValue) && is_object($validValues->ValidValue)) { + $validValues = array($validValues->ValidValue); + } elseif ($validValues instanceof stdClass && isset($validValues->ValidValue)) { + $validValues = $validValues->ValidValue; + } + + $data = array(); + foreach ($validValues AS $value) { + if (is_object($value)) { + $data[] = new SSRS_Object_ReportParameter_ValidValue((string) $value->Label, (string) $value->Value); + } elseif (is_array($value)) { + $data[] = new SSRS_Object_ReportParameter_ValidValue((string) $value['Label'], (string) $value['Value']); + } else { + $data[] = new SSRS_Object_ReportParameter_ValidValue((string) $value, (string) $value); + } + } + + $this->data['ValidValues'] = $data; + return $this; + } + + /** + * + * @return \SSRS_Object_ReportParameter_ValidValue[] + */ + public function getValidValues() { + return empty($this->data['ValidValues']) ? array() : $this->data['ValidValues']; + } + + /** + * + * @return bool + */ + public function hasDependencies() { + return (isset($this->data['Dependencies']->Dependency) + && !empty($this->data['Dependencies']->Dependency)); + } + + /** + * + * @return bool + */ + public function getDependencies() { + return (array) $this->data['Dependencies']->Dependency; + } + + /** + * + * @return bool + */ + public function hasOutstandingDependencies() { + return ($this->getState() == 'HasOutstandingDependencies'); + } + + /** + * + * @return bool + */ + public function getState() { + return key_exists('State', $this->data) ? $this->data['State'] : null; + } + + /** + * + * @return bool + */ + public function isMultiValue() { + return !empty($this->data['MultiValue']); + } + + /** + * + * @return bool + */ + public function isSelect() { + return ($this->isMultiValue() || (!empty($this->data['ValidValues']) && is_array($this->data['ValidValues']) && count($this->data['ValidValues']) > 0)); + } + +} diff --git a/library/SSRS/Object/ReportParameter/ValidValue.php b/library/SSRS/Object/ReportParameter/ValidValue.php new file mode 100644 index 0000000..b75b07e --- /dev/null +++ b/library/SSRS/Object/ReportParameter/ValidValue.php @@ -0,0 +1,20 @@ +<?php + +class SSRS_Object_ReportParameter_ValidValue { + + /** + * capitals because of SSRS! + */ + public $Value; + public $Label; + + public function __construct($label, $value) { + $this->Value = $value; + $this->Label = $label; + } + + public function __toString() { + return $this->Value; + } + +}
\ No newline at end of file diff --git a/library/SSRS/Report.php b/library/SSRS/Report.php new file mode 100755 index 0000000..4c6a8f9 --- /dev/null +++ b/library/SSRS/Report.php @@ -0,0 +1,436 @@ +<?php + +/** + * php-ssrs http://www.apache.org/licenses/LICENSE-2.0 + * + * @author Arron Woods <arron@idealwebsites.co.uk> + * @link http://code.idealwebsites.co.uk/php-ssrs/ + * @copyright Copyright © 2011 Ideal Websites Ltd + * @license + * @version 0.1 + */ +require_once('Soap/NTLM.php'); +require_once('Soap/Exception.php'); +require_once('Object/Abstract.php'); +require_once('Object/ArrayIterator.php'); +require_once('Object/CatalogItems.php'); +require_once('Object/CatalogItem.php'); +require_once('Object/ItemDefinition.php'); +require_once('Object/ExecutionParameters.php'); +require_once('Object/ExecutionInfo.php'); +require_once('Object/Extensions.php'); +require_once('Object/Extension.php'); +require_once('Object/ReportParameter.php'); +require_once('Object/ReportOutput.php'); +require_once('Report/Exception.php'); + +class SSRS_Report { + + public $servicePath = 'ReportService2010.asmx'; + public $executionPath = 'ReportExecution2005.asmx'; + protected $_baseUri; + protected $_username; + protected $_passwd; + protected $_soapService; + protected $_soapExecution; + protected $_executionNameSpace = 'http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices'; + protected $_headerExecutionLayout = '<ExecutionHeader xmlns="%s"><ExecutionID>%s</ExecutionID></ExecutionHeader>'; + protected $_sessionId; + + /** + * + * @param string $baseUri + * @param array $options + */ + public function __construct($baseUri, $options = array()) { + $this->setBaseUri($baseUri); + + if (array_key_exists('username', $options)) { + $this->setUsername($options['username']); + } + + if (array_key_exists('password', $options)) { + $this->setPassword($options['password']); + } + } + + public function setBaseUri($uri) { + $this->_baseUri = rtrim($uri, '/'); + } + + public function getBaseUri() { + return $this->_baseUri; + } + + /** + * Sets the Soap client class with the Execution Uri so that the connection to the web service can be made. + * Should be the custom SOAP NTLM class to bypass NTLM security. + * + * @param SoapClient $client + */ + public function setSoapExecution(SoapClient $client) { + $this->_soapExecution = $client; + return $this; + } + + /** + * Sets the Soap client class with the Service Uri so that the connection to the web service can be made. + * Should be the custom SOAP NTLM class to bypass NTLM security. + * + * @param SoapClient $client + */ + public function setSoapService(SoapClient $client) { + $this->_soapService = $client; + return $this; + } + + /** + * Returns the SOAP client Execution object so that methods of the web service can be run. + * If the SOAP Execution object is undefined then it will be set. + * + * @return SoapClient + */ + public function getSoapExecution($runInit = true) { + if ($this->_soapExecution === null) { + $options = array('username' => $this->_username, 'password' => $this->_passwd); + $client = new SSRS_Soap_NTLM($this->_baseUri . '/' . $this->executionPath, $options); + if ($runInit) { + $client->init(); + } + + $this->setSoapExecution($client); + } + + return $this->_soapExecution; + } + + /** + * Returns the SOAP client Service object so that methods of the web service can be run. + * If the SOAP Service object is undefined then it will be set. + * + * @return SoapClient + */ + public function getSoapService($runInit = true) { + if ($this->_soapService === null) { + $options = array('username' => $this->_username, 'password' => $this->_passwd); + $client = new SSRS_Soap_NTLM($this->_baseUri . '/' . $this->servicePath, $options); + if ($runInit) { + $client->init(); + } + + $this->setSoapService($client); + } + + return $this->_soapService; + } + + /** + * Sets username property + * + * @param string $username + * @return SSRS_Report + */ + public function setUsername($username) { + $this->_username = (string) $username; + return $this; + } + + /** + * Sets password property + * + * @param string $password + * @return SSRS_Report + */ + public function setPassword($password) { + $this->_passwd = (string) $password; + return $this; + } + + /** + * Returns username property value + * + * @return string + */ + public function getUsername() { + return $this->_username; + } + + /** + * Returns password property value + * + * @return string + */ + public function getPassword() { + return $this->_passwd; + } + + /** + * Sets Session ID, taken from the LoadReport method under property 'ExecutionID'. + * Required for later methods to produce report. + * Adds to the main SOAP header through the SOAP Execution object. + * + * @param string $id + */ + public function setSessionId($id) { + $client = $this->getSoapExecution(); + $parameters = array(array('name' => 'ExecutionID', 'value' => $id)); + + $headerStr = sprintf($this->_headerExecutionLayout, $this->_executionNameSpace, $id); + $soapVar = new SoapVar($headerStr, XSD_ANYXML, null, null, null); + + $soapHeader = new SoapHeader($this->_executionNameSpace, 'ExecutionHeader', $soapVar); + $client->__setSoapHeaders(array($soapHeader)); + + $this->_sessionId = $id; + return $this; + } + + /** + * Returns a list of all child items from a specified location. + * Used to show all reports available. + * + * @param string $itemPath + * @param boolean $recursive + * @return SSRS_Object_CatalogItems + */ + public function listChildren($itemPath, $recursive = false) { + $params = array( + 'ItemPath' => $itemPath, + 'Recursive' => (bool) $recursive + ); + + $result = $this->getSoapService()->ListChildren($params); + return new SSRS_Object_CatalogItems($result); + } + + /** + * Returns item properties + * + * @param string $path + * @return \SSRS_Object_Properties + */ + public function getProperties($itemPath) { + $params = array( + 'ItemPath' => $itemPath, + ); + + $result = $this->getSoapService()->GetProperties($params); + return new SSRS_Object_Properties($result->Values->Property); + } + + /** + * Returns item definition details in a XML string. + * Used to backup report definitions into a XML based RDL file. + * + * @param string $itemPath + * @return SSRS_Object_ItemDefinition + */ + public function getItemDefinition($itemPath) { + $params = array( + 'ItemPath' => $itemPath, + ); + $result = $this->getSoapService()->GetItemDefinition($params); + return new SSRS_Object_ItemDefinition($result); + } + + /** + * Returns a list of all render types to output reports to, such as XML, HTML & PDF. + * + * @return SSRS_Object_Extensions + */ + public function listRenderingExtensions() { + return new SSRS_Object_Extensions($this->getSoapExecution()->ListRenderingExtensions()); + } + + /** + * + * @param type $toggleId + * @return type + */ + public function toggleItem($toggleId) { + $params = array( + 'ToggleID' => $toggleId + ); + return $this->getSoapExecution()->ToggleItem($params); + } + + public function sort($sortId, $direction, $clear) { + $params = array( + 'SortItem' => $sortId, + 'Direction' => $direction, + 'Clear' => $clear, + ); + return $this->getSoapExecution()->Sort($params); + } + + /** + * Loads all details relating to a report including all available search parameters + * + * @param string $Report + * @param string $HistoryId + * @return SSRS_Object_ExecutionInfo + */ + public function loadReport($Report, $HistoryId = null) { + $params = array( + 'Report' => $Report, + 'HistoryID' => $HistoryId + ); + + $result = $this->getSoapExecution()->LoadReport($params); + return new SSRS_Object_ExecutionInfo($result); + } + + /** + * Get current execution info + * + * @return \SSRS_Object_ExecutionInfo + */ + public function getExecutionInfo() { + $result = $this->getSoapExecution()->GetExecutionInfo2(); + return new SSRS_Object_ExecutionInfo($result); + } + + /** + * Sets all search parameters for the report to render. + * Pass details from 'LoadReport' method to set the search parameters. + * Requires the Session/Execution ID to be set. + * + * @param SSRS_Object_ExecutionParameters $request + * @param string $id + * @return SSRS_Object_ExecutionInfo + */ + public function setExecutionParameters(SSRS_Object_ExecutionParameters $parameters, $parameterLanguage = 'en-us') { + $this->checkSessionId(); + + $options = array( + 'Parameters' => $parameters->getParameterArrayForSoapCall(), + 'ParameterLanguage' => $parameterLanguage, + ); + + $result = $this->getSoapExecution()->SetExecutionParameters($options); + return new SSRS_Object_ExecutionInfo($result); + } + + /** + * Renders and outputs report depending on $format variable. + * + * @param string $format + * @param string $PaginationMode + * @return SSRS_Object_ReportOutput + */ + public function render($format, $deviceInfo = array(), $PaginationMode = 'Estimate') { + $this->checkSessionId(); + $deviceInfo = array('DeviceInfo' => $deviceInfo); + + $renderParams = array( + 'Format' => $format, + 'DeviceInfo' => $this->renderDeviceInfo($deviceInfo), + 'PaginationMode' => $PaginationMode + ); + + $result = $this->getSoapExecution()->Render2($renderParams); + return new SSRS_Object_ReportOutput($result); + } + + /** + * + * @param string $format + * @param string $streamId + * @param array $deviceInfo + * @return \SSRS_Object_RenderStream + */ + public function renderStream($format, $streamId, $deviceInfo = array()) { + $this->checkSessionId(); + $deviceInfo = array('DeviceInfo' => array_merge(array('Toolbar' => 'false'), $deviceInfo)); + + $renderParams = array( + 'Format' => $format, + 'StreamID' => $streamId, + 'DeviceInfo' => $this->renderDeviceInfo($deviceInfo), + ); + + $result = $this->getSoapExecution()->RenderStream($renderParams); + return new SSRS_Object_RenderStream($result); + } + + /** + * + * @param string $format + * @param string $streamId + * @param array $deviceInfo + * @return \SSRS_Object_RenderStream + */ + public function getRenderResource($format, $deviceInfo = array()) { + $this->checkSessionId(); + + $deviceInfo = array('DeviceInfo' => $deviceInfo); + + $renderParams = array( + 'Format' => (string) $format, + 'DeviceInfo' => $this->renderDeviceInfo($deviceInfo), + ); + + $result = $this->getSoapExecution()->GetRenderResource($renderParams); + return new SSRS_Object_RenderStream($result); + } + + /** + * Checks if there is a valid Session ID set. + * + */ + public function checkSessionId() { + if ($this->hasValidSessionId() === false) { + throw new SSRS_Report_Exception('Session ID not set'); + } + } + + /** + * Checks to see if the Session ID is not empty and returns boolean value + * @return bool + */ + public function hasValidSessionId() { + return (!empty($this->_sessionId)); + } + + /** + * Translate deviceInfo array into XML + * Look out for translation entities + * @param array $deviceInfo + */ + public function renderDeviceInfo(array $deviceInfo) { + $translations = array( + '_SID_' => $this->_sessionId, + '_TIME_' => time(), + ); + return $this->renderXmlOptions($deviceInfo, $translations); + } + + /** + * Takes an array of options and converts them to an XML string recursively + * @param array $options + * @param array $translations + * @return string $xml + */ + public function renderXmlOptions(array $options, $translations = array()) { + $xml = ''; + foreach ($options AS $key => $value) { + switch (true) { + case is_array($value): + $value = $this->renderXmlOptions($value, $translations); + break; + case is_bool($value): + $value = ($value) ? 'true' : 'false'; + break; + default: + $value = strtr($value, $translations); + $value = htmlentities($value); + } + + $key = preg_replace('/[^a-z0-9_\-]+/i', '_', $key); + $xml .= sprintf('<%s>%s</%s>', $key, $value, $key); + } + + return $xml; + } + +} diff --git a/library/SSRS/Report/Exception.php b/library/SSRS/Report/Exception.php new file mode 100755 index 0000000..a6afac5 --- /dev/null +++ b/library/SSRS/Report/Exception.php @@ -0,0 +1,3 @@ +<?php + +class SSRS_Report_Exception extends Exception{}
\ No newline at end of file diff --git a/library/SSRS/Soap/Exception.php b/library/SSRS/Soap/Exception.php new file mode 100755 index 0000000..5e6170d --- /dev/null +++ b/library/SSRS/Soap/Exception.php @@ -0,0 +1,15 @@ +<?php + +class SSRS_Soap_Exception extends Exception{ + + public $httpCode; + public $response; + + public function __construct($message, $code, $response = null) { + $this->httpCode = $code; + $this->response = $response; + + parent::__construct($message, $code); + } + +}
\ No newline at end of file diff --git a/library/SSRS/Soap/NTLM.php b/library/SSRS/Soap/NTLM.php new file mode 100755 index 0000000..929a642 --- /dev/null +++ b/library/SSRS/Soap/NTLM.php @@ -0,0 +1,175 @@ +<?php + +class SSRS_Soap_NTLM extends SoapClient { + + protected $_uri; + protected $_username; + protected $_passwd; + protected $_cachePath; + protected $_cacheExpiry; + protected $_lastRequest; + protected $_lastResponse; + + function __construct($wsdl, $options = array()) { + if (!array_key_exists('cache_wsdl_path', $options)) { + $options['cache_wsdl_path'] = '/tmp/' . md5($wsdl) . '.wsdl'; + } + + if (array_key_exists('username', $options)) { + $this->setUsername($options['username']); + } + + if (array_key_exists('password', $options)) { + $this->setPassword($options['password']); + } + + $this->setUri($wsdl); + $this->setCachePath($options['cache_wsdl_path']); + } + + public function init() { + $this->fetchWSDL(); + + $options['cache_wsdl'] = WSDL_CACHE_MEMORY; + $options['login'] = $this->_username; + $options['password'] = $this->_passwd; + + parent::__construct($this->_cachePath, $options); + return $this; + } + + public function setUri($uri) { + $this->_uri = $uri; + return $this; + } + + public function getUri() { + return $this->_uri; + } + + public function setCacheExpiry($cacheExpiry = 86400) { + $this->_cacheExpiry = $cacheExpiry; + return $this; + } + + public function getCacheExpiry() { + return $this->_cacheExpiry; + } + + public function isCacheValid() { + $checkTime = time() - $this->getCacheExpiry(); + return (file_exists($this->getCachePath()) && filemtime($this->getCachePath()) > $checkTime); + } + + public function setUsername($username) { + $this->_username = (string) $username; + return $this; + } + + public function setPassword($password) { + $this->_passwd = (string) $password; + return $this; + } + + public function setCachePath($path) { + $folder = dirname($path); + + if (!is_dir($folder)) { + throw new SSRS_Soap_Exception('WSDL cache path is not valid'); + } + + if (!is_writeable($folder)) { + throw new SSRS_Soap_Exception('WSDL cache path not writeable'); + } + + $this->_cachePath = $path; + return $this; + } + + public function getCachePath() { + return $this->_cachePath; + } + + public function cacheWSDL($fileContents) { + $result = file_put_contents($this->_cachePath, $fileContents); + if ($result) { + $this->setCacheWSDLPermission(0666); + } + } + + public function setCacheWSDLPermission($oct = 0666) { + @chmod($this->_cachePath, 0666); + } + + public function getCacheWSDL() { + return file_get_contents($this->getCachePath()); + } + + public function fetchWSDL() { + if ($this->isCacheValid() === false) { + $wsdlContent = $this->callCurl($this->_uri); + $this->cacheWSDL($wsdlContent); + } + } + + public function __doRequest($data, $url, $action) { + $this->_lastRequest = (string) $data; + $this->_lastResponse = $this->callCurl($url, $data, $action); + return $this->_lastResponse; + } + + public function callCurl($url, $data = null, $action = null) { + $handle = curl_init(); + curl_setopt($handle, CURLOPT_URL, $url); + curl_setopt($handle, CURLOPT_FAILONERROR, false); + curl_setopt($handle, CURLOPT_USERAGENT, 'PHP SOAP-NTLM Client'); + curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); + curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($handle, CURLOPT_USERPWD, $this->_username . ':' . $this->_passwd); + curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); + + $headers = array( + 'Method: ' . ($data === null) ? 'GET' : 'POST', + 'Connection: Keep-Alive', + 'User-Agent: PHP-SOAP-CURL', + ); + + if ($data !== null) { + $headers[] = 'Content-Type: text/xml; charset=utf-8'; + $headers[] = 'Content-Length: ' . strlen($data); + curl_setopt($handle, CURLOPT_POSTFIELDS, $data); + } + + if ($action !== null) { + $headers[] = 'SOAPAction: "' . $action . '"'; + } + + curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); + + $response = curl_exec($handle); + if ($response === false) { + throw new SSRS_Soap_Exception('CURL error: ' . curl_error($handle), curl_errno($handle)); + } + + $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE); + if ($httpCode >= 300 && $httpCode <= 600) { + throw SSRS_Soap_ServerException::fromResponse($response); + } else if ($httpCode !== 200) { + throw new SSRS_Soap_Exception('HTTP error: ' . $httpCode . ' ' . $response, $httpCode, $response); + } + curl_close($handle); + + $this->_lastResponse = (string) $response; + return $response; + } + + public function getLastRequest() { + return $this->_lastRequest; + } + + public function getLastResponse() { + return $this->_lastResponse; + } + +} diff --git a/library/SSRS/Soap/ServerException.php b/library/SSRS/Soap/ServerException.php new file mode 100644 index 0000000..3ffce47 --- /dev/null +++ b/library/SSRS/Soap/ServerException.php @@ -0,0 +1,29 @@ +<?php + +class SSRS_Soap_ServerException extends Exception { + + public $faultcode; + public $faultstring; + public $faultactor; + + static function fromResponse($string) { + $xml = new SimpleXMLElement($string); + $ns = $xml->getNamespaces(true); + + $soap = $xml->children($ns['soap']); + $body = $soap->Body->children($ns['soap']); + if (isset($body->Fault)) { + $fault = $body->Fault->children(); + + $exception = new SSRS_Soap_ServerException((string) $fault->faultstring); + $exception->faultcode = (string) $fault->faultcode; + $exception->faultstring = (string) $fault->faultstring; + $exception->faultactor = (string) $fault->faultactor; + } else { + throw new SSRS_Soap_Exception('Invalid server response'); + } + + return $exception; + } + +}
\ No newline at end of file |