CmisObjectNotFoundException
last analyzed

Complexity

Total Complexity 0

Size/Duplication

Total Lines 1
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 0%
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
wmc 0
lcom 0
cbo 0
1
<?php
2
# Licensed to the Apache Software Foundation (ASF) under one
3
# or more contributor license agreements.  See the NOTICE file
4
# distributed with this work for additional information
5
# regarding copyright ownership.  The ASF licenses this file
6
# to you under the Apache License, Version 2.0 (the
7
# "License"); you may not use this file except in compliance
8
# with the License.  You may obtain a copy of the License at
9
#
10
# http://www.apache.org/licenses/LICENSE-2.0
11
#
12
# Unless required by applicable law or agreed to in writing,
13
# software distributed under the License is distributed on an
14
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
# KIND, either express or implied.  See the License for the
16
# specific language governing permissions and limitations
17
# under the License.
18
19
define("HTTP_OK", 200);
20
define("HTTP_CREATED", 201);
21
define("HTTP_ACCEPTED", 202);
22
define("HTTP_NONAUTHORITATIVE_INFORMATION", 203);
23
define("HTTP_NO_CONTENT", 204);
24
define("HTTP_RESET_CONTENT", 205);
25
define("HTTP_PARTIAL_CONTENT", 206);
26
define("HTTP_MULTIPLE_CHOICES", 300);
27
define("HTTP_BAD_REQUEST", 400); // invalidArgument, filterNotValid
28
define("HTTP_UNAUTHORIZED", 401);
29
define("HTTP_FORBIDDEN", 403); // permissionDenied, streamNotSupported
30
define("HTTP_NOT_FOUND", 404); // objectNotFound
31
define("HTTP_METHOD_NOT_ALLOWED", 405); // notSupported
32
define("HTTP_NOT_ACCEPTABLE", 406);
33
define("HTTP_PROXY_AUTHENTICATION_REQUIRED", 407);
34
define("xHTTP_REQUEST_TIMEOUT", 408); //Had to change this b/c HTTP_REQUEST_TIMEOUT conflicts with definition in Drupal 7
35
define("HTTP_CONFLICT", 409); // constraint, contentAlreadyExists, versioning, updateConflict, nameConstraintViolation
36
define("HTTP_UNSUPPORTED_MEDIA_TYPE", 415);
37
define("HTTP_UNPROCESSABLE_ENTITY", 422);
38
define("HTTP_INTERNAL_SERVER_ERROR", 500); // runtime, storage
39
40
class CmisInvalidArgumentException extends Exception {}
41
class CmisObjectNotFoundException extends Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
42
class CmisPermissionDeniedException extends Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
43
class CmisNotSupportedException extends Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
44
class CmisConstraintException extends Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
45
class CmisRuntimeException extends Exception {}
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
46
47
class CMISRepositoryWrapper
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
48
{
49
    // Handles --
50
    //   Workspace -- but only endpoints with a single repo
51
    //   Entry -- but only for objects
52
    //   Feeds -- but only for non-hierarchical feeds
53
    // Does not handle --
54
    //   -- Hierarchical Feeds
55
    //   -- Types
56
    //   -- Others?
57
    // Only Handles Basic Auth
58
    // Very Little Error Checking
59
    // Does not work against pre CMIS 1.0 Repos
60
61
    var $url;
62
    var $username;
63
    var $password;
64
    var $authenticated;
65
    var $workspace;
66
    var $last_request;
67
    var $do_not_urlencode;
68
    protected $_addlCurlOptions = array();
69
70
    static $namespaces = array (
71
        "cmis" => "http://docs.oasis-open.org/ns/cmis/core/200908/",
72
        "cmisra" => "http://docs.oasis-open.org/ns/cmis/restatom/200908/",
73
        "atom" => "http://www.w3.org/2005/Atom",
74
        "app" => "http://www.w3.org/2007/app",
75
76
    );
77
78
    function __construct($url, $username = null, $password = null, $options = null, array $addlCurlOptions = array())
79
    {
80
        if (is_array($options) && $options["config:do_not_urlencode"]) {
81
            $this->do_not_urlencode=true;
82
        }
83
        $this->_addlCurlOptions = $addlCurlOptions; // additional cURL options
84
85
        $this->connect($url, $username, $password, $options);
86
    }
87
88
    static function getOpUrl($url, $options = null)
89
    {
90
        if (is_array($options) && (count($options) > 0))
91
        {
92
            $needs_question = strstr($url, "?") === false;
93
            return $url . ($needs_question ? "?" : "&") . http_build_query($options);
94
        } else
95
        {
96
            return $url;
97
        }
98
    }
99
100
    function convertStatusCode($code, $message)
101
    {
102
        switch ($code) {
103
            case HTTP_BAD_REQUEST:
104
                return new CmisInvalidArgumentException($message, $code);
105
            case HTTP_NOT_FOUND:
106
                return new CmisObjectNotFoundException($message, $code);
107
            case HTTP_FORBIDDEN:
108
                return new CmisPermissionDeniedException($message, $code);
109
            case HTTP_METHOD_NOT_ALLOWED:
110
                return new CmisNotSupportedException($message, $code);
111
            case HTTP_CONFLICT:
112
                return new CmisConstraintException($message, $code);
113
            default:
114
                return new CmisRuntimeException($message, $code);
115
            }
116
    }
117
118
    function connect($url, $username, $password, $options)
119
    {
120
        // TODO: Make this work with cookies
121
        $this->url = $url;
122
        $this->username = $username;
123
        $this->password = $password;
124
        $this->auth_options = $options;
125
        $this->authenticated = false;
126
        $retval = $this->doGet($this->url);
127
        if ($retval->code == HTTP_OK || $retval->code == HTTP_CREATED)
128
        {
129
            $this->authenticated = true;
130
            $this->workspace = CMISRepositoryWrapper :: extractWorkspace($retval->body);
131
        }
132
    }
133
134
    function doGet($url)
135
    {
136
        $retval = $this->doRequest($url);
137
        if ($retval->code != HTTP_OK)
138
        {
139
            throw $this->convertStatusCode($retval->code, $retval->body);
140
        }
141
        return $retval;
142
    }
143
144
    function doDelete($url)
145
    {
146
        $retval = $this->doRequest($url, "DELETE");
147
        if ($retval->code != HTTP_NO_CONTENT)
148
        {
149
            throw $this->convertStatusCode($retval->code, $retval->body);
150
        }
151
        return $retval;
152
    }
153
154
    function doPost($url, $content, $contentType, $charset = null)
155
    {
156
        $retval = $this->doRequest($url, "POST", $content, $contentType);
157
        if ($retval->code != HTTP_CREATED)
158
        {
159
            throw $this->convertStatusCode($retval->code, $retval->body);
160
        }
161
        return $retval;
162
    }
163
164
    function doPut($url, $content, $contentType, $charset = null)
165
    {
166
        $retval = $this->doRequest($url, "PUT", $content, $contentType);
167
        if (($retval->code < HTTP_OK) || ($retval->code >= HTTP_MULTIPLE_CHOICES))
168
        {
169
            throw $this->convertStatusCode($retval->code, $retval->body);
170
        }
171
        return $retval;
172
    }
173
174
    function doRequest($url, $method = "GET", $content = null, $contentType = null, $charset = null)
175
    {
176
        // Process the HTTP request
177
        // 'til now only the GET request has been tested
178
        // Does not URL encode any inputs yet
179
        if (is_array($this->auth_options))
180
        {
181
            $url = CMISRepositoryWrapper :: getOpUrl($url, $this->auth_options);
182
        }
183
        $session = curl_init($url);
184
        curl_setopt($session, CURLOPT_HEADER, false);
185
        curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
186
        if ($this->username)
187
        {
188
            curl_setopt($session, CURLOPT_USERPWD, $this->username . ":" . $this->password);
189
        }
190
        curl_setopt($session, CURLOPT_CUSTOMREQUEST, $method);
191
        if ($contentType)
192
        {
193
            curl_setopt($session, CURLOPT_HTTPHEADER, array (
194
                "Content-Type: " . $contentType
195
            ));
196
        }
197
        if ($content)
198
        {
199
            curl_setopt($session, CURLOPT_POSTFIELDS, $content);
200
        }
201
        if ($method == "POST")
202
        {
203
            curl_setopt($session, CURLOPT_POST, true);
204
        }
205
206
        // apply addl. cURL options
207
        // WARNING: this may override previously set options
208
        if (count($this->_addlCurlOptions)) {
209
            foreach ($this->_addlCurlOptions as $key => $value) {
210
                curl_setopt($session, $key, $value);
211
            }
212
        }
213
214
215
        //TODO: Make this storage optional
216
        $retval = new stdClass();
217
        $retval->url = $url;
218
        $retval->method = $method;
219
        $retval->content_sent = $content;
220
        $retval->content_type_sent = $contentType;
221
        $retval->body = curl_exec($session);
222
        $retval->code = curl_getinfo($session, CURLINFO_HTTP_CODE);
223
        $retval->content_type = curl_getinfo($session, CURLINFO_CONTENT_TYPE);
224
        $retval->content_length = curl_getinfo($session, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
225
        curl_close($session);
226
        $this->last_request = $retval;
227
        return $retval;
228
    }
229
230
    function getLastRequest()
231
    {
232
        return $this->last_request;
233
    }
234
235
    function getLastRequestBody()
236
    {
237
        return $this->last_request->body;
238
    }
239
240
    function getLastRequestCode()
241
    {
242
        return $this->last_request->code;
243
    }
244
245
    function getLastRequestContentType()
246
    {
247
        return $this->last_request->content_type;
248
    }
249
250
    function getLastRequestContentLength()
251
    {
252
        return $this->last_request->content_length;
253
    }
254
255
    function getLastRequestURL()
256
    {
257
        return $this->last_request->url;
258
    }
259
260
    function getLastRequestMethod()
261
    {
262
        return $this->last_request->method;
263
    }
264
265
    function getLastRequestContentTypeSent()
266
    {
267
        return $this->last_request->content_type_sent;
268
    }
269
270
    function getLastRequestContentSent()
271
    {
272
        return $this->last_request->content_sent;
273
    }
274
275
    // Static Utility Functions
276
    static function processTemplate($template, $values = array ())
277
    {
278
        // Fill in the blanks --
279
        $retval = $template;
280
        if (is_array($values))
281
        {
282
            foreach ($values as $name => $value)
283
            {
284
                $retval = str_replace("{" . $name . "}", $value, $retval);
285
            }
286
        }
287
        // Fill in any unpoupated variables with ""
288
        return preg_replace("/{[a-zA-Z0-9_]+}/", "", $retval);
289
290
    }
291
292
    static function doXQuery($xmldata, $xquery)
293
    {
294
        $doc = new DOMDocument();
295
        $doc->loadXML($xmldata);
296
        return CMISRepositoryWrapper :: doXQueryFromNode($doc, $xquery);
297
    }
298
299
    static function doXQueryFromNode($xmlnode, $xquery)
300
    {
301
        // Perform an XQUERY on a NODE
302
        // Register the 4 CMIS namespaces
303
        //THis may be a hopeless HACK!
304
        //TODO: Review
305
        if (!($xmlnode instanceof DOMDocument)) {
306
            $xdoc=new DOMDocument();
307
            $xnode = $xdoc->importNode($xmlnode,true);
308
            $xdoc->appendChild($xnode);
309
            $xpath = new DomXPath($xdoc);
310
        } else {
311
        	$xpath = new DomXPath($xmlnode);
312
        }
313
        foreach (CMISRepositoryWrapper :: $namespaces as $nspre => $nsuri)
314
        {
315
            $xpath->registerNamespace($nspre, $nsuri);
316
        }
317
        return $xpath->query($xquery);
318
319
    }
320
    static function getLinksArray($xmlnode)
321
    {
322
        // Gets the links of an object or a workspace
323
        // Distinguishes between the two "down" links
324
        //  -- the children link is put into the associative array with the "down" index
325
        //  -- the descendants link is put into the associative array with the "down-tree" index
326
        //  These links are distinguished by the mime type attribute, but these are probably the only two links that share the same rel ..
327
        //    so this was done as a one off
328
        $links = array ();
329
        $link_nodes = $xmlnode->getElementsByTagName("link");
330
        foreach ($link_nodes as $ln)
331
        {
332
            if ($ln->attributes->getNamedItem("rel")->nodeValue == "down" && $ln->attributes->getNamedItem("type")->nodeValue == "application/cmistree+xml")
333
            {
334
                //Descendents and children share same "rel" but different document type.
335
                $links["down-tree"] = $ln->attributes->getNamedItem("href")->nodeValue;
336
            } else
337
            {
338
                $links[$ln->attributes->getNamedItem("rel")->nodeValue] = $ln->attributes->getNamedItem("href")->nodeValue;
339
            }
340
        }
341
        return $links;
342
    }
343
	static function extractAllowableActions($xmldata)
344
    {
345
        $doc = new DOMDocument();
346
        $doc->loadXML($xmldata);
347
        return CMISRepositoryWrapper :: extractAllowableActionsFromNode($doc);
348
    }
349
    static function extractAllowableActionsFromNode($xmlnode)
350
    {
351
        $result = array();
352
        $allowableActions = $xmlnode->getElementsByTagName("allowableActions");
353
        if ($allowableActions->length > 0) {
354
            foreach($allowableActions->item(0)->childNodes as $action)
355
            {
356
                if (isset($action->localName)) {
357
                    $result[$action->localName] = (preg_match("/^true$/i", $action->nodeValue) > 0);
358
                }
359
            }
360
        }
361
        return $result;
362
    }
363
    static function extractObject($xmldata)
364
    {
365
        $doc = new DOMDocument();
366
        $doc->loadXML($xmldata);
367
        return CMISRepositoryWrapper :: extractObjectFromNode($doc);
368
369
    }
370
    static function extractObjectFromNode($xmlnode)
371
    {
372
        // Extracts the contents of an Object and organizes them into:
373
        //  -- Links
374
        //  -- Properties
375
        //  -- the Object ID
376
        // RRM -- NEED TO ADD ALLOWABLEACTIONS
377
        $retval = new stdClass();
378
        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
379
        $retval->properties = array ();
380
        $prop_nodes = $xmlnode->getElementsByTagName("object")->item(0)->getElementsByTagName("properties")->item(0)->childNodes;
381
        foreach ($prop_nodes as $pn)
382
        {
383
            if ($pn->attributes)
384
            {
385
                $propDefId = $pn->attributes->getNamedItem("propertyDefinitionId");
386
                // TODO: Maybe use ->length=0 to even detect null values
387
                if (!is_null($propDefId) && $pn->getElementsByTagName("value") && $pn->getElementsByTagName("value")->item(0))
388
                {
389
                	if ($pn->getElementsByTagName("value")->length > 1) {
390
                		$retval->properties[$propDefId->nodeValue] = array();
391
                		for ($idx=0;$idx < $pn->getElementsByTagName("value")->length;$idx++) {
392
                			$retval->properties[$propDefId->nodeValue][$idx] = $pn->getElementsByTagName("value")->item($idx)->nodeValue;
393
                		}
394
                	} else {
395
                		$retval->properties[$propDefId->nodeValue] = $pn->getElementsByTagName("value")->item(0)->nodeValue;
396
                	}
397
                }
398
            }
399
        }
400
        $retval->uuid = $xmlnode->getElementsByTagName("id")->item(0)->nodeValue;
401
        $retval->id = $retval->properties["cmis:objectId"];
402
        //TODO: RRM FIX THIS
403
        $children_node = $xmlnode->getElementsByTagName("children");
404
        if (is_object($children_node)) {
405
        	    $children_feed_c = $children_node->item(0);
406
        }
407
        if (is_object($children_feed_c)) {
408
			$children_feed_l = $children_feed_c->getElementsByTagName("feed");
409
        }
410
        if (isset($children_feed_l) && is_object($children_feed_l) && is_object($children_feed_l->item(0))) {
411
        	$children_feed = $children_feed_l->item(0);
412
			$children_doc = new DOMDocument();
413
			$xnode = $children_doc->importNode($children_feed,true); // Avoid Wrong Document Error
414
			$children_doc->appendChild($xnode);
415
	        $retval->children = CMISRepositoryWrapper :: extractObjectFeedFromNode($children_doc);
416
        }
417
		$retval->allowableActions = CMISRepositoryWrapper :: extractAllowableActionsFromNode($xmlnode);
418
        return $retval;
419
    }
420
421
    function handleSpaces($path)
422
    {
423
        return $this->do_not_urlencode ? $path : rawurlencode($path);
424
    }
425
426
    static function extractTypeDef($xmldata)
427
    {
428
        $doc = new DOMDocument();
429
        $doc->loadXML($xmldata);
430
        return CMISRepositoryWrapper :: extractTypeDefFromNode($doc);
431
432
    }
433
    static function extractTypeDefFromNode($xmlnode)
434
    {
435
        // Extracts the contents of an Object and organizes them into:
436
        //  -- Links
437
        //  -- Properties
438
        //  -- the Object ID
439
        // RRM -- NEED TO ADD ALLOWABLEACTIONS
440
        $retval = new stdClass();
441
        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
442
        $retval->properties = array ();
443
        $retval->attributes = array ();
444
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:type/*");
445
        foreach ($result as $node)
446
        {
447
            if ((substr($node->nodeName, 0, 13) == "cmis:property") && (substr($node->nodeName, -10) == "Definition"))
448
            {
449
                $id = $node->getElementsByTagName("id")->item(0)->nodeValue;
450
                $cardinality = $node->getElementsByTagName("cardinality")->item(0)->nodeValue;
451
                $propertyType = $node->getElementsByTagName("propertyType")->item(0)->nodeValue;
452
                // Stop Gap for now
453
                $retval->properties[$id] = array (
454
                    "cmis:propertyType" => $propertyType,
455
                    "cmis:cardinality" => $cardinality,
456
457
                );
458
            } else
459
            {
460
                $retval->attributes[$node->nodeName] = $node->nodeValue;
461
            }
462
            $retval->id = $retval->attributes["cmis:id"];
463
        }
464
        //TODO: RRM FIX THIS
465
        $children_node = $xmlnode->getElementsByTagName("children");
466
        if (is_object($children_node)) {
467
        	    $children_feed_c = $children_node->item(0);
468
        }
469
        if (is_object($children_feed_c)) {
470
			$children_feed_l = $children_feed_c->getElementsByTagName("feed");
471
        }
472
        if (is_object($children_feed_l) && is_object($children_feed_l->item(0))) {
473
        	$children_feed = $children_feed_l->item(0);
474
			$children_doc = new DOMDocument();
475
			$xnode = $children_doc->importNode($children_feed,true); // Avoid Wrong Document Error
476
			$children_doc->appendChild($xnode);
477
	        $retval->children = CMISRepositoryWrapper :: extractTypeFeedFromNode($children_doc);
478
        }
479
480
        /*
481
         *
482
483
484
485
        		$prop_nodes = $xmlnode->getElementsByTagName("object")->item(0)->getElementsByTagName("properties")->item(0)->childNodes;
486
        		foreach ($prop_nodes as $pn) {
487
        			if ($pn->attributes) {
488
        				$retval->properties[$pn->attributes->getNamedItem("propertyDefinitionId")->nodeValue] = $pn->getElementsByTagName("value")->item(0)->nodeValue;
489
        			}
490
        		}
491
                $retval->uuid=$xmlnode->getElementsByTagName("id")->item(0)->nodeValue;
492
                $retval->id=$retval->properties["cmis:objectId"];
493
         */
494
        return $retval;
495
    }
496
497
    static function extractObjectFeed($xmldata)
498
    {
499
        //Assumes only one workspace for now
500
        $doc = new DOMDocument();
501
        $doc->loadXML($xmldata);
502
        return CMISRepositoryWrapper :: extractObjectFeedFromNode($doc);
503
    }
504
    static function extractObjectFeedFromNode($xmlnode)
505
    {
506
        // Process a feed and extract the objects
507
        //   Does not handle hierarchy
508
        //   Provides two arrays
509
        //   -- one sequential array (a list)
510
        //   -- one hash table indexed by objectID
511
        //   and a property "numItems" that holds the total number of items available.
512
        $retval = new stdClass();
513
        // extract total number of items
514
        $numItemsNode = CMISRepositoryWrapper::doXQueryFromNode($xmlnode, "/atom:feed/cmisra:numItems");
515
        $retval->numItems = $numItemsNode->length ? (int) $numItemsNode->item(0)->nodeValue : -1; // set to negative value if info is not available
516
517
        $retval->objectList = array ();
518
        $retval->objectsById = array ();
519
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "/atom:feed/atom:entry");
520
        foreach ($result as $node)
521
        {
522
            $obj = CMISRepositoryWrapper :: extractObjectFromNode($node);
523
            $retval->objectsById[$obj->id] = $obj;
524
            $retval->objectList[] = & $retval->objectsById[$obj->id];
525
        }
526
        return $retval;
527
    }
528
529
    static function extractTypeFeed($xmldata)
530
    {
531
        //Assumes only one workspace for now
532
        $doc = new DOMDocument();
533
        $doc->loadXML($xmldata);
534
        return CMISRepositoryWrapper :: extractTypeFeedFromNode($doc);
535
    }
536
    static function extractTypeFeedFromNode($xmlnode)
537
    {
538
        // Process a feed and extract the objects
539
        //   Does not handle hierarchy
540
        //   Provides two arrays
541
        //   -- one sequential array (a list)
542
        //   -- one hash table indexed by objectID
543
        $retval = new stdClass();
544
        $retval->objectList = array ();
545
        $retval->objectsById = array ();
546
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "/atom:feed/atom:entry");
547
        foreach ($result as $node)
548
        {
549
            $obj = CMISRepositoryWrapper :: extractTypeDefFromNode($node);
550
            $retval->objectsById[$obj->id] = $obj;
551
            $retval->objectList[] = & $retval->objectsById[$obj->id];
552
        }
553
        return $retval;
554
    }
