GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 4e3a5f...45f3ef )
by
unknown
07:44
created

ObjectService::createDocumentFromSource()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 35
Code Lines 27

Duplication

Lines 5
Ratio 14.29 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 4
Bugs 0 Features 2
Metric Value
c 4
b 0
f 2
dl 5
loc 35
ccs 14
cts 14
cp 1
rs 8.5806
cc 4
eloc 27
nc 8
nop 9
crap 4

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
namespace Dkd\PhpCmis\Bindings\Browser;
3
4
/**
5
 * This file is part of php-cmis-lib.
6
 *
7
 * (c) Sascha Egerer <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
use Dkd\PhpCmis\Constants;
14
use Dkd\PhpCmis\Data\AclInterface;
15
use Dkd\PhpCmis\Data\AllowableActionsInterface;
16
use Dkd\PhpCmis\Data\BulkUpdateObjectIdAndChangeTokenInterface;
17
use Dkd\PhpCmis\Data\ExtensionDataInterface;
18
use Dkd\PhpCmis\Data\FailedToDeleteDataInterface;
19
use Dkd\PhpCmis\Data\ObjectDataInterface;
20
use Dkd\PhpCmis\Data\PropertiesInterface;
21
use Dkd\PhpCmis\Data\RenditionDataInterface;
22
use Dkd\PhpCmis\Enum\IncludeRelationships;
23
use Dkd\PhpCmis\Enum\UnfileObject;
24
use Dkd\PhpCmis\Enum\VersioningState;
25
use Dkd\PhpCmis\Exception\CmisInvalidArgumentException;
26
use Dkd\PhpCmis\ObjectServiceInterface;
27
use Dkd\PhpCmis\PropertyIds;
28
use Dkd\PhpCmis\SessionParameter;
29
use GuzzleHttp\Post\PostFile;
30
use GuzzleHttp\Stream\LimitStream;
31
use GuzzleHttp\Message\Response;
32
use GuzzleHttp\Stream\StreamInterface;
33
34
/**
35
 * Object Service Browser Binding client.
36
 */
