Closed jjgrainger closed 6 years ago
I've been looking to do the same for some of my own WP themes but when I sit down to refactor for dependency injection my eyes start glazing over at the task ahead. I'm where you are in terms of seeing where you want to be and how to get there, minus the optimism.
I'm borrowing your custom post class for a minute to rule out bugs in my own class but I like your tidy approach to adding admin edit columns. I look forward to seeing how it develops.
As an aside, you might consider using "require-dev"
for unit test and similar tooling to reduce bloat in production use.
Following on from issue #11 the Taxonomy
class could become a standalone thing, available to developers to register taxonomies.
Taxonomies could be created as objects then be passed to the post type to register it, or could still use the taxonomy slug.
// register a post type
$books = new PostType('book');
// register a taxonomy
$genre = new Taxonomy('genre');
// register the taxonomy to the books post type
// using the taxonomy object
$books->taxonomy($genre);
// or with the taxonomy slug
$books->taxonomy('genre');
// register the post type
$books->register();
Using the taxonomy class to create objects can then open up additional methods for manipulating the taxonomy.
$genre = new Taxonomy('genre');
// modify the taxonomy admin columns
$genre->columns()->add([
'populatrity_score' => __('Popularity')
]);
Then there is how the taxonomy is registered, can it register itself to a post type, or does that have to be done through a PostType
object? Or both?
// register taxonomy to post type
$genre->postType('post');
// alternativly, if a books PostType object is available
$books->taxonomy('genre');
Then there is whether we need to provide it with a register()
method too.
$genre->register();
Will explore this further...
I like how tidy all this looks. I'm going to give it a whirl in my dev theme and see what issues arise.
Now the Taxonomy
class is an independent thing from PostType
the last dependency to fix is the Columns
. Something I've discovered recently is that you can type hint a parameter but also default it to null.
In light of this, I'm thinking the columns()
method in the PostType
(and soon to be in Taxonomy
) can accept a ColumnManager
dependency. This can default to null
, which then will instantiate the default Column
class and assign it.
The method will look something like:
class PostType
{
//... additional methods and properties
public var $columns;
public function columns(ColumnManager $columns = null)
{
// if the column manager is already set, return it
if (isset($this->columns)) {
return $this->columns;
}
// if no custom ColumnManager is passed
if (is_null($columns)) {
// instatiate one using PostTypes default
$this->columns = new PostTypes\ColumnManager;
} else {
// otherwise assign the custom ColumnManager
$this->columns = $columns;
}
return $this->columns;
}
}
This way when creating PostTypes
and Taxonomy
classes:
// create post type
$books = new PostType('book');
// default to PostType\ColumnManager
$books->columns()->add([...]);
// using a custom ColumnManager
$books->columns(new MyCustomColumnManager)->add([...]);
// register the post type to WordPress
$books->register();
I've been wanting to add unit tests for a while but wasn't sure how. After some research, I've stumbled across a few interesting articles and tools that have shed some light on how to do this.
It has become clear that there are a couple of issues with how the class has been made so far.
Calling hooks in the class constructor
Though hooks aren't specifically called in the
__construct()
method, there is aninitialize()
method that is. This method adds all of the hooks the class registers to register post types, taxonomies and columns. Havinginitialize()
called in the constructor makes it difficult to test PostTypes in isolation of WordPress.To fix this, I'm looking at renaming the
initialize()
method toregister()
. This will allow PostTypes to be tested in isolation of WordPress, as the method that hooks into WordPress has to be called explicitly. However, Doing this will mean the developer has to callregister()
themselves in order to register their post type.Concrete dependencies and dependency injection
PostTypes has 3 Classes,
PostType
,Columns
andTaxonomy
.PostType
is the main class that handles everything from registering post types, taxonomies and modifying the admin columns.Both
Columns
andTaxonomy
are helper classes. They only really store information in a structured way to be used byPostType
later. These classes are explicitly created in the__construct
method.Though this won't necessarily cause issues, it's still not good practice. So may need to look into alternatives to instantiating these additional classes.
Use of globals
There are some WordPress globals used inside some methods. Most seem unnecessary so should be simple enough to remove.
Positives
Despite the issues raised, I feel quite positive. The research has helped to clarify some principles for the class and how to approach unit testing it.
register()
method should be explicitly called to hook into WordPressI'll will most likely edit/comment on this issue as I work on it