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 ( 42c65a...a98f71 )
by
unknown
07:18
created

Session   F

Complexity

Total Complexity 103

Size/Duplication

Total Lines 1267
Duplicated Lines 5.13 %

Coupling/Cohesion

Components 2
Dependencies 26

Test Coverage

Coverage 22.85%

Importance

Changes 31
Bugs 11 Features 6
Metric Value
wmc 103
c 31
b 11
f 6
lcom 2
cbo 26
dl 65
loc 1267
ccs 93
cts 407
cp 0.2285
rs 0.5217

50 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 46 8
B createObjectFactory() 0 23 4
A createDefaultObjectFactoryInstance() 0 4 1
B createCache() 0 27 4
A createDefaultCacheInstance() 0 4 1
A getCache() 0 4 1
A applyAcl() 0 8 1
A applyPolicies() 0 4 1
A bulkUpdateProperties() 0 8 1
A clear() 0 4 1
B createDocument() 0 36 4
B createDocumentFromSource() 0 49 6
A createFolder() 23 23 2
A createItem() 23 23 2
A createObjectId() 0 4 1
B createOperationContext() 0 30 3
A createPolicy() 0 9 1
A createQueryStatement() 0 15 3
B createRelationship() 0 24 3
A createType() 10 10 2
A delete() 0 9 1
A deleteType() 9 9 2
A getAcl() 0 4 1
A getBinding() 0 4 1
A getCheckedOutDocs() 0 4 1
A getCmisBindingHelper() 0 4 1
A getContentChanges() 0 21 2
A getContentStream() 0 12 2
A getDefaultContext() 0 4 1
A getLatestChangeLogToken() 0 4 1
A getLatestDocumentVersion() 0 7 1
A getLocale() 0 4 1
B getObject() 0 33 4
B getObjectByPath() 0 29 4
A getObjectFactory() 0 4 1
A getRelationships() 0 22 2
A getRepositoryInfo() 0 4 1
A getRepositoryId() 0 4 1
A getRootFolder() 0 15 3
A getTypeChildren() 0 10 1
A getTypeDefinition() 0 10 1
A getTypeDescendants() 0 9 1
B query() 0 35 5
B queryObjects() 0 60 8
A removeObjectFromCache() 0 4 1
A removePolicy() 0 4 1
A setAcl() 0 4 1
A setDefaultContext() 0 4 1
A updateType() 0 4 1
A convertTypeDefinition() 0 5 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Session often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Session, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Dkd\PhpCmis;
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\Bindings\CmisBindingInterface;
14
use Dkd\PhpCmis\Bindings\CmisBindingsHelper;
15
use Dkd\PhpCmis\CmisObject\CmisObjectInterface;
16
use Dkd\PhpCmis\Data\AceInterface;
17
use Dkd\PhpCmis\Data\AclInterface;
18
use Dkd\PhpCmis\Data\BulkUpdateObjectIdAndChangeTokenInterface;
19
use Dkd\PhpCmis\Data\DocumentInterface;
20
use Dkd\PhpCmis\Data\FolderInterface;
21
use Dkd\PhpCmis\Data\ObjectDataInterface;
22
use Dkd\PhpCmis\Data\ObjectIdInterface;
23
use Dkd\PhpCmis\Data\ObjectTypeInterface;
24
use Dkd\PhpCmis\Data\PolicyInterface;
25
use Dkd\PhpCmis\Data\RelationshipInterface;
26
use Dkd\PhpCmis\Data\RepositoryInfoInterface;
27
use Dkd\PhpCmis\DataObjects\ObjectId;
28
use Dkd\PhpCmis\Definitions\TypeDefinitionContainerInterface;
29
use Dkd\PhpCmis\Definitions\TypeDefinitionInterface;
30
use Dkd\PhpCmis\Definitions\TypeDefinitionListInterface;
31
use Dkd\PhpCmis\Enum\AclPropagation;
32
use Dkd\PhpCmis\Enum\BaseTypeId;
33
use Dkd\PhpCmis\Enum\CmisVersion;
34
use Dkd\PhpCmis\Enum\IncludeRelationships;
35
use Dkd\PhpCmis\Enum\RelationshipDirection;
36
use Dkd\PhpCmis\Enum\Updatability;
37
use Dkd\PhpCmis\Enum\VersioningState;
38
use Dkd\PhpCmis\Exception\CmisInvalidArgumentException;
39
use Dkd\PhpCmis\Exception\CmisNotSupportedException;
40
use Dkd\PhpCmis\Exception\CmisObjectNotFoundException;
41
use Dkd\PhpCmis\Exception\CmisRuntimeException;
42
use Dkd\PhpCmis\Exception\IllegalStateException;
43
use Doctrine\Common\Cache\ArrayCache;
44
use Doctrine\Common\Cache\Cache;
45
use Doctrine\Common\Cache\CacheProvider;
46
use GuzzleHttp\Stream\StreamInterface;
47
48
/**
49
 * Class Session
50
 *
51
 * @author Sascha Egerer <[email protected]>
52
 */
