Versioning::getRevisions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * This file is part of the Divergence package.
4
 *
5
 * (c) Henry Paradiz <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Divergence\Models;
12
13
use Exception;
14
15
use Divergence\Helpers\Util;
16
use Divergence\Models\Mapping\Column;
17
use Divergence\IO\Database\MySQL as DB;
18
use Divergence\IO\Database\Query\Insert;
19
use Divergence\IO\Database\Query\Select;
20
21
/**
22
 * Versioning.
23
 *
24
 * @package Divergence
25
 * @author  Henry Paradiz <[email protected]>
26
 * @inheritDoc
27
 * @property int $RevisionID ID of revision in the history table.
28
 * @property static[] $History All revisions for this object. This is hooked in the Relations trait.
29
 * @property string $historyTable
30
 * @property callable $createRevisionOnSave
31
 */
32
trait Versioning
33
{
34
    public $wasDirty = false;
35
36
    #[Column(type: "integer", unsigned:true, notnull:false)]
37
    protected $RevisionID;
38
39
    public static $versioningRelationships = [
40
        'History' => [
41
            'type' => 'history',
42
            'order' => ['RevisionID' => 'DESC'],
43
        ],
44
    ];
45
46
    /**
47
     * Returns static::$historyTable
48
     *
49
     * @throws Exception If static::$historyTable is not set.
50
     * @return string
51
     */
52 21
    public static function getHistoryTable()
53
    {
54 21
        if (!static::$historyTable) {
55 1
            throw new Exception('Static variable $historyTable must be defined to use model versioning.');
56
        }
57
58 21
        return static::$historyTable;
59
    }
60
61
    /**
62
     * The history table allows multiple records with the same ID.
63
     * The primary key becomes RevisionID.
64
     * This returns all the revisions by ID so you will get the history of that object.
65
     *
66
     * @return static[] Revisions by ID
67
     */
68 3
    public static function getRevisionsByID($ID, $options = [])
69
    {
70 3
        $options['conditions'][static::getPrimaryKey()] = $ID;
71
72 3
        return static::getRevisions($options);
73
    }
74
75
    /**
76
     * Gets all versions of all objects for this object.
77
     *
78
     * Use getRevisionsByID instead.
79
     *
80
     * @param array $options Query options
81
     * @return static[] Revisions
82
     */
83 5
    public static function getRevisions($options = [])
84
    {
85 5
        return static::instantiateRecords(static::getRevisionRecords($options));
86
    }
87
88
    /**
89
     * Gets raw revision data from the database and constructs a query
90
     *
91
     * @param array $options Query options
92
     * @return array
93
     */
94 5
    public static function getRevisionRecords($options = [])
95
    {
96 5
        $options = Util::prepareOptions($options, [
97 5
            'indexField' => false,
98 5
            'conditions' => [],
99 5
            'order' => false,
100 5
            'limit' => false,
101 5
            'offset' => 0,
102 5
        ]);
103
104
105 5
        $select = (new Select())->setTable(static::getHistoryTable());
106
107 5
        if ($options['conditions']) {
108 3
            $select->where(join(') AND (', static::_mapConditions($options['conditions'])));
109
        }
110
111 5
        if ($options['order']) {
112 3
            $select->order(join(',', static::_mapFieldOrder($options['order'])));
113
        }
114
115 5
        if ($options['limit']) {
116 1
            $select->limit(sprintf('%u,%u', $options['offset'], $options['limit']));
117
        }
118
119 5
        if ($options['indexField']) {
120
            return DB::table(static::_cn($options['indexField']), $select);
121
        } else {
122 5
            return DB::allRecords($select);
123
        }
124
    }
125
126
    /**
127
     * Sets wasDirty, isDirty, Created for the object before save
128
     *
129
     * @return void
130
     */
131 13
    public function beforeVersionedSave()
132
    {
133 13
        $this->wasDirty = false;
134 13
        if ($this->isDirty && static::$createRevisionOnSave) {
135
            // update creation time
136 12
            $this->Created = time();
137 12
            $this->wasDirty = true;
138
        }
139
    }
140
141
    /**
142
     * After save to regular database this saves to the history table
143
     *
144
     * @return void
145
     */
146 10
    public function afterVersionedSave()
147
    {
148 10
        if ($this->wasDirty && static::$createRevisionOnSave) {
149
            // save a copy to history table
150 10
            $recordValues = $this->_prepareRecordValues();
151 10
            $set = static::_mapValuesToSet($recordValues);
152 10
            DB::nonQuery((new Insert())->setTable(static::getHistoryTable())->set($set), null, [static::class,'handleError']);
153
        }
154
    }
155
}
156