From 0a63b42b62d7e669eb2b9390fe4b58a87f89682c Mon Sep 17 00:00:00 2001 From: Jaap Jansma <jaap.jansma@civicoop.org> Date: Tue, 2 Jul 2019 08:12:51 +0200 Subject: [PATCH] better error handling --- .../Selector/DataProcessorContactSearch.php | 2 +- CRM/Dataprocessor/BAO/DataProcessor.php | 22 ++++++++--- CRM/Dataprocessor/Form/AggregateField.php | 2 +- CRM/Dataprocessor/Form/DataProcessor.php | 2 +- CRM/Dataprocessor/Form/Field.php | 2 +- .../Form/Output/AbstractUIOutputForm.php | 2 +- CRM/Dataprocessor/Form/Source.php | 2 +- .../Form/AbstractSearch.php | 20 ++++++---- .../DataSpecification/DataSpecification.php | 5 ++- .../Exception/DataSourceNotFoundException.php | 11 ++++++ .../Exception/FieldNotFoundException.php | 11 ++++++ .../InvalidConfigurationException.php | 11 ++++++ .../CaseRolesFieldOutputHandler.php | 12 ++++++ .../ContactLinkFieldOutputHandler.php | 28 ++++++++++++++ .../EventRepeatingInfoFieldOutputHandler.php | 12 ++++++ .../FileFieldOutputHandler.php | 12 ++++++ .../GroupsOfContactFieldOutputHandler.php | 12 ++++++ .../RawFieldOutputHandler.php | 12 ++++++ .../FilterHandler/CaseRoleFilter.php | 22 ++++++++--- .../FilterHandler/ContactInGroupFilter.php | 20 +++++++--- .../FilterHandler/SimpleSqlFilter.php | 22 ++++++++--- Civi/DataProcessor/Output/Api.php | 38 +++++++++++++++++++ 22 files changed, 248 insertions(+), 34 deletions(-) create mode 100644 Civi/DataProcessor/Exception/DataSourceNotFoundException.php create mode 100644 Civi/DataProcessor/Exception/FieldNotFoundException.php create mode 100644 Civi/DataProcessor/Exception/InvalidConfigurationException.php diff --git a/CRM/Contact/Selector/DataProcessorContactSearch.php b/CRM/Contact/Selector/DataProcessorContactSearch.php index 55c29f7d..23226896 100644 --- a/CRM/Contact/Selector/DataProcessorContactSearch.php +++ b/CRM/Contact/Selector/DataProcessorContactSearch.php @@ -130,7 +130,7 @@ class CRM_Contact_Selector_DataProcessorContactSearch { } $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->data_processor_id)); - $this->dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); $this->dataProcessorId = $dao->data_processor_id; $this->dataProcessorOutput = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $dao->output_id)); diff --git a/CRM/Dataprocessor/BAO/DataProcessor.php b/CRM/Dataprocessor/BAO/DataProcessor.php index 829243b2..cdda1c46 100644 --- a/CRM/Dataprocessor/BAO/DataProcessor.php +++ b/CRM/Dataprocessor/BAO/DataProcessor.php @@ -60,7 +60,11 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc $dataProcessorClass = $factory->getDataProcessorTypeByName($dataProcessor['type']); $sources = civicrm_api3('DataProcessorSource', 'get', array('data_processor_id' => $dataProcessor['id'], 'options' => array('limit' => 0))); foreach($sources['values'] as $sourceDao) { - CRM_Dataprocessor_BAO_DataProcessorSource::addSourceToDataProcessor($sourceDao, $dataProcessorClass); + try { + CRM_Dataprocessor_BAO_DataProcessorSource::addSourceToDataProcessor($sourceDao, $dataProcessorClass); + } catch (\Exception $e) { + CRM_Core_Session::setStatus($e->getMessage(), E::ts("Could not add data source"), 'error'); + } } $aggregationFields = array(); @@ -79,8 +83,12 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc $filterHandler = $factory->getFilterByName($filter['type']); if ($filterHandler) { $filterHandler->setDataProcessor($dataProcessorClass); - $filterHandler->initialize($filter['name'], $filter['title'], $filter['is_required'], $filter['configuration']); - $dataProcessorClass->addFilterHandler($filterHandler); + try { + $filterHandler->initialize($filter['name'], $filter['title'], $filter['is_required'], $filter['configuration']); + $dataProcessorClass->addFilterHandler($filterHandler); + } catch (\Exception $e) { + CRM_Core_Session::setStatus($e->getMessage(), E::ts("Invalid filter"), 'error'); + } } } @@ -89,8 +97,12 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc $outputHandler = $factory->getOutputHandlerByName($field['type']); if ($outputHandler) { $outputHandler->setDataProcessor($dataProcessorClass); - $outputHandler->initialize($field['name'], $field['title'], $field['configuration']); - $dataProcessorClass->addOutputFieldHandlers($outputHandler); + try { + $outputHandler->initialize($field['name'], $field['title'], $field['configuration']); + $dataProcessorClass->addOutputFieldHandlers($outputHandler); + } catch (\Exception $e) { + CRM_Core_Session::setStatus($e->getMessage(), E::ts("Invalid field"), 'error'); + } } } return $dataProcessorClass; diff --git a/CRM/Dataprocessor/Form/AggregateField.php b/CRM/Dataprocessor/Form/AggregateField.php index de74d9af..3782e899 100644 --- a/CRM/Dataprocessor/Form/AggregateField.php +++ b/CRM/Dataprocessor/Form/AggregateField.php @@ -23,7 +23,7 @@ class CRM_Dataprocessor_Form_AggregateField extends CRM_Core_Form { function preProcess() { $this->dataProcessorId = CRM_Utils_Request::retrieve('id', 'Integer'); $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId)); - $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); $this->assign('data_processor_id', $this->dataProcessorId); $title = E::ts('Data Processor Field'); diff --git a/CRM/Dataprocessor/Form/DataProcessor.php b/CRM/Dataprocessor/Form/DataProcessor.php index bfad9fdb..281520ff 100644 --- a/CRM/Dataprocessor/Form/DataProcessor.php +++ b/CRM/Dataprocessor/Form/DataProcessor.php @@ -29,7 +29,7 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form { $this->dataProcessorId = CRM_Utils_Request::retrieve('id', 'Integer'); if ($this->dataProcessorId) { $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', ['id' => $this->dataProcessorId]); - $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); } $this->currentUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId)); $this->assign('data_processor_id', $this->dataProcessorId); diff --git a/CRM/Dataprocessor/Form/Field.php b/CRM/Dataprocessor/Form/Field.php index e1662f2c..4e815a76 100644 --- a/CRM/Dataprocessor/Form/Field.php +++ b/CRM/Dataprocessor/Form/Field.php @@ -51,7 +51,7 @@ class CRM_Dataprocessor_Form_Field extends CRM_Core_Form { $this->assign('data_processor_id', $this->dataProcessorId); if ($this->dataProcessorId) { $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId)); - $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); } $this->id = CRM_Utils_Request::retrieve('id', 'Integer'); diff --git a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php index 53e3e473..9f1b8cd5 100644 --- a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php +++ b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php @@ -76,7 +76,7 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co } $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->data_processor_id)); - $this->dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); $this->dataProcessorId = $dao->data_processor_id; $this->dataProcessorOutput = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $dao->output_id)); diff --git a/CRM/Dataprocessor/Form/Source.php b/CRM/Dataprocessor/Form/Source.php index 8824acab..6850093b 100644 --- a/CRM/Dataprocessor/Form/Source.php +++ b/CRM/Dataprocessor/Form/Source.php @@ -56,7 +56,7 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form { $this->assign('data_processor_id', $this->dataProcessorId); if ($this->dataProcessorId) { $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId)); - $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor); + $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor, true); } $this->id = CRM_Utils_Request::retrieve('id', 'Integer'); diff --git a/CRM/DataprocessorSearch/Form/AbstractSearch.php b/CRM/DataprocessorSearch/Form/AbstractSearch.php index d9b78440..c186c0ff 100644 --- a/CRM/DataprocessorSearch/Form/AbstractSearch.php +++ b/CRM/DataprocessorSearch/Form/AbstractSearch.php @@ -246,7 +246,11 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce while($record = $this->dataProcessorClass->getDataFlow()->nextRecord()) { $i ++; $row = array(); - $row['id'] = $record[$id_field]->formattedValue; + + $row['id'] = null; + if (isset($record[$id_field])) { + $row['id'] = $record[$id_field]->formattedValue; + } $row['checkbox'] = CRM_Core_Form::CB_PREFIX.$row['id']; $row['record'] = $record; @@ -258,12 +262,14 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $this->addElement('checkbox', $row['checkbox'], NULL, NULL, ['class' => 'select-row']); - $prevnextData[] = array( - 'entity_id1' => $row['id'], - 'entity_table' => $this->getEntityTable(), - 'data' => $record, - ); - $ids[] = $row['id']; + if ($row['id']) { + $prevnextData[] = array( + 'entity_id1' => $row['id'], + 'entity_table' => $this->getEntityTable(), + 'data' => $record, + ); + $ids[] = $row['id']; + } $rows[] = $row; } diff --git a/Civi/DataProcessor/DataSpecification/DataSpecification.php b/Civi/DataProcessor/DataSpecification/DataSpecification.php index 04b81b71..88a7b95f 100644 --- a/Civi/DataProcessor/DataSpecification/DataSpecification.php +++ b/Civi/DataProcessor/DataSpecification/DataSpecification.php @@ -48,7 +48,10 @@ class DataSpecification { * @return \Civi\DataProcessor\DataSpecification\FieldSpecification */ public function getFieldSpecificationByName($name) { - return $this->fields[$name]; + if (isset($this->fields[$name])) { + return $this->fields[$name]; + } + return null; } /** diff --git a/Civi/DataProcessor/Exception/DataSourceNotFoundException.php b/Civi/DataProcessor/Exception/DataSourceNotFoundException.php new file mode 100644 index 00000000..aa5d99d8 --- /dev/null +++ b/Civi/DataProcessor/Exception/DataSourceNotFoundException.php @@ -0,0 +1,11 @@ +<?php +/** + * @author Jaap Jansma <jaap.jansma@civicoop.org> + * @license AGPL-3.0 + */ + +namespace Civi\DataProcessor\Exception; + +class DataSourceNotFoundException extends \Exception { + +} \ No newline at end of file diff --git a/Civi/DataProcessor/Exception/FieldNotFoundException.php b/Civi/DataProcessor/Exception/FieldNotFoundException.php new file mode 100644 index 00000000..fa7277ff --- /dev/null +++ b/Civi/DataProcessor/Exception/FieldNotFoundException.php @@ -0,0 +1,11 @@ +<?php +/** + * @author Jaap Jansma <jaap.jansma@civicoop.org> + * @license AGPL-3.0 + */ + +namespace Civi\DataProcessor\Exception; + +class FieldNotFoundException extends \Exception { + +} \ No newline at end of file diff --git a/Civi/DataProcessor/Exception/InvalidConfigurationException.php b/Civi/DataProcessor/Exception/InvalidConfigurationException.php new file mode 100644 index 00000000..db9941be --- /dev/null +++ b/Civi/DataProcessor/Exception/InvalidConfigurationException.php @@ -0,0 +1,11 @@ +<?php +/** + * @author Jaap Jansma <jaap.jansma@civicoop.org> + * @license AGPL-3.0 + */ + +namespace Civi\DataProcessor\Exception; + +class InvalidConfigurationException extends \Exception { + +} \ No newline at end of file diff --git a/Civi/DataProcessor/FieldOutputHandler/CaseRolesFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/CaseRolesFieldOutputHandler.php index 5f051529..3749f8e8 100644 --- a/Civi/DataProcessor/FieldOutputHandler/CaseRolesFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/CaseRolesFieldOutputHandler.php @@ -10,6 +10,8 @@ use Civi\DataProcessor\ProcessorType\AbstractProcessorType; use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; use Civi\DataProcessor\FieldOutputHandler\FieldOutput; class CaseRolesFieldOutputHandler extends AbstractFieldOutputHandler { @@ -68,7 +70,17 @@ class CaseRolesFieldOutputHandler extends AbstractFieldOutputHandler { public function initialize($alias, $title, $configuration) { $this->outputFieldSpecification = new FieldSpecification($alias, 'String', $title, null, $alias); $this->caseIdSource = $this->dataProcessor->getDataSourceByName($configuration['datasource']); + if (!$this->caseIdSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); + } $this->caseIdField = $this->caseIdSource->getAvailableFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->caseIdField) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } $this->caseIdSource->ensureFieldInSource($this->caseIdField); $this->outputFieldSpecification = new FieldSpecification($this->caseIdField->name, 'String', $title, null, $alias); diff --git a/Civi/DataProcessor/FieldOutputHandler/ContactLinkFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/ContactLinkFieldOutputHandler.php index d9893d20..be7e9ec0 100644 --- a/Civi/DataProcessor/FieldOutputHandler/ContactLinkFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/ContactLinkFieldOutputHandler.php @@ -11,6 +11,8 @@ use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; use Civi\DataProcessor\FieldOutputHandler\FieldOutput; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; class ContactLinkFieldOutputHandler extends AbstractFieldOutputHandler implements OutputHandlerSortable { @@ -78,11 +80,37 @@ class ContactLinkFieldOutputHandler extends AbstractFieldOutputHandler implement public function initialize($alias, $title, $configuration) { $this->outputFieldSpecification = new FieldSpecification($alias, 'String', $title, null, $alias); $this->contactIdSource = $this->dataProcessor->getDataSourceByName($configuration['contact_id_datasource']); + if (!$this->contactIdSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array( + 1=>$title, + 2=>$configuration['datasource']) + )); + } $this->contactIdField = $this->contactIdSource->getAvailableFields()->getFieldSpecificationByName($configuration['contact_id_field']); + if (!$this->contactIdField) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['contact_id_field'], + 3 => $configuration['contact_id_datasource'] + ))); + } $this->contactIdSource->ensureFieldInSource($this->contactIdField); $this->contactNameSource = $this->dataProcessor->getDataSourceByName($configuration['contact_name_datasource']); + if (!$this->contactIdSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array( + 1=>$title, + 2=>$configuration['contact_name_datasource']) + )); + } $this->contactNameField = $this->contactNameSource->getAvailableFields()->getFieldSpecificationByName($configuration['contact_name_field']); + if (!$this->contactNameField) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['contact_name_field'], + 3 => $configuration['contact_name_datasource'] + ))); + } $this->contactNameSource->ensureFieldInSource($this->contactNameField); $this->outputFieldSpecification = new FieldSpecification($this->contactIdField->name, 'String', $title, null, $alias); diff --git a/Civi/DataProcessor/FieldOutputHandler/EventRepeatingInfoFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/EventRepeatingInfoFieldOutputHandler.php index a0a4254d..6f31c742 100644 --- a/Civi/DataProcessor/FieldOutputHandler/EventRepeatingInfoFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/EventRepeatingInfoFieldOutputHandler.php @@ -9,6 +9,8 @@ namespace Civi\DataProcessor\FieldOutputHandler; use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; class EventRepeatingInfoFieldOutputHandler extends AbstractFieldOutputHandler implements OutputHandlerSortable{ @@ -60,7 +62,17 @@ class EventRepeatingInfoFieldOutputHandler extends AbstractFieldOutputHandler im */ public function initialize($alias, $title, $configuration) { $this->dataSource = $this->dataProcessor->getDataSourceByName($configuration['datasource']); + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); + } $this->inputFieldSpec = $this->dataSource->getAvailableFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->inputFieldSpec) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } $this->dataSource->ensureFieldInSource($this->inputFieldSpec); $this->outputFieldSpec = new FieldSpecification($alias, 'String', $title, $alias); diff --git a/Civi/DataProcessor/FieldOutputHandler/FileFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/FileFieldOutputHandler.php index ce0c3a56..a17678d8 100644 --- a/Civi/DataProcessor/FieldOutputHandler/FileFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/FileFieldOutputHandler.php @@ -10,6 +10,8 @@ use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; use Civi\DataProcessor\FieldOutputHandler\FieldOutput; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; class FileFieldOutputHandler extends AbstractFieldOutputHandler { @@ -88,7 +90,17 @@ class FileFieldOutputHandler extends AbstractFieldOutputHandler { */ public function initialize($alias, $title, $configuration) { $this->dataSource = $this->dataProcessor->getDataSourceByName($configuration['datasource']); + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); + } $this->inputFieldSpec = $this->dataSource->getAvailableFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->inputFieldSpec) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } $this->dataSource->ensureFieldInSource($this->inputFieldSpec); $this->outputFieldSpec = clone $this->inputFieldSpec; diff --git a/Civi/DataProcessor/FieldOutputHandler/GroupsOfContactFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/GroupsOfContactFieldOutputHandler.php index 34d63ea6..194bbb4e 100644 --- a/Civi/DataProcessor/FieldOutputHandler/GroupsOfContactFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/GroupsOfContactFieldOutputHandler.php @@ -11,6 +11,8 @@ use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; use Civi\DataProcessor\FieldOutputHandler\FieldOutput; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; class GroupsOfContactFieldOutputHandler extends AbstractFieldOutputHandler { @@ -66,7 +68,17 @@ class GroupsOfContactFieldOutputHandler extends AbstractFieldOutputHandler { public function initialize($alias, $title, $configuration) { $this->outputFieldSpecification = new FieldSpecification($alias, 'String', $title, null, $alias); $this->contactIdSource = $this->dataProcessor->getDataSourceByName($configuration['datasource']); + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); + } $this->contactIdField = $this->contactIdSource->getAvailableFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->inputFieldSpec) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } $this->contactIdSource->ensureFieldInSource($this->contactIdField); $this->outputFieldSpecification = new FieldSpecification($this->contactIdField->name, 'String', $title, null, $alias); diff --git a/Civi/DataProcessor/FieldOutputHandler/RawFieldOutputHandler.php b/Civi/DataProcessor/FieldOutputHandler/RawFieldOutputHandler.php index 66b63ddc..f8a0d93b 100644 --- a/Civi/DataProcessor/FieldOutputHandler/RawFieldOutputHandler.php +++ b/Civi/DataProcessor/FieldOutputHandler/RawFieldOutputHandler.php @@ -6,6 +6,8 @@ namespace Civi\DataProcessor\FieldOutputHandler; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; use CRM_Dataprocessor_ExtensionUtil as E; use Civi\DataProcessor\Source\SourceInterface; use Civi\DataProcessor\DataSpecification\FieldSpecification; @@ -60,7 +62,17 @@ class RawFieldOutputHandler extends AbstractFieldOutputHandler implements Output */ public function initialize($alias, $title, $configuration) { $this->dataSource = $this->dataProcessor->getDataSourceByName($configuration['datasource']); + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Field %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); + } $this->inputFieldSpec = $this->dataSource->getAvailableFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->inputFieldSpec) { + throw new FieldNotFoundException(E::ts("Field %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } $this->dataSource->ensureFieldInSource($this->inputFieldSpec); $this->outputFieldSpec = clone $this->inputFieldSpec; diff --git a/Civi/DataProcessor/FilterHandler/CaseRoleFilter.php b/Civi/DataProcessor/FilterHandler/CaseRoleFilter.php index ec3fc3e1..bb235428 100644 --- a/Civi/DataProcessor/FilterHandler/CaseRoleFilter.php +++ b/Civi/DataProcessor/FilterHandler/CaseRoleFilter.php @@ -10,6 +10,9 @@ use Civi\DataProcessor\DataFlow\SqlDataFlow; use Civi\DataProcessor\DataFlow\SqlTableDataFlow; use Civi\DataProcessor\DataSpecification\CustomFieldSpecification; use Civi\DataProcessor\DataSpecification\FieldSpecification; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; +use Civi\DataProcessor\Exception\InvalidConfigurationException; use Civi\DataProcessor\Source\SourceInterface; use CRM_Dataprocessor_ExtensionUtil as E; @@ -47,17 +50,26 @@ class CaseRoleFilter extends AbstractFilterHandler { return; // Already initialized. } if (!isset($configuration['datasource']) || !isset($configuration['field'])) { - return; // Invalid configuration + throw new InvalidConfigurationException(E::ts("Filter %1 requires a field to filter on. None given.", array(1=>$title))); } $this->is_required = $is_required; $this->dataSource = $this->data_processor->getDataSourceByName($configuration['datasource']); - if ($this->dataSource) { - $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); - $this->fieldSpecification->alias = $alias; - $this->fieldSpecification->title = $title; + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Filter %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); } + $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->fieldSpecification) { + throw new FieldNotFoundException(E::ts("Filter %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } + $this->fieldSpecification->alias = $alias; + $this->fieldSpecification->title = $title; + if (isset($configuration['relationship_types']) && is_array($configuration['relationship_types'])) { $this->relationship_type_ids = array(); diff --git a/Civi/DataProcessor/FilterHandler/ContactInGroupFilter.php b/Civi/DataProcessor/FilterHandler/ContactInGroupFilter.php index 04f3e630..14aa02c1 100644 --- a/Civi/DataProcessor/FilterHandler/ContactInGroupFilter.php +++ b/Civi/DataProcessor/FilterHandler/ContactInGroupFilter.php @@ -10,6 +10,8 @@ use Civi\DataProcessor\DataFlow\SqlDataFlow; use Civi\DataProcessor\DataFlow\SqlTableDataFlow; use Civi\DataProcessor\DataSpecification\CustomFieldSpecification; use Civi\DataProcessor\DataSpecification\FieldSpecification; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; use Civi\DataProcessor\Source\SourceInterface; use CRM_Dataprocessor_ExtensionUtil as E; @@ -47,17 +49,25 @@ class ContactInGroupFilter extends AbstractFilterHandler { return; // Already initialized. } if (!isset($configuration['datasource']) || !isset($configuration['field'])) { - return; // Invalid configuration + throw new InvalidConfigurationException(E::ts("Filter %1 requires a field to filter on. None given.", array(1=>$title))); } $this->is_required = $is_required; $this->dataSource = $this->data_processor->getDataSourceByName($configuration['datasource']); - if ($this->dataSource) { - $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); - $this->fieldSpecification->alias = $alias; - $this->fieldSpecification->title = $title; + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Filter %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); } + $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->fieldSpecification) { + throw new FieldNotFoundException(E::ts("Filter %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } + $this->fieldSpecification->alias = $alias; + $this->fieldSpecification->title = $title; if (isset($configuration['parent_group']) && $configuration['parent_group']) { $this->parent_group_id = civicrm_api3('Group', 'getvalue', array('return' => 'id', 'name' => $configuration['parent_group'])); diff --git a/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php b/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php index a16ac201..eb50a34d 100644 --- a/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php +++ b/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php @@ -10,6 +10,9 @@ use Civi\DataProcessor\DataFlow\SqlDataFlow; use Civi\DataProcessor\DataFlow\SqlTableDataFlow; use Civi\DataProcessor\DataSpecification\CustomFieldSpecification; use Civi\DataProcessor\DataSpecification\FieldSpecification; +use Civi\DataProcessor\Exception\DataSourceNotFoundException; +use Civi\DataProcessor\Exception\FieldNotFoundException; +use Civi\DataProcessor\Exception\InvalidConfigurationException; use Civi\DataProcessor\Source\SourceInterface; use CRM_Dataprocessor_ExtensionUtil as E; @@ -42,17 +45,26 @@ class SimpleSqlFilter extends AbstractFilterHandler { return; // Already initialized. } if (!isset($configuration['datasource']) || !isset($configuration['field'])) { - return; // Invalid configuration + throw new InvalidConfigurationException(E::ts("Filter %1 requires a field to filter on. None given.", array(1=>$title))); } $this->is_required = $is_required; $this->dataSource = $this->data_processor->getDataSourceByName($configuration['datasource']); - if ($this->dataSource) { - $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); - $this->fieldSpecification->alias = $alias; - $this->fieldSpecification->title = $title; + if (!$this->dataSource) { + throw new DataSourceNotFoundException(E::ts("Filter %1 requires data source '%2' which could not be found. Did you rename or deleted the data source?", array(1=>$title, 2=>$configuration['datasource']))); } + $this->fieldSpecification = clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']); + if (!$this->fieldSpecification) { + throw new FieldNotFoundException(E::ts("Filter %1 requires a field with the name '%2' in the data source '%3'. Did you change the data source type?", array( + 1 => $title, + 2 => $configuration['field'], + 3 => $configuration['datasource'] + ))); + } + $this->fieldSpecification->alias = $alias; + $this->fieldSpecification->title = $title; + } /** diff --git a/Civi/DataProcessor/Output/Api.php b/Civi/DataProcessor/Output/Api.php index 9817db18..762cee94 100644 --- a/Civi/DataProcessor/Output/Api.php +++ b/Civi/DataProcessor/Output/Api.php @@ -166,6 +166,9 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte $result['count'] = count($result['values']); } + + $result = $this->checkForErrors($result); + return $result; } @@ -273,6 +276,9 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte $result['count'] = count($result['values']); } + + $result = $this->checkForErrors($result); + return $result; } @@ -383,14 +389,46 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte 'count' => count($values), 'is_error' => 0, ); + if (isset($params['debug']) && $params['debug']) { $return['debug_info'] = $dataProcessorClass->getDataFlow()->getDebugInformation(); } + $return = $this->checkForErrors($return); + return $return; } } + /** + * Check for errors in the CiviCRM Status messages list + * and if errors are present create a civicrm api return error with the messages in + * the status list + * + * @param $return + * + * @return mixed + */ + protected function checkForErrors($return) { + $session = \CRM_Core_Session::singleton(); + $statuses = $session->getStatus(true); + foreach($statuses as $status) { + if ($status['type'] == 'error') { + $return['is_error'] = 1; + unset($return['values']); + unset($return['count']); + if (!isset($return['error_message'])) { + $return['error_message'] = ""; + } + $return['error_message'] .= " ".$status['text']; + } + } + if (isset($return['error_message'])) { + $return['error_message'] = trim($return['error_message']); + } + return $return; + } + /** * @param int $version * API version. -- GitLab