Completed
Pull Request — master (#3)
by James
03:09
created
src/Contract/Core/Container.php 1 patch
Indentation   +66 added lines, -66 removed lines patch added patch discarded remove patch
@@ -2,75 +2,75 @@
 block discarded – undo
2 2
 namespace Intraxia\Jaxion\Contract\Core;
3 3
 
4 4
 interface Container extends \ArrayAccess, \Iterator {
5
-	/**
6
-	 * Define a new service or value on the Container.
7
-	 *
8
-	 * The alias is the name that the value will be referenced by. This can be used by both
9
-	 * the `get` method to retrieve the value or through ArrayAccess (`$container['alias']`).
10
-	 * It should be a short name used to reference the defined value. The definition can be
11
-	 * any scalar value to assign to the alias, or it can define a service object to return.
12
-	 * This can be accomplished by passing in a closure, which takes the container and returns
13
-	 * a fully constructed object. This closure will be executed every time the class is fetched.
14
-	 * If an already-instantiated object is passed in, it will be returned when fetched. A
15
-	 * Definition object will be returned for additional manipulation. Scalar values will be
16
-	 * locked automatically and can't be overridden.
17
-	 *
18
-	 * @param string|array $alias
19
-	 * @param mixed        $definition
20
-	 *
21
-	 * @return $this
22
-	 */
23
-	public function define( $alias, $definition );
5
+    /**
6
+     * Define a new service or value on the Container.
7
+     *
8
+     * The alias is the name that the value will be referenced by. This can be used by both
9
+     * the `get` method to retrieve the value or through ArrayAccess (`$container['alias']`).
10
+     * It should be a short name used to reference the defined value. The definition can be
11
+     * any scalar value to assign to the alias, or it can define a service object to return.
12
+     * This can be accomplished by passing in a closure, which takes the container and returns
13
+     * a fully constructed object. This closure will be executed every time the class is fetched.
14
+     * If an already-instantiated object is passed in, it will be returned when fetched. A
15
+     * Definition object will be returned for additional manipulation. Scalar values will be
16
+     * locked automatically and can't be overridden.
17
+     *
18
+     * @param string|array $alias
19
+     * @param mixed        $definition
20
+     *
21
+     * @return $this
22
+     */
23
+    public function define( $alias, $definition );
24 24
 
25
-	/**
26
-	 * Defines a new singleton on the Container.
27
-	 *
28
-	 * Functions identically to Container::define, except closures passed in are only executed
29
-	 * once, and the return value is reused across multiple fetches.
30
-	 *
31
-	 * @param string|array $alias
32
-	 * @param mixed        $definition
33
-	 *
34
-	 * @return $this
35
-	 */
36
-	public function share( $alias, $definition );
25
+    /**
26
+     * Defines a new singleton on the Container.
27
+     *
28
+     * Functions identically to Container::define, except closures passed in are only executed
29
+     * once, and the return value is reused across multiple fetches.
30
+     *
31
+     * @param string|array $alias
32
+     * @param mixed        $definition
33
+     *
34
+     * @return $this
35
+     */
36
+    public function share( $alias, $definition );
37 37
 
38
-	/**
39
-	 * Fetches the value for the provided alias.
40
-	 *
41
-	 * @param string $alias
42
-	 *
43
-	 * @return mixed
44
-	 */
45
-	public function fetch( $alias );
38
+    /**
39
+     * Fetches the value for the provided alias.
40
+     *
41
+     * @param string $alias
42
+     *
43
+     * @return mixed
44
+     */
45
+    public function fetch( $alias );
46 46
 
47
-	/**
48
-	 * Checks whether the provided alias exists on the container.
49
-	 *
50
-	 * @param string $alias
51
-	 *
52
-	 * @return bool
53
-	 */
54
-	public function has( $alias );
47
+    /**
48
+     * Checks whether the provided alias exists on the container.
49
+     *
50
+     * @param string $alias
51
+     *
52
+     * @return bool
53
+     */
54
+    public function has( $alias );
55 55
 
56
-	/**
57
-	 * Removes the provided alias from the container.
58
-	 *
59
-	 * @param string $alias
60
-	 *
61
-	 * @return bool
62
-	 */
63
-	public function remove( $alias );
56
+    /**
57
+     * Removes the provided alias from the container.
58
+     *
59
+     * @param string $alias
60
+     *
61
+     * @return bool
62
+     */
63
+    public function remove( $alias );
64 64
 
65
-	/**
66
-	 * Registers a service provider with the container.
67
-	 *
68
-	 * A service provider is responsible for defining and generating services that will be bound
69
-	 * into the container. This keeps the container and Application responsible solely for maintaining
70
-	 * the generated services and the API for registering them and allows for a clean interface for
71
-	 * adding new services to the container.
72
-	 *
73
-	 * @param ServiceProvider $provider
74
-	 */
75
-	public function register( ServiceProvider $provider );
65
+    /**
66
+     * Registers a service provider with the container.
67
+     *
68
+     * A service provider is responsible for defining and generating services that will be bound
69
+     * into the container. This keeps the container and Application responsible solely for maintaining
70
+     * the generated services and the API for registering them and allows for a clean interface for
71
+     * adding new services to the container.
72
+     *
73
+     * @param ServiceProvider $provider
74
+     */
75
+    public function register( ServiceProvider $provider );
76 76
 }
Please login to merge, or discard this patch.
src/Contract/Http/Filter.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -10,13 +10,13 @@
 block discarded – undo
10 10
  * @subpackage Contract\Http
11 11
  */
12 12
 interface Filter {
13
-	/**
14
-	 * Generates argument rules.
15
-	 *
16
-	 * Returns an array matching the WP-API format for argument rules,
17
-	 * including sanitization, validation, required, or defaults.
18
-	 *
19
-	 * @return array
20
-	 */
21
-	public function rules();
13
+    /**
14
+     * Generates argument rules.
15
+     *
16
+     * Returns an array matching the WP-API format for argument rules,
17
+     * including sanitization, validation, required, or defaults.
18
+     *
19
+     * @return array
20
+     */
21
+    public function rules();
22 22
 }
Please login to merge, or discard this patch.
src/Contract/Http/Guard.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -10,13 +10,13 @@
 block discarded – undo
10 10
  * @subpackage Contract\Http
11 11
  */
12 12
 interface Guard {
13
-	/**
14
-	 * Validates when the user is authorized for the route.
15
-	 *
16
-	 * Returns a boolean based on whether the current user is authorized
17
-	 * to interact with the given route.
18
-	 *
19
-	 * @return bool
20
-	 */
21
-	public function authorized();
13
+    /**
14
+     * Validates when the user is authorized for the route.
15
+     *
16
+     * Returns a boolean based on whether the current user is authorized
17
+     * to interact with the given route.
18
+     *
19
+     * @return bool
20
+     */
21
+    public function authorized();
22 22
 }
Please login to merge, or discard this patch.
src/Http/Endpoint.php 1 patch
Indentation   +137 added lines, -137 removed lines patch added patch discarded remove patch
@@ -14,141 +14,141 @@
 block discarded – undo
14 14
  * @subpackage Http
15 15
  */
16 16
 class Endpoint {
17
-	/**
18
-	 * Endpoint's route.
19
-	 *
20
-	 * @var string
21
-	 */
22
-	protected $route;
23
-
24
-	/**
25
-	 * Endpoint's HTTP verb(s).
26
-	 *
27
-	 * @var string
28
-	 */
29
-	protected $method;
30
-
31
-	/**
32
-	 * Endpoint's callback.
33
-	 *
34
-	 * @var callable
35
-	 */
36
-	protected $callback;
37
-
38
-	/**
39
-	 * Endpoint's permission guard.
40
-	 *
41
-	 * @var GuardContract
42
-	 */
43
-	protected $guard;
44
-
45
-	/**
46
-	 * Endpoint's arguments filter.
47
-	 *
48
-	 * @var FilterContract
49
-	 */
50
-	protected $filter;
51
-
52
-	/**
53
-	 * Endpoint's route prefix.
54
-	 *
55
-	 * @var string
56
-	 */
57
-	protected $prefix;
58
-
59
-	/**
60
-	 * Instantiate a new endpoint with a provided route, method, and callback.
61
-	 *
62
-	 * @param string   $route
63
-	 * @param string   $method
64
-	 * @param callable $callback
65
-	 *
66
-	 * @throws MalformedRouteException
67
-	 */
68
-	public function __construct( $route, $method, $callback ) {
69
-		if ( ! Str::starts_with( $route, '/' ) || Str::ends_with( $route, '/' ) ) {
70
-			throw new MalformedRouteException;
71
-		}
72
-
73
-		$this->route    = $route;
74
-		$this->method   = $method;
75
-		$this->callback = $callback;
76
-	}
77
-
78
-	/**
79
-	 * Generates the endpoint's route.
80
-	 *
81
-	 * Combines the prefix with the route to generate the full route string.
82
-	 *
83
-	 * @return string
84
-	 */
85
-	public function get_route() {
86
-		return ( $this->prefix ?: '' ) . $this->route;
87
-	}
88
-
89
-	/**
90
-	 * Generates the endpoint's WP-API options array.
91
-	 *
92
-	 * @return array
93
-	 */
94
-	public function get_options() {
95
-		$options = array(
96
-			'methods'  => $this->method,
97
-			'callback' => $this->callback,
98
-		);
99
-
100
-		if ( $this->guard ) {
101
-			$options['permission_callback'] = array( $this->guard, 'authorized' );
102
-		}
103
-
104
-		if ( $this->filter ) {
105
-			$options['args'] = $this->filter->rules();
106
-		}
107
-
108
-		return $options;
109
-	}
110
-
111
-	/**
112
-	 * Sets the endpoint's permission guard.
113
-	 *
114
-	 * @param GuardContract $guard
115
-	 *
116
-	 * @return $this
117
-	 */
118
-	public function set_guard( GuardContract $guard ) {
119
-		$this->guard = $guard;
120
-
121
-		return $this;
122
-	}
123
-
124
-	/**
125
-	 * Sets the endpoint's arguments filter.
126
-	 *
127
-	 * @param FilterContract $filter
128
-	 *
129
-	 * @return $this
130
-	 */
131
-	public function set_filter( FilterContract $filter ) {
132
-		$this->filter = $filter;
133
-
134
-		return $this;
135
-	}
136
-
137
-	/**
138
-	 * Sets the endpoint's prefix.
139
-	 *
140
-	 * @param string $prefix
141
-	 *
142
-	 * @return $this
143
-	 * @throws MalformedRouteException
144
-	 */
145
-	public function set_prefix( $prefix ) {
146
-		if ( ! Str::starts_with( $prefix, '/' ) || Str::ends_with( $prefix, '/' ) ) {
147
-			throw new MalformedRouteException;
148
-		}
149
-
150
-		$this->prefix = $prefix;
151
-
152
-		return $this;
153
-	}
17
+    /**
18
+     * Endpoint's route.
19
+     *
20
+     * @var string
21
+     */
22
+    protected $route;
23
+
24
+    /**
25
+     * Endpoint's HTTP verb(s).
26
+     *
27
+     * @var string
28
+     */
29
+    protected $method;
30
+
31
+    /**
32
+     * Endpoint's callback.
33
+     *
34
+     * @var callable
35
+     */
36
+    protected $callback;
37
+
38
+    /**
39
+     * Endpoint's permission guard.
40
+     *
41
+     * @var GuardContract
42
+     */
43
+    protected $guard;
44
+
45
+    /**
46
+     * Endpoint's arguments filter.
47
+     *
48
+     * @var FilterContract
49
+     */
50
+    protected $filter;
51
+
52
+    /**
53
+     * Endpoint's route prefix.
54
+     *
55
+     * @var string
56
+     */
57
+    protected $prefix;
58
+
59
+    /**
60
+     * Instantiate a new endpoint with a provided route, method, and callback.
61
+     *
62
+     * @param string   $route
63
+     * @param string   $method
64
+     * @param callable $callback
65
+     *
66
+     * @throws MalformedRouteException
67
+     */
68
+    public function __construct( $route, $method, $callback ) {
69
+        if ( ! Str::starts_with( $route, '/' ) || Str::ends_with( $route, '/' ) ) {
70
+            throw new MalformedRouteException;
71
+        }
72
+
73
+        $this->route    = $route;
74
+        $this->method   = $method;
75
+        $this->callback = $callback;
76
+    }
77
+
78
+    /**
79
+     * Generates the endpoint's route.
80
+     *
81
+     * Combines the prefix with the route to generate the full route string.
82
+     *
83
+     * @return string
84
+     */
85
+    public function get_route() {
86
+        return ( $this->prefix ?: '' ) . $this->route;
87
+    }
88
+
89
+    /**
90
+     * Generates the endpoint's WP-API options array.
91
+     *
92
+     * @return array
93
+     */
94
+    public function get_options() {
95
+        $options = array(
96
+            'methods'  => $this->method,
97
+            'callback' => $this->callback,
98
+        );
99
+
100
+        if ( $this->guard ) {
101
+            $options['permission_callback'] = array( $this->guard, 'authorized' );
102
+        }
103
+
104
+        if ( $this->filter ) {
105
+            $options['args'] = $this->filter->rules();
106
+        }
107
+
108
+        return $options;
109
+    }
110
+
111
+    /**
112
+     * Sets the endpoint's permission guard.
113
+     *
114
+     * @param GuardContract $guard
115
+     *
116
+     * @return $this
117
+     */
118
+    public function set_guard( GuardContract $guard ) {
119
+        $this->guard = $guard;
120
+
121
+        return $this;
122
+    }
123
+
124
+    /**
125
+     * Sets the endpoint's arguments filter.
126
+     *
127
+     * @param FilterContract $filter
128
+     *
129
+     * @return $this
130
+     */
131
+    public function set_filter( FilterContract $filter ) {
132
+        $this->filter = $filter;
133
+
134
+        return $this;
135
+    }
136
+
137
+    /**
138
+     * Sets the endpoint's prefix.
139
+     *
140
+     * @param string $prefix
141
+     *
142
+     * @return $this
143
+     * @throws MalformedRouteException
144
+     */
145
+    public function set_prefix( $prefix ) {
146
+        if ( ! Str::starts_with( $prefix, '/' ) || Str::ends_with( $prefix, '/' ) ) {
147
+            throw new MalformedRouteException;
148
+        }
149
+
150
+        $this->prefix = $prefix;
151
+
152
+        return $this;
153
+    }
154 154
 }
Please login to merge, or discard this patch.
src/Axolotl/Model.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -825,7 +825,7 @@
 block discarded – undo
825 825
 	 * @param string $type
826 826
 	 * @param string $local_key
827 827
 	 *
828
-	 * @return HasMany
828
+	 * @return BelongsToOne
829 829
 	 */
830 830
 	protected function belongs_to_one( $class, $type, $local_key = '' ) {
831 831
 		return new BelongsToOne( $this, $class, $type, $local_key );
Please login to merge, or discard this patch.
Indentation   +841 added lines, -841 removed lines patch added patch discarded remove patch
@@ -23,845 +23,845 @@
 block discarded – undo
23 23
  * @since      0.1.0
24 24
  */
25 25
 abstract class Model implements Serializes {
26
-	/**
27
-	 * Memoized values for class methods.
28
-	 *
29
-	 * @var array
30
-	 */
31
-	private static $memo = array();
32
-
33
-	/**
34
-	 * Model attributes.
35
-	 *
36
-	 * @var array
37
-	 */
38
-	private $attributes = array(
39
-		'table'  => array(),
40
-		'object' => null,
41
-	);
42
-
43
-	/**
44
-	 * Model's original attributes.
45
-	 *
46
-	 * @var array
47
-	 */
48
-	private $original = array(
49
-		'table'  => array(),
50
-		'object' => null,
51
-	);
52
-
53
-	/**
54
-	 * Properties which are allowed to be set on the model.
55
-	 *
56
-	 * If this array is empty, any attributes can be set on the model.
57
-	 *
58
-	 * @var string[]
59
-	 */
60
-	protected $fillable = array();
61
-
62
-	/**
63
-	 * Properties which cannot be automatically filled on the model.
64
-	 *
65
-	 * If the model is unguarded, these properties can be filled.
66
-	 *
67
-	 * @var array
68
-	 */
69
-	protected $guarded = array();
70
-
71
-	/**
72
-	 * Properties which should not be serialized.
73
-	 *
74
-	 * @var array
75
-	 */
76
-	protected $hidden = array();
77
-
78
-	/**
79
-	 * Properties which should be serialized.
80
-	 *
81
-	 * @var array
82
-	 */
83
-	protected $visible = array();
84
-
85
-	/**
86
-	 * Relations saved on the Model.
87
-	 *
88
-	 * @var array
89
-	 */
90
-	protected $related = array();
91
-
92
-	/**
93
-	 * Whether the model's properties are guarded.
94
-	 *
95
-	 * When false, allows guarded properties to be filled.
96
-	 *
97
-	 * @var bool
98
-	 */
99
-	protected $is_guarded = true;
100
-
101
-	/**
102
-	 * Whether the Model is having its relations filled.
103
-	 *
104
-	 * @var bool
105
-	 */
106
-	protected $filling = false;
107
-
108
-	/**
109
-	 * Constructs a new model with provided attributes.
110
-	 *
111
-	 * If 'object' is passed as one of the attributes, the underlying post
112
-	 * will be overwritten.
113
-	 *
114
-	 * @param array <string, mixed> $attributes
115
-	 */
116
-	public function __construct( array $attributes = array() ) {
117
-		$this->maybe_boot();
118
-		$this->sync_original();
119
-
120
-		if ( $this->uses_wp_object() ) {
121
-			$this->create_wp_object();
122
-		}
123
-
124
-		$this->refresh( $attributes );
125
-	}
126
-
127
-	/**
128
-	 * Refreshes the model's current attributes with the provided array.
129
-	 *
130
-	 * The model's attributes will match what was provided in the array,
131
-	 * and any attributes not passed
132
-	 *
133
-	 * @param array $attributes
134
-	 *
135
-	 * @return $this
136
-	 */
137
-	public function refresh( array $attributes ) {
138
-		$this->clear();
139
-
140
-		return $this->merge( $attributes );
141
-	}
142
-
143
-	/**
144
-	 * Merges the provided attributes with the provided array.
145
-	 *
146
-	 * @param array $attributes
147
-	 *
148
-	 * @return $this
149
-	 */
150
-	public function merge( array $attributes ) {
151
-		foreach ( $attributes as $name => $value ) {
152
-			$this->set_attribute( $name, $value );
153
-		}
154
-
155
-		return $this;
156
-	}
157
-
158
-	/**
159
-	 * Get the model's table attributes.
160
-	 *
161
-	 * Returns the array of for the model that will either need to be
162
-	 * saved in postmeta or a separate table.
163
-	 *
164
-	 * @return array
165
-	 */
166
-	public function get_table_attributes() {
167
-		return $this->attributes['table'];
168
-	}
169
-
170
-	/**
171
-	 * Get the model's original attributes.
172
-	 *
173
-	 * @return array
174
-	 */
175
-	public function get_original_table_attributes() {
176
-		return $this->original['table'];
177
-	}
178
-
179
-	/**
180
-	 * Retrieve an array of the attributes on the model
181
-	 * that have changed compared to the model's
182
-	 * original data.
183
-	 *
184
-	 * @return array
185
-	 */
186
-	public function get_changed_table_attributes() {
187
-		$changed = array();
188
-
189
-		foreach ( $this->get_table_attributes() as $attribute ) {
190
-			if ( $this->get_attribute( $attribute ) !==
191
-			     $this->get_original_attribute( $attribute )
192
-			) {
193
-				$changed[ $attribute ] = $this->get_attribute( $attribute );
194
-			}
195
-		}
196
-
197
-		return $changed;
198
-	}
199
-
200
-	/**
201
-	 * Get the model's underlying post.
202
-	 *
203
-	 * Returns the underlying WP_Post object for the model, representing
204
-	 * the data that will be save in the wp_posts table.
205
-	 *
206
-	 * @return false|WP_Post|WP_Term
207
-	 */
208
-	public function get_underlying_wp_object() {
209
-		if ( isset( $this->attributes['object'] ) ) {
210
-			return $this->attributes['object'];
211
-		}
212
-
213
-		return false;
214
-	}
215
-
216
-	/**
217
-	 * Get the model's original underlying post.
218
-	 *
219
-	 * @return WP_Post
220
-	 */
221
-	public function get_original_underlying_wp_object() {
222
-		return $this->original['object'];
223
-	}
224
-
225
-	/**
226
-	 * Get the model attributes on the WordPress object
227
-	 * that have changed compared to the model's
228
-	 * original attributes.
229
-	 *
230
-	 * @return array
231
-	 */
232
-	public function get_changed_wp_object_attributes() {
233
-		$changed = array();
234
-
235
-		foreach ( $this->get_wp_object_keys() as $key ) {
236
-			if ( $this->get_attribute( $key ) !==
237
-			     $this->get_original_attribute( $key )
238
-			) {
239
-				$changed[ $key ] = $this->get_attribute( $key );
240
-			}
241
-		}
242
-
243
-		return $changed;
244
-	}
245
-
246
-	/**
247
-	 * Magic __set method.
248
-	 *
249
-	 * Passes the name and value to set_attribute, which is where the magic happens.
250
-	 *
251
-	 * @param string $name
252
-	 * @param mixed  $value
253
-	 */
254
-	public function __set( $name, $value ) {
255
-		$this->set_attribute( $name, $value );
256
-	}
257
-
258
-	/**
259
-	 * Sets the model attributes.
260
-	 *
261
-	 * Checks whether the model attribute can be set, check if it
262
-	 * maps to the WP_Post property, otherwise, assigns it to the
263
-	 * table attribute array.
264
-	 *
265
-	 * @param string $name
266
-	 * @param mixed  $value
267
-	 *
268
-	 * @return $this
269
-	 *
270
-	 * @throws GuardedPropertyException
271
-	 */
272
-	public function set_attribute( $name, $value ) {
273
-		if ( 'object' === $name ) {
274
-			return $this->override_wp_object( $value );
275
-		}
276
-
277
-		if ( ! $this->is_fillable( $name ) ) {
278
-			throw new GuardedPropertyException;
279
-		}
280
-
281
-		if ( $method = $this->has_map_method( $name ) ) {
282
-			$this->attributes['object']->{$this->{$method}()} = $value;
283
-		} else {
284
-			$this->attributes['table'][ $name ] = $value;
285
-		}
286
-
287
-		return $this;
288
-	}
289
-
290
-	/**
291
-	 * Retrieves all the attribute keys for the model.
292
-	 *
293
-	 * @return array
294
-	 */
295
-	public function get_attribute_keys() {
296
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
297
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
298
-		}
299
-
300
-		return self::$memo[ get_called_class() ][ __METHOD__ ]
301
-			= array_merge(
302
-				$this->fillable,
303
-				$this->guarded,
304
-				$this->get_compute_methods(),
305
-				$this->get_related_methods()
306
-			);
307
-	}
308
-
309
-	/**
310
-	 * Retrieves the attribute keys that aren't mapped to a post.
311
-	 *
312
-	 * @return array
313
-	 */
314
-	public function get_table_keys() {
315
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
316
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
317
-		}
318
-
319
-		$keys = array();
320
-
321
-		foreach ( $this->get_attribute_keys() as $key ) {
322
-			if ( ! $this->has_map_method( $key ) &&
323
-			     ! $this->has_compute_method( $key ) &&
324
-			     ! $this->has_related_method( $key )
325
-			) {
326
-				$keys[] = $key;
327
-			}
328
-		}
329
-
330
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
331
-	}
332
-
333
-	/**
334
-	 * Retrieves the attribute keys that are mapped to a post.
335
-	 *
336
-	 * @return array
337
-	 */
338
-	public function get_wp_object_keys() {
339
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
340
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
341
-		}
342
-
343
-		$keys = array();
344
-
345
-		foreach ( $this->get_attribute_keys() as $key ) {
346
-			if ( $this->has_map_method( $key ) ) {
347
-				$keys[] = $key;
348
-			}
349
-		}
350
-
351
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
352
-	}
353
-
354
-	/**
355
-	 * Returns the model's keys that are computed at call time.
356
-	 *
357
-	 * @return array
358
-	 */
359
-	public function get_computed_keys() {
360
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
361
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
362
-		}
363
-
364
-		$keys = array();
365
-
366
-		foreach ( $this->get_attribute_keys() as $key ) {
367
-			if ( $this->has_compute_method( $key ) ) {
368
-				$keys[] = $key;
369
-			}
370
-		}
371
-
372
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
373
-	}
374
-
375
-	/**
376
-	 * Returns the model's keys that are related to other Models.
377
-	 *
378
-	 * @return array
379
-	 */
380
-	public function get_related_keys() {
381
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
382
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
383
-		}
384
-
385
-		$keys = array();
386
-
387
-		foreach ( $this->get_attribute_keys() as $key ) {
388
-			if ( $this->has_related_method( $key ) ) {
389
-				$keys[] = $key;
390
-			}
391
-		}
392
-
393
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
394
-	}
395
-
396
-	/**
397
-	 * Serializes the model's public data into an array.
398
-	 *
399
-	 * @return array
400
-	 */
401
-	public function serialize() {
402
-		$attributes = array();
403
-
404
-		if ( $this->visible ) {
405
-			// If visible attributes are set, we'll only reveal those.
406
-			foreach ( $this->visible as $key ) {
407
-				$attributes[ $key ] = $this->get_attribute( $key );
408
-			}
409
-		} elseif ( $this->hidden ) {
410
-			// If hidden attributes are set, we'll grab everything and hide those.
411
-			foreach ( $this->get_attribute_keys() as $key ) {
412
-				if ( ! in_array( $key, $this->hidden ) ) {
413
-					$attributes[ $key ] = $this->get_attribute( $key );
414
-				}
415
-			}
416
-		} else {
417
-			// If nothing is hidden/visible, we'll grab and reveal everything.
418
-			foreach ( $this->get_attribute_keys() as $key ) {
419
-				$attributes[ $key ] = $this->get_attribute( $key );
420
-			}
421
-		}
422
-
423
-		return array_map( function ( $attribute ) {
424
-			if ( $attribute instanceof Serializes ) {
425
-				return $attribute->serialize();
426
-			}
427
-
428
-			return $attribute;
429
-		}, $attributes );
430
-	}
431
-
432
-	/**
433
-	 * Syncs the current attributes to the model's original.
434
-	 *
435
-	 * @return $this
436
-	 */
437
-	public function sync_original() {
438
-		$this->original = $this->attributes;
439
-
440
-		if ( $this->attributes['object'] ) {
441
-			$this->original['object'] = clone $this->attributes['object'];
442
-		}
443
-
444
-		return $this;
445
-	}
446
-
447
-	/**
448
-	 * Checks if a given attribute is mass-fillable.
449
-	 *
450
-	 * Returns true if the attribute can be filled, false if it can't.
451
-	 *
452
-	 * @param string $name
453
-	 *
454
-	 * @return bool
455
-	 */
456
-	private function is_fillable( $name ) {
457
-		// If this model isn't guarded, everything is fillable.
458
-		if ( ! $this->is_guarded ) {
459
-			return true;
460
-		}
461
-
462
-		// If it's in the fillable array, then it's fillable.
463
-		if ( in_array( $name, $this->fillable ) ) {
464
-			return true;
465
-		}
466
-
467
-		// If it's explicitly guarded, then it's not fillable.
468
-		if ( in_array( $name, $this->guarded ) ) {
469
-			return false;
470
-		}
471
-
472
-		// If fillable hasn't been defined, then everything else fillable.
473
-		return ! $this->fillable;
474
-	}
475
-
476
-	/**
477
-	 * Overrides the current WP_Post with a provided one.
478
-	 *
479
-	 * Resets the post's default values and stores it in the attributes.
480
-	 *
481
-	 * @param WP_Post $value
482
-	 *
483
-	 * @return $this
484
-	 */
485
-	private function override_wp_object( $value ) {
486
-		$this->attributes['object'] = $this->set_wp_object_constants( $value );
487
-
488
-		return $this;
489
-	}
490
-
491
-	/**
492
-	 * Create and set with a new blank post.
493
-	 *
494
-	 * Creates a new WP_Post object, assigns it the default attributes,
495
-	 * and stores it in the attributes.
496
-	 *
497
-	 * @throws LogicException
498
-	 */
499
-	private function create_wp_object() {
500
-		switch ( true ) {
501
-			case $this instanceof UsesWordPressPost:
502
-				$object = new WP_Post( (object) array() );
503
-				break;
504
-			case $this instanceof UsesWordPressTerm:
505
-				$object = new WP_Term( (object) array() );
506
-				break;
507
-			default:
508
-				throw new LogicException;
509
-				break;
510
-		}
511
-
512
-		$this->attributes['object'] = $this->set_wp_object_constants( $object );
513
-	}
514
-
515
-	/**
516
-	 * Enforces values on the post that can't change.
517
-	 *
518
-	 * Primarily, this is used to make sure the post_type always maps
519
-	 * to the model's "$type" property, but this can all be overridden
520
-	 * by the developer to enforce other values in the model.
521
-	 *
522
-	 * @param object $object
523
-	 *
524
-	 * @return object
525
-	 */
526
-	protected function set_wp_object_constants( $object ) {
527
-		if ( $this instanceof UsesWordPressPost ) {
528
-			$object->post_type = $this::get_post_type();
529
-		}
530
-
531
-		if ( $this instanceof UsesWordPressTerm ) {
532
-			$object->taxonomy = $this::get_taxonomy();
533
-		}
534
-
535
-		return $object;
536
-	}
537
-
538
-	/**
539
-	 * Magic __get method.
540
-	 *
541
-	 * Passes the name and value to get_attribute, which is where the magic happens.
542
-	 *
543
-	 * @param string $name
544
-	 *
545
-	 * @return mixed
546
-	 */
547
-	public function __get( $name ) {
548
-		return $this->get_attribute( $name );
549
-	}
550
-
551
-	/**
552
-	 * Retrieves the model attribute.
553
-	 *
554
-	 * @param string $name
555
-	 *
556
-	 * @return mixed
557
-	 *
558
-	 * @throws PropertyDoesNotExistException If property isn't found.
559
-	 */
560
-	public function get_attribute( $name ) {
561
-		if ( $method = $this->has_map_method( $name ) ) {
562
-			$value = $this->attributes['object']->{$this->{$method}()};
563
-		} elseif ( $method = $this->has_compute_method( $name ) ) {
564
-			$value = $this->{$method}();
565
-		} else if ( $method = $this->has_related_method( $name ) ) {
566
-			$value = $this->get_related( $this->{$method}()->get_sha() );
567
-		} else {
568
-			if ( ! isset( $this->attributes['table'][ $name ] ) ) {
569
-				throw new PropertyDoesNotExistException;
570
-			}
571
-
572
-			$value = $this->attributes['table'][ $name ];
573
-		}
574
-
575
-		return $value;
576
-	}
577
-
578
-	/**
579
-	 * Retrieve the model's original attribute value.
580
-	 *
581
-	 * @param string $name
582
-	 *
583
-	 * @return mixed
584
-	 *
585
-	 * @throws PropertyDoesNotExistException If property isn't found.
586
-	 */
587
-	public function get_original_attribute( $name ) {
588
-		$original = new static( $this->original );
589
-
590
-		return $original->get_attribute( $name );
591
-	}
592
-
593
-	/**
594
-	 * Fetches the Model's primary ID, depending on the model
595
-	 * implementation.
596
-	 *
597
-	 * @return int
598
-	 *
599
-	 * @throws LogicException
600
-	 */
601
-	public function get_primary_id() {
602
-		if ( $this instanceof UsesWordPressPost ) {
603
-			return $this->get_underlying_wp_object()->ID;
604
-		}
605
-
606
-		if ( $this instanceof UsesWordPressTerm ) {
607
-			return $this->get_underlying_wp_object()->term_id;
608
-		}
609
-
610
-		// Model w/o wp_object not yet supported.
611
-		throw new LogicException;
612
-	}
613
-
614
-	/**
615
-	 * Generates the table foreign key, depending on the model
616
-	 * implementation.
617
-	 *
618
-	 * @return string
619
-	 *
620
-	 * @throws LogicException
621
-	 */
622
-	public function get_foreign_key() {
623
-		if ( $this instanceof UsesWordPressPost ) {
624
-			return 'post_id';
625
-		}
626
-
627
-		// Model w/o wp_object not yet supported.
628
-		throw new LogicException;
629
-	}
630
-
631
-	/**
632
-	 * Gets the related Model or Collection for the given sha.
633
-	 *
634
-	 * @param string $sha
635
-	 *
636
-	 * @return Model|Collection
637
-	 */
638
-	public function get_related( $sha ) {
639
-		return $this->related[ $sha ];
640
-	}
641
-
642
-	/**
643
-	 * Sets the related Model or Collection for the given sha.
644
-	 *
645
-	 * @param string           $sha
646
-	 * @param Model|Collection $target
647
-	 *
648
-	 * @throws RuntimeException
649
-	 */
650
-	public function set_related( $sha, $target ) {
651
-		if ( ! ( $target instanceof Model ) && ! ( $target instanceof Collection ) ) {
652
-			throw new RuntimeException;
653
-		}
654
-
655
-		$this->related[ $sha ] = $target;
656
-	}
657
-
658
-	/**
659
-	 * Checks whether the attribute has a map method.
660
-	 *
661
-	 * This is used to determine whether the attribute maps to a
662
-	 * property on the underlying WP_Post object. Returns the
663
-	 * method if one exists, returns false if it doesn't.
664
-	 *
665
-	 * @param string $name
666
-	 *
667
-	 * @return false|string
668
-	 */
669
-	protected function has_map_method( $name ) {
670
-		if ( method_exists( $this, $method = "map_{$name}" ) ) {
671
-			return $method;
672
-		}
673
-
674
-		return false;
675
-	}
676
-
677
-	/**
678
-	 * Checks whether the attribute has a compute method.
679
-	 *
680
-	 * This is used to determine if the attribute should be computed
681
-	 * from other attributes.
682
-	 *
683
-	 * @param string $name
684
-	 *
685
-	 * @return false|string
686
-	 */
687
-	protected function has_compute_method( $name ) {
688
-		if ( method_exists( $this, $method = "compute_{$name}" ) ) {
689
-			return $method;
690
-		}
691
-
692
-		return false;
693
-	}
694
-
695
-	/**
696
-	 * Checks whether the attribute has a compute method.
697
-	 *
698
-	 * This is used to determine if the attribute should be computed
699
-	 * from other attributes.
700
-	 *
701
-	 * @param string $name
702
-	 *
703
-	 * @return false|string
704
-	 */
705
-	protected function has_related_method( $name ) {
706
-		if ( method_exists( $this, $method = "related_{$name}" ) ) {
707
-			return $method;
708
-		}
709
-
710
-		return false;
711
-	}
712
-
713
-	/**
714
-	 * Clears all the current attributes from the model.
715
-	 *
716
-	 * This does not touch the model's original attributes, and will
717
-	 * only clear fillable attributes, unless the model is unguarded.
718
-	 *
719
-	 * @return $this
720
-	 */
721
-	public function clear() {
722
-		$keys = $this->get_attribute_keys();
723
-
724
-		foreach ( $keys as $key ) {
725
-			try {
726
-				$this->set_attribute( $key, null );
727
-			} catch ( GuardedPropertyException $e ) {
728
-				// We won't clear out guarded attributes.
729
-			}
730
-		}
731
-
732
-		return $this;
733
-	}
734
-
735
-	/**
736
-	 * Unguards the model.
737
-	 *
738
-	 * Sets the model to be unguarded, allowing the filling of
739
-	 * guarded attributes.
740
-	 */
741
-	public function unguard() {
742
-		$this->is_guarded = false;
743
-	}
744
-
745
-	/**
746
-	 * Reguards the model.
747
-	 *
748
-	 * Sets the model to be guarded, preventing filling of
749
-	 * guarded attributes.
750
-	 */
751
-	public function reguard() {
752
-		$this->is_guarded = true;
753
-	}
754
-
755
-	/**
756
-	 * Retrieves all the compute methods on the model.
757
-	 *
758
-	 * @return array
759
-	 */
760
-	protected function get_compute_methods() {
761
-		$methods = get_class_methods( get_called_class() );
762
-		$methods = array_filter( $methods, function ( $method ) {
763
-			return strrpos( $method, 'compute_', - strlen( $method ) ) !== false;
764
-		} );
765
-		$methods = array_map( function ( $method ) {
766
-			return substr( $method, strlen( 'compute_' ) );
767
-		}, $methods );
768
-
769
-		return $methods;
770
-	}
771
-
772
-	/**
773
-	 * Retrieves all the related methods on the model.
774
-	 *
775
-	 * @return array
776
-	 */
777
-	protected function get_related_methods() {
778
-		$methods = get_class_methods( get_called_class() );
779
-		$methods = array_filter( $methods, function ( $method ) {
780
-			return strrpos( $method, 'related_', - strlen( $method ) ) !== false;
781
-		} );
782
-		$methods = array_map( function ( $method ) {
783
-			return substr( $method, strlen( 'related_' ) );
784
-		}, $methods );
785
-
786
-		return $methods;
787
-	}
788
-
789
-	/**
790
-	 * Returns whether this relation has already been filled on the model.
791
-	 *
792
-	 * @param string $relation
793
-	 *
794
-	 * @return bool
795
-	 */
796
-	public function relation_is_filled( $relation ) {
797
-		$sha = $this
798
-			->{$this->has_related_method( $relation )}()
799
-			->get_sha();
800
-
801
-		return isset( $this->related[ $sha ] );
802
-	}
803
-
804
-	/**
805
-	 * Returns whether the Model is currently having
806
-	 * its relationships filled.
807
-	 *
808
-	 * @return bool
809
-	 */
810
-	public function is_filling() {
811
-		return $this->filling;
812
-	}
813
-
814
-	/**
815
-	 * Sets whether the Model is having its relationships filled.
816
-	 *
817
-	 * @param bool $is_filling
818
-	 */
819
-	public function set_filling( $is_filling ) {
820
-		$this->filling = $is_filling;
821
-	}
822
-
823
-	/**
824
-	 * Returns a HasMany relationship for the model.
825
-	 *
826
-	 * @param string $class
827
-	 * @param string $type
828
-	 * @param string $foreign_key
829
-	 *
830
-	 * @return HasMany
831
-	 */
832
-	protected function has_many( $class, $type, $foreign_key ) {
833
-		return new HasMany( $this, $class, $type, $foreign_key );
834
-	}
835
-
836
-	/**
837
-	 * Returns a BelongsToOne relationship for the model.
838
-	 *
839
-	 * @param string $class
840
-	 * @param string $type
841
-	 * @param string $local_key
842
-	 *
843
-	 * @return HasMany
844
-	 */
845
-	protected function belongs_to_one( $class, $type, $local_key = '' ) {
846
-		return new BelongsToOne( $this, $class, $type, $local_key );
847
-	}
848
-
849
-	/**
850
-	 * Sets up the memo array for the creating model.
851
-	 */
852
-	private function maybe_boot() {
853
-		if ( ! isset( self::$memo[ get_called_class() ] ) ) {
854
-			self::$memo[ get_called_class() ] = array();
855
-		}
856
-	}
857
-
858
-	/**
859
-	 * Whether this Model uses an underlying WordPress object.
860
-	 *
861
-	 * @return bool
862
-	 */
863
-	protected function uses_wp_object() {
864
-		return $this instanceof UsesWordPressPost ||
865
-			$this instanceof UsesWordPressTerm;
866
-	}
26
+    /**
27
+     * Memoized values for class methods.
28
+     *
29
+     * @var array
30
+     */
31
+    private static $memo = array();
32
+
33
+    /**
34
+     * Model attributes.
35
+     *
36
+     * @var array
37
+     */
38
+    private $attributes = array(
39
+        'table'  => array(),
40
+        'object' => null,
41
+    );
42
+
43
+    /**
44
+     * Model's original attributes.
45
+     *
46
+     * @var array
47
+     */
48
+    private $original = array(
49
+        'table'  => array(),
50
+        'object' => null,
51
+    );
52
+
53
+    /**
54
+     * Properties which are allowed to be set on the model.
55
+     *
56
+     * If this array is empty, any attributes can be set on the model.
57
+     *
58
+     * @var string[]
59
+     */
60
+    protected $fillable = array();
61
+
62
+    /**
63
+     * Properties which cannot be automatically filled on the model.
64
+     *
65
+     * If the model is unguarded, these properties can be filled.
66
+     *
67
+     * @var array
68
+     */
69
+    protected $guarded = array();
70
+
71
+    /**
72
+     * Properties which should not be serialized.
73
+     *
74
+     * @var array
75
+     */
76
+    protected $hidden = array();
77
+
78
+    /**
79
+     * Properties which should be serialized.
80
+     *
81
+     * @var array
82
+     */
83
+    protected $visible = array();
84
+
85
+    /**
86
+     * Relations saved on the Model.
87
+     *
88
+     * @var array
89
+     */
90
+    protected $related = array();
91
+
92
+    /**
93
+     * Whether the model's properties are guarded.
94
+     *
95
+     * When false, allows guarded properties to be filled.
96
+     *
97
+     * @var bool
98
+     */
99
+    protected $is_guarded = true;
100
+
101
+    /**
102
+     * Whether the Model is having its relations filled.
103
+     *
104
+     * @var bool
105
+     */
106
+    protected $filling = false;
107
+
108
+    /**
109
+     * Constructs a new model with provided attributes.
110
+     *
111
+     * If 'object' is passed as one of the attributes, the underlying post
112
+     * will be overwritten.
113
+     *
114
+     * @param array <string, mixed> $attributes
115
+     */
116
+    public function __construct( array $attributes = array() ) {
117
+        $this->maybe_boot();
118
+        $this->sync_original();
119
+
120
+        if ( $this->uses_wp_object() ) {
121
+            $this->create_wp_object();
122
+        }
123
+
124
+        $this->refresh( $attributes );
125
+    }
126
+
127
+    /**
128
+     * Refreshes the model's current attributes with the provided array.
129
+     *
130
+     * The model's attributes will match what was provided in the array,
131
+     * and any attributes not passed
132
+     *
133
+     * @param array $attributes
134
+     *
135
+     * @return $this
136
+     */
137
+    public function refresh( array $attributes ) {
138
+        $this->clear();
139
+
140
+        return $this->merge( $attributes );
141
+    }
142
+
143
+    /**
144
+     * Merges the provided attributes with the provided array.
145
+     *
146
+     * @param array $attributes
147
+     *
148
+     * @return $this
149
+     */
150
+    public function merge( array $attributes ) {
151
+        foreach ( $attributes as $name => $value ) {
152
+            $this->set_attribute( $name, $value );
153
+        }
154
+
155
+        return $this;
156
+    }
157
+
158
+    /**
159
+     * Get the model's table attributes.
160
+     *
161
+     * Returns the array of for the model that will either need to be
162
+     * saved in postmeta or a separate table.
163
+     *
164
+     * @return array
165
+     */
166
+    public function get_table_attributes() {
167
+        return $this->attributes['table'];
168
+    }
169
+
170
+    /**
171
+     * Get the model's original attributes.
172
+     *
173
+     * @return array
174
+     */
175
+    public function get_original_table_attributes() {
176
+        return $this->original['table'];
177
+    }
178
+
179
+    /**
180
+     * Retrieve an array of the attributes on the model
181
+     * that have changed compared to the model's
182
+     * original data.
183
+     *
184
+     * @return array
185
+     */
186
+    public function get_changed_table_attributes() {
187
+        $changed = array();
188
+
189
+        foreach ( $this->get_table_attributes() as $attribute ) {
190
+            if ( $this->get_attribute( $attribute ) !==
191
+                    $this->get_original_attribute( $attribute )
192
+            ) {
193
+                $changed[ $attribute ] = $this->get_attribute( $attribute );
194
+            }
195
+        }
196
+
197
+        return $changed;
198
+    }
199
+
200
+    /**
201
+     * Get the model's underlying post.
202
+     *
203
+     * Returns the underlying WP_Post object for the model, representing
204
+     * the data that will be save in the wp_posts table.
205
+     *
206
+     * @return false|WP_Post|WP_Term
207
+     */
208
+    public function get_underlying_wp_object() {
209
+        if ( isset( $this->attributes['object'] ) ) {
210
+            return $this->attributes['object'];
211
+        }
212
+
213
+        return false;
214
+    }
215
+
216
+    /**
217
+     * Get the model's original underlying post.
218
+     *
219
+     * @return WP_Post
220
+     */
221
+    public function get_original_underlying_wp_object() {
222
+        return $this->original['object'];
223
+    }
224
+
225
+    /**
226
+     * Get the model attributes on the WordPress object
227
+     * that have changed compared to the model's
228
+     * original attributes.
229
+     *
230
+     * @return array
231
+     */
232
+    public function get_changed_wp_object_attributes() {
233
+        $changed = array();
234
+
235
+        foreach ( $this->get_wp_object_keys() as $key ) {
236
+            if ( $this->get_attribute( $key ) !==
237
+                    $this->get_original_attribute( $key )
238
+            ) {
239
+                $changed[ $key ] = $this->get_attribute( $key );
240
+            }
241
+        }
242
+
243
+        return $changed;
244
+    }
245
+
246
+    /**
247
+     * Magic __set method.
248
+     *
249
+     * Passes the name and value to set_attribute, which is where the magic happens.
250
+     *
251
+     * @param string $name
252
+     * @param mixed  $value
253
+     */
254
+    public function __set( $name, $value ) {
255
+        $this->set_attribute( $name, $value );
256
+    }
257
+
258
+    /**
259
+     * Sets the model attributes.
260
+     *
261
+     * Checks whether the model attribute can be set, check if it
262
+     * maps to the WP_Post property, otherwise, assigns it to the
263
+     * table attribute array.
264
+     *
265
+     * @param string $name
266
+     * @param mixed  $value
267
+     *
268
+     * @return $this
269
+     *
270
+     * @throws GuardedPropertyException
271
+     */
272
+    public function set_attribute( $name, $value ) {
273
+        if ( 'object' === $name ) {
274
+            return $this->override_wp_object( $value );
275
+        }
276
+
277
+        if ( ! $this->is_fillable( $name ) ) {
278
+            throw new GuardedPropertyException;
279
+        }
280
+
281
+        if ( $method = $this->has_map_method( $name ) ) {
282
+            $this->attributes['object']->{$this->{$method}()} = $value;
283
+        } else {
284
+            $this->attributes['table'][ $name ] = $value;
285
+        }
286
+
287
+        return $this;
288
+    }
289
+
290
+    /**
291
+     * Retrieves all the attribute keys for the model.
292
+     *
293
+     * @return array
294
+     */
295
+    public function get_attribute_keys() {
296
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
297
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
298
+        }
299
+
300
+        return self::$memo[ get_called_class() ][ __METHOD__ ]
301
+            = array_merge(
302
+                $this->fillable,
303
+                $this->guarded,
304
+                $this->get_compute_methods(),
305
+                $this->get_related_methods()
306
+            );
307
+    }
308
+
309
+    /**
310
+     * Retrieves the attribute keys that aren't mapped to a post.
311
+     *
312
+     * @return array
313
+     */
314
+    public function get_table_keys() {
315
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
316
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
317
+        }
318
+
319
+        $keys = array();
320
+
321
+        foreach ( $this->get_attribute_keys() as $key ) {
322
+            if ( ! $this->has_map_method( $key ) &&
323
+                 ! $this->has_compute_method( $key ) &&
324
+                 ! $this->has_related_method( $key )
325
+            ) {
326
+                $keys[] = $key;
327
+            }
328
+        }
329
+
330
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
331
+    }
332
+
333
+    /**
334
+     * Retrieves the attribute keys that are mapped to a post.
335
+     *
336
+     * @return array
337
+     */
338
+    public function get_wp_object_keys() {
339
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
340
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
341
+        }
342
+
343
+        $keys = array();
344
+
345
+        foreach ( $this->get_attribute_keys() as $key ) {
346
+            if ( $this->has_map_method( $key ) ) {
347
+                $keys[] = $key;
348
+            }
349
+        }
350
+
351
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
352
+    }
353
+
354
+    /**
355
+     * Returns the model's keys that are computed at call time.
356
+     *
357
+     * @return array
358
+     */
359
+    public function get_computed_keys() {
360
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
361
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
362
+        }
363
+
364
+        $keys = array();
365
+
366
+        foreach ( $this->get_attribute_keys() as $key ) {
367
+            if ( $this->has_compute_method( $key ) ) {
368
+                $keys[] = $key;
369
+            }
370
+        }
371
+
372
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
373
+    }
374
+
375
+    /**
376
+     * Returns the model's keys that are related to other Models.
377
+     *
378
+     * @return array
379
+     */
380
+    public function get_related_keys() {
381
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
382
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
383
+        }
384
+
385
+        $keys = array();
386
+
387
+        foreach ( $this->get_attribute_keys() as $key ) {
388
+            if ( $this->has_related_method( $key ) ) {
389
+                $keys[] = $key;
390
+            }
391
+        }
392
+
393
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
394
+    }
395
+
396
+    /**
397
+     * Serializes the model's public data into an array.
398
+     *
399
+     * @return array
400
+     */
401
+    public function serialize() {
402
+        $attributes = array();
403
+
404
+        if ( $this->visible ) {
405
+            // If visible attributes are set, we'll only reveal those.
406
+            foreach ( $this->visible as $key ) {
407
+                $attributes[ $key ] = $this->get_attribute( $key );
408
+            }
409
+        } elseif ( $this->hidden ) {
410
+            // If hidden attributes are set, we'll grab everything and hide those.
411
+            foreach ( $this->get_attribute_keys() as $key ) {
412
+                if ( ! in_array( $key, $this->hidden ) ) {
413
+                    $attributes[ $key ] = $this->get_attribute( $key );
414
+                }
415
+            }
416
+        } else {
417
+            // If nothing is hidden/visible, we'll grab and reveal everything.
418
+            foreach ( $this->get_attribute_keys() as $key ) {
419
+                $attributes[ $key ] = $this->get_attribute( $key );
420
+            }
421
+        }
422
+
423
+        return array_map( function ( $attribute ) {
424
+            if ( $attribute instanceof Serializes ) {
425
+                return $attribute->serialize();
426
+            }
427
+
428
+            return $attribute;
429
+        }, $attributes );
430
+    }
431
+
432
+    /**
433
+     * Syncs the current attributes to the model's original.
434
+     *
435
+     * @return $this
436
+     */
437
+    public function sync_original() {
438
+        $this->original = $this->attributes;
439
+
440
+        if ( $this->attributes['object'] ) {
441
+            $this->original['object'] = clone $this->attributes['object'];
442
+        }
443
+
444
+        return $this;
445
+    }
446
+
447
+    /**
448
+     * Checks if a given attribute is mass-fillable.
449
+     *
450
+     * Returns true if the attribute can be filled, false if it can't.
451
+     *
452
+     * @param string $name
453
+     *
454
+     * @return bool
455
+     */
456
+    private function is_fillable( $name ) {
457
+        // If this model isn't guarded, everything is fillable.
458
+        if ( ! $this->is_guarded ) {
459
+            return true;
460
+        }
461
+
462
+        // If it's in the fillable array, then it's fillable.
463
+        if ( in_array( $name, $this->fillable ) ) {
464
+            return true;
465
+        }
466
+
467
+        // If it's explicitly guarded, then it's not fillable.
468
+        if ( in_array( $name, $this->guarded ) ) {
469
+            return false;
470
+        }
471
+
472
+        // If fillable hasn't been defined, then everything else fillable.
473
+        return ! $this->fillable;
474
+    }
475
+
476
+    /**
477
+     * Overrides the current WP_Post with a provided one.
478
+     *
479
+     * Resets the post's default values and stores it in the attributes.
480
+     *
481
+     * @param WP_Post $value
482
+     *
483
+     * @return $this
484
+     */
485
+    private function override_wp_object( $value ) {
486
+        $this->attributes['object'] = $this->set_wp_object_constants( $value );
487
+
488
+        return $this;
489
+    }
490
+
491
+    /**
492
+     * Create and set with a new blank post.
493
+     *
494
+     * Creates a new WP_Post object, assigns it the default attributes,
495
+     * and stores it in the attributes.
496
+     *
497
+     * @throws LogicException
498
+     */
499
+    private function create_wp_object() {
500
+        switch ( true ) {
501
+            case $this instanceof UsesWordPressPost:
502
+                $object = new WP_Post( (object) array() );
503
+                break;
504
+            case $this instanceof UsesWordPressTerm:
505
+                $object = new WP_Term( (object) array() );
506
+                break;
507
+            default:
508
+                throw new LogicException;
509
+                break;
510
+        }
511
+
512
+        $this->attributes['object'] = $this->set_wp_object_constants( $object );
513
+    }
514
+
515
+    /**
516
+     * Enforces values on the post that can't change.
517
+     *
518
+     * Primarily, this is used to make sure the post_type always maps
519
+     * to the model's "$type" property, but this can all be overridden
520
+     * by the developer to enforce other values in the model.
521
+     *
522
+     * @param object $object
523
+     *
524
+     * @return object
525
+     */
526
+    protected function set_wp_object_constants( $object ) {
527
+        if ( $this instanceof UsesWordPressPost ) {
528
+            $object->post_type = $this::get_post_type();
529
+        }
530
+
531
+        if ( $this instanceof UsesWordPressTerm ) {
532
+            $object->taxonomy = $this::get_taxonomy();
533
+        }
534
+
535
+        return $object;
536
+    }
537
+
538
+    /**
539
+     * Magic __get method.
540
+     *
541
+     * Passes the name and value to get_attribute, which is where the magic happens.
542
+     *
543
+     * @param string $name
544
+     *
545
+     * @return mixed
546
+     */
547
+    public function __get( $name ) {
548
+        return $this->get_attribute( $name );
549
+    }
550
+
551
+    /**
552
+     * Retrieves the model attribute.
553
+     *
554
+     * @param string $name
555
+     *
556
+     * @return mixed
557
+     *
558
+     * @throws PropertyDoesNotExistException If property isn't found.
559
+     */
560
+    public function get_attribute( $name ) {
561
+        if ( $method = $this->has_map_method( $name ) ) {
562
+            $value = $this->attributes['object']->{$this->{$method}()};
563
+        } elseif ( $method = $this->has_compute_method( $name ) ) {
564
+            $value = $this->{$method}();
565
+        } else if ( $method = $this->has_related_method( $name ) ) {
566
+            $value = $this->get_related( $this->{$method}()->get_sha() );
567
+        } else {
568
+            if ( ! isset( $this->attributes['table'][ $name ] ) ) {
569
+                throw new PropertyDoesNotExistException;
570
+            }
571
+
572
+            $value = $this->attributes['table'][ $name ];
573
+        }
574
+
575
+        return $value;
576
+    }
577
+
578
+    /**
579
+     * Retrieve the model's original attribute value.
580
+     *
581
+     * @param string $name
582
+     *
583
+     * @return mixed
584
+     *
585
+     * @throws PropertyDoesNotExistException If property isn't found.
586
+     */
587
+    public function get_original_attribute( $name ) {
588
+        $original = new static( $this->original );
589
+
590
+        return $original->get_attribute( $name );
591
+    }
592
+
593
+    /**
594
+     * Fetches the Model's primary ID, depending on the model
595
+     * implementation.
596
+     *
597
+     * @return int
598
+     *
599
+     * @throws LogicException
600
+     */
601
+    public function get_primary_id() {
602
+        if ( $this instanceof UsesWordPressPost ) {
603
+            return $this->get_underlying_wp_object()->ID;
604
+        }
605
+
606
+        if ( $this instanceof UsesWordPressTerm ) {
607
+            return $this->get_underlying_wp_object()->term_id;
608
+        }
609
+
610
+        // Model w/o wp_object not yet supported.
611
+        throw new LogicException;
612
+    }
613
+
614
+    /**
615
+     * Generates the table foreign key, depending on the model
616
+     * implementation.
617
+     *
618
+     * @return string
619
+     *
620
+     * @throws LogicException
621
+     */
622
+    public function get_foreign_key() {
623
+        if ( $this instanceof UsesWordPressPost ) {
624
+            return 'post_id';
625
+        }
626
+
627
+        // Model w/o wp_object not yet supported.
628
+        throw new LogicException;
629
+    }
630
+
631
+    /**
632
+     * Gets the related Model or Collection for the given sha.
633
+     *
634
+     * @param string $sha
635
+     *
636
+     * @return Model|Collection
637
+     */
638
+    public function get_related( $sha ) {
639
+        return $this->related[ $sha ];
640
+    }
641
+
642
+    /**
643
+     * Sets the related Model or Collection for the given sha.
644
+     *
645
+     * @param string           $sha
646
+     * @param Model|Collection $target
647
+     *
648
+     * @throws RuntimeException
649
+     */
650
+    public function set_related( $sha, $target ) {
651
+        if ( ! ( $target instanceof Model ) && ! ( $target instanceof Collection ) ) {
652
+            throw new RuntimeException;
653
+        }
654
+
655
+        $this->related[ $sha ] = $target;
656
+    }
657
+
658
+    /**
659
+     * Checks whether the attribute has a map method.
660
+     *
661
+     * This is used to determine whether the attribute maps to a
662
+     * property on the underlying WP_Post object. Returns the
663
+     * method if one exists, returns false if it doesn't.
664
+     *
665
+     * @param string $name
666
+     *
667
+     * @return false|string
668
+     */
669
+    protected function has_map_method( $name ) {
670
+        if ( method_exists( $this, $method = "map_{$name}" ) ) {
671
+            return $method;
672
+        }
673
+
674
+        return false;
675
+    }
676
+
677
+    /**
678
+     * Checks whether the attribute has a compute method.
679
+     *
680
+     * This is used to determine if the attribute should be computed
681
+     * from other attributes.
682
+     *
683
+     * @param string $name
684
+     *
685
+     * @return false|string
686
+     */
687
+    protected function has_compute_method( $name ) {
688
+        if ( method_exists( $this, $method = "compute_{$name}" ) ) {
689
+            return $method;
690
+        }
691
+
692
+        return false;
693
+    }
694
+
695
+    /**
696
+     * Checks whether the attribute has a compute method.
697
+     *
698
+     * This is used to determine if the attribute should be computed
699
+     * from other attributes.
700
+     *
701
+     * @param string $name
702
+     *
703
+     * @return false|string
704
+     */
705
+    protected function has_related_method( $name ) {
706
+        if ( method_exists( $this, $method = "related_{$name}" ) ) {
707
+            return $method;
708
+        }
709
+
710
+        return false;
711
+    }
712
+
713
+    /**
714
+     * Clears all the current attributes from the model.
715
+     *
716
+     * This does not touch the model's original attributes, and will
717
+     * only clear fillable attributes, unless the model is unguarded.
718
+     *
719
+     * @return $this
720
+     */
721
+    public function clear() {
722
+        $keys = $this->get_attribute_keys();
723
+
724
+        foreach ( $keys as $key ) {
725
+            try {
726
+                $this->set_attribute( $key, null );
727
+            } catch ( GuardedPropertyException $e ) {
728
+                // We won't clear out guarded attributes.
729
+            }
730
+        }
731
+
732
+        return $this;
733
+    }
734
+
735
+    /**
736
+     * Unguards the model.
737
+     *
738
+     * Sets the model to be unguarded, allowing the filling of
739
+     * guarded attributes.
740
+     */
741
+    public function unguard() {
742
+        $this->is_guarded = false;
743
+    }
744
+
745
+    /**
746
+     * Reguards the model.
747
+     *
748
+     * Sets the model to be guarded, preventing filling of
749
+     * guarded attributes.
750
+     */
751
+    public function reguard() {
752
+        $this->is_guarded = true;
753
+    }
754
+
755
+    /**
756
+     * Retrieves all the compute methods on the model.
757
+     *
758
+     * @return array
759
+     */
760
+    protected function get_compute_methods() {
761
+        $methods = get_class_methods( get_called_class() );
762
+        $methods = array_filter( $methods, function ( $method ) {
763
+            return strrpos( $method, 'compute_', - strlen( $method ) ) !== false;
764
+        } );
765
+        $methods = array_map( function ( $method ) {
766
+            return substr( $method, strlen( 'compute_' ) );
767
+        }, $methods );
768
+
769
+        return $methods;
770
+    }
771
+
772
+    /**
773
+     * Retrieves all the related methods on the model.
774
+     *
775
+     * @return array
776
+     */
777
+    protected function get_related_methods() {
778
+        $methods = get_class_methods( get_called_class() );
779
+        $methods = array_filter( $methods, function ( $method ) {
780
+            return strrpos( $method, 'related_', - strlen( $method ) ) !== false;
781
+        } );
782
+        $methods = array_map( function ( $method ) {
783
+            return substr( $method, strlen( 'related_' ) );
784
+        }, $methods );
785
+
786
+        return $methods;
787
+    }
788
+
789
+    /**
790
+     * Returns whether this relation has already been filled on the model.
791
+     *
792
+     * @param string $relation
793
+     *
794
+     * @return bool
795
+     */
796
+    public function relation_is_filled( $relation ) {
797
+        $sha = $this
798
+            ->{$this->has_related_method( $relation )}()
799
+            ->get_sha();
800
+
801
+        return isset( $this->related[ $sha ] );
802
+    }
803
+
804
+    /**
805
+     * Returns whether the Model is currently having
806
+     * its relationships filled.
807
+     *
808
+     * @return bool
809
+     */
810
+    public function is_filling() {
811
+        return $this->filling;
812
+    }
813
+
814
+    /**
815
+     * Sets whether the Model is having its relationships filled.
816
+     *
817
+     * @param bool $is_filling
818
+     */
819
+    public function set_filling( $is_filling ) {
820
+        $this->filling = $is_filling;
821
+    }
822
+
823
+    /**
824
+     * Returns a HasMany relationship for the model.
825
+     *
826
+     * @param string $class
827
+     * @param string $type
828
+     * @param string $foreign_key
829
+     *
830
+     * @return HasMany
831
+     */
832
+    protected function has_many( $class, $type, $foreign_key ) {
833
+        return new HasMany( $this, $class, $type, $foreign_key );
834
+    }
835
+
836
+    /**
837
+     * Returns a BelongsToOne relationship for the model.
838
+     *
839
+     * @param string $class
840
+     * @param string $type
841
+     * @param string $local_key
842
+     *
843
+     * @return HasMany
844
+     */
845
+    protected function belongs_to_one( $class, $type, $local_key = '' ) {
846
+        return new BelongsToOne( $this, $class, $type, $local_key );
847
+    }
848
+
849
+    /**
850
+     * Sets up the memo array for the creating model.
851
+     */
852
+    private function maybe_boot() {
853
+        if ( ! isset( self::$memo[ get_called_class() ] ) ) {
854
+            self::$memo[ get_called_class() ] = array();
855
+        }
856
+    }
857
+
858
+    /**
859
+     * Whether this Model uses an underlying WordPress object.
860
+     *
861
+     * @return bool
862
+     */
863
+    protected function uses_wp_object() {
864
+        return $this instanceof UsesWordPressPost ||
865
+            $this instanceof UsesWordPressTerm;
866
+    }
867 867
 }
Please login to merge, or discard this patch.
src/Axolotl/Relationship/BelongsToOne.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -90,7 +90,7 @@
 block discarded – undo
90 90
 	/**
91 91
 	 * Gets the ID value for the target model to search by.
92 92
 	 *
93
-	 * @return int|false
93
+	 * @return integer
94 94
 	 *
95 95
 	 * @throws LogicException
96 96
 	 */
Please login to merge, or discard this patch.
Indentation   +106 added lines, -106 removed lines patch added patch discarded remove patch
@@ -13,110 +13,110 @@
 block discarded – undo
13 13
  * @subpackage Axolotl\Relationship
14 14
  */
15 15
 class BelongsToOne extends Root {
16
-	/**
17
-	 * Relationship's primary key name
18
-	 * on related model.
19
-	 *
20
-	 * @var string
21
-	 */
22
-	protected $local_key = '';
23
-
24
-	/**
25
-	 * HasMany constructor.
26
-	 *
27
-	 * @param Model  $model
28
-	 * @param string $class
29
-	 * @param string $type
30
-	 * @param string $local_key
31
-	 */
32
-	public function __construct( Model $model, $class, $type, $local_key ) {
33
-		$this->local_key = $local_key;
34
-
35
-		parent::__construct( $model, $class, $type );
36
-	}
37
-
38
-	/**
39
-	 * {@inheritDoc}
40
-	 *
41
-	 * @param EntityManager $database
42
-	 *
43
-	 * @throws LogicException
44
-	 */
45
-	public function attach_relation( EntityManager $database ) {
46
-		if ( $this->get_model()->is_filling() ) {
47
-			return;
48
-		}
49
-
50
-		$this->get_model()->set_filling( true );
51
-
52
-		$id = $this->make_target_id();
53
-
54
-		if ( $id ) {
55
-			$target = $database->find(
56
-				$this->get_class(),
57
-				$id
58
-			);
59
-
60
-			$this->set_target( $target );
61
-		}
62
-
63
-		$this->get_model()->set_filling( false );
64
-	}
65
-
66
-	/**
67
-	 * {@inheritDoc}
68
-	 *
69
-	 * @return string
70
-	 */
71
-	public function get_sha() {
72
-		return sha1(
73
-			__CLASS__ .
74
-			get_class( $this->model ) .
75
-			$this->class .
76
-			$this->type .
77
-			$this->local_key
78
-		);
79
-	}
80
-
81
-	/**
82
-	 * Get the relationship's local key.
83
-	 *
84
-	 * @return string
85
-	 */
86
-	public function get_local_key() {
87
-		return $this->local_key;
88
-	}
89
-
90
-	/**
91
-	 * Gets the ID value for the target model to search by.
92
-	 *
93
-	 * @return int|false
94
-	 *
95
-	 * @throws LogicException
96
-	 */
97
-	protected function make_target_id() {
98
-		$class = $this->get_class();
99
-
100
-		switch ( $this->get_relationship_type() ) {
101
-			case 'post_post':
102
-				return $this->get_model()
103
-					->get_underlying_wp_object()
104
-					->{$this->local_key};
105
-			case 'post_term':
106
-				$terms = wp_get_post_terms(
107
-					$this->get_model()
108
-						->get_underlying_wp_object()
109
-						->ID,
110
-					$class::get_taxonomy()
111
-				);
112
-
113
-				if ( ! $terms || is_wp_error( $terms ) ) {
114
-					return false;
115
-				}
116
-
117
-				return $terms[0]->term_id;
118
-			default:
119
-				throw new LogicException;
120
-		}
121
-	}
16
+    /**
17
+     * Relationship's primary key name
18
+     * on related model.
19
+     *
20
+     * @var string
21
+     */
22
+    protected $local_key = '';
23
+
24
+    /**
25
+     * HasMany constructor.
26
+     *
27
+     * @param Model  $model
28
+     * @param string $class
29
+     * @param string $type
30
+     * @param string $local_key
31
+     */
32
+    public function __construct( Model $model, $class, $type, $local_key ) {
33
+        $this->local_key = $local_key;
34
+
35
+        parent::__construct( $model, $class, $type );
36
+    }
37
+
38
+    /**
39
+     * {@inheritDoc}
40
+     *
41
+     * @param EntityManager $database
42
+     *
43
+     * @throws LogicException
44
+     */
45
+    public function attach_relation( EntityManager $database ) {
46
+        if ( $this->get_model()->is_filling() ) {
47
+            return;
48
+        }
49
+
50
+        $this->get_model()->set_filling( true );
51
+
52
+        $id = $this->make_target_id();
53
+
54
+        if ( $id ) {
55
+            $target = $database->find(
56
+                $this->get_class(),
57
+                $id
58
+            );
59
+
60
+            $this->set_target( $target );
61
+        }
62
+
63
+        $this->get_model()->set_filling( false );
64
+    }
65
+
66
+    /**
67
+     * {@inheritDoc}
68
+     *
69
+     * @return string
70
+     */
71
+    public function get_sha() {
72
+        return sha1(
73
+            __CLASS__ .
74
+            get_class( $this->model ) .
75
+            $this->class .
76
+            $this->type .
77
+            $this->local_key
78
+        );
79
+    }
80
+
81
+    /**
82
+     * Get the relationship's local key.
83
+     *
84
+     * @return string
85
+     */
86
+    public function get_local_key() {
87
+        return $this->local_key;
88
+    }
89
+
90
+    /**
91
+     * Gets the ID value for the target model to search by.
92
+     *
93
+     * @return int|false
94
+     *
95
+     * @throws LogicException
96
+     */
97
+    protected function make_target_id() {
98
+        $class = $this->get_class();
99
+
100
+        switch ( $this->get_relationship_type() ) {
101
+            case 'post_post':
102
+                return $this->get_model()
103
+                    ->get_underlying_wp_object()
104
+                    ->{$this->local_key};
105
+            case 'post_term':
106
+                $terms = wp_get_post_terms(
107
+                    $this->get_model()
108
+                        ->get_underlying_wp_object()
109
+                        ->ID,
110
+                    $class::get_taxonomy()
111
+                );
112
+
113
+                if ( ! $terms || is_wp_error( $terms ) ) {
114
+                    return false;
115
+                }
116
+
117
+                return $terms[0]->term_id;
118
+            default:
119
+                throw new LogicException;
120
+        }
121
+    }
122 122
 }
