Skip to content

Commit f2ff412

Browse files
committed
feat: add Model abstract class
1 parent 99c22fe commit f2ff412

1 file changed

Lines changed: 251 additions & 0 deletions

File tree

src/Model/Model.php

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<?php
2+
3+
/**
4+
*
5+
* Model class
6+
*
7+
* @copyright Apereo
8+
* @category OpenLRW
9+
* @package Entity
10+
* @author Xavier Chopin <bonjour@xavierchop.in>
11+
* @license http://www.osedu.org/licenses/ECL-2.0 ECL-2.0 License
12+
*/
13+
14+
namespace OpenLRW\Model;
15+
16+
abstract class Model
17+
{
18+
19+
/**
20+
* The model's attributes.
21+
*
22+
* @var array
23+
*/
24+
protected $attributes = array();
25+
26+
27+
/**
28+
* The primary key for the model.
29+
*
30+
* @var string
31+
*/
32+
protected $primaryKey = 'sourcedId';
33+
34+
35+
/**
36+
* The attributes that are mass assignable.
37+
*
38+
* @var array
39+
*/
40+
protected $fillable = array();
41+
42+
43+
/**
44+
* Create a new model instance.
45+
*
46+
* @param array $attributes
47+
* @return void
48+
*/
49+
public function __construct(array $attributes = array())
50+
{
51+
$this->fill($attributes);
52+
}
53+
54+
/**
55+
* Fill the model with an array of attributes.
56+
*
57+
* @param array $attributes
58+
* @return $this
59+
*
60+
*/
61+
public function fill(array $attributes)
62+
{
63+
foreach ($this->fillableFromArray($attributes) as $key => $value)
64+
{
65+
$this->setAttribute($key, $value);
66+
}
67+
return $this;
68+
}
69+
70+
/**
71+
* Get the fillable attributes of a given array.
72+
*
73+
* @param array $attributes
74+
* @return array
75+
*/
76+
protected function fillableFromArray(array $attributes)
77+
{
78+
if (count($this->fillable) > 0)
79+
{
80+
return array_intersect_key($attributes, array_flip($this->fillable));
81+
}
82+
return $attributes;
83+
}
84+
85+
/**
86+
* Set a given attribute on the model.
87+
*
88+
* @param string $key
89+
* @param mixed $value
90+
* @return void
91+
*/
92+
public function setAttribute($key, $value)
93+
{
94+
// First we will check for the presence of a mutator for the set operation
95+
// which simply lets the developers tweak the attribute as it is set on
96+
// the model, such as "json_encoding" an listing of data for storage.
97+
if ($this->hasSetMutator($key)) {
98+
$method = 'set'.$this->studly_case($key).'Attribute';
99+
return $this->{$method}($value);
100+
}
101+
102+
103+
$this->attributes[$key] = $value;
104+
}
105+
106+
107+
/**
108+
* Determine if a set mutator exists for an attribute.
109+
*
110+
* @param string $key
111+
* @return bool
112+
*/
113+
public function hasSetMutator($key)
114+
{
115+
return method_exists($this, 'set'.$this->studly_case($key).'Attribute');
116+
}
117+
118+
/**
119+
* Convert a value to studly caps case.
120+
*
121+
* @param string $value
122+
* @return string
123+
*/
124+
public function studly_case($value)
125+
{
126+
$value = ucwords(str_replace(['-', '_'], ' ', $value));
127+
return str_replace(' ', '', $value);
128+
}
129+
130+
/**
131+
* Handle dynamic static method calls into the method.
132+
*
133+
* @param string $method
134+
* @param array $parameters
135+
* @return mixed
136+
*/
137+
public static function __callStatic($method, $parameters)
138+
{
139+
return (new static)->$method(...$parameters);
140+
}
141+
142+
/**
143+
* Convert the model to its string representation.
144+
*
145+
* @return string
146+
*/
147+
public function __toString()
148+
{
149+
return $this->toJson();
150+
}
151+
152+
153+
/**
154+
* Convert the model instance to JSON.
155+
*
156+
* @param int $options
157+
* @return string
158+
*
159+
*/
160+
public function toJson($options = 0)
161+
{
162+
return json_encode($this->attributes, $options);
163+
}
164+
165+
166+
167+
/**
168+
* Dynamically retrieve attributes on the model.
169+
*
170+
* @param string $key
171+
* @return mixed
172+
*/
173+
public function __get($key)
174+
{
175+
return $this->getAttribute($key);
176+
}
177+
178+
179+
/**
180+
* Dynamically set attributes on the model.
181+
*
182+
* @param string $key
183+
* @param mixed $value
184+
* @return void
185+
*/
186+
public function __set($key, $value)
187+
{
188+
$this->setAttribute($key, $value);
189+
}
190+
191+
/**
192+
* Determine if a get mutator exists for an attribute.
193+
*
194+
* @param string $key
195+
* @return bool
196+
*/
197+
public function hasGetMutator($key)
198+
{
199+
return method_exists($this, 'get'.$this->studly_case($key).'Attribute');
200+
}
201+
202+
/**
203+
* Get an attribute from the model.
204+
*
205+
* @param string $key
206+
* @return mixed
207+
*/
208+
public function getAttribute($key)
209+
{
210+
if (! $key) {
211+
return;
212+
}
213+
// If the attribute exists in the attribute array or has a "get" mutator we will
214+
// get the attribute's value. Otherwise, we will proceed as if the developers
215+
// are asking for a relationship's value. This covers both types of values.
216+
if (array_key_exists($key, $this->attributes) ||
217+
$this->hasGetMutator($key)) {
218+
return $this->getAttributeValue($key);
219+
}
220+
// Here we will determine if the model base class itself contains this given key
221+
// since we don't want to treat any of those methods as relationships because
222+
// they are all intended as helper methods and none of these are relations.
223+
if (method_exists(self::class, $key)) {
224+
return;
225+
}
226+
}
227+
228+
229+
/**
230+
* Get a plain attribute (not a relationship).
231+
*
232+
* @param string $key
233+
* @return mixed
234+
*/
235+
public function getAttributeValue($key)
236+
{
237+
return $this->attributes[$key];
238+
}
239+
240+
/**
241+
* Get the value of the model's primary key.
242+
*
243+
* @return mixed
244+
*/
245+
public function getPrimaryKeyValue()
246+
{
247+
return $this->getAttributeValue($this->primaryKey);
248+
}
249+
250+
251+
}

0 commit comments

Comments
 (0)