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\Controller\Traits; |
13
|
|
|
|
14
|
|
|
use Phalcon\Mvc\ModelInterface; |
15
|
|
|
use Zemit\Mvc\Controller\Traits\Abstracts\AbstractInjectable; |
16
|
|
|
use Zemit\Mvc\Controller\Traits\Abstracts\AbstractModel; |
17
|
|
|
|
18
|
|
|
trait Model |
19
|
|
|
{ |
20
|
|
|
use AbstractModel; |
21
|
|
|
|
22
|
|
|
use AbstractInjectable; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* The name of the model. |
26
|
|
|
* @var ?string |
27
|
|
|
*/ |
28
|
|
|
protected ?string $modelName; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* The namespaces for the model lookup. |
32
|
|
|
* @var string[] |
33
|
|
|
*/ |
34
|
|
|
protected ?array $modelNamespaces; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Retrieves the name of the model associated with the controller. |
38
|
|
|
* |
39
|
|
|
* @return string|null The name of the model associated with the controller, or null if not found. |
40
|
|
|
*/ |
41
|
|
|
public function getModelName(): ?string |
42
|
|
|
{ |
43
|
|
|
if (!isset($this->modelName)) { |
44
|
|
|
$this->modelName = $this->getModelNameFromController(); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
return $this->modelName; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Sets the name of the model to be used. |
52
|
|
|
* |
53
|
|
|
* @param string|null $modelName The name of the model to be set. |
54
|
|
|
* |
55
|
|
|
* @return void |
56
|
|
|
*/ |
57
|
|
|
public function setModelName(?string $modelName): void |
58
|
|
|
{ |
59
|
|
|
$this->modelName = $modelName; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Gets the namespaces used for the model lookup. |
64
|
|
|
* If no model namespace is set, the namespaces defined in the loader will be returned. |
65
|
|
|
* |
66
|
|
|
* @return array The namespaces used for the model lookup. |
67
|
|
|
*/ |
68
|
|
|
public function getModelNamespaces(): array |
69
|
|
|
{ |
70
|
|
|
if (!isset($this->modelNamespaces)) { |
71
|
|
|
$this->modelNamespaces = $this->loader->getNamespaces(); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
return $this->modelNamespaces ?? []; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Set the namespaces for the models. |
79
|
|
|
* |
80
|
|
|
* @param array|null $modelNamespaces The array of namespaces for the models. |
81
|
|
|
* |
82
|
|
|
* @return void |
83
|
|
|
*/ |
84
|
|
|
public function setModelNamespaces(?array $modelNamespaces): void |
85
|
|
|
{ |
86
|
|
|
$this->modelNamespaces = $modelNamespaces; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Retrieves the model name from the controller by following certain naming conventions. |
91
|
|
|
* |
92
|
|
|
* @param array|null $namespaces Optional. An array of namespaces to search for the model. Default is null and will use $this->getModelNamespaces(). |
93
|
|
|
* @param string $needle Optional. The keyword to search for in the namespace. Default is 'Models'. |
94
|
|
|
* |
95
|
|
|
* @return string|null The model name if found, otherwise null. |
96
|
|
|
*/ |
97
|
|
|
public function getModelNameFromController(?array $namespaces = null, string $needle = 'Models'): ?string |
98
|
|
|
{ |
99
|
|
|
$model = ucfirst( |
100
|
|
|
$this->helper->camelize( |
101
|
|
|
$this->helper->uncamelize( |
102
|
|
|
$this->getControllerName() |
103
|
|
|
) |
104
|
|
|
) |
105
|
|
|
); |
106
|
|
|
|
107
|
|
|
if (class_exists($model)) { |
108
|
|
|
return $model; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
$namespaces ??= $this->getModelNamespaces(); |
112
|
|
|
foreach ($namespaces as $namespace => $path) { |
113
|
|
|
if (str_contains($namespace, $needle)) { |
114
|
|
|
$possibleModel = $namespace . $model; |
115
|
|
|
if (class_exists($possibleModel) && is_subclass_of($possibleModel, ModelInterface::class)) { |
116
|
|
|
return $possibleModel; |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return null; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Returns the name of the controller. |
126
|
|
|
* |
127
|
|
|
* If the controller name is not set in the dispatcher, it extracts the controller name from the class name |
128
|
|
|
* of the current instance. |
129
|
|
|
* |
130
|
|
|
* @return string The name of the controller. |
131
|
|
|
*/ |
132
|
|
|
public function getControllerName(): string |
133
|
|
|
{ |
134
|
|
|
return $this->dispatcher->getControllerName() |
135
|
|
|
?: substr(basename(str_replace('\\', '/', get_class($this))), 0, -10); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* Loads a model by its name using the modelsManager. |
140
|
|
|
* |
141
|
|
|
* @param string|null $modelName The name of the model to load. Default is null and will use $this->getModelName(). |
142
|
|
|
* |
143
|
|
|
* @return ModelInterface The loaded model. |
144
|
|
|
*/ |
145
|
|
|
public function loadModel(?string $modelName = null): ModelInterface |
146
|
|
|
{ |
147
|
|
|
$modelName ??= $this->getModelName() ?? ''; |
148
|
|
|
return $this->modelsManager->load($modelName); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Appends the model name to the specified field string, if not already present. |
153
|
|
|
* |
154
|
|
|
* @param string $field The field string to append the model name to. |
155
|
|
|
* @param string|null $modelName The name of the model to append. If null, the default model name will be used. |
156
|
|
|
* |
157
|
|
|
* @return string The modified field string with the model name appended. |
158
|
|
|
*/ |
159
|
|
|
public function appendModelName(string $field, ?string $modelName = null): string |
160
|
|
|
{ |
161
|
|
|
$modelName ??= $this->getModelName(); |
162
|
|
|
|
163
|
|
|
if (empty($field)) { |
164
|
|
|
return $field; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
// Add the current model name by default |
168
|
|
|
$explode = explode(' ', $field); |
169
|
|
|
if (!strpos($field, '.') !== false) { |
170
|
|
|
$field = trim('[' . $modelName . '].[' . array_shift($explode) . '] ' . implode(' ', $explode)); |
171
|
|
|
} |
172
|
|
|
else if (!str_contains($field, ']') && !str_contains($field, '[')) { |
173
|
|
|
$field = trim('[' . implode('].[', explode('.', array_shift($explode))) . ']' . implode(' ', $explode)); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
return $field; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|