Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Base.php « Common « OpenCloud « lib « php-opencloud « 3rdparty « files_external « apps - github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f80c9320e2ac67e7c2e9f6c7ecc85f6a65d3479f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
<?php
/**
 * @copyright 2012-2013 Rackspace Hosting, Inc.
 * See COPYING for licensing information
 * @package phpOpenCloud
 * @version 1.0
 * @author Glen Campbell <glen.campbell@rackspace.com>
 * @author Jamie Hannaford <jamie.hannaford@rackspace.com>
 */

namespace OpenCloud\Common;

use OpenCloud\Common\Lang;
use OpenCloud\Common\Exceptions\AttributeError;
use OpenCloud\Common\Exceptions\JsonError;
use OpenCloud\Common\Exceptions\UrlError;

/**
 * The root class for all other objects used or defined by this SDK.
 *
 * It contains common code for error handling as well as service functions that
 * are useful. Because it is an abstract class, it cannot be called directly,
 * and it has no publicly-visible properties.
 */
abstract class Base
{

    private $http_headers = array();
    private $_errors = array();

    /**
     * Debug status.
     *
     * @var    LoggerInterface
     * @access private
     */
    private $logger;

    /**
     * Sets the Logger object.
     * 
     * @param \OpenCloud\Common\Log\LoggerInterface $logger
     */
    public function setLogger(Log\LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * Returns the Logger object.
     * 
     * @return \OpenCloud\Common\Log\AbstractLogger
     */
    public function getLogger()
    {
        if (null === $this->logger) {
            $this->setLogger(new Log\Logger);
        }
        return $this->logger;
    }

    /**
     * Returns the URL of the service/object
     *
     * The assumption is that nearly all objects will have a URL; at this
     * base level, it simply throws an exception to enforce the idea that
     * subclasses need to define this method.
     *
     * @throws UrlError
     */
    public function url($subresource = '')
    {
        throw new UrlError(Lang::translate(
            'URL method must be overridden in class definition'
        ));
    }

/**
     * Populates the current object based on an unknown data type.
     * 
     * @param  array|object|string|integer $info
     * @throws Exceptions\InvalidArgumentError
     */
    public function populate($info, $setObjects = true)
    {
        if (is_string($info) || is_integer($info)) {
            
            // If the data type represents an ID, the primary key is set
            // and we retrieve the full resource from the API
            $this->{$this->primaryKeyField()} = (string) $info;
            $this->refresh($info);
            
        } elseif (is_object($info) || is_array($info)) {
            
            foreach($info as $key => $value) {
                
                if ($key == 'metadata' || $key == 'meta') {
                    
                    if (empty($this->metadata) || !$this->metadata instanceof Metadata) {
                        $this->metadata = new Metadata;
                    }
                    
                    // Metadata
                    $this->$key->setArray($value);
                    
                } elseif (!empty($this->associatedResources[$key]) && $setObjects === true) {
                    
                    // Associated resource
                    try {
                        $resource = $this->service()->resource($this->associatedResources[$key], $value);
                        $resource->setParent($this);
                        $this->$key = $resource;
                    } catch (Exception\ServiceException $e) {}
                    
                } elseif (!empty($this->associatedCollections[$key]) && $setObjects === true) {
                    
                    // Associated collection
                    try {
                        $this->$key = $this->service()->resourceList($this->associatedCollections[$key], null, $this); 
                    } catch (Exception\ServiceException $e) {}
                    
                } else {
                    
                    // Normal key/value pair
                    $this->$key = $value; 
                }
            }
        } elseif (null !== $info) {
            throw new Exceptions\InvalidArgumentError(sprintf(
                Lang::translate('Argument for [%s] must be string or object'), 
                get_class()
            ));
        }
    }
    
    /**
     * Sets extended attributes on an object and validates them
     *
     * This function is provided to ensure that attributes cannot
     * arbitrarily added to an object. If this function is called, it
     * means that the attribute is not defined on the object, and thus
     * an exception is thrown.
     *
     * @codeCoverageIgnore
     * 
     * @param string $property the name of the attribute
     * @param mixed $value the value of the attribute
     * @return void
     */
    public function __set($property, $value)
    {
        $this->setProperty($property, $value);
    }

    /**
     * Sets an extended (unrecognized) property on the current object
     *
     * If RAXSDK_STRICT_PROPERTY_CHECKS is TRUE, then the prefix of the
     * property name must appear in the $prefixes array, or else an
     * exception is thrown.
     *
     * @param string $property the property name
     * @param mixed $value the value of the property
     * @param array $prefixes optional list of supported prefixes
     * @throws \OpenCloud\AttributeError if strict checks are on and
     *      the property prefix is not in the list of prefixes.
     */
    public function setProperty($property, $value, array $prefixes = array())
    {
        // if strict checks are off, go ahead and set it
        if (!RAXSDK_STRICT_PROPERTY_CHECKS 
            || $this->checkAttributePrefix($property, $prefixes)
        ) {
            $this->$property = $value;
        } else {
            // if that fails, then throw the exception
            throw new AttributeError(sprintf(
                Lang::translate('Unrecognized attribute [%s] for [%s]'),
                $property,
                get_class($this)
            ));
        }
    }

    /**
     * Converts an array of key/value pairs into a single query string
     *
     * For example, array('A'=>1,'B'=>2) would become 'A=1&B=2'.
     *
     * @param array $arr array of key/value pairs
     * @return string
     */
    public function makeQueryString($array)
    {
        $queryString = '';

        foreach($array as $key => $value) {
            if ($queryString) {
                $queryString .= '&';
            }
            $queryString .= urlencode($key) . '=' . urlencode($this->to_string($value));
        }

        return $queryString;
    }

    /**
     * Checks the most recent JSON operation for errors
     *
     * This function should be called after any `json_*()` function call.
     * This ensures that nasty JSON errors are detected and the proper
     * exception thrown.
     *
     * Example:
     *   `$obj = json_decode($string);`
     *   `if (check_json_error()) do something ...`
     *
     * @return boolean TRUE if an error occurred, FALSE if none
     * @throws JsonError
     * 
     * @codeCoverageIgnore
     */
    public function checkJsonError()
    {
        switch (json_last_error()) {
            case JSON_ERROR_NONE:
                return;
            case JSON_ERROR_DEPTH:
                $jsonError = 'JSON error: The maximum stack depth has been exceeded';
                break;
            case JSON_ERROR_STATE_MISMATCH:
                $jsonError = 'JSON error: Invalid or malformed JSON';
                break;
            case JSON_ERROR_CTRL_CHAR:
                $jsonError = 'JSON error: Control character error, possibly incorrectly encoded';
                break;
            case JSON_ERROR_SYNTAX:
                $jsonError = 'JSON error: Syntax error';
                break;
            case JSON_ERROR_UTF8:
                $jsonError = 'JSON error: Malformed UTF-8 characters, possibly incorrectly encoded';
                break;
            default:
                $jsonError = 'Unexpected JSON error';
                break;
        }
        
        if (isset($jsonError)) {
            throw new JsonError(Lang::translate($jsonError));
        }
    }

    /**
     * Returns a class that implements the HttpRequest interface.
     *
     * This can be stubbed out for unit testing and avoid making live calls.
     */
    public function getHttpRequestObject($url, $method = 'GET', array $options = array())
    {
        return new Request\Curl($url, $method, $options);
    }

    /**
     * Checks the attribute $property and only permits it if the prefix is
     * in the specified $prefixes array
     *
     * This is to support extension namespaces in some services.
     *
     * @param string $property the name of the attribute
     * @param array $prefixes a list of prefixes
     * @return boolean TRUE if valid; FALSE if not
     */
    private function checkAttributePrefix($property, array $prefixes = array())
    {
        $prefix = strstr($property, ':', true);

        if (in_array($prefix, $prefixes)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Converts a value to an HTTP-displayable string form
     *
     * @param mixed $x a value to convert
     * @return string
     */
    private function to_string($x)
    {
        if (is_bool($x) && $x) {
            return 'True';
        } elseif (is_bool($x)) {
            return 'False';
        } else {
            return (string) $x;
        }
    }

}