37
class ObjectService extends AbstractBrowserBindingService implements ObjectServiceInterface
38
{
39
    /**
40
     * Appends the content stream to the content of the document.
41
     *
42
     * The stream in contentStream is consumed but not closed by this method.
43
     *
44
     * @param string $repositoryId the identifier for the repository
45
     * @param string $objectId The identifier for the object. The repository might return a different/new object id
46
     * @param StreamInterface $contentStream The content stream to append
47
     * @param boolean $isLastChunk Indicates if this content stream is the last chunk
48
     * @param string|null $changeToken The last change token of this object that the client received.
49
     *      The repository might return a new change token (default is <code>null</code>)
50
     * @param ExtensionDataInterface|null $extension
51
     */
52
    public function appendContentStream(
53
        $repositoryId,
54
        & $objectId,
55
        StreamInterface $contentStream,
56
        $isLastChunk,
57
        & $changeToken = null,
58
        ExtensionDataInterface $extension = null
59
    ) {
60
        // TODO: Implement appendContentStream() method.
61
    }
62
63
    /**
64
     * Updates properties and secondary types of one or more objects.
65
     *
66
     * @param string $repositoryId the identifier for the repository
67
     * @param BulkUpdateObjectIdAndChangeTokenInterface[] $objectIdsAndChangeTokens
68
     * @param PropertiesInterface $properties
69
     * @param string[] $addSecondaryTypeIds the secondary types to apply
70
     * @param string[] $removeSecondaryTypeIds the secondary types to remove
71
     * @param ExtensionDataInterface|null $extension
72
     * @return BulkUpdateObjectIdAndChangeTokenInterface[]
73
     */
74
    public function bulkUpdateProperties(
75
        $repositoryId,
76
        array $objectIdsAndChangeTokens,
77
        PropertiesInterface $properties,
78
        array $addSecondaryTypeIds,
79
        array $removeSecondaryTypeIds,
80
        ExtensionDataInterface $extension = null
81
    ) {
82
        // TODO: Implement bulkUpdateProperties() method.
83
    }
84
85
    /**
86
     * @param string $action
87
     * @param PropertiesInterface $properties
88
     * @param string[] $policies
89
     * @param AclInterface $addAces
0 ignored issues
show
Documentation introduced by
Should the type for parameter $addAces not be null|AclInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
90
     * @param AclInterface $removeAces
0 ignored issues
show
Documentation introduced by
Should the type for parameter $removeAces not be null|AclInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
91
     * @param ExtensionDataInterface $extension
0 ignored issues
show
Documentation introduced by
Should the type for parameter $extension not be null|ExtensionDataInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
92
     * @return array
93
     */
94
    protected function createQueryArray(
95
        $action,
96
        PropertiesInterface $properties,
97
        array $policies = array(),
98
        AclInterface $addAces = null,
99
        AclInterface $removeAces = null,
100
        ExtensionDataInterface $extension = null
0 ignored issues
show
Unused Code introduced by
The parameter $extension is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
101
    ) {
102
        $queryArray = array_replace(
103
            array(
104
                Constants::CONTROL_CMISACTION => $action,
105
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false',
106
            ),
107 3
            $this->convertPropertiesToQueryArray($properties),
108
            $this->convertPolicyIdArrayToQueryArray($policies)
109
        );
110
        if (!empty($removeAces)) {
111
            $queryArray = array_replace($queryArray, $this->convertAclToQueryArray(
112
                $removeAces,
113
                Constants::CONTROL_REMOVE_ACE_PRINCIPAL,
114
                Constants::CONTROL_REMOVE_ACE_PERMISSION
115
            ));
116
        }
117
        if (!empty($addAces)) {
118 3
            $queryArray = array_replace($queryArray, $this->convertAclToQueryArray(
119 1
                $addAces,
120 1
                Constants::CONTROL_ADD_ACE_PRINCIPAL,
121 2
                Constants::CONTROL_ADD_ACE_PERMISSION
122
            ));
123
        }
124
        return $queryArray;
125
    }
126
127
    /**
128 3
     * Creates a document object of the specified type (given by the cmis:objectTypeId property)
129 1
     * in the (optionally) specified location.
130 1
     *
131 1
     * @param string $repositoryId the identifier for the repository
132 1
     * @param PropertiesInterface $properties the property values that must be applied to the newly
133 1
     *      created document object
134 1
     * @param string|null $folderId if specified, the identifier for the folder that must be the parent
135
     *      folder for the newly created document object
136 3
     * @param StreamInterface|null $contentStream the content stream that must be stored for the newly
137
     *      created document object
138 3
     * @param VersioningState|null $versioningState specifies what the versioning state of the newly created object
139 3
     *      must be (default is <code>VersioningState::MAJOR</code>)
140
     * @param string[] $policies a list of policy IDs that must be applied to the newly created document object
141 3
     * @param AclInterface|null $addAces a list of ACEs that must be added to the newly created document object,
142 3
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
143 3
     * @param AclInterface|null $removeAces a list of ACEs that must be removed from the newly created document object,
144 3
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
145 3
     * @param ExtensionDataInterface|null $extension
146 2
     * @return string|null Returns the new object id or <code>null</code> if the repository sent an empty
147 2
     *      result (which should not happen)
148 2
     */
149
    public function createDocument(
150 2
        $repositoryId,
151 2
        PropertiesInterface $properties,
152 3
        $folderId = null,
153 2
        StreamInterface $contentStream = null,
154 2
        VersioningState $versioningState = null,
155 2
        array $policies = array(),
156
        AclInterface $addAces = null,
157 2
        AclInterface $removeAces = null,
158 2
        ExtensionDataInterface $extension = null
159 3
    ) {
160 2 View Code Duplication
        if ($folderId === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161 2
            $url = $this->getRepositoryUrl($repositoryId);
162 3
        } else {
163 3
            $url = $this->getObjectUrl($repositoryId, $folderId);
164
        }
165 3
166
        // Guzzle gets the mime type for a file by the filename extension. Sometimes the filename does not contain
167 3
        // the correct filename extension for example when a file is uploaded in php it gets a temporary name without
168
        // a file extension. If the filename does not contain a file extension we use the given 'cmis:name' property
169 3
        // as filename. See also https://github.com/guzzle/guzzle/issues/571
170
        if ($contentStream !== null && pathinfo($contentStream->getMetadata('uri'), PATHINFO_EXTENSION) === '') {
171
            $contentStream = new PostFile(
172
                'content',
173
                $contentStream,
174
                $properties->getProperties()['cmis:name']->getFirstValue()
175
            );
176
        }
177
178
        $queryArray = $this->createQueryArray(
179
            Constants::CMISACTION_CREATE_DOCUMENT,
180
            $properties,
181
            $policies,
182
            $addAces,
183
            $removeAces,
184
            $extension
185
        );
186
        if ($versioningState !== null) {
187
            $queryArray[Constants::PARAM_VERSIONING_STATE] = (string) $versioningState;
188
        }
189
        if ($contentStream) {
190
            $queryArray['content'] = $contentStream;
191
        }
192 2
        $responseData = $this->post(
193
            $url,
194
            $queryArray
195
        )->json();
196
197
        $newObject = $this->getJsonConverter()->convertObject($responseData);
198
199
        return ($newObject === null) ? null : $newObject->getId();
200
    }
201
202
    /**
203 2
     * Creates a document object as a copy of the given source document in the (optionally) specified location.
204
     *
205
     * @param string $repositoryId the identifier for the repository
206 2
     * @param string $sourceId the identifier for the source document
207
     * @param PropertiesInterface $properties the property values that must be applied to the newly
208
     *      created document object
209 2
     * @param string|null $folderId if specified, the identifier for the folder that must be the parent folder for the
210
     *      newly created document object
211 2
     * @param VersioningState|null $versioningState specifies what the versioning state of the newly created object
212 2
     *      must be (default is <code>VersioningState::MAJOR</code>)
213 2
     * @param string[] $policies a list of policy IDs that must be applied to the newly created document object
214 2
     * @param AclInterface|null $addAces a list of ACEs that must be added to the newly created document object,
215 2
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
216 2
     * @param AclInterface|null $removeAces a list of ACEs that must be removed from the newly created document object,
217 2
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
218 2
     * @param ExtensionDataInterface|null $extension
219 1
     * @return string|null Returns the new object id or <code>null</code> if the repository sent an empty
220 1
     *      result (which should not happen)
221 1
     */
222
    public function createDocumentFromSource(
223 1
        $repositoryId,
224 1
        $sourceId,
225 2
        PropertiesInterface $properties,
226 1
        $folderId = null,
227 1
        VersioningState $versioningState = null,
228 1
        array $policies = array(),
229
        AclInterface $addAces = null,
230 1
        AclInterface $removeAces = null,
231 1
        ExtensionDataInterface $extension = null
232 2
    ) {
233 1 View Code Duplication
        if ($folderId === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234 1
            $url = $this->getRepositoryUrl($repositoryId);
235 2
        } else {
236
            $url = $this->getObjectUrl($repositoryId, $folderId);
237 2
        }
238
239 2
        $queryArray = $this->createQueryArray(
240
            Constants::CMISACTION_CREATE_DOCUMENT_FROM_SOURCE,
241
            $properties,
242
            $policies,
243
            $addAces,
244
            $removeAces,
245
            $extension
246
        );
247
        $queryArray[Constants::PARAM_SOURCE_ID] = (string) $sourceId;
248
        if ($versioningState !== null) {
249
            $queryArray[Constants::PARAM_VERSIONING_STATE] = (string) $versioningState;
250
        }
251
        $responseData = $this->post($url, $queryArray)->json();
252
253
        $newObject = $this->getJsonConverter()->convertObject($responseData);
254
255
        return ($newObject === null) ? null : $newObject->getId();
256
    }
257
258
    /**
259
     * Creates a folder object of the specified type (given by the cmis:objectTypeId property) in
260 2
     * the specified location.
261
     *
262
     * @param string $repositoryId the identifier for the repository
263
     * @param PropertiesInterface $properties the property values that must be applied to the newly
264
     *      created document object
265
     * @param string $folderId if specified, the identifier for the folder that must be the parent folder for the
266
     *      newly created document object
267
     * @param string[] $policies a list of policy IDs that must be applied to the newly created document object
268
     * @param AclInterface|null $addAces a list of ACEs that must be added to the newly created document object,
269 2
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
270 2
     * @param AclInterface|null $removeAces a list of ACEs that must be removed from the newly created document object,
271
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
272 2
     * @param ExtensionDataInterface|null $extension
273 2
     * @return string|null Returns the new object id or <code>null</code> if the repository sent an empty
274 2
     *      result (which should not happen)
275 2
     */
276 View Code Duplication
    public function createFolder(
277 2
        $repositoryId,
278
        PropertiesInterface $properties,
279 2
        $folderId,
280 2
        array $policies = array(),
281 2
        AclInterface $addAces = null,
282
        AclInterface $removeAces = null,
283 2
        ExtensionDataInterface $extension = null
284
    ) {
285 2
        $url = $this->getObjectUrl($repositoryId, $folderId);
286
        $queryArray = $this->createQueryArray(
287 2
            Constants::CMISACTION_CREATE_FOLDER,
288
            $properties,
289
            $policies,
290
            $addAces,
291
            $removeAces,
292
            $extension
293
        );
294
295
        $responseData = $this->post($url, $queryArray)->json();
296
297
        $newObject = $this->getJsonConverter()->convertObject($responseData);
298
299
        return ($newObject === null) ? null : $newObject->getId();
300
    }
301
302
    /**
303
     * Creates an item object of the specified type (given by the cmis:objectTypeId property).
304
     *
305
     * @param string $repositoryId The identifier for the repository
306
     * @param PropertiesInterface $properties The property values that must be applied to the newly
307 2
     *      created document object
308
     * @param string|null $folderId If specified, the identifier for the folder that must be the parent folder for the
309
     *      newly created document object
310
     * @param string[] $policies A list of policy IDs that must be applied to the newly created document object
311
     * @param AclInterface|null $addAces A list of ACEs that must be added to the newly created document object,
312
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
313
     * @param AclInterface|null $removeAces A list of ACEs that must be removed from the newly created document object,
314
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
315
     * @param ExtensionDataInterface|null $extension
316 2
     * @return string|null Returns the new item id or <code>null</code> if the repository sent an empty
317
     *      result (which should not happen)
318
     */
319 2
    public function createItem(
320
        $repositoryId,
321
        PropertiesInterface $properties,
322 2
        $folderId = null,
323
        array $policies = array(),
324 2
        AclInterface $addAces = null,
325 2
        AclInterface $removeAces = null,
326 2
        ExtensionDataInterface $extension = null
327 2
    ) {
328
        if ($folderId === null) {
329 2
            $url = $this->getRepositoryUrl($repositoryId);
330
        } else {
331 2
            $url = $this->getObjectUrl($repositoryId, $folderId);
332 2
        }
333 2
334
        $queryArray = $this->createQueryArray(
335 2
            Constants::CMISACTION_CREATE_ITEM,
336
            $properties,
337 2
            $policies,
338
            $addAces,
339 2
            $removeAces,
340
            $extension
341
        );
342
343
        $responseData = $this->post($url, $queryArray)->json();
344
345
        $newObject = $this->getJsonConverter()->convertObject($responseData);
346
347
        return ($newObject === null) ? null : $newObject->getId();
348
    }
349
350
    /**
351
     * Creates a policy object of the specified type (given by the cmis:objectTypeId property).
352
     *
353
     * @param string $repositoryId The identifier for the repository
354
     * @param PropertiesInterface $properties The property values that must be applied to the newly
355
     *      created document object
356
     * @param string|null $folderId If specified, the identifier for the folder that must be the parent folder for the
357
     *      newly created document object
358
     * @param string[] $policies A list of policy IDs that must be applied to the newly created document object
359
     * @param AclInterface|null $addAces A list of ACEs that must be added to the newly created document object,
360
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
361
     * @param AclInterface|null $removeAces A list of ACEs that must be removed from the newly created document object,
362
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
363
     * @param ExtensionDataInterface|null $extension
364
     * @return string The id of the newly-created policy.
365
     */
366
    public function createPolicy(
367
        $repositoryId,
368
        PropertiesInterface $properties,
369
        $folderId = null,
370
        array $policies = array(),
371
        AclInterface $addAces = null,
372
        AclInterface $removeAces = null,
373
        ExtensionDataInterface $extension = null
374
    ) {
375
        // TODO: Implement createPolicy() method.
376
    }
377
378
    /**
379
     * Creates a relationship object of the specified type (given by the cmis:objectTypeId property).
380
     *
381
     * @param string $repositoryId the identifier for the repository
382
     * @param PropertiesInterface $properties the property values that must be applied to the newly
383
     *      created document object
384
     * @param string[] $policies a list of policy IDs that must be applied to the newly created document object
385
     * @param AclInterface|null $addAces a list of ACEs that must be added to the newly created document object,
386
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified
387
     * @param AclInterface|null $removeAces a list of ACEs that must be removed from the newly created document object,
388
     *      either using the ACL from folderId if specified, or being ignored if no folderId is specified
389
     * @param ExtensionDataInterface|null $extension
390
     * @return string|null Returns the new item id of the relationship object or <code>null</code> if the repository
391
     *      sent an empty result (which should not happen)
392
     */
393 View Code Duplication
    public function createRelationship(
394
        $repositoryId,
395
        PropertiesInterface $properties,
396
        array $policies = array(),
397
        AclInterface $addAces = null,
398
        AclInterface $removeAces = null,
399
        ExtensionDataInterface $extension = null
400
    ) {
401
        $url = $this->getRepositoryUrl($repositoryId);
402
403
        $queryArray = $this->createQueryArray(
404
            Constants::CMISACTION_CREATE_RELATIONSHIP,
405
            $properties,
406
            $policies,
407
            $addAces,
408
            $removeAces,
409
            $extension
410
        );
411
412
        $responseData = $this->post($url, $queryArray)->json();
413
414
        $newObject = $this->getJsonConverter()->convertObject($responseData);
415
416
        return ($newObject === null) ? null : $newObject->getId();
417
    }
418
419
    /**
420
     * Deletes the content stream for the specified document object.
421
     *
422
     * @param string $repositoryId the identifier for the repository
423
     * @param string $objectId the identifier for the object. The repository might return a different/new object id
424 3
     * @param string|null $changeToken the last change token of this object that the client received.
425
     *      The repository might return a new change token (default is <code>null</code>)
426
     * @param ExtensionDataInterface|null $extension
427
     * @throws CmisInvalidArgumentException If $objectId is empty
428
     */
429
    public function deleteContentStream(
430 3
        $repositoryId,
431
        & $objectId,
432
        & $changeToken = null,
433
        ExtensionDataInterface $extension = null
434 3
    ) {
435
        if (empty($objectId)) {
436 3
            throw new CmisInvalidArgumentException('Object id must not be empty!');
437
        }
438 3
439 3
        $url = $this->getObjectUrl($repositoryId, $objectId);
440 3
441 3
        $url->getQuery()->modify(
442
            array(
443 3
                Constants::CONTROL_CMISACTION => Constants::CMISACTION_DELETE_CONTENT,
444 1
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false'
445 1
            )
446
        );
447 3
448 3 View Code Duplication
        if ($changeToken !== null && !$this->getSession()->get(SessionParameter::OMIT_CHANGE_TOKENS, false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
449
            $url->getQuery()->modify(array(Constants::PARAM_CHANGE_TOKEN => $changeToken));
450
        }
451 3
452 3
        $responseData = $this->post($url)->json();
453 3
        $newObject = $this->getJsonConverter()->convertObject($responseData);
454 3
455 3
        // $objectId was passed by reference. The value is changed here to new object id
456 2
        $objectId = null;
457 View Code Duplication
        if ($newObject !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
458 2
            $objectId = $newObject->getId();
459 2
            $newObjectProperties = $newObject->getProperties()->getProperties();
460 3
            if ($changeToken !== null && count($newObjectProperties) > 0) {
461 3
                $newChangeToken = $newObjectProperties[PropertyIds::CHANGE_TOKEN];
462
                // $changeToken was passed by reference. The value is changed here
463
                $changeToken = $newChangeToken === null ? null : $newChangeToken->getFirstValue();
464
            }
465
        }
466
    }
467
468
    /**
469
     * Deletes the specified object.
470
     *
471
     * @param string $repositoryId the identifier for the repository
472 2
     * @param string $objectId the identifier for the object
473
     * @param boolean $allVersions If <code>true</code> then delete all versions of the document, otherwise delete only
474
     *      the document object specified (default is <code>true</code>)
475
     * @param ExtensionDataInterface|null $extension
476
     */
477
    public function deleteObject(
478 2
        $repositoryId,
479 2
        $objectId,
480
        $allVersions = true,
481 2
        ExtensionDataInterface $extension = null
482 2
    ) {
483
        $url = $this->getObjectUrl($repositoryId, $objectId);
484 2
        $url->getQuery()->modify(
485
            array(
486 2
                Constants::CONTROL_CMISACTION => Constants::CMISACTION_DELETE,
487 2
                Constants::PARAM_ALL_VERSIONS => $allVersions ? 'true' : 'false',
488
            )
489
        );
490
491
        $this->post($url);
492
    }
493
494
    /**
495
     * Deletes the specified folder object and all of its child- and descendant-objects.
496
     *
497
     * @param string $repositoryId the identifier for the repository
498
     * @param string $folderId the identifier for the folder
499
     * @param boolean $allVersions If <code>true</code> then delete all versions of the document, otherwise delete only
500
     *      the document object specified (default is <code>true</code>)
501
     * @param UnfileObject|null $unfileObjects defines how the repository must process file-able child- or
502
     *      descendant-objects (default is <code>UnfileObject::DELETE</code>)
503
     * @param boolean $continueOnFailure If <code>true</code>, then the repository should continue attempting to
504 4
     *      perform this operation even if deletion of a child- or descendant-object in the specified folder cannot
505
     *      be deleted
506
     * @param ExtensionDataInterface|null $extension
507
     * @return FailedToDeleteDataInterface Returns a list of object ids that could not be deleted
508
     */
509
    public function deleteTree(
510
        $repositoryId,
511
        $folderId,
512 4
        $allVersions = true,
513 4
        UnfileObject $unfileObjects = null,
514
        $continueOnFailure = false,
515 4
        ExtensionDataInterface $extension = null
516 4
    ) {
517 4
        $url = $this->getObjectUrl($repositoryId, $folderId);
518 4
        $url->getQuery()->modify(
519 4
            array(
520 4
                Constants::CONTROL_CMISACTION => Constants::CMISACTION_DELETE_TREE,
521
                Constants::PARAM_FOLDER_ID => $folderId,
522 4
                Constants::PARAM_ALL_VERSIONS => $allVersions ? 'true' : 'false',
523 1
                Constants::PARAM_CONTINUE_ON_FAILURE => $continueOnFailure ? 'true' : 'false'
524 1
            )
525
        );
526 4
527
        if ($unfileObjects !== null) {
528 4
            $url->getQuery()->modify(array(Constants::PARAM_UNFILE_OBJECTS => (string) $unfileObjects));
529
        }
530
531
        $response = $this->post($url);
532
533
        return $this->getJsonConverter()->convertFailedToDelete((array) $response->json());
534
    }
535
536
    /**
537
     * Gets the list of allowable actions for an object.
538
     *
539
     * @param string $repositoryId the identifier for the repository
540
     * @param string $objectId the identifier for the object
541
     * @param ExtensionDataInterface|null $extension
542
     * @return AllowableActionsInterface
543
     */
544
    public function getAllowableActions($repositoryId, $objectId, ExtensionDataInterface $extension = null)
545
    {
546
        // TODO: Implement getAllowableActions() method.
547
    }
548
549
    /**
550
     * Gets the content stream for the specified document object, or gets a rendition stream for
551
     * a specified rendition of a document or folder object.
552
     *
553
     * @param string $repositoryId the identifier for the repository
554
     * @param string $objectId the identifier for the object
555
     * @param string|null $streamId The identifier for the rendition stream, when used to get a rendition stream.
556
     *      For documents, if not provided then this method returns the content stream. For folders,
557
     *      it MUST be provided.
558
     * @param integer|null $offset
559 3
     * @param integer|null $length
560
     * @param ExtensionDataInterface|null $extension
561
     * @return StreamInterface|null
562
     * @throws CmisInvalidArgumentException If object id is empty
563
     */
564
    public function getContentStream(
565
        $repositoryId,
566
        $objectId,
567 3
        $streamId = null,
568
        $offset = null,
569
        $length = null,
570
        ExtensionDataInterface $extension = null
571 3
    ) {
572
        if (empty($objectId)) {
573 3
            throw new CmisInvalidArgumentException('Object id must not be empty!');
574 1
        }
575 1
576
        $url = $this->getObjectUrl($repositoryId, $objectId, Constants::SELECTOR_CONTENT);
577
578 3
        if ($streamId !== null) {
579
            $url->getQuery()->modify(array(Constants::PARAM_STREAM_ID => $streamId));
580 3
        }
581 3
582
        /** @var Response $response */
583
        $response = $this->getHttpInvoker()->get($url);
584
585 3
        $contentStream = $response->getBody();
586 1
        if (!$contentStream instanceof StreamInterface) {
587 1
            return null;
588
        }
589 3
590
        if ($offset !== null) {
591
            $contentStream = new LimitStream($contentStream, $length !== null ? $length : - 1, $offset);
592
        }
593
594
        return $contentStream;
595
    }
596
597
    /**
598
     * Gets the specified information for the object specified by id.
599
     *
600
     * @param string $repositoryId the identifier for the repository
601
     * @param string $objectId the identifier for the object
602
     * @param string|null $filter a comma-separated list of query names that defines which properties must be
603
     *      returned by the repository (default is repository specific)
604
     * @param boolean $includeAllowableActions if <code>true</code>, then the repository must return the allowable
605
     *      actions for the object (default is <code>false</code>)
606
     * @param IncludeRelationships|null $includeRelationships indicates what relationships in which the objects
607
     *      participate must be returned (default is <code>IncludeRelationships::NONE</code>)
608
     * @param string $renditionFilter indicates what set of renditions the repository must return whose kind
609
     *      matches this filter (default is "cmis:none")
610
     * @param boolean $includePolicyIds if <code>true</code>, then the repository must return the policy ids for
611
     *      the object (default is <code>false</code>)
612
     * @param boolean $includeAcl if <code>true</code>, then the repository must return the ACL for the object
613 3
     *      (default is <code>false</code>)
614
     * @param ExtensionDataInterface|null $extension
615
     * @return ObjectDataInterface|null Returns object of type ObjectDataInterface or <code>null</code>
616
     *     if the repository response was empty
617
     */
618 View Code Duplication
    public function getObject(
619
        $repositoryId,
620
        $objectId,
621
        $filter = null,
622
        $includeAllowableActions = false,
623
        IncludeRelationships $includeRelationships = null,
624 3
        $renditionFilter = Constants::RENDITION_NONE,
625 3
        $includePolicyIds = false,
626
        $includeAcl = false,
627 3
        ExtensionDataInterface $extension = null
628 3
    ) {
629 3
        $url = $this->getObjectUrl($repositoryId, $objectId, Constants::SELECTOR_OBJECT);
630 3
        $url->getQuery()->modify(
631 3
            array(
632 3
                Constants::PARAM_ALLOWABLE_ACTIONS => $includeAllowableActions ? 'true' : 'false',
633 3
                Constants::PARAM_RENDITION_FILTER => $renditionFilter,
634 3
                Constants::PARAM_POLICY_IDS => $includePolicyIds ? 'true' : 'false',
635
                Constants::PARAM_ACL => $includeAcl ? 'true' : 'false',
636 3
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false',
637 2
                Constants::PARAM_DATETIME_FORMAT => (string) $this->getDateTimeFormat()
638 2
            )
639
        );
640 3
641 2
        if (!empty($filter)) {
642 2
            $url->getQuery()->modify(array(Constants::PARAM_FILTER => (string) $filter));
643
        }
644 3
645
        if ($includeRelationships !== null) {
646
            $url->getQuery()->modify(array(Constants::PARAM_RELATIONSHIPS => (string) $includeRelationships));
647 3
        }
648
649
        $responseData = $this->read($url)->json();
650
651
        // TODO: Implement Cache
652
        return $this->getJsonConverter()->convertObject($responseData);
653
    }
654
655
    /**
656
     * Gets the specified information for the object specified by path.
657
     *
658
     * @param string $repositoryId the identifier for the repository
659
     * @param string $path the path to the object
660
     * @param string|null $filter a comma-separated list of query names that defines which properties must be
661
     *      returned by the repository (default is repository specific)
662
     * @param boolean $includeAllowableActions if <code>true</code>, then the repository must return the allowable
663
     *      actions for the object (default is <code>false</code>)
664
     * @param IncludeRelationships|null $includeRelationships indicates what relationships in which the objects
665
     *      participate must be returned (default is <code>IncludeRelationships::NONE</code>)
666
     * @param string $renditionFilter indicates what set of renditions the repository must return whose kind
667
     *      matches this filter (default is "cmis:none")
668
     * @param boolean $includePolicyIds if <code>true</code>, then the repository must return the policy ids for
669
     *      the object (default is <code>false</code>)
670
     * @param boolean $includeAcl if <code>true</code>, then the repository must return the ACL for the object
671 3
     *      (default is <code>false</code>)
672
     * @param ExtensionDataInterface|null $extension
673
     * @return ObjectDataInterface|null Returns object of type <code>ObjectDataInterface</code> or <code>null</code>
674
     *      if the repository response was empty
675
     */
676 View Code Duplication
    public function getObjectByPath(
677
        $repositoryId,
678
        $path,
679
        $filter = null,
680
        $includeAllowableActions = false,
681
        IncludeRelationships $includeRelationships = null,
682 3
        $renditionFilter = Constants::RENDITION_NONE,
683 3
        $includePolicyIds = false,
684
        $includeAcl = false,
685 3
        ExtensionDataInterface $extension = null
686 3
    ) {
687 3
        $url = $this->getPathUrl($repositoryId, $path, Constants::SELECTOR_OBJECT);
688 3
        $url->getQuery()->modify(
689 3
            array(
690 3
                Constants::PARAM_ALLOWABLE_ACTIONS => $includeAllowableActions ? 'true' : 'false',
691 3
                Constants::PARAM_RENDITION_FILTER => $renditionFilter,
692 3
                Constants::PARAM_POLICY_IDS => $includePolicyIds ? 'true' : 'false',
693
                Constants::PARAM_ACL => $includeAcl ? 'true' : 'false',
694 3
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false',
695 2
                Constants::PARAM_DATETIME_FORMAT => (string) $this->getDateTimeFormat()
696 2
            )
697
        );
698 3
699 2
        if (!empty($filter)) {
700 2
            $url->getQuery()->modify(array(Constants::PARAM_FILTER => (string) $filter));
701
        }
702 3
703
        if ($includeRelationships !== null) {
704
            $url->getQuery()->modify(array(Constants::PARAM_RELATIONSHIPS => (string) $includeRelationships));
705 3
        }
706
707
        $responseData = $this->read($url)->json();
708
709
        // TODO Implement Cache
710
        return $this->getJsonConverter()->convertObject($responseData);
711
    }
712
713
    /**
714
     * Gets the list of properties for an object.
715
     *
716
     * @param string $repositoryId the identifier for the repository
717
     * @param string $objectId the identifier for the object
718 2
     * @param string|null $filter a comma-separated list of query names that defines which properties must be
719
     *      returned by the repository (default is repository specific)
720
     * @param ExtensionDataInterface|null $extension
721
     * @return PropertiesInterface
722
     */
723
    public function getProperties(
724 2
        $repositoryId,
725 2
        $objectId,
726
        $filter = null,
727 2
        ExtensionDataInterface $extension = null
728 2
    ) {
729 2
        $url = $this->getObjectUrl($repositoryId, $objectId, Constants::SELECTOR_PROPERTIES);
730 2
        $url->getQuery()->modify(
731
            array(
732 2
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false',
733 1
                Constants::PARAM_DATETIME_FORMAT => (string) $this->getDateTimeFormat()
734 1
            )
735
        );
736 2
737
        if (!empty($filter)) {
738
            $url->getQuery()->modify(array(Constants::PARAM_FILTER => (string) $filter));
739 2
        }
740
741
        $responseData = $this->read($url)->json();
742 2
743
        // TODO: Implement Cache
744
        if ($this->getSuccinct()) {
745
            return $this->getJsonConverter()->convertSuccinctProperties($responseData);
746
        } else {
747
            return $this->getJsonConverter()->convertProperties($responseData);
748
        }
749
    }
750
751
    /**
752
     * Gets the list of associated renditions for the specified object.
753
     * Only rendition attributes are returned, not rendition stream.
754
     *
755
     * @param string $repositoryId the identifier for the repository
756
     * @param string $objectId the identifier for the object
757
     * @param string $renditionFilter indicates what set of renditions the repository must return whose kind
758
     *      matches this filter (default is "cmis:none")
759
     * @param integer|null $maxItems the maximum number of items to return in a response
760
     *       (default is repository specific)
761
     * @param integer $skipCount number of potential results that the repository MUST skip/page over before
762 2
     *      returning any results (default is 0)
763
     * @param ExtensionDataInterface|null $extension
764
     * @return RenditionDataInterface[]
765
     * @throws CmisInvalidArgumentException If object id is empty or skip count not of type integer
766
     */
767
    public function getRenditions(
768
        $repositoryId,
769
        $objectId,
770 2
        $renditionFilter = Constants::RENDITION_NONE,
771
        $maxItems = null,
772
        $skipCount = 0,
773
        ExtensionDataInterface $extension = null
774 2
    ) {
775
        if (empty($objectId)) {
776
            throw new CmisInvalidArgumentException('Object id must not be empty!');
777
        }
778 2
779 2
        if (!is_int($skipCount)) {
780
            throw new CmisInvalidArgumentException('Skip count must be of type integer!');
781 2
        }
782 2
783
        $url = $this->getObjectUrl($repositoryId, $objectId, Constants::SELECTOR_RENDITIONS);
784 2
        $url->getQuery()->modify(
785
            array(
786 2
                Constants::PARAM_RENDITION_FILTER => $renditionFilter,
787 1
                Constants::PARAM_SKIP_COUNT => (string) $skipCount,
788 1
            )
789
        );
790 2
791
        if ($maxItems !== null) {
792 2
            $url->getQuery()->modify(array(Constants::PARAM_MAX_ITEMS => (string) $maxItems));
793
        }
794
795
        $responseData = $this->read($url)->json();
796
797
        return $this->getJsonConverter()->convertRenditions($responseData);
798
    }
799
800
    /**
801
     * Moves the specified file-able object from one folder to another.
802
     *
803
     * @param string $repositoryId the identifier for the repository
804
     * @param string $objectId the identifier for the object. The repository might return a different/new object id
805
     * @param string $targetFolderId the identifier for the target folder
806 1
     * @param string $sourceFolderId the identifier for the source folder
807
     * @param ExtensionDataInterface|null $extension
808
     * @return ObjectDataInterface|null Returns object of type ObjectDataInterface or <code>null</code>
809
     *     if the repository response was empty
810
     */
811
    public function moveObject(
812
        $repositoryId,
813 1
        & $objectId,
814 1
        $targetFolderId,
815
        $sourceFolderId,
816 1
        ExtensionDataInterface $extension = null
817 1
    ) {
818 1
        $url = $this->getObjectUrl($repositoryId, $objectId);
819 1
        $url->getQuery()->modify(
820 1
            array(
821 1
                Constants::CONTROL_CMISACTION => Constants::CMISACTION_MOVE,
822
                Constants::PARAM_TARGET_FOLDER_ID => $targetFolderId,
823 1
                Constants::PARAM_SOURCE_FOLDER_ID => $sourceFolderId,
824 1
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false'
825
            )
826
        );
827 1
828
        $responseData = $this->post($url)->json();
829 1
        $newObject = $this->getJsonConverter()->convertObject($responseData);
830
831
        // $objectId was passed by reference. The value is changed here to new object id
832
        $objectId = ($newObject === null) ? null : $newObject->getId();
833
834
        return $newObject;
835
    }
836
837
    /**
838
     * Sets the content stream for the specified document object.
839
     *
840
     * @param string $repositoryId The identifier for the repository
841
     * @param string $objectId The identifier for the object. The repository might return a different/new object id
842
     * @param StreamInterface $contentStream The content stream
843
     * @param boolean $overwriteFlag If <code>true</code>, then the repository must replace the existing content stream
844
     *      for the object (if any) with the input content stream. If <code>false</code>, then the repository must
845
     *      only set the input content stream for the object if the object currently does not have a content stream
846
     *      (default is <code>true</code>)
847 3
     * @param string|null $changeToken The last change token of this object that the client received.
848
     *      The repository might return a new change token (default is <code>null</code>)
849
     * @param ExtensionDataInterface|null $extension
850
     * @throws CmisInvalidArgumentException If object id is empty
851
     */
852
    public function setContentStream(
853
        $repositoryId,
854
        & $objectId,
855 3
        StreamInterface $contentStream,
856
        $overwriteFlag = true,
857
        & $changeToken = null,
858
        ExtensionDataInterface $extension = null
859 3
    ) {
860
        if (empty($objectId)) {
861 3
            throw new CmisInvalidArgumentException('Object id must not be empty!');
862
        }
863 3
864 3
        $url = $this->getObjectUrl($repositoryId, $objectId);
865 3
866 3
        $url->getQuery()->modify(
867 3
            array(
868
                Constants::CONTROL_CMISACTION => Constants::CMISACTION_SET_CONTENT,
869 3
                Constants::PARAM_OVERWRITE_FLAG => $overwriteFlag ? 'true' : 'false',
870 1
                Constants::PARAM_SUCCINCT => $this->getSuccinct() ? 'true' : 'false'
871 1
            )
872
        );
873 3
874 3 View Code Duplication
        if ($changeToken !== null && !$this->getSession()->get(SessionParameter::OMIT_CHANGE_TOKENS, false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
875
            $url->getQuery()->modify(array(Constants::PARAM_CHANGE_TOKEN => $changeToken));
876 3
        }
877
878 3
        $responseData = $this->post(
879
            $url,
880
            array('content' => $contentStream)
881 3
        )->json();
882 3
883 3
        $newObject = $this->getJsonConverter()->convertObject($responseData);
884 3
885 3
        // $objectId was passed by reference. The value is changed here to new object id
886 2
        $objectId = null;
887 View Code Duplication
        if ($newObject !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
888 2
            $objectId = $newObject->getId();
889 2
            $newObjectProperties = $newObject->getProperties()->getProperties();
890 3
            if ($changeToken !== null && count($newObjectProperties) > 0) {
891 3
                $newChangeToken = $newObjectProperties[PropertyIds::CHANGE_TOKEN];
892
                // $changeToken was passed by reference. The value is changed here
893
                $changeToken = $newChangeToken === null ? null : $newChangeToken->getFirstValue();
894
            }
895
        }
896
    }
897
898
    /**
899
     * Updates properties of the specified object.
900
     *
901
     * @param string $repositoryId The identifier for the repository
902
     * @param string $objectId The identifier for the object. The repository might return a different/new object id
903
     * @param PropertiesInterface $properties The updated property values that must be applied to the object
904 3
     * @param string|null $changeToken The last change token of this object that the client received.
905
     *      The repository might return a new change token (default is <code>null</code>)
906
     * @param ExtensionDataInterface|null $extension
907
     * @throws CmisInvalidArgumentException If $objectId is empty
908
     */
909
    public function updateProperties(
910
        $repositoryId,
911 3
        & $objectId,
912
        PropertiesInterface $properties,
913
        & $changeToken = null,
914
        ExtensionDataInterface $extension = null
915 3
    ) {
916
        if (empty($objectId)) {
917 3
            throw new CmisInvalidArgumentException('Object id must not be empty!');
918 1
        }
919 1
920
        $url = $this->getObjectUrl($repositoryId, $objectId);
921 3
922 3 View Code Duplication
        if ($changeToken !== null && !$this->getSession()->get(SessionParameter::OMIT_CHANGE_TOKENS, false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
923 3
            $url->getQuery()->modify(array(Constants::PARAM_CHANGE_TOKEN => $changeToken));
924 3
        }
925 3
926
        $queryArray = $this->convertPropertiesToQueryArray($properties);
927
        $queryArray[Constants::CONTROL_CMISACTION] = Constants::CMISACTION_UPDATE_PROPERTIES;
928 3
        $queryArray[Constants::PARAM_SUCCINCT] = $this->getSuccinct() ? 'true' : 'false';
929 3
        $responseData = $this->post($url, $queryArray)->json();
930 3
        $newObject = $this->getJsonConverter()->convertObject($responseData);
931 3
932 3
        // $objectId was passed by reference. The value is changed here to new object id
933 2
        $objectId = null;
934 View Code Duplication
        if ($newObject !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
935 2
            $objectId = $newObject->getId();
936 2
            $newObjectProperties = $newObject->getProperties()->getProperties();
937 3
            if ($changeToken !== null && count($newObjectProperties) > 0) {
938 3
                $newChangeToken = $newObjectProperties[PropertyIds::CHANGE_TOKEN];
939
                // $changeToken was passed by reference. The value is changed here
940
                $changeToken = $newChangeToken === null ? null : $newChangeToken->getFirstValue();
941
            }
942
        }
943
    }
944
}
945