diff --git a/dt-metrics/metrics.php b/dt-metrics/metrics.php index ea56cd849..7fb85fb95 100644 --- a/dt-metrics/metrics.php +++ b/dt-metrics/metrics.php @@ -35,7 +35,10 @@ public function __construct(){ // wait for D.T post type classes to be set up before building metrics for them add_action( 'after_setup_theme', function (){ $modules = dt_get_option( 'dt_post_type_modules' ); + // Personal + require_once( get_template_directory() . '/dt-metrics/records/genmap.php' ); + new DT_Metrics_Groups_Genmap( 'personal', __( 'Personal', 'disciple_tools' ) ); require_once( get_template_directory() . '/dt-metrics/personal/coaching-tree.php' ); require_once( get_template_directory() . '/dt-metrics/personal/baptism-tree.php' ); require_once( get_template_directory() . '/dt-metrics/personal/group-tree.php' ); @@ -76,7 +79,7 @@ public function __construct(){ require_once( get_template_directory() . '/dt-metrics/combined/hover-map.php' ); /* Record Types */ - require_once( get_template_directory() . '/dt-metrics/records/genmap.php' ); + new DT_Metrics_Groups_Genmap( 'records', __( 'Genmap', 'disciple_tools' ) ); require_once( get_template_directory() . '/dt-metrics/records/dynamic-records-map.php' ); } if ( !empty( $modules['access_module']['enabled'] ) ){ diff --git a/dt-metrics/records/genmap.js b/dt-metrics/records/genmap.js index b455c0f98..f8dc99352 100644 --- a/dt-metrics/records/genmap.js +++ b/dt-metrics/records/genmap.js @@ -1,5 +1,9 @@ jQuery(document).ready(function ($) { - if (window.wpApiShare.url_path.startsWith('metrics/records/genmap')) { + if ( + window.wpApiShare.url_path.startsWith( + `metrics/${window.dtMetricsProject.base_slug}/genmap`, + ) + ) { project_records_genmap(); } @@ -10,7 +14,10 @@ jQuery(document).ready(function ($) { let spinner = ' '; chart.empty().html(spinner); - jQuery('#metrics-sidemenu').foundation('down', jQuery('#records-menu')); + jQuery('#metrics-sidemenu').foundation( + 'down', + jQuery(`#${window.dtMetricsProject.base_slug}-menu`), + ); let translations = window.dtMetricsProject.translations; @@ -98,7 +105,11 @@ jQuery(document).ready(function ($) { // Fetch generational map chart. window - .makeRequest('POST', 'metrics/records/genmap', payload) + .makeRequest( + 'POST', + `metrics/${window.dtMetricsProject.base_slug}/genmap`, + payload, + ) .promise() .then((response) => { let container = jQuery('#genmap'); @@ -133,6 +144,39 @@ jQuery(document).ready(function ($) { initCompleted: function (chart) { const post_types = window.dtMetricsProject.post_types; + /** + * Non-Shared Items + */ + + // Identify and obfuscate items not shared with current user. + const non_shared_items = identify_items_by_field_value( + response, + 'shared', + 0, + {}, + ); + + // Obfuscate identified items. + if (non_shared_items) { + for (const [id, item] of Object.entries(non_shared_items)) { + const node = $(chart).find(`#${id}.node`); + if (node) { + const color = '#808080'; + $(node).css('background-color', color); + $(node).find('.title').text('.......'); + $(node).find('.title').css('background-color', color); + $(node).find('.content').css('background-color', color); + $(node).find('.content').css('border', '0px'); + + $(node).data('shared', '0'); + } + } + } + + /** + * Archived Items + */ + // Identify archived items, in order to update corresponding node color. if ( post_types && @@ -174,7 +218,13 @@ jQuery(document).ready(function ($) { let node_id = node.attr('id'); let node_parent_id = node.data('parent'); - open_modal_details(node_id, node_parent_id, selected_post_type); + // Ensure non-shared item nodes are ignored. + const node_shared = node.data('shared'); + if (!node_shared || String(node_shared) !== '0') { + open_modal_details(node_id, node_parent_id, selected_post_type); + } else { + jQuery('#genmap-details').empty(); + } }); }) .catch((error) => { @@ -256,11 +306,12 @@ jQuery(document).ready(function ($) { } function identify_items_by_field_value(data, field, value, items) { - if (data?.[field] === value) { + if (String(data?.[field]) === String(value)) { items[data['id']] = { id: data['id'], name: data['name'], status: data['status'], + shared: data['shared'], }; } diff --git a/dt-metrics/records/genmap.php b/dt-metrics/records/genmap.php index 21e8c89c6..a0f0d2edb 100644 --- a/dt-metrics/records/genmap.php +++ b/dt-metrics/records/genmap.php @@ -3,25 +3,28 @@ exit; } // Exit if accessed directly. - class DT_Metrics_Groups_Genmap extends DT_Metrics_Chart_Base { //slug and title of the top menu folder - public $base_slug = 'records'; // lowercase + public $base_slug; // lowercase public $slug = 'genmap'; // lowercase public $base_title; public $title; public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. - public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics' ]; + public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics', 'multiplier' ]; public $namespace = null; - public function __construct() { - parent::__construct(); + public function __construct( $base_slug, $base_title ) { if ( !$this->has_permission() ){ return; } - $this->base_title = __( 'Genmap', 'disciple_tools' ); - $this->title = __( 'Generation Map', 'disciple_tools' ); + + $this->base_slug = $base_slug; + $this->base_title = $base_title; + + parent::__construct(); + + $this->title = __( 'Generational Trees', 'disciple_tools' ); $url_path = dt_get_url_path( true ); if ( "metrics/$this->base_slug/$this->slug" === $url_path ) { @@ -36,7 +39,7 @@ public function add_api_routes() { $version = '1'; $namespace = 'dt/v' . $version; register_rest_route( - $namespace, '/metrics/records/genmap', [ + $namespace, "/metrics/$this->base_slug/genmap", [ [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => [ $this, 'tree' ], @@ -84,6 +87,7 @@ public function scripts() { wp_localize_script( 'dt_metrics_project_script', 'dtMetricsProject', [ 'root' => esc_url_raw( rest_url() ), + 'base_slug' => $this->base_slug, 'site_url' => esc_url_raw( site_url() ), 'theme_uri' => get_template_directory_uri(), 'nonce' => wp_create_nonce( 'wp_rest' ), @@ -92,7 +96,7 @@ public function scripts() { 'map_key' => empty( DT_Mapbox_API::get_key() ) ? '' : DT_Mapbox_API::get_key(), 'data' => [], 'translations' => [ - 'title' => __( 'Generation Map', 'disciple_tools' ), + 'title' => __( 'Generational Trees', 'disciple_tools' ), 'show_archived' => __( 'Show Archived', 'disciple_tools' ), 'highlight_active' => __( 'Highlight Active', 'disciple_tools' ), 'highlight_churches' => __( 'Highlight Churches', 'disciple_tools' ), @@ -157,6 +161,8 @@ public function get_query( $post_type, $p2p_type, $p2p_direction, $filters = [] $select_parent_id = 'p2p_from'; } + $user = wp_get_current_user(); + // Determine archived meta values. $status_key = $filters['status_key'] ?? ''; $query = $wpdb->get_results( $wpdb->prepare( " @@ -164,7 +170,8 @@ public function get_query( $post_type, $p2p_type, $p2p_direction, $filters = [] a.ID as id, 0 as parent_id, 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 + ( 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, + ( SELECT EXISTS( SELECT p_shared.user_id FROM $wpdb->dt_share as p_shared WHERE p_shared.user_id = %d AND p_shared.post_id = a.ID ) ) as shared FROM $wpdb->posts as a WHERE a.post_type = %s AND a.ID %1s IN ( @@ -184,10 +191,11 @@ public function get_query( $post_type, $p2p_type, $p2p_direction, $filters = [] 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 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 + ( 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, + ( SELECT EXISTS( SELECT u_shared.user_id FROM $wpdb->dt_share as u_shared WHERE u_shared.user_id = %d AND u_shared.post_id = p.%1s ) ) as shared FROM $wpdb->p2p as p WHERE p.p2p_type = %s; - ", $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 ); + ", $status_key, $user->ID, $post_type, $not_from, $p2p_type, $not_to, $p2p_type, $select_id, $select_parent_id, $select_id, $select_id, $status_key, $user->ID, $select_id, $p2p_type ), ARRAY_A ); return $query; } @@ -232,13 +240,18 @@ public function build_array( $parent_id, $menu_data, $gen, $depth_limit, $filter } } + $shared = intval( $menu_data['items'][ $parent_id ]['shared'] ?? 0 ); $array = [ 'id' => $parent_id, - 'name' => $menu_data['items'][ $parent_id ]['name'] ?? 'SYSTEM', + 'name' => ( ( $shared === 1 ) || ( $gen === 0 ) ) ? ( $menu_data['items'][ $parent_id ]['name'] ?? 'SYSTEM' ) : '', 'status' => $menu_data['items'][ $parent_id ]['status'] ?? '', + 'shared' => $shared, 'content' => 'Gen ' . $gen ]; + // Ensure to exclude non-shared generations. + $children = $this->exclude_non_shared_generations( $children ); + // Determine if archived records are to be excluded. if ( !$filters['show_archived'] ) { @@ -294,6 +307,19 @@ public function exclude_archived_children( $children, $archived_key ): array { return $updated_children; } + + public function exclude_non_shared_generations( $children ): array { + $updated_children = []; + foreach ( $children ?? [] as $child ) { + if ( !empty( $child['children'] ) ) { + $child['children'] = $this->exclude_non_shared_generations( $child['children'] ); + } + if ( !empty( $child['children'] ) || ( isset( $child['shared'] ) && intval( $child['shared'] ) === 1 ) ) { + $updated_children[] = $child; + } + } + + return $updated_children; + } } -new DT_Metrics_Groups_Genmap();