Last active
June 25, 2018 19:18
-
-
Save bronius/92393784768bc531eca95fb55f68d3d2 to your computer and use it in GitHub Desktop.
Super fast replacement for field_encrypt_views_query_alter in contrib module https://www.drupal.org/project/field_encrypt_views_filters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// The original project query_alter takes each encrypted field with a value sought out of the query | |
// Executes a query of all other fields (or none if none) | |
// Creates a MySQL temporary table and populates with decrypted fields' values | |
// Adds that temp table as a join on the original View | |
// And then executes the view, letting MySQL query against that temporary table of decrypted values. | |
// | |
// This approach expects a parallel field, field_name_md5, to contain an md5 hash of the original, | |
// decrypted value (CRUD updated with entity/node hooks or as calculated field). At query execution, | |
// all encrypted field and filter values are swapped out for md5-equiv and md5 of the filter value, | |
// and BAM it's lightning fast. | |
function field_encrypt_views_filters_views_query_alter(&$view, &$query) { | |
// Check for encrypted fields in the filters. | |
$encrypted_filter_fields = _field_encrypt_views_filters_get_encrypted_filters($view, $query); | |
if (empty($encrypted_filter_fields)) { | |
return; | |
} | |
$encrypted_query_filters = array(); | |
foreach($encrypted_filter_fields as $field_name) { | |
$encrypted_query_filters[$field_name] = $view->exposed_raw_input[$field_name . '_value']; | |
} | |
// dpm($encrypted_query_filters, 'encrypted fields'); | |
$encrypted_field_columns = _field_encrypt_views_filters_get_encrypted_columns($view); | |
// dpm($encrypted_field_columns, 'efcolumns'); | |
// Change the query so that no encrypted fields are in the filters. | |
foreach ($query->where as $group => $where) { | |
foreach ($where['conditions'] as $index => $condition) { | |
if (isset($condition['field'])) { | |
if (is_string($condition['field']) && in_array($condition['field'], $encrypted_field_columns)) { | |
// Rewrite the where clause with the parallel md5 equivalent field table, column name and md5 hash value. | |
$field_col_name_parts = explode('.', $query->where[$group]['conditions'][$index]['field']); | |
$field_col_name_part_value = substr($field_col_name_parts[1], 0, -6) . '_md5_value'; | |
$table_name_md5 = $field_col_name_parts[0] . '_md5'; | |
$query->where[$group]['conditions'][$index]['field'] = $table_name_md5 . '.' . $field_col_name_part_value; | |
$query->where[$group]['conditions'][$index]['value'] = md5($query->where[$group]['conditions'][$index]['value']); | |
// Join the temporary table to the views query. | |
$join = new views_join(); | |
$join->left_table = $view->base_table; | |
$join->left_field = $view->base_field; | |
$join->table = $table_name_md5; | |
$join->field = 'entity_id'; | |
$join->type = 'LEFT'; | |
$query->table_queue[$table_name_md5] = array( | |
'alias' => $table_name_md5, | |
'table' => $table_name_md5, | |
'relationship' => 'node', | |
'join' => $join, | |
); | |
} | |
// BRONIUS: not analyzed | |
elseif (is_string($condition['field']) && _field_encrypt_views_filters_combined_field_query($view, $condition['field'], 'match')) { | |
unset($query->where[$group]['conditions'][$index]); | |
} | |
// BRONIUS: not analyzed | |
elseif ($condition['field'] instanceof DatabaseCondition && _field_encrypt_views_filters_combined_field_database_condition($view, $condition['field'], 'match')) { | |
unset($query->where[$group]['conditions'][$index]); | |
} | |
} | |
} | |
} | |
// dpm($query->where, 'query where'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment