Test Failed
Push — master ( ce60e5...378563 )
by Julien
12:41 queued 07:49
created

Uuid::initializeUuid()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4.0218

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 16
c 6
b 0
f 0
dl 0
loc 22
ccs 16
cts 18
cp 0.8889
rs 9.7333
cc 4
nc 1
nop 1
crap 4.0218
1
<?php
2
3
/**
4
 * This file is part of the Zemit Framework.
5
 *
6
 * (c) Zemit Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zemit\Mvc\Model;
13
14
use Phalcon\Db\RawValue;
15
use Phalcon\Encryption\Security;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Zemit\Mvc\Model\Security. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Phalcon\Mvc\EntityInterface;
17
use Zemit\Mvc\Model\AbstractTrait\AbstractBehavior;
18
use Zemit\Mvc\Model\AbstractTrait\AbstractInjectable;
19
use Zemit\Mvc\Model\Behavior\Transformable;
20
21
trait Uuid
22
{
23
    use AbstractBehavior;
24
    use AbstractInjectable;
25
    use Options;
26
    use Behavior;
27
    
28
    /**
29
     * Initializing Uuid
30
     */
31 2
    public function initializeUuid(?array $options = null): void
32
    {
33 2
        $options ??= $this->getOptionsManager()->get('uuid') ?? [];
34
        
35 2
        $field = $options['field'] ?? 'uuid';
36 2
        $native = $options['native'] ?? true;
37 2
        $binary = $options['binary'] ?? true;
38
        
39 2
        $security = $this->getDI()->get('security');
40 2
        assert($security instanceof Security);
41
        
42 2
        $this->setUuidBehavior(new Transformable([
43 2
            'beforeValidationOnCreate' => [
44 2
                $field => function (EntityInterface $model, string $field) use ($security, $native, $binary) {
45 1
                    return $model->readAttribute($field) ?? $native
46 1
                        ? ($binary
47 1
                            ? new RawValue('UUID_TO_BIN(UUID())')
48 1
                            : new RawValue('UUID()')
49 1
                        )
50
                        : ($binary
51
                            ? $this->getBinaryUuid($security->getRandom()->uuid())
52 1
                            : $security->getRandom()->uuid()
53 1
                        );
54 2
                },
55 2
            ],
56 2
//            'beforeValidation' => [
57 2
//                $field => function (EntityInterface $model, string $field) use ($security, $binary) {
58 2
//                    if ($binary) {
59 2
//                        // uuid field should remain unchanged
60 2
//                        return new RawValue('`' . $field . '`');
61 2
//                    }
62 2
//                },
63 2
//            ],
64 2
//            'afterFetch' => [
65 2
//                $field => function (EntityInterface $model, string $field) use ($binary) {
66 2
//                    // $native not yet supported while fetching
67 2
//                    $value = $model->readAttribute($field);
68 2
//                    if ($binary && !empty($value)) {
69 2
//                        $hex = bin2hex($value);
70 2
//                        return sprintf(
71 2
//                            '%s-%s-%s-%s-%s',
72 2
//                            substr($hex, 0, 8),
73 2
//                            substr($hex, 8, 4),
74 2
//                            substr($hex, 12, 4),
75 2
//                            substr($hex, 16, 4),
76 2
//                            substr($hex, 20, 12)
77 2
//                        );
78 2
//                    }
79 2
//                    return $value;
80 2
//                },
81 2
//            ],
82 2
        ]));
83
    }
84
    
85
    /**
86
     * Get Binary Uuid
87
     *
88
     * @param string $uuid The UUID string to convert to binary representation
89
     * @return string The binary representation of the given UUID
90
     */
91
    private function getBinaryUuid(string $uuid): string
92
    {
93
        return pack('h*', str_replace('-', '', $uuid));
94
    }
95
    
96
    /**
97
     * Set Uuid Behavior
98
     */
99 2
    public function setUuidBehavior(Transformable $uuidBehavior): void
100
    {
101 2
        $this->setBehavior('uuid', $uuidBehavior);
102
    }
103
    
104
    /**
105
     * Get Uuid Behavior
106
     */
107
    public function getUuidBehavior(): Transformable
108
    {
109
        $behavior = $this->getBehavior('uuid');
110
        assert($behavior instanceof Transformable);
111
        return $behavior;
112
    }
113
}
114