555
556
    static function extractWorkspace($xmldata)
557
    {
558
        //Assumes only one workspace for now
559
        $doc = new DOMDocument();
560
        $doc->loadXML($xmldata);
561
        return CMISRepositoryWrapper :: extractWorkspaceFromNode($doc);
562
    }
563
    static function extractWorkspaceFromNode($xmlnode)
564
    {
565
        // Assumes only one workspace for now
566
        // Load up the workspace object with arrays of
567
        //  links
568
        //  URI Templates
569
        //  Collections
570
        //  Capabilities
571
        //  General Repository Information
572
        $retval = new stdClass();
573
        $retval->links = CMISRepositoryWrapper :: getLinksArray($xmlnode);
574
        $retval->uritemplates = array ();
575
        $retval->collections = array ();
576
        $retval->capabilities = array ();
577
        $retval->repositoryInfo = array ();
578
        $retval->permissions = array();
579
        $retval->permissionsMapping = array();
580
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:uritemplate");
581
        foreach ($result as $node)
582
        {
583
            $retval->uritemplates[$node->getElementsByTagName("type")->item(0)->nodeValue] = $node->getElementsByTagName("template")->item(0)->nodeValue;
584
        }
585
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//app:collection");
586
        foreach ($result as $node)
587
        {
588
            $retval->collections[$node->getElementsByTagName("collectionType")->item(0)->nodeValue] = $node->attributes->getNamedItem("href")->nodeValue;
589
        }
590
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:capabilities/*");
591
        foreach ($result as $node)
592
        {
593
            $retval->capabilities[$node->nodeName] = $node->nodeValue;
594
        }
595
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmisra:repositoryInfo/*[name()!='cmis:capabilities' and name()!='cmis:aclCapability']");
596
        foreach ($result as $node)
597
        {
598
            $retval->repositoryInfo[$node->nodeName] = $node->nodeValue;
599
        }
600
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/cmis:permissions");
601
        foreach ($result as $node)
602
        {
603
            $retval->permissions[$node->getElementsByTagName("permission")->item(0)->nodeValue] = $node->getElementsByTagName("description")->item(0)->nodeValue;
604
        }
605
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/cmis:mapping");
606
        foreach ($result as $node)
607
        {
608
            $key = $node->getElementsByTagName("key")->item(0)->nodeValue;
609
            $values = array();
610
            foreach ($node->getElementsByTagName("permission") as $value)
611
            {
612
                array_push($values, $value->nodeValue);
613
            }
614
            $retval->permissionsMapping[$key] = $values;
615
        }
616
        $result = CMISRepositoryWrapper :: doXQueryFromNode($xmlnode, "//cmis:aclCapability/*[name()!='cmis:permissions' and name()!='cmis:mapping']");
617
        foreach ($result as $node)
618
        {
619
            $retval->repositoryInfo[$node->nodeName] = $node->nodeValue;
620
        }
621
622
        return $retval;
623
    }
624
}
625
626
// Option Contants for Array Indexing
627
// -- Generally optional flags that control how much information is returned
628
// -- Change log token is an anomoly -- but included in URL as parameter
629
define("OPT_MAX_ITEMS", "maxItems");
630
define("OPT_SKIP_COUNT", "skipCount");
631
define("OPT_FILTER", "filter");
632
define("OPT_INCLUDE_PROPERTY_DEFINITIONS", "includePropertyDefinitions");
633
define("OPT_INCLUDE_RELATIONSHIPS", "includeRelationships");
634
define("OPT_INCLUDE_POLICY_IDS", "includePolicyIds");
635
define("OPT_RENDITION_FILTER", "renditionFilter");
636
define("OPT_INCLUDE_ACL", "includeACL");
637
define("OPT_INCLUDE_ALLOWABLE_ACTIONS", "includeAllowableActions");
638
define("OPT_DEPTH", "depth");
639
define("OPT_CHANGE_LOG_TOKEN", "changeLogToken");
640
641
define("LINK_ALLOWABLE_ACTIONS", "http://docs.oasis-open.org/ns/cmis/link/200908/allowableactions");
642
643
define("MIME_ATOM_XML", 'application/atom+xml');
644
define("MIME_ATOM_XML_ENTRY", 'application/atom+xml;type=entry');
645
define("MIME_ATOM_XML_FEED", 'application/atom+xml;type=feed');
646
define("MIME_CMIS_TREE", 'application/cmistree+xml');
647
define("MIME_CMIS_QUERY", 'application/cmisquery+xml');
648
649
// Many Links have a pattern to them based upon objectId -- but can that be depended upon?
650
651
class CMISService extends CMISRepositoryWrapper
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
652
{
653
    var $_link_cache;
654
    var $_title_cache;
655
    var $_objTypeId_cache;
656
    var $_type_cache;
657
    function __construct($url, $username, $password, $options = null, array $addlCurlOptions = array())
658
    {
659
        parent :: __construct($url, $username, $password, $options, $addlCurlOptions);
660
        $this->_link_cache = array ();
661
        $this->_title_cache = array ();
662
        $this->_objTypeId_cache = array ();
663
        $this->_type_cache = array ();
664
    }
665
666
    // Utility Methods -- Added Titles
667
    // Should refactor to allow for single object
668
    function cacheObjectInfo($obj)
669
    {
670
        $this->_link_cache[$obj->id] = $obj->links;
671
        $this->_title_cache[$obj->id] = $obj->properties["cmis:name"]; // Broad Assumption Here?
672
        $this->_objTypeId_cache[$obj->id] = $obj->properties["cmis:objectTypeId"];
673
    }
674
675
    function cacheFeedInfo($objs)
676
    {
677
        foreach ($objs->objectList as $obj)
678
        {
679
            $this->cacheObjectInfo($obj);
680
        }
681
    }
682
683
    function cacheTypeFeedInfo($typs)
684
    {
685
        foreach ($typs->objectList as $typ)
686
        {
687
            $this->cacheTypeInfo($typ);
688
        }
689
    }
690
691
    function cacheTypeInfo($tDef)
692
    {
693
        // TODO: Fix Type Caching with missing properties
694
        $this->_type_cache[$tDef->id] = $tDef;
695
    }
696
697
    function getPropertyType($typeId, $propertyId)
698
    {
699
        if ($this->_type_cache[$typeId]->properties)
700
        {
701
            return $this->_type_cache[$typeId]->properties[$propertyId]["cmis:propertyType"];
702
        }
703
        $obj = $this->getTypeDefinition($typeId);
704
        return $obj->properties[$propertyId]["cmis:propertyType"];
705
    }
706
707
    function getObjectType($objectId)
708
    {
709
        if ($this->_objTypeId_cache[$objectId])
710
        {
711
            return $this->_objTypeId_cache[$objectId];
712
        }
713
        $obj = $this->getObject($objectId);
714
        return $obj->properties["cmis:objectTypeId"];
715
    }
716
717
    function getTitle($objectId)
718
    {
719
        if ($this->_title_cache[$objectId])
720
        {
721
            return $this->_title_cache[$objectId];
722
        }
723
        $obj = $this->getObject($objectId);
724
        return $obj->properties["cmis:name"];
725
    }
726
727
    function getTypeLink($typeId, $linkName)
728
    {
729
        if ($this->_type_cache[$typeId]->links)
730
        {
731
            return $this->_type_cache[$typeId]->links[$linkName];
732
        }
733
        $typ = $this->getTypeDefinition($typeId);
734
        return $typ->links[$linkName];
735
    }
736
737
    function getLink($objectId, $linkName)
738
    {
739
        if ($this->_link_cache[$objectId][$linkName])
740
        {
741
            return $this->_link_cache[$objectId][$linkName];
742
        }
743
        $obj = $this->getObject($objectId);
744
        return $obj->links[$linkName];
745
    }
746
747
    // Repository Services
748
    function getRepositories()
749
    {
750
        throw Exception("Not Implemented");
751
    }
752
753
    function getRepositoryInfo()
754
    {
755
        return $this->workspace;
756
    }
757
758
    function getTypeDescendants($typeId=null, $depth, $options = array ())
759
    {
760
    	// TODO: Refactor Type Entries Caching
761
        $varmap = $options;
762
        if ($typeId) {
763
	        $hash_values = $options;
764
	        $hash_values['depth'] = $depth;
765
	        $myURL = $this->getTypeLink($typeId, "down-tree");
766
	        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
767
        } else {
768
        	$myURL = $this->processTemplate($this->workspace->collections['http://docs.oasis-open.org/ns/cmis/link/200908/typedescendants'], $varmap);
769
        }
770
        $ret = $this->doGet($myURL);
771
        $typs = $this->extractTypeFeed($ret->body);
772
        $this->cacheTypeFeedInfo($typs);
773
        return $typs;
774
    }
775
776
    function getTypeChildren($typeId=null, $options = array ())
777
    {
778
    	// TODO: Refactor Type Entries Caching
779
        $varmap = $options;
780
        if ($typeId) {
781
	        $myURL = $this->getTypeLink($typeId, "down");
782
	        //TODO: Need GenURLQueryString Utility
783
        } else {
784
            //TODO: Need right URL
785
        	$myURL = $this->processTemplate($this->workspace->collections['types'], $varmap);
786
        }
787
        $ret = $this->doGet($myURL);
788
        $typs = $this->extractTypeFeed($ret->body);
789
        $this->cacheTypeFeedInfo($typs);
790
        return $typs;
791
    }
792
793
    function getTypeDefinition($typeId, $options = array ())
794
    { // Nice to have
795
        $varmap = $options;
796
        $varmap["id"] = $typeId;
797
        $myURL = $this->processTemplate($this->workspace->uritemplates['typebyid'], $varmap);
798
        $ret = $this->doGet($myURL);
799
        $obj = $this->extractTypeDef($ret->body);
800
        $this->cacheTypeInfo($obj);
801
        return $obj;
802
    }
803
804
    function getObjectTypeDefinition($objectId)
805
    { // Nice to have
806
        $myURL = $this->getLink($objectId, "describedby");
807
        $ret = $this->doGet($myURL);
808
        $obj = $this->extractTypeDef($ret->body);
809
        $this->cacheTypeInfo($obj);
810
        return $obj;
811
    }
812
    //Navigation Services
813
    function getFolderTree($folderId, $depth, $options = array ())
814
    {
815
        $hash_values = $options;
816
        $hash_values['depth'] = $depth;
817
        $myURL = $this->getLink($folderId, "http://docs.oasis-open.org/ns/cmis/link/200908/foldertree");
818
        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
819
        $ret = $this->doGet($myURL);
820
        $objs = $this->extractObjectFeed($ret->body);
821
        $this->cacheFeedInfo($objs);
822
        return $objs;
823
    }
824
825
    function getDescendants($folderId, $depth, $options = array ())
826
    { // Nice to have
827
        $hash_values = $options;
828
        $hash_values['depth'] = $depth;
829
        $myURL = $this->getLink($folderId, "down-tree");
830
        $myURL = CMISRepositoryWrapper :: getOpUrl ($myURL, $hash_values);
831
        $ret = $this->doGet($myURL);
832
        $objs = $this->extractObjectFeed($ret->body);
833
        $this->cacheFeedInfo($objs);
834
        return $objs;
835
    }
836
837
    function getChildren($folderId, $options = array ())
838
    {
839
        $myURL = $this->getLink($folderId, "down");
840
        //TODO: Need GenURLQueryString Utility
841
        $ret = $this->doGet($myURL);
842
        $objs = $this->extractObjectFeed($ret->body);
843
        $this->cacheFeedInfo($objs);
844
        return $objs;
845
    }
846
847
    function getFolderParent($folderId, $options = array ())
848
    { //yes
849
        $myURL = $this->getLink($folderId, "up");
850
        //TODO: Need GenURLQueryString Utility
851
        $ret = $this->doGet($myURL);
852
        $obj = $this->extractObjectEntry($ret->body);
0 ignored issues
show
Bug introduced by
The method extractObjectEntry() does not exist on CMISService. Did you maybe mean extractObject()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
853
        $this->cacheObjectInfo($obj);
854
        return $obj;
855
    }
856
857
    function getObjectParents($objectId, $options = array ())
858
    { // yes
859
        $myURL = $this->getLink($objectId, "up");
860
        //TODO: Need GenURLQueryString Utility
861
        $ret = $this->doGet($myURL);
862
        $objs = $this->extractObjectFeed($ret->body);
863
        $this->cacheFeedInfo($objs);
864
        return $objs;
865
    }
866
867
    function getCheckedOutDocs($options = array ())
868
    {
869
        $obj_url = $this->workspace->collections['checkedout'];
870
        $ret = $this->doGet($obj_url);
871
        $objs = $this->extractObjectFeed($ret->body);
872
        $this->cacheFeedInfo($objs);
873
        return $objs;
874
    }
875
876
    //Discovery Services
877
878
    static function getQueryTemplate()
879
    {
880
        ob_start();
881
        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
882
?>
883
<cmis:query xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/"
884
xmlns:cmism="http://docs.oasis-open.org/ns/cmis/messaging/200908/"
885
xmlns:atom="http://www.w3.org/2005/Atom"
886
xmlns:app="http://www.w3.org/2007/app"
887
xmlns:cmisra="http://docs.oasisopen.org/ns/cmis/restatom/200908/">
888
<cmis:statement>{q}</cmis:statement>
889
<cmis:searchAllVersions>{searchAllVersions}</cmis:searchAllVersions>
890
<cmis:includeAllowableActions>{includeAllowableActions}</cmis:includeAllowableActions>
891
<cmis:includeRelationships>{includeRelationships}</cmis:includeRelationships>
892
<cmis:renditionFilter>{renditionFilter}</cmis:renditionFilter>
893
<cmis:maxItems>{maxItems}</cmis:maxItems>
894
<cmis:skipCount>{skipCount}</cmis:skipCount>
895
</cmis:query>
896
<?php
897
898
        return ob_get_clean();
899
    }
900
    function query($statement, $options = array ())
901
    {
902
        static $query_template;
903
        if (!isset ($query_template))
904
        {
905
            $query_template = CMISService :: getQueryTemplate();
906
        }
907
        $hash_values = $options;
908
        $hash_values['q'] = $statement;
909
        $post_value = CMISRepositoryWrapper :: processTemplate($query_template, $hash_values);
910
        $ret = $this->doPost($this->workspace->collections['query'], $post_value, MIME_CMIS_QUERY);
911
        $objs = $this->extractObjectFeed($ret->body);
912
        $this->cacheFeedInfo($objs);
913
        return $objs;
914
    }
915
916
    function getContentChanges()
917
    {
918
        throw Exception("Not Implemented");
919
    }
920
921
    //Object Services
922
    static function getEntryTemplate()
923
    {
924
        ob_start();
925
        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . "\n";
926
?>
927
<atom:entry xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/"
928
xmlns:cmism="http://docs.oasis-open.org/ns/cmis/messaging/200908/"
929
xmlns:atom="http://www.w3.org/2005/Atom"
930
xmlns:app="http://www.w3.org/2007/app"
931
xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/">
932
<atom:title>{title}</atom:title>
933
{SUMMARY}
934
{CONTENT}
935
<cmisra:object><cmis:properties>{PROPERTIES}</cmis:properties></cmisra:object>
936
</atom:entry>
937
<?php
938
939
        return ob_get_clean();
940
    }
941
942
    static function getPropertyTemplate()
943
    {
944
        ob_start();
945
?>
946
		<cmis:property{propertyType} propertyDefinitionId="{propertyId}">
947
			<cmis:value>{properties}</cmis:value>
948
		</cmis:property{propertyType}>
949
<?php
950
951
        return ob_get_clean();
952
    }
953
954
    function processPropertyTemplates($objectType, $propMap)
955
    {
956
        static $propTemplate;
957
        static $propertyTypeMap;
958
        if (!isset ($propTemplate))
959
        {
960
            $propTemplate = CMISService :: getPropertyTemplate();
961
        }
962
        if (!isset ($propertyTypeMap))
963
        { // Not sure if I need to do this like this
964
            $propertyTypeMap = array (
965
                "integer" => "Integer",
966
                "boolean" => "Boolean",
967
                "datetime" => "DateTime",
968
                "decimal" => "Decimal",
969
                "html" => "Html",
970
                "id" => "Id",
971
                "string" => "String",
972
                "url" => "Url",
973
                "xml" => "Xml",
974
975
            );
976
        }
977
        $propertyContent = "";
978
        $hash_values = array ();
979
        foreach ($propMap as $propId => $propValue)
980
        {
981
            $hash_values['propertyType'] = $propertyTypeMap[$this->getPropertyType($objectType, $propId)];
982
            $hash_values['propertyId'] = $propId;
983
            if (is_array($propValue))
984
            {
985
                $first_one = true;
986
                $hash_values['properties'] = "";
987
                foreach ($propValue as $val)
988
                {
989
                    //This is a bit of a hack
990
                    if ($first_one)
991
                    {
992
                        $first_one = false;
993
                    } else
994
                    {
995
                        $hash_values['properties'] .= "</cmis:value>\n<cmis:value>";
996
                    }
997
                    $hash_values['properties'] .= $val;
998
                }
999
            } else
1000
            {
1001
                $hash_values['properties'] = $propValue;
1002
            }
1003
            //echo "HASH:\n";
1004
            //print_r(array("template" =>$propTemplate, "Hash" => $hash_values));
1005
            $propertyContent .= CMISRepositoryWrapper :: processTemplate($propTemplate, $hash_values);
1006
        }
1007
        return $propertyContent;
1008
    }
1009
1010
    static function getContentEntry($content, $content_type = "application/octet-stream")
1011
    {
1012
        static $contentTemplate;
1013
        if (!isset ($contentTemplate))
1014
        {
1015
            $contentTemplate = CMISService :: getContentTemplate();
1016
        }
1017
        if ($content)
1018
        {
1019
            return CMISRepositoryWrapper :: processTemplate($contentTemplate, array (
1020
                "content" => base64_encode($content
1021
            ), "content_type" => $content_type));
1022
        } else
1023
        {
1024
            return "";
1025
        }
1026
    }
1027
1028
    static function getSummaryTemplate()
1029
    {
1030
        ob_start();
1031
?>
1032
		<atom:summary>{summary}</atom:summary>
1033
<?php
1034
1035
        return ob_get_clean();
1036
    }
1037
1038
    static function getContentTemplate()
1039
    {
1040
        ob_start();
1041
?>
1042
		<cmisra:content>
1043
			<cmisra:mediatype>
1044
				{content_type}
1045
			</cmisra:mediatype>
1046
			<cmisra:base64>
1047
				{content}
1048
			</cmisra:base64>
1049
		</cmisra:content>
1050
<?php
1051
1052
        return ob_get_clean();
1053
    }
1054
    static function createAtomEntry($name, $properties)
1055
    {
1056
1057
    }
1058
    function getObject($objectId, $options = array ())
1059
    {
1060
        $varmap = $options;
1061
        $varmap["id"] = $objectId;
1062
        $obj_url = $this->processTemplate($this->workspace->uritemplates['objectbyid'], $varmap);
1063
        $ret = $this->doGet($obj_url);
1064
        $obj = $this->extractObject($ret->body);
1065
        $this->cacheObjectInfo($obj);
1066
        return $obj;
1067
    }
1068
1069
    function getObjectByPath($path, $options = array ())
1070
    {
1071
        $varmap = $options;
1072
        $varmap["path"] = $this->handleSpaces($path);
1073
        $obj_url = $this->processTemplate($this->workspace->uritemplates['objectbypath'], $varmap);
1074
        $ret = $this->doGet($obj_url);
1075
        $obj = $this->extractObject($ret->body);
1076
        $this->cacheObjectInfo($obj);
1077
        return $obj;
1078
    }
1079
1080
    function getProperties($objectId, $options = array ())
1081
    {
1082
        // May need to set the options array default --
1083
        return $this->getObject($objectId, $options);
1084
    }
1085
1086
    function getAllowableActions($objectId, $options = array ())
1087
    {
1088
        $myURL = $this->getLink($objectId, LINK_ALLOWABLE_ACTIONS);
1089
        $ret = $this->doGet($myURL);
1090
        $result = $this->extractAllowableActions($ret->body);
1091
        return $result;
1092
    }
1093
1094
    function getRenditions($objectId, $options = array (
1095
        OPT_RENDITION_FILTER => "*"
1096
    ))
1097
    {
1098
        return getObject($objectId, $options);
1099
    }
1100
1101
    function getContentStream($objectId, $options = array ())
1102
    { // Yes
1103
        $myURL = $this->getLink($objectId, "edit-media");
1104
        $ret = $this->doGet($myURL);
1105
        // doRequest stores the last request information in this object
1106
        return $ret->body;
1107
    }
1108
1109
    function postObject($folderId, $objectName, $objectType, $properties = array (), $content = null, $content_type = "application/octet-stream", $options = array ())
1110
    { // Yes
1111
        $myURL = $this->getLink($folderId, "down");
1112
        // TODO: Need Proper Query String Handling
1113
        // Assumes that the 'down' link does not have a querystring in it
1114
        $myURL = CMISRepositoryWrapper :: getOpUrl($myURL, $options);
1115
        static $entry_template;
1116
        if (!isset ($entry_template))
1117
        {
1118
            $entry_template = CMISService :: getEntryTemplate();
1119
        }
1120
        if (is_array($properties))
1121
        {
1122
            $hash_values = $properties;
1123
        } else
1124
        {
1125
            $hash_values = array ();
1126
        }
1127
        if (!isset ($hash_values["cmis:objectTypeId"]))
1128
        {
1129
            $hash_values["cmis:objectTypeId"] = $objectType;
1130
        }
1131
        $properties_xml = $this->processPropertyTemplates($hash_values["cmis:objectTypeId"], $hash_values);
1132
        if (is_array($options))
1133
        {
1134
            $hash_values = $options;
1135
        } else
1136
        {
1137
            $hash_values = array ();
1138
        }
1139
        $hash_values["PROPERTIES"] = $properties_xml;
1140
        $hash_values["SUMMARY"] = CMISService :: getSummaryTemplate();
1141
        if ($content)
1142
        {
1143
            $hash_values["CONTENT"] = CMISService :: getContentEntry($content, $content_type);
1144
        }
1145
        if (!isset ($hash_values['title']))
1146
        {
1147
            $hash_values['title'] = $objectName;
1148
        }
1149
        if (!isset ($hash_values['summary']))
1150
        {
1151
            $hash_values['summary'] = $objectName;
1152
        }
1153
        $post_value = CMISRepositoryWrapper :: processTemplate($entry_template, $hash_values);
1154
        $ret = $this->doPost($myURL, $post_value, MIME_ATOM_XML_ENTRY);
1155
        // print "DO_POST\n";
1156
        // print_r($ret);
1157
        $obj = $this->extractObject($ret->body);
1158
        $this->cacheObjectInfo($obj);
1159
        return $obj;
1160
    }
1161
1162
    function createDocument($folderId, $fileName, $properties = array (), $content = null, $content_type = "application/octet-stream", $options = array ())
1163
    { // Yes
1164
        return $this->postObject($folderId, $fileName, "cmis:document", $properties, $content, $content_type, $options);
1165
    }
1166
1167
    function createDocumentFromSource()
1168
    { //Yes?
1169
        throw new CmisNotSupportedException("createDocumentFromSource is not supported by the AtomPub binding!");
1170
    }
1171
1172
    function createFolder($folderId, $folderName, $properties = array (), $options = array ())
1173
    { // Yes
1174
        return $this->postObject($folderId, $folderName, "cmis:folder", $properties, null, null, $options);
1175
    }
1176
1177
    function createRelationship()
1178
    { // Not in first Release
1179
        throw Exception("Not Implemented");
1180
    }
1181
1182
    function createPolicy()
1183
    { // Not in first Release
1184
        throw Exception("Not Implemented");
1185
    }
1186
1187
    function updateProperties($objectId, $properties = array (), $options = array ())
1188
    { // Yes
1189
        $varmap = $options;
1190
        $varmap["id"] = $objectId;
1191
        $objectName = $this->getTitle($objectId);
1192
        $objectType = $this->getObjectType($objectId);
1193
        $obj_url = $this->getLink($objectId, "edit");
1194
        $obj_url = CMISRepositoryWrapper :: getOpUrl($obj_url, $options);
1195
        static $entry_template;
1196
        if (!isset ($entry_template))
1197
        {
1198
            $entry_template = CMISService :: getEntryTemplate();
1199
        }
1200
        if (is_array($properties))
1201
        {
1202
            $hash_values = $properties;
1203
        } else
1204
        {
1205
            $hash_values = array ();
1206
        }
1207
        $properties_xml = $this->processPropertyTemplates($objectType, $hash_values);
1208
        if (is_array($options))
1209
        {
1210
            $hash_values = $options;
1211
        } else
1212
        {
1213
            $hash_values = array ();
1214
        }
1215
        $hash_values["PROPERTIES"] = $properties_xml;
1216
        $hash_values["SUMMARY"] = CMISService :: getSummaryTemplate();
1217
        if (!isset ($hash_values['title']))
1218
        {
1219
            $hash_values['title'] = $objectName;
1220
        }
1221
        if (!isset ($hash_values['summary']))
1222
        {
1223
            $hash_values['summary'] = $objectName;
1224
        }
1225
        $put_value = CMISRepositoryWrapper :: processTemplate($entry_template, $hash_values);
1226
	 	// print $put_value; // RRM DEBUG
1227
        $ret = $this->doPut($obj_url, $put_value, MIME_ATOM_XML_ENTRY);
1228
        $obj = $this->extractObject($ret->body);
1229
        $this->cacheObjectInfo($obj);
1230
        return $obj;
1231
    }
1232
1233
    function moveObject($objectId, $targetFolderId, $sourceFolderId, $options = array ())
1234
    { //yes
1235
        $options['sourceFolderId'] = $sourceFolderId;
1236
        return $this->postObject($targetFolderId, $this->getTitle($objectId), $this->getObjectType($objectId), array (
1237
            "cmis:objectId" => $objectId
1238
        ), null, null, $options);
1239
    }
1240
1241
    function deleteObject($objectId, $options = array ())
1242
    { //Yes
1243
        $varmap = $options;
1244
        $varmap["id"] = $objectId;
1245
        $obj_url = $this->getLink($objectId, "edit");
1246
        $ret = $this->doDelete($obj_url);
1247
        return;
1248
    }
1249
1250
    function deleteTree()
1251
    { // Nice to have
1252
        throw Exception("Not Implemented");
1253
    }
1254
1255
    function setContentStream($objectId, $content, $content_type, $options = array ())
1256
    { //Yes
1257
        $myURL = $this->getLink($objectId, "edit-media");
1258
        $ret = $this->doPut($myURL, $content, $content_type);
1259
    }
1260
1261
    function deleteContentStream($objectId, $options = array ())
1262
    { //yes
1263
        $myURL = $this->getLink($objectId, "edit-media");
1264
        $ret = $this->doDelete($myURL);
1265
        return;
1266
    }
1267
1268
    //Versioning Services
1269
    function getPropertiesOfLatestVersion($objectId, $major =false, $options = array ())
1270
    {
1271
        return $this->getObjectOfLatestVersion($objectId, $major, $options);
1272
    }
1273
1274
    function getObjectOfLatestVersion($objectId, $major = false, $options = array ())
1275
    {
1276
        return $this->getObject($objectId, $options); // Won't be able to handle major/minor distinction
1277
        // Need to add this -- "current-version"
1278
        /*
1279
         * Headers: CMIS-filter, CMIS-returnVersion (enumReturnVersion)
1280
         * HTTP Arguments: filter, returnVersion
1281
         * Enum returnVersion: This, Latest, Major
1282
         */
1283
    }
