Completed
Pull Request — master (#6)
by James
46:36
created
src/Assets/ServiceProvider.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -11,40 +11,40 @@
 block discarded – undo
11 11
  * @subpackage Assets
12 12
  */
13 13
 class ServiceProvider implements ServiceProviderContract {
14
-	/**
15
-	 * Container to register with.
16
-	 *
17
-	 * @var Container
18
-	 */
19
-	protected $container;
14
+    /**
15
+     * Container to register with.
16
+     *
17
+     * @var Container
18
+     */
19
+    protected $container;
20 20
 
21
-	/**
22
-	 * {@inheritDoc}
23
-	 *
24
-	 * @param Container $container
25
-	 */
26
-	public function register( Container $container ) {
27
-		$this->container = $container;
21
+    /**
22
+     * {@inheritDoc}
23
+     *
24
+     * @param Container $container
25
+     */
26
+    public function register( Container $container ) {
27
+        $this->container = $container;
28 28
 
29
-		$container->define(
30
-			array( 'assets' => 'Intraxia\Jaxion\Contract\Assets\Register' ),
31
-			$register = new Register( $container->fetch( 'url' ), $container->fetch( 'version' ) )
32
-		);
29
+        $container->define(
30
+            array( 'assets' => 'Intraxia\Jaxion\Contract\Assets\Register' ),
31
+            $register = new Register( $container->fetch( 'url' ), $container->fetch( 'version' ) )
32
+        );
33 33
 
34
-		$this->add_assets( $register );
35
-	}
34
+        $this->add_assets( $register );
35
+    }
36 36
 
37
-	/**
38
-	 * Registers the assets on the generated Register.
39
-	 *
40
-	 * This is a no-op by default by can be overwritten by the implementing developer
41
-	 * to provide a single, clean location to register their assets.
42
-	 *
43
-	 * @param Register $register
44
-	 *
45
-	 * @codeCoverageIgnore
46
-	 */
47
-	protected function add_assets( Register $register ) {
48
-		// no-op
49
-	}
37
+    /**
38
+     * Registers the assets on the generated Register.
39
+     *
40
+     * This is a no-op by default by can be overwritten by the implementing developer
41
+     * to provide a single, clean location to register their assets.
42
+     *
43
+     * @param Register $register
44
+     *
45
+     * @codeCoverageIgnore
46
+     */
47
+    protected function add_assets( Register $register ) {
48
+        // no-op
49
+    }
50 50
 }
Please login to merge, or discard this patch.
src/Core/Loader.php 1 patch
Indentation   +97 added lines, -97 removed lines patch added patch discarded remove patch
@@ -15,109 +15,109 @@
 block discarded – undo
15 15
  * @subpackage Core
16 16
  */
17 17
 class Loader implements LoaderContract {
18
-	/**
19
-	 * Array of action hooks to attach.
20
-	 *
21
-	 * @var array[]
22
-	 */
23
-	protected $actions = array();
18
+    /**
19
+     * Array of action hooks to attach.
20
+     *
21
+     * @var array[]
22
+     */
23
+    protected $actions = array();
24 24
 
25
-	/**
26
-	 * Array of filter hooks to attach.
27
-	 *
28
-	 * @var array[]
29
-	 */
30
-	protected $filters = array();
25
+    /**
26
+     * Array of filter hooks to attach.
27
+     *
28
+     * @var array[]
29
+     */
30
+    protected $filters = array();
31 31
 
32
-	/**
33
-	 * {@inheritDoc}
34
-	 */
35
-	public function run() {
36
-		foreach ( $this->actions as $action ) {
37
-			add_action(
38
-				$action['hook'],
39
-				array( $action['service'], $action['method'] ),
40
-				$action['priority'],
41
-				$action['args']
42
-			);
43
-		}
32
+    /**
33
+     * {@inheritDoc}
34
+     */
35
+    public function run() {
36
+        foreach ( $this->actions as $action ) {
37
+            add_action(
38
+                $action['hook'],
39
+                array( $action['service'], $action['method'] ),
40
+                $action['priority'],
41
+                $action['args']
42
+            );
43
+        }
44 44
 
45
-		foreach ( $this->filters as $filter ) {
46
-			add_filter(
47
-				$filter['hook'],
48
-				array( $filter['service'], $filter['method'] ),
49
-				$filter['priority'],
50
-				$filter['args']
51
-			);
52
-		}
53
-	}
45
+        foreach ( $this->filters as $filter ) {
46
+            add_filter(
47
+                $filter['hook'],
48
+                array( $filter['service'], $filter['method'] ),
49
+                $filter['priority'],
50
+                $filter['args']
51
+            );
52
+        }
53
+    }
54 54
 
55
-	/**
56
-	 * {@inheritDoc}
57
-	 *
58
-	 * @param HasActions $service
59
-	 */
60
-	public function register_actions( HasActions $service ) {
61
-		foreach ( $service->action_hooks() as $action ) {
62
-			$this->actions = $this->add(
63
-				$this->actions,
64
-				$action['hook'],
65
-				$service,
66
-				$action['method'],
67
-				isset( $action['priority'] ) ? $action['priority'] : 10,
68
-				isset( $action['args'] ) ? $action['args'] : 1
69
-			);
70
-		}
71
-	}
55
+    /**
56
+     * {@inheritDoc}
57
+     *
58
+     * @param HasActions $service
59
+     */
60
+    public function register_actions( HasActions $service ) {
61
+        foreach ( $service->action_hooks() as $action ) {
62
+            $this->actions = $this->add(
63
+                $this->actions,
64
+                $action['hook'],
65
+                $service,
66
+                $action['method'],
67
+                isset( $action['priority'] ) ? $action['priority'] : 10,
68
+                isset( $action['args'] ) ? $action['args'] : 1
69
+            );
70
+        }
71
+    }
72 72
 
73
-	/**
74
-	 * {@inheritDoc}
75
-	 *
76
-	 * @param HasFilters $service
77
-	 */
78
-	public function register_filters( HasFilters $service ) {
79
-		foreach ( $service->filter_hooks() as $filter ) {
80
-			$this->filters = $this->add(
81
-				$this->filters,
82
-				$filter['hook'],
83
-				$service,
84
-				$filter['method'],
85
-				isset( $filter['priority'] ) ? $filter['priority'] : 10,
86
-				isset( $filter['args'] ) ? $filter['args'] : 1
87
-			);
88
-		}
89
-	}
73
+    /**
74
+     * {@inheritDoc}
75
+     *
76
+     * @param HasFilters $service
77
+     */
78
+    public function register_filters( HasFilters $service ) {
79
+        foreach ( $service->filter_hooks() as $filter ) {
80
+            $this->filters = $this->add(
81
+                $this->filters,
82
+                $filter['hook'],
83
+                $service,
84
+                $filter['method'],
85
+                isset( $filter['priority'] ) ? $filter['priority'] : 10,
86
+                isset( $filter['args'] ) ? $filter['args'] : 1
87
+            );
88
+        }
89
+    }
90 90
 
91
-	/**
92
-	 * {@inheritDoc}
93
-	 *
94
-	 * @param HasShortcode $service
95
-	 */
96
-	public function register_shortcode( HasShortcode $service ) {
97
-		add_shortcode( $service->shortcode_name(), array( $service, 'do_shortcode' ) );
98
-	}
91
+    /**
92
+     * {@inheritDoc}
93
+     *
94
+     * @param HasShortcode $service
95
+     */
96
+    public function register_shortcode( HasShortcode $service ) {
97
+        add_shortcode( $service->shortcode_name(), array( $service, 'do_shortcode' ) );
98
+    }
99 99
 
100
-	/**
101
-	 * Utility to register the actions and hooks into a single collection.
102
-	 *
103
-	 * @param array  $hooks
104
-	 * @param string $hook
105
-	 * @param object $service
106
-	 * @param string $method
107
-	 * @param int    $priority
108
-	 * @param int    $accepted_args
109
-	 *
110
-	 * @return array
111
-	 */
112
-	protected function add( $hooks, $hook, $service, $method, $priority, $accepted_args ) {
113
-		$hooks[] = array(
114
-			'hook'     => $hook,
115
-			'service'  => $service,
116
-			'method'   => $method,
117
-			'priority' => $priority,
118
-			'args'     => $accepted_args,
119
-		);
100
+    /**
101
+     * Utility to register the actions and hooks into a single collection.
102
+     *
103
+     * @param array  $hooks
104
+     * @param string $hook
105
+     * @param object $service
106
+     * @param string $method
107
+     * @param int    $priority
108
+     * @param int    $accepted_args
109
+     *
110
+     * @return array
111
+     */
112
+    protected function add( $hooks, $hook, $service, $method, $priority, $accepted_args ) {
113
+        $hooks[] = array(
114
+            'hook'     => $hook,
115
+            'service'  => $service,
116
+            'method'   => $method,
117
+            'priority' => $priority,
118
+            'args'     => $accepted_args,
119
+        );
120 120
 
121
-		return $hooks;
122
-	}
121
+        return $hooks;
122
+    }
123 123
 }
Please login to merge, or discard this patch.
src/Core/Container.php 1 patch
Indentation   +318 added lines, -318 removed lines patch added patch discarded remove patch
@@ -13,322 +13,322 @@
 block discarded – undo
13 13
  * @subpackage Core
14 14
  */
15 15
 class Container implements ContainerContract {
16
-	/**
17
-	 * ServiceProvider names to register with the container.
18
-	 *
19
-	 * Can be overwritten to include predefined providers.
20
-	 *
21
-	 * @var string[]
22
-	 */
23
-	protected $providers = array();
24
-
25
-	/**
26
-	 * Registered definitions.
27
-	 *
28
-	 * @var mixed[]
29
-	 */
30
-	private $definitions = array();
31
-
32
-	/**
33
-	 * Aliases to share between fetches.
34
-	 *
35
-	 * @var <string, true>[]
36
-	 */
37
-	private $shared = array();
38
-
39
-	/**
40
-	 * Aliases of all the registered services.
41
-	 *
42
-	 * @var <string, true>[]
43
-	 */
44
-	private $aliases = array();
45
-
46
-	/**
47
-	 * Array of classes registered on the container.
48
-	 *
49
-	 * @var <string, true>[]
50
-	 */
51
-	private $classes = array();
52
-
53
-	/**
54
-	 * Current position in the loop.
55
-	 *
56
-	 * @var int
57
-	 */
58
-	private $position;
59
-
60
-	/**
61
-	 * 0-indexed array of aliases for looping.
62
-	 *
63
-	 * @var string[]
64
-	 */
65
-	private $keys = array();
66
-
67
-	/**
68
-	 * Create a new container with the given providers.
69
-	 *
70
-	 * Providers can be instances or the class of the provider as a string.
71
-	 *
72
-	 * @param ServiceProvider[]|string[] $providers
73
-	 */
74
-	public function __construct( array $providers = array() ) {
75
-		// array_unique ensures we only register each provider once.
76
-		$providers = array_unique( array_merge( $this->providers, $providers ) );
77
-
78
-		foreach ( $providers as $provider ) {
79
-			if ( is_string( $provider ) && class_exists( $provider ) ) {
80
-				$provider = new $provider;
81
-			}
82
-
83
-			if ( $provider instanceof ServiceProvider ) {
84
-				$this->register( $provider );
85
-			}
86
-		}
87
-	}
88
-
89
-
90
-	/**
91
-	 * {@inheritdoc}
92
-	 *
93
-	 * @param string|array $alias
94
-	 * @param mixed        $definition
95
-	 *
96
-	 * @throws DefinedAliasException
97
-	 *
98
-	 * @return $this
99
-	 */
100
-	public function define( $alias, $definition ) {
101
-		if ( is_array( $alias ) ) {
102
-			$class = current( $alias );
103
-			$alias = key( $alias );
104
-		}
105
-
106
-		if ( isset( $this->aliases[ $alias ] ) ) {
107
-			throw new DefinedAliasException( $alias );
108
-		}
109
-
110
-		$this->aliases[ $alias ]     = true;
111
-		$this->definitions[ $alias ] = $definition;
112
-
113
-		// Closures are treated as factories unless
114
-		// defined via Container::share.
115
-		if ( ! $definition instanceof \Closure ) {
116
-			$this->shared[ $alias ] = true;
117
-		}
118
-
119
-		if ( isset( $class ) ) {
120
-			$this->classes[ $class ] = $alias;
121
-		}
122
-
123
-		return $this;
124
-	}
125
-
126
-	/**
127
-	 * {@inheritdoc}
128
-	 *
129
-	 * @param string|array $alias
130
-	 * @param mixed        $definition
131
-	 *
132
-	 * @throws DefinedAliasException
133
-	 *
134
-	 * @return $this
135
-	 */
136
-	public function share( $alias, $definition ) {
137
-		$this->define( $alias, $definition );
138
-
139
-		if ( is_array( $alias ) ) {
140
-			$alias = key( $alias );
141
-		}
142
-
143
-		$this->shared[ $alias ] = true;
144
-
145
-		return $this;
146
-	}
147
-
148
-	/**
149
-	 * {@inheritdoc}
150
-	 *
151
-	 * @param string $alias
152
-	 *
153
-	 * @throws UndefinedAliasException
154
-	 *
155
-	 * @return mixed
156
-	 */
157
-	public function fetch( $alias ) {
158
-		if ( isset( $this->classes[ $alias ] ) ) {
159
-			// If the alias is a class name,
160
-			// then retrieve its linked alias.
161
-			// This is only registered when
162
-			// registering using an array.
163
-			$alias = $this->classes[ $alias ];
164
-		}
165
-
166
-		if ( ! isset( $this->aliases[ $alias ] ) ) {
167
-			throw new UndefinedAliasException( $alias );
168
-		}
169
-
170
-		$value = $this->definitions[ $alias ];
171
-
172
-		// If the shared value is a closure,
173
-		// execute it and assign the result
174
-		// in place of the closure.
175
-		if ( $value instanceof \Closure ) {
176
-			$factory = $value;
177
-			$value   = $factory( $this );
178
-		}
179
-
180
-		// If the value is shared, save the shared value.
181
-		if ( isset( $this->shared[ $alias ] ) ) {
182
-			$this->definitions[ $alias ] = $value;
183
-		}
184
-
185
-		// Return the fetched value.
186
-		return $value;
187
-	}
188
-
189
-	/**
190
-	 * {@inheritdoc}
191
-	 *
192
-	 * @param  string $alias
193
-	 *
194
-	 * @return bool
195
-	 */
196
-	public function has( $alias ) {
197
-		return isset( $this->aliases[ $alias ] );
198
-	}
199
-
200
-	/**
201
-	 * {@inheritDoc}
202
-	 *
203
-	 * @param string $alias
204
-	 *
205
-	 * @return $this
206
-	 */
207
-	public function remove( $alias ) {
208
-		if ( isset( $this->aliases[ $alias ] ) ) {
209
-			/**
210
-			 * If there's no reference in the aliases array,
211
-			 * the service won't be found on fetching and
212
-			 * can be overwritten on setting.
213
-			 *
214
-			 * Pros: Quick setting/unsetting, faster
215
-			 * performance on those operations when doing
216
-			 * a lot of these.
217
-			 *
218
-			 * Cons: Objects and values set in the container
219
-			 * can't get garbage collected.
220
-			 *
221
-			 * If this is a problem, this may need to be revisited.
222
-			 */
223
-			unset( $this->aliases[ $alias ] );
224
-		}
225
-
226
-		return $this;
227
-	}
228
-
229
-	/**
230
-	 * {@inheritDoc}
231
-	 *
232
-	 * @param ServiceProvider $provider
233
-	 *
234
-	 * @return $this
235
-	 */
236
-	public function register( ServiceProvider $provider ) {
237
-		// @todo make sure provider is only registered once
238
-		$provider->register( $this );
239
-
240
-		return $this;
241
-	}
242
-
243
-	/**
244
-	 * Set a value into the container.
245
-	 *
246
-	 * @param  string $id
247
-	 * @param  mixed  $value
248
-	 *
249
-	 * @see    define
250
-	 */
251
-	public function offsetSet( $id, $value ) {
252
-		$this->define( $id, $value );
253
-	}
254
-
255
-	/**
256
-	 * Get an value from the container.
257
-	 *
258
-	 * @param  string $id
259
-	 *
260
-	 * @return object
261
-	 * @throws UndefinedAliasException
262
-	 *
263
-	 * @see    fetch
264
-	 */
265
-	public function offsetGet( $id ) {
266
-		return $this->fetch( $id );
267
-	}
268
-
269
-	/**
270
-	 * Checks if a key is set on the container.
271
-	 *
272
-	 * @param  string $id
273
-	 *
274
-	 * @return bool
275
-	 *
276
-	 * @see    has
277
-	 */
278
-	public function offsetExists( $id ) {
279
-		return $this->has( $id );
280
-	}
281
-
282
-	/**
283
-	 * Remove a key from the container.
284
-	 *
285
-	 * @param string $id
286
-	 *
287
-	 * @see   remove
288
-	 */
289
-	public function offsetUnset( $id ) {
290
-		$this->remove( $id );
291
-	}
292
-
293
-	/**
294
-	 * Sets the object properties to prepare for the loop.
295
-	 */
296
-	public function rewind() {
297
-		$this->position = 0;
298
-		$this->keys     = array_keys( $this->aliases );
299
-	}
300
-
301
-	/**
302
-	 * Retrieves the service object for the current step in the loop.
303
-	 *
304
-	 * @return object
305
-	 */
306
-	public function current() {
307
-		return $this->fetch( $this->keys[ $this->position ] );
308
-	}
309
-
310
-	/**
311
-	 * Retrieves the key for the current step in the loop.
312
-	 *
313
-	 * @return string
314
-	 */
315
-	public function key() {
316
-		return $this->keys[ $this->position ];
317
-	}
318
-
319
-	/**
320
-	 * Increments to the next step in the loop.
321
-	 */
322
-	public function next() {
323
-		$this->position ++;
324
-	}
325
-
326
-	/**
327
-	 * Checks if the next step in the loop in valid.
328
-	 *
329
-	 * @return bool
330
-	 */
331
-	public function valid() {
332
-		return isset( $this->keys[ $this->position ] );
333
-	}
16
+    /**
17
+     * ServiceProvider names to register with the container.
18
+     *
19
+     * Can be overwritten to include predefined providers.
20
+     *
21
+     * @var string[]
22
+     */
23
+    protected $providers = array();
24
+
25
+    /**
26
+     * Registered definitions.
27
+     *
28
+     * @var mixed[]
29
+     */
30
+    private $definitions = array();
31
+
32
+    /**
33
+     * Aliases to share between fetches.
34
+     *
35
+     * @var <string, true>[]
36
+     */
37
+    private $shared = array();
38
+
39
+    /**
40
+     * Aliases of all the registered services.
41
+     *
42
+     * @var <string, true>[]
43
+     */
44
+    private $aliases = array();
45
+
46
+    /**
47
+     * Array of classes registered on the container.
48
+     *
49
+     * @var <string, true>[]
50
+     */
51
+    private $classes = array();
52
+
53
+    /**
54
+     * Current position in the loop.
55
+     *
56
+     * @var int
57
+     */
58
+    private $position;
59
+
60
+    /**
61
+     * 0-indexed array of aliases for looping.
62
+     *
63
+     * @var string[]
64
+     */
65
+    private $keys = array();
66
+
67
+    /**
68
+     * Create a new container with the given providers.
69
+     *
70
+     * Providers can be instances or the class of the provider as a string.
71
+     *
72
+     * @param ServiceProvider[]|string[] $providers
73
+     */
74
+    public function __construct( array $providers = array() ) {
75
+        // array_unique ensures we only register each provider once.
76
+        $providers = array_unique( array_merge( $this->providers, $providers ) );
77
+
78
+        foreach ( $providers as $provider ) {
79
+            if ( is_string( $provider ) && class_exists( $provider ) ) {
80
+                $provider = new $provider;
81
+            }
82
+
83
+            if ( $provider instanceof ServiceProvider ) {
84
+                $this->register( $provider );
85
+            }
86
+        }
87
+    }
88
+
89
+
90
+    /**
91
+     * {@inheritdoc}
92
+     *
93
+     * @param string|array $alias
94
+     * @param mixed        $definition
95
+     *
96
+     * @throws DefinedAliasException
97
+     *
98
+     * @return $this
99
+     */
100
+    public function define( $alias, $definition ) {
101
+        if ( is_array( $alias ) ) {
102
+            $class = current( $alias );
103
+            $alias = key( $alias );
104
+        }
105
+
106
+        if ( isset( $this->aliases[ $alias ] ) ) {
107
+            throw new DefinedAliasException( $alias );
108
+        }
109
+
110
+        $this->aliases[ $alias ]     = true;
111
+        $this->definitions[ $alias ] = $definition;
112
+
113
+        // Closures are treated as factories unless
114
+        // defined via Container::share.
115
+        if ( ! $definition instanceof \Closure ) {
116
+            $this->shared[ $alias ] = true;
117
+        }
118
+
119
+        if ( isset( $class ) ) {
120
+            $this->classes[ $class ] = $alias;
121
+        }
122
+
123
+        return $this;
124
+    }
125
+
126
+    /**
127
+     * {@inheritdoc}
128
+     *
129
+     * @param string|array $alias
130
+     * @param mixed        $definition
131
+     *
132
+     * @throws DefinedAliasException
133
+     *
134
+     * @return $this
135
+     */
136
+    public function share( $alias, $definition ) {
137
+        $this->define( $alias, $definition );
138
+
139
+        if ( is_array( $alias ) ) {
140
+            $alias = key( $alias );
141
+        }
142
+
143
+        $this->shared[ $alias ] = true;
144
+
145
+        return $this;
146
+    }
147
+
148
+    /**
149
+     * {@inheritdoc}
150
+     *
151
+     * @param string $alias
152
+     *
153
+     * @throws UndefinedAliasException
154
+     *
155
+     * @return mixed
156
+     */
157
+    public function fetch( $alias ) {
158
+        if ( isset( $this->classes[ $alias ] ) ) {
159
+            // If the alias is a class name,
160
+            // then retrieve its linked alias.
161
+            // This is only registered when
162
+            // registering using an array.
163
+            $alias = $this->classes[ $alias ];
164
+        }
165
+
166
+        if ( ! isset( $this->aliases[ $alias ] ) ) {
167
+            throw new UndefinedAliasException( $alias );
168
+        }
169
+
170
+        $value = $this->definitions[ $alias ];
171
+
172
+        // If the shared value is a closure,
173
+        // execute it and assign the result
174
+        // in place of the closure.
175
+        if ( $value instanceof \Closure ) {
176
+            $factory = $value;
177
+            $value   = $factory( $this );
178
+        }
179
+
180
+        // If the value is shared, save the shared value.
181
+        if ( isset( $this->shared[ $alias ] ) ) {
182
+            $this->definitions[ $alias ] = $value;
183
+        }
184
+
185
+        // Return the fetched value.
186
+        return $value;
187
+    }
188
+
189
+    /**
190
+     * {@inheritdoc}
191
+     *
192
+     * @param  string $alias
193
+     *
194
+     * @return bool
195
+     */
196
+    public function has( $alias ) {
197
+        return isset( $this->aliases[ $alias ] );
198
+    }
199
+
200
+    /**
201
+     * {@inheritDoc}
202
+     *
203
+     * @param string $alias
204
+     *
205
+     * @return $this
206
+     */
207
+    public function remove( $alias ) {
208
+        if ( isset( $this->aliases[ $alias ] ) ) {
209
+            /**
210
+             * If there's no reference in the aliases array,
211
+             * the service won't be found on fetching and
212
+             * can be overwritten on setting.
213
+             *
214
+             * Pros: Quick setting/unsetting, faster
215
+             * performance on those operations when doing
216
+             * a lot of these.
217
+             *
218
+             * Cons: Objects and values set in the container
219
+             * can't get garbage collected.
220
+             *
221
+             * If this is a problem, this may need to be revisited.
222
+             */
223
+            unset( $this->aliases[ $alias ] );
224
+        }
225
+
226
+        return $this;
227
+    }
228
+
229
+    /**
230
+     * {@inheritDoc}
231
+     *
232
+     * @param ServiceProvider $provider
233
+     *
234
+     * @return $this
235
+     */
236
+    public function register( ServiceProvider $provider ) {
237
+        // @todo make sure provider is only registered once
238
+        $provider->register( $this );
239
+
240
+        return $this;
241
+    }
242
+
243
+    /**
244
+     * Set a value into the container.
245
+     *
246
+     * @param  string $id
247
+     * @param  mixed  $value
248
+     *
249
+     * @see    define
250
+     */
251
+    public function offsetSet( $id, $value ) {
252
+        $this->define( $id, $value );
253
+    }
254
+
255
+    /**
256
+     * Get an value from the container.
257
+     *
258
+     * @param  string $id
259
+     *
260
+     * @return object
261
+     * @throws UndefinedAliasException
262
+     *
263
+     * @see    fetch
264
+     */
265
+    public function offsetGet( $id ) {
266
+        return $this->fetch( $id );
267
+    }
268
+
269
+    /**
270
+     * Checks if a key is set on the container.
271
+     *
272
+     * @param  string $id
273
+     *
274
+     * @return bool
275
+     *
276
+     * @see    has
277
+     */
278
+    public function offsetExists( $id ) {
279
+        return $this->has( $id );
280
+    }
281
+
282
+    /**
283
+     * Remove a key from the container.
284
+     *
285
+     * @param string $id
286
+     *
287
+     * @see   remove
288
+     */
289
+    public function offsetUnset( $id ) {
290
+        $this->remove( $id );
291
+    }
292
+
293
+    /**
294
+     * Sets the object properties to prepare for the loop.
295
+     */
296
+    public function rewind() {
297
+        $this->position = 0;
298
+        $this->keys     = array_keys( $this->aliases );
299
+    }
300
+
301
+    /**
302
+     * Retrieves the service object for the current step in the loop.
303
+     *
304
+     * @return object
305
+     */
306
+    public function current() {
307
+        return $this->fetch( $this->keys[ $this->position ] );
308
+    }
309
+
310
+    /**
311
+     * Retrieves the key for the current step in the loop.
312
+     *
313
+     * @return string
314
+     */
315
+    public function key() {
316
+        return $this->keys[ $this->position ];
317
+    }
318
+
319
+    /**
320
+     * Increments to the next step in the loop.
321
+     */
322
+    public function next() {
323
+        $this->position ++;
324
+    }
325
+
326
+    /**
327
+     * Checks if the next step in the loop in valid.
328
+     *
329
+     * @return bool
330
+     */
331
+    public function valid() {
332
+        return isset( $this->keys[ $this->position ] );
333
+    }
334 334
 }
Please login to merge, or discard this patch.
src/Core/Application.php 1 patch
Indentation   +142 added lines, -142 removed lines patch added patch discarded remove patch
@@ -13,146 +13,146 @@
 block discarded – undo
13 13
  * @package Intraxia\Jaxion
14 14
  */
15 15
 class Application extends Container implements ApplicationContract {
16
-	/**
17
-	 * Define plugin version on Application.
18
-	 */
19
-	const VERSION = '';
20
-
21
-	/**
22
-	 * Singleton instance of the Application object
23
-	 *
24
-	 * @var Application
25
-	 */
26
-	protected static $instance = null;
27
-
28
-	/**
29
-	 * Instantiates a new Application container.
30
-	 *
31
-	 * The Application constructor enforces the presence of of a single instance
32
-	 * of the Application. If an instance already exists, an Exception will be thrown.
33
-	 *
34
-	 * @param string $file
35
-	 * @param array  $providers
36
-	 *
37
-	 * @throws ApplicationAlreadyBootedException
38
-	 */
39
-	public function __construct( $file, array $providers = array() ) {
40
-		if ( null !== static::$instance ) {
41
-			throw new ApplicationAlreadyBootedException;
42
-		}
43
-
44
-		static::$instance = $this;
45
-
46
-		$this->register_constants( $file );
47
-		$this->register_core_services();
48
-		$this->load_i18n();
49
-
50
-		register_activation_hook( $file, array( $this, 'activate' ) );
51
-		register_deactivation_hook( $file, array( $this, 'deactivate' ) );
52
-
53
-		parent::__construct( $providers );
54
-	}
55
-
56
-	/**
57
-	 * {@inheritDoc}
58
-	 *
59
-	 * @throws UnexpectedValueException
60
-	 */
61
-	public function boot() {
62
-		$loader = $this->fetch( 'loader' );
63
-
64
-		if ( ! $loader instanceof LoaderContract ) {
65
-			throw new UnexpectedValueException;
66
-		}
67
-
68
-		foreach ( $this as $alias => $value ) {
69
-			if ( $value instanceof HasActions ) {
70
-				$loader->register_actions( $value );
71
-			}
72
-
73
-			if ( $value instanceof HasFilters ) {
74
-				$loader->register_filters( $value );
75
-			}
76
-
77
-			if ( $value instanceof HasShortcode ) {
78
-				$loader->register_shortcode( $value );
79
-			}
80
-		}
81
-
82
-		add_action( 'plugins_loaded', array( $loader, 'run' ) );
83
-	}
84
-
85
-	/**
86
-	 * {@inheritdoc}
87
-	 *
88
-	 * @codeCoverageIgnore
89
-	 */
90
-	public function activate() {
91
-		// no-op
92
-	}
93
-
94
-	/**
95
-	 * {@inheritdoc}
96
-	 *
97
-	 * @codeCoverageIgnore
98
-	 */
99
-	public function deactivate() {
100
-		// no-op
101
-	}
102
-
103
-	/**
104
-	 * {@inheritDoc}
105
-	 *
106
-	 * @return Application
107
-	 * @throws ApplicationNotBootedException
108
-	 */
109
-	public static function instance() {
110
-		if ( null === static::$instance ) {
111
-			throw new ApplicationNotBootedException;
112
-		}
113
-
114
-		return static::$instance;
115
-	}
116
-
117
-	/**
118
-	 * {@inheritDoc}
119
-	 */
120
-	public static function shutdown() {
121
-		if ( null !== static::$instance ) {
122
-			static::$instance = null;
123
-		}
124
-	}
125
-
126
-	/**
127
-	 * Sets the plugin's url, path, and basename.
128
-	 *
129
-	 * @param string $file
130
-	 */
131
-	private function register_constants( $file ) {
132
-		$this->share( 'url', plugin_dir_url( $file ) );
133
-		$this->share( 'path', plugin_dir_path( $file ) );
134
-		$this->share( 'basename', $basename = plugin_basename( $file ) );
135
-		$this->share( 'slug', dirname( $basename ) );
136
-		$this->share( 'version', static::VERSION );
137
-	}
138
-
139
-	/**
140
-	 * Registers the built-in services with the Application container.
141
-	 */
142
-	private function register_core_services() {
143
-		$this->share( array( 'loader' => 'Intraxia\Jaxion\Contract\Core\Loader' ), function ( $app ) {
144
-			return new Loader( $app );
145
-		} );
146
-	}
147
-
148
-	/**
149
-	 * Load's the plugin's translation files.
150
-	 */
151
-	private function load_i18n() {
152
-		load_plugin_textdomain(
153
-			$this->fetch( 'basename' ),
154
-			false,
155
-			basename( $this->fetch( 'path' ) ) . '/languages/'
156
-		);
157
-	}
16
+    /**
17
+     * Define plugin version on Application.
18
+     */
19
+    const VERSION = '';
20
+
21
+    /**
22
+     * Singleton instance of the Application object
23
+     *
24
+     * @var Application
25
+     */
26
+    protected static $instance = null;
27
+
28
+    /**
29
+     * Instantiates a new Application container.
30
+     *
31
+     * The Application constructor enforces the presence of of a single instance
32
+     * of the Application. If an instance already exists, an Exception will be thrown.
33
+     *
34
+     * @param string $file
35
+     * @param array  $providers
36
+     *
37
+     * @throws ApplicationAlreadyBootedException
38
+     */
39
+    public function __construct( $file, array $providers = array() ) {
40
+        if ( null !== static::$instance ) {
41
+            throw new ApplicationAlreadyBootedException;
42
+        }
43
+
44
+        static::$instance = $this;
45
+
46
+        $this->register_constants( $file );
47
+        $this->register_core_services();
48
+        $this->load_i18n();
49
+
50
+        register_activation_hook( $file, array( $this, 'activate' ) );
51
+        register_deactivation_hook( $file, array( $this, 'deactivate' ) );
52
+
53
+        parent::__construct( $providers );
54
+    }
55
+
56
+    /**
57
+     * {@inheritDoc}
58
+     *
59
+     * @throws UnexpectedValueException
60
+     */
61
+    public function boot() {
62
+        $loader = $this->fetch( 'loader' );
63
+
64
+        if ( ! $loader instanceof LoaderContract ) {
65
+            throw new UnexpectedValueException;
66
+        }
67
+
68
+        foreach ( $this as $alias => $value ) {
69
+            if ( $value instanceof HasActions ) {
70
+                $loader->register_actions( $value );
71
+            }
72
+
73
+            if ( $value instanceof HasFilters ) {
74
+                $loader->register_filters( $value );
75
+            }
76
+
77
+            if ( $value instanceof HasShortcode ) {
78
+                $loader->register_shortcode( $value );
79
+            }
80
+        }
81
+
82
+        add_action( 'plugins_loaded', array( $loader, 'run' ) );
83
+    }
84
+
85
+    /**
86
+     * {@inheritdoc}
87
+     *
88
+     * @codeCoverageIgnore
89
+     */
90
+    public function activate() {
91
+        // no-op
92
+    }
93
+
94
+    /**
95
+     * {@inheritdoc}
96
+     *
97
+     * @codeCoverageIgnore
98
+     */
99
+    public function deactivate() {
100
+        // no-op
101
+    }
102
+
103
+    /**
104
+     * {@inheritDoc}
105
+     *
106
+     * @return Application
107
+     * @throws ApplicationNotBootedException
108
+     */
109
+    public static function instance() {
110
+        if ( null === static::$instance ) {
111
+            throw new ApplicationNotBootedException;
112
+        }
113
+
114
+        return static::$instance;
115
+    }
116
+
117
+    /**
118
+     * {@inheritDoc}
119
+     */
120
+    public static function shutdown() {
121
+        if ( null !== static::$instance ) {
122
+            static::$instance = null;
123
+        }
124
+    }
125
+
126
+    /**
127
+     * Sets the plugin's url, path, and basename.
128
+     *
129
+     * @param string $file
130
+     */
131
+    private function register_constants( $file ) {
132
+        $this->share( 'url', plugin_dir_url( $file ) );
133
+        $this->share( 'path', plugin_dir_path( $file ) );
134
+        $this->share( 'basename', $basename = plugin_basename( $file ) );
135
+        $this->share( 'slug', dirname( $basename ) );
136
+        $this->share( 'version', static::VERSION );
137
+    }
138
+
139
+    /**
140
+     * Registers the built-in services with the Application container.
141
+     */
142
+    private function register_core_services() {
143
+        $this->share( array( 'loader' => 'Intraxia\Jaxion\Contract\Core\Loader' ), function ( $app ) {
144
+            return new Loader( $app );
145
+        } );
146
+    }
147
+
148
+    /**
149
+     * Load's the plugin's translation files.
150
+     */
151
+    private function load_i18n() {
152
+        load_plugin_textdomain(
153
+            $this->fetch( 'basename' ),
154
+            false,
155
+            basename( $this->fetch( 'path' ) ) . '/languages/'
156
+        );
157
+    }
158 158
 }
Please login to merge, or discard this patch.
src/Utility/Str.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -11,39 +11,39 @@
 block discarded – undo
11 11
  * @subpackage Utility
12 12
  */
13 13
 class Str {
14
-	/**
15
-	 * Determine if a given string starts with a given substring.
16
-	 *
17
-	 * @param  string       $haystack
18
-	 * @param  string|array $needles
19
-	 *
20
-	 * @return bool
21
-	 */
22
-	public static function starts_with( $haystack, $needles ) {
23
-		foreach ( (array) $needles as $needle ) {
24
-			if ( '' !== $needle && 0 === strpos( $haystack, $needle ) ) {
25
-				return true;
26
-			}
27
-		}
14
+    /**
15
+     * Determine if a given string starts with a given substring.
16
+     *
17
+     * @param  string       $haystack
18
+     * @param  string|array $needles
19
+     *
20
+     * @return bool
21
+     */
22
+    public static function starts_with( $haystack, $needles ) {
23
+        foreach ( (array) $needles as $needle ) {
24
+            if ( '' !== $needle && 0 === strpos( $haystack, $needle ) ) {
25
+                return true;
26
+            }
27
+        }
28 28
 
29
-		return false;
30
-	}
29
+        return false;
30
+    }
31 31
 
32
-	/**
33
-	 * Determine if a given string ends with a given substring.
34
-	 *
35
-	 * @param  string       $haystack
36
-	 * @param  string|array $needles
37
-	 *
38
-	 * @return bool
39
-	 */
40
-	public static function ends_with( $haystack, $needles ) {
41
-		foreach ( (array) $needles as $needle ) {
42
-			if ( substr( $haystack, - strlen( $needle ) ) === (string) $needle ) {
43
-				return true;
44
-			}
45
-		}
32
+    /**
33
+     * Determine if a given string ends with a given substring.
34
+     *
35
+     * @param  string       $haystack
36
+     * @param  string|array $needles
37
+     *
38
+     * @return bool
39
+     */
40
+    public static function ends_with( $haystack, $needles ) {
41
+        foreach ( (array) $needles as $needle ) {
42
+            if ( substr( $haystack, - strlen( $needle ) ) === (string) $needle ) {
43
+                return true;
44
+            }
45
+        }
46 46
 
47
-		return false;
48
-	}
47
+        return false;
48
+    }
49 49
 }
Please login to merge, or discard this patch.
src/Contract/Axolotl/EntityManager.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -6,54 +6,54 @@
 block discarded – undo
6 6
 use WP_Error;
7 7
 
8 8
 interface EntityManager {
9
-	/**
10
-	 * Get a single model of the provided class with the given ID.
11
-	 *
12
-	 * @param string $class Fully qualified class name of model.
13
-	 * @param int    $id    ID of the model.
14
-	 *
15
-	 * @return Model|WP_Error
16
-	 */
17
-	public function find( $class, $id );
9
+    /**
10
+     * Get a single model of the provided class with the given ID.
11
+     *
12
+     * @param string $class Fully qualified class name of model.
13
+     * @param int    $id    ID of the model.
14
+     *
15
+     * @return Model|WP_Error
16
+     */
17
+    public function find( $class, $id );
18 18
 
19
-	/**
20
-	 * Finds all the models of the provided class for the given params.
21
-	 *
22
-	 * This method will return an empty Collection if the query returns no models.
23
-	 *
24
-	 * @param string $class  Fully qualified class name of models to find.
25
-	 * @param array  $params Params to constrain the find.
26
-	 *
27
-	 * @return Collection|WP_Error
28
-	 */
29
-	public function find_by( $class, $params = array() );
19
+    /**
20
+     * Finds all the models of the provided class for the given params.
21
+     *
22
+     * This method will return an empty Collection if the query returns no models.
23
+     *
24
+     * @param string $class  Fully qualified class name of models to find.
25
+     * @param array  $params Params to constrain the find.
26
+     *
27
+     * @return Collection|WP_Error
28
+     */
29
+    public function find_by( $class, $params = array() );
30 30
 
31
-	/**
32
-	 * Saves a new model of the provided class with the given data.
33
-	 *
34
-	 * @param string $class
35
-	 * @param array  $data
36
-	 *
37
-	 * @return Model|WP_Error
38
-	 */
39
-	public function create( $class, $data = array() );
31
+    /**
32
+     * Saves a new model of the provided class with the given data.
33
+     *
34
+     * @param string $class
35
+     * @param array  $data
36
+     *
37
+     * @return Model|WP_Error
38
+     */
39
+    public function create( $class, $data = array() );
40 40
 
41
-	/**
42
-	 * Updates a model with its latest dataE.
43
-	 *
44
-	 * @param Model $model
45
-	 *
46
-	 * @return Model|WP_Error
47
-	 */
48
-	public function persist( Model $model );
41
+    /**
42
+     * Updates a model with its latest dataE.
43
+     *
44
+     * @param Model $model
45
+     *
46
+     * @return Model|WP_Error
47
+     */
48
+    public function persist( Model $model );
49 49
 
50
-	/**
51
-	 * Delete the provide
52
-	 *
53
-	 * @param Model $model
54
-	 * @param bool  $force
55
-	 *
56
-	 * @return mixed
57
-	 */
58
-	public function delete( Model $model, $force = false );
50
+    /**
51
+     * Delete the provide
52
+     *
53
+     * @param Model $model
54
+     * @param bool  $force
55
+     *
56
+     * @return mixed
57
+     */
58
+    public function delete( Model $model, $force = false );
59 59
 }
Please login to merge, or discard this patch.
src/Axolotl/Model.php 1 patch
Indentation   +673 added lines, -673 removed lines patch added patch discarded remove patch
@@ -20,677 +20,677 @@
 block discarded – undo
20 20
  * @since      0.1.0
21 21
  */
22 22
 abstract class Model implements Serializes {
23
-	/**
24
-	 * Table attribute key.
25
-	 */
26
-	const TABLE_KEY = '@@table';
27
-
28
-	/**
29
-	 * Object attribute key.
30
-	 */
31
-	const OBJECT_KEY = '@@object';
32
-
33
-	/**
34
-	 * Memoized values for class methods.
35
-	 *
36
-	 * @var array
37
-	 */
38
-	private static $memo = array();
39
-
40
-	/**
41
-	 * Model attributes.
42
-	 *
43
-	 * @var array
44
-	 */
45
-	private $attributes = array(
46
-		self::TABLE_KEY  => array(),
47
-		self::OBJECT_KEY => null,
48
-	);
49
-
50
-	/**
51
-	 * Model's original attributes.
52
-	 *
53
-	 * @var array
54
-	 */
55
-	private $original = array(
56
-		self::TABLE_KEY  => array(),
57
-		self::OBJECT_KEY => null,
58
-	);
59
-
60
-	/**
61
-	 * Properties which are allowed to be set on the model.
62
-	 *
63
-	 * If this array is empty, any attributes can be set on the model.
64
-	 *
65
-	 * @var string[]
66
-	 */
67
-	protected $fillable = array();
68
-
69
-	/**
70
-	 * Properties which cannot be automatically filled on the model.
71
-	 *
72
-	 * If the model is unguarded, these properties can be filled.
73
-	 *
74
-	 * @var array
75
-	 */
76
-	protected $guarded = array();
77
-
78
-	/**
79
-	 * Properties which should not be serialized.
80
-	 *
81
-	 * @var array
82
-	 */
83
-	protected $hidden = array();
84
-
85
-	/**
86
-	 * Properties which should be serialized.
87
-	 *
88
-	 * @var array
89
-	 */
90
-	protected $visible = 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
-	 * Constructs a new model with provided attributes.
103
-	 *
104
-	 * If self::OBJECT_KEY is passed as one of the attributes, the underlying post
105
-	 * will be overwritten.
106
-	 *
107
-	 * @param array <string, mixed> $attributes
108
-	 */
109
-	public function __construct( array $attributes = array() ) {
110
-		$this->maybe_boot();
111
-		$this->sync_original();
112
-
113
-		if ( $this->uses_wp_object() ) {
114
-			$this->create_wp_object();
115
-		}
116
-
117
-		$this->refresh( $attributes );
118
-	}
119
-
120
-	/**
121
-	 * Refreshes the model's current attributes with the provided array.
122
-	 *
123
-	 * The model's attributes will match what was provided in the array,
124
-	 * and any attributes not passed
125
-	 *
126
-	 * @param array $attributes
127
-	 *
128
-	 * @return $this
129
-	 */
130
-	public function refresh( array $attributes ) {
131
-		$this->clear();
132
-
133
-		return $this->merge( $attributes );
134
-	}
135
-
136
-	/**
137
-	 * Merges the provided attributes with the provided array.
138
-	 *
139
-	 * @param array $attributes
140
-	 *
141
-	 * @return $this
142
-	 */
143
-	public function merge( array $attributes ) {
144
-		foreach ( $attributes as $name => $value ) {
145
-			$this->set_attribute( $name, $value );
146
-		}
147
-
148
-		return $this;
149
-	}
150
-
151
-	/**
152
-	 * Get the model's table attributes.
153
-	 *
154
-	 * Returns the array of for the model that will either need to be
155
-	 * saved in postmeta or a separate table.
156
-	 *
157
-	 * @return array
158
-	 */
159
-	public function get_table_attributes() {
160
-		return $this->attributes[ self::TABLE_KEY ];
161
-	}
162
-
163
-	/**
164
-	 * Get the model's original attributes.
165
-	 *
166
-	 * @return array
167
-	 */
168
-	public function get_original_table_attributes() {
169
-		return $this->original[ self::TABLE_KEY ];
170
-	}
171
-
172
-	/**
173
-	 * Retrieve an array of the attributes on the model
174
-	 * that have changed compared to the model's
175
-	 * original data.
176
-	 *
177
-	 * @return array
178
-	 */
179
-	public function get_changed_table_attributes() {
180
-		$changed = array();
181
-
182
-		foreach ( $this->get_table_attributes() as $attribute ) {
183
-			if ( $this->get_attribute( $attribute ) !==
184
-			     $this->get_original_attribute( $attribute )
185
-			) {
186
-				$changed[ $attribute ] = $this->get_attribute( $attribute );
187
-			}
188
-		}
189
-
190
-		return $changed;
191
-	}
192
-
193
-	/**
194
-	 * Get the model's underlying post.
195
-	 *
196
-	 * Returns the underlying WP_Post object for the model, representing
197
-	 * the data that will be save in the wp_posts table.
198
-	 *
199
-	 * @return false|WP_Post|WP_Term
200
-	 */
201
-	public function get_underlying_wp_object() {
202
-		if ( isset( $this->attributes[ self::OBJECT_KEY ] ) ) {
203
-			return $this->attributes[ self::OBJECT_KEY ];
204
-		}
205
-
206
-		return false;
207
-	}
208
-
209
-	/**
210
-	 * Get the model's original underlying post.
211
-	 *
212
-	 * @return WP_Post
213
-	 */
214
-	public function get_original_underlying_wp_object() {
215
-		return $this->original[ self::OBJECT_KEY ];
216
-	}
217
-
218
-	/**
219
-	 * Get the model attributes on the WordPress object
220
-	 * that have changed compared to the model's
221
-	 * original attributes.
222
-	 *
223
-	 * @return array
224
-	 */
225
-	public function get_changed_wp_object_attributes() {
226
-		$changed = array();
227
-
228
-		foreach ( $this->get_wp_object_keys() as $key ) {
229
-			if ( $this->get_attribute( $key ) !==
230
-			     $this->get_original_attribute( $key )
231
-			) {
232
-				$changed[ $key ] = $this->get_attribute( $key );
233
-			}
234
-		}
235
-
236
-		return $changed;
237
-	}
238
-
239
-	/**
240
-	 * Magic __set method.
241
-	 *
242
-	 * Passes the name and value to set_attribute, which is where the magic happens.
243
-	 *
244
-	 * @param string $name
245
-	 * @param mixed  $value
246
-	 */
247
-	public function __set( $name, $value ) {
248
-		$this->set_attribute( $name, $value );
249
-	}
250
-
251
-	/**
252
-	 * Sets the model attributes.
253
-	 *
254
-	 * Checks whether the model attribute can be set, check if it
255
-	 * maps to the WP_Post property, otherwise, assigns it to the
256
-	 * table attribute array.
257
-	 *
258
-	 * @param string $name
259
-	 * @param mixed  $value
260
-	 *
261
-	 * @return $this
262
-	 *
263
-	 * @throws GuardedPropertyException
264
-	 */
265
-	public function set_attribute( $name, $value ) {
266
-		if ( self::OBJECT_KEY === $name ) {
267
-			return $this->override_wp_object( $value );
268
-		}
269
-
270
-		if ( ! $this->is_fillable( $name ) ) {
271
-			throw new GuardedPropertyException;
272
-		}
273
-
274
-		if ( $method = $this->has_map_method( $name ) ) {
275
-			$this->attributes[ self::OBJECT_KEY ]->{$this->{$method}()} = $value;
276
-		} else {
277
-			$this->attributes[ self::TABLE_KEY ][ $name ] = $value;
278
-		}
279
-
280
-		return $this;
281
-	}
282
-
283
-	/**
284
-	 * Retrieves all the attribute keys for the model.
285
-	 *
286
-	 * @return array
287
-	 */
288
-	public function get_attribute_keys() {
289
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
290
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
291
-		}
292
-
293
-		return self::$memo[ get_called_class() ][ __METHOD__ ]
294
-			= array_merge(
295
-				$this->fillable,
296
-				$this->guarded,
297
-				$this->get_compute_methods()
298
-			);
299
-	}
300
-
301
-	/**
302
-	 * Retrieves the attribute keys that aren't mapped to a post.
303
-	 *
304
-	 * @return array
305
-	 */
306
-	public function get_table_keys() {
307
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
308
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
309
-		}
310
-
311
-		$keys = array();
312
-
313
-		foreach ( $this->get_attribute_keys() as $key ) {
314
-			if ( ! $this->has_map_method( $key ) &&
315
-			     ! $this->has_compute_method( $key )
316
-			) {
317
-				$keys[] = $key;
318
-			}
319
-		}
320
-
321
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
322
-	}
323
-
324
-	/**
325
-	 * Retrieves the attribute keys that are mapped to a post.
326
-	 *
327
-	 * @return array
328
-	 */
329
-	public function get_wp_object_keys() {
330
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
331
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
332
-		}
333
-
334
-		$keys = array();
335
-
336
-		foreach ( $this->get_attribute_keys() as $key ) {
337
-			if ( $this->has_map_method( $key ) ) {
338
-				$keys[] = $key;
339
-			}
340
-		}
341
-
342
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
343
-	}
344
-
345
-	/**
346
-	 * Returns the model's keys that are computed at call time.
347
-	 *
348
-	 * @return array
349
-	 */
350
-	public function get_computed_keys() {
351
-		if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
352
-			return self::$memo[ get_called_class() ][ __METHOD__ ];
353
-		}
354
-
355
-		$keys = array();
356
-
357
-		foreach ( $this->get_attribute_keys() as $key ) {
358
-			if ( $this->has_compute_method( $key ) ) {
359
-				$keys[] = $key;
360
-			}
361
-		}
362
-
363
-		return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
364
-	}
365
-
366
-	/**
367
-	 * Serializes the model's public data into an array.
368
-	 *
369
-	 * @return array
370
-	 */
371
-	public function serialize() {
372
-		$attributes = array();
373
-
374
-		if ( $this->visible ) {
375
-			// If visible attributes are set, we'll only reveal those.
376
-			foreach ( $this->visible as $key ) {
377
-				$attributes[ $key ] = $this->get_attribute( $key );
378
-			}
379
-		} elseif ( $this->hidden ) {
380
-			// If hidden attributes are set, we'll grab everything and hide those.
381
-			foreach ( $this->get_attribute_keys() as $key ) {
382
-				if ( ! in_array( $key, $this->hidden ) ) {
383
-					$attributes[ $key ] = $this->get_attribute( $key );
384
-				}
385
-			}
386
-		} else {
387
-			// If nothing is hidden/visible, we'll grab and reveal everything.
388
-			foreach ( $this->get_attribute_keys() as $key ) {
389
-				$attributes[ $key ] = $this->get_attribute( $key );
390
-			}
391
-		}
392
-
393
-		return array_map( function ( $attribute ) {
394
-			if ( $attribute instanceof Serializes ) {
395
-				return $attribute->serialize();
396
-			}
397
-
398
-			return $attribute;
399
-		}, $attributes );
400
-	}
401
-
402
-	/**
403
-	 * Syncs the current attributes to the model's original.
404
-	 *
405
-	 * @return $this
406
-	 */
407
-	public function sync_original() {
408
-		$this->original = $this->attributes;
409
-
410
-		if ( $this->attributes[ self::OBJECT_KEY ] ) {
411
-			$this->original[ self::OBJECT_KEY ] = clone $this->attributes[ self::OBJECT_KEY ];
412
-		}
413
-
414
-		return $this;
415
-	}
416
-
417
-	/**
418
-	 * Checks if a given attribute is mass-fillable.
419
-	 *
420
-	 * Returns true if the attribute can be filled, false if it can't.
421
-	 *
422
-	 * @param string $name
423
-	 *
424
-	 * @return bool
425
-	 */
426
-	private function is_fillable( $name ) {
427
-		// If this model isn't guarded, everything is fillable.
428
-		if ( ! $this->is_guarded ) {
429
-			return true;
430
-		}
431
-
432
-		// If it's in the fillable array, then it's fillable.
433
-		if ( in_array( $name, $this->fillable ) ) {
434
-			return true;
435
-		}
436
-
437
-		// If it's explicitly guarded, then it's not fillable.
438
-		if ( in_array( $name, $this->guarded ) ) {
439
-			return false;
440
-		}
441
-
442
-		// If fillable hasn't been defined, then everything else fillable.
443
-		return ! $this->fillable;
444
-	}
445
-
446
-	/**
447
-	 * Overrides the current WP_Post with a provided one.
448
-	 *
449
-	 * Resets the post's default values and stores it in the attributes.
450
-	 *
451
-	 * @param WP_Post $value
452
-	 *
453
-	 * @return $this
454
-	 */
455
-	private function override_wp_object( $value ) {
456
-		$this->attributes[ self::OBJECT_KEY ] = $this->set_wp_object_constants( $value );
457
-
458
-		return $this;
459
-	}
460
-
461
-	/**
462
-	 * Create and set with a new blank post.
463
-	 *
464
-	 * Creates a new WP_Post object, assigns it the default attributes,
465
-	 * and stores it in the attributes.
466
-	 *
467
-	 * @throws LogicException
468
-	 */
469
-	private function create_wp_object() {
470
-		switch ( true ) {
471
-			case $this instanceof UsesWordPressPost:
472
-				$object = new WP_Post( (object) array() );
473
-				break;
474
-			case $this instanceof UsesWordPressTerm:
475
-				$object = new WP_Term( (object) array() );
476
-				break;
477
-			default:
478
-				throw new LogicException;
479
-				break;
480
-		}
481
-
482
-		$this->attributes[ self::OBJECT_KEY ] = $this->set_wp_object_constants( $object );
483
-	}
484
-
485
-	/**
486
-	 * Enforces values on the post that can't change.
487
-	 *
488
-	 * Primarily, this is used to make sure the post_type always maps
489
-	 * to the model's "$type" property, but this can all be overridden
490
-	 * by the developer to enforce other values in the model.
491
-	 *
492
-	 * @param object $object
493
-	 *
494
-	 * @return object
495
-	 */
496
-	protected function set_wp_object_constants( $object ) {
497
-		if ( $this instanceof UsesWordPressPost ) {
498
-			$object->post_type = $this::get_post_type();
499
-		}
500
-
501
-		if ( $this instanceof UsesWordPressTerm ) {
502
-			$object->taxonomy = $this::get_taxonomy();
503
-		}
504
-
505
-		return $object;
506
-	}
507
-
508
-	/**
509
-	 * Magic __get method.
510
-	 *
511
-	 * Passes the name and value to get_attribute, which is where the magic happens.
512
-	 *
513
-	 * @param string $name
514
-	 *
515
-	 * @return mixed
516
-	 */
517
-	public function __get( $name ) {
518
-		return $this->get_attribute( $name );
519
-	}
520
-
521
-	/**
522
-	 * Retrieves the model attribute.
523
-	 *
524
-	 * @param string $name
525
-	 *
526
-	 * @return mixed
527
-	 *
528
-	 * @throws PropertyDoesNotExistException If property isn't found.
529
-	 */
530
-	public function get_attribute( $name ) {
531
-		if ( $method = $this->has_map_method( $name ) ) {
532
-			$value = $this->attributes[ self::OBJECT_KEY ]->{$this->{$method}()};
533
-		} elseif ( $method = $this->has_compute_method( $name ) ) {
534
-			$value = $this->{$method}();
535
-		} else {
536
-			if ( ! isset( $this->attributes[ self::TABLE_KEY ][ $name ] ) ) {
537
-				throw new PropertyDoesNotExistException;
538
-			}
539
-
540
-			$value = $this->attributes[ self::TABLE_KEY ][ $name ];
541
-		}
542
-
543
-		return $value;
544
-	}
545
-
546
-	/**
547
-	 * Retrieve the model's original attribute value.
548
-	 *
549
-	 * @param string $name
550
-	 *
551
-	 * @return mixed
552
-	 *
553
-	 * @throws PropertyDoesNotExistException If property isn't found.
554
-	 */
555
-	public function get_original_attribute( $name ) {
556
-		$original = new static( $this->original );
557
-
558
-		return $original->get_attribute( $name );
559
-	}
560
-
561
-	/**
562
-	 * Fetches the Model's primary ID, depending on the model
563
-	 * implementation.
564
-	 *
565
-	 * @return int
566
-	 *
567
-	 * @throws LogicException
568
-	 */
569
-	public function get_primary_id() {
570
-		if ( $this instanceof UsesWordPressPost ) {
571
-			return $this->get_underlying_wp_object()->ID;
572
-		}
573
-
574
-		if ( $this instanceof UsesWordPressTerm ) {
575
-			return $this->get_underlying_wp_object()->term_id;
576
-		}
577
-
578
-		// Model w/o wp_object not yet supported.
579
-		throw new LogicException;
580
-	}
581
-
582
-	/**
583
-	 * Checks whether the attribute has a map method.
584
-	 *
585
-	 * This is used to determine whether the attribute maps to a
586
-	 * property on the underlying WP_Post object. Returns the
587
-	 * method if one exists, returns false if it doesn't.
588
-	 *
589
-	 * @param string $name
590
-	 *
591
-	 * @return false|string
592
-	 */
593
-	protected function has_map_method( $name ) {
594
-		if ( method_exists( $this, $method = "map_{$name}" ) ) {
595
-			return $method;
596
-		}
597
-
598
-		return false;
599
-	}
600
-
601
-	/**
602
-	 * Checks whether the attribute has a compute method.
603
-	 *
604
-	 * This is used to determine if the attribute should be computed
605
-	 * from other attributes.
606
-	 *
607
-	 * @param string $name
608
-	 *
609
-	 * @return false|string
610
-	 */
611
-	protected function has_compute_method( $name ) {
612
-		if ( method_exists( $this, $method = "compute_{$name}" ) ) {
613
-			return $method;
614
-		}
615
-
616
-		return false;
617
-	}
618
-
619
-	/**
620
-	 * Clears all the current attributes from the model.
621
-	 *
622
-	 * This does not touch the model's original attributes, and will
623
-	 * only clear fillable attributes, unless the model is unguarded.
624
-	 *
625
-	 * @return $this
626
-	 */
627
-	public function clear() {
628
-		$keys = $this->get_attribute_keys();
629
-
630
-		foreach ( $keys as $key ) {
631
-			try {
632
-				$this->set_attribute( $key, null );
633
-			} catch ( GuardedPropertyException $e ) {
634
-				// We won't clear out guarded attributes.
635
-			}
636
-		}
637
-
638
-		return $this;
639
-	}
640
-
641
-	/**
642
-	 * Unguards the model.
643
-	 *
644
-	 * Sets the model to be unguarded, allowing the filling of
645
-	 * guarded attributes.
646
-	 */
647
-	public function unguard() {
648
-		$this->is_guarded = false;
649
-	}
650
-
651
-	/**
652
-	 * Reguards the model.
653
-	 *
654
-	 * Sets the model to be guarded, preventing filling of
655
-	 * guarded attributes.
656
-	 */
657
-	public function reguard() {
658
-		$this->is_guarded = true;
659
-	}
660
-
661
-	/**
662
-	 * Retrieves all the compute methods on the model.
663
-	 *
664
-	 * @return array
665
-	 */
666
-	protected function get_compute_methods() {
667
-		$methods = get_class_methods( get_called_class() );
668
-		$methods = array_filter( $methods, function ( $method ) {
669
-			return strrpos( $method, 'compute_', - strlen( $method ) ) !== false;
670
-		} );
671
-		$methods = array_map( function ( $method ) {
672
-			return substr( $method, strlen( 'compute_' ) );
673
-		}, $methods );
674
-
675
-		return $methods;
676
-	}
677
-
678
-	/**
679
-	 * Sets up the memo array for the creating model.
680
-	 */
681
-	private function maybe_boot() {
682
-		if ( ! isset( self::$memo[ get_called_class() ] ) ) {
683
-			self::$memo[ get_called_class() ] = array();
684
-		}
685
-	}
686
-
687
-	/**
688
-	 * Whether this Model uses an underlying WordPress object.
689
-	 *
690
-	 * @return bool
691
-	 */
692
-	protected function uses_wp_object() {
693
-		return $this instanceof UsesWordPressPost ||
694
-			$this instanceof UsesWordPressTerm;
695
-	}
23
+    /**
24
+     * Table attribute key.
25
+     */
26
+    const TABLE_KEY = '@@table';
27
+
28
+    /**
29
+     * Object attribute key.
30
+     */
31
+    const OBJECT_KEY = '@@object';
32
+
33
+    /**
34
+     * Memoized values for class methods.
35
+     *
36
+     * @var array
37
+     */
38
+    private static $memo = array();
39
+
40
+    /**
41
+     * Model attributes.
42
+     *
43
+     * @var array
44
+     */
45
+    private $attributes = array(
46
+        self::TABLE_KEY  => array(),
47
+        self::OBJECT_KEY => null,
48
+    );
49
+
50
+    /**
51
+     * Model's original attributes.
52
+     *
53
+     * @var array
54
+     */
55
+    private $original = array(
56
+        self::TABLE_KEY  => array(),
57
+        self::OBJECT_KEY => null,
58
+    );
59
+
60
+    /**
61
+     * Properties which are allowed to be set on the model.
62
+     *
63
+     * If this array is empty, any attributes can be set on the model.
64
+     *
65
+     * @var string[]
66
+     */
67
+    protected $fillable = array();
68
+
69
+    /**
70
+     * Properties which cannot be automatically filled on the model.
71
+     *
72
+     * If the model is unguarded, these properties can be filled.
73
+     *
74
+     * @var array
75
+     */
76
+    protected $guarded = array();
77
+
78
+    /**
79
+     * Properties which should not be serialized.
80
+     *
81
+     * @var array
82
+     */
83
+    protected $hidden = array();
84
+
85
+    /**
86
+     * Properties which should be serialized.
87
+     *
88
+     * @var array
89
+     */
90
+    protected $visible = 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
+     * Constructs a new model with provided attributes.
103
+     *
104
+     * If self::OBJECT_KEY is passed as one of the attributes, the underlying post
105
+     * will be overwritten.
106
+     *
107
+     * @param array <string, mixed> $attributes
108
+     */
109
+    public function __construct( array $attributes = array() ) {
110
+        $this->maybe_boot();
111
+        $this->sync_original();
112
+
113
+        if ( $this->uses_wp_object() ) {
114
+            $this->create_wp_object();
115
+        }
116
+
117
+        $this->refresh( $attributes );
118
+    }
119
+
120
+    /**
121
+     * Refreshes the model's current attributes with the provided array.
122
+     *
123
+     * The model's attributes will match what was provided in the array,
124
+     * and any attributes not passed
125
+     *
126
+     * @param array $attributes
127
+     *
128
+     * @return $this
129
+     */
130
+    public function refresh( array $attributes ) {
131
+        $this->clear();
132
+
133
+        return $this->merge( $attributes );
134
+    }
135
+
136
+    /**
137
+     * Merges the provided attributes with the provided array.
138
+     *
139
+     * @param array $attributes
140
+     *
141
+     * @return $this
142
+     */
143
+    public function merge( array $attributes ) {
144
+        foreach ( $attributes as $name => $value ) {
145
+            $this->set_attribute( $name, $value );
146
+        }
147
+
148
+        return $this;
149
+    }
150
+
151
+    /**
152
+     * Get the model's table attributes.
153
+     *
154
+     * Returns the array of for the model that will either need to be
155
+     * saved in postmeta or a separate table.
156
+     *
157
+     * @return array
158
+     */
159
+    public function get_table_attributes() {
160
+        return $this->attributes[ self::TABLE_KEY ];
161
+    }
162
+
163
+    /**
164
+     * Get the model's original attributes.
165
+     *
166
+     * @return array
167
+     */
168
+    public function get_original_table_attributes() {
169
+        return $this->original[ self::TABLE_KEY ];
170
+    }
171
+
172
+    /**
173
+     * Retrieve an array of the attributes on the model
174
+     * that have changed compared to the model's
175
+     * original data.
176
+     *
177
+     * @return array
178
+     */
179
+    public function get_changed_table_attributes() {
180
+        $changed = array();
181
+
182
+        foreach ( $this->get_table_attributes() as $attribute ) {
183
+            if ( $this->get_attribute( $attribute ) !==
184
+                    $this->get_original_attribute( $attribute )
185
+            ) {
186
+                $changed[ $attribute ] = $this->get_attribute( $attribute );
187
+            }
188
+        }
189
+
190
+        return $changed;
191
+    }
192
+
193
+    /**
194
+     * Get the model's underlying post.
195
+     *
196
+     * Returns the underlying WP_Post object for the model, representing
197
+     * the data that will be save in the wp_posts table.
198
+     *
199
+     * @return false|WP_Post|WP_Term
200
+     */
201
+    public function get_underlying_wp_object() {
202
+        if ( isset( $this->attributes[ self::OBJECT_KEY ] ) ) {
203
+            return $this->attributes[ self::OBJECT_KEY ];
204
+        }
205
+
206
+        return false;
207
+    }
208
+
209
+    /**
210
+     * Get the model's original underlying post.
211
+     *
212
+     * @return WP_Post
213
+     */
214
+    public function get_original_underlying_wp_object() {
215
+        return $this->original[ self::OBJECT_KEY ];
216
+    }
217
+
218
+    /**
219
+     * Get the model attributes on the WordPress object
220
+     * that have changed compared to the model's
221
+     * original attributes.
222
+     *
223
+     * @return array
224
+     */
225
+    public function get_changed_wp_object_attributes() {
226
+        $changed = array();
227
+
228
+        foreach ( $this->get_wp_object_keys() as $key ) {
229
+            if ( $this->get_attribute( $key ) !==
230
+                    $this->get_original_attribute( $key )
231
+            ) {
232
+                $changed[ $key ] = $this->get_attribute( $key );
233
+            }
234
+        }
235
+
236
+        return $changed;
237
+    }
238
+
239
+    /**
240
+     * Magic __set method.
241
+     *
242
+     * Passes the name and value to set_attribute, which is where the magic happens.
243
+     *
244
+     * @param string $name
245
+     * @param mixed  $value
246
+     */
247
+    public function __set( $name, $value ) {
248
+        $this->set_attribute( $name, $value );
249
+    }
250
+
251
+    /**
252
+     * Sets the model attributes.
253
+     *
254
+     * Checks whether the model attribute can be set, check if it
255
+     * maps to the WP_Post property, otherwise, assigns it to the
256
+     * table attribute array.
257
+     *
258
+     * @param string $name
259
+     * @param mixed  $value
260
+     *
261
+     * @return $this
262
+     *
263
+     * @throws GuardedPropertyException
264
+     */
265
+    public function set_attribute( $name, $value ) {
266
+        if ( self::OBJECT_KEY === $name ) {
267
+            return $this->override_wp_object( $value );
268
+        }
269
+
270
+        if ( ! $this->is_fillable( $name ) ) {
271
+            throw new GuardedPropertyException;
272
+        }
273
+
274
+        if ( $method = $this->has_map_method( $name ) ) {
275
+            $this->attributes[ self::OBJECT_KEY ]->{$this->{$method}()} = $value;
276
+        } else {
277
+            $this->attributes[ self::TABLE_KEY ][ $name ] = $value;
278
+        }
279
+
280
+        return $this;
281
+    }
282
+
283
+    /**
284
+     * Retrieves all the attribute keys for the model.
285
+     *
286
+     * @return array
287
+     */
288
+    public function get_attribute_keys() {
289
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
290
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
291
+        }
292
+
293
+        return self::$memo[ get_called_class() ][ __METHOD__ ]
294
+            = array_merge(
295
+                $this->fillable,
296
+                $this->guarded,
297
+                $this->get_compute_methods()
298
+            );
299
+    }
300
+
301
+    /**
302
+     * Retrieves the attribute keys that aren't mapped to a post.
303
+     *
304
+     * @return array
305
+     */
306
+    public function get_table_keys() {
307
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
308
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
309
+        }
310
+
311
+        $keys = array();
312
+
313
+        foreach ( $this->get_attribute_keys() as $key ) {
314
+            if ( ! $this->has_map_method( $key ) &&
315
+                 ! $this->has_compute_method( $key )
316
+            ) {
317
+                $keys[] = $key;
318
+            }
319
+        }
320
+
321
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
322
+    }
323
+
324
+    /**
325
+     * Retrieves the attribute keys that are mapped to a post.
326
+     *
327
+     * @return array
328
+     */
329
+    public function get_wp_object_keys() {
330
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
331
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
332
+        }
333
+
334
+        $keys = array();
335
+
336
+        foreach ( $this->get_attribute_keys() as $key ) {
337
+            if ( $this->has_map_method( $key ) ) {
338
+                $keys[] = $key;
339
+            }
340
+        }
341
+
342
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
343
+    }
344
+
345
+    /**
346
+     * Returns the model's keys that are computed at call time.
347
+     *
348
+     * @return array
349
+     */
350
+    public function get_computed_keys() {
351
+        if ( isset( self::$memo[ get_called_class() ][ __METHOD__ ] ) ) {
352
+            return self::$memo[ get_called_class() ][ __METHOD__ ];
353
+        }
354
+
355
+        $keys = array();
356
+
357
+        foreach ( $this->get_attribute_keys() as $key ) {
358
+            if ( $this->has_compute_method( $key ) ) {
359
+                $keys[] = $key;
360
+            }
361
+        }
362
+
363
+        return self::$memo[ get_called_class() ][ __METHOD__ ] = $keys;
364
+    }
365
+
366
+    /**
367
+     * Serializes the model's public data into an array.
368
+     *
369
+     * @return array
370
+     */
371
+    public function serialize() {
372
+        $attributes = array();
373
+
374
+        if ( $this->visible ) {
375
+            // If visible attributes are set, we'll only reveal those.
376
+            foreach ( $this->visible as $key ) {
377
+                $attributes[ $key ] = $this->get_attribute( $key );
378
+            }
379
+        } elseif ( $this->hidden ) {
380
+            // If hidden attributes are set, we'll grab everything and hide those.
381
+            foreach ( $this->get_attribute_keys() as $key ) {
382
+                if ( ! in_array( $key, $this->hidden ) ) {
383
+                    $attributes[ $key ] = $this->get_attribute( $key );
384
+                }
385
+            }
386
+        } else {
387
+            // If nothing is hidden/visible, we'll grab and reveal everything.
388
+            foreach ( $this->get_attribute_keys() as $key ) {
389
+                $attributes[ $key ] = $this->get_attribute( $key );
390
+            }
391
+        }
392
+
393
+        return array_map( function ( $attribute ) {
394
+            if ( $attribute instanceof Serializes ) {
395
+                return $attribute->serialize();
396
+            }
397
+
398
+            return $attribute;
399
+        }, $attributes );
400
+    }
401
+
402
+    /**
403
+     * Syncs the current attributes to the model's original.
404
+     *
405
+     * @return $this
406
+     */
407
+    public function sync_original() {
408
+        $this->original = $this->attributes;
409
+
410
+        if ( $this->attributes[ self::OBJECT_KEY ] ) {
411
+            $this->original[ self::OBJECT_KEY ] = clone $this->attributes[ self::OBJECT_KEY ];
412
+        }
413
+
414
+        return $this;
415
+    }
416
+
417
+    /**
418
+     * Checks if a given attribute is mass-fillable.
419
+     *
420
+     * Returns true if the attribute can be filled, false if it can't.
421
+     *
422
+     * @param string $name
423
+     *
424
+     * @return bool
425
+     */
426
+    private function is_fillable( $name ) {
427
+        // If this model isn't guarded, everything is fillable.
428
+        if ( ! $this->is_guarded ) {
429
+            return true;
430
+        }
431
+
432
+        // If it's in the fillable array, then it's fillable.
433
+        if ( in_array( $name, $this->fillable ) ) {
434
+            return true;
435
+        }
436
+
437
+        // If it's explicitly guarded, then it's not fillable.
438
+        if ( in_array( $name, $this->guarded ) ) {
439
+            return false;
440
+        }
441
+
442
+        // If fillable hasn't been defined, then everything else fillable.
443
+        return ! $this->fillable;
444
+    }
445
+
446
+    /**
447
+     * Overrides the current WP_Post with a provided one.
448
+     *
449
+     * Resets the post's default values and stores it in the attributes.
450
+     *
451
+     * @param WP_Post $value
452
+     *
453
+     * @return $this
454
+     */
455
+    private function override_wp_object( $value ) {
456
+        $this->attributes[ self::OBJECT_KEY ] = $this->set_wp_object_constants( $value );
457
+
458
+        return $this;
459
+    }
460
+
461
+    /**
462
+     * Create and set with a new blank post.
463
+     *
464
+     * Creates a new WP_Post object, assigns it the default attributes,
465
+     * and stores it in the attributes.
466
+     *
467
+     * @throws LogicException
468
+     */
469
+    private function create_wp_object() {
470
+        switch ( true ) {
471
+            case $this instanceof UsesWordPressPost:
472
+                $object = new WP_Post( (object) array() );
473
+                break;
474
+            case $this instanceof UsesWordPressTerm:
475
+                $object = new WP_Term( (object) array() );
476
+                break;
477
+            default:
478
+                throw new LogicException;
479
+                break;
480
+        }
481
+
482
+        $this->attributes[ self::OBJECT_KEY ] = $this->set_wp_object_constants( $object );
483
+    }
484
+
485
+    /**
486
+     * Enforces values on the post that can't change.
487
+     *
488
+     * Primarily, this is used to make sure the post_type always maps
489
+     * to the model's "$type" property, but this can all be overridden
490
+     * by the developer to enforce other values in the model.
491
+     *
492
+     * @param object $object
493
+     *
494
+     * @return object
495
+     */
496
+    protected function set_wp_object_constants( $object ) {
497
+        if ( $this instanceof UsesWordPressPost ) {
498
+            $object->post_type = $this::get_post_type();
499
+        }
500
+
501
+        if ( $this instanceof UsesWordPressTerm ) {
502
+            $object->taxonomy = $this::get_taxonomy();
503
+        }
504
+
505
+        return $object;
506
+    }
507
+
508
+    /**
509
+     * Magic __get method.
510
+     *
511
+     * Passes the name and value to get_attribute, which is where the magic happens.
512
+     *
513
+     * @param string $name
514
+     *
515
+     * @return mixed
516
+     */
517
+    public function __get( $name ) {
518
+        return $this->get_attribute( $name );
519
+    }
520
+
521
+    /**
522
+     * Retrieves the model attribute.
523
+     *
524
+     * @param string $name
525
+     *
526
+     * @return mixed
527
+     *
528
+     * @throws PropertyDoesNotExistException If property isn't found.
529
+     */
530
+    public function get_attribute( $name ) {
531
+        if ( $method = $this->has_map_method( $name ) ) {
532
+            $value = $this->attributes[ self::OBJECT_KEY ]->{$this->{$method}()};
533
+        } elseif ( $method = $this->has_compute_method( $name ) ) {
534
+            $value = $this->{$method}();
535
+        } else {
536
+            if ( ! isset( $this->attributes[ self::TABLE_KEY ][ $name ] ) ) {
537
+                throw new PropertyDoesNotExistException;
538
+            }
539
+
540
+            $value = $this->attributes[ self::TABLE_KEY ][ $name ];
541
+        }
542
+
543
+        return $value;
544
+    }
545
+
546
+    /**
547
+     * Retrieve the model's original attribute value.
548
+     *
549
+     * @param string $name
550
+     *
551
+     * @return mixed
552
+     *
553
+     * @throws PropertyDoesNotExistException If property isn't found.
554
+     */
555
+    public function get_original_attribute( $name ) {
556
+        $original = new static( $this->original );
557
+
558
+        return $original->get_attribute( $name );
559
+    }
560
+
561
+    /**
562
+     * Fetches the Model's primary ID, depending on the model
563
+     * implementation.
564
+     *
565
+     * @return int
566
+     *
567
+     * @throws LogicException
568
+     */
569
+    public function get_primary_id() {
570
+        if ( $this instanceof UsesWordPressPost ) {
571
+            return $this->get_underlying_wp_object()->ID;
572
+        }
573
+
574
+        if ( $this instanceof UsesWordPressTerm ) {
575
+            return $this->get_underlying_wp_object()->term_id;
576
+        }
577
+
578
+        // Model w/o wp_object not yet supported.
579
+        throw new LogicException;
580
+    }
581
+
582
+    /**
583
+     * Checks whether the attribute has a map method.
584
+     *
585
+     * This is used to determine whether the attribute maps to a
586
+     * property on the underlying WP_Post object. Returns the
587
+     * method if one exists, returns false if it doesn't.
588
+     *
589
+     * @param string $name
590
+     *
591
+     * @return false|string
592
+     */
593
+    protected function has_map_method( $name ) {
594
+        if ( method_exists( $this, $method = "map_{$name}" ) ) {
595
+            return $method;
596
+        }
597
+
598
+        return false;
599
+    }
600
+
601
+    /**
602
+     * Checks whether the attribute has a compute method.
603
+     *
604
+     * This is used to determine if the attribute should be computed
605
+     * from other attributes.
606
+     *
607
+     * @param string $name
608
+     *
609
+     * @return false|string
610
+     */
611
+    protected function has_compute_method( $name ) {
612
+        if ( method_exists( $this, $method = "compute_{$name}" ) ) {
613
+            return $method;
614
+        }
615
+
616
+        return false;
617
+    }
618
+
619
+    /**
620
+     * Clears all the current attributes from the model.
621
+     *
622
+     * This does not touch the model's original attributes, and will
623
+     * only clear fillable attributes, unless the model is unguarded.
624
+     *
625
+     * @return $this
626
+     */
627
+    public function clear() {
628
+        $keys = $this->get_attribute_keys();
629
+
630
+        foreach ( $keys as $key ) {
631
+            try {
632
+                $this->set_attribute( $key, null );
633
+            } catch ( GuardedPropertyException $e ) {
634
+                // We won't clear out guarded attributes.
635
+            }
636
+        }
637
+
638
+        return $this;
639
+    }
640
+
641
+    /**
642
+     * Unguards the model.
643
+     *
644
+     * Sets the model to be unguarded, allowing the filling of
645
+     * guarded attributes.
646
+     */
647
+    public function unguard() {
648
+        $this->is_guarded = false;
649
+    }
650
+
651
+    /**
652
+     * Reguards the model.
653
+     *
654
+     * Sets the model to be guarded, preventing filling of
655
+     * guarded attributes.
656
+     */
657
+    public function reguard() {
658
+        $this->is_guarded = true;
659
+    }
660
+
661
+    /**
662
+     * Retrieves all the compute methods on the model.
663
+     *
664
+     * @return array
665
+     */
666
+    protected function get_compute_methods() {
667
+        $methods = get_class_methods( get_called_class() );
668
+        $methods = array_filter( $methods, function ( $method ) {
669
+            return strrpos( $method, 'compute_', - strlen( $method ) ) !== false;
670
+        } );
671
+        $methods = array_map( function ( $method ) {
672
+            return substr( $method, strlen( 'compute_' ) );
673
+        }, $methods );
674
+
675
+        return $methods;
676
+    }
677
+
678
+    /**
679
+     * Sets up the memo array for the creating model.
680
+     */
681
+    private function maybe_boot() {
682
+        if ( ! isset( self::$memo[ get_called_class() ] ) ) {
683
+            self::$memo[ get_called_class() ] = array();
684
+        }
685
+    }
686
+
687
+    /**
688
+     * Whether this Model uses an underlying WordPress object.
689
+     *
690
+     * @return bool
691
+     */
692
+    protected function uses_wp_object() {
693
+        return $this instanceof UsesWordPressPost ||
694
+            $this instanceof UsesWordPressTerm;
695
+    }
696 696
 }
