Skip to content

Instantly share code, notes, and snippets.

@deviationist
Last active March 17, 2020 16:33
Show Gist options
  • Save deviationist/263ab2a2121d94120b05a9bc5456fa96 to your computer and use it in GitHub Desktop.
Save deviationist/263ab2a2121d94120b05a9bc5456fa96 to your computer and use it in GitHub Desktop.
A class to index all post types on all blogs in a WordPress multi-site setup. This is helpful since function "get_post_types" does not respect multisite functions like "switch_to_blog" etc.
<?php
/**
* Class Multisite_Post_Type_Index
*
* This class creates and index of all the different post types on each blog in a multisite. As of now WordPress does not have a feature to list post types by blog, and hence this hacky but working solution.*
*/
class Multisite_Post_Type_Index {
/**
* The option name we would like to store post types with.
*
* @var string
*/
private $option_name = 'registered_post_types';
/**
* Singleton instance.
*
* @var null
*/
private static $instance = null;
/**
* Instantiate class.
*
* @return Multisite_Post_Type_Index|null
*/
public static function get_instance() {
if ( self::$instance == null ) {
self::$instance = new Multisite_Post_Type_Index;
}
return self::$instance;
}
/**
* Multisite_Post_Type_Index constructor.
*/
private function __construct() {
if ( ! is_multisite() ) return;
add_action( 'registered_post_type', [$this, 'index_multisite_post_types'], 10, 2 );
}
/**
* Index the post type that gets registered.
*
* @param $post_type_name
* @param $post_type_object
*/
public function index_multisite_post_types( $post_type_name, $post_type_object ) {
$registered_post_types = $this->get_post_types();
$blog_id_key = $this->get_current_blog_id_key();
if ( ! $this->should_index_post_type($post_type_object) ) return;
if ( ! array_key_exists($blog_id_key, $registered_post_types) ) $registered_post_types[$blog_id_key] = [];
if ( ! array_key_exists($post_type_name, $registered_post_types[$blog_id_key]) ) {
$registered_post_types[$blog_id_key][$post_type_name] = $this->format_post_type_object($post_type_object);
$this->set_post_types($registered_post_types);
}
}
/**
* Format the post type object before storing it.
*
* @param $post_type_object
*
* @return mixed
*/
private function format_post_type_object($post_type_object) {
return apply_filters('multisite_post_type_index_formatting', $post_type_object);
}
/**
* Get all post types in the multisite.
*
* @param $prefix_post_type_with_blog_id
*
* @return mixed
*/
public function get_all_post_types_in_multisite($prefix_post_type_with_blog_id = false) {
$registered_post_types = $this->get_post_types();
$post_types = [];
foreach ( $registered_post_types as $blog_id => $post_types ) {
foreach ( $post_types as $post_type ) {
$key = ( $prefix_post_type_with_blog_id ? $blog_id . '_' . $post_type : $post_type );
$post_types[$key] = $post_type;
}
}
retun array_unique($post_types);
}
/**
* Get post types by blog Id.
*
* @param $blog_id
*
* @return bool|mixed
*/
public function get_post_types_for_blog($blog_id) {
$registered_post_types = $this->get_post_types();
$blog_id_key = $this->get_blog_id_key($blog_id);
if ( ! array_key_exists($blog_id_key, $registered_post_types) ) {
$post_types = $registered_post_types[$blog_id_key];
if ( is_array($post_types) ) {
$post_types = array_map(function ($post_type) {
return (object) $post_type;
}, $post_types);
return $post_types;
}
}
return false;
}
/**
* Check if we want to index this post type.
*
* @param $post_type_object
*
* @return bool
*/
private function should_index_post_type($post_type_object) {
if ( ! $post_type_object->public ) {
return false;
}
return true;
}
/**
* Get main blog Id.
*
* @return mixed
*/
private function main_blog_id() {
return get_network()->site_id;
}
/**
* Get registered post types.
*
* @return array
*/
private function get_post_types() {
return (array) get_blog_option($this->main_blog_id(), $this->option_name, []);
}
/**
* Set registered post types.
*
* @param $post_types
*
* @return mixed
*/
private function set_post_types($post_types) {
return update_blog_option($this->main_blog_id(), $this->option_name, $post_types);
}
/**
* Clear registered post types.
*/
public function clear_post_types($post_types) {
$this->set_post_types([]);
}
/**
* Get blog key for storage.
*
* @param $blog_id
*
* @return string
*/
private function get_blog_id_key($blog_id) {
return 'blog_' . $blog_id;
}
/**
* Get main blog key for storage.
*
* @return string
*/
private function get_current_blog_id_key() {
return $this->get_blog_id_key(get_current_blog_id());
}
}
Multisite_Post_Type_Index::get_instance();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment