Created
June 19, 2015 00:57
-
-
Save gmazzap/e45bb38565e221876958 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Giuseppe Mazzapica <[email protected]> | |
* @license http://opensource.org/licenses/MIT MIT | |
*/ | |
class MetaboxStealer | |
{ | |
/** | |
* @var bool | |
*/ | |
private static $stealing; | |
/** | |
* @var string | |
*/ | |
private $post_type; | |
/** | |
* @var array | |
*/ | |
private $boxes = []; | |
/** | |
* When the request contain special variable, this function will make it | |
* return a serialized version of $wp_meta_boxes array and die. | |
*/ | |
public static function init() | |
{ | |
add_filter('post_updated_messages', function ($messages) { | |
if (MetaboxStealer::stealing()) { | |
ob_start(); | |
return []; | |
} | |
return $messages; | |
}); | |
add_action('do_meta_boxes', function () { | |
if (MetaboxStealer::stealing()) { | |
ob_end_clean(); | |
global $wp_meta_boxes; | |
echo serialize($wp_meta_boxes); | |
die(); | |
} | |
}); | |
} | |
/** | |
* Checks that the request contain a special variable that will make request | |
* return a serialized version of $wp_meta_boxes array and die. | |
* | |
* @return bool | |
*/ | |
public static function stealing() | |
{ | |
if (is_null(self::$stealing)) { | |
$screen = function_exists('get_current_screen') ? get_current_screen() : null; | |
$stealing = filter_input(INPUT_GET, 'stealing-boxes', FILTER_SANITIZE_STRING); | |
self::$stealing = | |
$screen instanceof \WP_Screen | |
&& $stealing | |
&& wp_verify_nonce($stealing, $screen->post_type); | |
} | |
return self::$stealing; | |
} | |
/** | |
* @param string $post_type Current post type | |
*/ | |
public function __construct($post_type) | |
{ | |
$this->post_type = $post_type; | |
} | |
/** | |
* Send a HTTP request to post edit page of a given CPT setting a special | |
* variable that will make that page return serialized $wp_meta_boxes array. | |
* After that, so obtained boxes are merged with the boxes for current post type. | |
* | |
* @param string $cpt CPT to steal metaboxes from | |
*/ | |
public function steal($cpt) | |
{ | |
$vars = [ | |
'post_type' => $cpt, | |
'stealing-boxes' => wp_create_nonce($cpt), | |
]; | |
$url = add_query_arg($vars, admin_url('/post-new.php')); | |
$cookies = []; | |
foreach ($_COOKIE as $name => $value) { | |
if ('PHPSESSID' !== strtoupper($name)) { | |
$cookies[] = new \WP_Http_Cookie([ | |
'name' => $name, | |
'value' => $value, | |
]); | |
} | |
} | |
$response = wp_remote_get($url, ['cookies' => $cookies]); | |
if (! is_wp_error($response)) { | |
$body = wp_remote_retrieve_body($response); | |
if (is_serialized($body)) { | |
$boxes = unserialize($body); | |
$this->boxes = isset($boxes[$cpt]) ? $boxes[$cpt] : []; | |
empty($this->boxes) or $this->merge(); | |
} | |
} | |
} | |
/** | |
* Merge meta boxes from current request with boxes obtained from HTTP request to another CPT. | |
*/ | |
private function merge() | |
{ | |
global $wp_meta_boxes; | |
isset($wp_meta_boxes[$this->post_type]) or $wp_meta_boxes[$this->post_type] = []; | |
foreach ($this->boxes as $context => $priorities) { | |
foreach ($priorities as $priority => $boxes) { | |
if (! isset($wp_meta_boxes[$this->post_type][$context])) { | |
$wp_meta_boxes[$this->post_type][$context] = []; | |
} | |
if (! isset($wp_meta_boxes[$this->post_type][$context][$priority])) { | |
$wp_meta_boxes[$this->post_type][$context][$priority] = []; | |
} | |
$wp_meta_boxes[$this->post_type][$context][$priority] = array_merge( | |
$wp_meta_boxes[$this->post_type][$context][$priority], | |
$boxes | |
); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How To Use