Passed
Pull Request — develop (#49)
by
unknown
02:00
created

RestObject::validateUniqueFieldDataType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 17
c 0
b 0
f 0
ccs 11
cts 11
cp 1
rs 9.4285
cc 2
eloc 11
nc 2
nop 2
crap 2
1
<?php
2
namespace Fathomminds\Rest\Database\Clusterpoint;
3
4
use Fathomminds\Rest\Exceptions\RestException;
5
use Fathomminds\Rest\Objects\RestObject as CoreRestObject;
6
7
class RestObject extends CoreRestObject
8
{
9
    protected $primaryKey = '_id';
10
    protected $databaseClass = Database::class;
11
12 3
    public function find($client = null)
13
    {
14 3
        if ($client === null) {
15 1
            $client = $this->getClient();
16
        }
17 3
        return (new Finder($client))
18 3
            ->database($this->getDatabaseName())
19 3
            ->from($this->getResourceName());
20
    }
21
22 6
    public function validateUniqueFields()
23
    {
24 6
        $query = $this->getUniqueFieldQuery();
25 6
        $res = $query->get();
26 6
        if ((int)$res->hits() > 0) {
27 2
            $results = json_decode($res->rawResponse())->results;
28 2
            $message = $results[0]->{$this->primaryKey} === $this->getPrimaryKeyValue() ?
29 2
                'Primary key collision' : 'Unique constraint violation';
30 2
            throw new RestException(
31 2
                $message,
32 2
                ['resourceName' => $this->resourceName, 'confilct' => $results[0]]
33
            );
34
        }
35 4
    }
36
37 6
    private function getUniqueFieldQuery()
38
    {
39 6
        $uniqueFields = $this->getUniqueFields();
40 6
        $query = $this->getClient()->database($this->getDatabaseName() . '.' . $this->resourceName);
41 6
        if ($this->isModification()) {
42 2
            $uniqueFields = array_diff($uniqueFields, [$this->primaryKey]);
43 2
            $query->where($this->primaryKey, '!=', $this->getPrimaryKeyValue());
44
        }
45
        // @codeCoverageIgnoreStart
46
        $query->where(function($query) use ($uniqueFields) {
47
            foreach ($uniqueFields as $fieldName) {
48
                list($propertyExists, $propertyValue) = $this->getProperty($fieldName);
49
                if ($propertyExists) {
50
                    $this->validateUniqueFieldDataType($fieldName, $propertyValue);
51
                    $query->orWhere($fieldName, '==', $propertyValue);
52
                }
53
            }
54
        });
55
        // @codeCoverageIgnoreEnd
56 6
        return $query->limit(1);
57
    }
58
59 1
    private function getProperty($fieldNameDotted, $resource = null)
60
    {
61 1
        if ($resource === null) {
62 1
            $resource = $this->resource;
63
        }
64 1
        $fieldNameArr = explode('.', $fieldNameDotted);
65 1
        $fieldName = array_shift($fieldNameArr);
66 1
        if (!property_exists($resource, $fieldName)) {
67
            return [
68 1
                false,
69
                null
70
            ];
71
        }
72 1
        if (count($fieldNameArr) === 0) {
73
            return [
74 1
                true,
75 1
                $resource->{$fieldName}
76
            ];
77
        }
78 1
        return $this->getProperty(implode('.', $fieldNameArr), $resource->{$fieldName});
79
    }
80
81 1
    private function validateUniqueFieldDataType($fieldName, $propertyValue)
82
    {
83 1
        $dataType = gettype($propertyValue);
84 1
        if (in_array($dataType, $this->validUniqueFieldTypes)) {
85 1
            return;
86
        }
87 1
        throw new RestException(
88 1
            'Data type is invalid for unique field',
89
            [
90 1
                'resourceName' => $this->resourceName,
91 1
                'fieldName' => $fieldName,
92 1
                'data' => $propertyValue,
93 1
                'dataType' => $dataType,
94 1
                'validDataTypes' => $this->validUniqueFieldTypes
95
            ]
96
        );
97
    }
98
99 6
    private function isModification()
100
    {
101 6
        if ($this->updateMode() || $this->replaceMode()) {
102 2
            return true;
103
        }
104 4
        return false;
105
    }
106
107 1
    public function query()
108
    {
109 1
        $query = $this->getClient()->database($this->getDatabaseName() . '.' . $this->resourceName);
110 1
        return $query;
111
    }
112
}
113