Opened 8 years ago
Last modified 3 months ago
#39699 new enhancement
Filter to check XML-RPC data before any DB insertion
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | 4.8 |
Component: | XML-RPC | Keywords: | has-patch has-unit-tests dev-feedback |
Focuses: | Cc: |
Description
After searching into XML-RPC server class code, I realized that it seems that there isn't way to check XML-RPC input data before starting to insert/update any rows to database nor to return an IXR
custom error message.
For example for new post, in order to check custom fields, a possible workaround is to use wp_insert_post_empty_content
filter, but we are unable to customize the error message. Moreover at this point some DB rows are inserted, so inside the filter above we have to call wp_delete_post
manually in order to clean DB (taking care to check auto-draft
post status).
In the case of editing post, things get a bit more complicated, so we could use transactions with the help of xmlrpc_call
/wp_insert_post
actions.
So, the patch aims to add a new filter named xmlrpc_before_insert_post
that allows to do this check in a more robust manner (for wp.newPost
and wp.editPost
XML-RCP methods).
Typical usage:
<?php if ( defined( 'XMLRPC_REQUEST' ) ) { add_filter( 'xmlrpc_before_insert_post', 'my_filter_xmlrpc_before_insert_post', 10, 3 ); } function my_filter_xmlrpc_before_insert_post ( $post_data, $content_struct, $user ) { // do checks with $post_data, i.e: if ( title_contains_stop_words( $post_data['post_title'] ) ) return new IXR_Error( 500, 'Post title contains invalid words' ); return $post_data, }
The filter is placed inside _insert_post
helper function before get_default_post_to_edit()
that isthe first statement that adds a new DB row.
Regards
Attachments (1)
Change History (10)
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 years ago
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 years ago
This ticket was mentioned in PR #8494 on WordPress/wordpress-develop by @SirLouen.
3 months ago
#6
- Keywords has-unit-tests added
This patch is an adaptation of the original patch made 8 years ago in the ticket
It adds some corrections + sorting of PHPCS issues.
More info about this patch in Trac.
Trac ticket: [](https://core.trac.wordpress.org/ticket/39699)
#7
@
3 months ago
- Keywords dev-feedback added; needs-testing removed
Test Report
Description
This report validates that the indicated patch works as expected.
Given that the patch is 8 years old, I have uploaded a new patch to Github, adding some PHPCS corrections and fixing the merging process that slightly failed.
Patch tested: https://patch-diff.githubusercontent.com/raw/WordPress/wordpress-develop/pull/8494.diff
Environment
- WordPress: 6.8-beta2-59971-src
- PHP: 8.2.27
- Server: nginx/1.27.4
- Database: mysqli (Server: 8.4.4 / Client: mysqlnd 8.2.27)
- Browser: Firefox 136.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.1
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Testing Instructions
- Run the code below adding before to
functions.php
or a custom plugin the filter hook proposed also there - The post should be published without issues
- Apply the patch
- Run the code again
- It throws an error like:
Error: 500 - Post title too short.
Actual Results
- ✅ Issue resolved with patch.
- ✅ Both tests pass with the two asserts each correctly
Additional Notes
I doubt that anyone in the world is still using RPC, but I have admit that this adds a fun filter for those who needs some extra limitations when publishing content.
Supplemental Artifacts
I'm using this script to test it manually with an external PHP library. It basically replicates a similar example to the one exposed in the tests:
<?php // First Run: composer require phpxmlrpc/phpxmlrpc require_once 'vendor/autoload.php'; use PhpXmlRpc\Client; use PhpXmlRpc\Value; use PhpXmlRpc\Request; // Create a new XML-RPC client $client = new Client('http://localhost:8889/xmlrpc.php'); // Create custom fields array $customFields = new Value( array( new Value( array( 'key' => new Value('custom_field_to_create', 'string'), 'value' => new Value('123456789', 'string') ), 'struct' ) ), 'array' ); // Create post data $postData = new Value( array( 'post_title' => new Value('This title is too long', 'string'), 'custom_fields' => $customFields ), 'struct' ); // Create parameters for the request $params = array( new Value(1, 'int'), // Blog ID new Value('testuser', 'string'), // Username new Value('password', 'string'), // Password $postData ); // Create and send the request $request = new Request('wp.newPost', $params); $response = $client->send($request); // Check for errors and display result if ($response->faultCode()) { echo "Error: " . $response->faultCode() . " - " . $response->faultString(); } else { echo "Post created with ID: " . $response->value()->scalarval(); }
Plus we can use this code in a plugin or in the functions.php:
<?php function filter_xmlrpc_before_insert_post ( $post_data, $content_struct, $user ) { if ( strlen( $post_data['post_title'] ) > 10 ) { return new \IXR_Error( 500, 'Post title too long.' ); } return $post_data; } add_filter( 'xmlrpc_before_insert_post', 'filter_xmlrpc_before_insert_post', 10, 3 );
#8
@
3 months ago
Raising attention of current XML-RPC @markoheijnen, this is totally ready to move forward.
#9
@
3 months ago
Hi,
glad to see that this my old patch is still getting a little interest :-)
Actually, since it wasn’t put in the core, I added that filter to my REST XML-RPC Data Checker plugin (which still I use on some of my systems).
PS: Since it uses the same filter name, if it will get into core, I'll remove filter from plugin (for WordPress versions greater than or equal to the one containing the patch)
Punting to Future Release per today's 4.8 bug scrub.