Commit 8d56157abf064bb4477a3b193132ffa4d502bcd8

Authored by Paul Barrett
1 parent d82d4ae8

Update CMIS Object Attributes

Story ID:2295472. Update KT CMIS implementation to 1.0 compliance

Committed by: Paul Barrett
lib/api/ktcmis/classes/CMISObject.inc.php
@@ -44,22 +44,33 @@ @@ -44,22 +44,33 @@
44 * @version Version 0.1 44 * @version Version 0.1
45 */ 45 */
46 46
47 -abstract class CMISObject { 47 +// NOTE designation "opaque" means the value may not be changed
  48 +
  49 +// TODO consider attributes as a class similar to property definitions, in order to more easily extract without having
  50 +// to have attribute specific code
48 51
49 - protected $typeId;  
50 - protected $queryName;  
51 - protected $displayName;  
52 - protected $baseType;  
53 - protected $baseTypeQueryName;  
54 - protected $parentId;  
55 - protected $description;  
56 - protected $creatable;  
57 - protected $fileable;  
58 - protected $queryable;  
59 - protected $includedInSupertypeQuery;  
60 - protected $controllable; // NOTE deprecated? part of policy objects specification, policy objects are indicated as TODO remove  
61 - protected $contentStreamAllowed = 'notAllowed'; 52 +abstract class CMISObject {
62 53
  54 + protected $id; // ID (opaque); identifies the object-type in the repository
  55 + protected $localName; // String (opaque, optional); local name for object-type - need not be set
  56 + protected $localNamespace; // String (opaque, optional); optional local namespace for object-type - need not be set
  57 + // NOTE queryName should not contain characters that negatively interact with BNF grammar
  58 + protected $queryName; // String (opaque); used for query and filter operations on object-types
  59 + protected $displayName; // String (optional); used for presentation by application
  60 + protected $baseId; // Enum; indicates base type
  61 + protected $parentId; // ID; id of immediate parent type; must be "not set" for a base type (Document, Folder, Relationship, Policy)
  62 + protected $description; // String (optional); used for presentation by application
  63 + protected $creatable; // Boolean; indicates whether new objects of this type may be created
  64 + protected $fileable; // Boolean; indicates whether objects of this type are fileable
  65 + protected $queryable; // Boolean; indicates whether this object-type can appear inthe FROM clause of a query statement
  66 + protected $controllablePolicy; // Boolean; indicates whether objects of this type are controllable via policies
  67 + protected $controllableACL; // Boolean; indicates whether objects of this type are controllable by ACLs
  68 + protected $fulltextIndexed; // Boolean; indicates whether objects of this type are indexed for full-text search
  69 + // for querying via the CONTAINS() query predicate
  70 + protected $includedInSupertypeQuery; // Boolean; indicates whether this type and sub-types appear in a query of this type's ancestor types
  71 + // For example: if Invoice is a sub-type of cmis:document, if this is TRUE on Invoice then for a query
  72 + // 391 on cmis:document, instances of Invoice will be returned if they match.
  73 +
63 protected $properties; // list of property objects which define the additional properties for this object 74 protected $properties; // list of property objects which define the additional properties for this object
64 75
65 // TODO all we have here so far is getAttributes & getProperties 76 // TODO all we have here so far is getAttributes & getProperties
@@ -82,18 +93,21 @@ abstract class CMISObject { @@ -82,18 +93,21 @@ abstract class CMISObject {
82 93
83 // TODO look at how chemistry does this and implement something similar 94 // TODO look at how chemistry does this and implement something similar
84 // for now this is fine as we are just trying to get things up and running :) 95 // for now this is fine as we are just trying to get things up and running :)
85 - $attributes['typeId'] = $this->typeId; 96 + $attributes['id'] = $this->id;
  97 + $attributes['localName'] = $this->localName;
  98 + $attributes['localNamespace'] = $this->localNamespace;
86 $attributes['queryName'] = $this->queryName; 99 $attributes['queryName'] = $this->queryName;
87 $attributes['displayName'] = $this->displayName; 100 $attributes['displayName'] = $this->displayName;
88 - $attributes['baseType'] = $this->baseType;  
89 - $attributes['baseTypeQueryName'] = $this->baseTypeQueryName; 101 + $attributes['baseId'] = $this->baseId;
90 $attributes['parentId'] = $this->parentId; 102 $attributes['parentId'] = $this->parentId;
91 $attributes['description'] = $this->description; 103 $attributes['description'] = $this->description;
92 $attributes['creatable'] = $this->creatable; 104 $attributes['creatable'] = $this->creatable;
93 $attributes['fileable'] = $this->fileable; 105 $attributes['fileable'] = $this->fileable;
94 $attributes['queryable'] = $this->queryable; 106 $attributes['queryable'] = $this->queryable;
  107 + $attributes['controllablePolicy'] = $this->controllablePolicy;
  108 + $attributes['controllableACL'] = $this->controllableACL;
  109 + $attributes['fulltextIndexed'] = $this->fulltextIndexed;
95 $attributes['includedInSupertypeQuery'] = $this->includedInSupertypeQuery; 110 $attributes['includedInSupertypeQuery'] = $this->includedInSupertypeQuery;
96 - $attributes['controllable'] = $this->includedInSupertypeQuery;  
97 111
98 return $attributes; 112 return $attributes;
99 } 113 }
@@ -136,12 +150,12 @@ abstract class CMISObject { @@ -136,12 +150,12 @@ abstract class CMISObject {
136 return $this->properties->getValue($property); 150 return $this->properties->getValue($property);
137 } 151 }
138 152
139 - public function reload($documentId) 153 + public function reload($objectId)
140 { 154 {
141 - $this->_get($documentId); 155 + $this->_get($objectId);
142 } 156 }
143 157
144 - private function _get($documentId) 158 + private function _get($objectId)
145 { 159 {
146 // override in child classes 160 // override in child classes
147 } 161 }
lib/api/ktcmis/objecttypes/CMISDocumentObject.inc.php
@@ -52,41 +52,34 @@ require_once(CMIS_DIR . '/util/CMISUtil.inc.php'); @@ -52,41 +52,34 @@ require_once(CMIS_DIR . '/util/CMISUtil.inc.php');
52 52
53 class CMISDocumentObject extends CMISObject { 53 class CMISDocumentObject extends CMISObject {
54 54
55 - protected $versionable;  
56 - private $ktapi;  
57 - private $uri;  
58 - 55 + protected $versionable; // Bolean; indicates whether objects of this type are versionable
  56 + protected $contentStreamAllowed; // Enum; notallowed, allowed, required
  57 + protected $ktapi;
  58 +
59 // TODO some of this should probably come from configuration files as it is repository specific 59 // TODO some of this should probably come from configuration files as it is repository specific
60 function __construct($documentId = null, &$ktapi = null, $uri = null) 60 function __construct($documentId = null, &$ktapi = null, $uri = null)
61 { 61 {
62 $this->ktapi = $ktapi; 62 $this->ktapi = $ktapi;
63 - // uri to use for document links  
64 - $this->uri = $uri;  
65 63
66 // attributes 64 // attributes
67 - $this->typeId = 'Document'; // <repository-specific>  
68 - $this->queryName = 'Document';  
69 - $this->displayName = ''; // <repository-specific>  
70 - $this->baseType = 'document';  
71 - $this->baseTypeQueryName = 'Document';  
72 - $this->parentId = null; // MUST NOT be set  
73 - $this->description = ''; // <repository-specific>  
74 - $this->creatable = ''; // <repository-specific>  
75 - /*  
76 - * fileable SHOULD be set as follows:  
77 - * If the repository does NOT support the รขโ‚ฌล“un-filingรขโ‚ฌ? capability:  
78 - * TRUE  
79 - * If the repository does support the รขโ‚ฌล“un-filingรขโ‚ฌ? capability:  
80 - * <repository-specific>, but SHOULD be TRUE  
81 - */  
82 - $this->fileable = true; // TODO implement check for whether un-filing is supported 65 + $this->id = 'cmis:document';
  66 + $this->localName = null; // <repository-specific>
  67 + $this->localNamespace = null; // <repository-specific>
  68 + $this->queryName = 'cmis:document';
  69 + $this->displayName = 'Document'; // <repository-specific>
  70 + $this->baseId = 'cmis:document';
  71 + $this->parentId = null; // MUST NOT be set for base document object-type
  72 + $this->description = null; // <repository-specific>
  73 + $this->creatable = true; // <repository-specific>
  74 + $this->fileable = true;
83 $this->queryable = true; // SHOULD be true 75 $this->queryable = true; // SHOULD be true
84 - $this->includedInSupertypeQuery = true; //  
85 - // TODO determine what these next 3 should be  
86 - $this->controllable = false; // <repository-specific> 76 + $this->controllablePolicy = false; // <repository-specific>
  77 + $this->includedInSupertypeQuery = true; // <repository-specific>
87 $this->versionable = true; // <repository-specific> 78 $this->versionable = true; // <repository-specific>
88 - $this->contentStreamAllowed = 'required'; // <repository-specific> notAllowed/allowed/required  
89 - 79 + $this->contentStreamAllowed = 'required'; // <repository-specific> notallowed/allowed/required
  80 + $this->controllableACL = false; // <repository-specific>
  81 + $this->fulltextIndexed = false; // <repository-specific>
  82 +
90 // properties 83 // properties
91 $this->properties = new CMISDocumentPropertyCollection(); 84 $this->properties = new CMISDocumentPropertyCollection();
92 85
@@ -98,7 +91,7 @@ class CMISDocumentObject extends CMISObject { @@ -98,7 +91,7 @@ class CMISDocumentObject extends CMISObject {
98 if (!is_null($documentId)) 91 if (!is_null($documentId))
99 { 92 {
100 try { 93 try {
101 - $this->get($documentId); 94 + $this->_get($documentId);
102 } 95 }
103 catch (exception $e) { 96 catch (exception $e) {
104 throw new ObjectNotFoundException($e->getMessage()); 97 throw new ObjectNotFoundException($e->getMessage());
@@ -107,8 +100,9 @@ class CMISDocumentObject extends CMISObject { @@ -107,8 +100,9 @@ class CMISDocumentObject extends CMISObject {
107 100
108 // TODO throw exception if unable to create? 101 // TODO throw exception if unable to create?
109 } 102 }
110 -  
111 - private function get($documentId) 103 +
  104 + // TODO abstract shared stuff to base class where possible
  105 + private function _get($documentId)
112 { 106 {
113 $object = $this->ktapi->get_document_by_id((int)$documentId); 107 $object = $this->ktapi->get_document_by_id((int)$documentId);
114 108
@@ -131,9 +125,9 @@ class CMISDocumentObject extends CMISObject { @@ -131,9 +125,9 @@ class CMISDocumentObject extends CMISObject {
131 // $this->_setPropertyInternal('uri', $uri); 125 // $this->_setPropertyInternal('uri', $uri);
132 $this->_setPropertyInternal('uri', ''); 126 $this->_setPropertyInternal('uri', '');
133 // TODO what is this? Assuming it is the object type id, and not OUR document type? 127 // TODO what is this? Assuming it is the object type id, and not OUR document type?
134 - $this->_setPropertyInternal('objectTypeId', 'cmis:' . strtolower($this->getAttribute('typeId'))); 128 + $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
135 // Needed to distinguish type 129 // Needed to distinguish type
136 - $this->_setPropertyInternal('baseTypeId', 'cmis:' . strtolower($this->getAttribute('typeId'))); 130 + $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
137 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']); 131 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
138 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']); 132 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
139 $this->_setPropertyInternal('lastModifiedBy', $objectProperties['modified_by']); 133 $this->_setPropertyInternal('lastModifiedBy', $objectProperties['modified_by']);
@@ -181,6 +175,22 @@ class CMISDocumentObject extends CMISObject { @@ -181,6 +175,22 @@ class CMISDocumentObject extends CMISObject {
181 $this->_setPropertyInternal('contentStreamUri', $this->getProperty('objectId') . '/' . $objectProperties['filename']); 175 $this->_setPropertyInternal('contentStreamUri', $this->getProperty('objectId') . '/' . $objectProperties['filename']);
182 $this->_setPropertyInternal('author', $objectProperties['created_by']); 176 $this->_setPropertyInternal('author', $objectProperties['created_by']);
183 } 177 }
  178 +
  179 + /**
  180 + * Returns a listing of all attributes in an array
  181 + *
  182 + * @return array $attributes
  183 + */
  184 + public function getAttributes()
  185 + {
  186 + $attributes = parent::getAttributes();
  187 +
  188 + // add document object-type specific attributes
  189 + $attributes['versionable'] = $this->versionable;
  190 + $attributes['contentStreamAllowed'] = $this->contentStreamAllowed;
  191 +
  192 + return $attributes;
  193 + }
184 194
185 } 195 }
186 196
lib/api/ktcmis/objecttypes/CMISFolderObject.inc.php
@@ -50,34 +50,36 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;); @@ -50,34 +50,36 @@ require_once(CMIS_DIR . &#39;/util/CMISUtil.inc.php&#39;);
50 50
51 class CMISFolderObject extends CMISObject { 51 class CMISFolderObject extends CMISObject {
52 52
53 - private $ktapi;  
54 - private $uri; 53 + protected $ktapi;
55 54
56 public function __construct($folderId = null, &$ktapi = null, $uri = null) 55 public function __construct($folderId = null, &$ktapi = null, $uri = null)
57 { 56 {
58 $this->ktapi = $ktapi; 57 $this->ktapi = $ktapi;
59 - $this->uri = $uri;  
60 58
61 - $this->typeId = 'Folder'; // <repository-specific>  
62 - $this->queryName = 'Folder';  
63 - $this->displayName = ''; // <repository-specific>  
64 - $this->baseType = 'folder';  
65 - $this->baseTypeQueryName = 'Folder'; 59 + $this->id = 'cmis:folder'; // <repository-specific>
  60 + $this->localName = null; // <repository-specific>
  61 + $this->localNamespace = null; // <repository-specific>
  62 + $this->queryName = 'cmis:folder';
  63 + $this->displayName = 'Folder'; // <repository-specific>
  64 + $this->baseId = 'cmis:folder';
66 $this->parentId = null; // MUST NOT be set 65 $this->parentId = null; // MUST NOT be set
67 - $this->description = ''; // <repository-specific>  
68 - $this->creatable = ''; // <repository-specific> 66 + $this->description = null; // <repository-specific>
  67 + $this->creatable = true; // <repository-specific>
69 $this->fileable = true; 68 $this->fileable = true;
70 $this->queryable = true; // SHOULD be true 69 $this->queryable = true; // SHOULD be true
71 - $this->includedInSupertypeQuery = true; //  
72 - $this->controllable = ''; // <repository-specific>  
73 - 70 + $this->controllablePolicy = false; // <repository-specific>
  71 + $this->includedInSupertypeQuery = true; // <repository-specific>
  72 + $this->contentStreamAllowed = 'required'; // <repository-specific> notallowed/allowed/required
  73 + $this->controllableACL = false; // <repository-specific>
  74 + $this->fulltextIndexed = false; // <repository-specific>
  75 +
74 // properties 76 // properties
75 $this->properties = new CMISFolderPropertyCollection(); 77 $this->properties = new CMISFolderPropertyCollection();
76 78
77 if (!is_null($folderId)) 79 if (!is_null($folderId))
78 { 80 {
79 try { 81 try {
80 - $this->get($folderId); 82 + $this->_get($folderId);
81 } 83 }
82 catch (exception $e) { 84 catch (exception $e) {
83 throw new ObjectNotFoundException($e->getMessage()); 85 throw new ObjectNotFoundException($e->getMessage());
@@ -85,7 +87,8 @@ class CMISFolderObject extends CMISObject { @@ -85,7 +87,8 @@ class CMISFolderObject extends CMISObject {
85 } 87 }
86 } 88 }
87 89
88 - private function get($folderId) 90 + // TODO abstract shared stuff to base class where possible
  91 + private function _get($folderId)
89 { 92 {
90 $object = $this->ktapi->get_folder_by_id((int)$folderId); 93 $object = $this->ktapi->get_folder_by_id((int)$folderId);
91 94
@@ -109,9 +112,9 @@ class CMISFolderObject extends CMISObject { @@ -109,9 +112,9 @@ class CMISFolderObject extends CMISObject {
109 // $this->_setPropertyInternal('uri', $uri); 112 // $this->_setPropertyInternal('uri', $uri);
110 $this->_setPropertyInternal('uri', ''); 113 $this->_setPropertyInternal('uri', '');
111 // TODO what is this? Assuming it is the object type id, and not OUR document type? 114 // TODO what is this? Assuming it is the object type id, and not OUR document type?
112 - $this->_setPropertyInternal('objectTypeId', 'cmis:' . strtolower($this->getAttribute('typeId'))); 115 + $this->_setPropertyInternal('objectTypeId', strtolower($this->getAttribute('id')));
113 // Needed to distinguish type 116 // Needed to distinguish type
114 - $this->_setPropertyInternal('baseTypeId', 'cmis:' . strtolower($this->getAttribute('typeId'))); 117 + $this->_setPropertyInternal('baseTypeId', strtolower($this->getAttribute('id')));
115 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']); 118 $this->_setPropertyInternal('createdBy', $objectProperties['created_by']);
116 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by 119 // TODO cannot currently retrieve via ktapi or regular folder code - add as with created by
117 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']); 120 $this->_setPropertyInternal('creationDate', $objectProperties['created_date']);
lib/api/ktcmis/services/CMISObjectService.inc.php
@@ -64,7 +64,7 @@ class CMISObjectService { @@ -64,7 +64,7 @@ class CMISObjectService {
64 throw new ConstraintViolationException('Object base type could not be determined. ' . $e->getMessage()); 64 throw new ConstraintViolationException('Object base type could not be determined. ' . $e->getMessage());
65 } 65 }
66 66
67 - if ($typeDefinition['attributes']['baseType'] != 'document') 67 + if ($typeDefinition['attributes']['baseId'] != 'cmis:document')
68 { 68 {
69 throw new ConstraintViolationException('Object is not of base type document'); 69 throw new ConstraintViolationException('Object is not of base type document');
70 } 70 }
@@ -244,7 +244,7 @@ class CMISObjectService { @@ -244,7 +244,7 @@ class CMISObjectService {
244 throw new StorageException('The repository was unable to create the document. ' . $response['message']); 244 throw new StorageException('The repository was unable to create the document. ' . $response['message']);
245 } 245 }
246 else { 246 else {
247 - $objectId = CMISUtil::encodeObjectId('Document', $response['results']['document_id']); 247 + $objectId = CMISUtil::encodeObjectId(DOCUMENT, $response['results']['document_id']);
248 } 248 }
249 249
250 // remove temporary file 250 // remove temporary file
@@ -294,7 +294,7 @@ class CMISObjectService { @@ -294,7 +294,7 @@ class CMISObjectService {
294 throw new ConstraintViolationException('Object is not of base type folder. ' . $e->getMessage()); 294 throw new ConstraintViolationException('Object is not of base type folder. ' . $e->getMessage());
295 } 295 }
296 296
297 - if ($typeDefinition['attributes']['baseType'] != 'folder') { 297 + if ($typeDefinition['attributes']['baseId'] != 'cmis:folder') {
298 throw new ConstraintViolationException('Object is not of base type folder'); 298 throw new ConstraintViolationException('Object is not of base type folder');
299 } 299 }
300 300
@@ -322,7 +322,7 @@ class CMISObjectService { @@ -322,7 +322,7 @@ class CMISObjectService {
322 } 322 }
323 else 323 else
324 { 324 {
325 - $objectId = CMISUtil::encodeObjectId('Folder', $response['results']['id']); 325 + $objectId = CMISUtil::encodeObjectId(FOLDER, $response['results']['id']);
326 } 326 }
327 327
328 return $objectId; 328 return $objectId;
@@ -633,7 +633,7 @@ class CMISObjectService { @@ -633,7 +633,7 @@ class CMISObjectService {
633 // TODO consider sending back full properties on each object? 633 // TODO consider sending back full properties on each object?
634 // Not sure yet what this output may be used for by a client, and the current specification (0.61c) says: 634 // Not sure yet what this output may be used for by a client, and the current specification (0.61c) says:
635 // "A list of identifiers of objects in the folder tree that were not deleted", so let's leave it returning just ids for now. 635 // "A list of identifiers of objects in the folder tree that were not deleted", so let's leave it returning just ids for now.
636 - $failedToDelete[] = CMISUtil::encodeObjectId('Folder', $objectId); 636 + $failedToDelete[] = CMISUtil::encodeObjectId(FOLDER, $objectId);
637 $folderContents = $object->get_full_listing(); 637 $folderContents = $object->get_full_listing();
638 foreach($folderContents as $folderObject) 638 foreach($folderContents as $folderObject)
639 { 639 {
@@ -723,7 +723,7 @@ class CMISObjectService { @@ -723,7 +723,7 @@ class CMISObjectService {
723 } 723 }
724 // else 724 // else
725 // { 725 // {
726 -// $objectId = CMISUtil::encodeObjectId('Document', $response['results']['id']); 726 +// $objectId = CMISUtil::encodeObjectId(DOCUMENT, $response['results']['id']);
727 // } 727 // }
728 728
729 @unlink($csFile); 729 @unlink($csFile);
lib/api/ktcmis/services/CMISVersioningService.inc.php
@@ -117,7 +117,7 @@ class CMISVersioningService { @@ -117,7 +117,7 @@ class CMISVersioningService {
117 117
118 // if successful, set $contentCopied = true; unless contentStream is not set 118 // if successful, set $contentCopied = true; unless contentStream is not set
119 if ($pwc->getProperty('contentStreamFilename') != '') $contentCopied = true; 119 if ($pwc->getProperty('contentStreamFilename') != '') $contentCopied = true;
120 - $documentId = CMISUtil::encodeObjectId('Document', $documentId); 120 + $documentId = CMISUtil::encodeObjectId(DOCUMENT, $documentId);
121 121
122 // mark document object as checked out 122 // mark document object as checked out
123 $pwc->setProperty('isVersionSeriesCheckedOut', true); 123 $pwc->setProperty('isVersionSeriesCheckedOut', true);
lib/api/ktcmis/util/CMISUtil.inc.php
@@ -307,8 +307,11 @@ class CMISUtil { @@ -307,8 +307,11 @@ class CMISUtil {
307 * via var_export (which returns a useable PHP string for creating the object from array content) 307 * via var_export (which returns a useable PHP string for creating the object from array content)
308 * and regular expressions to extract the array definitions and structure without the class specific code 308 * and regular expressions to extract the array definitions and structure without the class specific code
309 * 309 *
310 - * NOTE this function is not reliable for objects which contain ktapi instances, as it appears there is a recursive reference  
311 - * TODO attempt to deal with recursive references? 310 + * NOTE this function is not reliable for objects which contain ktapi instances, as it appears there is a recursive reference;
  311 + * this will apply to any class which contains recursive references (which is bad practice and should not be done - the
  312 + * problem is with the object and not this code
  313 + *
  314 + * TODO attempt to deal with recursive references? - better to fix the objects in question, if possible
312 * 315 *
313 * @param object $data 316 * @param object $data
314 * @return array $array 317 * @return array $array
@@ -318,7 +321,7 @@ class CMISUtil { @@ -318,7 +321,7 @@ class CMISUtil {
318 $array = array(); 321 $array = array();
319 322
320 $stringdata = var_export($data, true); 323 $stringdata = var_export($data, true);
321 - // clean up ", )" - NOTE this may not be necessary 324 + // clean up ", )" - NOTE this may not be necessary, but is included for safety
322 $stringdata = preg_replace('/, *\r?\n? *\)/', ')', $stringdata); 325 $stringdata = preg_replace('/, *\r?\n? *\)/', ')', $stringdata);
323 326
324 // NOTE is this while loop even needed? 327 // NOTE is this while loop even needed?
@@ -351,14 +354,14 @@ class CMISUtil { @@ -351,14 +354,14 @@ class CMISUtil {
351 /** 354 /**
352 * Checks the contentStream and ensures that it is a correct base64 string; 355 * Checks the contentStream and ensures that it is a correct base64 string;
353 * This is purely for clients such as CMISSpaces breaking the content into 356 * This is purely for clients such as CMISSpaces breaking the content into
354 - * chunks before base64 encoding. 357 + * chunks before base64 encoding each and this coming through as a single string containing multiple base64 chunks.
355 * 358 *
356 * If the stream is chunked, it is decoded in chunks and sent back as a single stream. 359 * If the stream is chunked, it is decoded in chunks and sent back as a single stream.
357 * If it is not chunked it is decoded as is and sent back as a single stream. 360 * If it is not chunked it is decoded as is and sent back as a single stream.
358 * 361 *
359 * NOTE there is an alternative version of this function called decodeChunkedContentStreamLong. 362 * NOTE there is an alternative version of this function called decodeChunkedContentStreamLong.
360 * that version checks line lengths, which should not be necessary. 363 * that version checks line lengths, which should not be necessary.
361 - * this version merely splits on one or two "=" which is less complex and possibly faster (test this assumption) 364 + * this version merely splits on one or two "=" which is less complex and appears to be faster
362 * (one or two "=" signs is the specified padding used for base64 encoding at the end of an encoded string, when needed) 365 * (one or two "=" signs is the specified padding used for base64 encoding at the end of an encoded string, when needed)
363 * 366 *
364 * @param object $contentStream 367 * @param object $contentStream
@@ -394,7 +397,7 @@ class CMISUtil { @@ -394,7 +397,7 @@ class CMISUtil {
394 } 397 }
395 } 398 }
396 399
397 - // decode, append to output to be re-encoded 400 + // decode, append to output
398 $decoded .= base64_decode($part); 401 $decoded .= base64_decode($part);
399 } 402 }
400 403