• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

podio-community / podio-php / 5754930657

pending completion
5754930657

push

github

daniel-sc
fix: removing overlooked podio client parameters

4 of 4 new or added lines in 1 file covered. (100.0%)

916 of 2104 relevant lines covered (43.54%)

32.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.93
/lib/PodioObject.php
1
<?php
2

3
class PodioObject
4
{
5
    private $__attributes = array();
6
    private $__belongs_to;
7
    private $__properties = array();
8
    private $__relationships = array();
9

10
    protected $__id_column;
11

12
    public function __construct()
13
    {
14
    }
788✔
15

16
    public function init($default_attributes = array())
17
    {
18
        if (is_int($default_attributes)) {
784✔
19
            $default_attributes = array('id' => $default_attributes);
12✔
20
        }
21
        if (is_string($default_attributes)) {
784✔
22
            $default_attributes = array('external_id' => $default_attributes);
4✔
23
        }
24
        if (!is_array($default_attributes)) {
784✔
25
            $default_attributes = array();
4✔
26
        }
27

28
        $has_api_values = !empty($default_attributes['__api_values']);
784✔
29

30
        // Create object instance from attributes
31
        foreach ($this->__properties as $name => $property) {
784✔
32
            if (isset($property['options']['id'])) {
784✔
33
                $this->__id_column = $name;
672✔
34
                if (array_key_exists('id', $default_attributes)) {
672✔
35
                    $this->id = $default_attributes['id'];
8✔
36
                }
37
            }
38
            if (array_key_exists($name, $default_attributes)) {
784✔
39

40
        // Special handling for PodioItemField values property so
41
                // we can construct using both the API format when receiving responses
42
                // and the much simpler podio-php format when constructing manually.
43
                if ($name == 'values' && !$has_api_values) {
720✔
44
                    $this->values = $default_attributes[$name];
64✔
45
                } else {
46
                    $this->set_attribute($name, $default_attributes[$name]);
720✔
47
                }
48
            }
49
        }
50
        if ($this->__relationships) {
784✔
51
            foreach ($this->__relationships as $name => $type) {
280✔
52
                if (array_key_exists($name, $default_attributes)) {
280✔
53
                    $property = $this->__properties[$name];
28✔
54
                    $class_name = 'Podio'.$property['type'];
28✔
55

56
                    if ($type == 'has_one') {
28✔
57
                        $child = is_object($default_attributes[$name]) ? $default_attributes[$name] : new $class_name($default_attributes[$name]);
12✔
58
                        $child->add_relationship($this, $name);
12✔
59
                        $this->set_attribute($name, $child);
12✔
60
                    } elseif ($type == 'has_many' && is_array($default_attributes[$name])) {
24✔
61

62
            // Special handling for ItemField and AppField.
63
                        // We need to create collection of the right type
64
                        if ($class_name == 'PodioItemField') {
16✔
65
                            $values = $default_attributes[$name];
×
66

67
                            // Make sure we pass along info on whether the values property
68
                            // contains API style values or not
69
                            $collection = new PodioItemFieldCollection($values, $has_api_values);
×
70
                        } elseif ($class_name == 'PodioAppField') {
16✔
71
                            $values = $default_attributes[$name];
4✔
72
                            $collection = new PodioAppFieldCollection($values);
4✔
73
                        } else {
74
                            $values = array();
12✔
75
                            foreach ($default_attributes[$name] as $value) {
12✔
76
                                $child = is_object($value) ? $value : new $class_name($value);
12✔
77
                                $values[] = $child;
12✔
78
                            }
79
                            $collection = new PodioCollection($values);
12✔
80
                        }
81
                        $collection->add_relationship($this, $name);
16✔
82
                        $this->set_attribute($name, $collection);
16✔
83
                    }
84
                }
85
            }
86
        }
87
    }
88
    public function __set($name, $value)
89
    {
90
        if ($name == 'id' && !empty($this->__id_column)) {
600✔
91
            return $this->set_attribute($this->__id_column, $value);
60✔
92
        }
93
        return $this->set_attribute($name, $value);
596✔
94
    }
95
    public function __get($name)
96
    {
97
        if ($name == 'id' && !empty($this->__id_column)) {
608✔
98
            return empty($this->__attributes[$this->__id_column]) ? null : $this->__attributes[$this->__id_column];
212✔
99
        }
100
        if ($this->has_attribute($name)) {
608✔
101
            // Create DateTime object if necessary
102
            if ($this->has_property($name) && ($this->__properties[$name]['type'] == 'datetime' || $this->__properties[$name]['type'] == 'date')) {
588✔
103
                $tz = new DateTimeZone('UTC');
24✔
104
                return DateTime::createFromFormat($this->date_format_for_property($name), $this->__attributes[$name], $tz);
24✔
105
            }
106

107
            return $this->__attributes[$name];
564✔
108
        }
109
    }
110
    public function __isset($name)
111
    {
112
        return isset($this->__attributes[$name]);
16✔
113
    }
114
    public function __unset($name)
115
    {
116
        unset($this->__attributes[$name]);
16✔
117
    }
118
    public function __toString()
119
    {
120
        return print_r($this->as_json(false), true);
×
121
    }
122

123
    public function date_format_for_property($name)
124
    {
125
        if ($this->has_property($name)) {
24✔
126
            if ($this->__properties[$name]['type'] == 'datetime') {
24✔
127
                return 'Y-m-d H:i:s';
12✔
128
            } elseif ($this->__properties[$name]['type'] == 'date') {
12✔
129
                return 'Y-m-d';
12✔
130
            }
131
        }
132
    }
133

134
    public function relationship()
135
    {
136
        return $this->__belongs_to;
12✔
137
    }
138

139
    public function add_relationship($instance, $property = 'fields')
140
    {
141
        $this->__belongs_to = array('property' => $property, 'instance' => $instance);
20✔
142
    }
143

144
    protected function set_attribute($name, $value)
145
    {
146
        if ($this->has_property($name)) {
776✔
147
            $property = $this->__properties[$name];
776✔
148
            switch ($property['type']) {
776✔
149
        case 'integer':
776✔
150
          $this->__attributes[$name] = $value ? (int)$value : null;
708✔
151
          break;
708✔
152
        case 'boolean':
772✔
153
          $this->__attributes[$name] = null;
116✔
154
          if ($value === true || $value === false) {
116✔
155
              $this->__attributes[$name] = $value;
116✔
156
          } elseif ($value) {
×
157
              $this->__attributes[$name] = in_array(trim(strtolower($value)), array('true', 1, 'yes'));
×
158
          }
159
          break;
116✔
160
        case 'datetime':
772✔
161
        case 'date':
772✔
162
          if (is_a($value, 'DateTime')) {
112✔
163
              $this->__attributes[$name] = $value->format($this->date_format_for_property($name));
16✔
164
          } else {
165
              $this->__attributes[$name] = $value;
112✔
166
          }
167
          break;
112✔
168
        case 'string':
772✔
169
          if (is_array($value)) {
760✔
170
              $value = join(', ', $value);
×
171
          }
172

173
          $this->__attributes[$name] = $value ? (string)$value : null;
760✔
174
          break;
760✔
175
        case 'array':
648✔
176
        case 'hash':
144✔
177
          $this->__attributes[$name] = $value ? (array)$value : array();
648✔
178
          break;
648✔
179
        default:
180
          $this->__attributes[$name] = $value;
44✔
181
      }
182
            return true;
776✔
183
        }
184
        throw new PodioDataIntegrityError("Attribute cannot be assigned. Property '{$name}' doesn't exist.");
×
185
    }
186

187
    public static function listing(PodioClient $podio_client, $response_or_attributes)
188
    {
189
        if ($response_or_attributes) {
4✔
190
            if (is_object($response_or_attributes) && get_class($response_or_attributes) == 'PodioResponse') {
4✔
191
                $body = $response_or_attributes->json_body();
×
192
            } else {
193
                $body = $response_or_attributes;
4✔
194
            }
195
            $list = array();
4✔
196
            foreach ($body as $attributes) {
4✔
197
                $class_name = get_called_class();
4✔
198
                $list[] = new $class_name(array_merge($attributes, array('__api_values' => true)));
4✔
199
            }
200
            return $list;
4✔
201
        }
202
    }
203

204
    public static function member(PodioClient $podio_client, $response)
205
    {
206
        if ($response) {
4✔
207
            $class_name = get_called_class();
4✔
208
            return new $class_name(array_merge($response instanceof PodioResponse ? $response->json_body() : $response, array('__api_values' => true)));
4✔
209
        }
210
    }
211

212
    public static function collection(PodioClient $podio_client, $response, $collection_type = "PodioCollection")
213
    {
214
        if ($response) {
×
215
            $body = $response->json_body();
×
216
            $list = array();
×
217
            if (isset($body['items'])) {
×
218
                foreach ($body['items'] as $attributes) {
×
219
                    $class_name = get_called_class();
×
220
                    $list[] = new $class_name(array_merge($attributes, array('__api_values' => true)));
×
221
                }
222
            }
223
            return new $collection_type($list, $body['filtered'], $body['total']);
×
224
        }
225
    }
226

227
    public function can($right)
228
    {
229
        if ($this->has_property('rights')) {
4✔
230
            return $this->has_attribute('rights') && in_array($right, $this->rights);
4✔
231
        }
232
        return false;
×
233
    }
234

235
    public function has_attribute($name)
236
    {
237
        return array_key_exists($name, $this->__attributes);
636✔
238
    }
239

240
    public function has_property($name)
241
    {
242
        return array_key_exists($name, $this->__properties);
784✔
243
    }
244

245
    public function has_relationship($name)
246
    {
247
        return array_key_exists($name, $this->__relationships);
280✔
248
    }
249

250
    public function properties()
251
    {
252
        return $this->__properties;
4✔
253
    }
254

255
    public function relationships()
256
    {
257
        return $this->__relationships;
4✔
258
    }
259

260
    /**
261
     * Raw access to attributes. Only used for unit testing. Do not use.
262
     */
263
    public function __attribute($name)
264
    {
265
        return $this->__attributes[$name];
260✔
266
    }
267

268
    // Define a property on this object
269
    public function property($name, $type, $options = array())
270
    {
271
        if (!$this->has_property($name)) {
784✔
272
            $this->__properties[$name] = array('type' => $type, 'options' => $options);
784✔
273
        }
274
    }
275

276
    public function has_one($name, $class_name, $options = array())
277
    {
278
        $this->property($name, $class_name, $options);
276✔
279
        if (!$this->has_relationship($name)) {
276✔
280
            $this->__relationships[$name] = 'has_one';
276✔
281
        }
282
    }
283

284
    public function has_many($name, $class_name, $options = array())
285
    {
286
        $this->property($name, $class_name, $options);
256✔
287
        if (!$this->has_relationship($name)) {
256✔
288
            $this->__relationships[$name] = 'has_many';
256✔
289
        }
290
    }
291

292
    public function as_json($encoded = true)
293
    {
294
        $result = array();
56✔
295
        foreach ($this->__properties as $name => $property) {
56✔
296
            if (!$this->has_relationship($name) && $this->has_attribute($name) && !is_null($this->__attributes[$name])) {
56✔
297
                $result[$name] = $this->__attributes[$name];
52✔
298
            }
299
        }
300
        foreach ($this->__relationships as $name => $type) {
56✔
301
            if ($type == 'has_one') {
56✔
302
                $target_name = $name;
52✔
303
                if (!empty($this->__properties[$name]['options']['json_target'])) {
52✔
304
                    $target_name = $this->__properties[$name]['options']['json_target'];
4✔
305
                }
306

307
                if ($this->has_attribute($name)) {
52✔
308
                    if (!empty($this->__properties[$name]['options']['json_value'])) {
4✔
309
                        $result[$target_name] = $this->__attributes[$name]->{$this->__properties[$name]['options']['json_value']};
×
310
                    } elseif (is_a($this->__attributes[$name], 'PodioFieldCollection')) {
4✔
311
                        foreach ($this->__attributes[$name] as $field) {
×
312
                            // Only use external_id for item fields
313
                            $key = $field->external_id && is_a($this->__attributes[$name], 'PodioItemFieldCollection') ? $field->external_id : $field->id;
×
314
                            $list[$key] = $field->as_json(false);
×
315
                        }
316
                        $result[$name] = $list;
×
317
                    } elseif (is_object($this->__attributes[$name]) && get_class($this->__attributes[$name]) == 'PodioReference') {
4✔
318
                        $result['ref_type'] = $this->__attributes[$name]->type;
×
319
                        $result['ref_id'] = $this->__attributes[$name]->id;
×
320
                    } else {
321
                        $child = $this->__attributes[$name]->as_json(false);
4✔
322
                        if ($child) {
4✔
323
                            $result[$target_name] = $child;
52✔
324
                        }
325
                    }
326
                }
327
            } elseif ($type == 'has_many') {
44✔
328
                if ($this->has_attribute($name)) {
44✔
329
                    $list = array();
8✔
330
                    foreach ($this->__attributes[$name] as $item) {
8✔
331
                        if (!empty($this->__properties[$name]['options']['json_value'])) {
8✔
332
                            $list[] = $item->{$this->__properties[$name]['options']['json_value']};
×
333
                        }
334
                        // TODO: This really should be moved to PodioCollection (should implement as_json)
335
                        //       and PodioItemFieldCollection for the special case
336
                        elseif (get_class($this->__attributes[$name]) === 'PodioItemFieldCollection') {
8✔
337
                            $key = $item->external_id ? $item->external_id : (string)$item->field_id;
4✔
338
                            $list[$key] = $item->as_json(false);
4✔
339
                        } else {
340
                            $list[] = $item->as_json(false);
4✔
341
                        }
342
                    }
343
                    if ($list) {
8✔
344
                        if (!empty($this->__properties[$name]['options']['json_target'])) {
8✔
345
                            $result[$this->__properties[$name]['options']['json_target']] = $list;
×
346
                        } else {
347
                            $result[$name] = $list;
8✔
348
                        }
349
                    }
350
                }
351
            }
352
        }
353

354
        if ($result) {
56✔
355
            return $encoded ? json_encode($result) : $result;
56✔
356
        }
357
        return null;
×
358
    }
359
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc