I have three custom 'location'
post types which make up a hierarchy of areas:
location1, location2, location3.
location1
is the top level and then location2
and location3
are childeren of each other. For example, location1
might be Buildings, location2
Floors
, and location3
Rooms.
location2
and location3
have metaboxes with fields loc2_parent_location
and loc3_parent_location
respectively. I’m looking to make an array which would populate from custom post types to show like:
Post Type Reference:
location1 > location2 > location3
Echo as:
Building 1
Building 1 > Floor 1
Building 1 > Floor 1 > Room A
Building 1 > Floor 1 > Room B
Building 1 > Floor 2
Building 1 > Floor 3
Building 2
Here is the function I’m working on:
function location_types_query ( $query ) {
// get custom post types
$args = array( 'post_type' => 'location1' );
$args = array( 'post_type' => 'location2' );
$args = array( 'post_type' => 'location3' );
// create hierachy relationships
if ($location2) {
$parent_location = get_post_meta( $post->ID, 'loc2_parent_location', true );
} elseif ($location3) {
$parent_location = get_post_meta( $post->ID, 'loc3_parent_location', true );
} elseif ($location1) {
$parent_location = '';
}
// Run the query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
foreach ($location as $locations)
if (isset($location1)) {
echo $location1;
}
if (isset($location1 && $location2)) {
echo $location1 . '>' . $location2;
}
if (isset($location1 && $location2 && $location3)) {
echo $location1 . '>' . $location2 . '>' . $location3;
}
return array($locations); // output array
endwhile;
endif;
// Reset Post Data
wp_reset_postdata();
}
?>
What should I do to make this function work properly and spit out an array of the fields.
/——————————————————-/
/* Edit 10/23 – Additional Information
/——————————————————-/
@Kaiser – Best way to break this down is as if I am making a real estate property management website. I have the post types like listed above. It’s all dynamic from the options so a user could set up the system to be like above:
Building 1
Building 1 > Floor 1
Building 1 > Floor 1 > Room A
Where “building 1” is a post in cpt location1, “Floor 1” is a post in cpt location2 and “Room A” is a post in cpt location 3.
OR it can be set up like
(location1) > (location2) > (location3) // Post types
Building 1 > Floor 1 > Apartment A // Posts
Building 1 > Floor 1 > Apartment B
Additionally, each post type has a metabox which has values for the details of the location.
For ..
Location 1:
– Location Plan
– Person in charge
Location 2:
– Location Plan
– Person in charge
– Parent Location
Location 3:
– Location Plan
– Person in charge
– Parent Location
I’ve already set up the entire location database for my real estate site. What I now want to do is add a maintenance form on WP’s frontend in a secure member area so tenant’s can submit a maintenance request. I decided to use gravity forms with a multiple select field. I need to populate an array like above to show the different locations in the different buildings, so user can select it and then populate the field like below using the post type array I created for locations:
/*-------------------------------------------------------*/
/* Location
/*-------------------------------------------------------*/
add_filter("gform_pre_render", "gform_prepopluate_populate_location");
add_filter("gform_admin_pre_render", "gform_prepopluate_populate_location");
function gform_prepopluate_populate_location($form){
$querytype = array('location1', 'location2', 'location3')
$formid = 5;
$fieldid = 7;
if($form["id"] != $formid)
return $form;
$posts = query_posts( array( 'post_type' => $querytype ) );
$items = array(); /* Add Blank */
$items[] = array("text" => "", "value" => "");
foreach($posts as $post)
$items[] = array("value" => $post->ID, "text" => $post->post_title);
foreach($form["fields"] as &$field)
if($field["id"] == $fieldid ){
$field["choices"] = $items;
}
return $form;
}
I can then return the form results as a custom post type, say “maintenance_requests” and have the person doing the work (person responsible) view the request on their tablet and click location which pulls up the plan.
It seems that you are looking to accomplish is a simple parent/child relationship with *n levels. I ran into something similar when working on subordinate posts https://github.com/codearachnid/wp-subordinate-post. The way I resolved the hierarchy (and even allowed for deep permalinking was to utilize the post_parent field. Based on your statements it seems like there might be several extra associations such as hooking a (maintenance/sales) person to a floor which would cover multiple room etc. However, to answer you main problem is seems that if you tackle the hierarchy that will solve the relationships in the list?
Thus to spit out the ordered array I’d recommend setting up a looping query for children by parent.
Doing it different
Your problem mainly is a “XY Problem”. You might make your life a lot easier with simply having three post types, one for each building, or just one named “Rooms”. Then assign the different locations (Building/Floor) to them. You can add descriptions to terms and output them in the right place. Much easier and much more the “native” way, as shared things like the same building or floor should be taxonomy terms. By making them hierarchical you can summon rooms under them.
In other words, your “Rooms” get assigned a “Floor” and a “Building”. Or even better (if you want to have the possibility to assign floor plans or whatever additional info that is unique to a floor, then you just assign a single floor that has a parent term with the name of the respective Building name as term.
And the rooms are for example
and the parent term “Building B” can just get called in the context (it’s already connected to the term.
Advantage is that you easily can add stuff like: “Are you searching for …”
which might make it easier to correct mistakes if someone is on the right floor but in the wrong building, etc. Endless possibilities.
Registering the right way
First take a look at
register_taxonomy()
and it’s arguments. You’ll notice that you can add a taxonomy that’shierarchical
as the built in “category” taxonomy is:Important: Make sure you register the taxonomies and the post types to each other right when you register them. Make sure you do so early enough, on
init
on a priority of0
. More info about that here.Doing the
tax_query
Then look at
WP_Query
parameters.You can simply query by multiple post types:
The loop and term ancestors
Then you can loop through your new
$location
loop. Every time you call a post, you can simplyget_ancestors( $termID, $taxonomyName )
to get all ancestors (Building/Floor) for that location.