Google_Service_Resource::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 4
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2010 Google Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
require_once 'Google/Client.php';
18
require_once 'Google/Exception.php';
19
require_once 'Google/Utils.php';
20
require_once 'Google/Http/Request.php';
21
require_once 'Google/Http/MediaFileUpload.php';
22
require_once 'Google/Http/REST.php';
23
24
/**
25
 * Implements the actual methods/resources of the discovered Google API using magic function
26
 * calling overloading (__call()), which on call will see if the method name (plus.activities.list)
27
 * is available in this service, and if so construct an apiHttpRequest representing it.
28
 *
29
 * @author Chris Chabot <[email protected]>
30
 * @author Chirag Shah <[email protected]>
31
 */
32
class Google_Service_Resource
33
{
34
    // Valid query parameters that work, but don't appear in discovery.
35
    private $stackParameters = [
36
        'alt'         => ['type' => 'string', 'location' => 'query'],
37
        'fields'      => ['type' => 'string', 'location' => 'query'],
38
        'trace'       => ['type' => 'string', 'location' => 'query'],
39
        'userIp'      => ['type' => 'string', 'location' => 'query'],
40
        'userip'      => ['type' => 'string', 'location' => 'query'],
41
        'quotaUser'   => ['type' => 'string', 'location' => 'query'],
42
        'data'        => ['type' => 'string', 'location' => 'body'],
43
        'mimeType'    => ['type' => 'string', 'location' => 'header'],
44
        'uploadType'  => ['type' => 'string', 'location' => 'query'],
45
        'mediaUpload' => ['type' => 'complex', 'location' => 'query'],
46
    ];
47
48
    /** @var Google_Service $service */
49
    private $service;
50
51
    /** @var Google_Client $client */
52
    private $client;
53
54
    /** @var string $serviceName */
55
    private $serviceName;
56
57
    /** @var string $resourceName */
58
    private $resourceName;
59
60
    /** @var array $methods */
61
    private $methods;
62
63
    public function __construct($service, $serviceName, $resourceName, $resource)
64
    {
65
        $this->service = $service;
66
        $this->client = $service->getClient();
67
        $this->serviceName = $serviceName;
68
        $this->resourceName = $resourceName;
69
        $this->methods = isset($resource['methods']) ?
70
            $resource['methods'] :
71
            [$resourceName => $resource];
72
    }
73
74
    /**
75
     * TODO(ianbarber): This function needs simplifying.
76
     *
77
     * @param $name
78
     * @param $arguments
79
     * @param $expected_class - optional, the expected class name
80
     *
81
     * @throws Google_Exception
82
     *
83
     * @return Google_Http_Request|expected_class
84
     */
85
    public function call($name, $arguments, $expected_class = null)
86
    {
87
        if (!isset($this->methods[$name])) {
88
            throw new Google_Exception(
89
                'Unknown function: '.
90
                "{$this->serviceName}->{$this->resourceName}->{$name}()"
91
            );
92
        }
93
        $method = $this->methods[$name];
94
        $parameters = $arguments[0];
95
96
        // postBody is a special case since it's not defined in the discovery
97
        // document as parameter, but we abuse the param entry for storing it.
98
        $postBody = null;
99
        if (isset($parameters['postBody'])) {
100
            if (is_object($parameters['postBody'])) {
101
                $parameters['postBody'] =
102
                    $this->convertToArrayAndStripNulls($parameters['postBody']);
103
            }
104
105
            $postBody = json_encode($parameters['postBody']);
106
            unset($parameters['postBody']);
107
        }
108
109
        // TODO(ianbarber): optParams here probably should have been
110
        // handled already - this may well be redundant code.
111
        if (isset($parameters['optParams'])) {
112
            $optParams = $parameters['optParams'];
113
            unset($parameters['optParams']);
114
            $parameters = array_merge($parameters, $optParams);
115
        }
116
117
        if (!isset($method['parameters'])) {
118
            $method['parameters'] = [];
119
        }
120
121
        $method['parameters'] = array_merge(
122
            $method['parameters'],
123
            $this->stackParameters
124
        );
125
        foreach ($parameters as $key => $val) {
126
            if ($key != 'postBody' && !isset($method['parameters'][$key])) {
127
                throw new Google_Exception("($name) unknown parameter: '$key'");
128
            }
129
        }
130
131
        foreach ($method['parameters'] as $paramName => $paramSpec) {
132
            if (isset($paramSpec['required']) &&
133
                $paramSpec['required'] &&
134
                !isset($parameters[$paramName])
135
            ) {
136
                throw new Google_Exception("($name) missing required param: '$paramName'");
137
            }
138
            if (isset($parameters[$paramName])) {
139
                $value = $parameters[$paramName];
140
                $parameters[$paramName] = $paramSpec;
141
                $parameters[$paramName]['value'] = $value;
142
                unset($parameters[$paramName]['required']);
143
            } else {
144
                // Ensure we don't pass nulls.
145
                unset($parameters[$paramName]);
146
            }
147
        }
148
149
        $servicePath = $this->service->servicePath;
150
151
        $url = Google_Http_REST::createRequestUri(
152
            $servicePath,
153
            $method['path'],
154
            $parameters
155
        );
156
157
        $httpRequest = new Google_Http_Request(
158
            $this->client,
159
            $url,
160
            $method['httpMethod'],
161
            null,
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
162
            $postBody
163
        );
164
165
        if ($postBody) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $postBody of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
166
            $contentTypeHeader = [];
167
            $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
168
            $httpRequest->setRequestHeaders($contentTypeHeader);
169
            $httpRequest->setPostBody($postBody);
170
        }
171
172
        $httpRequest = $this->client->getAuth()->sign($httpRequest);
173
        $httpRequest->setExpectedClass($expected_class);
174
175
        if (isset($parameters['data']) &&
176
            ($parameters['uploadType']['value'] == 'media' || $parameters['uploadType']['value'] == 'multipart')
177
        ) {
178
            // If we are doing a simple media upload, trigger that as a convenience.
179
            $mfu = new Google_Http_MediaFileUpload(
0 ignored issues
show
Unused Code introduced by
$mfu is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
180
                $this->client,
181
                $httpRequest,
182
                isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream',
183
                $parameters['data']['value']
184
            );
185
        }
186
187
        if ($this->client->shouldDefer()) {
188
            // If we are in batch or upload mode, return the raw request.
189
            return $httpRequest;
190
        }
191
192
        return $httpRequest->execute();
193
    }
194
195
    protected function convertToArrayAndStripNulls($o)
196
    {
197
        $o = (array) $o;
198
        foreach ($o as $k => $v) {
199
            if ($v === null) {
200
                unset($o[$k]);
201
            } elseif (is_object($v) || is_array($v)) {
202
                $o[$k] = $this->convertToArrayAndStripNulls($o[$k]);
203
            }
204
        }
205
206
        return $o;
207
    }
208
}
209