From fb97a60ca65284754864eecf740bdc74f14f7033 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Fri, 19 Jul 2024 13:52:01 +0100 Subject: [PATCH 01/11] Support record maps within personal metrics --- dt-mapping/mapping-queries.php | 42 ++++++------- dt-metrics/metrics.php | 4 +- dt-metrics/records/dynamic-records-map.js | 70 +++++++++++++--------- dt-metrics/records/dynamic-records-map.php | 57 ++++++++++++++---- 4 files changed, 115 insertions(+), 58 deletions(-) diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index 9b02bd4f09..89b4bd8aa7 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -1267,26 +1267,28 @@ public static function query_user_location_grid_totals( $status = null ) { } - private static function format_results( $results, $post_type ){ + private static function format_results( $results, $post_type, $can_list_all = true, $allowed_post_ids = [] ){ $features = []; foreach ( $results as $result ) { - $features[] = array( - 'type' => 'Feature', - 'properties' => array( - 'address' => $result['address'] ?? '', - 'post_id' => $result['post_id'], - 'name' => $result['name'], - 'post_type' => $post_type - ), - 'geometry' => array( - 'type' => 'Point', - 'coordinates' => array( - $result['lng'], - $result['lat'], - 1 + if ( $can_list_all || in_array( $result['post_id'], $allowed_post_ids ) ) { + $features[] = array( + 'type' => 'Feature', + 'properties' => array( + 'address' => $result['address'] ?? '', + 'post_id' => $result['post_id'], + 'name' => $result['name'], + 'post_type' => $post_type ), - ), - ); + 'geometry' => array( + 'type' => 'Point', + 'coordinates' => array( + $result['lng'], + $result['lat'], + 1 + ), + ), + ); + } } $new_data = array( @@ -1336,7 +1338,7 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ $results = $wpdb->get_results( $prepared_query, ARRAY_A ); //phpcs:enable - return self::format_results( $results, $post_type ); + return self::format_results( $results, $post_type, $args['list_all'], $args['assigned_post_ids'] ); } public static function cluster_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ @@ -1360,7 +1362,7 @@ public static function cluster_geojson( $post_type, $query = [], $offset = 0, $l ); //phpcs:enable - return self::format_results( $results, $post_type ); + return self::format_results( $results, $post_type, $query['list_all'], $query['assigned_post_ids'] ); } public static function points_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ @@ -1383,7 +1385,7 @@ public static function points_geojson( $post_type, $query = [], $offset = 0, $li ); //phpcs:enable - return self::format_results( $results, $post_type ); + return self::format_results( $results, $post_type, $query['list_all'], $query['assigned_post_ids'] ); } public static function get_location_grid_meta_label( $location_grid_meta_id ){ diff --git a/dt-metrics/metrics.php b/dt-metrics/metrics.php index e9e60a11dd..55e373ccd9 100644 --- a/dt-metrics/metrics.php +++ b/dt-metrics/metrics.php @@ -39,6 +39,8 @@ public function __construct(){ // 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/records/dynamic-records-map.php' ); + new DT_Metrics_Dynamic_Records_Map( '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' ); @@ -80,7 +82,7 @@ public function __construct(){ /* Record Types */ new DT_Metrics_Groups_Genmap( 'records', __( 'Genmap', 'disciple_tools' ) ); - require_once( get_template_directory() . '/dt-metrics/records/dynamic-records-map.php' ); + new DT_Metrics_Dynamic_Records_Map( 'records', __( 'Records Map', 'disciple_tools' ) ); } if ( !empty( $modules['access_module']['enabled'] ) ){ require_once( get_template_directory() . '/dt-metrics/combined/critical-path.php' ); diff --git a/dt-metrics/records/dynamic-records-map.js b/dt-metrics/records/dynamic-records-map.js index 44660f6c75..506ef9460c 100644 --- a/dt-metrics/records/dynamic-records-map.js +++ b/dt-metrics/records/dynamic-records-map.js @@ -30,6 +30,7 @@ jQuery(document).ready(function ($) { body.offset = offset; body.limit = limit; + body.list_all = mapbox_library_api.obj.settings.can_list_all; let query = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.post_type_rest_url, @@ -1502,13 +1503,15 @@ jQuery(document).ready(function ($) { points_map: { setup: async function () { + let payload = { + post_type: mapbox_library_api.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; let points = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.points_rest_url, - { - post_type: mapbox_library_api.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ); this.load_layer(points); @@ -1645,13 +1648,15 @@ jQuery(document).ready(function ($) { let cluster_map = { default_setup: async function () { + let payload = { + post_type: mapbox_library_api.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; let geojson = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.rest_url, - { - post_type: mapbox_library_api.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ); cluster_map.load_layer(geojson); @@ -1792,13 +1797,15 @@ jQuery(document).ready(function ($) { behind_layer: null, setup: async function (behind_layer = null) { area_map.behind_layer = behind_layer; + let payload = { + post_type: mapbox_library_api.obj.settings.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; area_map.grid_data = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.totals_rest_url, - { - post_type: mapbox_library_api.obj.settings.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ); await area_map.load_layer(); @@ -2051,15 +2058,18 @@ jQuery(document).ready(function ($) { if (details.admin2_grid_id !== null) { jQuery('#admin2_list').html(spinner_html); + let payload = { + grid_id: details.admin2_grid_id, + post_type: mapbox_library_api.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = + mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', mapbox_library_api.obj.settings.list_by_grid_rest_url, - { - grid_id: details.admin2_grid_id, - post_type: mapbox_library_api.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ) .done((list_by_grid) => { @@ -2071,15 +2081,18 @@ jQuery(document).ready(function ($) { }); } else if (details.admin1_grid_id !== null) { jQuery('#admin1_list').html(spinner_html); + let payload = { + grid_id: details.admin1_grid_id, + post_type: mapbox_library_api.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = + mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', mapbox_library_api.obj.settings.list_by_grid_rest_url, - { - grid_id: details.admin1_grid_id, - post_type: mapbox_library_api.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ) .done((list_by_grid) => { @@ -2091,15 +2104,18 @@ jQuery(document).ready(function ($) { }); } else if (details.admin0_grid_id !== null) { jQuery('#admin0_list').html(spinner_html); + let payload = { + grid_id: details.admin0_grid_id, + post_type: mapbox_library_api.post_type, + query: mapbox_library_api.query_args || {}, + }; + payload.query.list_all = + mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', mapbox_library_api.obj.settings.list_by_grid_rest_url, - { - grid_id: details.admin0_grid_id, - post_type: mapbox_library_api.post_type, - query: mapbox_library_api.query_args || {}, - }, + payload, mapbox_library_api.obj.settings.rest_base_url, ) .done((list_by_grid) => { diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index cdc6eb0b4f..62a3a0193e 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -7,7 +7,7 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base { //slug and title of the top menu folder - public $base_slug = 'records'; // lowercase + public $base_slug; // lowercase public $base_title; public $post_type = 'contacts'; public $post_types = []; @@ -18,17 +18,21 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base public $slug = 'dynamic_records_map'; // lowercase public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. public $js_file_name = '/dt-metrics/records/dynamic-records-map.js'; // should be full file name plus extension - public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics' ]; + public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics', 'multiplier' ]; public $namespace = 'dt-metrics/records'; public $base_filter = []; - public function __construct() { - parent::__construct(); + public function __construct( $base_slug, $base_title ) { if ( !$this->has_permission() ){ return; } + + $this->base_slug = $base_slug; + $this->base_title = $base_title; + + parent::__construct(); + $this->title = __( 'Records Map', 'disciple_tools' ); - $this->base_title = __( 'Contacts', 'disciple_tools' ); // Build post types array, ignoring some for now. // TODO: Only select post types with valid location field types! @@ -69,6 +73,8 @@ public function __construct() { if ( "metrics/$this->base_slug/$this->slug" === $url_path ) { add_action( 'wp_enqueue_scripts', [ $this, 'scripts' ], 99 ); } + + $this->namespace = "dt-metrics/$this->base_slug/$this->slug"; add_action( 'rest_api_init', [ $this, 'add_api_routes' ] ); } @@ -101,6 +107,7 @@ public function scripts() { 'map_key' => DT_Mapbox_API::get_key(), 'no_map_key_msg' => _x( 'To view this map, a mapbox key is needed; click here to add.', 'install mapbox key to view map', 'disciple_tools' ), 'map_mirror' => dt_get_location_grid_mirror( true ), + 'can_list_all' => in_array( $this->base_slug, [ 'records' ] ), 'menu_slug' => $this->base_slug, 'post_type' => $this->post_type, 'post_types' => $this->post_type_options, @@ -183,8 +190,14 @@ public function post_type_geojson( WP_REST_Request $request ){ break; } + // Determine if record restriction (listing-all) should take effect. + $params = self::capture_list_all_setting( $params ); + // Execute request query. $response = Disciple_Tools_Mapping_Queries::post_type_geojson( $params['post_type'], $params, $offset, $limit ); + + // Ensure to unset assigned_post_ids for security reasons. + unset( $params['assigned_post_ids'] ); } return [ @@ -202,7 +215,7 @@ public function cluster_geojson( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::cluster_geojson( $post_type, $query ); + return Disciple_Tools_Mapping_Queries::cluster_geojson( $post_type, self::capture_list_all_setting( $query ) ); } @@ -215,7 +228,7 @@ public function get_grid_totals( WP_REST_Request $request ) { $post_type = $params['post_type']; $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - $results = Disciple_Tools_Mapping_Queries::query_location_grid_meta_totals( $post_type, $query ); + $results = Disciple_Tools_Mapping_Queries::query_location_grid_meta_totals( $post_type, self::capture_list_all_setting( $query ) ); $list = []; foreach ( $results as $result ) { @@ -236,7 +249,7 @@ public function get_list_by_grid_id( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::query_under_location_grid_meta_id( $post_type, $grid_id, $query ); + return Disciple_Tools_Mapping_Queries::query_under_location_grid_meta_id( $post_type, $grid_id, self::capture_list_all_setting( $query ) ); } @@ -252,9 +265,33 @@ public function points_geojson( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::points_geojson( $post_type, $query ); + return Disciple_Tools_Mapping_Queries::points_geojson( $post_type, self::capture_list_all_setting( $query ) ); } + private function capture_list_all_setting( $params ) { + if ( !isset( $params['list_all'] ) || !$params['list_all'] ) { + $params['list_all'] = false; + $params['assigned_post_ids'] = self::list_assigned_post_ids( ( ( $params['post_type'] === 'system-users' ) ? 'contacts' : $params['post_type'] ), get_current_user_id() ); + } else { + $params['list_all'] = true; + $params['assigned_post_ids'] = []; + } + + return $params; + } + + private function list_assigned_post_ids( $post_type, $user_id, $fields = [ 'ID' ], $limit = 500000 ): array { + $assigned_posts = DT_Posts::search_viewable_post( $post_type, [ + 'limit' => $limit, + 'fields' => $fields, + 'assigned_to' => [ $user_id ], + 'subassigned' => [ $user_id ], + 'shared_with' => [ $user_id ] + ] ); + + return array_map( function ( $post ) { + return $post->ID; + }, $assigned_posts['posts'] ?? [] ); + } } -new DT_Metrics_Dynamic_Records_Map(); From 1debcc09772a44106f1f6ce32a35c4998eb62fd4 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Tue, 23 Jul 2024 17:27:05 +0100 Subject: [PATCH 02/11] Embedded filter by post id sql + Split local storage cookie across menu slugs --- dt-assets/js/shared-functions.js | 8 +++ dt-mapping/mapping-queries.php | 79 +++++++++++++++------- dt-metrics/records/dynamic-records-map.js | 70 +++++++++++++++---- dt-metrics/records/dynamic-records-map.php | 30 +++----- 4 files changed, 126 insertions(+), 61 deletions(-) diff --git a/dt-assets/js/shared-functions.js b/dt-assets/js/shared-functions.js index 52f80aff23..60c6b0e3a5 100644 --- a/dt-assets/js/shared-functions.js +++ b/dt-assets/js/shared-functions.js @@ -662,6 +662,14 @@ window.SHAREDFUNCTIONS = { window.localStorage.setItem(key, JSON.stringify(json)); } }, + remove_json_from_local_storage(key, path) { + if (path) { + key = path + '_' + key; + } + if (localStorage) { + window.localStorage.removeItem(key); + } + }, createCustomFilter(field, value) { return { fields: [ diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index 89b4bd8aa7..fb77ececf4 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -1267,28 +1267,26 @@ public static function query_user_location_grid_totals( $status = null ) { } - private static function format_results( $results, $post_type, $can_list_all = true, $allowed_post_ids = [] ){ + private static function format_results( $results, $post_type ){ $features = []; foreach ( $results as $result ) { - if ( $can_list_all || in_array( $result['post_id'], $allowed_post_ids ) ) { - $features[] = array( - 'type' => 'Feature', - 'properties' => array( - 'address' => $result['address'] ?? '', - 'post_id' => $result['post_id'], - 'name' => $result['name'], - 'post_type' => $post_type + $features[] = array( + 'type' => 'Feature', + 'properties' => array( + 'address' => $result['address'] ?? '', + 'post_id' => $result['post_id'], + 'name' => $result['name'], + 'post_type' => $post_type + ), + 'geometry' => array( + 'type' => 'Point', + 'coordinates' => array( + $result['lng'], + $result['lat'], + 1 ), - 'geometry' => array( - 'type' => 'Point', - 'coordinates' => array( - $result['lng'], - $result['lat'], - 1 - ), - ), - ); - } + ), + ); } $new_data = array( @@ -1303,34 +1301,65 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ global $wpdb; //phpcs:disable + // Determine if post id filtering should take place. + $post_id_filter_sql = ''; + if ( isset( $args['list_all'], $args['list_all_by_user_id'] ) && !$args['list_all'] ) { + $post_id_filter_sql = $wpdb->prepare( " + SELECT * FROM + ( + SELECT api_p.ID + FROM $wpdb->posts api_p + LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = api_p.ID ) + LEFT JOIN $wpdb->postmeta as field_type ON ( field_type.post_id = api_p.ID AND field_type.meta_key = 'type' ) + WHERE ( + (field_shared_with.user_id IN ( %d )) + OR ((field_type.meta_value = 'access' OR field_type.meta_value = 'user' OR field_type.meta_value = 'access_placeholder') + )) + AND (api_p.post_status = 'publish') + AND api_p.post_type = %s + GROUP BY api_p.ID + LIMIT 0, 50000 + ) AS assigned_post_ids + ", $args['list_all_by_user_id'], ( ( $post_type === 'system-users' ) ? 'contacts' : $post_type ) ); + + if ( isset( $args['field_type'] ) && $args['field_type'] == 'user_select' ) { + $post_id_filter_sql = 'AND (um.meta_value IN ('. $post_id_filter_sql .'))'; + } else { + $post_id_filter_sql = 'AND (p.ID IN ('. $post_id_filter_sql .'))'; + } + } + if ( isset( $args['field_key'], $args['field_type'] ) && in_array( $args['field_type'], [ 'key_select', 'multi_select' ] ) ){ $prepared_query = $wpdb->prepare( " - SELECT p.post_title AS name, lgm.post_id, lgm.lng, lgm.lat + SELECT DISTINCT p.post_title AS name, lgm.post_id, lgm.lng, lgm.lat FROM $wpdb->dt_location_grid_meta AS lgm JOIN $wpdb->posts AS p ON ( p.ID = lgm.post_id ) LEFT JOIN $wpdb->postmeta AS pm ON ( p.ID = pm.post_id ) WHERE lgm.post_type = %s AND (pm.meta_key = %s)" . ( !empty( $args['field_values'] ) ? " AND (pm.meta_value IN (" . dt_array_to_sql( $args['field_values'] ) . "))" : '' ) ." + ". $post_id_filter_sql ." LIMIT %d, %d; ", $post_type, $args['field_key'], $offset, $limit ); } elseif ( isset( $args['field_type'] ) && $args['field_type'] == 'user_select' ){ $prepared_query = $wpdb->prepare(" - SELECT u.display_name AS name, um.meta_value AS post_id, lgm.lng, lgm.lat + SELECT DISTINCT u.display_name AS name, um.meta_value AS post_id, lgm.lng, lgm.lat FROM $wpdb->dt_location_grid_meta AS lgm JOIN $wpdb->users AS u ON ( u.ID = lgm.post_id ) LEFT JOIN $wpdb->usermeta AS um ON ( u.ID = um.user_id AND um.meta_key = %s ) INNER JOIN $wpdb->usermeta AS um_cap ON ( u.ID = um_cap.user_id AND um_cap.meta_key = %s ) WHERE lgm.post_type = %s + ". $post_id_filter_sql ." LIMIT %d, %d; ", ( $wpdb->prefix . 'corresponds_to_contact' ), ( $wpdb->prefix . 'capabilities' ), 'users', $offset, $limit ); } else { $prepared_query = $wpdb->prepare( " - SELECT p.post_title AS name, lgm.post_id, lgm.lng, lgm.lat + SELECT DISTINCT p.post_title AS name, lgm.post_id, lgm.lng, lgm.lat FROM $wpdb->dt_location_grid_meta AS lgm JOIN $wpdb->posts AS p ON ( p.ID = lgm.post_id ) WHERE lgm.post_type = %s + ". $post_id_filter_sql ." LIMIT %d, %d; ", $post_type, $offset, $limit ); } @@ -1338,7 +1367,7 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ $results = $wpdb->get_results( $prepared_query, ARRAY_A ); //phpcs:enable - return self::format_results( $results, $post_type, $args['list_all'], $args['assigned_post_ids'] ); + return self::format_results( $results, $post_type ); } public static function cluster_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ @@ -1362,7 +1391,7 @@ public static function cluster_geojson( $post_type, $query = [], $offset = 0, $l ); //phpcs:enable - return self::format_results( $results, $post_type, $query['list_all'], $query['assigned_post_ids'] ); + return self::format_results( $results, $post_type ); } public static function points_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ @@ -1385,7 +1414,7 @@ public static function points_geojson( $post_type, $query = [], $offset = 0, $li ); //phpcs:enable - return self::format_results( $results, $post_type, $query['list_all'], $query['assigned_post_ids'] ); + return self::format_results( $results, $post_type ); } public static function get_location_grid_meta_label( $location_grid_meta_id ){ diff --git a/dt-metrics/records/dynamic-records-map.js b/dt-metrics/records/dynamic-records-map.js index 506ef9460c..74cb13e297 100644 --- a/dt-metrics/records/dynamic-records-map.js +++ b/dt-metrics/records/dynamic-records-map.js @@ -11,6 +11,7 @@ jQuery(document).ready(function ($) { spinner: null, map_query_layer_payloads: {}, dt_maps_layers_cookie_id: 'dt-maps-layers-cookie', + dt_maps_layers_cookie_id_by_slug: `dt-maps-layers-cookie-${window.dt_mapbox_metrics.settings.menu_slug}`, recursive_load: async function ( body, data = {}, @@ -439,15 +440,25 @@ jQuery(document).ready(function ($) { mapbox_library_api.dt_maps_layers_cookie_id, {}, ); + if (!dt_maps_layers_cookie) { + dt_maps_layers_cookie = + window.SHAREDFUNCTIONS.get_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, + {}, + ); + } if (!dt_maps_layers_cookie) { dt_maps_layers_cookie = {}; } dt_maps_layers_cookie['' + response.request.id] = cookie; window.SHAREDFUNCTIONS.save_json_to_local_storage( - mapbox_library_api.dt_maps_layers_cookie_id, + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, dt_maps_layers_cookie, null, ); + window.SHAREDFUNCTIONS.remove_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id, + ); // Adjust all map layer points. mapbox_library_api.adjust_layer_point_sizes(); @@ -502,16 +513,26 @@ jQuery(document).ready(function ($) { mapbox_library_api.dt_maps_layers_cookie_id, {}, ); + if (!dt_maps_layers_cookie) { + dt_maps_layers_cookie = + window.SHAREDFUNCTIONS.get_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, + {}, + ); + } if (!dt_maps_layers_cookie) { dt_maps_layers_cookie = {}; } dt_maps_layers_cookie['' + layer_id] = map_query_layer_payload; window.SHAREDFUNCTIONS.save_json_to_local_storage( - mapbox_library_api.dt_maps_layers_cookie_id, + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, dt_maps_layers_cookie, null, ); + window.SHAREDFUNCTIONS.remove_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id, + ); // Close layer records edit modal. $('#add_records_div').fadeOut('fast'); @@ -545,14 +566,24 @@ jQuery(document).ready(function ($) { window.SHAREDFUNCTIONS.get_json_from_local_storage( mapbox_library_api.dt_maps_layers_cookie_id, ); + if (!dt_maps_layers_cookie) { + dt_maps_layers_cookie = + window.SHAREDFUNCTIONS.get_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, + {}, + ); + } if (dt_maps_layers_cookie['' + map_query_layer_payload.id]) { delete dt_maps_layers_cookie['' + map_query_layer_payload.id]; window.SHAREDFUNCTIONS.save_json_to_local_storage( - mapbox_library_api.dt_maps_layers_cookie_id, + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, dt_maps_layers_cookie, null, ); + window.SHAREDFUNCTIONS.remove_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id, + ); } // Remove from map memory. @@ -635,12 +666,22 @@ jQuery(document).ready(function ($) { window.SHAREDFUNCTIONS.get_json_from_local_storage( mapbox_library_api.dt_maps_layers_cookie_id, ); + if (!dt_maps_layers_cookie) { + dt_maps_layers_cookie = + window.SHAREDFUNCTIONS.get_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, + {}, + ); + } dt_maps_layers_cookie['' + div_layer_id] = layer_settings; window.SHAREDFUNCTIONS.save_json_to_local_storage( - mapbox_library_api.dt_maps_layers_cookie_id, + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, dt_maps_layers_cookie, null, ); + window.SHAREDFUNCTIONS.remove_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id, + ); } break; } @@ -700,6 +741,13 @@ jQuery(document).ready(function ($) { mapbox_library_api.dt_maps_layers_cookie_id, false, ); + if (!dt_maps_layers_cookie) { + dt_maps_layers_cookie = + window.SHAREDFUNCTIONS.get_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, + false, + ); + } // Convert parent object to array of layer objects. let layer_cookies = []; @@ -730,10 +778,13 @@ jQuery(document).ready(function ($) { dt_maps_layers_cookie = {}; dt_maps_layers_cookie['' + default_cookie['id']] = default_cookie; window.SHAREDFUNCTIONS.save_json_to_local_storage( - mapbox_library_api.dt_maps_layers_cookie_id, + mapbox_library_api.dt_maps_layers_cookie_id_by_slug, dt_maps_layers_cookie, null, ); + window.SHAREDFUNCTIONS.remove_json_from_local_storage( + mapbox_library_api.dt_maps_layers_cookie_id, + ); // Force a reload. reload_data = true; @@ -1507,7 +1558,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; let points = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.points_rest_url, @@ -1652,7 +1702,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; let geojson = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.rest_url, @@ -1801,7 +1850,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.obj.settings.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = mapbox_library_api.obj.settings.can_list_all; area_map.grid_data = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.totals_rest_url, @@ -2063,8 +2111,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = - mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', @@ -2086,8 +2132,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = - mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', @@ -2109,8 +2153,6 @@ jQuery(document).ready(function ($) { post_type: mapbox_library_api.post_type, query: mapbox_library_api.query_args || {}, }; - payload.query.list_all = - mapbox_library_api.obj.settings.can_list_all; window .makeRequest( 'POST', diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index 62a3a0193e..5f6427f70c 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -196,8 +196,8 @@ public function post_type_geojson( WP_REST_Request $request ){ // Execute request query. $response = Disciple_Tools_Mapping_Queries::post_type_geojson( $params['post_type'], $params, $offset, $limit ); - // Ensure to unset assigned_post_ids for security reasons. - unset( $params['assigned_post_ids'] ); + // Ensure to unset list_all_by_user_id for security reasons. + unset( $params['list_all_by_user_id'] ); } return [ @@ -215,7 +215,7 @@ public function cluster_geojson( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::cluster_geojson( $post_type, self::capture_list_all_setting( $query ) ); + return Disciple_Tools_Mapping_Queries::cluster_geojson( $post_type, $query ); } @@ -228,7 +228,7 @@ public function get_grid_totals( WP_REST_Request $request ) { $post_type = $params['post_type']; $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - $results = Disciple_Tools_Mapping_Queries::query_location_grid_meta_totals( $post_type, self::capture_list_all_setting( $query ) ); + $results = Disciple_Tools_Mapping_Queries::query_location_grid_meta_totals( $post_type, $query ); $list = []; foreach ( $results as $result ) { @@ -249,7 +249,7 @@ public function get_list_by_grid_id( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::query_under_location_grid_meta_id( $post_type, $grid_id, self::capture_list_all_setting( $query ) ); + return Disciple_Tools_Mapping_Queries::query_under_location_grid_meta_id( $post_type, $grid_id, $query ); } @@ -265,33 +265,19 @@ public function points_geojson( WP_REST_Request $request ) { $query = ( isset( $params['query'] ) && !empty( $params['query'] ) ) ? $params['query'] : []; $query = dt_array_merge_recursive_distinct( $query, $this->base_filter ); - return Disciple_Tools_Mapping_Queries::points_geojson( $post_type, self::capture_list_all_setting( $query ) ); + return Disciple_Tools_Mapping_Queries::points_geojson( $post_type, $query ); } private function capture_list_all_setting( $params ) { if ( !isset( $params['list_all'] ) || !$params['list_all'] ) { $params['list_all'] = false; - $params['assigned_post_ids'] = self::list_assigned_post_ids( ( ( $params['post_type'] === 'system-users' ) ? 'contacts' : $params['post_type'] ), get_current_user_id() ); + $params['list_all_by_user_id'] = get_current_user_id(); } else { $params['list_all'] = true; - $params['assigned_post_ids'] = []; + $params['list_all_by_user_id'] = null; } return $params; } - private function list_assigned_post_ids( $post_type, $user_id, $fields = [ 'ID' ], $limit = 500000 ): array { - $assigned_posts = DT_Posts::search_viewable_post( $post_type, [ - 'limit' => $limit, - 'fields' => $fields, - 'assigned_to' => [ $user_id ], - 'subassigned' => [ $user_id ], - 'shared_with' => [ $user_id ] - ] ); - - return array_map( function ( $post ) { - return $post->ID; - }, $assigned_posts['posts'] ?? [] ); - } - } From 0a9505154a78f02dc2a55d299f567475181ef25d Mon Sep 17 00:00:00 2001 From: kodinkat Date: Tue, 6 Aug 2024 16:22:14 +0100 Subject: [PATCH 03/11] Updated sql to ensure only shared records are returned --- dt-mapping/mapping-queries.php | 115 +++++++++++++++++---------------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index fb77ececf4..d9922e17c0 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -36,7 +36,7 @@ public static function get_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_by_grid_id', $results, $grid_id ); @@ -77,7 +77,7 @@ public static function get_parent_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_parent_by_grid_id', $results, $grid_id ); @@ -117,7 +117,7 @@ public static function get_children_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_children_by_grid_id', $results, $grid_id ); @@ -129,7 +129,7 @@ public static function get_by_grid_id_list( $list, $short = false ) { global $wpdb; if ( empty( $list ) ) { - return []; + return array(); } $prepared_list = dt_array_to_sql( $list ); @@ -179,7 +179,7 @@ public static function get_by_grid_id_list( $list, $short = false ) { // phpcs:enable if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -247,7 +247,7 @@ public static function get_countries( $ids_only = false ) { } if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -338,7 +338,7 @@ public static function get_hierarchy( $grid_id = null ) { } if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_hierarchy', $results, $grid_id ); @@ -391,7 +391,7 @@ public static function get_drilldown_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_drilldown_by_grid_id', $results, $grid_id ); @@ -435,7 +435,7 @@ public static function get_regions() { // ", ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_regions', $results ); @@ -470,7 +470,7 @@ public static function get_continents() { // ", ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -501,7 +501,7 @@ public static function get_earth() { ", ARRAY_A ); if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -552,7 +552,7 @@ public static function counter() { "); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'counter', $results ); @@ -566,7 +566,7 @@ public static function counter() { * Count post types, churches and groups in each used location and across admin levels * @todo rewrite. user is no longer found here and these are listing milstones */ - public static function get_location_grid_totals_on_field( $post_type, $field, $force_refresh = false ) : array { + public static function get_location_grid_totals_on_field( $post_type, $field, $force_refresh = false ): array { global $wpdb; @@ -653,7 +653,7 @@ public static function get_location_grid_totals_on_field( $post_type, $field, $f if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -663,7 +663,7 @@ public static function get_location_grid_totals_on_field( $post_type, $field, $f /** * Count post types, churches and groups in each used location and across admin levels */ - public static function get_location_grid_totals() : array { + public static function get_location_grid_totals(): array { global $wpdb; @@ -766,7 +766,7 @@ public static function get_location_grid_totals() : array { if ( empty( $results ) ) { - $results = []; + $results = array(); } return $results; @@ -804,7 +804,7 @@ public static function get_location_grid_totals_for_countries() { if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'get_location_grid_totals_for_countries', $results ); @@ -812,7 +812,7 @@ public static function get_location_grid_totals_for_countries() { return $results; } - public static function active_admin0_grid_ids() : array { + public static function active_admin0_grid_ids(): array { if ( wp_cache_get( 'active_admin0_grid_ids' ) ) { return wp_cache_get( 'active_admin0_grid_ids' ); @@ -829,7 +829,7 @@ public static function active_admin0_grid_ids() : array { "); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'active_admin0_grid_ids', $results ); @@ -837,7 +837,7 @@ public static function active_admin0_grid_ids() : array { return $results; } - public static function active_admin1_grid_ids() : array { + public static function active_admin1_grid_ids(): array { if ( wp_cache_get( 'active_admin1_grid_ids' ) ) { return wp_cache_get( 'active_admin1_grid_ids' ); @@ -854,7 +854,7 @@ public static function active_admin1_grid_ids() : array { "); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'active_admin1_grid_ids', $results ); @@ -862,7 +862,7 @@ public static function active_admin1_grid_ids() : array { return $results; } - public static function active_admin2_grid_ids() : array { + public static function active_admin2_grid_ids(): array { if ( wp_cache_get( 'active_admin2_grid_ids' ) ) { return wp_cache_get( 'active_admin2_grid_ids' ); @@ -879,7 +879,7 @@ public static function active_admin2_grid_ids() : array { "); if ( empty( $results ) ) { - $results = []; + $results = array(); } wp_cache_set( 'active_admin2_grid_ids', $results ); @@ -983,10 +983,10 @@ public static function search_location_grid_by_name( $args ) { // phpcs:enable $total_rows = $wpdb->get_var( 'SELECT found_rows();' ); - return [ + return array( 'location_grid' => $location_grid, - 'total' => $total_rows - ]; + 'total' => $total_rows, + ); } public static function search_used_location_grid_by_name( $args ) { @@ -1025,10 +1025,10 @@ public static function search_used_location_grid_by_name( $args ) { ARRAY_A ); $total_rows = $wpdb->get_var( 'SELECT found_rows();' ); - return [ + return array( 'location_grid' => $location_grid, - 'total' => $total_rows - ]; + 'total' => $total_rows, + ); } public static function get_names_from_ids( $location_grid_ids ) { @@ -1043,7 +1043,7 @@ public static function get_names_from_ids( $location_grid_ids ) { WHERE grid_id IN ( $ids ) ", ARRAY_A ); // phpcs:enable - $prepared = []; + $prepared = array(); foreach ( $results as $row ){ $prepared[$row['grid_id']] = $row['alt_name']; } @@ -1053,13 +1053,13 @@ public static function get_names_from_ids( $location_grid_ids ) { public static function get_location_grid_ids_and_names_for_post_ids( $post_ids ) { global $wpdb; - $prepared = []; + $prepared = array(); foreach ( $post_ids as $post_id ) { - $prepared[$post_id] = []; + $prepared[$post_id] = array(); } if ( empty( $post_ids ) ){ - return []; + return array(); } $joined_post_ids = dt_array_to_sql( $post_ids ); // phpcs:disable @@ -1081,16 +1081,16 @@ public static function get_location_grid_ids_and_names_for_post_ids( $post_ids ) WHERE grid_id IN ( $joined_location_grid_ids ) ", ARRAY_A ); // phpcs:enable - $mapped_location_grid_id_to_name = []; + $mapped_location_grid_id_to_name = array(); foreach ( $location_grid_id_names as $location_grid ){ $mapped_location_grid_id_to_name[$location_grid['grid_id']] = $location_grid['alt_name']; } foreach ( $location_grids as $location_grid ){ if ( isset( $mapped_location_grid_id_to_name[$location_grid['meta_value']] ) ){ - $prepared[$location_grid['post_id']][] = [ + $prepared[$location_grid['post_id']][] = array( 'location_grid_id' => $location_grid['meta_value'], - 'name' => $mapped_location_grid_id_to_name[$location_grid['meta_value']] - ]; + 'name' => $mapped_location_grid_id_to_name[$location_grid['meta_value']], + ); } } return $prepared; @@ -1256,7 +1256,7 @@ public static function query_user_location_grid_totals( $status = null ) { ", $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid' ), ARRAY_A ); } - $list = []; + $list = array(); if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1268,7 +1268,7 @@ public static function query_user_location_grid_totals( $status = null ) { private static function format_results( $results, $post_type ){ - $features = []; + $features = array(); foreach ( $results as $result ) { $features[] = array( 'type' => 'Feature', @@ -1276,14 +1276,14 @@ private static function format_results( $results, $post_type ){ 'address' => $result['address'] ?? '', 'post_id' => $result['post_id'], 'name' => $result['name'], - 'post_type' => $post_type + 'post_type' => $post_type, ), 'geometry' => array( 'type' => 'Point', 'coordinates' => array( $result['lng'], $result['lat'], - 1 + 1, ), ), ); @@ -1297,36 +1297,37 @@ private static function format_results( $results, $post_type ){ return $new_data; } - public static function post_type_geojson( $post_type, $args = [], $offset = 0, $limit = 50000 ){ + public static function post_type_geojson( $post_type, $args = array(), $offset = 0, $limit = 50000 ){ global $wpdb; //phpcs:disable // Determine if post id filtering should take place. $post_id_filter_sql = ''; + $shared_user_join_sql = ''; + $shared_user_condition_sql = ''; if ( isset( $args['list_all'], $args['list_all_by_user_id'] ) && !$args['list_all'] ) { $post_id_filter_sql = $wpdb->prepare( " SELECT * FROM ( SELECT api_p.ID FROM $wpdb->posts api_p - LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = api_p.ID ) LEFT JOIN $wpdb->postmeta as field_type ON ( field_type.post_id = api_p.ID AND field_type.meta_key = 'type' ) - WHERE ( - (field_shared_with.user_id IN ( %d )) - OR ((field_type.meta_value = 'access' OR field_type.meta_value = 'user' OR field_type.meta_value = 'access_placeholder') - )) + WHERE (field_type.meta_value = 'access' OR field_type.meta_value = 'user' OR field_type.meta_value = 'access_placeholder') AND (api_p.post_status = 'publish') AND api_p.post_type = %s GROUP BY api_p.ID LIMIT 0, 50000 ) AS assigned_post_ids - ", $args['list_all_by_user_id'], ( ( $post_type === 'system-users' ) ? 'contacts' : $post_type ) ); + ", ( ( $post_type === 'system-users' ) ? 'contacts' : $post_type ) ); if ( isset( $args['field_type'] ) && $args['field_type'] == 'user_select' ) { + $shared_user_join_sql = "LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = um.meta_value )"; $post_id_filter_sql = 'AND (um.meta_value IN ('. $post_id_filter_sql .'))'; } else { + $shared_user_join_sql = "LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = p.ID )"; $post_id_filter_sql = 'AND (p.ID IN ('. $post_id_filter_sql .'))'; } + $shared_user_condition_sql = "AND (field_shared_with.user_id = ". $args['list_all_by_user_id'] .")"; } if ( isset( $args['field_key'], $args['field_type'] ) && in_array( $args['field_type'], [ 'key_select', 'multi_select' ] ) ){ @@ -1335,7 +1336,9 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ FROM $wpdb->dt_location_grid_meta AS lgm JOIN $wpdb->posts AS p ON ( p.ID = lgm.post_id ) LEFT JOIN $wpdb->postmeta AS pm ON ( p.ID = pm.post_id ) + ". $shared_user_join_sql ." WHERE lgm.post_type = %s + ". $shared_user_condition_sql ." AND (pm.meta_key = %s)" . ( !empty( $args['field_values'] ) ? " AND (pm.meta_value IN (" . dt_array_to_sql( $args['field_values'] ) . "))" : '' ) ." ". $post_id_filter_sql ." LIMIT %d, %d; @@ -1348,7 +1351,9 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ JOIN $wpdb->users AS u ON ( u.ID = lgm.post_id ) LEFT JOIN $wpdb->usermeta AS um ON ( u.ID = um.user_id AND um.meta_key = %s ) INNER JOIN $wpdb->usermeta AS um_cap ON ( u.ID = um_cap.user_id AND um_cap.meta_key = %s ) + ". $shared_user_join_sql ." WHERE lgm.post_type = %s + ". $shared_user_condition_sql ." ". $post_id_filter_sql ." LIMIT %d, %d; ", ( $wpdb->prefix . 'corresponds_to_contact' ), ( $wpdb->prefix . 'capabilities' ), 'users', $offset, $limit ); @@ -1358,7 +1363,9 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ SELECT DISTINCT p.post_title AS name, lgm.post_id, lgm.lng, lgm.lat FROM $wpdb->dt_location_grid_meta AS lgm JOIN $wpdb->posts AS p ON ( p.ID = lgm.post_id ) + ". $shared_user_join_sql ." WHERE lgm.post_type = %s + ". $shared_user_condition_sql ." ". $post_id_filter_sql ." LIMIT %d, %d; ", $post_type, $offset, $limit ); @@ -1370,7 +1377,7 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ return self::format_results( $results, $post_type ); } - public static function cluster_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ + public static function cluster_geojson( $post_type, $query = array(), $offset = 0, $limit = 50000 ){ global $wpdb; $sql = DT_Posts::fields_to_sql( $post_type, $query ); if ( empty( $sql['where_sql'] ) ){ @@ -1394,7 +1401,7 @@ public static function cluster_geojson( $post_type, $query = [], $offset = 0, $l return self::format_results( $results, $post_type ); } - public static function points_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ + public static function points_geojson( $post_type, $query = array(), $offset = 0, $limit = 50000 ){ global $wpdb; $sql = DT_Posts::fields_to_sql( $post_type, $query ); if ( empty( $sql['where_sql'] ) ){ @@ -1510,7 +1517,7 @@ public static function query_location_grid_meta_totals( $post_type, $query ) { //phpcs:enable - $list = []; + $list = array(); if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1743,7 +1750,7 @@ public static function query_contacts_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = []; + $list = array(); if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1897,7 +1904,7 @@ public static function query_groups_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = []; + $list = array(); if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -2063,7 +2070,7 @@ public static function query_church_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = []; + $list = array(); if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; From 74880150196e37ec0e02b282c736eee0a2f044c4 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Mon, 12 Aug 2024 13:54:17 +0100 Subject: [PATCH 04/11] Resolved auto formatting issue --- dt-mapping/mapping-queries.php | 92 +++++++++++++++++----------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index d9922e17c0..65c4eeccf0 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -36,7 +36,7 @@ public static function get_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_by_grid_id', $results, $grid_id ); @@ -77,7 +77,7 @@ public static function get_parent_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_parent_by_grid_id', $results, $grid_id ); @@ -117,7 +117,7 @@ public static function get_children_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_children_by_grid_id', $results, $grid_id ); @@ -129,7 +129,7 @@ public static function get_by_grid_id_list( $list, $short = false ) { global $wpdb; if ( empty( $list ) ) { - return array(); + return []; } $prepared_list = dt_array_to_sql( $list ); @@ -179,7 +179,7 @@ public static function get_by_grid_id_list( $list, $short = false ) { // phpcs:enable if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -247,7 +247,7 @@ public static function get_countries( $ids_only = false ) { } if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -338,7 +338,7 @@ public static function get_hierarchy( $grid_id = null ) { } if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_hierarchy', $results, $grid_id ); @@ -391,7 +391,7 @@ public static function get_drilldown_by_grid_id( $grid_id ) { ", $grid_id ), ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_drilldown_by_grid_id', $results, $grid_id ); @@ -435,7 +435,7 @@ public static function get_regions() { // ", ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_regions', $results ); @@ -470,7 +470,7 @@ public static function get_continents() { // ", ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -501,7 +501,7 @@ public static function get_earth() { ", ARRAY_A ); if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -552,7 +552,7 @@ public static function counter() { "); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'counter', $results ); @@ -566,7 +566,7 @@ public static function counter() { * Count post types, churches and groups in each used location and across admin levels * @todo rewrite. user is no longer found here and these are listing milstones */ - public static function get_location_grid_totals_on_field( $post_type, $field, $force_refresh = false ): array { + public static function get_location_grid_totals_on_field( $post_type, $field, $force_refresh = false ) : array { global $wpdb; @@ -653,7 +653,7 @@ public static function get_location_grid_totals_on_field( $post_type, $field, $f if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -663,7 +663,7 @@ public static function get_location_grid_totals_on_field( $post_type, $field, $f /** * Count post types, churches and groups in each used location and across admin levels */ - public static function get_location_grid_totals(): array { + public static function get_location_grid_totals() : array { global $wpdb; @@ -766,7 +766,7 @@ public static function get_location_grid_totals(): array { if ( empty( $results ) ) { - $results = array(); + $results = []; } return $results; @@ -804,7 +804,7 @@ public static function get_location_grid_totals_for_countries() { if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'get_location_grid_totals_for_countries', $results ); @@ -812,7 +812,7 @@ public static function get_location_grid_totals_for_countries() { return $results; } - public static function active_admin0_grid_ids(): array { + public static function active_admin0_grid_ids() : array { if ( wp_cache_get( 'active_admin0_grid_ids' ) ) { return wp_cache_get( 'active_admin0_grid_ids' ); @@ -829,7 +829,7 @@ public static function active_admin0_grid_ids(): array { "); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'active_admin0_grid_ids', $results ); @@ -837,7 +837,7 @@ public static function active_admin0_grid_ids(): array { return $results; } - public static function active_admin1_grid_ids(): array { + public static function active_admin1_grid_ids() : array { if ( wp_cache_get( 'active_admin1_grid_ids' ) ) { return wp_cache_get( 'active_admin1_grid_ids' ); @@ -854,7 +854,7 @@ public static function active_admin1_grid_ids(): array { "); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'active_admin1_grid_ids', $results ); @@ -862,7 +862,7 @@ public static function active_admin1_grid_ids(): array { return $results; } - public static function active_admin2_grid_ids(): array { + public static function active_admin2_grid_ids() : array { if ( wp_cache_get( 'active_admin2_grid_ids' ) ) { return wp_cache_get( 'active_admin2_grid_ids' ); @@ -879,7 +879,7 @@ public static function active_admin2_grid_ids(): array { "); if ( empty( $results ) ) { - $results = array(); + $results = []; } wp_cache_set( 'active_admin2_grid_ids', $results ); @@ -983,10 +983,10 @@ public static function search_location_grid_by_name( $args ) { // phpcs:enable $total_rows = $wpdb->get_var( 'SELECT found_rows();' ); - return array( + return [ 'location_grid' => $location_grid, - 'total' => $total_rows, - ); + 'total' => $total_rows + ]; } public static function search_used_location_grid_by_name( $args ) { @@ -1025,10 +1025,10 @@ public static function search_used_location_grid_by_name( $args ) { ARRAY_A ); $total_rows = $wpdb->get_var( 'SELECT found_rows();' ); - return array( + return [ 'location_grid' => $location_grid, - 'total' => $total_rows, - ); + 'total' => $total_rows + ]; } public static function get_names_from_ids( $location_grid_ids ) { @@ -1043,7 +1043,7 @@ public static function get_names_from_ids( $location_grid_ids ) { WHERE grid_id IN ( $ids ) ", ARRAY_A ); // phpcs:enable - $prepared = array(); + $prepared = []; foreach ( $results as $row ){ $prepared[$row['grid_id']] = $row['alt_name']; } @@ -1053,13 +1053,13 @@ public static function get_names_from_ids( $location_grid_ids ) { public static function get_location_grid_ids_and_names_for_post_ids( $post_ids ) { global $wpdb; - $prepared = array(); + $prepared = []; foreach ( $post_ids as $post_id ) { - $prepared[$post_id] = array(); + $prepared[$post_id] = []; } if ( empty( $post_ids ) ){ - return array(); + return []; } $joined_post_ids = dt_array_to_sql( $post_ids ); // phpcs:disable @@ -1081,16 +1081,16 @@ public static function get_location_grid_ids_and_names_for_post_ids( $post_ids ) WHERE grid_id IN ( $joined_location_grid_ids ) ", ARRAY_A ); // phpcs:enable - $mapped_location_grid_id_to_name = array(); + $mapped_location_grid_id_to_name = []; foreach ( $location_grid_id_names as $location_grid ){ $mapped_location_grid_id_to_name[$location_grid['grid_id']] = $location_grid['alt_name']; } foreach ( $location_grids as $location_grid ){ if ( isset( $mapped_location_grid_id_to_name[$location_grid['meta_value']] ) ){ - $prepared[$location_grid['post_id']][] = array( + $prepared[$location_grid['post_id']][] = [ 'location_grid_id' => $location_grid['meta_value'], - 'name' => $mapped_location_grid_id_to_name[$location_grid['meta_value']], - ); + 'name' => $mapped_location_grid_id_to_name[$location_grid['meta_value']] + ]; } } return $prepared; @@ -1256,7 +1256,7 @@ public static function query_user_location_grid_totals( $status = null ) { ", $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid', $wpdb->prefix . 'location_grid' ), ARRAY_A ); } - $list = array(); + $list = []; if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1268,7 +1268,7 @@ public static function query_user_location_grid_totals( $status = null ) { private static function format_results( $results, $post_type ){ - $features = array(); + $features = []; foreach ( $results as $result ) { $features[] = array( 'type' => 'Feature', @@ -1297,7 +1297,7 @@ private static function format_results( $results, $post_type ){ return $new_data; } - public static function post_type_geojson( $post_type, $args = array(), $offset = 0, $limit = 50000 ){ + public static function post_type_geojson( $post_type, $args = [], $offset = 0, $limit = 50000 ){ global $wpdb; //phpcs:disable @@ -1377,7 +1377,7 @@ public static function post_type_geojson( $post_type, $args = array(), $offset = return self::format_results( $results, $post_type ); } - public static function cluster_geojson( $post_type, $query = array(), $offset = 0, $limit = 50000 ){ + public static function cluster_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ global $wpdb; $sql = DT_Posts::fields_to_sql( $post_type, $query ); if ( empty( $sql['where_sql'] ) ){ @@ -1401,7 +1401,7 @@ public static function cluster_geojson( $post_type, $query = array(), $offset = return self::format_results( $results, $post_type ); } - public static function points_geojson( $post_type, $query = array(), $offset = 0, $limit = 50000 ){ + public static function points_geojson( $post_type, $query = [], $offset = 0, $limit = 50000 ){ global $wpdb; $sql = DT_Posts::fields_to_sql( $post_type, $query ); if ( empty( $sql['where_sql'] ) ){ @@ -1517,7 +1517,7 @@ public static function query_location_grid_meta_totals( $post_type, $query ) { //phpcs:enable - $list = array(); + $list = []; if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1750,7 +1750,7 @@ public static function query_contacts_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = array(); + $list = []; if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -1904,7 +1904,7 @@ public static function query_groups_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = array(); + $list = []; if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; @@ -2070,7 +2070,7 @@ public static function query_church_location_grid_totals( $status = null ) { ", ARRAY_A ); } - $list = array(); + $list = []; if ( is_array( $results ) ) { foreach ( $results as $result ) { $list[$result['grid_id']] = $result; From 85d1b033138817992ea9627337d21fc577a801de Mon Sep 17 00:00:00 2001 From: kodinkat Date: Mon, 12 Aug 2024 13:57:41 +0100 Subject: [PATCH 05/11] Additional tidy-ups --- dt-mapping/mapping-queries.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index 65c4eeccf0..24fa4b76fb 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -1276,14 +1276,14 @@ private static function format_results( $results, $post_type ){ 'address' => $result['address'] ?? '', 'post_id' => $result['post_id'], 'name' => $result['name'], - 'post_type' => $post_type, + 'post_type' => $post_type ), 'geometry' => array( 'type' => 'Point', 'coordinates' => array( $result['lng'], $result['lat'], - 1, + 1 ), ), ); From 1fdfafd49971a7cac8a8edc7ebd7a2c2a42f4239 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Tue, 13 Aug 2024 13:14:07 +0100 Subject: [PATCH 06/11] Simplified sql --- dt-mapping/mapping-queries.php | 14 ++++-------- dt-metrics/records/dynamic-records-map.js | 2 +- dt-metrics/records/dynamic-records-map.php | 26 ++++++---------------- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/dt-mapping/mapping-queries.php b/dt-mapping/mapping-queries.php index 24fa4b76fb..cc6ec03101 100644 --- a/dt-mapping/mapping-queries.php +++ b/dt-mapping/mapping-queries.php @@ -1305,29 +1305,23 @@ public static function post_type_geojson( $post_type, $args = [], $offset = 0, $ $post_id_filter_sql = ''; $shared_user_join_sql = ''; $shared_user_condition_sql = ''; - if ( isset( $args['list_all'], $args['list_all_by_user_id'] ) && !$args['list_all'] ) { + if ( isset( $args['slug'], $args['user_id'] ) && $args['slug'] === 'personal' ) { $post_id_filter_sql = $wpdb->prepare( " - SELECT * FROM - ( SELECT api_p.ID FROM $wpdb->posts api_p - LEFT JOIN $wpdb->postmeta as field_type ON ( field_type.post_id = api_p.ID AND field_type.meta_key = 'type' ) - WHERE (field_type.meta_value = 'access' OR field_type.meta_value = 'user' OR field_type.meta_value = 'access_placeholder') - AND (api_p.post_status = 'publish') + WHERE (api_p.post_status = 'publish') AND api_p.post_type = %s GROUP BY api_p.ID - LIMIT 0, 50000 - ) AS assigned_post_ids ", ( ( $post_type === 'system-users' ) ? 'contacts' : $post_type ) ); if ( isset( $args['field_type'] ) && $args['field_type'] == 'user_select' ) { - $shared_user_join_sql = "LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = um.meta_value )"; + $shared_user_join_sql = "LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = um.meta_value )"; $post_id_filter_sql = 'AND (um.meta_value IN ('. $post_id_filter_sql .'))'; } else { $shared_user_join_sql = "LEFT JOIN $wpdb->dt_share as field_shared_with ON ( field_shared_with.post_id = p.ID )"; $post_id_filter_sql = 'AND (p.ID IN ('. $post_id_filter_sql .'))'; } - $shared_user_condition_sql = "AND (field_shared_with.user_id = ". $args['list_all_by_user_id'] .")"; + $shared_user_condition_sql = "AND (field_shared_with.user_id = ". $args['user_id'] .")"; } if ( isset( $args['field_key'], $args['field_type'] ) && in_array( $args['field_type'], [ 'key_select', 'multi_select' ] ) ){ diff --git a/dt-metrics/records/dynamic-records-map.js b/dt-metrics/records/dynamic-records-map.js index 74cb13e297..9b45c23905 100644 --- a/dt-metrics/records/dynamic-records-map.js +++ b/dt-metrics/records/dynamic-records-map.js @@ -31,7 +31,7 @@ jQuery(document).ready(function ($) { body.offset = offset; body.limit = limit; - body.list_all = mapbox_library_api.obj.settings.can_list_all; + body.slug = mapbox_library_api.obj.settings.menu_slug; let query = await window.makeRequest( 'POST', mapbox_library_api.obj.settings.post_type_rest_url, diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index 5f6427f70c..25b56cd7e7 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -18,7 +18,7 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base public $slug = 'dynamic_records_map'; // lowercase public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. public $js_file_name = '/dt-metrics/records/dynamic-records-map.js'; // should be full file name plus extension - public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics', 'multiplier' ]; + public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics', 'access_contacts', 'access_groups' ]; public $namespace = 'dt-metrics/records'; public $base_filter = []; @@ -107,7 +107,6 @@ public function scripts() { 'map_key' => DT_Mapbox_API::get_key(), 'no_map_key_msg' => _x( 'To view this map, a mapbox key is needed; click here to add.', 'install mapbox key to view map', 'disciple_tools' ), 'map_mirror' => dt_get_location_grid_mirror( true ), - 'can_list_all' => in_array( $this->base_slug, [ 'records' ] ), 'menu_slug' => $this->base_slug, 'post_type' => $this->post_type, 'post_types' => $this->post_type_options, @@ -190,14 +189,16 @@ public function post_type_geojson( WP_REST_Request $request ){ break; } - // Determine if record restriction (listing-all) should take effect. - $params = self::capture_list_all_setting( $params ); + // Determine type of query to be executed, based on incoming slug. + if ( isset( $params['slug'] ) && $params['slug'] === 'personal' ) { + $params['user_id'] = get_current_user_id(); + } // Execute request query. $response = Disciple_Tools_Mapping_Queries::post_type_geojson( $params['post_type'], $params, $offset, $limit ); - // Ensure to unset list_all_by_user_id for security reasons. - unset( $params['list_all_by_user_id'] ); + // Ensure to unset user_id for security reasons. + unset( $params['user_id'] ); } return [ @@ -267,17 +268,4 @@ public function points_geojson( WP_REST_Request $request ) { return Disciple_Tools_Mapping_Queries::points_geojson( $post_type, $query ); } - - private function capture_list_all_setting( $params ) { - if ( !isset( $params['list_all'] ) || !$params['list_all'] ) { - $params['list_all'] = false; - $params['list_all_by_user_id'] = get_current_user_id(); - } else { - $params['list_all'] = true; - $params['list_all_by_user_id'] = null; - } - - return $params; - } - } From 64c397de784ca67c5075d3f80fd96ba6e86eeba3 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Wed, 14 Aug 2024 10:04:51 +0100 Subject: [PATCH 07/11] Ensure metrics is only shown for specific user roles --- dt-metrics/records/dynamic-records-map.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index 25b56cd7e7..b28114b098 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -18,7 +18,7 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base public $slug = 'dynamic_records_map'; // lowercase public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. public $js_file_name = '/dt-metrics/records/dynamic-records-map.js'; // should be full file name plus extension - public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics', 'access_contacts', 'access_groups' ]; + public $permissions = []; public $namespace = 'dt-metrics/records'; public $base_filter = []; @@ -27,6 +27,12 @@ public function __construct( $base_slug, $base_title ) { return; } + // Ensure metric is only made available for specific user roles. + $current_user = wp_get_current_user(); + if ( !empty( $current_user ) && !empty( $current_user->roles ) && empty( array_intersect( [ 'administrator', 'multiplier' ], $current_user->roles ) ) ) { + return; + } + $this->base_slug = $base_slug; $this->base_title = $base_title; From 51ffd8a631e289f7feeb06f3955b57acfb30267b Mon Sep 17 00:00:00 2001 From: kodinkat Date: Wed, 14 Aug 2024 12:13:58 +0100 Subject: [PATCH 08/11] Personal for all. Dynamics by permissions --- dt-metrics/records/dynamic-records-map.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index b28114b098..ecc8264dae 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -18,18 +18,12 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base public $slug = 'dynamic_records_map'; // lowercase public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. public $js_file_name = '/dt-metrics/records/dynamic-records-map.js'; // should be full file name plus extension - public $permissions = []; + public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics' ]; public $namespace = 'dt-metrics/records'; public $base_filter = []; public function __construct( $base_slug, $base_title ) { - if ( !$this->has_permission() ){ - return; - } - - // Ensure metric is only made available for specific user roles. - $current_user = wp_get_current_user(); - if ( !empty( $current_user ) && !empty( $current_user->roles ) && empty( array_intersect( [ 'administrator', 'multiplier' ], $current_user->roles ) ) ) { + if ( ( $base_slug === 'records' ) && !$this->has_permission() ) { return; } From be8905fa89089ae75c51d5d8b22641db60ba9f37 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Wed, 21 Aug 2024 16:45:46 +0100 Subject: [PATCH 09/11] Prevent non-slug related requests --- dt-metrics/records/dynamic-records-map.js | 10 ++++++---- dt-metrics/records/dynamic-records-map.php | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/dt-metrics/records/dynamic-records-map.js b/dt-metrics/records/dynamic-records-map.js index 9b45c23905..611771f6f9 100644 --- a/dt-metrics/records/dynamic-records-map.js +++ b/dt-metrics/records/dynamic-records-map.js @@ -1,6 +1,8 @@ jQuery(document).ready(function ($) { let spinner_html = ''; + const loading_spinner = jQuery('#loading-spinner'); + const loading_legend = jQuery('#loading-legend'); let mapbox_library_api = { container_set_up: false, current_map_type: 'points', @@ -18,7 +20,7 @@ jQuery(document).ready(function ($) { offset = 0, limit = 50000, ) { - jQuery('#loading-spinner').show(); + jQuery(loading_spinner).show(); if (data.response === undefined) { data = { request: {}, @@ -38,12 +40,13 @@ jQuery(document).ready(function ($) { body, mapbox_library_api.obj.settings.rest_base_url, ); + jQuery(loading_spinner).hide(); data.request = query.request; data.response.features = data.response.features.concat( query.response.features, ); - jQuery('#loading-legend').html( + jQuery(loading_legend).html( `(${data.response.features.length.toLocaleString()})`, ); @@ -62,8 +65,7 @@ jQuery(document).ready(function ($) { limit, ); } - jQuery('#loading-legend').html(''); - jQuery('#loading-spinner').hide(); + jQuery(loading_legend).html(''); return data; }, setup_container: function () { diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index ecc8264dae..18c5550d31 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -178,7 +178,9 @@ public function post_type_geojson( WP_REST_Request $request ){ $params = $request->get_json_params() ?? $request->get_body_params(); $offset = !empty( $params['offset'] ) ? $params['offset'] : 0; $limit = !empty( $params['limit'] ) ? $params['limit'] : 500000; - if ( !empty( $params['post_type'] ) ){ + + // Ensure to prevent any backdoor entries for non-slug related requests. + if ( !empty( $params['post_type'] ) && !empty( $params['slug'] ) ) { // Ensure params shape is altered accordingly, for system based post types. switch ( $params['post_type'] ){ @@ -190,7 +192,7 @@ public function post_type_geojson( WP_REST_Request $request ){ } // Determine type of query to be executed, based on incoming slug. - if ( isset( $params['slug'] ) && $params['slug'] === 'personal' ) { + if ( $params['slug'] === 'personal' ) { $params['user_id'] = get_current_user_id(); } From 9fd2f94fe4b00508ed6f1614981f4126dc6ec2cc Mon Sep 17 00:00:00 2001 From: kodinkat Date: Wed, 21 Aug 2024 17:51:07 +0100 Subject: [PATCH 10/11] Moved permissions check to endpoint --- dt-metrics/charts-base.php | 10 +++++++ dt-metrics/records/dynamic-records-map.php | 33 ++++++++++++++-------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/dt-metrics/charts-base.php b/dt-metrics/charts-base.php index 6a2e4b3412..b485885b95 100644 --- a/dt-metrics/charts-base.php +++ b/dt-metrics/charts-base.php @@ -97,6 +97,16 @@ public function has_permission(){ return $pass; } + public function has_permission_for( $permissions ): bool { + $pass = count( $permissions ) === 0; + foreach ( $permissions as $permission ){ + if ( current_user_can( $permission ) ){ + $pass = true; + } + } + return $pass; + } + public function my_list() { $list = Disciple_Tools_Posts::search_viewable_post( 'contacts', [ 'assigned_to' => [ 'shared', 'me' ] ] ); if ( is_wp_error( $list ) ) { diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index 18c5550d31..1619cd0bfc 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -18,15 +18,11 @@ class DT_Metrics_Dynamic_Records_Map extends DT_Metrics_Chart_Base public $slug = 'dynamic_records_map'; // lowercase public $js_object_name = 'wp_js_object'; // This object will be loaded into the metrics.js file by the wp_localize_script. public $js_file_name = '/dt-metrics/records/dynamic-records-map.js'; // should be full file name plus extension - public $permissions = [ 'dt_all_access_contacts', 'view_project_metrics' ]; + public $permissions = []; public $namespace = 'dt-metrics/records'; public $base_filter = []; public function __construct( $base_slug, $base_title ) { - if ( ( $base_slug === 'records' ) && !$this->has_permission() ) { - return; - } - $this->base_slug = $base_slug; $this->base_title = $base_title; @@ -181,6 +177,7 @@ public function post_type_geojson( WP_REST_Request $request ){ // Ensure to prevent any backdoor entries for non-slug related requests. if ( !empty( $params['post_type'] ) && !empty( $params['slug'] ) ) { + $slug = $params['slug']; // Ensure params shape is altered accordingly, for system based post types. switch ( $params['post_type'] ){ @@ -191,16 +188,28 @@ public function post_type_geojson( WP_REST_Request $request ){ break; } - // Determine type of query to be executed, based on incoming slug. - if ( $params['slug'] === 'personal' ) { - $params['user_id'] = get_current_user_id(); + // Ensure user has required permissions, based on specified slug request. + $has_permission = false; + if ( ( $slug === 'personal' ) && $this->has_permission_for( [ 'view_project_metrics' ] ) ) { + $has_permission = true; + } + if ( ( $slug === 'records' ) && $this->has_permission_for( [ 'dt_all_access_contacts', 'view_project_metrics' ] ) ) { + $has_permission = true; } - // Execute request query. - $response = Disciple_Tools_Mapping_Queries::post_type_geojson( $params['post_type'], $params, $offset, $limit ); + if ( $has_permission ) { - // Ensure to unset user_id for security reasons. - unset( $params['user_id'] ); + // Determine type of query to be executed, based on incoming slug. + if ( $slug === 'personal' ) { + $params['user_id'] = get_current_user_id(); + } + + // Execute request query. + $response = Disciple_Tools_Mapping_Queries::post_type_geojson( $params['post_type'], $params, $offset, $limit ); + + // Ensure to unset user_id for security reasons. + unset( $params['user_id'] ); + } } return [ From 1cacd6f878f12bd6b2daf4647eeb5b599b37b890 Mon Sep 17 00:00:00 2001 From: kodinkat Date: Thu, 22 Aug 2024 09:51:39 +0100 Subject: [PATCH 11/11] Revised permission checks + Updated genmap to follow new checks --- dt-metrics/charts-base.php | 10 --- dt-metrics/records/dynamic-records-map.php | 4 +- dt-metrics/records/genmap.php | 97 ++++++++++++---------- 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/dt-metrics/charts-base.php b/dt-metrics/charts-base.php index b485885b95..6a2e4b3412 100644 --- a/dt-metrics/charts-base.php +++ b/dt-metrics/charts-base.php @@ -97,16 +97,6 @@ public function has_permission(){ return $pass; } - public function has_permission_for( $permissions ): bool { - $pass = count( $permissions ) === 0; - foreach ( $permissions as $permission ){ - if ( current_user_can( $permission ) ){ - $pass = true; - } - } - return $pass; - } - public function my_list() { $list = Disciple_Tools_Posts::search_viewable_post( 'contacts', [ 'assigned_to' => [ 'shared', 'me' ] ] ); if ( is_wp_error( $list ) ) { diff --git a/dt-metrics/records/dynamic-records-map.php b/dt-metrics/records/dynamic-records-map.php index 1619cd0bfc..0f53390465 100644 --- a/dt-metrics/records/dynamic-records-map.php +++ b/dt-metrics/records/dynamic-records-map.php @@ -190,10 +190,10 @@ public function post_type_geojson( WP_REST_Request $request ){ // Ensure user has required permissions, based on specified slug request. $has_permission = false; - if ( ( $slug === 'personal' ) && $this->has_permission_for( [ 'view_project_metrics' ] ) ) { + if ( ( $slug === 'personal' ) && current_user_can( 'access_contacts' ) ) { $has_permission = true; } - if ( ( $slug === 'records' ) && $this->has_permission_for( [ 'dt_all_access_contacts', 'view_project_metrics' ] ) ) { + if ( ( $slug === 'records' ) && ( current_user_can( 'dt_all_access_contacts' ) || current_user_can( 'view_project_metrics' ) ) ) { $has_permission = true; } diff --git a/dt-metrics/records/genmap.php b/dt-metrics/records/genmap.php index 32a608dcfb..1867a6a452 100644 --- a/dt-metrics/records/genmap.php +++ b/dt-metrics/records/genmap.php @@ -11,14 +11,10 @@ class DT_Metrics_Groups_Genmap extends DT_Metrics_Chart_Base 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', 'multiplier' ]; + public $permissions = []; public $namespace = null; public function __construct( $base_slug, $base_title ) { - if ( !$this->has_permission() ){ - return; - } - $this->base_slug = $base_slug; $this->base_title = $base_title; @@ -52,53 +48,66 @@ public function add_api_routes() { } public function tree( WP_REST_Request $request ) { - if ( !$this->has_permission() ){ - return new WP_Error( __METHOD__, 'Missing Permissions', [ 'status' => 400 ] ); - } $params = dt_recursive_sanitize_array( $request->get_params() ); - if ( ! isset( $params['p2p_type'], $params['p2p_direction'], $params['post_type'] ) ) { - return new WP_Error( __METHOD__, 'Missing parameters! [Required: p2p_type, p2p_direction, post_type ]', [ 'status' => 400 ] ); + if ( ! isset( $params['p2p_type'], $params['p2p_direction'], $params['post_type'], $params['slug'] ) ) { + return new WP_Error( __METHOD__, 'Missing parameters! [Required: p2p_type, p2p_direction, post_type, slug ]', [ '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; - } + $slug = $params['slug']; + + // Ensure user has required permissions, based on specified slug request. + $has_permission = false; + if ( ( $slug === 'personal' ) && current_user_can( 'access_contacts' ) ) { + $has_permission = true; + } + if ( ( $slug === 'records' ) && ( current_user_can( 'dt_all_access_contacts' ) || current_user_can( 'view_project_metrics' ) ) ) { + $has_permission = true; } - $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 ); + if ( $has_permission ) { + $user = wp_get_current_user(); + $post_type = $params['post_type']; + $post_settings = DT_Posts::get_post_settings( $post_type ); - $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 ); + // Determine scope of query focus, based on specified slug. + $focus_id = $params['focus_id'] ?? 0; + if ( ( $post_type === 'contacts' ) && ( $slug === 'personal' ) ) { + $focus_id = Disciple_Tools_Users::get_contact_for_user( $user->ID ); + } - // 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; - } + // Ensure sourced focus_id is not a wp exception. + if ( is_wp_error( $focus_id ) ) { + return new WP_Error( __METHOD__, 'Missing Permissions', [ 'status' => 400 ] ); + } - return [ - 'data_layers' => $this->package_data_layer_post_fields( $query, $post_type, $post_settings, $params['data_layers'] ?? [] ), - 'genmap' => $generated_genmap - ]; + $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 ); + + $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 [ + 'data_layers' => $this->package_data_layer_post_fields( $query, $post_type, $post_settings, $params['data_layers'] ?? [] ), + 'genmap' => $generated_genmap + ]; + } else { + return new WP_Error( __METHOD__, 'Missing Permissions', [ 'status' => 400 ] ); + } } public function scripts() {