Issues (31)

src/Model/AbstractModel.php (3 issues)

1
<?php
2
3
namespace Pagantis\OrdersApiClient\Model;
4
5
use Nayjest\StrCaseConverter\Str;
6
7
/**
8
 * Class AbstractModel
9
 *
10
 * @package Pagantis\OrdersApiClient\Model
11
 */
12
abstract class AbstractModel implements ModelInterface
13
{
14
    /**
15
     * Export as Array the object recursively
16
     *
17
     * @param bool $validation
18
     *
19
     * @return \stdClass
20
     */
21
    public function export($validation = true)
22
    {
23
        $result = new \StdClass();
24
        foreach ($this as $key => $value) {
25
            if (!is_null($value)) {
26
                $result->{Str::toSnakeCase($key)} = $this->parseValue($value, $validation);
27
            }
28
        }
29
30
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type StdClass which is incompatible with the return type mandated by Pagantis\OrdersApiClient...odelInterface::export() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
31
    }
32
33
    /**
34
     * Parse the value of the object depending of type.
35
     *
36
     * @param $value
37
     * @param $validation
38
     *
39
     * @return array|string
40
     */
41
    protected function parseValue($value, $validation)
42
    {
43
        if (is_array($value) && !empty($value)) {
44
            $valueArray = array();
45
            foreach ($value as $subKey => $subValue) {
46
                if (is_object($subValue) && $subValue instanceof AbstractModel) {
47
                    $valueArray[Str::toSnakeCase($subKey)] = $subValue->export($validation);
48
                } else {
49
                    $valueArray[Str::toSnakeCase($subKey)] = $subValue;
50
                }
51
            }
52
            return $valueArray;
53
        }
54
        if (is_object($value) && $value instanceof AbstractModel && !empty($value)) {
55
            return $value->export();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value->export() returns the type stdClass which is incompatible with the documented return type array|string.
Loading history...
56
        }
57
        if (is_object($value) && $value instanceof \DateTime && !empty($value)) {
58
            return $value->format('Y-m-d\Th:i:s');
59
        }
60
61
        return $value;
62
    }
63
64
    /**
65
     * Fill Up the Order from the json_decode(false) result of the API response.
66
     *
67
     * @param \stdClass $object
68
     *
69
     * @throws \Exception
70
     */
71
    public function import($object)
72
    {
73
        if (is_object($object)) {
74
            $properties = get_object_vars($object);
75
            foreach ($properties as $key => $value) {
76
                if (property_exists($this, lcfirst(Str::toCamelCase($key)))) {
77
                    if (is_object($value)) {
78
                        $objectProperty = $this->{lcfirst(Str::toCamelCase($key))};
79
                        if ($objectProperty instanceof AbstractModel) {
80
                            $objectProperty->import($value);
81
                        }
82
                    } else {
83
                        if (is_string($value) && $this->validateDate($value)) {
84
                            $this->{lcfirst(Str::toCamelCase($key))} = new \DateTime($value);
85
                        } else {
86
                            $this->{lcfirst(Str::toCamelCase($key))} = $value;
87
                        }
88
                    }
89
                }
90
            }
91
        }
92
    }
93
94
    /**
95
     * @param $date
96
     *
97
     * @return bool
98
     */
99
    private function validateDate($date)
100
    {
101
        try {
102
            $dateTime = new \DateTime($date);
103
        } catch (\Exception $exception) {
104
            return false;
105
        }
106
107
        if ($dateTime && substr($dateTime->format('c'), 0, 19) === substr($date, 0, 19)) {
108
            return true;
109
        }
110
111
        return false;
112
    }
113
114
    /**
115
     * @param null $date
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $date is correct as it would always require null to be passed?
Loading history...
116
     * @return null | String
117
     */
118
    protected function checkDateFormat($date = null)
119
    {
120
        if (empty($date) || $date == '0000-00-00') {
121
            return null;
122
        }
123
        if ($date instanceof \DateTime) {
124
            return $date->format('Y-m-d');
125
        }
126
        try {
127
            $dateTime = new \DateTime(trim($date));
128
            $today = new \DateTime('tomorrow');
129
            if ($dateTime >= $today) {
130
                return null;
131
            }
132
            return $dateTime->format('Y-m-d');
133
        } catch (\Exception $exception) {
134
            return null;
135
        }
136
    }
137
138
}
139