initial_static_options = array
(
'has_pro_version' =>0,
'show_opts' =>true,
'show_rating_message'=>true,
'display_tabs' =>false,
'required_role' =>'install_plugins',
'default_managed' =>'singlesite', //network, singlesite, both
);
$this->initial_user_options = array
(
'hierarchy_permalinks_too' => 1,
'custom_post_types' => "post,",
'hierarchy_using' => "query_post", // "query_post" or "modify_post_obj" or "rewrite" (worst case)
);
}
public function __construct_my()
{
add_action( 'registered_post_type', [$this, 'enable_hierarchy_fields'], 123, 2);
add_filter( 'post_type_labels_'.$post_type='post', [$this, 'enable_hierarchy_fields_for_js'], 11, 2);
if($this->opts['hierarchy_permalinks_too']) {
//just example funcs into init
if(is_admin())
add_action('init', array($this, 'init_action'), 777 );
// change permalinks on front-end source links
add_filter('pre_post_link', array($this,'change_permalinks'), 8, 3 );
// DIFFICULT PART: making WP to recoginzed the hierarchied URL-STRUCTURE //
// (modify_post_obj): using "registered_post_type"
// ** "register_post_type_args" almost same as "registered_post_type", but worse (the labels are set as "page" (see output: https://pastebin.com/raw/iVahbbLw ). also, 'rewrite' gives error. (See more details at: https://pastebin.com/raw/0ujkRzLE ) . Also, similar results to "reregister_post" so, i use only this version ( `reregister_post` is worse than `modify_post_obj`. see: https://pastebin.com/raw/9ZabSn0E )
if($this->opts['hierarchy_using'] == 'modify_post_obj'){
add_action('registered_post_type', array($this, 'method__modify_post_obj'), 150 , 2);
}
// (query_post): using "pre_get_posts"
elseif($this->opts['hierarchy_using'] == 'query_post'){
add_filter( 'pre_get_posts', array($this,'method__query') , 888 );
add_action( 'registered_post_type', array($this, 'hierarchy_for_custom_post'), 90 , 2 );
// $this->load_pro();
}
//(rewrite): using "add_rewrite_rule"
elseif($this->opts['hierarchy_using'] == 'rewrite'){
add_action('init', array($this, 'method__rewrite'), 150 );
}
//check if permalinks not enabled
add_action('current_screen', function(){
$screen = get_current_screen();
if ( $screen->base == 'post' ) {
$this->alert_if_not_pretty_permalinks();
}
} );
}
}
// ============================================================================================================== //
// ============================================================================================================== //
public function deactivation_funcs($network_wide){
if ( is_multisite() ) { // && $network_wide
global $wpdb;
$blogs = $wpdb->get_col("SELECT blog_id FROM ". $wpdb->blogs);
foreach ($blogs as $blog_id) {
switch_to_blog($blog_id);
$this->flush_rules_original();
restore_current_blog();
}
}
else {
$this->flush_rules_original();
}
//in activtion could have been: $this->add_rewrites();
}
public function flush_rules_original() {
//$this->update_option_CHOSEN('rewrite_rules', $this->get_option_CHOSEN('rewrite_rules_BACKUPED__AHPTP') );
$this->flush_rules(false);
}
// ============================================================================================================== //
// ============================================================================================================== //
// register_post_type_args //$args['rewrite']['slug']='/';
public function init_action() {
$this->flush_rules_if_needed(__FILE__);
}
// note, with 'registered_post_type' argument $post_type_object is same as $GLOBALS['wp_post_types']['post'], but globalized one (from: wp-includes/post: 1120 ), however, they behave samely
// =====================================================================
// ============== Add PARENT FIELD to POST TYPE support ===========
public function enable_hierarchy_fields($post_type, $post_type_object){
if($post_type== 'post' ){
$post_type_object->hierarchical = true;
$GLOBALS['_wp_post_type_features']['post']['page-attributes']=true;
}
}
public function enable_hierarchy_fields_for_js($labels){
$labels->parent_item_colon='Parent Post';
return $labels;
}
// =====================================================================
// ===================================================
// ============== Start URL hierarchy ===========
// method 1 (seems useless): child posts work, pages (or other things) go to 404
public function method__modify_post_obj($post_type, $post_type_object){
$Type = 'post';
if($post_type==$Type){
$post_type_object->rewrite = array('with_front'=>false, 'slug'=>'/', 'feeds' => 1); // otherwise bugs in class-wp-post-type.php 566 ; [pages] => 1 [feeds] => 1 [ep_mask] => 1
$post_type_object->query_var = 'post'; //'post' or true; without this line, everything goes 404
// at this moment, we cant call that function, so, call later
add_action('init', function(){
// this function causes exactly to finalize everything before. so, it makes hierarchied post to work, but break other post types (page or etc..) to 404
$GLOBALS['wp_post_types']['post']-> add_rewrite_rules(); // ref: https://pastebin.com/raw/3yVg8jXp
// $this->add_rewrite_for_post();
} );
}
}
// method 2 (also, independent)
public function method__query( $query )
{
$pType = 'post';
$q=$query;
if( $q->is_main_query() && !is_admin() ) {
//at first, check if it's attachment, because only attachment meet this rewrite like hierarchied post
if(
true
// needs to be attachement: wp-includes\class-wp-query.php, but everything happens in parse_request(), because of rewrite match, that is attachement
//&& ( (!is_multisite() && $q->is_attachment) || (is_multisite() && !$q->is_attachment) ) )
){
$possible_post_path = trailingslashit( preg_replace_callback('/(.*?)\/((page|feed|rdf|rss|rss2|atom)\/.*)/i', function($matches) { return $matches[1]; } , $this->path_after_blog() ) );
//if seems hierarchied - 2 slashes at least, like: parent/child/
if(substr_count($possible_post_path, "/") >= 2) {
$post=get_page_by_path($possible_post_path, OBJECT, $pType);
if ($post){
// create query
//no need of $q->init();
$q->parse_query( array('post_type'=>array($pType) ) ) ; //better than $q->set('post_type', 'post');
$q->is_home = false;
//$q->is_page = $method_is_page ? true : false;
$q->is_single = true;
$q->is_singular = true;
$q->queried_object_id=$post->ID;
$q->set('page_id',$post->ID);
//add_action('wp', function (){ v($GLOBALS['wp_query']); });
return $q;
}
}
}
}
return $q;
}
public function hierarchy_for_custom_post($post_type, $post_type_object){
$custom_posts = !empty( $this->opts["custom_post_types"] ) ? array_filter( explode(",", $this->opts["custom_post_types"] ) ) : array( 'post');
foreach ($custom_posts as $each_type){
$each_type = trim($each_type);
if($post_type==$each_type){
$post_type_object->hierarchical = true;
}
}
}
/*
// method 2: hierarchy posts work, pages break
// public function method__reregister_post() {
// $Type = 'post';
// $post_obj = get_post_type_object($Type);
// $args_existing = json_decode(json_encode($post_obj), true);
// $args_new = $args_existing;
// $args_new['has_archive'] = true; //
// $args_new['query_var'] = 'post'; // 'post' or true
// $args_new['rewrite'] = array('with_front'=>false, 'slug'=>'/'); // / 'rewrite' => array("ep_mask"=>EP_PERMALINK ...) OR 'permalink_epmask'=>EP_PERMALINK,
//
// register_post_type( $Type, $args_new );
// register_post_type function : https://pastebin.com/raw/3fjqYHPj
// $this->add_rewrite_for_post();
// }
public function method__rewrite(){
add_rewrite_rule( $reg = '([^/]*)/(.*)' , $match='index.php?name=$matches[2]', $priority='top' );
$this->flush_rules_if_needed(__FILE__);
// https://pastebin.com/raw/kvEXCqKQ
//
//add_rewrite_rule($reg, 'index.php?name=$matches[2]', 'top' );
// '([^/]+)/?', //([^/]+) //([^/]*)/(.*)
// add_rewrite_rule( '([^/]*)/(.*)', 'index.php?name=$matches[2]', 'top' );
//$rules = get_option( 'rewrite_rules' );
// if(!is_admin()) { var_dump($rules ); }
// check if our rules are not yet included
if ( false ){
if (! isset( $rules[$reg] ) ) {
// $this->update_option_CHOSEN('rewrite_rules_BACKUPED__AHPTP', $rules );
// https://developer.wordpress.org/reference/functions/add_rewrite_tag/
add_rewrite_rule($reg, 'index.php?name=$matches[2]', 'top' );
//
//add_rewrite_rule('^\/(.*)(\/|?|#|)$', 'index.php?pagename=$matches[1]', 'top');
//add_rewrite_tag( '%postname%', '(.?.+?)', 'pagename=$matches[1]' );
flush_rewrite_rules();
}
}
//these re defaults for new type
// './?$' => string 'index.php?post_type=post' (length=24)
// './feed/(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?post_type=post&feed=$matches[1]' (length=41)
// './(feed|rdf|rss|rss2|atom)/?$' => string 'index.php?post_type=post&feed=$matches[1]' (length=41)
// './page/([0-9]{1,})/?$' => string 'index.php?post_type=post&paged=$matches[1]' (length=42)
}
public function add_rewrite_for_post(){
add_rewrite_rule( $reg = '.+/([^/]+)/?$' , $match='index.php?name=$matches[1]', $priority='top' );
}
*/
// ==================== POST_LINK (WHEN %postname% tags not available yet {after 10'th priority it's available} ) ======================//
//i.e: http://example.com/post_name OR http://example.com/%if_any_additinonal_custom_structural_tag%/post_name
public function change_permalinks( $permalink, $post=false, $leavename=false ) {
$postTypes = !empty($this->opts["custom_post_types"]) ? array_filter(explode(",", $this->opts["custom_post_types"] )) : array('post');
foreach ($postTypes as $each_post_type){
if($post->post_type == $each_post_type){
// return if %postname% tag is not present in the url:
if ( false === strpos( $permalink, '%postname%')) { return $permalink; }
$permalink = $this->remove_extra_slashes('/'. $this->get_parent_slugs($post). '/'. '%postname%' );
}
}
return $permalink;
}
public function get_parent_slugs($post){
$final_SLUGG = '';
if (!empty($post->post_parent)){
$parent_post= get_post($post->post_parent);
while(!empty($parent_post)){
$final_SLUGG = $parent_post->post_name .'/'.$final_SLUGG;
if (!empty($parent_post->post_parent) ) { $parent_post = get_post( $parent_post->post_parent); } else{ break ;}
}
}
return $final_SLUGG;
}
// =========================================================================================================================================== //
public function alert_if_not_pretty_permalinks()
{
if( $this->opts['hierarchy_permalinks_too'] && !get_option('permalink_structure') ){
echo '';
}
}
// =================================== Options page ================================ //
public function opts_page_output()
{
$this->settings_page_part("start");
?>
active_tab=="Options")
{
//if form updated
if(isset($_POST["_wpnonce"]) && check_admin_referer("nonce_".$this->plugin_slug) )
{
$this->opts['hierarchy_permalinks_too'] = !empty($_POST[ $this->plugin_slug ]['hierarchy_permalinks_too']) ;
$this->opts['hierarchy_using'] = sanitize_key($_POST[ $this->plugin_slug ]['hierarchy_using']) ;
$this->opts['custom_post_types'] = trim(sanitize_text_field($_POST[ $this->plugin_slug ]['custom_post_types'])) ;
$this->opts['last_update_time'] = time() ; // need only for flush rules
$this->update_opts();
$this->flush_rules_checkmark(true);
}
?>
Custom Post Type (there are other plugins for it), because Custom Post Type has native support for hierarchy and ideally, it\s better then using default Post Type as hierarchy. However, if you are sure you need this our plugin, go on... )', 'add-hierarchy-parent-to-post'); ?>