diff --git a/lib/api/ktcmis/exceptions/ContentAlreadyExistsException.inc.php b/lib/api/ktcmis/exceptions/ContentAlreadyExistsException.inc.php new file mode 100644 index 0000000..c97c4bc --- /dev/null +++ b/lib/api/ktcmis/exceptions/ContentAlreadyExistsException.inc.php @@ -0,0 +1,7 @@ + diff --git a/lib/api/ktcmis/exceptions/RuntimeException.inc.php b/lib/api/ktcmis/exceptions/RuntimeException.inc.php new file mode 100644 index 0000000..cb1a5b2 --- /dev/null +++ b/lib/api/ktcmis/exceptions/RuntimeException.inc.php @@ -0,0 +1,7 @@ + diff --git a/lib/api/ktcmis/exceptions/StreamNotSupportedException.inc.php b/lib/api/ktcmis/exceptions/StreamNotSupportedException.inc.php new file mode 100644 index 0000000..4e29acb --- /dev/null +++ b/lib/api/ktcmis/exceptions/StreamNotSupportedException.inc.php @@ -0,0 +1,7 @@ + diff --git a/lib/api/ktcmis/exceptions/UpdateConflictException.inc.php b/lib/api/ktcmis/exceptions/UpdateConflictException.inc.php new file mode 100644 index 0000000..f3e8847 --- /dev/null +++ b/lib/api/ktcmis/exceptions/UpdateConflictException.inc.php @@ -0,0 +1,7 @@ + diff --git a/lib/api/ktcmis/exceptions/VersioningException.inc.php b/lib/api/ktcmis/exceptions/VersioningException.inc.php new file mode 100644 index 0000000..e84ff24 --- /dev/null +++ b/lib/api/ktcmis/exceptions/VersioningException.inc.php @@ -0,0 +1,7 @@ + diff --git a/lib/api/ktcmis/ktcmis.inc.php b/lib/api/ktcmis/ktcmis.inc.php index 8b38935..08776e8 100644 --- a/lib/api/ktcmis/ktcmis.inc.php +++ b/lib/api/ktcmis/ktcmis.inc.php @@ -468,7 +468,42 @@ class KTObjectService extends KTCMISBase { } /** - * Function to create a folder + * Creates a new document within the repository + * + * @param string $repositoryId The repository to which the document must be added + * @param string $typeId Object Type id for the document object being created + * @param array $properties Array of properties which must be applied to the created document object + * @param string $folderId The id of the folder which will be the parent of the created document object + * This parameter is optional IF unfilingCapability is supported + * @param contentStream $contentStream optional content stream data + * @param string $versioningState optional version state value: checkedout/major/minor + * @return string $objectId The id of the created folder object + */ + function createDocument($repositoryId, $typeId, $properties, $folderId = null, + $contentStream = null, $versioningState = 'Major') + { + $objectId = null; + + try { + $objectId = $this->ObjectService->createDocument($repositoryId, $typeId, $properties, $folderId, + $contentStream, $versioningState); + } + catch (Exception $e) + { + return array( + "status_code" => 1, + "message" => $e->getMessage() + ); + } + + return array( + 'status_code' => 0, + 'results' => $objectId + ); + } + + /** + * Creates a new folder within the repository * * @param string $repositoryId The repository to which the folder must be added * @param string $typeId Object Type id for the folder object being created @@ -497,6 +532,41 @@ class KTObjectService extends KTCMISBase { ); } + /** + * Sets the content stream data for an existing document + * + * if $overwriteFlag = TRUE, the new content stream is applied whether or not the document has an existing content stream + * if $overwriteFlag = FALSE, the new content stream is applied only if the document does not have an existing content stream + * + * NOTE A Repository MAY automatically create new Document versions as part of this service method. + * Therefore, the documentId output NEED NOT be identical to the documentId input. + * + * @param string $repositoryId + * @param string $documentId + * @param boolean $overwriteFlag + * @param string $contentStream + * @param string $changeToken + * @return string $documentId + */ + function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) + { + try { + $objectId = $this->ObjectService->setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken); + } + catch (Exception $e) + { + return array( + "status_code" => 1, + "message" => $e->getMessage() + ); + } + + return array( + 'status_code' => 0, + 'results' => $documentId + ); + } + } ?> diff --git a/lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php b/lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php index 7f45780..bfb6822 100644 --- a/lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php +++ b/lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php @@ -81,10 +81,9 @@ class CMISDocumentObject extends CMISBaseObject { $this->includedInSupertypeQuery = true; // // TODO determine what these next 3 should be $this->controllable = false; // - $this->versionable = false; // - $this->contentStreamAllowed = false; // - $this->contentStreamLength = 0; - $this->contentStreamMimeType = ''; + $this->versionable = true; // + $this->contentStreamAllowed = 'required'; // notAllowed/allowed/required + // properties $this->properties = new CMISDocumentPropertyCollection(); diff --git a/lib/api/ktcmis/services/CMISObjectService.inc.php b/lib/api/ktcmis/services/CMISObjectService.inc.php index 157d9ab..b40c7f0 100644 --- a/lib/api/ktcmis/services/CMISObjectService.inc.php +++ b/lib/api/ktcmis/services/CMISObjectService.inc.php @@ -2,8 +2,12 @@ require_once(KT_DIR . '/ktapi/ktapi.inc.php'); require_once(CMIS_DIR . '/exceptions/ConstraintViolationException.inc.php'); +require_once(CMIS_DIR . '/exceptions/ContentAlreadyExistsException.inc.php'); require_once(CMIS_DIR . '/exceptions/ObjectNotFoundException.inc.php'); require_once(CMIS_DIR . '/exceptions/StorageException.inc.php'); +require_once(CMIS_DIR . '/exceptions/StreamNotSupportedException.inc.php'); +require_once(CMIS_DIR . '/exceptions/UpdateConflictException.inc.php'); +require_once(CMIS_DIR . '/exceptions/VersioningException.inc.php'); require_once(CMIS_DIR . '/services/CMISRepositoryService.inc.php'); require_once(CMIS_DIR . '/objecttypes/CMISDocumentObject.inc.php'); require_once(CMIS_DIR . '/objecttypes/CMISFolderObject.inc.php'); @@ -68,7 +72,128 @@ class CMISObjectService { } /** - * Function to create a folder + * Creates a new document within the repository + * + * @param string $repositoryId The repository to which the document must be added + * @param string $typeId Object Type id for the document object being created + * @param array $properties Array of properties which must be applied to the created document object + * @param string $folderId The id of the folder which will be the parent of the created document object + * This parameter is optional IF unfilingCapability is supported + * @param contentStream $contentStream optional content stream data + * @param string $versioningState optional version state value: checkedout/major/minor + * @return string $objectId The id of the created folder object + */ + // TODO throw ConstraintViolationException if: + // value of any of the properties violates the min/max/required/length constraints + // specified in the property definition in the Object-Type. + // TODO throw ConstraintViolationException if: + // The Object-Type definition specified by the typeId parameter's "contentStreamAllowed" attribute + // is set to "required" and no contentStream input parameter is provided + // TODO throw ConstraintViolationException if: + // The Object-Type definition specified by the typeId parameter's "versionable" attribute + // is set to "false" and a value for the versioningState input parameter is provided + function createDocument($repositoryId, $typeId, $properties, $folderId = null, + $contentStream = null, $versioningState = 'Major') + { + $objectId = null; + + // fetch type definition of supplied type and check for base type "document", if not true throw exception + $RepositoryService = new CMISRepositoryService(); + try { + $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId); + } + // NOTE Not sure that we should throw this specific exception, maybe just let the underlying + // exception propogate upward... + // Alternatively: throw new exception with original exception message appended + // NOTE The latter method has been adopted for the moment + catch (Exception $e) + { + throw new ConstraintViolationException('Object is not of base type document. ' . $e->getMessage()); + } + + if ($typeDefinition['attributes']['baseType'] != 'document') + { + throw new ConstraintViolationException('Object is not of base type document'); + } + + // if no $folderId submitted and repository does not support "unfiling" throw exception + if (empty($folderId)) + { + $repositoryInfo = $RepositoryService->getRepositoryInfo($repositoryId); + $capabilities = $repositoryInfo->getCapabilities(); + if (!$capabilities->hasCapabilityUnfiling()) + { + throw new ConstraintViolationException('Repository does not support the Unfiling capability and no folder id was supplied'); + } + } + + // Attempt to decode $folderId, use as is if not detected as encoded + $tmpObjectId = $folderId; + $tmpTypeId = CMISUtil::decodeObjectId($tmpObjectId); + if ($tmpTypeId != 'Unknown') + $folderId = $tmpObjectId; + + // if parent folder is not allowed to hold this type, throw exception + $CMISFolder = new CMISFolderObject($folderId, $this->ktapi); + $folderProperties = $CMISFolder->getProperties(); + $allowed = $folderProperties->getValue('AllowedChildObjectTypeIds'); + if (!is_array($allowed) || !in_array($typeId, $allowed)) + { + throw new ConstraintViolationException('Parent folder may not hold objects of this type (' . $typeId . ')'); + } + + // set title and name identical if only one submitted + if ($properties['title'] == '') + { + $properties['title'] = $properties['name']; + } + else if ($properties['name'] == '') + { + $properties['name'] = $properties['title']; + } + + if ($properties['type'] == '') + { + $properties['type'] = $properties['Default']; + } + + // if content stream is required and no content stream is supplied, throw a ConstraintViolationException + if (($typeDefinition['attributes']['contentStreamAllowed'] == 'required') && empty($contentStream)) + { + throw new ConstraintViolationException('The Knowledgetree Repository requires a content stream for document creation. ' + . 'Refusing to create an empty document'); + } + else if (($typeDefinition['attributes']['contentStreamAllowed'] == 'notAllowed') && !empty($contentStream)) + { + throw new StreamNotSupportedException('Content Streams are not supported'); + } + + // TODO deal with $versioningState when supplied + + // TODO Use add_document_with_metadata instead if metadata content submitted + $response = $this->ktapi->add_document($folderId, $properties['title'], $properties['name'], $properties['type'], $uploadedFile); + if ($response['status_code'] != 0) + { + throw new StorageException('The repository was unable to create the document - ' . $response['message']); + } + else + { + $objectId = CMISUtil::encodeObjectId('Document', $response['results']['id']); + } + + // now that the document object exists, create the content stream from the supplied data + if (!empty($contentStream)) + { + // TODO changeToken support + $changeToken = null; + $this->setContentStream($repositoryId, $objectId, false, $contentStream, $changeToken); + } + + return $objectId; + } + + /** + * Creates a new folder within the repository * * @param string $repositoryId The repository to which the folder must be added * @param string $typeId Object Type id for the folder object being created @@ -81,14 +206,20 @@ class CMISObjectService { // specified in the property definition in the Object-Type. function createFolder($repositoryId, $typeId, $properties, $folderId) { + $objectId = null; + // fetch type definition of supplied type and check for base type "folder", if not true throw exception $RepositoryService = new CMISRepositoryService(); try { $typeDefinition = $RepositoryService->getTypeDefinition($repositoryId, $typeId); } + // NOTE Not sure that we should throw this specific exception, maybe just let the underlying + // exception propogate upward... + // Alternatively: throw new exception with original exception message appended + // NOTE The latter method has been adopted for the moment catch (Exception $e) { - throw new ConstraintViolationException('Object is not of base type folder.'); + throw new ConstraintViolationException('Object is not of base type folder. ' . $e->getMessage()); } if ($typeDefinition['attributes']['baseType'] != 'folder') @@ -96,12 +227,11 @@ class CMISObjectService { throw new ConstraintViolationException('Object is not of base type folder'); } - // TODO determine whether this is in fact necessary or if we should require decoding in the calling code // Attempt to decode $folderId, use as is if not detected as encoded - $objectId = $folderId; - $tmpTypeId = CMISUtil::decodeObjectId($objectId); + $tmpObjectId = $folderId; + $tmpTypeId = CMISUtil::decodeObjectId($tmpObjectId); if ($tmpTypeId != 'Unknown') - $folderId = $objectId; + $folderId = $tmpObjectId; // if parent folder is not allowed to hold this type, throw exception $CMISFolder = new CMISFolderObject($folderId, $this->ktapi); @@ -115,7 +245,6 @@ class CMISObjectService { $response = $this->ktapi->create_folder($folderId, $properties['name'], $sig_username = '', $sig_password = '', $reason = ''); if ($response['status_code'] != 0) { - // throw storageException throw new StorageException('The repository was unable to create the folder - ' . $response['message']); } else @@ -126,6 +255,62 @@ class CMISObjectService { return $objectId; } + /** + * Sets the content stream data for an existing document + * + * if $overwriteFlag = TRUE, the new content stream is applied whether or not the document has an existing content stream + * if $overwriteFlag = FALSE, the new content stream is applied only if the document does not have an existing content stream + * + * NOTE A Repository MAY automatically create new Document versions as part of this service method. + * Therefore, the documentId output NEED NOT be identical to the documentId input. + * + * @param string $repositoryId + * @param string $documentId + * @param boolean $overwriteFlag + * @param string $contentStream + * @param string $changeToken + * @return string $documentId + */ + // TODO exceptions: + // updateConflictException: The operation is attempting to update an object that is no longer current + // (as determined by the repository). + // versioningException: The repository MAY throw this exception if the object is a non-current Document Version. + function setContentStream($repositoryId, $documentId, $overwriteFlag, $contentStream, $changeToken = null) + { + // fetch type definition of supplied document + $CMISDocument = new CMISDocumentObject($documentId, $this->ktapi); + + // if content stream is not allowed for this object type definition, throw a ConstraintViolationException + if (($CMISDocument->getAttribute('contentStreamAllowed') == 'notAllowed')) + { + // NOTE spec version 0.61c specifies both a ConstraintViolationException and a StreamNotSupportedException + // for this case. Choosing to throw StreamNotSupportedException until the specification is clarified + // as it is a more specific exception + throw new StreamNotSupportedException('Content Streams are not allowed for this object type'); + } + + $properties = $CMISDocument->getProperties(); + if (!empty($properties->getValue('ContentStreamFilename')) && (!$overwriteFlag)) + { + throw new ContentAlreadyExistsException('Unable to overwrite existing content stream'); + } + + // in order to set the stream we need to do the following: + // 1. decode the stream from the supplied base64 encoding + // 2. create a temporary file as if it were uploaded via a file upload dialog + // 3. create the document content as per usual + // 4. link to the created document object? this perhaps only happens on read anyway + + // if there is any problem updating the content stream, throw StorageException + // TODO real test parameter instead of hard-coded FALSE + if (false) + { + throw new StorageException('Unable to update the content stream'); + } + + return $documentId; + } + } ?> diff --git a/tests/ktcmis/testCmisApi.php b/tests/ktcmis/testCmisApi.php index 94fd66d..96b2fb0 100644 --- a/tests/ktcmis/testCmisApi.php +++ b/tests/ktcmis/testCmisApi.php @@ -592,14 +592,14 @@ class CMISTestCase extends KTUnitTestCase { foreach($results as $key => $value) { ?>
$propval) { - if ($propval == '') continue; + if ($propval['value'] == '') continue; - $this->printRow($propkey, $propval); + $this->printRow($propkey, $propval['value']); } // now any children diff --git a/webservice/classes/soap/WSHelper.class.php b/webservice/classes/soap/WSHelper.class.php index a7e82cb..5bd0058 100755 --- a/webservice/classes/soap/WSHelper.class.php +++ b/webservice/classes/soap/WSHelper.class.php @@ -1,183 +1,183 @@ -uri = $uri; - $this->setWSDLCacheFolder($_SERVER['DOCUMENT_ROOT'].dirname($_SERVER['PHP_SELF'])."/wsdl/"); - if($class) $this->setClass($class); - } - - /** - * Adds the given class name to the list of classes - * to be included in the documentation/WSDL/Request handlers - * @param string - * @return void - */ - public function setClass($name){ - $this->name = $name; - $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; - } - - public function setWSDLCacheFolder($folder) { - $this->wsdlFolder = $folder; - //reset wsdlfile - $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; - } - /** - * Sets the persistence level for the soap class - */ - public function setPersistence($persistence) { - $this->persistence = $persistence; - } - - /** - * Handles everything. Makes sure the webservice is handled, - * documentations is generated, or the wsdl is generated, - * according to the page request - * @return void - */ - public function handle(){ - if(substr($_SERVER['QUERY_STRING'], -4) == 'wsdl'){ - $this->showWSDL(); - }elseif(isset($GLOBALS['HTTP_RAW_POST_DATA']) && strlen($GLOBALS['HTTP_RAW_POST_DATA'])>0){ - $this->handleRequest(); - }else{ - $this->createDocumentation(); - } - } - /** - * Checks if the current WSDL is up-to-date, regenerates if necessary and outputs the WSDL - * @return void - */ - public function showWSDL(){ - //check if it's a legal webservice class - if(!in_array($this->name, $this->classNameArr)) - throw new Exception("No valid webservice class."); - - //@TODO: nog een mooie oplossing voor het cachen zoeken - header("Content-type: text/xml"); - if($this->useWSDLCache && file_exists($this->wsdlfile)){ - readfile($this->wsdlfile); - }else{ - //make sure to refresh PHP WSDL cache system - ini_set("soap.wsdl_cache_enabled",0); - echo $this->createWSDL(); - } - } - - private function createWSDL(){ - $this->class = new IPReflectionClass($this->name); - $wsdl = new WSDLStruct($this->uri, "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?class=".$this->name, $this->type, $this->use); - $wsdl->setService($this->class); - - try { - $gendoc = $wsdl->generateDocument(); - } catch (WSDLException $exception) { - $exception->Display(); - exit(); - } - - $fh = fopen($this->wsdlfile, "w+"); - fwrite($fh, $gendoc); - fclose($fh); - - return $gendoc; - } - - /** - * Lets the native PHP5 soap implementation handle the request - * after registrating the class - * @return void - */ - private function handleRequest(){ - //check if it's a legal webservice class - if(!in_array($this->name, $this->classNameArr)) - throw new Exception("No valid webservice class."); - - //check cache - //if(!file_exists($this->wsdlfile)) - $this->createWSDL(); - - $options = Array('actor' => $this->actor, 'classmap' => $this->structureMap); - - header("Content-type: text/xml"); - $this->server = new SoapServer($this->wsdlfile, $options); - $this->server->setClass($this->name); - $this->server->setPersistence($this->persistence); - - use_soap_error_handler(true); - $this->server->handle(); - } - - /** - * @param string code - * @param string string - * @param string actor - * @param mixed details - * @param string name - * @return void - */ - public function fault($code, $string, $actor, $details, $name='') { - return $this->server->fault($code, $string, $actor, $details, $name); - } - - /** - * Generates the documentations for the webservice usage. - * @TODO: "int", "boolean", "double", "float", "string", "void" - * @param string Template filename - * @return void - */ - public function createDocumentation($template="classes/soap/templates/docclass.xsl") { - if(!is_file($template)) - throw new WSException("Could not find the template file: '$template'"); - $this->class = new IPReflectionClass($this->name); - $xtpl = new IPXSLTemplate($template); - $documentation = Array(); - $documentation['menu'] = Array(); - //loop menu items - sort($this->classNameArr); - foreach($this->classNameArr as $className) { - $documentation['menu'][] = new IPReflectionClass($className); - } - - if($this->class){ - $this->class->properties = $this->class->getProperties(false, false); - $this->class->methods = $this->class->getMethods(false, false); - foreach((array)$this->class->methods as $method) { - $method->params = $method->getParameters(); - } - - $documentation['class'] = $this->class; - } - echo $xtpl->execute($documentation); - } -} +uri = $uri; + $this->setWSDLCacheFolder($_SERVER['DOCUMENT_ROOT'].dirname($_SERVER['PHP_SELF'])."/wsdl/"); + if($class) $this->setClass($class); + } + + /** + * Adds the given class name to the list of classes + * to be included in the documentation/WSDL/Request handlers + * @param string + * @return void + */ + public function setClass($name){ + $this->name = $name; + $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; + } + + public function setWSDLCacheFolder($folder) { + $this->wsdlFolder = $folder; + //reset wsdlfile + $this->wsdlfile = $this->wsdlFolder.$this->name.".wsdl"; + } + /** + * Sets the persistence level for the soap class + */ + public function setPersistence($persistence) { + $this->persistence = $persistence; + } + + /** + * Handles everything. Makes sure the webservice is handled, + * documentations is generated, or the wsdl is generated, + * according to the page request + * @return void + */ + public function handle(){ + if(substr($_SERVER['QUERY_STRING'], -4) == 'wsdl'){ + $this->showWSDL(); + }elseif(isset($GLOBALS['HTTP_RAW_POST_DATA']) && strlen($GLOBALS['HTTP_RAW_POST_DATA'])>0){ + $this->handleRequest(); + }else{ + $this->createDocumentation(); + } + } + /** + * Checks if the current WSDL is up-to-date, regenerates if necessary and outputs the WSDL + * @return void + */ + public function showWSDL(){ + //check if it's a legal webservice class + if(!in_array($this->name, $this->classNameArr)) + throw new Exception("No valid webservice class."); + + //@TODO: nog een mooie oplossing voor het cachen zoeken + header("Content-type: text/xml"); + if($this->useWSDLCache && file_exists($this->wsdlfile)){ + readfile($this->wsdlfile); + }else{ + //make sure to refresh PHP WSDL cache system + ini_set("soap.wsdl_cache_enabled",0); + echo $this->createWSDL(); + } + } + + private function createWSDL(){ + $this->class = new IPReflectionClass($this->name); + $wsdl = new WSDLStruct($this->uri, "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?class=".$this->name, $this->type, $this->use); + $wsdl->setService($this->class); + + try { + $gendoc = $wsdl->generateDocument(); + } catch (WSDLException $exception) { + $exception->Display(); + exit(); + } + + $fh = fopen($this->wsdlfile, "w+"); + fwrite($fh, $gendoc); + fclose($fh); + + return $gendoc; + } + + /** + * Lets the native PHP5 soap implementation handle the request + * after registrating the class + * @return void + */ + private function handleRequest(){ + //check if it's a legal webservice class + if(!in_array($this->name, $this->classNameArr)) + throw new Exception("No valid webservice class."); + + //check cache + //if(!file_exists($this->wsdlfile)) + $this->createWSDL(); + + $options = Array('actor' => $this->actor, 'classmap' => $this->structureMap); + + header("Content-type: text/xml"); + $this->server = new SoapServer($this->wsdlfile, $options); + $this->server->setClass($this->name); + $this->server->setPersistence($this->persistence); + + use_soap_error_handler(true); + $this->server->handle(); + } + + /** + * @param string code + * @param string string + * @param string actor + * @param mixed details + * @param string name + * @return void + */ + public function fault($code, $string, $actor, $details, $name='') { + return $this->server->fault($code, $string, $actor, $details, $name); + } + + /** + * Generates the documentations for the webservice usage. + * @TODO: "int", "boolean", "double", "float", "string", "void" + * @param string Template filename + * @return void + */ + public function createDocumentation($template="classes/soap/templates/docclass.xsl") { + if(!is_file($template)) + throw new WSException("Could not find the template file: '$template'"); + $this->class = new IPReflectionClass($this->name); + $xtpl = new IPXSLTemplate($template); + $documentation = Array(); + $documentation['menu'] = Array(); + //loop menu items + sort($this->classNameArr); + foreach($this->classNameArr as $className) { + $documentation['menu'][] = new IPReflectionClass($className); + } + + if($this->class){ + $this->class->properties = $this->class->getProperties(false, false); + $this->class->methods = $this->class->getMethods(false, false); + foreach((array)$this->class->methods as $method) { + $method->params = $method->getParameters(); + } + + $documentation['class'] = $this->class; + } + echo $xtpl->execute($documentation); + } +} ?> \ No newline at end of file diff --git a/webservice/classes/soap/templates/str.replace.function.xsl b/webservice/classes/soap/templates/str.replace.function.xsl index 5d74e86..626e549 100755 --- a/webservice/classes/soap/templates/str.replace.function.xsl +++ b/webservice/classes/soap/templates/str.replace.function.xsl @@ -1,105 +1,105 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ERROR: function implementation of str:replace() relies on exsl:node-set(). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERROR: function implementation of str:replace() relies on exsl:node-set(). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webservice/tests/annotations.php b/webservice/tests/annotations.php index e10ef44..a0ee1ff 100755 --- a/webservice/tests/annotations.php +++ b/webservice/tests/annotations.php @@ -1,44 +1,44 @@ -'you'); - */ -class something{ - /** - * @var string - * @Controller(type => DefaultController::TYPE_PLAIN, length => 100) - */ - public $propertyA; - - /** - * @var string - * @Controller(type => DefaultController::TYPE_HTML, length => 100) - */ - public function methodB () { - return "aap"; - } -} - -/* Annotation example */ -$rel = new IPReflectionClass("something"); -$properties = $rel->getProperties(); -$methods = $rel->getMethods(); - -var_dump($rel->getAnnotation("ann1", "stdClass")); - -$property = $properties["propertyA"]; -$ann = $property->getAnnotation("Controller", "DefaultController"); -var_dump($ann); - -$method = $methods["methodB"]; -$ann = $method->getAnnotation("Controller", "DefaultController"); -var_dump($ann); +'you'); + */ +class something{ + /** + * @var string + * @Controller(type => DefaultController::TYPE_PLAIN, length => 100) + */ + public $propertyA; + + /** + * @var string + * @Controller(type => DefaultController::TYPE_HTML, length => 100) + */ + public function methodB () { + return "aap"; + } +} + +/* Annotation example */ +$rel = new IPReflectionClass("something"); +$properties = $rel->getProperties(); +$methods = $rel->getMethods(); + +var_dump($rel->getAnnotation("ann1", "stdClass")); + +$property = $properties["propertyA"]; +$ann = $property->getAnnotation("Controller", "DefaultController"); +var_dump($ann); + +$method = $methods["methodB"]; +$ann = $method->getAnnotation("Controller", "DefaultController"); +var_dump($ann); ?> \ No newline at end of file