Skip to content

Instantly share code, notes, and snippets.

@bronius
Last active June 25, 2018 19:18
Show Gist options
  • Select an option

  • Save bronius/92393784768bc531eca95fb55f68d3d2 to your computer and use it in GitHub Desktop.

Select an option

Save bronius/92393784768bc531eca95fb55f68d3d2 to your computer and use it in GitHub Desktop.

Revisions

  1. bronius renamed this gist Jun 25, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. bronius created this gist Jun 25, 2018.
    71 changes: 71 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    <?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');
    }