[wp-trac] [WordPress Trac] #45331: 'rest_url_prefix' filter fails to impact flush_rewrite_rules() on plugin activation
WordPress Trac
noreply at wordpress.org
Mon Nov 12 14:39:16 UTC 2018
#45331: 'rest_url_prefix' filter fails to impact flush_rewrite_rules() on plugin
activation
-------------------------------------------------+-------------------------
Reporter: KestutisIT | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting
| Review
Component: Permalinks | Version: 4.9.8
Severity: major | Keywords: needs-patch
Focuses: administration, rest-api, coding- | ux-feedback
standards |
-------------------------------------------------+-------------------------
'rest_url_prefix' filter fails to impact flush_rewrite_rules() on plugin
activation
=========================================================================
So here is the bug - 'flush_rewrite_rules' is called on plugin activation
after 'rest_url_prefix' filter added with new API ENDPOINT,
but if I go to '<MY-DOMAIN>/<NEW-ENDPOINT>/' it gives me 404 error. And if
I access '<MY-DOMAIN>/wp-json/' on Firefox Developer Edition in 'Header'
section I see:\\
`Link <http://<MY-DOMAIN>/<NEW-ENDPOINT>/>; rel="https://api.w.org/"`\\
So the header is correct here. And it will fix the issue if I go to WP
Settings -> Permalinks -> Save.\\
But that is a bug. As you won't have to instruct that to your plugin user,
after his activation he will see that API is not working.\\
\\
Install Controller class - 'flush_rewrite_rules' is called on plugin
activation after 'rest_url_prefix' filter added with new API ENDPOINT:
{{{#!php
<?php
namespace GreatestEverManager\Controllers\Admin;
final class InstallController
{
<...>
public function setCustomWP_RestAPI_Prefix()
{
// NOTE: Do not forget to do the same on install with
flush_rewrite_rules(); after it.
add_filter('rest_url_prefix', function() { return
ConfigurationInterface::WP_REST_API_PREFIX; }, 10, 1);
// NOTE: As there is no custom post types or custom taxonomies
registration later, we perform rewrite rules flush right now
flush_rewrite_rules();
}
<...>
}
}}}
\\
Main Controller class:
{{{#!php
<?php
namespace GreatestEverManager\Controllers;
use SoftwareLicenseManager\Models\Configuration\ConfigurationInterface;
<...>
final class MainController
{
<...>
public function __construct(ConfigurationInterface
$paramConfWithoutRouting)
{
<...>
if(!is_null($this->confWithoutRouting))
{
register_activation_hook($this->confWithoutRouting->getPluginPathWithFilename(),
array(&$this, 'networkOrSingleActivate'));
register_deactivation_hook($this->confWithoutRouting->getPluginPathWithFilename(),
array(&$this, 'networkDeactivate'));
<...>
}
}
/**
* Activate (enable+install or enable only) plugin for across the
whole network
* @note - 'get_sites' function requires WordPress 4.6 or newer!
*/
public function networkOrSingleActivate()
{
if(is_multisite())
{
// A workaround until WP will get fixed
// SHOULD be 'networkActivate' but WordPress does not yet
support that feature,
// so this means as long as the 'MULTISITE' constant is
defined in wp-config, we use that method
$this->multisiteActivate();
} else
{
// A workaround until WP will get fixed
$this->activate();
}
}
public function activate()
{
try
{
<...>
// Install plugin for single site
$objInstaller = new
\GreatestEverManager\Controllers\Admin\InstallController($conf, $lang,
$conf->getBlogId());
// Install
<...>
$objInstaller->setCustomWP_RestAPI_Prefix();
<...>
} catch (\Exception $e)
{
if(StaticValidator::inWPDebug())
{
// In WP activation we can kill the install only via
'trigger_error' with 'E_USER_ERROR' param
$error = sprintf(static::LANG_ERROR_IN_METHOD_TEXT,
__FUNCTION__, $e->getMessage());
trigger_error($error, E_USER_ERROR);
}
}
}
public function run()
{
if($this->canProcess)
{
<...>
add_filter('rest_url_prefix', function() { return
ConfigurationInterface::WP_REST_API_PREFIX; }, 10, 1);
add_action('rest_api_init', array(&$this,
'frontEndAPI_Callback'), 0);
<...>
}
}
<...>
}
}}}
\\
Plugin main file (wp-
content/plugins/GreatestEverManager/GreatestEverManager.php):
{{{#!php
<?php
/**
* Plugin Name: Greatest Ever Manager
* <...>
*/
namespace GreatestEverManager;
require_once 'Models/Configuration/ConfigurationInterface.php';
require_once 'Models/Configuration/Configuration.php';
require_once 'Controllers/MainController.php';
<...>
use GreatestEverManager\Models\Configuration\Configuration;
use GreatestEverManager\Controllers\MainController;
if(!class_exists('GreatestEverManager\GreatestEverManager'))
{
final class GreatestEverManager
{
// Configuration
const REQUIRED_PHP_VERSION = '5.4.0';
const REQUIRED_WP_VERSION = 4.6;
const OLDEST_COMPATIBLE_PLUGIN_VERSION = 6.0;
const PLUGIN_VERSION = 6.0;
// Settings
private static $params = array(
'plugin_id' => 0,
'plugin_prefix' => 'greatest_ever_manager_',
'plugin_api_namespace' => 'gem/v1',
'plugin_handle_prefix' => 'greatest-ever-manager-',
<...>
);
private static $objConfiguration = NULL;
private static $objMainController = NULL;
<...>
/**
* @return Configuration
*/
public static function getConfiguration()
{
if(is_null(static::$objConfiguration) ||
!(static::$objConfiguration instanceof Configuration))
{
// Create an instance of plugin configuration model
static::$objConfiguration = new Configuration(
$GLOBALS['wpdb'],
get_current_blog_id(),
static::REQUIRED_PHP_VERSION, phpversion(),
static::REQUIRED_WP_VERSION, $GLOBALS['wp_version'],
static::OLDEST_COMPATIBLE_PLUGIN_VERSION,
static::PLUGIN_VERSION,
__FILE__,
static::$params
);
}
return static::$objConfiguration;
}
/**
* Creates new or returns existing instance of plugin main
controller
* @return MainController
*/
public static function getMainController()
{
if(is_null(static::$objMainController) ||
!(static::$objMainController instanceof MainController))
{
// NOTE: This is not passing by reference!
static::$objMainController = new
MainController(static::getConfiguration());
}
return static::$objMainController;
}
<...>
}
<...>
// Run the plugin
GreatestEverManager::getMainController()->run();
}
}}}
\\
The coding pattern is S.O.L.I.D. MVC, Version 6, based on PSR-4
Autoloaders and PSR-2 Coding Standards.
To deeply inspect load process (without the REST_API part), you can
inspect 'Expadandable FAQ' - SolidMVC boiler-plate plugin:
[https://wordpress.org/plugins/expandable-faq/]
--
Ticket URL: <https://core.trac.wordpress.org/ticket/45331>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list