Please login to merge, or discard this patch.
src/Axolotl/Collection.php 1 patch
Indentation   +148 added lines, -148 removed lines patch added patch discarded remove patch
@@ -14,152 +14,152 @@
 block discarded – undo
14 14
  * @subpackage Axolotl
15 15
  */
16 16
 class Collection implements Countable, Iterator, Serializes {
17
-	/**
18
-	 * Collection elements.
19
-	 *
20
-	 * @var array
21
-	 */
22
-	protected $elements = array();
23
-
24
-	/**
25
-	 * Models registered to the collection.
26
-	 *
27
-	 * @var string
28
-	 */
29
-	protected $model;
30
-
31
-	/**
32
-	 * Where Collection is in loop.
33
-	 *
34
-	 * @var int
35
-	 */
36
-	protected $position = 0;
37
-
38
-	/**
39
-	 * Collection constructor.
40
-	 *
41
-	 * @param array $elements
42
-	 * @param array $config
43
-	 */
44
-	public function __construct( array $elements = array(), array $config = array() ) {
45
-		$this->parse_config( $config );
46
-
47
-		foreach ( $elements as $element ) {
48
-			$this->add( $element );
49
-		}
50
-	}
51
-
52
-	/**
53
-	 * Adds a new element to the Collection.
54
-	 *
55
-	 * @param mixed $element
56
-	 *
57
-	 * @throws RuntimeException
58
-	 */
59
-	public function add( $element ) {
60
-		if ( $this->model && is_array( $element ) ) {
61
-			$element = new $this->model( $element );
62
-		}
63
-
64
-		if ( $this->model && ! ( $element instanceof $this->model ) ) {
65
-			throw new RuntimeException;
66
-		}
67
-
68
-		$this->elements[] = $element;
69
-	}
70
-
71
-	/**
72
-	 * Fetches the element at the provided index.
73
-	 *
74
-	 * @param int $index
75
-	 *
76
-	 * @return mixed
77
-	 */
78
-	public function at( $index ) {
79
-		return isset( $this->elements[ $index ] ) ? $this->elements[ $index ] : null;
80
-	}
81
-
82
-	/**
83
-	 * Return the current element.
84
-	 *
85
-	 * @return mixed
86
-	 */
87
-	public function current() {
88
-		return $this->at( $this->position );
89
-	}
90
-
91
-	/**
92
-	 * Move forward to next element.
93
-	 */
94
-	public function next() {
95
-		$this->position ++;
96
-	}
97
-
98
-	/**
99
-	 * Return the key of the current element.
100
-	 *
101
-	 * @return mixed
102
-	 */
103
-	public function key() {
104
-		return $this->position;
105
-	}
106
-
107
-	/**
108
-	 * Checks if current position is valid.
109
-	 *
110
-	 * @return bool
111
-	 */
112
-	public function valid() {
113
-		return isset( $this->elements[ $this->position ] );
114
-	}
115
-
116
-	/**
117
-	 * Rewind the Iterator to the first element.
118
-	 */
119
-	public function rewind() {
120
-		$this->position = 0;
121
-	}
122
-
123
-	/**
124
-	 * Count elements of an object.
125
-	 *
126
-	 * @return int
127
-	 */
128
-	public function count() {
129
-		return count( $this->elements );
130
-	}
131
-
132
-	/**
133
-	 * Parses the Collection config to set its properties.
134
-	 *
135
-	 * @param array $config
136
-	 *
137
-	 * @throws LogicException
138
-	 */
139
-	protected function parse_config( array $config ) {
140
-		if ( isset( $config['model'] ) ) {
141
-			$model = $config['model'];
142
-
143
-			if ( ! is_subclass_of( $model, 'Intraxia\Jaxion\Axolotl\Model' ) ) {
144
-				throw new LogicException;
145
-			}
146
-
147
-			$this->model = $model;
148
-		}
149
-	}
150
-
151
-	/**
152
-	 * {@inheritDoc}
153
-	 *
154
-	 * @return array
155
-	 */
156
-	public function serialize() {
157
-		return array_map(function( $element ) {
158
-			if ( $element instanceof Serializes ) {
159
-				return $element->serialize();
160
-			}
161
-
162
-			return $element;
163
-		}, $this->elements);
164
-	}
17
+    /**
18
+     * Collection elements.
19
+     *
20
+     * @var array
21
+     */
22
+    protected $elements = array();
23
+
24
+    /**
25
+     * Models registered to the collection.
26
+     *
27
+     * @var string
28
+     */
29
+    protected $model;
30
+
31
+    /**
32
+     * Where Collection is in loop.
33
+     *
34
+     * @var int
35
+     */
36
+    protected $position = 0;
37
+
38
+    /**
39
+     * Collection constructor.
40
+     *
41
+     * @param array $elements
42
+     * @param array $config
43
+     */
44
+    public function __construct( array $elements = array(), array $config = array() ) {
45
+        $this->parse_config( $config );
46
+
47
+        foreach ( $elements as $element ) {
48
+            $this->add( $element );
49
+        }
50
+    }
51
+
52
+    /**
53
+     * Adds a new element to the Collection.
54
+     *
55
+     * @param mixed $element
56
+     *
57
+     * @throws RuntimeException
58
+     */
59
+    public function add( $element ) {
60
+        if ( $this->model && is_array( $element ) ) {
61
+            $element = new $this->model( $element );
62
+        }
63
+
64
+        if ( $this->model && ! ( $element instanceof $this->model ) ) {
65
+            throw new RuntimeException;
66
+        }
67
+
68
+        $this->elements[] = $element;
69
+    }
70
+
71
+    /**
72
+     * Fetches the element at the provided index.
73
+     *
74
+     * @param int $index
75
+     *
76
+     * @return mixed
77
+     */
78
+    public function at( $index ) {
79
+        return isset( $this->elements[ $index ] ) ? $this->elements[ $index ] : null;
80
+    }
81
+
82
+    /**
83
+     * Return the current element.
84
+     *
85
+     * @return mixed
86
+     */
87
+    public function current() {
88
+        return $this->at( $this->position );
89
+    }
90
+
91
+    /**
92
+     * Move forward to next element.
93
+     */
94
+    public function next() {
95
+        $this->position ++;
96
+    }
97
+
98
+    /**
99
+     * Return the key of the current element.
100
+     *
101
+     * @return mixed
102
+     */
103
+    public function key() {
104
+        return $this->position;
105
+    }
106
+
107
+    /**
108
+     * Checks if current position is valid.
109
+     *
110
+     * @return bool
111
+     */
112
+    public function valid() {
113
+        return isset( $this->elements[ $this->position ] );
114
+    }
115
+
116
+    /**
117
+     * Rewind the Iterator to the first element.
118
+     */
119
+    public function rewind() {
120
+        $this->position = 0;
121
+    }
122
+
123
+    /**
124
+     * Count elements of an object.
125
+     *
126
+     * @return int
127
+     */
128
+    public function count() {
129
+        return count( $this->elements );
130
+    }
131
+
132
+    /**
133
+     * Parses the Collection config to set its properties.
134
+     *
135
+     * @param array $config
136
+     *
137
+     * @throws LogicException
138
+     */
139
+    protected function parse_config( array $config ) {
140
+        if ( isset( $config['model'] ) ) {
141
+            $model = $config['model'];
142
+
143
+            if ( ! is_subclass_of( $model, 'Intraxia\Jaxion\Axolotl\Model' ) ) {
144
+                throw new LogicException;
145
+            }
146
+
147
+            $this->model = $model;
148
+        }
149
+    }
150
+
151
+    /**
152
+     * {@inheritDoc}
153
+     *
154
+     * @return array
155
+     */
156
+    public function serialize() {
157
+        return array_map(function( $element ) {
158
+            if ( $element instanceof Serializes ) {
159
+                return $element->serialize();
160
+            }
161
+
162
+            return $element;
163
+        }, $this->elements);
164
+    }
165 165
 }
Please login to merge, or discard this patch.