Please login to merge, or discard this patch.
src/Axolotl/Repository/AbstractRepository.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -159,7 +159,7 @@
 block discarded – undo
159 159
 	/**
160 160
 	 * Fills the provided Model with attributes from its custom table.
161 161
 	 *
162
-	 * @param Model|UsesCustomTable $model
162
+	 * @param Model $model
163 163
 	 */
164 164
 	protected function fill_table_attrs_from_table( Model $model ) {
165 165
 		$sql[] = "SELECT * FROM {$this->make_table_name( $model )}";
Please login to merge, or discard this patch.
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -17,200 +17,200 @@
 block discarded – undo
17 17
  * @subpackage Axolotl\Repository
18 18
  */
19 19
 abstract class AbstractRepository {
20
-	/**
21
-	 * All models found by Repositories.
22
-	 *
23
-	 * @var array
24
-	 */
25
-	protected static $found = array();
26
-
27
-	/**
28
-	 * Reset the array of found model
29
-	 */
30
-	public static function free() {
31
-		self::$found = array();
32
-	}
33
-
34
-	/**
35
-	 * Retrieves the retrieved model by class and id.
36
-	 *
37
-	 * @param string $class
38
-	 * @param int    $id
39
-	 *
40
-	 * @return bool
41
-	 */
42
-	protected static function get_found( $class, $id ) {
43
-		if ( isset( self::$found[ $class ][ $id ] ) ) {
44
-			return self::$found[ $class ][ $id ];
45
-		}
46
-
47
-		return false;
48
-	}
49
-
50
-	/**
51
-	 * EntityManger service.
52
-	 *
53
-	 * @var EntityManager
54
-	 */
55
-	protected $database;
56
-
57
-	/**
58
-	 * Model class for this repository.
59
-	 *
60
-	 * @var string
61
-	 */
62
-	protected $class;
63
-
64
-	/**
65
-	 * EntityManager prefix.
66
-	 *
67
-	 * @var string
68
-	 */
69
-	protected $prefix;
70
-
71
-	/**
72
-	 * WP_Query instance.
73
-	 *
74
-	 * @var WP_Query
75
-	 */
76
-	protected $main;
77
-
78
-	/**
79
-	 * WordPress Database connection.
80
-	 *
81
-	 * @var wpdb
82
-	 */
83
-	protected $wpdb;
84
-
85
-	/**
86
-	 * AbstractRepository constructor.
87
-	 *
88
-	 * @param EntityManager $database
89
-	 * @param string        $class
90
-	 */
91
-	public function __construct( EntityManager $database, $class ) {
92
-		$this->database = $database;
93
-		$this->class    = $class;
94
-		$this->prefix   = $database->get_prefix();
95
-		$this->main     = $database->get_main_query();
96
-		$this->wpdb     = $database->get_wpdb();
97
-
98
-		if ( ! isset( self::$found[ $class ] ) ) {
99
-			self::$found[ $class ] = array();
100
-		}
101
-	}
102
-
103
-	/**
104
-	 * Get a single model of the repository class with the given ID.
105
-	 *
106
-	 * @param int $id ID of the model.
107
-	 *
108
-	 * @return Model|WP_Error
109
-	 */
110
-	abstract public function find( $id );
111
-
112
-	/**
113
-	 * Finds all the models of the repository class for the given params.
114
-	 *
115
-	 * @param array $params Params to constrain the find.
116
-	 *
117
-	 * @return Collection|WP_Error
118
-	 */
119
-	abstract public function find_by( array $params = array() );
120
-
121
-	/**
122
-	 * Create and saves a new model of the repository class
123
-	 * with the given data.
124
-	 *
125
-	 * @param array $data
126
-	 *
127
-	 * @return Model|WP_Error
128
-	 */
129
-	abstract public function create( array $data = array() );
130
-
131
-	/**
132
-	 * Updates a model with its latest data.
133
-	 *
134
-	 * @param Model $model
135
-	 *
136
-	 * @return Model|WP_Error
137
-	 */
138
-	abstract public function persist( Model $model );
139
-
140
-	/**
141
-	 * Delete the provided Model.
142
-	 *
143
-	 * @param Model $model
144
-	 * @param bool  $force
145
-	 *
146
-	 * @return Model|WP_Error
147
-	 */
148
-	abstract public function delete( Model $model, $force = false );
149
-
150
-	/**
151
-	 * Registers the found Model with the EntityManager.
152
-	 *
153
-	 * @param Model $model
154
-	 */
155
-	public function register_model( Model $model ) {
156
-		self::$found[ $this->class ][ $model->get_primary_id() ] = $model;
157
-	}
158
-
159
-	/**
160
-	 * Fills the provided Model with attributes from its custom table.
161
-	 *
162
-	 * @param Model|UsesCustomTable $model
163
-	 */
164
-	protected function fill_table_attrs_from_table( Model $model ) {
165
-		$sql[] = "SELECT * FROM {$this->make_table_name( $model )}";
166
-		$sql[] = "WHERE {$model->get_foreign_key()} = %d";
167
-
168
-		$sql = $this->wpdb->prepare(
169
-			implode( ' ', $sql ),
170
-			$model->get_primary_id()
171
-		);
172
-
173
-		$row = $this->wpdb->get_row( $sql, ARRAY_A );
174
-
175
-		$model->unguard();
176
-
177
-		foreach ( $row as $key => $value ) {
178
-			$model->set_attribute( $key, $value );
179
-		}
180
-
181
-		$model->reguard();
182
-	}
183
-
184
-	/**
185
-	 * Saves the Model's changed table attributes to its table.
186
-	 *
187
-	 * @param Model $model
188
-	 *
189
-	 * @throws LogicException
190
-	 */
191
-	protected function save_table_attributes_to_table( Model $model ) {
192
-		throw new LogicException;
193
-	}
194
-
195
-	/**
196
-	 * Deletes the Model's table attributes from its table.
197
-	 *
198
-	 * @param Model $model
199
-	 *
200
-	 * @throws LogicException
201
-	 */
202
-	protected function delete_table_attributes_from_table( Model $model ) {
203
-		throw new LogicException;
204
-	}
205
-
206
-	/**
207
-	 * Creates the table name string for the provided Model.
208
-	 *
209
-	 * @param UsesCustomTable $model
210
-	 *
211
-	 * @return string
212
-	 */
213
-	protected function make_table_name( UsesCustomTable $model ) {
214
-		return "{$this->wpdb->prefix}{$this->prefix}_{$model::get_table_name()}";
215
-	}
20
+    /**
21
+     * All models found by Repositories.
22
+     *
23
+     * @var array
24
+     */
25
+    protected static $found = array();
26
+
27
+    /**
28
+     * Reset the array of found model
29
+     */
30
+    public static function free() {
31
+        self::$found = array();
32
+    }
33
+
34
+    /**
35
+     * Retrieves the retrieved model by class and id.
36
+     *
37
+     * @param string $class
38
+     * @param int    $id
39
+     *
40
+     * @return bool
41
+     */
42
+    protected static function get_found( $class, $id ) {
43
+        if ( isset( self::$found[ $class ][ $id ] ) ) {
44
+            return self::$found[ $class ][ $id ];
45
+        }
46
+
47
+        return false;
48
+    }
49
+
50
+    /**
51
+     * EntityManger service.
52
+     *
53
+     * @var EntityManager
54
+     */
55
+    protected $database;
56
+
57
+    /**
58
+     * Model class for this repository.
59
+     *
60
+     * @var string
61
+     */
62
+    protected $class;
63
+
64
+    /**
65
+     * EntityManager prefix.
66
+     *
67
+     * @var string
68
+     */
69
+    protected $prefix;
70
+
71
+    /**
72
+     * WP_Query instance.
73
+     *
74
+     * @var WP_Query
75
+     */
76
+    protected $main;
77
+
78
+    /**
79
+     * WordPress Database connection.
80
+     *
81
+     * @var wpdb
82
+     */
83
+    protected $wpdb;
84
+
85
+    /**
86
+     * AbstractRepository constructor.
87
+     *
88
+     * @param EntityManager $database
89
+     * @param string        $class
90
+     */
91
+    public function __construct( EntityManager $database, $class ) {
92
+        $this->database = $database;
93
+        $this->class    = $class;
94
+        $this->prefix   = $database->get_prefix();
95
+        $this->main     = $database->get_main_query();
96
+        $this->wpdb     = $database->get_wpdb();
97
+
98
+        if ( ! isset( self::$found[ $class ] ) ) {
99
+            self::$found[ $class ] = array();
100
+        }
101
+    }
102
+
103
+    /**
104
+     * Get a single model of the repository class with the given ID.
105
+     *
106
+     * @param int $id ID of the model.
107
+     *
108
+     * @return Model|WP_Error
109
+     */
110
+    abstract public function find( $id );
111
+
112
+    /**
113
+     * Finds all the models of the repository class for the given params.
114
+     *
115
+     * @param array $params Params to constrain the find.
116
+     *
117
+     * @return Collection|WP_Error
118
+     */
119
+    abstract public function find_by( array $params = array() );
120
+
121
+    /**
122
+     * Create and saves a new model of the repository class
123
+     * with the given data.
124
+     *
125
+     * @param array $data
126
+     *
127
+     * @return Model|WP_Error
128
+     */
129
+    abstract public function create( array $data = array() );
130
+
131
+    /**
132
+     * Updates a model with its latest data.
133
+     *
134
+     * @param Model $model
135
+     *
136
+     * @return Model|WP_Error
137
+     */
138
+    abstract public function persist( Model $model );
139
+
140
+    /**
141
+     * Delete the provided Model.
142
+     *
143
+     * @param Model $model
144
+     * @param bool  $force
145
+     *
146
+     * @return Model|WP_Error
147
+     */
148
+    abstract public function delete( Model $model, $force = false );
149
+
150
+    /**
151
+     * Registers the found Model with the EntityManager.
152
+     *
153
+     * @param Model $model
154
+     */
155
+    public function register_model( Model $model ) {
156
+        self::$found[ $this->class ][ $model->get_primary_id() ] = $model;
157
+    }
158
+
159
+    /**
160
+     * Fills the provided Model with attributes from its custom table.
161
+     *
162
+     * @param Model|UsesCustomTable $model
163
+     */
164
+    protected function fill_table_attrs_from_table( Model $model ) {
165
+        $sql[] = "SELECT * FROM {$this->make_table_name( $model )}";
166
+        $sql[] = "WHERE {$model->get_foreign_key()} = %d";
167
+
168
+        $sql = $this->wpdb->prepare(
169
+            implode( ' ', $sql ),
170
+            $model->get_primary_id()
171
+        );
172
+
173
+        $row = $this->wpdb->get_row( $sql, ARRAY_A );
174
+
175
+        $model->unguard();
176
+
177
+        foreach ( $row as $key => $value ) {
178
+            $model->set_attribute( $key, $value );
179
+        }
180
+
181
+        $model->reguard();
182
+    }
183
+
184
+    /**
185
+     * Saves the Model's changed table attributes to its table.
186
+     *
187
+     * @param Model $model
188
+     *
189
+     * @throws LogicException
190
+     */
191
+    protected function save_table_attributes_to_table( Model $model ) {
192
+        throw new LogicException;
193
+    }
194
+
195
+    /**
196
+     * Deletes the Model's table attributes from its table.
197
+     *
198
+     * @param Model $model
199
+     *
200
+     * @throws LogicException
201
+     */
202
+    protected function delete_table_attributes_from_table( Model $model ) {
203
+        throw new LogicException;
204
+    }
205
+
206
+    /**
207
+     * Creates the table name string for the provided Model.
208
+     *
209
+     * @param UsesCustomTable $model
210
+     *
211
+     * @return string
212
+     */
213
+    protected function make_table_name( UsesCustomTable $model ) {
214
+        return "{$this->wpdb->prefix}{$this->prefix}_{$model::get_table_name()}";
215
+    }
216 216
 }
Please login to merge, or discard this patch.
src/Axolotl/Repository/AbstractWordPress.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -239,7 +239,7 @@
 block discarded – undo
239 239
 	 *
240 240
 	 * @param Model $model
241 241
 	 *
242
-	 * @return int|WP_Error
242
+	 * @return integer
243 243
 	 */
244 244
 	abstract protected function save_wp_object( Model $model );
245 245
 
Please login to merge, or discard this patch.
Indentation   +276 added lines, -276 removed lines patch added patch discarded remove patch
@@ -16,280 +16,280 @@
 block discarded – undo
16 16
  * @subpackage Axolotl\Repository
17 17
  */
18 18
 abstract class AbstractWordPress extends AbstractRepository {
19
-	/**
20
-	 * {@inheritDoc}
21
-	 *
22
-	 * @param int $id
23
-	 */
24
-	public function find( $id ) {
25
-		if ( $model = self::get_found( $this->class, $id ) ) {
26
-			return $model;
27
-		}
28
-
29
-		$object = $this->get_wp_object_by_id( $id );
30
-
31
-		if ( ! $object ) {
32
-			return new WP_Error(
33
-				'not_found',
34
-				__( 'Entity not found', 'jaxion' )
35
-			);
36
-		}
37
-
38
-		return $this->make_model_from_wp_object( $object );
39
-	}
40
-
41
-	/**
42
-	 * {@inheritDoc}
43
-	 *
44
-	 * @param array $params
45
-	 *
46
-	 * @return Collection
47
-	 */
48
-	public function find_by( array $params = array() ) {
49
-		$collection = new Collection(
50
-			array(),
51
-			array( 'model' => $this->class )
52
-		);
53
-
54
-		foreach ( $this->get_wp_objects_by_params( $params ) as $object ) {
55
-			$collection->add(
56
-				$this->make_model_from_wp_object( $object )
57
-			);
58
-		}
59
-
60
-		return $collection;
61
-	}
62
-
63
-	/**
64
-	 * {@inheritDoc}
65
-	 *
66
-	 * @param array $data
67
-	 *
68
-	 * @return Model|WP_Error
69
-	 */
70
-	public function create( array $data = array() ) {
71
-		/**
72
-		 * Model object.
73
-		 *
74
-		 * @var Model $model
75
-		 */
76
-		$model = new $this->class( $data );
77
-
78
-		$id = $this->save_wp_object( $model );
79
-
80
-		if ( is_wp_error( $id ) ) {
81
-			return $id;
82
-		}
83
-
84
-		$model->set_attribute(
85
-			'object',
86
-			$this->get_wp_object_by_id( $id )
87
-		);
88
-
89
-		$this->save_table_attributes( $model );
90
-		$model->sync_original();
91
-
92
-		return $model;
93
-	}
94
-
95
-	/**
96
-	 * {@inheritDoc}
97
-	 *
98
-	 * @param Model $model
99
-	 *
100
-	 * @return Model|WP_Error
101
-	 */
102
-	public function persist( Model $model ) {
103
-		$id = $this->save_wp_object( $model );
104
-
105
-		if ( is_wp_error( $id ) ) {
106
-			return $id;
107
-		}
108
-
109
-		$model->set_attribute(
110
-			'object',
111
-			$this->get_wp_object_by_id( $id )
112
-		);
113
-
114
-		$this->save_table_attributes( $model );
115
-		$model->sync_original();
116
-
117
-		return $model;
118
-	}
119
-
120
-	/**
121
-	 * {@inheritDoc}
122
-	 *
123
-	 * @param Model $model
124
-	 * @param bool  $force
125
-	 *
126
-	 * @return Model|WP_Error
127
-	 */
128
-	public function delete( Model $model, $force = false ) {
129
-		$result = $this->delete_wp_object( $model, $force );
130
-
131
-		if ( is_wp_error( $result ) ) {
132
-			return $result;
133
-		}
134
-
135
-		if ( $force ) {
136
-			$this->delete_table_attributes( $model );
137
-		}
138
-
139
-		return $model;
140
-	}
141
-
142
-	/**
143
-	 * Builds the provided model class from the a wp object.
144
-	 *
145
-	 * @param WP_Post|WP_Term $object
146
-	 *
147
-	 * @return Model
148
-	 */
149
-	protected function make_model_from_wp_object( $object ) {
150
-		if ( $model = self::get_found( $this->class, $this->get_wp_object_id( $object ) ) ) {
151
-			return $model;
152
-		}
153
-
154
-		/**
155
-		 * Found Model.
156
-		 *
157
-		 * @var Model $model
158
-		 */
159
-		$model = new $this->class( array( 'object' => $object ) );
160
-
161
-		if ( $model instanceof UsesCustomTable ) {
162
-			$this->fill_table_attrs_from_table( $model );
163
-		} else {
164
-			$this->fill_table_attrs_from_meta( $model );
165
-		}
166
-
167
-		return $model;
168
-	}
169
-
170
-	/**
171
-	 * Save the table attributes for the provided model
172
-	 * to either a custom table or the Model's object's
173
-	 * metadata.
174
-	 *
175
-	 * @param Model $model
176
-	 */
177
-	protected function save_table_attributes( Model $model ) {
178
-		if ( $model instanceof UsesCustomTable ) {
179
-			$this->save_table_attributes_to_table( $model );
180
-		} else {
181
-			$this->save_table_attributes_to_meta( $model );
182
-		}
183
-	}
184
-
185
-	/**
186
-	 * Delete the table attributes for the provided model
187
-	 * from either a custom table or the Model's object's
188
-	 * metadata.
189
-	 *
190
-	 * @param Model $model
191
-	 */
192
-	protected function delete_table_attributes( Model $model ) {
193
-		if ( $model instanceof UsesCustomTable ) {
194
-			$this->delete_table_attributes_from_table( $model );
195
-		} else {
196
-			$this->delete_table_attributes_from_meta( $model );
197
-		}
198
-	}
199
-
200
-	/**
201
-	 * Generates the unique meta key for
202
-	 * a WordPress model's data.
203
-	 *
204
-	 * @param string $key
205
-	 *
206
-	 * @return string
207
-	 */
208
-	protected function make_meta_key( $key ) {
209
-		return "_{$this->prefix}_{$key}";
210
-	}
211
-
212
-	/**
213
-	 * Retrieves an WordPress object by the provided id.
214
-	 *
215
-	 * @param int $id
216
-	 *
217
-	 * @return object|false
218
-	 */
219
-	abstract protected function get_wp_object_by_id( $id );
220
-
221
-	/**
222
-	 * Retrieves an array of WordPress objects by the provided params.
223
-	 *
224
-	 * @param array $params
225
-	 *
226
-	 * @return array
227
-	 */
228
-	abstract protected function get_wp_objects_by_params( $params );
229
-
230
-	/**
231
-	 * Fills the provided Model with its meta attributes.
232
-	 *
233
-	 * @param Model $model
234
-	 */
235
-	abstract protected function fill_table_attrs_from_meta( Model $model );
236
-
237
-	/**
238
-	 * Save the provided WordPress object to the WordPress database.
239
-	 *
240
-	 * @param Model $model
241
-	 *
242
-	 * @return int|WP_Error
243
-	 */
244
-	abstract protected function save_wp_object( Model $model );
245
-
246
-	/**
247
-	 * Saves the provided Model's changed table attributes
248
-	 * to the appropriate meta table.
249
-	 *
250
-	 * @param Model $model
251
-	 */
252
-	abstract protected function save_table_attributes_to_meta( Model $model );
253
-
254
-	/**
255
-	 * Delete the WordPress object associated with the
256
-	 * provided model. If `$force` is true, the object
257
-	 * will be deleted directly rather than
258
-	 *
259
-	 * @param Model $model
260
-	 * @param bool  $force
261
-	 */
262
-	abstract protected function delete_wp_object( Model $model, $force = false );
263
-
264
-	/**
265
-	 * Delete all of the metadata associated with the object on
266
-	 * the provided model.
267
-	 *
268
-	 * @param Model $model
269
-	 */
270
-	abstract protected function delete_table_attributes_from_meta( Model $model );
271
-
272
-	/**
273
-	 * Gets the primary ID of the provided WordPress object.
274
-	 *
275
-	 * @param WP_Post|WP_Term $object
276
-	 *
277
-	 * @return int|null
278
-	 *
279
-	 * @throws LogicException
280
-	 */
281
-	protected function get_wp_object_id( $object ) {
282
-		if ( $object instanceof WP_Post ) {
283
-			return $object->ID;
284
-		}
285
-
286
-		if ( $object instanceof WP_Term ||
287
-		     // This is required for WP4.3- compatibility, when they returned stdClass.
288
-		     ( $object instanceof \stdClass && property_exists( $object, 'term_id' ) )
289
-		) {
290
-			return $object->term_id;
291
-		}
292
-
293
-		throw new LogicException;
294
-	}
19
+    /**
20
+     * {@inheritDoc}
21
+     *
22
+     * @param int $id
23
+     */
24
+    public function find( $id ) {
25
+        if ( $model = self::get_found( $this->class, $id ) ) {
26
+            return $model;
27
+        }
28
+
29
+        $object = $this->get_wp_object_by_id( $id );
30
+
31
+        if ( ! $object ) {
32
+            return new WP_Error(
33
+                'not_found',
34
+                __( 'Entity not found', 'jaxion' )
35
+            );
36
+        }
37
+
38
+        return $this->make_model_from_wp_object( $object );
39
+    }
40
+
41
+    /**
42
+     * {@inheritDoc}
43
+     *
44
+     * @param array $params
45
+     *
46
+     * @return Collection
47
+     */
48
+    public function find_by( array $params = array() ) {
49
+        $collection = new Collection(
50
+            array(),
51
+            array( 'model' => $this->class )
52
+        );
53
+
54
+        foreach ( $this->get_wp_objects_by_params( $params ) as $object ) {
55
+            $collection->add(
56
+                $this->make_model_from_wp_object( $object )
57
+            );
58
+        }
59
+
60
+        return $collection;
61
+    }
62
+
63
+    /**
64
+     * {@inheritDoc}
65
+     *
66
+     * @param array $data
67
+     *
68
+     * @return Model|WP_Error
69
+     */
70
+    public function create( array $data = array() ) {
71
+        /**
72
+         * Model object.
73
+         *
74
+         * @var Model $model
75
+         */
76
+        $model = new $this->class( $data );
77
+
78
+        $id = $this->save_wp_object( $model );
79
+
80
+        if ( is_wp_error( $id ) ) {
81
+            return $id;
82
+        }
83
+
84
+        $model->set_attribute(
85
+            'object',
86
+            $this->get_wp_object_by_id( $id )
87
+        );
88
+
89
+        $this->save_table_attributes( $model );
90
+        $model->sync_original();
91
+
92
+        return $model;
93
+    }
94
+
95
+    /**
96
+     * {@inheritDoc}
97
+     *
98
+     * @param Model $model
99
+     *
100
+     * @return Model|WP_Error
101
+     */
102
+    public function persist( Model $model ) {
103
+        $id = $this->save_wp_object( $model );
104
+
105
+        if ( is_wp_error( $id ) ) {
106
+            return $id;
107
+        }
108
+
109
+        $model->set_attribute(
110
+            'object',
111
+            $this->get_wp_object_by_id( $id )
112
+        );
113
+
114
+        $this->save_table_attributes( $model );
115
+        $model->sync_original();
116
+
117
+        return $model;
118
+    }
119
+
120
+    /**
121
+     * {@inheritDoc}
122
+     *
123
+     * @param Model $model
124
+     * @param bool  $force
125
+     *
126
+     * @return Model|WP_Error
127
+     */
128
+    public function delete( Model $model, $force = false ) {
129
+        $result = $this->delete_wp_object( $model, $force );
130
+
131
+        if ( is_wp_error( $result ) ) {
132
+            return $result;
133
+        }
134
+
135
+        if ( $force ) {
136
+            $this->delete_table_attributes( $model );
137
+        }
138
+
139
+        return $model;
140
+    }
141
+
142
+    /**
143
+     * Builds the provided model class from the a wp object.
144
+     *
145
+     * @param WP_Post|WP_Term $object
146
+     *
147
+     * @return Model
148
+     */
149
+    protected function make_model_from_wp_object( $object ) {
150
+        if ( $model = self::get_found( $this->class, $this->get_wp_object_id( $object ) ) ) {
151
+            return $model;
152
+        }
153
+
154
+        /**
155
+         * Found Model.
156
+         *
157
+         * @var Model $model
158
+         */
159
+        $model = new $this->class( array( 'object' => $object ) );
160
+
161
+        if ( $model instanceof UsesCustomTable ) {
162
+            $this->fill_table_attrs_from_table( $model );
163
+        } else {
164
+            $this->fill_table_attrs_from_meta( $model );
165
+        }
166
+
167
+        return $model;
168
+    }
169
+
170
+    /**
171
+     * Save the table attributes for the provided model
172
+     * to either a custom table or the Model's object's
173
+     * metadata.
174
+     *
175
+     * @param Model $model
176
+     */
177
+    protected function save_table_attributes( Model $model ) {
178
+        if ( $model instanceof UsesCustomTable ) {
179
+            $this->save_table_attributes_to_table( $model );
180
+        } else {
181
+            $this->save_table_attributes_to_meta( $model );
182
+        }
183
+    }
184
+
185
+    /**
186
+     * Delete the table attributes for the provided model
187
+     * from either a custom table or the Model's object's
188
+     * metadata.
189
+     *
190
+     * @param Model $model
191
+     */
192
+    protected function delete_table_attributes( Model $model ) {
193
+        if ( $model instanceof UsesCustomTable ) {
194
+            $this->delete_table_attributes_from_table( $model );
195
+        } else {
196
+            $this->delete_table_attributes_from_meta( $model );
197
+        }
198
+    }
199
+
200
+    /**
201
+     * Generates the unique meta key for
202
+     * a WordPress model's data.
203
+     *
204
+     * @param string $key
205
+     *
206
+     * @return string
207
+     */
208
+    protected function make_meta_key( $key ) {
209
+        return "_{$this->prefix}_{$key}";
210
+    }
211
+
212
+    /**
213
+     * Retrieves an WordPress object by the provided id.
214
+     *
215
+     * @param int $id
216
+     *
217
+     * @return object|false
218
+     */
219
+    abstract protected function get_wp_object_by_id( $id );
220
+
221
+    /**
222
+     * Retrieves an array of WordPress objects by the provided params.
223
+     *
224
+     * @param array $params
225
+     *
226
+     * @return array
227
+     */
228
+    abstract protected function get_wp_objects_by_params( $params );
229
+
230
+    /**
231
+     * Fills the provided Model with its meta attributes.
232
+     *
233
+     * @param Model $model
234
+     */
235
+    abstract protected function fill_table_attrs_from_meta( Model $model );
236
+
237
+    /**
238
+     * Save the provided WordPress object to the WordPress database.
239
+     *
240
+     * @param Model $model
241
+     *
242
+     * @return int|WP_Error
243
+     */
244
+    abstract protected function save_wp_object( Model $model );
245
+
246
+    /**
247
+     * Saves the provided Model's changed table attributes
248
+     * to the appropriate meta table.
249
+     *
250
+     * @param Model $model
251
+     */
252
+    abstract protected function save_table_attributes_to_meta( Model $model );
253
+
254
+    /**
255
+     * Delete the WordPress object associated with the
256
+     * provided model. If `$force` is true, the object
257
+     * will be deleted directly rather than
258
+     *
259
+     * @param Model $model
260
+     * @param bool  $force
261
+     */
262
+    abstract protected function delete_wp_object( Model $model, $force = false );
263
+
264
+    /**
265
+     * Delete all of the metadata associated with the object on
266
+     * the provided model.
267
+     *
268
+     * @param Model $model
269
+     */
270
+    abstract protected function delete_table_attributes_from_meta( Model $model );
271
+
272
+    /**
273
+     * Gets the primary ID of the provided WordPress object.
274
+     *
275
+     * @param WP_Post|WP_Term $object
276
+     *
277
+     * @return int|null
278
+     *
279
+     * @throws LogicException
280
+     */
281
+    protected function get_wp_object_id( $object ) {
282
+        if ( $object instanceof WP_Post ) {
283
+            return $object->ID;
284
+        }
285
+
286
+        if ( $object instanceof WP_Term ||
287
+             // This is required for WP4.3- compatibility, when they returned stdClass.
288
+             ( $object instanceof \stdClass && property_exists( $object, 'term_id' ) )
289
+        ) {
290
+            return $object->term_id;
291
+        }
292
+
293
+        throw new LogicException;
294
+    }
295 295
 }
Please login to merge, or discard this patch.
src/Http/Filter.php 1 patch
Indentation   +130 added lines, -130 removed lines patch added patch discarded remove patch
@@ -12,134 +12,134 @@
 block discarded – undo
12 12
  * @subpackage Http
13 13
  */
14 14
 class Filter implements FilterContract {
15
-	/**
16
-	 * Filter rules.
17
-	 *
18
-	 * @var array
19
-	 */
20
-	protected $rules;
21
-
22
-	/**
23
-	 * Instantiates a new filter with the provided rules array.
24
-	 *
25
-	 * @param array $rules
26
-	 */
27
-	public function __construct( $rules = array() ) {
28
-		$this->rules = $rules;
29
-	}
30
-
31
-	/**
32
-	 * Generates argument rules.
33
-	 *
34
-	 * Returns an array matching the WP-API format for argument rules,
35
-	 * including sanitization, validation, required, or defaults.
36
-	 *
37
-	 * @return array
38
-	 */
39
-	public function rules() {
40
-		$args = array();
41
-
42
-		foreach ( $this->rules as $arg => $validation ) {
43
-			if ( ! $validation || ! is_string( $validation ) ) {
44
-				continue;
45
-			}
46
-
47
-			$args[ $arg ] = $this->parse_validation( $validation );
48
-		}
49
-
50
-		return $args;
51
-	}
52
-
53
-	/**
54
-	 * Parses a validation string into a WP-API compatible rule.
55
-	 *
56
-	 * @param string $validation
57
-	 *
58
-	 * @return array
59
-	 *
60
-	 * @todo The next rule added needs to refactor this process.
61
-	 */
62
-	protected function parse_validation( $validation ) {
63
-		$validation = explode( '|', $validation );
64
-
65
-		$rules = array();
66
-
67
-		foreach ( $validation as $rule ) {
68
-			if ( 0 === strpos( $rule, 'default' ) ) {
69
-				$rule_arr = explode( ':', $rule );
70
-
71
-				$rules['default'] = count( $rule_arr ) === 2 ? array_pop( $rule_arr ) : '';
72
-			}
73
-
74
-			if ( 0 === strpos( $rule, 'oneof' ) ) {
75
-				list( $rule, $values ) = explode( ':', $rule );
76
-
77
-				$values   = explode( ',', $values );
78
-				$callback = function ( $value ) use ( $values ) {
79
-					if ( in_array( $value, $values, true ) ) {
80
-						return true;
81
-					}
82
-
83
-					return false;
84
-				};
85
-
86
-				$rules['validate_callback'] = isset( $rules['validate_callback'] ) ? $this->add_callback( $rules['validate_callback'], $callback ) : $callback;
87
-			}
88
-
89
-			switch ( $rule ) {
90
-				case 'required':
91
-					$rules['required'] = true;
92
-					break;
93
-				case 'integer':
94
-					$callback                   = array( $this, 'validate_integer' );
95
-					$rules['validate_callback'] = isset( $rules['validate_callback'] ) ? $this->add_callback( $rules['validate_callback'], $callback ) : $callback;
96
-
97
-					$callback                   = array( $this, 'make_integer' );
98
-					$rules['sanitize_callback'] = isset( $rules['sanitize_callback'] ) ? $this->add_callback( $rules['sanitize_callback'], $callback ) : $callback;
99
-					break;
100
-			}
101
-		}
102
-
103
-		return $rules;
104
-	}
105
-
106
-	/**
107
-	 * Validate that provided value is an integer.
108
-	 *
109
-	 * @param mixed $value
110
-	 *
111
-	 * @return bool
112
-	 */
113
-	public function validate_integer( $value ) {
114
-		return filter_var( $value, FILTER_VALIDATE_INT ) !== false;
115
-	}
116
-
117
-	/**
118
-	 * Casts a provided value to an integer.
119
-	 *
120
-	 * @param mixed $value
121
-	 *
122
-	 * @return int
123
-	 */
124
-	public function make_integer( $value ) {
125
-		return (int) $value;
126
-	}
127
-
128
-	/**
129
-	 * Creates a new callback that connects the previous and next callback.
130
-	 *
131
-	 * @param callable $previous
132
-	 * @param callable $next
133
-	 *
134
-	 * @return \Closure;
135
-	 */
136
-	private function add_callback( $previous, $next ) {
137
-		return function ( $value ) use ( $previous, $next ) {
138
-			if ( call_user_func( $previous, $value ) ) {
139
-				return call_user_func( $next, $value );
140
-			}
141
-
142
-			return false;
143
-		};
144
-	}
15
+    /**
16
+     * Filter rules.
17
+     *
18
+     * @var array
19
+     */
20
+    protected $rules;
21
+
22
+    /**
23
+     * Instantiates a new filter with the provided rules array.
24
+     *
25
+     * @param array $rules
26
+     */
27
+    public function __construct( $rules = array() ) {
28
+        $this->rules = $rules;
29
+    }
30
+
31
+    /**
32
+     * Generates argument rules.
33
+     *
34
+     * Returns an array matching the WP-API format for argument rules,
35
+     * including sanitization, validation, required, or defaults.
36
+     *
37
+     * @return array
38
+     */
39
+    public function rules() {
40
+        $args = array();
41
+
42
+        foreach ( $this->rules as $arg => $validation ) {
43
+            if ( ! $validation || ! is_string( $validation ) ) {
44
+                continue;
45
+            }
46
+
47
+            $args[ $arg ] = $this->parse_validation( $validation );
48
+        }
49
+
50
+        return $args;
51
+    }
52
+
53
+    /**
54
+     * Parses a validation string into a WP-API compatible rule.
55
+     *
56
+     * @param string $validation
57
+     *
58
+     * @return array
59
+     *
60
+     * @todo The next rule added needs to refactor this process.
61
+     */
62
+    protected function parse_validation( $validation ) {
63
+        $validation = explode( '|', $validation );
64
+
65
+        $rules = array();
66
+
67
+        foreach ( $validation as $rule ) {
68
+            if ( 0 === strpos( $rule, 'default' ) ) {
69
+                $rule_arr = explode( ':', $rule );
70
+
71
+                $rules['default'] = count( $rule_arr ) === 2 ? array_pop( $rule_arr ) : '';
72
+            }
73
+
74
+            if ( 0 === strpos( $rule, 'oneof' ) ) {
75
+                list( $rule, $values ) = explode( ':', $rule );
76
+
77
+                $values   = explode( ',', $values );
78
+                $callback = function ( $value ) use ( $values ) {
79
+                    if ( in_array( $value, $values, true ) ) {
80
+                        return true;
81
+                    }
82
+
83
+                    return false;
84
+                };
85
+
86
+                $rules['validate_callback'] = isset( $rules['validate_callback'] ) ? $this->add_callback( $rules['validate_callback'], $callback ) : $callback;
87
+            }
88
+
89
+            switch ( $rule ) {
90
+                case 'required':
91
+                    $rules['required'] = true;
92
+                    break;
93
+                case 'integer':
94
+                    $callback                   = array( $this, 'validate_integer' );
95
+                    $rules['validate_callback'] = isset( $rules['validate_callback'] ) ? $this->add_callback( $rules['validate_callback'], $callback ) : $callback;
96
+
97
+                    $callback                   = array( $this, 'make_integer' );
98
+                    $rules['sanitize_callback'] = isset( $rules['sanitize_callback'] ) ? $this->add_callback( $rules['sanitize_callback'], $callback ) : $callback;
99
+                    break;
100
+            }
101
+        }
102
+
103
+        return $rules;
104
+    }
105
+
106
+    /**
107
+     * Validate that provided value is an integer.
108
+     *
109
+     * @param mixed $value
110
+     *
111
+     * @return bool
112
+     */
113
+    public function validate_integer( $value ) {
114
+        return filter_var( $value, FILTER_VALIDATE_INT ) !== false;
115
+    }
116
+
117
+    /**
118
+     * Casts a provided value to an integer.
119
+     *
120
+     * @param mixed $value
121
+     *
122
+     * @return int
123
+     */
124
+    public function make_integer( $value ) {
125
+        return (int) $value;
126
+    }
127
+
128
+    /**
129
+     * Creates a new callback that connects the previous and next callback.
130
+     *
131
+     * @param callable $previous
132
+     * @param callable $next
133
+     *
134
+     * @return \Closure;
135
+     */
136
+    private function add_callback( $previous, $next ) {
137
+        return function ( $value ) use ( $previous, $next ) {
138
+            if ( call_user_func( $previous, $value ) ) {
139
+                return call_user_func( $next, $value );
140
+            }
141
+
142
+            return false;
143
+        };
144
+    }
145 145
 }
Please login to merge, or discard this patch.