1284
1285
    function getAllVersions()
1286
    {
1287
        throw Exception("Not Implemented");
1288
    }
1289
1290
    function checkOut()
1291
    {
1292
        throw Exception("Not Implemented");
1293
    }
1294
1295
    function checkIn()
1296
    {
1297
        throw Exception("Not Implemented");
1298
    }
1299
1300
    function cancelCheckOut()
1301
    {
1302
        throw Exception("Not Implemented");
1303
    }
1304
1305
    function deleteAllVersions()
1306
    {
1307
        throw Exception("Not Implemented");
1308
    }
1309
1310
    //Relationship Services
1311
    function getObjectRelationships()
1312
    {
1313
        // get stripped down version of object (for the links) and then get the relationships?
1314
        // Low priority -- can get all information when getting object
1315
        throw Exception("Not Implemented");
1316
    }
1317
1318
    //Multi-Filing Services
1319
    function addObjectToFolder()
1320
    { // Probably
1321
        throw Exception("Not Implemented");
1322
    }
1323
1324
    function removeObjectFromFolder()
1325
    { //Probably
1326
        throw Exception("Not Implemented");
1327
    }
1328
1329
    //Policy Services
1330
    function getAppliedPolicies()
1331
    {
1332
        throw Exception("Not Implemented");
1333
    }
1334
1335
    function applyPolicy()
1336
    {
1337
        throw Exception("Not Implemented");
1338
    }
1339
1340
    function removePolicy()
1341
    {
1342
        throw Exception("Not Implemented");
1343
    }
1344
1345
    //ACL Services
1346
    function getACL()
1347
    {
1348
        throw Exception("Not Implemented");
1349
    }
1350
1351
    function applyACL()
1352
    {
1353
        throw Exception("Not Implemented");
1354
    }
1355
}
1356