Skip to content
Snippets Groups Projects
Commit 5d4a1032 authored by jaapjansma's avatar jaapjansma
Browse files

Added filter to respect the ACL.

parent 792dfd9b
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* Added filter to search text in multiple fields. * Added filter to search text in multiple fields.
* Added filter for searching contacts with a certain tag. * Added filter for searching contacts with a certain tag.
* Added filter for searching contacts with a certain type. * Added filter for searching contacts with a certain type.
* Added filter to respect the ACL. So that a user only sees the contacts he is allowed to see.
# Version 1.0.7 # Version 1.0.7
......
...@@ -59,6 +59,8 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc ...@@ -59,6 +59,8 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
$cache_key = 'dataprocessor_'.$dataProcessor['id']; $cache_key = 'dataprocessor_'.$dataProcessor['id'];
$cache = CRM_Dataprocessor_Utils_Cache::singleton(); $cache = CRM_Dataprocessor_Utils_Cache::singleton();
if ($dataProcessorClass = $cache->get($cache_key)) { if ($dataProcessorClass = $cache->get($cache_key)) {
// Reset the default filter values as they might have been changed.
$dataProcessorClass->setDefaultFilterValues();
return $dataProcessorClass; return $dataProcessorClass;
} }
$factory = dataprocessor_get_factory(); $factory = dataprocessor_get_factory();
......
...@@ -54,7 +54,9 @@ class InTableWhereClause implements WhereClauseInterface { ...@@ -54,7 +54,9 @@ class InTableWhereClause implements WhereClauseInterface {
public function getWhereClause() { public function getWhereClause() {
$clauses = array("1"); $clauses = array("1");
foreach($this->filters as $clause) { foreach($this->filters as $clause) {
$clauses[] = $clause->getWhereClause(); if ($clause->getWhereClause()) {
$clauses[] = $clause->getWhereClause();
}
} }
$whereClause = implode(" AND ", $clauses); $whereClause = implode(" AND ", $clauses);
...@@ -65,4 +67,4 @@ class InTableWhereClause implements WhereClauseInterface { ...@@ -65,4 +67,4 @@ class InTableWhereClause implements WhereClauseInterface {
)"; )";
} }
} }
\ No newline at end of file
<?php
/**
* @author Jaap Jansma <jaap.jansma@civicoop.org>
* @license AGPL-3.0
*/
namespace Civi\DataProcessor\DataFlow\SqlDataFlow;
class PureSqlStatementClause implements WhereClauseInterface {
protected $isJoinClause = FALSE;
protected $where;
public function __construct($pureSqlStatement, $isJoinClause = FALSE) {
$this->where = $pureSqlStatement;
$this->isJoinClause = $isJoinClause;
}
/**
* Returns the where clause
* E.g. contact_type = 'Individual'
*
* @return string
*/
public function getWhereClause() {
return $this->where;
}
/**
* Returns true when this where clause can be added to the
* join or whether this clause should be propagated to the where part of the
* query
*
* @return bool
*/
public function isJoinClause() {
return $this->isJoinClause;
}
}
...@@ -134,6 +134,7 @@ class Factory { ...@@ -134,6 +134,7 @@ class Factory {
$this->addFilter('contact_in_group_filter', 'Civi\DataProcessor\FilterHandler\ContactInGroupFilter', E::ts('Contact in Group filter')); $this->addFilter('contact_in_group_filter', 'Civi\DataProcessor\FilterHandler\ContactInGroupFilter', E::ts('Contact in Group filter'));
$this->addFilter('contact_with_tag_filter', 'Civi\DataProcessor\FilterHandler\ContactWithTagFilter', E::ts('Contact has Tag filter')); $this->addFilter('contact_with_tag_filter', 'Civi\DataProcessor\FilterHandler\ContactWithTagFilter', E::ts('Contact has Tag filter'));
$this->addFilter('contact_type_filter', 'Civi\DataProcessor\FilterHandler\ContactTypeFilter', E::ts('Contact Type filter')); $this->addFilter('contact_type_filter', 'Civi\DataProcessor\FilterHandler\ContactTypeFilter', E::ts('Contact Type filter'));
$this->addFilter('permission_to_view_contact', 'Civi\DataProcessor\FilterHandler\PermissionToViewContactFilter', E::ts('Permission to view contact'));
$this->addFilter('case_role_filter', 'Civi\DataProcessor\FilterHandler\CaseRoleFilter', E::ts('Case Role filter')); $this->addFilter('case_role_filter', 'Civi\DataProcessor\FilterHandler\CaseRoleFilter', E::ts('Case Role filter'));
$this->addFilter('in_api_filter', 'Civi\DataProcessor\FilterHandler\InApiFilter', E::ts('API filter')); $this->addFilter('in_api_filter', 'Civi\DataProcessor\FilterHandler\InApiFilter', E::ts('API filter'));
$this->addjoinType('simple_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleJoin', E::ts('Select fields to join on')); $this->addjoinType('simple_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleJoin', E::ts('Select fields to join on'));
......
...@@ -103,4 +103,4 @@ abstract class AbstractFieldFilterHandler extends AbstractFilterHandler { ...@@ -103,4 +103,4 @@ abstract class AbstractFieldFilterHandler extends AbstractFilterHandler {
} }
} }
} }
\ No newline at end of file
...@@ -105,10 +105,19 @@ abstract class AbstractFilterHandler { ...@@ -105,10 +105,19 @@ abstract class AbstractFilterHandler {
$this->doInitialization(); $this->doInitialization();
$this->setDefaultFilterValues();
$this->is_initialized = true;
}
/**
* Sets the default filter.
*
* @throws \Exception
*/
public function setDefaultFilterValues() {
if (!empty($this->defaultFilterValues)) { if (!empty($this->defaultFilterValues)) {
$this->applyFilterFromSubmittedFilterParams($this->defaultFilterValues); $this->applyFilterFromSubmittedFilterParams($this->defaultFilterValues);
} }
$this->is_initialized = true;
} }
/** /**
......
<?php
/**
* @author Jaap Jansma <jaap.jansma@civicoop.org>
* @license AGPL-3.0
*/
namespace Civi\DataProcessor\FilterHandler;
use Civi\DataProcessor\DataFlow\SqlDataFlow;
use Civi\DataProcessor\Exception\InvalidConfigurationException;
use CRM_Dataprocessor_ExtensionUtil as E;
class PermissionToViewContactFilter extends AbstractFieldFilterHandler {
/**
* Initialize the filter
*
* @throws \Civi\DataProcessor\Exception\DataSourceNotFoundException
* @throws \Civi\DataProcessor\Exception\InvalidConfigurationException
* @throws \Civi\DataProcessor\Exception\FieldNotFoundException
*/
protected function doInitialization() {
if (!isset($this->configuration['datasource']) || !isset($this->configuration['field'])) {
throw new InvalidConfigurationException(E::ts("Filter %1 requires a field to filter on. None given.", array(1=>$this->title)));
}
$this->initializeField($this->configuration['datasource'], $this->configuration['field']);
}
/**
* Sets the default filter.
*
* @throws \Exception
*/
public function setDefaultFilterValues() {
$this->setFilter([]);
}
/**
* @param array $filter
* The filter settings
* @return mixed
*/
public function setFilter($filter) {
$this->resetFilter();
$dataFlow = $this->dataSource->ensureField($this->fieldSpecification->name);
$where = $this->getAclWhereClause();
$contactTableAlias = 'civicrm_contact_'.$this->fieldSpecification->alias;
$where = str_replace(["`contact_a`.", "contact_a."], "`{$contactTableAlias}`.", $where);
if ($where) {
$contactFilters[] = new SqlDataFlow\PureSqlStatementClause($where);
if ($dataFlow && $dataFlow instanceof SqlDataFlow) {
$this->whereClause = new SqlDataFlow\InTableWhereClause(
'id',
'civicrm_contact',
$contactTableAlias,
$contactFilters,
$dataFlow->getName(),
$this->fieldSpecification->name,
'IN'
);
$dataFlow->addWhereClause($this->whereClause);
}
}
}
protected function getAclWhereClause() {
$tables = array();
$whereTables = array();
$where = \CRM_ACL_API::whereClause(\CRM_ACL_API::VIEW, $tables, $whereTables, NULL, FALSE, TRUE, FALSE);
return $where;
}
/**
* Returns true when this filter has additional configuration
*
* @return bool
*/
public function hasConfiguration() {
return true;
}
/**
* When this filter type has additional configuration you can add
* the fields on the form with this function.
*
* @param \CRM_Core_Form $form
* @param array $filter
*/
public function buildConfigurationForm(\CRM_Core_Form $form, $filter=array()) {
$fieldSelect = \CRM_Dataprocessor_Utils_DataSourceFields::getAvailableFilterFieldsInDataSources($filter['data_processor_id']);
$form->add('select', 'contact_id_field', E::ts('Contact ID Field'), $fieldSelect, true, array(
'style' => 'min-width:250px',
'class' => 'crm-select2 huge data-processor-field-for-name',
'placeholder' => E::ts('- select -'),
));
if (isset($filter['configuration'])) {
$configuration = $filter['configuration'];
$defaults = array();
if (isset($configuration['field']) && isset($configuration['datasource'])) {
$defaults['contact_id_field'] = $configuration['datasource'] . '::' . $configuration['field'];
}
$form->setDefaults($defaults);
}
}
/**
* When this filter type has configuration specify the template file name
* for the configuration form.
*
* @return false|string
*/
public function getConfigurationTemplateFileName() {
return "CRM/Dataprocessor/Form/Filter/Configuration/PermissionToViewContactFilter.tpl";
}
/**
* Process the submitted values and create a configuration array
*
* @param $submittedValues
* @return array
*/
public function processConfiguration($submittedValues) {
list($datasource, $field) = explode('::', $submittedValues['contact_id_field'], 2);
$configuration['field'] = $field;
$configuration['datasource'] = $datasource;
return $configuration;
}
/**
* Add the elements to the filter form.
*
* @param \CRM_Core_Form $form
* @param array $defaultFilterValue
* @param string $size
* Possible values: full or compact
* @return array
* Return variables belonging to this filter.
*/
public function addToFilterForm(\CRM_Core_Form $form, $defaultFilterValue, $size='full') {
return null; // This filter has no additional options to select.
}
}
...@@ -177,4 +177,15 @@ abstract class AbstractProcessorType { ...@@ -177,4 +177,15 @@ abstract class AbstractProcessorType {
return $this->dataflow; return $this->dataflow;
} }
} /**
\ No newline at end of file * Sets the default filter values for all filters.
*
* @throws \Exception
*/
public function setDefaultFilterValues() {
foreach($this->filterHandlers as $filterHandler) {
$filterHandler->setDefaultFilterValues();
}
}
}
{crmScope extensionKey='dataprocessor'}
<div class="crm-section">
<div class="label">{$form.contact_id_field.label}</div>
<div class="content">{$form.contact_id_field.html}</div>
<div class="clear"></div>
</div>
{/crmScope}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment