Completed
Branch 09branch (740a7d)
by Anton
02:52
created

TimestampsTrait::__describe__timestamps()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * spiral
4
 *
5
 * @author    Wolfy-J
6
 */
7
8
namespace Models\Traits;
9
10
use Spiral\Models\Events\DescribeEvent;
11
use Spiral\Models\Events\EntityEvent;
12
use Spiral\ODM\DocumentEntity;
13
use Spiral\ODM\Schemas\DocumentSchema;
14
use Spiral\ORM\RecordEntity;
15
use Spiral\ORM\Schemas\RecordSchema;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
18
/**
19
 * Timestamps traits adds two magic fields into model/document schema time updated and time created
20
 * automatically populated when entity being saved. Can be used in Models and Documents.
21
 *
22
 * ORM: time_created, time_updated
23
 * ODM: timeCreated, timeUpdated
24
 */
25
trait TimestampsTrait
26
{
27
    /**
28
     * Touch object and update it's time_updated value.
29
     *
30
     * @return $this
31
     */
32
    public function touch()
33
    {
34
        if ($this instanceof RecordEntity) {
35
            $this->setField('time_updated', new \DateTime(), false);
36
        } elseif ($this instanceof DocumentEntity) {
37
            $this->setField('timeUpdated', new \MongoDate(time()), false);
38
        }
39
40
        return $this;
41
    }
42
43
    /**
44
     * Called when model class are initiated.
45
     */
46
    protected static function __init__timestamps()
47
    {
48
        /**
49
         * Updates values of time_updated and time_created fields.
50
         */
51
        $listener = self::__timestamps__saveListener();
52
53
        self::events()->addListener('saving', $listener);
54
        self::events()->addListener('updating', $listener);
55
    }
56
57
    /**
58
     * When schema being analyzed.
59
     */
60
    protected static function __describe__timestamps()
61
    {
62
        self::events()->addListener('describe', self::__timestamps__describeListener());
63
    }
64
65
    /**
66
     * DataEntity save.
67
     *
68
     * @return \Closure
69
     */
70
    private static function __timestamps__saveListener()
71
    {
72
        return function (EntityEvent $event, $eventName) {
73
            $entity = $event->getEntity();
74
            if ($entity instanceof RecordEntity) {
75
                switch ($eventName) {
76
                    case 'create':
77
                        $entity->setField('time_created', new \DateTime(), false);
78
                    //no-break
79
                    case 'update':
80
                        $entity->setField('time_updated', new \DateTime(), false);
81
                }
82
            }
83
84
            if ($entity instanceof DocumentEntity) {
85
                switch ($eventName) {
86
                    case 'create':
87
                        $entity->setField('timeCreated', new \MongoDate(time()), false);
88
                    //no-break
89
                    case 'update':
90
                        $entity->setField('timeUpdated', new \MongoDate(time()), false);
91
                }
92
            }
93
        };
94
    }
95
96
    /**
97
     * Create appropriate schema modification listener. Executed only in analysis.
98
     *
99
     * @return callable
100
     */
101
    private static function __timestamps__describeListener()
102
    {
103
        return function (DescribeEvent $event) {
104
            if ($event->getProperty() != 'schema') {
105
                return;
106
            }
107
108
            $schema = $event->getValue();
109
110
            //Registering fields in schema
111
            switch (get_class($event->getReflection())) {
112
                case RecordSchema::class:
113
                    $schema += [
114
                        'time_created' => 'datetime, null',
115
                        'time_updated' => 'datetime, null'
116
                    ];
117
                    break;
118
                case DocumentSchema::class:
119
                    $schema += [
120
                        'timeCreated' => 'timestamp',
121
                        'timeUpdated' => 'timestamp'
122
                    ];
123
                    break;
124
            }
125
126
            //Updating schema value
127
            $event->setValue($schema);
128
        };
129
    }
130
131
    /**
132
     * @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
133
     */
134
    abstract public static function events(): EventDispatcherInterface;
135
}