53
class Session implements SessionInterface
54
{
55
    /**
56
     * @var CmisBindingInterface
57
     */
58
    protected $binding;
59
60
    /**
61
     * @var Cache
62
     */
63
    protected $cache;
64
65
    /**
66
     * @var OperationContextInterface
67
     */
68
    private $defaultContext;
69
70
    /**
71
     * @var CmisBindingsHelper
72
     */
73
    protected $cmisBindingHelper;
74
75
    /**
76
     * @var ObjectFactoryInterface
77
     */
78
    private $objectFactory;
79
80
    /**
81
     * @var RepositoryInfoInterface
82
     */
83
    protected $repositoryInfo;
84
85
    /**
86
     * @var array
87
     */
88
    protected $parameters = array();
89
90
    /**
91
     * @var Cache
92
     */
93
    protected $typeDefinitionCache;
94
95
    /**
96
     * @var Cache
97
     */
98
    protected $objectTypeCache;
99
100
    /**
101
     * @var Updatability[]
102
     */
103
    protected static $createUpdatability = array();
104
105
    /**
106
     * @var Updatability[]
107
     */
108
    protected static $createAndCheckoutUpdatability = array();
109
110
    /**
111
     * @param array $parameters
112
     * @param ObjectFactoryInterface|null $objectFactory
113
     * @param Cache|null $cache
114
     * @param Cache|null $typeDefinitionCache
115
     * @param Cache|null $objectTypeCache
116
     * @param CmisBindingsHelper|null $cmisBindingHelper
117
     * @throws CmisInvalidArgumentException
118
     * @throws IllegalStateException
119
     */
120 11
    public function __construct(
121
        array $parameters,
122
        ObjectFactoryInterface $objectFactory = null,
123
        Cache $cache = null,
124
        Cache $typeDefinitionCache = null,
125
        Cache $objectTypeCache = null,
126
        CmisBindingsHelper $cmisBindingHelper = null
127
    ) {
128 11
        if (empty($parameters)) {
129 1
            throw new CmisInvalidArgumentException('No parameters provided!', 1408115280);
130
        }
131
132 10
        $this->parameters = $parameters;
133 10
        $this->objectFactory = $objectFactory === null ? $this->createObjectFactory() : $objectFactory;
134 9
        $this->cache = $cache === null ? $this->createCache() : $cache;
135 8
        $this->typeDefinitionCache = $typeDefinitionCache === null ? $this->createCache() : $typeDefinitionCache;
136 8
        $this->objectTypeCache = $objectTypeCache === null ? $this->createCache() : $objectTypeCache;
137 8
        $this->cmisBindingHelper = $cmisBindingHelper === null ? new CmisBindingsHelper() : $cmisBindingHelper;
138
139 8
        $this->defaultContext = new OperationContext();
140 8
        $this->defaultContext->setCacheEnabled(true);
141
142 8
        $this->binding = $this->getCmisBindingHelper()->createBinding(
143 8
            $this->parameters,
144 8
            $this->typeDefinitionCache
145 8
        );
146
147 8
        if (!isset($this->parameters[SessionParameter::REPOSITORY_ID])) {
148
            throw new IllegalStateException('Repository ID is not set!');
149
        }
150
151 8
        $this->repositoryInfo = $this->getBinding()->getRepositoryService()->getRepositoryInfo(
152 8
            $this->parameters[SessionParameter::REPOSITORY_ID]
153 8
        );
154
155 8
        self::$createUpdatability = array(
156 8
            Updatability::cast(Updatability::ONCREATE),
157 8
            Updatability::cast(Updatability::READWRITE)
158 8
        );
159
160 8
        self::$createAndCheckoutUpdatability = array(
161 8
            Updatability::cast(Updatability::ONCREATE),
162 8
            Updatability::cast(Updatability::READWRITE),
163 8
            Updatability::cast(Updatability::WHENCHECKEDOUT)
164 8
        );
165 8
    }
166
167
    /**
168
     * Create an object factory based on the SessionParameter::OBJECT_FACTORY_CLASS. If not set it returns an instance
169
     * of ObjectFactory.
170
     *
171
     * @return ObjectFactoryInterface
172
     * @throws \RuntimeException
173
     */
174 9
    protected function createObjectFactory()
175
    {
176
        try {
177 9
            if (isset($this->parameters[SessionParameter::OBJECT_FACTORY_CLASS])) {
178 2
                $objectFactoryClass = new $this->parameters[SessionParameter::OBJECT_FACTORY_CLASS];
179 2
            } else {
180 7
                $objectFactoryClass = $this->createDefaultObjectFactoryInstance();
181
            }
182
183 9
            if (!($objectFactoryClass instanceof ObjectFactoryInterface)) {
184 1
                throw new \RuntimeException('Class does not implement ObjectFactoryInterface!', 1408354119);
185
            }
186
187 8
            $objectFactoryClass->initialize($this, $this->parameters);
188
189 8
            return $objectFactoryClass;
190 1
        } catch (\Exception $exception) {
191 1
            throw new \RuntimeException(
192 1
                'Unable to create object factory: ' . $exception,
193
                1408354120
194 1
            );
195
        }
196
    }
197
198
    /**
199
     * Returns an instance of the ObjectFactory.
200
     * This methods is primarily required for unit testing.
201
     *
202
     * @return ObjectFactory
203
     */
204 6
    protected function createDefaultObjectFactoryInstance()
205
    {
206 6
        return new ObjectFactory();
207
    }
208
209
    /**
210
     * Create a cache instance based on the given session parameter SessionParameter::CACHE_CLASS.
211
     * If no session parameter SessionParameter::CACHE_CLASS is defined, the default Cache implementation will be used.
212
     *
213
     * @return Cache
214
     * @throws \InvalidArgumentException
215
     */
216 9
    protected function createCache()
217
    {
218
        try {
219 9
            if (isset($this->parameters[SessionParameter::CACHE_CLASS])) {
220 2
                $cache = new $this->parameters[SessionParameter::CACHE_CLASS];
221 2
            } else {
222 7
                $cache = $this->createDefaultCacheInstance();
223
            }
224
225 9
            if (!($cache instanceof CacheProvider)) {
226 1
                throw new \RuntimeException(
227 1
                    sprintf(
228 1
                        'Class %s does not subclass \\Doctrine\\Common\\Cache\\CacheProvider!',
229 1
                        get_class($cache)
230 1
                    ),
231
                    1408354124
232 1
                );
233
            }
234
235 8
            return $cache;
236 1
        } catch (\Exception $exception) {
237 1
            throw new CmisInvalidArgumentException(
238 1
                'Unable to create cache: ' . $exception,
239
                1408354123
240 1
            );
241
        }
242
    }
243
244
    /**
245
     * Returns an instance of the Doctrine ArrayCache.
246
     * This methods is primarily required for unit testing.
247
     *
248
     * @return CacheProvider
249
     */
250 7
    protected function createDefaultCacheInstance()
251
    {
252 7
        return new ArrayCache();
253
    }
254
255
    /**
256
     * Get the cache instance
257
     *
258
     * @return CacheProvider
259
     */
260 3
    public function getCache()
261
    {
262 3
        return $this->cache;
263
    }
264
265
    /**
266
     * Applies ACL changes to an object and dependent objects. Only direct ACEs can be added and removed.
267
     *
268
     * @param ObjectIdInterface $objectId the ID the object
269
     * @param AceInterface[] $addAces of ACEs to be added or <code>null</code> if no ACEs should be added
270
     * @param AceInterface[] $removeAces list of ACEs to be removed or <code>null</code> if no ACEs should be removed
271
     * @param AclPropagation|null $aclPropagation value that defines the propagation of the ACE changes;
272
     *      <code>null</code> is equal to AclPropagation.REPOSITORYDETERMINED
273
     * @return AclInterface the new ACL of the object
274
     */
275
    public function applyAcl(
276
        ObjectIdInterface $objectId,
277
        $addAces = array(),
278
        $removeAces = array(),
279
        AclPropagation $aclPropagation = null
280
    ) {
281
        // TODO: Implement applyAcl() method.
282
    }
283
284
    /**
285
     * Applies a set of policies to an object.
286
     *
287
     * @param ObjectIdInterface $objectId the ID the object
288
     * @param ObjectIdInterface[] $policyIds the IDs of the policies to be applied
289
     * @return mixed
290
     */
291
    public function applyPolicies(ObjectIdInterface $objectId, array $policyIds)
292
    {
293
        // TODO: Implement applyPolicy() method.
294
    }
295
296
    /**
297
     * Updates multiple objects in one request.
298
     *
299
     * @param CmisObjectInterface[] $objects
300
     * @param mixed[] $properties
301
     * @param string[] $addSecondaryTypeIds
302
     * @param string[] $removeSecondaryTypeIds
303
     * @return BulkUpdateObjectIdAndChangeTokenInterface[]
304
     */
305
    public function bulkUpdateProperties(
306
        array $objects,
307
        array $properties,
308
        array $addSecondaryTypeIds,
309
        array $removeSecondaryTypeIds
310
    ) {
311
        // TODO: Implement bulkUpdateProperties() method.
312
    }
313
314
    /**
315
     * Clears all cached data.
316
     */
317
    public function clear()
318
    {
319
        $this->getCache()->flushAll();
320
    }
321
322
    /**
323
     * Creates a new document. The stream in contentStream is consumed but not closed by this method.
324
     *
325
     * @param string[] $properties The property values that MUST be applied to the newly-created document object.
326
     * @param ObjectIdInterface|null $folderId If specified, the identifier for the folder that MUST be the parent
327
     *      folder for the newly-created document object. This parameter MUST be specified if the repository does NOT
328
     *      support the optional "unfiling" capability.
329
     * @param StreamInterface|null $contentStream The content stream that MUST be stored for the newly-created document
330
     *      object. The method of passing the contentStream to the server and the encoding mechanism will be specified
331
     *      by each specific binding. MUST be required if the type requires it.
332
     * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the
333
     *     newly-created object MUST be. Valid values are:
334
     *      <code>none</code>
335
     *          (default, if the object-type is not versionable) The document MUST be created as a non-versionable
336
     *          document.
337
     *     <code>checkedout</code>
338
     *          The document MUST be created in the checked-out state. The checked-out document MAY be
339
     *          visible to other users.
340
     *     <code>major</code>
341
     *          (default, if the object-type is versionable) The document MUST be created as a major version.
342
     *     <code>minor</code>
343
     *          The document MUST be created as a minor version.
344
     * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created
345
     *      document object.
346
     * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object,
347
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified.
348
     * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document
349
     *      object, either using the ACL from folderId if specified, or being ignored if no folderId is specified.
350
     * @return ObjectIdInterface|null the object ID of the new document or <code>null</code> if the document could not
351
     *      be created.
352
     * @throws CmisInvalidArgumentException Throws an <code>CmisInvalidArgumentException</code> if empty
353
     *      property list is given
354
     */
355
    public function createDocument(
356
        array $properties,
357
        ObjectIdInterface $folderId = null,
358
        StreamInterface $contentStream = null,
359
        VersioningState $versioningState = null,
360
        array $policies = array(),
361
        array $addAces = array(),
362
        array $removeAces = array()
363
    ) {
364
        if (empty($properties)) {
365
            throw new CmisInvalidArgumentException('Properties must not be empty!');
366
        }
367
368
        $objectId = $this->getBinding()->getObjectService()->createDocument(
369
            $this->getRepositoryId(),
370
            $this->getObjectFactory()->convertProperties(
371
                $properties,
372
                null,
373
                array(),
374
                self::$createAndCheckoutUpdatability
375
            ),
376
            $folderId === null ? null : $folderId->getId(),
377
            $contentStream,
378
            $versioningState,
379
            $this->getObjectFactory()->convertPolicies($policies),
380
            $this->getObjectFactory()->convertAces($addAces),
381
            $this->getObjectFactory()->convertAces($removeAces),
382
            null
383
        );
384
385
        if ($objectId === null) {
386
            return null;
387
        }
388
389
        return $this->createObjectId($objectId);
390
    }
391
392
    /**
393
     * Creates a new document from a source document.
394
     *
395
     * @param ObjectIdInterface $source The identifier for the source document.
396
     * @param string[] $properties The property values that MUST be applied to the object. This list of properties
397
     *      SHOULD only contain properties whose values differ from the source document.
398
     * @param ObjectIdInterface|null $folderId If specified, the identifier for the folder that MUST be the parent
399
     *      folder for the newly-created document object. This parameter MUST be specified if the repository does NOT
400
     *      support the optional "unfiling" capability.
401
     * @param VersioningState|null $versioningState An enumeration specifying what the versioning state of the
402
     *     newly-created object MUST be. Valid values are:
403
     *      <code>none</code>
404
     *          (default, if the object-type is not versionable) The document MUST be created as a non-versionable
405
     *          document.
406
     *     <code>checkedout</code>
407
     *          The document MUST be created in the checked-out state. The checked-out document MAY be
408
     *          visible to other users.
409
     *     <code>major</code>
410
     *          (default, if the object-type is versionable) The document MUST be created as a major version.
411
     *     <code>minor</code>
412
     *          The document MUST be created as a minor version.
413
     * @param PolicyInterface[] $policies A list of policy ids that MUST be applied to the newly-created
414
     *      document object.
415
     * @param AceInterface[] $addAces A list of ACEs that MUST be added to the newly-created document object,
416
     *      either using the ACL from folderId if specified, or being applied if no folderId is specified.
417
     * @param AceInterface[] $removeAces A list of ACEs that MUST be removed from the newly-created document
418
     *      object, either using the ACL from folderId if specified, or being ignored if no folderId is specified.
419
     * @return ObjectIdInterface|null the object ID of the new document or <code>null</code> if the document could not
420
     *      be created.
421
     * @throws CmisInvalidArgumentException Throws an <code>CmisInvalidArgumentException</code> if empty
422
     *      property list is given
423
     */
424
    public function createDocumentFromSource(
425
        ObjectIdInterface $source,
426
        array $properties = array(),
427
        ObjectIdInterface $folderId = null,
428
        VersioningState $versioningState = null,
429
        array $policies = array(),
430
        array $addAces = array(),
431
        array $removeAces = array()
432
    ) {
433
        if (!$source instanceof CmisObjectInterface) {
434
            $sourceObject = $this->getObject($source);
435
        } else {
436
            $sourceObject = $source;
437
        }
438
439
        $type = $sourceObject->getType();
440
        $secondaryTypes = $sourceObject->getSecondaryTypes();
441
442
        if ($secondaryTypes === null) {
443
            $secondaryTypes = array();
444
        }
445
446
        if (!BaseTypeId::cast($type->getBaseTypeId())->equals(BaseTypeId::CMIS_DOCUMENT)) {
447
            throw new CmisInvalidArgumentException('Source object must be a document!');
448
        }
449
450
        $objectId = $this->getBinding()->getObjectService()->createDocumentFromSource(
451
            $this->getRepositoryId(),
452
            $source->getId(),
453
            $this->getObjectFactory()->convertProperties(
454
                $properties,
455
                $type,
456
                $secondaryTypes,
457
                self::$createAndCheckoutUpdatability
458
            ),
459
            $folderId === null ? null : $folderId->getId(),
460
            $versioningState,
461
            $this->getObjectFactory()->convertPolicies($policies),
462
            $this->getObjectFactory()->convertAces($addAces),
463
            $this->getObjectFactory()->convertAces($removeAces),
464
            null
465
        );
466
467
        if ($objectId === null) {
468
            return null;
469
        }
470
471
        return $this->createObjectId($objectId);
472
    }
473
474
    /**
475
     * Creates a new folder.
476
     *
477
     * @param string[] $properties
478
     * @param ObjectIdInterface $folderId
479
     * @param PolicyInterface[] $policies
480
     * @param AceInterface[] $addAces
481
     * @param AceInterface[] $removeAces
482
     * @return ObjectIdInterface the object ID of the new folder
483
     * @throws CmisInvalidArgumentException Throws an <code>CmisInvalidArgumentException</code> if empty
484
     *      property list is given
485
     */
486 View Code Duplication
    public function createFolder(
487
        array $properties,
488
        ObjectIdInterface $folderId,
489
        array $policies = array(),
490
        array $addAces = array(),
491
        array $removeAces = array()
492
    ) {
493
        if (empty($properties)) {
494
            throw new CmisInvalidArgumentException('Properties must not be empty!');
495
        }
496
497
        $objectId = $this->getBinding()->getObjectService()->createFolder(
498
            $this->getRepositoryId(),
499
            $this->getObjectFactory()->convertProperties($properties),
500
            $folderId->getId(),
501
            $this->getObjectFactory()->convertPolicies($policies),
502
            $this->getObjectFactory()->convertAces($addAces),
503
            $this->getObjectFactory()->convertAces($removeAces),
504
            null
505
        );
506
507
        return $this->createObjectId($objectId);
508
    }
509
510
    /**
511
     * Creates a new item.
512
     *
513
     * @param string[] $properties
514
     * @param ObjectIdInterface $folderId
515
     * @param PolicyInterface[] $policies
516
     * @param AceInterface[] $addAces
517
     * @param AceInterface[] $removeAces
518
     * @return ObjectIdInterface the object ID of the new item
519
     * @throws CmisInvalidArgumentException Throws an <code>CmisInvalidArgumentException</code> if empty
520
     *      property list is given
521
     */
522 View Code Duplication
    public function createItem(
523
        array $properties,
524
        ObjectIdInterface $folderId,
525
        array $policies = array(),
526
        array $addAces = array(),
527
        array $removeAces = array()
528
    ) {
529
        if (empty($properties)) {
530
            throw new CmisInvalidArgumentException('Properties must not be empty!');
531
        }
532
533
        $objectId = $this->getBinding()->getObjectService()->createItem(
534
            $this->getRepositoryId(),
535
            $this->getObjectFactory()->convertProperties($properties),
536
            $folderId->getId(),
537
            $this->getObjectFactory()->convertPolicies($policies),
538
            $this->getObjectFactory()->convertAces($addAces),
539
            $this->getObjectFactory()->convertAces($removeAces),
540
            null
541
        );
542
543
        return $this->createObjectId($objectId);
544
    }
545
546
    /**
547
     * Creates an object ID from a String.
548
     *
549
     * @param string $id
550
     * @return ObjectIdInterface the object ID object
551
     */
552
    public function createObjectId($id)
553
    {
554
        return new ObjectId($id);
555
    }
556
557
    /**
558
     * Creates a new operation context object with the given properties.
559
     *
560
     * @param string[] $filter the property filter, a comma separated string of query names or "*" for all
561
     *      properties or <code>null</code> to let the repository determine a set of properties
562
     * @param boolean $includeAcls indicates whether ACLs should be included or not
563
     * @param boolean $includeAllowableActions indicates whether Allowable Actions should be included or not
564
     * @param boolean $includePolicies indicates whether policies should be included or not
565
     * @param IncludeRelationships|null $includeRelationships enum that indicates if and which
566
     *      relationships should be includes
567
     * @param string[] $renditionFilter the rendition filter or <code>null</code> for no renditions
568
     * @param boolean $includePathSegments indicates whether path segment or the relative path segment should
569
     *      be included or not
570
     * @param string|null $orderBy the object order, a comma-separated list of query names and the ascending
571
     * modifier "ASC" or the descending modifier "DESC" for each query name
572
     * @param boolean $cacheEnabled flag that indicates if the object cache should be used
573
     * @param integer $maxItemsPerPage the max items per page/batch
574
     * @return OperationContextInterface the newly created operation context object
575
     */
576
    public function createOperationContext(
577
        $filter = array(),
578
        $includeAcls = false,
579
        $includeAllowableActions = true,
580
        $includePolicies = false,
581
        IncludeRelationships $includeRelationships = null,
582
        array $renditionFilter = array(),
583
        $includePathSegments = true,
584
        $orderBy = null,
585
        $cacheEnabled = false,
586
        $maxItemsPerPage = 100
587
    ) {
588
        $operationContext = new OperationContext();
589
        $operationContext->setFilter($filter);
590
        $operationContext->setIncludeAcls($includeAcls);
591
        $operationContext->setIncludeAllowableActions($includeAllowableActions);
592
        $operationContext->setIncludePolicies($includePolicies);
593
        if ($includeRelationships !== null) {
594
            $operationContext->setIncludeRelationships($includeRelationships);
595
        }
596
        $operationContext->setRenditionFilter($renditionFilter);
597
        $operationContext->setIncludePathSegments($includePathSegments);
598
        if (!empty($orderBy)) {
599
            $operationContext->setOrderBy($orderBy);
600
        }
601
        $operationContext->setCacheEnabled($cacheEnabled);
602
        $operationContext->setMaxItemsPerPage($maxItemsPerPage);
603
604
        return $operationContext;
605
    }
606
607
    /**
608
     * Creates a new policy.
609
     *
610
     * @param string[] $properties
611
     * @param ObjectIdInterface $folderId
612
     * @param PolicyInterface[] $policies
613
     * @param AceInterface[] $addAces
614
     * @param AceInterface[] $removeAces
615
     * @return ObjectIdInterface the object ID of the new policy
616
     */
617
    public function createPolicy(
618
        array $properties,
619
        ObjectIdInterface $folderId,
620
        array $policies = array(),
621
        array $addAces = array(),
622
        array $removeAces = array()
623
    ) {
624
        // TODO: Implement createPolicy() method.
625
    }
626
627
    /**
628
     * Creates a query statement for a query of one primary type joined by zero or more secondary types.
629
     *
630
     * Generates something like this:
631
     * `SELECT d.cmis:name,s.SecondaryStringProp FROM cmis:document AS d JOIN MySecondaryType AS s ON
632
     * d.cmis:objectId=s.cmis:objectId WHERE d.cmis:name LIKE ? ORDER BY d.cmis:name,s.SecondaryIntegerProp`
633
     *
634
     * @param string[] $selectPropertyIds the property IDs in the SELECT statement,
635
     *      if <code>null</code> all properties are selected
636
     * @param string[] $fromTypes a Map of type aliases (keys) and type IDs (values), the Map must contain
637
     *      exactly one primary type and zero or more secondary types
638
     * @param string|null $whereClause an optional WHERE clause with placeholders ('?'), see QueryStatement for details
639
     * @param string[] $orderByPropertyIds an optional list of properties IDs for the ORDER BY clause
640
     * @return QueryStatementInterface a new query statement object
641
     * @throws CmisInvalidArgumentException
642
     */
643 2
    public function createQueryStatement(
644
        array $selectPropertyIds,
645
        array $fromTypes,
646
        $whereClause = null,
647
        array $orderByPropertyIds = array()
648
    ) {
649 2
        if (empty($selectPropertyIds)) {
650 1
            throw new CmisInvalidArgumentException('Select property IDs must not be empty');
651
        }
652 1
        if (empty($fromTypes)) {
653 1
            throw new CmisInvalidArgumentException('From types must not be empty');
654
        }
655
656
        return new QueryStatement($this, null, $selectPropertyIds, $fromTypes, $whereClause, $orderByPropertyIds);
657
    }
658
659
    /**
660
     * Creates a new relationship between 2 objects.
661
     *
662
     * @param string[] $properties
663
     * @param PolicyInterface[] $policies
664
     * @param AceInterface[] $addAces
665
     * @param AceInterface[] $removeAces
666
     * @return ObjectIdInterface|null the object ID of the new relationship or <code>null</code> if the relationship
667
     *      could not be created
668
     */
669
    public function createRelationship(
670
        array $properties,
671
        array $policies = array(),
672
        array $addAces = array(),
673
        array $removeAces = array()
674
    ) {
675
        if (empty($properties)) {
676
            throw new CmisInvalidArgumentException('Properties must not be empty!');
677
        }
678
679
        $newObjectId = $this->getBinding()->getObjectService()->createRelationship(
680
            $this->getRepositoryId(),
681
            $this->getObjectFactory()->convertProperties($properties, null, array(), self::$createUpdatability),
682
            $this->getObjectFactory()->convertPolicies($policies),
683
            $this->getObjectFactory()->convertAces($addAces),
684
            $this->getObjectFactory()->convertAces($removeAces)
685
        );
686
687
        if ($newObjectId === null) {
688
            return null;
689
        }
690
691
        return $this->createObjectId($newObjectId);
692
    }
693
694
    /**
695
     * Creates a new type.
696
     *
697
     * @param TypeDefinitionInterface $type
698
     * @return ObjectTypeInterface the new type definition
699
     * @throws CmisNotSupportedException If repository version 1.0
700
     */
701 View Code Duplication
    public function createType(TypeDefinitionInterface $type)
702
    {
703
        if ($this->getRepositoryInfo()->getCmisVersion() == CmisVersion::cast(CmisVersion::CMIS_1_0)) {
704
            throw new CmisNotSupportedException('This method is not supported for CMIS 1.0 repositories.');
705
        }
706
707
        return $this->convertTypeDefinition(
708
            $this->getBinding()->getRepositoryService()->createType($this->getRepositoryInfo()->getId(), $type)
709
        );
710
    }
711
712
    /**
713
     * Deletes an object and, if it is a document, all versions in the version series.
714
     *
715
     * @param ObjectIdInterface $objectId the ID of the object
716
     * @param boolean $allVersions if this object is a document this parameter defines
717
     *      if only this version or all versions should be deleted
718
     */
719
    public function delete(ObjectIdInterface $objectId, $allVersions = true)
720
    {
721
        $this->getBinding()->getObjectService()->deleteObject(
722
            $this->getRepositoryId(),
723
            $objectId->getId(),
724
            $allVersions
725
        );
726
        $this->removeObjectFromCache($objectId);
727
    }
728
729
    /**
730
     * Deletes a type.
731
     *
732
     * @param string $typeId the ID of the type to delete
733
     * @throws CmisNotSupportedException If repository version 1.0
734
     */
735 View Code Duplication
    public function deleteType($typeId)
736
    {
737
        if ($this->getRepositoryInfo()->getCmisVersion() == CmisVersion::cast(CmisVersion::CMIS_1_0)) {
738
            throw new CmisNotSupportedException('This method is not supported for CMIS 1.0 repositories.');
739
        }
740
741
        $this->getBinding()->getRepositoryService()->deleteType($this->getRepositoryId(), $typeId);
742
        $this->removeObjectFromCache($this->createObjectId($typeId));
743
    }
744
745
    /**
746
     * Fetches the ACL of an object from the repository.
747
     *
748
     * @param ObjectIdInterface $objectId the ID the object
749
     * @param boolean $onlyBasicPermissions if <code>true</code> the repository should express the ACL only with the
750
     *      basic permissions defined in the CMIS specification; if <code>false</code> the repository can express the
751
     *      ACL with basic and repository specific permissions
752
     * @return AclInterface the ACL of the object
753
     */
754
    public function getAcl(ObjectIdInterface $objectId, $onlyBasicPermissions)
755
    {
756
        // TODO: Implement getAcl() method.
757
    }
758
759
    /**
760
     * Returns the underlying binding object.
761
     *
762
     * @return CmisBindingInterface the binding object
763
     */
764 8
    public function getBinding()
765
    {
766 8
        return $this->binding;
767
    }
768
769
    /**
770
     * Returns all checked out documents with the given OperationContext.
771
     *
772
     * @param OperationContextInterface|null $context
773
     * @return DocumentInterface[]
774
     */
775
    public function getCheckedOutDocs(OperationContextInterface $context = null)
776
    {
777
        // TODO: Implement getCheckedOutDocs() method.
778
    }
779
780
    /**
781
     * @return CmisBindingsHelper
782
     */
783 8
    protected function getCmisBindingHelper()
784
    {
785 8
        return $this->cmisBindingHelper;
786
    }
787
788
    /**
789
     * Returns the content changes.
790
     *
791
     * @param string $changeLogToken the change log token to start from or <code>null</code> to start from
792
     *      the first available event in the repository
793
     * @param boolean $includeProperties indicates whether changed properties should be included in the result or not
794
     * @param integer|null $maxNumItems maximum numbers of events
795
     * @param OperationContextInterface|null $context the OperationContext
796
     * @return ChangeEventsInterface the change events
797
     */
798
    public function getContentChanges(
799
        $changeLogToken,
800
        $includeProperties,
801
        $maxNumItems = null,
802
        OperationContextInterface $context = null
803
    ) {
804
        if ($context === null) {
805
            $context = $this->getDefaultContext();
806
        }
807
808
        $objectList = $this->getBinding()->getDiscoveryService()->getContentChanges(
809
            $this->getRepositoryInfo()->getId(),
810
            $changeLogToken,
811
            $includeProperties,
812
            $context->isIncludePolicies(),
813
            $context->isIncludeAcls(),
814
            $maxNumItems
815
        );
816
817
        return $this->getObjectFactory()->convertChangeEvents($changeLogToken, $objectList);
818
    }
819
820
    /**
821
     * Retrieves the main content stream of a document.
822
     *
823
     * @param ObjectIdInterface $docId the ID of the document
824
     * @param string|null $streamId the stream ID
825
     * @param integer|null $offset the offset of the stream or <code>null</code> to read the stream from the beginning
826
     * @param integer|null $length the maximum length of the stream or <code>null</code> to read to the end of the
827
     *      stream
828
     * @return StreamInterface|null the content stream or <code>null</code> if the
829
     *      document has no content stream
830
     */
831
    public function getContentStream(ObjectIdInterface $docId, $streamId = null, $offset = null, $length = null)
832
    {
833
        $contentStream = $this->getBinding()->getObjectService()->getContentStream(
834
            $this->getRepositoryId(),
835
            $docId->getId(),
836
            $streamId,
837
            $offset,
838
            $length
839
        );
840
841
        return $contentStream instanceof StreamInterface ? $contentStream : null;
842
    }
843
844
    /**
845
     * Returns the current default operation parameters for filtering, paging and caching.
846
     *
847
     * @return OperationContextInterface the default operation context
848
     */
849 1
    public function getDefaultContext()
850
    {
851 1
        return $this->defaultContext;
852
    }
853
854
    /**
855
     * Returns the latest change log token.
856
     *
857
     * In contrast to the repository info, this change log token is *not cached*.
858
     * This method requests the token from the repository every single time it is called.
859
     *
860
     * @return string|null the latest change log token or <code>null</code> if the repository doesn't provide one
861
     */
862
    public function getLatestChangeLogToken()
863
    {
864
        // TODO: Implement getLatestChangeLogToken() method.
865
    }
866
867
    /**
868
     * Returns the latest version in a version series.
869
     *
870
     * @param ObjectIdInterface $objectId the document ID of an arbitrary version in the version series
871
     * @param boolean $major if <code>true</code> the latest major version will be returned,
872
     *      otherwise the very last version will be returned
873
     * @param OperationContextInterface|null $context the OperationContext to use
874
     * @return DocumentInterface the latest document version
875
     */
876
    public function getLatestDocumentVersion(
877
        ObjectIdInterface $objectId,
878
        $major = false,
879
        OperationContextInterface $context = null
880
    ) {
881
        // TODO: Implement getLatestDocumentVersion() method.
882
    }
883
884
    /**
885
     * Get the current locale to be used for this session.
886
     *
887
     * @return \Locale the current locale, may be <code>null</code>
888
     */
889
    public function getLocale()
890
    {
891
        // TODO: Implement getLocale() method.
892
    }
893
894
    /**
895
     * @param ObjectIdInterface $objectId the object ID
896
     * @param OperationContextInterface|null $context the OperationContext to use
897
     * @return CmisObjectInterface the requested object
898
     * @throws CmisObjectNotFoundException - if an object with the given ID doesn't exist
899
     */
900
    public function getObject(ObjectIdInterface $objectId, OperationContextInterface $context = null)
901
    {
902
        if ($context === null) {
903
            $context = $this->getDefaultContext();
904
        }
905
906
        $objectIdString = $objectId->getId();
907
        $cacheIdentity = $objectIdString . '|' . $context->getCacheKey();
908
909
        if ($this->getCache()->contains($cacheIdentity)) {
910
            return $this->getCache()->fetch($cacheIdentity);
911
        }
912
913
        $objectData = $this->getBinding()->getObjectService()->getObject(
914
            $this->getRepositoryInfo()->getId(),
915
            $objectIdString,
916
            $context->getQueryFilterString(),
917
            $context->isIncludeAllowableActions(),
918
            $context->getIncludeRelationships(),
919
            $context->getRenditionFilterString(),
920
            $context->isIncludePolicies(),
921
            $context->isIncludeAcls(),
922
            null
923
        );
924
925
        if (!$objectData instanceof ObjectDataInterface) {
926
            throw new CmisObjectNotFoundException('Could not find object for given id.');
927
        }
928
929
        $object = $this->getObjectFactory()->convertObject($objectData, $context);
930
        $this->getCache()->save($cacheIdentity, $object);
931
        return $object;
932
    }
933
934
    /**
935
     * Returns a CMIS object from the session cache. If the object is not in the cache or the given OperationContext
936
     * has caching turned off, it will load the object from the repository and puts it into the cache.
937
     * This method might return a stale object if the object has been found in the cache and has been changed in or
938
     * removed from the repository. Use CmisObject::refresh() and CmisObject::refreshIfOld() to update the object
939
     * if necessary.
940
     *
941
     * @param string $path the object path
942
     * @param OperationContextInterface|null $context the OperationContext to use
943
     * @return CmisObjectInterface Returns a CMIS object from the session cache.
944
     * @throws CmisInvalidArgumentException Throws an <code>CmisInvalidArgumentException</code>
945
     *      if path is empty.
946
     * @throws CmisObjectNotFoundException - if an object with the given path doesn't exist
947
     */
948
    public function getObjectByPath($path, OperationContextInterface $context = null)
949
    {
950
        if (empty($path)) {
951
            throw new CmisInvalidArgumentException('Path must not be empty.');
952
        }
953
954
        if ($context === null) {
955
            $context = $this->getDefaultContext();
956
        }
957
958
        $objectData = $this->getBinding()->getObjectService()->getObjectByPath(
959
            $this->getRepositoryInfo()->getId(),
960
            $path,
961
            $context->getQueryFilterString(),
962
            $context->isIncludeAllowableActions(),
963
            $context->getIncludeRelationships(),
964
            $context->getRenditionFilterString(),
965
            $context->isIncludePolicies(),
966
            $context->isIncludeAcls()
967
        );
968
969
        if (!$objectData instanceof ObjectDataInterface) {
970
            throw new CmisObjectNotFoundException(sprintf('Could not find object for given path "%s".', $path));
971
        }
972
973
        // TODO: Implement cache!
974
975
        return $this->getObjectFactory()->convertObject($objectData, $context);
976
    }
977
978
    /**
979
     * Gets a factory object that provides methods to create the objects used by this API.
980
     *
981
     * @return ObjectFactoryInterface the repository info
982
     */
983 3
    public function getObjectFactory()
984
    {
985 3
        return $this->objectFactory;
986
    }
987
988
    /**
989
     * Fetches the relationships from or to an object from the repository.
990
     *
991
     * @param ObjectIdInterface $objectId
992
     * @param boolean $includeSubRelationshipTypes
993
     * @param RelationshipDirection $relationshipDirection
994
     * @param ObjectTypeInterface $type
995
     * @param OperationContextInterface|null $context
996
     * @return RelationshipInterface[]
997
     */
998 1
    public function getRelationships(
999
        ObjectIdInterface $objectId,
1000
        $includeSubRelationshipTypes,
1001
        RelationshipDirection $relationshipDirection,
1002
        ObjectTypeInterface $type,
1003
        OperationContextInterface $context = null
1004
    ) {
1005
1006 1
        if ($context === null) {
1007 1
            $context = $this->getDefaultContext();
1008 1
        }
1009
1010
        // TODO: Implement cache!
1011
1012 1
        return $this->getBinding()->getRelationshipService()->getObjectRelationships(
1013 1
            $this->getRepositoryId(),
1014 1
            $objectId->getId(),
1015 1
            $includeSubRelationshipTypes,
1016 1
            $relationshipDirection,
1017 1
            $type->getId()
1018 1
        );
1019
    }
1020
1021
    /**
1022
     * Returns the repository info of the repository associated with this session.
1023
     *
1024
     * @return RepositoryInfoInterface the repository info
1025
     */
1026 1
    public function getRepositoryInfo()
1027
    {
1028 1
        return $this->repositoryInfo;
1029
    }
1030
1031
    /**
1032
     * Returns the repository id.
1033
     *
1034
     * @return string the repository id
1035
     */
1036 1
    public function getRepositoryId()
1037
    {
1038 1
        return $this->getRepositoryInfo()->getId();
1039
    }
1040
1041
    /**
1042
     * Gets the root folder of the repository with the given OperationContext.
1043
     *
1044
     * @param OperationContextInterface|null $context
1045
     * @return FolderInterface the root folder object
1046
     * @throws CmisRuntimeException
1047
     */
1048
    public function getRootFolder(OperationContextInterface $context = null)
1049
    {
1050
        $rootFolderId = $this->getRepositoryInfo()->getRootFolderId();
1051
1052
        $rootFolder = $this->getObject(
1053
            $this->createObjectId($rootFolderId),
1054
            $context === null ? $this->getDefaultContext() : $context
1055
        );
1056
1057
        if (!($rootFolder instanceof FolderInterface)) {
1058
            throw new CmisRuntimeException('Root folder object is not a folder!', 1423735889);
1059
        }
1060
1061
        return $rootFolder;
1062
    }
1063
1064
    /**
1065
     * Gets the type children of a type.
1066
     *
1067
     * @param string $typeId the type ID or <code>null</code> to request the base types
1068
     * @param boolean $includePropertyDefinitions indicates whether the property definitions should be included or not
1069
     * @return TypeDefinitionListInterface the type iterator
1070
     * @throws CmisObjectNotFoundException - if a type with the given type ID doesn't exist
1071
     */
1072
    public function getTypeChildren($typeId, $includePropertyDefinitions)
1073
    {
1074
        return $this->getBinding()->getRepositoryService()->getTypeChildren(
1075
            $this->getRepositoryId(),
1076
            $typeId,
1077
            $includePropertyDefinitions,
1078
            999, // set max items to 999 - TODO: Implement CollectionIterable() method to iterate over all objects.
1079
            0 // TODO: Implement CollectionIterable() method to iterate over all objects.
1080
        );
1081
    }
1082
1083
    /**
1084
     * Gets the definition of a type.
1085
     *
1086
     * @param string $typeId the ID of the type
1087
     * @param boolean $useCache specifies if the type definition should be first looked up in the type definition
1088
     *     cache, if it is set to <code>false</code> or the type definition is not in the cache, the type definition is
1089
     *     loaded from the repository
1090
     * @return ObjectTypeInterface the type definition
1091
     * @throws CmisObjectNotFoundException - if a type with the given type ID doesn't exist
1092
     */
1093
    public function getTypeDefinition($typeId, $useCache = true)
1094
    {
1095
        // TODO: Implement cache!
1096
        $typeDefinition = $this->getBinding()->getRepositoryService()->getTypeDefinition(
1097
            $this->getRepositoryId(),
1098
            $typeId
1099
        );
1100
1101
        return $this->convertTypeDefinition($typeDefinition);
1102
    }
1103
1104
    /**
1105
     * Gets the type descendants of a type.
1106
     *
1107
     * @param string $typeId the type ID or <code>null</code> to request the base types
1108
     * @param integer $depth indicates whether the property definitions should be included or not
1109
     * @param boolean $includePropertyDefinitions the tree depth, must be greater than 0 or -1 for infinite depth
1110
     * @return TypeDefinitionContainerInterface[] A tree that contains ObjectTypeInterface objects
1111
     * @see ObjectTypeInterface ObjectTypeInterface contained in returned Tree
1112
     * @throws CmisObjectNotFoundException - if a type with the given type ID doesn't exist
1113
     */
1114
    public function getTypeDescendants($typeId, $depth, $includePropertyDefinitions)
1115
    {
1116
        return $this->getBinding()->getRepositoryService()->getTypeDescendants(
1117
            $this->getRepositoryId(),
1118
            $typeId,
1119
            (integer) $depth,
1120
            $includePropertyDefinitions
1121
        );
1122
    }
1123
1124
    /**
1125
     * Sends a query to the repository using the given OperationContext. (See CMIS spec "2.1.10 Query".)
1126
     *
1127
     * @param string $statement the query statement (CMIS query language)
1128
     * @param boolean $searchAllVersions specifies whether non-latest document versions should be included or not,
1129
     *      <code>true</code> searches all document versions, <code>false</code> only searches latest document versions
1130
     * @param OperationContextInterface|null $context the operation context to use
1131
     * @return QueryResultInterface[]
1132
     * @throws CmisInvalidArgumentException If statement is empty
1133
     */
1134
    public function query($statement, $searchAllVersions = false, OperationContextInterface $context = null)
1135
    {
1136
        if (empty($statement)) {
1137
            throw new CmisInvalidArgumentException('Statement must not be empty.');
1138
        }
1139
1140
        if ($context === null) {
1141
            $context = $this->getDefaultContext();
1142
        }
1143
1144
        $queryResults = array();
1145
        $skipCount = 0;
1146
1147
        $objectList = $this->getBinding()->getDiscoveryService()->query(
1148
            $this->getRepositoryInfo()->getId(),
1149
            $statement,
1150
            $searchAllVersions,
1151
            $context->getIncludeRelationships(),
1152
            $context->getRenditionFilterString(),
1153
            $context->isIncludeAllowableActions(),
1154
            $context->getMaxItemsPerPage(),
1155
            $skipCount
1156
        );
1157
1158
        foreach ($objectList->getObjects() as $objectData) {
1159
            $queryResult = $this->getObjectFactory()->convertQueryResult($objectData);
1160
            if ($queryResult instanceof QueryResultInterface) {
1161
                $queryResults[] = $queryResult;
1162
            }
1163
        }
1164
1165
        // TODO: Implement pagination using skipCount
1166
1167
        return $queryResults;
1168
    }
1169
1170
    /**
1171
     * Builds a CMIS query and returns the query results as an iterator of CmisObject objects.
1172
     *
1173
     * @param string $typeId the ID of the object type
1174
     * @param string|null $where the WHERE part of the query
1175
     * @param boolean $searchAllVersions specifies whether non-latest document versions should be included or not,
1176
     *      <code>true</code> searches all document versions, <code>false</code> only searches latest document versions
1177
     * @param OperationContextInterface|null $context the operation context to use
1178
     * @return CmisObjectInterface[]
1179
     * @throws CmisInvalidArgumentException If type id is empty
1180
     */
1181
    public function queryObjects(
1182
        $typeId,
1183
        $where = null,
1184
        $searchAllVersions = false,
1185
        OperationContextInterface $context = null
1186
    ) {
1187
        if (empty($typeId)) {
1188
            throw new CmisInvalidArgumentException('Type id must not be empty.');
1189
        }
1190
1191
        if ($context === null) {
1192
            $context = $this->getDefaultContext();
1193
        }
1194
1195
        $queryFilterString = $context->getQueryFilterString();
1196
        if (!empty($queryFilterString)) {
1197
            $querySelect = $queryFilterString;
1198
        } else {
1199
            $querySelect = '*';
1200
        }
1201
1202
        $whereClause = '';
1203
        if (!empty($where)) {
1204
            $whereClause = ' WHERE ' . $where;
1205
        }
1206
1207
        $orderBy = $context->getOrderBy();
1208
        if (!empty($orderBy)) {
1209
            $orderBy = ' ORDER BY ' . $orderBy;
1210
        }
1211
1212
        $typeDefinition = $this->getTypeDefinition($typeId);
1213
        $statement = 'SELECT ' . $querySelect . ' FROM ' . $typeDefinition->getQueryName() . $whereClause . $orderBy;
1214
        $queryStatement = new QueryStatement($this, $statement);
1215
1216
        $resultObjects = array();
1217
        $skipCount = 0;
1218
1219
        $objectList = $this->getBinding()->getDiscoveryService()->query(
1220
            $this->getRepositoryInfo()->getId(),
1221
            $queryStatement->toQueryString(),
1222
            $searchAllVersions,
1223
            $context->getIncludeRelationships(),
1224
            $context->getRenditionFilterString(),
1225
            $context->isIncludeAllowableActions(),
1226
            $context->getMaxItemsPerPage(),
1227
            $skipCount
1228
        );
1229
1230
        foreach ($objectList->getObjects() as $objectData) {
1231
            $object = $this->getObjectFactory()->convertObject($objectData, $context);
1232
            if ($object instanceof CmisObjectInterface) {
1233
                $resultObjects[] = $object;
1234
            }
1235
        }
1236
1237
        // TODO: Implement pagination using skipCount
1238
1239
        return $resultObjects;
1240
    }
1241
1242
    /**
1243
     * Removes the given object from the cache.
1244
     *
1245
     * Note about specific implementation: in order to avoid an over-engineered
1246
     * taggable cache mechanism and with it, extensive traversal of objects when
1247
     * creating tags, objects are not tagged in the cache. In addition, objects
1248
     * are added to the cache with a secondary identification; the context - and
1249
     * the context is not available here when removing a single object from the
1250
     * cache. Instead, we opt to simply flush the entire cache and let it refill.
1251
     *
1252
     * @param ObjectIdInterface $objectId
1253
     */
1254
    public function removeObjectFromCache(ObjectIdInterface $objectId)
1255
    {
1256
        $this->clear();
1257
    }
1258
1259
    /**
1260
     * Removes a set of policies from an object. This operation is not atomic.
1261
     * If it fails some policies might already be removed.
1262
     *
1263
     * @param ObjectIdInterface $objectId the ID the object
1264
     * @param ObjectIdInterface[] $policyIds the IDs of the policies to be removed
1265
     */
1266
    public function removePolicy(ObjectIdInterface $objectId, array $policyIds)
1267
    {
1268
        // TODO: Implement removePolicy() method.
1269
    }
1270
1271
    /**
1272
     * Removes the direct ACEs of an object and sets the provided ACEs.
1273
     * The changes are local to the given object and are not propagated to dependent objects.
1274
     *
1275
     * @param ObjectIdInterface $objectId
1276
     * @param AceInterface[] $aces
1277
     * @return AclInterface the new ACL of the object
1278
     */
1279
    public function setAcl(ObjectIdInterface $objectId, array $aces)
1280
    {
1281
        // TODO: Implement setAcl() method.
1282
    }
1283
1284
    /**
1285
     * Sets the current session parameters for filtering, paging and caching.
1286
     *
1287
     * @param OperationContextInterface $context the OperationContext to be used for the session;
1288
     *      if null, a default context is used
1289
     */
1290
    public function setDefaultContext(OperationContextInterface $context)
1291
    {
1292
        $this->defaultContext = $context;
1293
    }
1294
1295
    /**
1296
     * Updates an existing type.
1297
     *
1298
     * @param TypeDefinitionInterface $type the type definition updates
1299
     * @return ObjectTypeInterface the updated type definition
1300
     */
1301
    public function updateType(TypeDefinitionInterface $type)
1302
    {
1303
        // TODO: Implement updateType() method.
1304
    }
1305
1306
    /**
1307
     * Converts a type definition into an object type. If the object type is
1308
     * cached, it returns the cached object. Otherwise it creates an object type
1309
     * object and puts it into the cache.
1310
     *
1311
     * @param TypeDefinitionInterface $typeDefinition
1312
     * @return ObjectTypeInterface
1313
     */
1314
    private function convertTypeDefinition(TypeDefinitionInterface $typeDefinition)
1315
    {
1316
        // TODO: Implement cache. See Java Implementation for example
1317
        return $this->getObjectFactory()->convertTypeDefinition($typeDefinition);
1318
    }
1319
}
1320