-
Notifications
You must be signed in to change notification settings - Fork 5
Pass WP_Query to Content Getter Implementations. #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
An implementation might need more information that's available in the query. Therefore, instead of passing a query to go get, let's pass the query and let each implementation initialize itself. This enhancement makes the new implementation design even more reusable.
1. Fixed the RestRequestTest. 2. Modified the testGetPostsArePostsShouldFilter() test to focus it on testing when a query is supplied. 3. Added e2e test for FilterWPQuery by running a REST request.
1. Load Patchwork early, before everything else. 2. Don't load the plugin's bootstrap file as part of the unit test startup process. 3. Moved the internationalization mocking to the Test Case. Leveraged the stubs in Brain Monkey to handle it for us.
@Shelob9 After I created this PR, it dawned on me focus this PR on just passing the query around. The plugin does load now and handles filtering the query. I think it's better to have the Factory and Args Modifier enhancements in another branch and PR. Don't you? It's easier to track what we're doing and deal with any issues that might arise. |
You know that moment when you look at your code and think "What the heck was I thinking?!" This commit fixes one of _those_ moments. In the integration tests, pass the number of posts into WP_Query as an argument. Duh.
Yes. I agree. But I don't think this refactor brings us to a place where we can have one factory that wires everything. My concerns to get there: We still have Maybe, the |
/** | ||
* Set up the stubs for the common WordPress escaping and internationalization functions. | ||
*/ | ||
protected function setup_common_wp_stubs() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hellofromtonya I did phpcs:disable here because I didn't know why setup_common_wp_stubs
isn't camel cased.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it camelCase. It's a copy from my other work, which uses WPCS 100%.
src/ContentGetter/PostsGenerator.php
Outdated
* | ||
* @return array | ||
*/ | ||
public function getContent(WP_Query $query): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really do think, if I'm designing an implementation I want a WP_REST_Request
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, then let's make that change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but you asked for upsides and downsides so I wrote the last paragraph of this comment: #6 (comment) and now I really feel like the change either:
- Strongly couples the interface to the REST API. 👎
or - We have to have another level of abstraction below it. Ok. I'll do that I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change made
e2e1719
*/ | ||
private function getQuantity(): int | ||
{ | ||
if (!isset($this->query->query)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a separate concern, but this interface will need to communicate total in the current result set and total pages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember here that our PostsGenerator
is an experimental implementation to merely mock creating posts. It has a private function to get how many posts to create.
In a real-world application, you would want a different approach as you've indicated. But here, this approach fits the needs of the educational experiment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right.
BTW @hellofromtonya I made ba0f8e5 on this branch because it's just the results of the code sniffer/ fixer. I am branching from here to work on creating the one factory like we discussed. Just wanted to make merge easier. |
If we were to use the exact same interface design for methods like It's okay to have different signatures and implementations if that's the intent. It's not a code smell. Why? We've intentionally designed this method for this specific purpose. Now, if your intent is to design a global pattern and signature whereby all of the implementations have a The key then is to determine:
|
Gutenberg hooks into both of the filters we need to work with
|
OK, so I'm as far into #7 as creating interfaces for the two other classes. Intent: we want queries to post type routes such as So I think to wire an arbitrary number of implementations, we need to hook rest_{$post_type}collection_params and rest{$post_type}_query for every post type. Then we have some sort of container that is aware of the So, I think we want to make the filtering as magic as possible, since that's repetitive. End implementation should supply the new query args and new schema args and a class that implements I think making implementations will be more flexible if |
Now with 3268a62 I have a factory that takes an array fo arguments for the REST API to add, and an array of post types -- like this that auto-wires those filters. BTW a lot of my concern about setting objects went away by letting the plugins API supply the data. BTW[] Next: an extensible way to load these or route the right ContentGetter |
With 1bfce07 I'm capturing the current request so it can be injected to content getter using the |
@hellofromtonya I changed your Theory is that now getPosts() acts as a dispatcher the last set |
With last commit I think I'm doing today, instantiation of our default implementation uses part of new factory We should now be able to remove |
The design we have now is simplistic, as it wires one implementation to the filter. Then the implementation itself figures out what needs to be done. We've abstracted the tasks of processing getting content from the task of filtering. In this experiment, it works. But there are cases where one might want to convert Keep it simple. I think we can keep it simple for the purposes of this experiment and teaching opportunity. But you can note in your articles to invite devs to expand upon the design for their needs. |
In 7c94c74 I added a filter in In a4ea96c I introduced a In 82db8a7 I added a filter that if it is null, uses this internal router. If its a valid object, that is returned. I proved this with an integration test. I used an integration test over a unit test for this because it demonstrates how a key part of an add-on implementation would work. Concerns:
|
This PR improves the reuse of the plugin by passing query to the content getter implementation. An implementation may need more information than just the quantity to process and return. By passing the query to the implementation, it can handle its own work.
This PR also improves the testing suite for the filtering process.
This PR also fixes the plugin's bootstrap so that the plugin does actually filter the query when doing a RESTful request. Booyah! #