• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tempestphp / tempest-framework / 14049246919

24 Mar 2025 09:42PM UTC coverage: 79.353% (-0.04%) from 79.391%
14049246919

push

github

web-flow
feat(support): support array parameters in string manipulations (#1073)

48 of 48 new or added lines in 2 files covered. (100.0%)

735 existing lines in 126 files now uncovered.

10492 of 13222 relevant lines covered (79.35%)

90.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.78
/src/Tempest/Database/src/IsDatabaseModel.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\Database;
6

7
use Tempest\Database\Builder\ModelQueryBuilder;
8
use Tempest\Database\Builder\TableName;
9
use Tempest\Database\Config\DatabaseConfig;
10
use Tempest\Database\Exceptions\MissingRelation;
11
use Tempest\Database\Exceptions\MissingValue;
12
use Tempest\Database\TableName as TableNameAttribute;
13
use Tempest\Reflection\ClassReflector;
14
use Tempest\Reflection\PropertyReflector;
15

16
use function Tempest\get;
17
use function Tempest\make;
18

19
/** @phpstan-require-implements \Tempest\Database\DatabaseModel */
20
trait IsDatabaseModel
21
{
22
    public ?Id $id = null;
23

24
    public function __get(string $name): mixed
3✔
25
    {
26
        $property = PropertyReflector::fromParts($this, $name);
3✔
27

28
        if ($property->hasAttribute(Lazy::class)) {
3✔
29
            $this->load($name);
1✔
30

31
            return $property->getValue($this);
1✔
32
        }
33

34
        $type = $property->getType();
2✔
35

36
        if ($type->isIterable()) {
2✔
UNCOV
37
            throw new MissingRelation($this, $name);
×
38
        }
39

40
        if ($type->isBuiltIn()) {
2✔
41
            throw new MissingValue($this, $name);
1✔
42
        }
43

44
        throw new MissingRelation($this, $name);
1✔
45
    }
46

47
    public function setId(Id $id): self
57✔
48
    {
49
        $this->id = $id;
57✔
50

51
        return $this;
57✔
52
    }
53

54
    public function getId(): Id
19✔
55
    {
56
        return $this->id;
19✔
57
    }
58

59
    public static function table(): TableName
64✔
60
    {
61
        $specificName = new ClassReflector(static::class)
64✔
62
            ->getAttribute(TableNameAttribute::class)
64✔
63
            ?->name;
64✔
64

65
        $conventionalName = get(DatabaseConfig::class)
64✔
66
            ->namingStrategy
64✔
67
            ->getName(self::class);
64✔
68

69
        return new TableName($specificName ?? $conventionalName);
64✔
70
    }
71

72
    public static function new(mixed ...$params): self
62✔
73
    {
74
        return make(self::class)->from($params);
62✔
75
    }
76

77
    /**
78
     * @return \Tempest\Database\Builder\ModelQueryBuilder<self>
79
     */
80
    public static function query(): ModelQueryBuilder
49✔
81
    {
82
        return new ModelQueryBuilder(self::class);
49✔
83
    }
84

85
    /** @return self[] */
86
    public static function all(array $relations = []): array
14✔
87
    {
88
        return self::query()
14✔
89
            ->with(...$relations)
14✔
90
            ->all();
14✔
91
    }
92

93
    public static function get(Id $id, array $relations = []): ?self
20✔
94
    {
95
        return self::query()
20✔
96
            ->with(...$relations)
20✔
97
            ->get($id);
20✔
98
    }
99

100
    public static function find(mixed ...$conditions): ModelQueryBuilder
1✔
101
    {
102
        $query = self::query();
1✔
103

104
        array_walk($conditions, fn ($value, $column) => $query->whereField($column, $value));
1✔
105

106
        return $query;
1✔
107
    }
108

109
    public function load(string ...$relations): self
9✔
110
    {
111
        $new = self::get($this->getId(), $relations);
9✔
112

113
        foreach (new ClassReflector($new)->getPublicProperties() as $property) {
9✔
114
            $property->setValue($this, $property->getValue($new));
9✔
115
        }
116

117
        return $this;
9✔
118
    }
119

120
    public static function create(mixed ...$params): self
57✔
121
    {
122
        $model = self::new(...$params);
57✔
123

124
        $id = make(Query::class)->from($model)->execute();
57✔
125

126
        $model->setId($id);
57✔
127

128
        return $model;
57✔
129
    }
130

131
    public static function updateOrNew(array $find, array $update): self
1✔
132
    {
133
        $existing = self::query()->bind(...$find);
1✔
134

135
        foreach ($find as $key => $value) {
1✔
136
            $existing = $existing->where("{$key} = :{$key}");
1✔
137
        }
138

139
        $model = $existing->first() ?? self::new(...$find);
1✔
140

141
        foreach ($update as $key => $value) {
1✔
142
            $model->{$key} = $value;
1✔
143
        }
144

145
        return $model;
1✔
146
    }
147

148
    public static function updateOrCreate(array $find, array $update): self
1✔
149
    {
150
        return self::updateOrNew($find, $update)->save();
1✔
151
    }
152

153
    public function save(): self
39✔
154
    {
155
        $id = make(Query::class)->from($this)->execute();
39✔
156

157
        $this->setId($id);
39✔
158

159
        return $this;
39✔
160
    }
161

162
    public function update(mixed ...$params): self
1✔
163
    {
164
        foreach ($params as $key => $value) {
1✔
165
            $this->{$key} = $value;
1✔
166
        }
167

168
        $query = make(Query::class)->from($this);
1✔
169

170
        $query->execute();
1✔
171

172
        return $this;
1✔
173
    }
174

175
    public function delete(): void
2✔
176
    {
177
        $table = self::table();
2✔
178

179
        $query = new Query(
2✔
180
            sprintf(
2✔
181
                'DELETE FROM %s WHERE `id` = :id',
2✔
182
                $table,
2✔
183
            ),
2✔
184
            [
2✔
185
                'id' => $this->getId()->id,
2✔
186
            ],
2✔
187
        );
2✔
188

189
        $query->execute();
2✔
190
    }
191
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc