(This article was originally published by Torque Magazine and reprinted with permission.)
In recent years, the author has written a lot of articles on object-oriented PHP and WordPress REST APIs in Torque magazine, which also involves using Composer for dependency management and automatic loading, as well as unit testing. The core point of all articles is: By applying established software development best practices to WordPress development, we can create better plugins.
This is the first in a series of articles that will integrate these concepts in a practical, functional example. I'll walk through how to create a WordPress plugin to modify the functionality of the WordPress REST API endpoint to better optimize searches. The plugin is available on GitHub. You may need to browse the commit log to understand my build process.
In this series, I will cover how to build plugins and classes using modern object-oriented PHP, and how to make it testable, and how to write automated tests for it. I'll cover the differences between unit testing, integration testing, and acceptance testing and show you how to write and automate each type of test. This article first introduces how to use an object-oriented method to modify the WordPress REST API using filters.
Key Points
- Enhance WordPress REST API endpoints with object-oriented PHP for better search capabilities and integrate with advanced search tools such as ElasticSearch.
- Modify the REST API endpoint parameters and WP_Query interaction to bypass the limitations of default WordPress searches and improve the response quality of complex queries.
- Use unit testing, integration testing and acceptance testing for robust and easy-to-maintain code to ensure that each component runs correctly in the WordPress ecosystem.
- Use dependency injection and PHP Traits to cleanly manage class dependencies, enabling easier maintenance and testing code.
- Customize REST API endpoint mode to include additional parameters such as
post_type
, allowing for more flexible and powerful search capabilities. - Dynamically adjust the WP_Query parameters through specific REST API requests, and use filters to effectively refine search results and endpoint behavior.
Improving WordPress search with REST API
Usually use plugins like SearchWP or Relevansi, or integration with ElasticSearch (a technology that uses a completely different stack from WordPress) to improve WordPress search. These types of plugins provide better search results and are often used with a multifaceted search interface, which is very useful for e-commerce applications.
Search through WordPress REST API inherits all these same problems and the same solutions. In this post, I will first introduce how search works and its limitations. We will then look at how to modify searches and integrate with SearchWP using two different methods.
The built-in search functionality of WordPress usually requires improvement using external services. While this article is about an object-oriented approach to modifying how WordPress REST API post routing works, the actual example would be to improve search.
When WordPress is used as a backend for decoupling front-ends (such as native mobile applications or web applications, which may be built using Vue, React, or Angular), it is important to do high-quality search through the REST API. The code presented in this article will help you if your application users need to find the right product variant or search for content based on complex algorithms based on multiple taxonomy and you are writing custom code instead of just installing plugins .
Search posts using WordPress REST API
If you want to search for all posts with a post type of “product” on one site, use the search term “Taco Shirts” and you will make a request to the /wp/v2/product?s=Taco Shirt
endpoint. If you want to improve the quality of your results, the solutions listed above will help.
As mentioned above, WP_Query (thing used by the post endpoint of the WordPress REST API) is not a good search tool. More specifically, WP_Query may be less likely than dedicated search tools that tend to be built using NoSQL databases due to its dependency on MySQL.
First, let's see how to bypass WP_Query's interaction with WordPress database when making REST API requests.
This is a strategy used by many search plugins to replace their own search system results (which are generated by default for WP_Query). The search system can use the same database. It can also connect to other databases, possibly via API requests, such as to ElasticSearch or Apache Solr servers.
If you look at WordPress core code, you will find that the filter "posts_pre_query" runs before the WP_Query query database, but after the SQL query is ready. This filter returns null by default. If the value is null, WordPress continues its default behavior: query the WordPress database and return the result as a simple array of WP_Post objects.
On the other hand, if the return value of this filter is an array (that would like to contain a WP_Post object), the default behavior of WordPress is not used.
Let's see how to use posts_pre_query to return a simulated WP_Post. This strategy is very useful for testing, but a more complex version of the same schema can be used to integrate a separate database with your WordPress site:
// ... (代码示例与原文相同) ...
In this example, we are using mock data, but we can use SearchWP's query class or anything else. Another thing to note about this code is that it will run on any WP_Query, not just the WP_Query object created by the WordPress REST API. Let's modify it so that we don't use filters unless it's a WordPress REST API request:
// ... (代码示例与原文相同) ...
Modify WordPress REST API endpoint parameters
We just looked at how to change the search results generated for WordPress REST API requests. This allows us to optimize the query for better search results, but it may expose the need for different patterns of the endpoint.
For example, if you want to allow searches for product endpoints optionally allow other post types to be included in the search, I introduced another solution to the same problem last year.
Horizontal focus
We are about to look at how to modify allowed endpoint parameters and how to use them to create WP_Query parameters. These are two separate concerns, and the single responsibility principle states that we need to create a class for each concern. But these two classes will have shared concerns.
For example, if we want to allow querying by different post types, we need to know which public post types are, and what their slug and rest_base parameters are. All this information is available from the function get_post_types.
The output of this function is not exactly what we need. So let's design a class to format the data according to the requirements I just listed and provide us with a helper way to access it.
Think of it as a common shape for all post type data we need to use in available containers:
// ... (代码示例与原文相同) ...
Note that instead of calling get_post_types() in the class, we use it as a dependency, injected through the constructor. Therefore, this class can be tested without loading WordPress.
This is why I describe this kind as "unit-testable". It doesn't rely on any other API, and we don't worry about side effects. We can test it as a separate, isolated unit. Separate the focus and isolate its functionality into small parts, and once we have unit test coverage, we can make the code easy to maintain. I'll cover how to test this type of class in my next post.
Remember that this class does depend on WP_Post_Type. My unit tests will not define the class because only integration tests can use WordPress or any other external dependencies. This class is used only to represent data, not to perform any action. Therefore, we can say that its use will not have any side effects. So I'd love to use mocks in unit tests instead of real WP_Post_Type.
Speaking of dependency injection, classes that require objects of this new class, we want to follow the same pattern. Instead of instantiating PreparedPostTypes in the class that requires them, we pass in an instance. This means that classes using PreparedPostTypes and PreparedPostType are kept isolated and can be tested separately.
It can also cause code reuse because we have to make dependency injection possible and set a property for this object. We can use cut and paste, or we can use PHP Trait, a more advanced and extensible method for copying methods and properties between classes.
This is a Trait that establishes a pattern for injecting PreparedPostTypes objects into other classes:
// ... (代码示例与原文相同) ...
One of our concerns is that we need to know some information about the post type in multiple places. For example, post type slug. This is slightly different from the previous cross-cutting concern. The last problem we solved involves dynamic data. Now we just need to change the strings we use in multiple places in one place.
A class with class constants simply solved this problem for us:
// ... (代码示例与原文相同) ...
Now we can make these strings consistent throughout the code. This seems to be an unnecessary step. But my sample code works for post post type. If you want to change the post type you are using, this class needs to be changed without changing anything else. This is following Tom McFarlin's preferred definition of the single responsibility principle when he wrote "A class should have only one reason to change."
Modify REST API endpoint mode
Now we need to modify the pattern of the post type endpoint. By doing so, WordPress will communicate to the REST API endpoint that the post type parameter is allowed and that new endpoint parameters are allowed when parsing the request.
This is our class to add the post_type property. Please note that it uses the trait UsesPreparedPostTypes we just discussed:
// ... (代码示例与原文相同) ...
In the settings of this property, we tell WordPress that this property is an array property, and we use the "enum" index of the array to specify the allowed values.
In "enum", we enumerate allowed values. In this case, the PreparedPostTypes class provides an array of allowed values, as this is a previously solved cross-cutting concern.
Note that this class is not coupled to any post type or even this specific use case. We will soon go back to what hooks to use to make this class work for specific post types.
Modify REST API WP_Query parameter
The previous section describes how to make the new endpoint property post_type available. This does not actually change the WP_Query parameter generated by the WordPress REST API. We already have everything we need except the last filter.
Post type is a WP_Query parameter that the core code specifically does not allow changes to the REST API request. We have a dynamically named filter—rest_{$post_type}_query—can override any WP_Query parameter.
This is our class, which injects our post_type parameters, which were not allowed before:
// ... (代码示例与原文相同) ...
Most of it is just to verify that we should make changes and then use the get_param method of WP_Rest_Request to get the value from the request. Most of it is automatic because we modify the pattern first to match.
Modify the WP_Query object requested by WordPress REST API
I have already covered how to do this in the first part of this article. This is a class that implements the same pattern:
// ... (代码示例与原文相同) ...
I hope you notice that this code is closely related to WordPress and is not testable. It uses WP_Post from WordPress, which is checking constants for WordPress and interacting with WordPress's plugin API. We can simulate WP_Post, and we can set constants ourselves. But the plugin's API - this is an important feature that needs to be tested. In my next few posts, I'll cover how to refactor this class so that we can use unit tests to cover everything except the effect of removing that filter, and use integration tests to check that effect.
I chose to use a static method for two reasons. First, it makes it easy to add and remove it in multiple locations. For example, in the ModifyQuery class, I only hook this filter if needed:
// ... (代码示例与原文相同) ...
Also, it is easy to create recursive loops when using this filter. It's great to be able to remove it as easily as in this example code.
Another reason I chose to use a static method is that the function interacts with other APIs. It will never be truly unit-testable. This pattern, a class with static methods, makes it very easy to simulate the class in integration testing, thus minimizing the impact of lack of strong isolation in one part of this system.
Make all content work together
The code we've seen so far is very uncoupled from WordPress. There are many benefits to this. But that means it does nothing on its own. This is very good. We have only dealt with business logic requirements so far. Now we need to consider integration.
This is not difficult, just add some hooks. What hooks? The exact same two hooks as we designed for the ModifyQuery and ModifySchema classes. The desire for decoupling business logic does not mean that we cannot consider the actual reasons why we write code when designing their public interfaces. Otherwise, we will only add extra complexity to our code without reason.
Generally speaking, I try to increase software complexity only when it makes life easier. I've deviated from this path in the past. We all have it, it doesn't matter, practice forgiveness.
The methods in the class we are about to hook use exactly the same parameters and return types as the hook. Their job is to assign these values to other components.
// ... (代码示例与原文相同) ...
Next step: Test
This is close enough. It will work. Due to the lack of a formal system to add hooks, this is the best thing we can do for initialization. This is very good. I will cover how to create a more complex and scalable boot process in a future article on WordPress integration testing.
In this article, we examine the underlying WP_Query for creating code to modify schema, WP_Query parameter generation, and post type. I encourage you to convert this code into a plugin and use Composer for automatic loading. In my next post, we will look at unit tests to cover these classes.
(The following is the original FAQ part, and the pseudo-original creation has been made based on the original content)
FAQs about advanced OOP and custom REST API endpoints in WordPress
What is the meaning of object-oriented programming (OOP) in WordPress?
Object-oriented programming (OOP) is a programming paradigm for designing applications and software using "objects". In a WordPress environment, OOP provides a simple, efficient and robust way to develop complex applications. It allows developers to group relevant tasks into classes and objects, making the code easier to read, reuse, and maintain. OOP also enhances application security by encapsulating data and preventing direct external access.
How to customize REST API endpoints in WordPress?
The WordPress REST API provides a set of default endpoints for different types of data. However, you can customize these endpoints or create new endpoints to suit your specific needs. This can be done by using the register_rest_route()
function in your plugin or theme. This function allows you to specify the route or URL of the endpoint and define the methods it should respond to (GET, POST, etc.).
What are the advantages of customizing WordPress REST API endpoints?
Custom WordPress REST API endpoints allow you to create more efficient, flexible and secure applications. You can adjust the data returned by the endpoint to reduce the amount of unnecessary data sent over the network. You can also create endpoints that perform specific tasks, such as processing form submissions or generating reports, making your application more interactive and user-friendly.
How does OOP enhance the security of WordPress applications?
OOP enhances the security of WordPress applications by encapsulating data and methods into objects. This means that the properties (data) and methods (functions) of the object are hidden from the rest of the application and are only accessible through the object's methods. This prevents unauthorized access and manipulation of data, thereby reducing the risk of security breaches.
Can OOP be used with older versions of WordPress?
Yes, you can use OOP with older versions of WordPress. However, it is important to note that newer versions of WordPress have improved OOP support and include many features to make it easier to develop using this paradigm. So while OOP can be used with older versions, it is generally recommended to use the latest version of WordPress for the best development experience.
What are the roles of classes and objects in OOP?
In OOP, a class is a blueprint or template for creating an object. It defines the properties (data) and methods (functions) that an object should have. On the other hand, an object is an instance of a class. It has its own set of properties and methods that may be different from other objects of the same class. The use of classes and objects makes the code more organized, reusable and easy to maintain.
How to create a new class in WordPress?
You can use the class
keyword, followed by the class name and a set of curly braces {}
to create a new class in WordPress. In parentheses, you can define the properties and methods of the class. To create an object of a class, you can use the new
keyword followed by the class name.
What is the REST API in WordPress?
The REST API in WordPress is an interface that allows you to interact with your WordPress site using HTTP requests. It provides a set of endpoints for different types of data such as posts, comments, and users that you can access using standard HTTP methods such as GET, POST, PUT, and DELETE. The REST API makes it easier for you to create, read, update, and delete data from your WordPress site from an external application.
How to access REST API in WordPress?
You can access the REST API in WordPress by sending HTTP requests to the corresponding endpoint. Each endpoint corresponds to a specific type of data and supports certain HTTP methods. For example, to retrieve a post list, you can send a GET request to the /wp/v2/posts
endpoint. The REST API will return data in JSON format, which you can then process and display in your application.
Can I use the REST API with a non-WordPress application?
Yes, you can use the REST API with non-WordPress applications. The REST API is platform-agnostic, which means it can be used with any application that can send HTTP requests and process JSON data. This makes it a powerful tool for integrating WordPress sites with other applications such as mobile apps, desktop apps, and other web services.
The above is the detailed content of Advanced OOP for WordPress: Customizing REST API Endpoints. For more information, please follow other related articles on the PHP Chinese website!

Do you want to move your blog from WordPress.com to WordPress.org? Many beginners start with WordPress.com but quickly realize their limitations and want to switch to the self-hosted WordPress.org platform. In this step-by-step guide, we will show you how to properly move your blog from WordPress.com to WordPress.org. Why migrate from WordPress.com to WordPress.org? WordPress.com allows anyone to create an account

Are you looking for ways to automate your WordPress website and social media accounts? With automation, you will be able to automatically share your WordPress blog posts or updates on Facebook, Twitter, LinkedIn, Instagram and more. In this article, we will show you how to easily automate WordPress and social media using IFTTT, Zapier, and Uncanny Automator. Why Automate WordPress and Social Media? Automate your WordPre

Just a few days ago, one of our users reported an unusual problem. The problem is that he reaches the limit of custom menu items. Any content he saves after reaching the menu item limit will not be saved at all. We've never heard of this issue, so we decided to give it a try on our local installation. More than 200 menu items were created and saved. The effect is very good. Move 100 items to the drop-down list and save them very well. Then we knew it had to do with the server. After further research, it seems that many others have encountered the same problem. After digging deeper, we found a trac ticket ( #14134 ) that highlighted this issue. Read very

Do you need to add custom metafields to custom taxonomy in WordPress? Custom taxonomy allows you to organize content besides categories and tags. Sometimes it is useful to add other fields to describe them. In this article, we will show you how to add other metafields to the taxonomy they create. When should custom metafields be added to custom taxonomy? When you create new content on your WordPress site, you can organize it using two default taxonomy (category and tag). Some websites benefit from the use of custom taxonomy. These allow you to sort content in other ways. For example,

Windows live writer is a versatile tool that allows you to post posts directly from your desktop to your WordPress blog. This means you don't need to log in to the WordPress admin panel to update your blog at all. In this tutorial, I will show you how to enable desktop publishing for your WordPress blog using Windows Live Writer. How to set up Windows Live Writer on WordPress Step 1: To use Windows Live Writer in WordPr

Recently, one of our users reported a very strange installation problem. When writing a post, they can’t see anything they write. Because the text in the post editor is white. What's more, all the visual editor buttons are missing, and the ability to switch from visual to HTML doesn't work either. In this article, we will show you how to fix the white text and missing button issues in the WordPress visual editor. Be a Beginner Note: If you are looking for hidden buttons that may be seen in screenshots of other websites, you may be looking for a kitchen sink. You have to click on the kitchen sink icon to see other options such as underline, copy from word, etc.

Do you want to display avatars in user emails in WordPress? Gravatar is a network service that connects a user's email address to an online avatar. WordPress automatically displays visitors’ profile pictures in the comments section, but you may also want to add them to other areas of the site. In this article, we will show you how to display avatars in user emails in WordPress. What is Gravatar and why should I display it? Gravatar stands for globally recognized avatars, which allows people to link images to their email addresses. If the website supports

Do you want to change the default media upload location in WordPress? Moving media files to other folders can improve website speed and performance and help you create backups faster. It also gives you the freedom to organize your files in the way that suits you best. In this article, we will show you how to change the default media upload location in WordPress. Why change the default media upload location? By default, WordPress stores all images and other media files in the /wp-content/uploads/ folder. In this folder you will find children of different years and months


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft