+
-
+
${window.lodash.escape(translations.title)}
@@ -70,6 +79,7 @@ jQuery(document).ready(function ($) {
.data('p2p_direction'),
post_type: selected_post_type,
gen_depth_limit: 100,
+ show_archived: jQuery('#archivedToggle').prop('checked'),
};
// Dynamically update URL parameters.
@@ -120,6 +130,39 @@ jQuery(document).ready(function ($) {
nodeContent: 'content',
direction: 'l2r',
nodeTemplate: nodeTemplate,
+ initCompleted: function (chart) {
+ const post_types = window.dtMetricsProject.post_types;
+
+ // Identify archived items, in order to update corresponding node color.
+ if (
+ post_types &&
+ post_types[selected_post_type] &&
+ post_types[selected_post_type]?.status_field?.archived_key
+ ) {
+ const archived_items = identify_items_by_field_value(
+ response,
+ 'status',
+ post_types[selected_post_type]['status_field'][
+ 'archived_key'
+ ],
+ {},
+ );
+
+ // Tweak node colouring of identified items; which have been archived.
+ if (archived_items) {
+ for (const [id, item] of Object.entries(archived_items)) {
+ const node = $(chart).find(`#${id}.node`);
+ if (node) {
+ const color = '#808080';
+ $(node).css('background-color', color);
+ $(node).find('.title').css('background-color', color);
+ $(node).find('.content').css('background-color', color);
+ $(node).find('.content').css('border', '0px');
+ }
+ }
+ }
+ }
+ },
});
let container_height = window.innerHeight - 200; // because it is rotated
@@ -206,6 +249,28 @@ jQuery(document).ready(function ($) {
jQuery(document).on('click', '#gen_tree_add_child_but', function (e) {
handle_add_child();
});
+
+ jQuery(document).on('click', '#archivedToggle', function (e) {
+ window.load_genmap();
+ });
+ }
+
+ function identify_items_by_field_value(data, field, value, items) {
+ if (data?.[field] === value) {
+ items[data['id']] = {
+ id: data['id'],
+ name: data['name'],
+ status: data['status'],
+ };
+ }
+
+ if (data?.['children']) {
+ data['children'].forEach(function (item) {
+ items = identify_items_by_field_value(item, field, value, items);
+ });
+ }
+
+ return items;
}
function identify_infinite_loops(data, loops) {
diff --git a/dt-metrics/records/genmap.php b/dt-metrics/records/genmap.php
index 451df082b..21e8c89c6 100644
--- a/dt-metrics/records/genmap.php
+++ b/dt-metrics/records/genmap.php
@@ -57,9 +57,18 @@ public function tree( WP_REST_Request $request ) {
return new WP_Error( __METHOD__, 'Missing parameters! [Required: p2p_type, p2p_direction, post_type ]', [ 'status' => 400 ] );
}
- $query = $this->get_query( $params['post_type'], $params['p2p_type'], $params['p2p_direction'] );
+ $post_type = $params['post_type'];
+ $post_settings = DT_Posts::get_post_settings( $post_type );
- return $this->get_genmap( $query, $params['gen_depth_limit'] ?? 100, $params['focus_id'] ?? 0 );
+ $filters = [
+ 'post_type' => $post_type,
+ 'show_archived' => $params['show_archived'] ?? false,
+ 'status_key' => $post_settings['status_field']['status_key'] ?? '',
+ 'archived_key' => $post_settings['status_field']['archived_key'] ?? ''
+ ];
+ $query = $this->get_query( $post_type, $params['p2p_type'], $params['p2p_direction'], $filters );
+
+ return $this->get_genmap( $query, $params['gen_depth_limit'] ?? 100, $params['focus_id'] ?? 0, $filters );
}
public function scripts() {
@@ -84,6 +93,7 @@ public function scripts() {
'data' => [],
'translations' => [
'title' => __( 'Generation Map', 'disciple_tools' ),
+ 'show_archived' => __( 'Show Archived', 'disciple_tools' ),
'highlight_active' => __( 'Highlight Active', 'disciple_tools' ),
'highlight_churches' => __( 'Highlight Churches', 'disciple_tools' ),
'members' => __( 'Members', 'disciple_tools' ),
@@ -131,7 +141,7 @@ public function scripts() {
wp_enqueue_style( 'orgchart_css', $css_uri, [], filemtime( $css_dir ) );
}
- public function get_query( $post_type, $p2p_type, $p2p_direction ) {
+ public function get_query( $post_type, $p2p_type, $p2p_direction, $filters = [] ) {
global $wpdb;
// p2p direction will govern overall query sql shape.
@@ -147,11 +157,14 @@ public function get_query( $post_type, $p2p_type, $p2p_direction ) {
$select_parent_id = 'p2p_from';
}
+ // Determine archived meta values.
+ $status_key = $filters['status_key'] ?? '';
$query = $wpdb->get_results( $wpdb->prepare( "
SELECT
a.ID as id,
0 as parent_id,
- a.post_title as name
+ a.post_title as name,
+ ( SELECT p_status.meta_value FROM $wpdb->postmeta as p_status WHERE ( p_status.post_id = a.ID ) AND ( p_status.meta_key = %s ) ) as status
FROM $wpdb->posts as a
WHERE a.post_type = %s
AND a.ID %1s IN (
@@ -170,15 +183,16 @@ public function get_query( $post_type, $p2p_type, $p2p_direction ) {
SELECT
p.%1s as id,
p.%1s as parent_id,
- (SELECT sub.post_title FROM $wpdb->posts as sub WHERE sub.ID = p.%1s ) as name
+ (SELECT sub.post_title FROM $wpdb->posts as sub WHERE sub.ID = p.%1s ) as name,
+ ( SELECT u_status.meta_value FROM $wpdb->postmeta as u_status WHERE ( u_status.post_id = p.%1s ) AND ( u_status.meta_key = %s ) ) as status
FROM $wpdb->p2p as p
WHERE p.p2p_type = %s;
- ", $post_type, $not_from, $p2p_type, $not_to, $p2p_type, $select_id, $select_parent_id, $select_id, $p2p_type ), ARRAY_A );
+ ", $status_key, $post_type, $not_from, $p2p_type, $not_to, $p2p_type, $select_id, $select_parent_id, $select_id, $select_id, $status_key, $p2p_type ), ARRAY_A );
return $query;
}
- public function get_genmap( $query, $depth_limit, $focus_id ) {
+ public function get_genmap( $query, $depth_limit, $focus_id, $filters = [] ) {
if ( is_wp_error( $query ) ){
return $this->_circular_structure_error( $query );
@@ -188,7 +202,7 @@ public function get_genmap( $query, $depth_limit, $focus_id ) {
}
$menu_data = $this->prepare_menu_array( $query );
- return $this->build_array( $focus_id ?? 0, $menu_data, 0, $depth_limit );
+ return $this->build_array( $focus_id ?? 0, $menu_data, 0, $depth_limit, $filters );
}
public function prepare_menu_array( $query ) {
@@ -206,7 +220,7 @@ public function prepare_menu_array( $query ) {
return $menu_data;
}
- public function build_array( $parent_id, $menu_data, $gen, $depth_limit ) {
+ public function build_array( $parent_id, $menu_data, $gen, $depth_limit, $filters = [] ) {
$children = [];
if ( isset( $menu_data['parents'][$parent_id] ) && ( $gen < $depth_limit ) )
{
@@ -214,34 +228,72 @@ public function build_array( $parent_id, $menu_data, $gen, $depth_limit ) {
foreach ( $menu_data['parents'][$parent_id] as $item_id )
{
- $children[] = $this->build_array( $item_id, $menu_data, $next_gen, $depth_limit );
+ $children[] = $this->build_array( $item_id, $menu_data, $next_gen, $depth_limit, $filters );
}
}
+
$array = [
'id' => $parent_id,
'name' => $menu_data['items'][ $parent_id ]['name'] ?? 'SYSTEM',
- 'content' => 'Gen ' . $gen,
- 'children' => $children,
- 'has_infinite_loop' => $this->has_infinite_loop( $parent_id, $children )
+ 'status' => $menu_data['items'][ $parent_id ]['status'] ?? '',
+ 'content' => 'Gen ' . $gen
];
+ // Determine if archived records are to be excluded.
+ if ( !$filters['show_archived'] ) {
+
+ // Recursively exclude associated children.
+ $children = $this->exclude_archived_children( $children, $filters['archived_key'] );
+
+ // Only capture node, if active children are still detected; otherwise return empty array.
+ if ( !empty( $children ) ) {
+ $array['children'] = $children;
+ $array['has_infinite_loop'] = $this->has_infinite_loop( $parent_id, $children );
+ } else {
+ $array['children'] = [];
+ $array['has_infinite_loop'] = false;
+ }
+ } else {
+ $array['children'] = $children;
+ $array['has_infinite_loop'] = $this->has_infinite_loop( $parent_id, $children );
+ }
+
return $array;
}
public function has_infinite_loop( $parent_id, $children ): bool {
foreach ( $children ?? [] as $child ) {
- if ( $parent_id === $child['id'] ) {
- return true;
- }
- if ( !empty( $child['children'] ) ) {
- if ( $this->has_infinite_loop( $parent_id, $child['children'] ) ) {
+ if ( isset( $child['id'], $child['children'] ) ) {
+ if ( $parent_id === $child['id'] ){
return true;
}
+ if ( !empty( $child['children'] ) ){
+ if ( $this->has_infinite_loop( $parent_id, $child['children'] ) ){
+ return true;
+ }
+ }
}
}
return false;
}
+
+ public function exclude_archived_children( $children, $archived_key ): array {
+ $updated_children = [];
+ foreach ( $children ?? [] as $child ) {
+ if ( isset( $child['status'] ) && $child['status'] == $archived_key ) {
+ $child['children'] = $this->exclude_archived_children( $child['children'], $archived_key );
+
+ if ( !empty( $child['children'] ) ) {
+ $updated_children[] = $child;
+ }
+ } else {
+ $updated_children[] = $child;
+ }
+ }
+
+ return $updated_children;
+ }
}
new DT_Metrics_Groups_Genmap();