Skip to content

Instantly share code, notes, and snippets.

@gyrus
Created August 16, 2012 16:06
Show Gist options
  • Save gyrus/3371380 to your computer and use it in GitHub Desktop.
Save gyrus/3371380 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: l3rady's CPT Structure Helper
Plugin URI: http://l3rady.com/projects/l3rady-cpt-structure-helper/
Description:
Author: Scott Cariss
Version: 0.2.1
Author URI: http://l3rady.com/
Text Domain: sccptshelper
Domain Path: /languages
*/
/* Copyright 2012 Scott Cariss (email : [email protected])
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Class l3radyCPTStructureHelper
{
private static $registered_cpt = array();
public static function init()
{
add_filter( "page_css_class", array( __CLASS__, "add_active_to_list_pages_for_CPTs" ), 5, 10 );
add_filter( "wp_get_nav_menu_items", array( __CLASS__, "add_active_to_menus_for_CPTs" ), 3, 10 );
add_action( 'admin_init', array( __CLASS__, 'add_cpt_reading_settings' ) );
}
public static function add_active_to_list_pages_for_CPTs( $css_class, $page, $depth, $args, $current_page )
{
if( ! $page_id = self::work_out_local_page() )
return $css_class;
if( ! isset( $page_id ) )
return $css_class;
static $ancestors;
if( ! isset( $ancestors ) )
$ancestors = (array) get_post_ancestors( $page_id );
if( $page->ID == $page_id )
$css_class[] = "current_page_item";
if( $page->ID == end( $ancestors ) )
$css_class[] = "current_page_parent";
if( in_array( $page->ID, $ancestors ) )
$css_class[] = "current_page_ancestor";
return $css_class;
}
public static function add_active_to_menus_for_CPTs( $items, $menu, $args )
{
if( ! $page_id = self::work_out_local_page() )
return $items;
static $ancestors;
if( ! isset( $ancestors ) )
$ancestors = (array) get_post_ancestors( $page_id );
foreach( $items as $key => $item )
{
if( $item->object_id == $page_id )
$items[ $key ]->classes = array_merge( $items[ $key ]->classes, array( "current-menu-item", "current_page_item" ) );
if( $item->object_id == end( $ancestors ) )
$items[ $key ]->classes = array_merge( $items[ $key ]->classes, array( "current-menu-parent", "current_page_parent" ) );
if( in_array( $item->object_id, $ancestors ) )
$items[ $key ]->classes = array_merge( $items[ $key ]->classes, array( "current-menu-ancestor", "current_page_ancestor" ) );
}
return $items;
}
public static function work_out_local_page()
{
if( ! ( is_single() || is_archive() || is_home() ) )
return false;
$settings = self::get_cpt_settings();
$post_type = get_post_type();
if( ! isset( $settings[$post_type] ) )
return false;
else
return $settings[$post_type];
}
public static function get_cpt_settings( )
{
$settings = get_option("sc_cpt_sh_permalinks");
$show_on_front = get_option( 'show_on_front' );
$page_for_posts = get_option( 'page_for_posts' );
if( "page" == $show_on_front && ! empty( $page_for_posts ) )
$settings['post'] = $page_for_posts;
return $settings;
}
/*
* Wrapper for register_post_type(). Use register_post_type_with_page_select() as if you were using
* register_post_type() but if this functions finds a setting to link the CPT to a page then it will adjust
* the slug accordingly. Could do with some enhancement that would allow for more complex structures E.G differences
* between slug and archive.
*/
public static function register_post_type_with_page_select( $post_type, $args )
{
// Get settings that hold links between CPT and page.
$settings = get_option("sc_cpt_sh_permalinks");
// Check if setting exists? If yes then adjust slug accordingly.
if( ! empty( $settings[ $post_type ] ) )
$args['rewrite']['slug'] = self::work_out_cpt_slug_from_page_id( $settings[ $post_type ], $args['rewrite']['slug'] );
self::$registered_cpt[ $post_type ] = ( isset( $args['label'] ) ) ? $args['label'] : $args['labels']['name'];
// Register post type the normal way
register_post_type( $post_type, $args );
}
/*
* Takes ID of a page and works out the full slug of the page including the page hierarchy. E.G. media-centre/news
* If page cannot be found then return $post_type as fallback.
*/
public static function work_out_cpt_slug_from_page_id( $id, $post_type )
{
// Get permalink of selected page ID
$permalink_of_page = get_permalink( $id );
// If fail to get permalink then fall back to using CPT slug
if( ! $permalink_of_page )
return $post_type;
// Return slug of page including the page hierarchy
return ltrim( rtrim( str_replace( home_url(), "", $permalink_of_page ), '/' ), '/' );
}
/*
* Adds to the reading settings page in admin. Will only show settings if some CPTs where registered using
* register_post_type_with_page_select();
*/
public static function add_cpt_reading_settings()
{
if( empty( self::$registered_cpt ) )
return;
register_setting("reading", "sc_cpt_sh_permalinks", array( __CLASS__, "validate_cpt_reading_settings" ) );
add_settings_section("sc_cpt_sh_cpt_reading", __("CPT Reading Settings", "sccptshelper"), array( __CLASS__, "cpt_reading_settings_description" ), "reading");
add_settings_field("sc_cpt_sh_cpt_reading_roots", __("CPT Root Pages", "sccptshelper"), array( __CLASS__, "cpt_reading_settings_roots" ), "reading", "sc_cpt_sh_cpt_reading");
}
/*
* Validates settings for CPT Seading Settings
*/
public static function validate_cpt_reading_settings( $input )
{
$input = array_map( "intval", $input ); // Make sure all values are integer
$input = array_filter( $input, array( __CLASS__, "filter_empty" ) ); // Remove all entries that are empty()
return $input;
}
/*
* Used in array_filter(). Used to remove all key/values that are empty()
*/
public static function filter_empty( $val )
{
return ! empty( $val );
}
public static function cpt_reading_settings_description()
{
echo "Some description to be added at a later date";
}
public static function cpt_reading_settings_roots()
{
$settings = get_option("sc_cpt_sh_permalinks");
foreach( self::$registered_cpt as $cpt_slug => $cpt_name)
{
echo "<p><label>Page for " . $cpt_name . ": ";
wp_dropdown_pages(
array(
'name' => 'sc_cpt_sh_permalinks[' . $cpt_slug . ']',
'echo' => 1,
'show_option_none' => __( '&mdash; Select &mdash;' ),
'option_none_value' => '0',
'selected' => $settings[ $cpt_slug ]
)
);
echo "</label></p>";
}
}
}
l3radyCPTStructureHelper::init();
/*
* API
*/
function sc_cpt_sh_register_post_type( $post_type = '', $args = array() )
{
l3radyCPTStructureHelper::register_post_type_with_page_select( $post_type, $args );
}
function sc_work_out_local_page()
{
return l3radyCPTStructureHelper::work_out_local_page();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment