Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2495 - Metrics - Personal - Gen-Map - Restrict To Records Responsible For #2504

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dt-metrics/records/genmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ jQuery(document).ready(function ($) {
post_type: selected_post_type,
gen_depth_limit: 100,
show_archived: jQuery('#archivedToggle').prop('checked'),
slug: window.dtMetricsProject.base_slug,
};

// Dynamically update URL parameters.
Expand Down
110 changes: 72 additions & 38 deletions dt-metrics/records/genmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,42 @@ public function tree( WP_REST_Request $request ) {
return new WP_Error( __METHOD__, 'Missing parameters! [Required: p2p_type, p2p_direction, post_type ]', [ 'status' => 400 ] );
}

$user = wp_get_current_user();
$post_type = $params['post_type'];
$post_settings = DT_Posts::get_post_settings( $post_type );

// Determine scope of query focus, based on specified slug.
$slug = $params['slug'] ?? 'personal';
$focus_id = $params['focus_id'] ?? 0;
if ( ( $post_type === 'contacts' ) && ( $slug === 'personal' ) ) {
$user_contact_id = Disciple_Tools_Users::get_contact_for_user( $user->ID );
if ( intval( $user_contact_id ) ){
$focus_id = $user_contact_id;
}
}

$filters = [
'slug' => $slug,
'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 );
$can_list_all = current_user_can( 'list_all_' . $post_type );
if ( $post_type === 'contacts' && current_user_can( 'dt_all_access_contacts' ) ){
$can_list_all = true;
}
$generated_genmap = $this->get_genmap( $query, $params['gen_depth_limit'] ?? 100, $focus_id, $filters, $can_list_all );

// Ensure empty hits on personal based slugs, still ensure user node is accessible.
if ( ( $focus_id !== 0 ) && empty( $generated_genmap['children'] ) ) {
$generated_genmap['shared'] = 1;
$generated_genmap['name'] = $user->display_name;
}

return $generated_genmap;
}

public function scripts() {
Expand Down Expand Up @@ -165,42 +189,46 @@ public function get_query( $post_type, $p2p_type, $p2p_direction, $filters = []

// 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,
( 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 (
SELECT DISTINCT (p2p_from)
FROM $wpdb->p2p
WHERE p2p_type = %s
GROUP BY p2p_from
)
AND a.ID %1s IN (
SELECT DISTINCT (p2p_to)
FROM $wpdb->p2p
WHERE p2p_type = %s
GROUP BY p2p_to
)
UNION
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 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, $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;

// Prepare sql shape to be executed.
$prepared_query = $wpdb->prepare( "
SELECT
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 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 (
SELECT DISTINCT (p2p_from)
FROM $wpdb->p2p
WHERE p2p_type = %s
GROUP BY p2p_from
)
AND a.ID %1s IN (
SELECT DISTINCT (p2p_to)
FROM $wpdb->p2p
WHERE p2p_type = %s
GROUP BY p2p_to
)
UNION
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 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, $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 );

//phpcs:disable
return $wpdb->get_results( $prepared_query, ARRAY_A );
//phpcs:enable
}

public function get_genmap( $query, $depth_limit, $focus_id, $filters = [] ) {
public function get_genmap( $query, $depth_limit, $focus_id, $filters = [], $can_list_all = false ){

if ( is_wp_error( $query ) ){
return $this->_circular_structure_error( $query );
Expand All @@ -210,7 +238,9 @@ public function get_genmap( $query, $depth_limit, $focus_id, $filters = [] ) {
}
$menu_data = $this->prepare_menu_array( $query );

return $this->build_array( $focus_id ?? 0, $menu_data, 0, $depth_limit, $filters );
$user_contact_id = Disciple_Tools_Users::get_contact_for_user( get_current_user_id() );

return $this->build_array( $focus_id ?? 0, $menu_data, 0, $depth_limit, $filters, $can_list_all, $user_contact_id );
}

public function prepare_menu_array( $query ) {
Expand All @@ -228,19 +258,23 @@ public function prepare_menu_array( $query ) {
return $menu_data;
}

public function build_array( $parent_id, $menu_data, $gen, $depth_limit, $filters = [] ) {
public function build_array( $parent_id, $menu_data, $gen, $depth_limit, $filters = [], $can_list_all = false, $user_contact_id = null ) {
$children = [];
if ( isset( $menu_data['parents'][$parent_id] ) && ( $gen < $depth_limit ) )
{
$next_gen = $gen + 1;

foreach ( $menu_data['parents'][$parent_id] as $item_id )
{
$children[] = $this->build_array( $item_id, $menu_data, $next_gen, $depth_limit, $filters );
$children[] = $this->build_array( $item_id, $menu_data, $next_gen, $depth_limit, $filters, $can_list_all, $user_contact_id );
}
}

// Ensure to force a record node share for administrators.
$shared = intval( $menu_data['items'][ $parent_id ]['shared'] ?? 0 );
if ( $parent_id === $user_contact_id ){
$shared = 1;
}
$array = [
'id' => $parent_id,
'name' => ( ( $shared === 1 ) || ( $gen === 0 ) ) ? ( $menu_data['items'][ $parent_id ]['name'] ?? 'SYSTEM' ) : '',
Expand Down
Loading