When creating meta boxes, in each meta box function it seems a reference to the global $post
is passed as a parameter ($event)
. I prefer this as it seems consistent and less likely to fudge the $post
var by declaring it explicitly as I have read elsewhere.
add_action('admin_init', 'events_admin');
function events_admin()
{
add_meta_box('display_events_date_meta_box',
'Dates',
'display_events_date_meta_box',
'events', 'normal', 'high'
);
}
function display_events_date_meta_box($event) // Referenced
{
//$event in this case is the $post global
}
I have created a filter and various other functions which currently just use the global $post
variable.
add_action( 'admin_head-post-new.php', 'test' );
add_action( 'admin_head-post.php', 'test' );
function test()
{
global $post; // Declared explicitly
}
Is there a standard / recommended way to pass the global $post
variable as a parameter to these functions?
When I need to deal with $post
variable on admin, I usually use a class to early catch and wrap global $post
variable, obtaining an universal way to access to it, without repetitely relying on the global variable.
class MyAdminPost
{
private static $post;
public static function init()
{
$p_get = filter_input(INPUT_GET, 'post', FILTER_SANITIZE_NUMBER_INT);
$p_post = filter_input(INPUT_POST, 'post', FILTER_SANITIZE_NUMBER_INT);
if ($p_get > 0 || $p_post > 0) {
self::$post = $p_get > 0 ? get_post($p_get) : get_post($p_post);
} elseif ($GLOBALS['pagenow'] === 'post-new.php') {
add_action('new_to_auto-draft', function(\WP_Post $post) {
if (is_null(MyAdminPost::$post)) {
MyAdminPost::$post = $post;
}
}, 0);
}
}
public function get()
{
return self::$post;
}
}
add_action('admin_init', array('MyAdminPost', 'init'));
On early stage of admin loading, that is 'admin_init'
hook, 'MyAdminPost'
class looks for post ID variable sent with request and store related post object.
That works on post.php
page, but not on post-new.php
, because on that page post ID is not sent with request because it does’t exist yet. In that case I add a callback to 'new_to_auto-draft'
that is one the "{old_status}_to_{new_status}"
hooks to store the post immediately after it is created on post-new.php
page.
In this way, in both pages, post object is stored in a class property very early.
Usage Example (Procedural)
function get_my_admin_post()
{
static $post = null;
if (is_null($post) && did_action('admin_init')) {
$map = new MyAdminPost();
$post = $map->get();
}
return $post;
}
add_action('admin_head-post.php', 'test');
function test()
{
$post = get_my_admin_post();
}
Usage Example (OOP)
class ClassThatUsesPostObject
{
private $post_provider;
function __construct(MyAdminPost $map)
{
$this->post_provider = $map;
}
function doSomethingWithPost()
{
$post = $this->post_provider->get();
}
}
Benefits
-
you can obtain post object very early in a way that is compatible to both post.php
and post-new.php
pages, so in all the hooks fired in those pages you have access to post object with no effort
-
you remove any global $post
variable reference in your code
-
your code becomes testable in isolation