Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Extensions
dataprocessor
Commits
11671073
Commit
11671073
authored
Feb 11, 2020
by
jaapjansma
Browse files
Added exposure of aggregation on search/report
parent
2792abdf
Changes
14
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
11671073
...
...
@@ -4,6 +4,7 @@
*
Change Group Filter so that it also works with smart groups
*
Fixed bug with date filter
*
Added date group by function to date output field handler.
*
Added exposure of Aggregation on the Search/Report output.
# Version 1.1.0
...
...
CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php
View file @
11671073
...
...
@@ -66,7 +66,7 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
$dataProcessorName
=
$this
->
getDataProcessorName
();
$sql
=
"
SELECT civicrm_data_processor.id as data_processor_id, civicrm_data_processor_output.id AS output_id
FROM civicrm_data_processor
FROM civicrm_data_processor
INNER JOIN civicrm_data_processor_output ON civicrm_data_processor.id = civicrm_data_processor_output.data_processor_id
WHERE is_active = 1 AND civicrm_data_processor.name = %1 AND civicrm_data_processor_output.type = %2
"
;
...
...
@@ -181,6 +181,7 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
$filterElements
[
$fieldSpec
->
alias
][
'template'
]
=
$filterHandler
->
getTemplateFileName
();
}
$this
->
assign
(
'filters'
,
$filterElements
);
$this
->
assign
(
'additional_criteria_template'
,
$this
->
getAdditionalCriteriaTemplate
());
}
}
...
...
@@ -193,4 +194,13 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
protected
function
getCriteriaElementSize
()
{
return
'full'
;
}
/**
* Returns the name of the additional criteria template.
*
* @return false|String
*/
protected
function
getAdditionalCriteriaTemplate
()
{
return
false
;
}
}
CRM/DataprocessorSearch/Form/AbstractSearch.php
View file @
11671073
...
...
@@ -228,6 +228,8 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
$sortFieldName
=
$sortField
[
'name'
];
}
$this
->
alterDataProcessor
(
$this
->
dataProcessorClass
);
$output
=
civicrm_api3
(
"DataProcessorOutput"
,
"getsingle"
,
array
(
'id'
=>
$export_id
));
$outputClass
=
$factory
->
getOutputByName
(
$output
[
'type'
]);
if
(
$outputClass
instanceof
\
Civi\DataProcessor\Output\ExportOutputInterface
)
{
...
...
CRM/DataprocessorSearch/Form/Search.php
View file @
11671073
...
...
@@ -90,4 +90,88 @@ class CRM_DataprocessorSearch_Form_Search extends CRM_DataprocessorSearch_Form_A
return
$this
->
_taskList
;
}
/**
* Build the criteria form
*/
protected
function
buildCriteriaForm
()
{
parent
::
buildCriteriaForm
();
$this
->
buildAggregateForm
();
}
/**
* Returns the name of the additional criteria template.
*
* @return false|String
*/
protected
function
getAdditionalCriteriaTemplate
()
{
if
(
isset
(
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
&&
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
{
return
"CRM/DataprocessorSearch/Form/Criteria/AggregateCriteria.tpl"
;
}
return
false
;
}
/**
* Build the aggregate form
*/
protected
function
buildAggregateForm
()
{
if
(
!
isset
(
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
||
!
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
{
return
;
}
$size
=
$this
->
getCriteriaElementSize
();
$sizeClass
=
'huge'
;
$minWidth
=
'min-width: 250px;'
;
if
(
$size
==
'compact'
)
{
$sizeClass
=
'medium'
;
$minWidth
=
''
;
}
$aggregateFields
=
array
();
$defaults
=
array
();
foreach
(
$this
->
dataProcessorClass
->
getDataFlow
()
->
getOutputFieldHandlers
()
as
$outputFieldHandler
)
{
if
(
$outputFieldHandler
instanceof
\
Civi\DataProcessor\FieldOutputHandler\OutputHandlerAggregate
)
{
$aggregateFields
[
$outputFieldHandler
->
getAggregateFieldSpec
()
->
alias
]
=
$outputFieldHandler
->
getOutputFieldSpecification
()
->
title
;
if
(
$outputFieldHandler
->
isAggregateField
())
{
$defaults
[]
=
$outputFieldHandler
->
getAggregateFieldSpec
()
->
alias
;
}
}
}
$this
->
add
(
'select'
,
"aggregateFields"
,
''
,
$aggregateFields
,
false
,
[
'style'
=>
$minWidth
,
'class'
=>
'crm-select2 '
.
$sizeClass
,
'multiple'
=>
TRUE
,
'placeholder'
=>
E
::
ts
(
'- Select -'
),
]);
$this
->
setDefaults
([
'aggregateFields'
=>
$defaults
]);
}
/**
* Alter the data processor.
*
* Use this function in child classes to add for example additional filters.
*
* E.g. The contact summary tab uses this to add additional filtering on the contact id of
* the displayed contact.
*
* @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass
*/
protected
function
alterDataProcessor
(
\
Civi\DataProcessor\ProcessorType\AbstractProcessorType
$dataProcessorClass
)
{
if
(
isset
(
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
&&
$this
->
dataProcessorOutput
[
'configuration'
][
'expose_aggregate'
])
{
$aggregateFields
=
$this
->
_formValues
[
'aggregateFields'
];
foreach
(
$this
->
dataProcessorClass
->
getDataFlow
()
->
getOutputFieldHandlers
()
as
$outputFieldHandler
)
{
if
(
$outputFieldHandler
instanceof
\
Civi\DataProcessor\FieldOutputHandler\OutputHandlerAggregate
)
{
$alias
=
$outputFieldHandler
->
getAggregateFieldSpec
()
->
alias
;
if
(
in_array
(
$alias
,
$aggregateFields
)
&&
!
$outputFieldHandler
->
isAggregateField
())
{
$outputFieldHandler
->
enableAggregation
();
}
elseif
(
!
in_array
(
$alias
,
$aggregateFields
)
&&
$outputFieldHandler
->
isAggregateField
())
{
$outputFieldHandler
->
disableAggregation
();
}
}
}
}
}
}
CRM/DataprocessorSearch/Search.php
View file @
11671073
...
...
@@ -58,6 +58,7 @@ class CRM_DataprocessorSearch_Search implements UIOutputInterface {
$form
->
add
(
'wysiwyg'
,
'help_text'
,
E
::
ts
(
'Help text for this search'
),
array
(
'rows'
=>
6
,
'cols'
=>
80
));
$form
->
add
(
'checkbox'
,
'expanded_search'
,
E
::
ts
(
'Expand criteria form initially'
));
$form
->
add
(
'checkbox'
,
'expose_aggregate'
,
E
::
ts
(
'Expose aggregate options'
));
// navigation field
$navigationOptions
=
$navigation
->
getNavigationOptions
();
...
...
@@ -91,6 +92,9 @@ class CRM_DataprocessorSearch_Search implements UIOutputInterface {
if
(
isset
(
$output
[
'configuration'
][
'expanded_search'
]))
{
$defaults
[
'expanded_search'
]
=
$output
[
'configuration'
][
'expanded_search'
];
}
if
(
isset
(
$output
[
'configuration'
][
'expose_aggregate'
]))
{
$defaults
[
'expose_aggregate'
]
=
$output
[
'configuration'
][
'expose_aggregate'
];
}
}
}
if
(
!
isset
(
$defaults
[
'permission'
]))
{
...
...
@@ -124,6 +128,7 @@ class CRM_DataprocessorSearch_Search implements UIOutputInterface {
$configuration
[
'hidden_fields'
]
=
$submittedValues
[
'hidden_fields'
];
$configuration
[
'help_text'
]
=
$submittedValues
[
'help_text'
];
$configuration
[
'expanded_search'
]
=
isset
(
$submittedValues
[
'expanded_search'
])
?
$submittedValues
[
'expanded_search'
]
:
false
;
$configuration
[
'expose_aggregate'
]
=
isset
(
$submittedValues
[
'expose_aggregate'
])
?
$submittedValues
[
'expose_aggregate'
]
:
false
;
return
$configuration
;
}
...
...
Civi/DataProcessor/DataFlow/AbstractDataFlow.php
View file @
11671073
...
...
@@ -251,6 +251,18 @@ abstract class AbstractDataFlow {
$this
->
aggregateOutputHandlers
[]
=
$aggregateOutputHandler
;
}
/**
* @param \Civi\DataProcessor\DataFlow\OutputHandlerAggregate $aggregateOutputHandler
*/
public
function
removeAggregateOutputHandler
(
OutputHandlerAggregate
$aggregateOutputHandler
)
{
foreach
(
$this
->
aggregateOutputHandlers
as
$key
=>
$item
)
{
if
(
$item
->
getAggregateFieldSpec
()
->
alias
==
$aggregateOutputHandler
->
getAggregateFieldSpec
()
->
alias
)
{
unset
(
$this
->
aggregateOutputHandlers
[
$key
]);
break
;
}
}
}
/**
* Adds a field for sorting
*
...
...
Civi/DataProcessor/FieldOutputHandler/DateFieldOutputHandler.php
View file @
11671073
...
...
@@ -183,6 +183,38 @@ class DateFieldOutputHandler extends AbstractSimpleFieldOutputHandler implements
return
$value
;
}
/**
* Enable aggregation for this field.
*
* @return void
*/
public
function
enableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
addAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
/**
* Disable aggregation for this field.
*
* @return void
*/
public
function
disableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
removeAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
protected
function
getFunctions
()
{
return
array
(
'date'
=>
array
(
...
...
Civi/DataProcessor/FieldOutputHandler/OptionFieldOutputHandler.php
View file @
11671073
...
...
@@ -11,7 +11,32 @@ use Civi\DataProcessor\Source\SourceInterface;
use
Civi\DataProcessor\DataSpecification\FieldSpecification
;
use
Civi\DataProcessor\FieldOutputHandler\FieldOutput
;
class
OptionFieldOutputHandler
extends
AbstractSimpleFieldOutputHandler
{
class
OptionFieldOutputHandler
extends
AbstractSimpleFieldOutputHandler
implements
OutputHandlerAggregate
{
/**
* @var bool
*/
protected
$isAggregateField
=
false
;
/**
* Initialize the processor
*
* @param String $alias
* @param String $title
* @param array $configuration
* @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $processorType
*/
public
function
initialize
(
$alias
,
$title
,
$configuration
)
{
parent
::
initialize
(
$alias
,
$title
,
$configuration
);
$this
->
isAggregateField
=
isset
(
$configuration
[
'is_aggregate'
])
?
$configuration
[
'is_aggregate'
]
:
false
;
if
(
$this
->
isAggregateField
)
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
addAggregateOutputHandler
(
$this
);
}
}
}
/**
...
...
@@ -63,5 +88,106 @@ class OptionFieldOutputHandler extends AbstractSimpleFieldOutputHandler {
return
false
;
}
/**
* @return \Civi\DataProcessor\DataSpecification\FieldSpecification
*/
public
function
getAggregateFieldSpec
()
{
return
$this
->
inputFieldSpec
;
}
/**
* @return bool
*/
public
function
isAggregateField
()
{
return
$this
->
isAggregateField
;
}
/**
* Enable aggregation for this field.
*
* @return void
*/
public
function
enableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
addAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
/**
* Disable aggregation for this field.
*
* @return void
*/
public
function
disableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
removeAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
/**
* Returns the value. And if needed a formatting could be applied.
* E.g. when the value is a date field and you want to aggregate on the month
* you can then return the month here.
*
* @param $value
*
* @return mixed
*/
public
function
formatAggregationValue
(
$value
)
{
return
$value
;
}
/**
* When this handler has additional configuration you can add
* the fields on the form with this function.
*
* @param \CRM_Core_Form $form
* @param array $field
*/
public
function
buildConfigurationForm
(
\
CRM_Core_Form
$form
,
$field
=
array
())
{
parent
::
buildConfigurationForm
(
$form
,
$field
);
$form
->
add
(
'checkbox'
,
'is_aggregate'
,
E
::
ts
(
'Aggregate on this field'
));
if
(
isset
(
$field
[
'configuration'
]))
{
$configuration
=
$field
[
'configuration'
];
$defaults
=
array
();
if
(
isset
(
$configuration
[
'is_aggregate'
]))
{
$defaults
[
'is_aggregate'
]
=
$configuration
[
'is_aggregate'
];
}
$form
->
setDefaults
(
$defaults
);
}
}
/**
* Process the submitted values and create a configuration array
*
* @param $submittedValues
* @return array
*/
public
function
processConfiguration
(
$submittedValues
)
{
$configuration
=
parent
::
processConfiguration
(
$submittedValues
);
$configuration
[
'is_aggregate'
]
=
isset
(
$submittedValues
[
'is_aggregate'
])
?
$submittedValues
[
'is_aggregate'
]
:
false
;
return
$configuration
;
}
/**
* When this handler has configuration specify the template file name
* for the configuration form.
*
* @return false|string
*/
public
function
getConfigurationTemplateFileName
()
{
return
"CRM/Dataprocessor/Form/Field/Configuration/OptionFieldOutputHandler.tpl"
;
}
}
Civi/DataProcessor/FieldOutputHandler/OutputHandlerAggregate.php
View file @
11671073
...
...
@@ -18,6 +18,21 @@ interface OutputHandlerAggregate {
*/
public
function
isAggregateField
();
/**
* Enable aggregation for this field.
*
* @return void
*/
public
function
enableAggregation
();
/**
* Disable aggregation for this field.
*
* @return void
*/
public
function
disableAggregation
();
/**
* Returns the value. And if needed a formatting could be applied.
* E.g. when the value is a date field and you want to aggregate on the month
...
...
Civi/DataProcessor/FieldOutputHandler/RawFieldOutputHandler.php
View file @
11671073
...
...
@@ -39,6 +39,38 @@ class RawFieldOutputHandler extends AbstractSimpleFieldOutputHandler implements
}
}
/**
* Enable aggregation for this field.
*
* @return void
*/
public
function
enableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
addAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
/**
* Disable aggregation for this field.
*
* @return void
*/
public
function
disableAggregation
()
{
try
{
$dataFlow
=
$this
->
dataSource
->
ensureField
(
$this
->
getAggregateFieldSpec
());
if
(
$dataFlow
)
{
$dataFlow
->
removeAggregateOutputHandler
(
$this
);
}
}
catch
(
\
Exception
$e
)
{
// Do nothing.
}
}
/**
* When this handler has additional configuration you can add
* the fields on the form with this function.
...
...
templates/CRM/Dataprocessor/Form/Field/Configuration/OptionFieldOutputHandler.tpl
0 → 100644
View file @
11671073
{
crmScope
extensionKey
=
'dataprocessor'
}
{
include
file
=
"CRM/Dataprocessor/Form/Field/Configuration/SimpleFieldOutputHandler.tpl"
}
<div
class=
"crm-section"
>
<div
class=
"label"
>
{
$form.is_aggregate.label
}
</div>
<div
class=
"content"
>
{
$form.is_aggregate.html
}
</div>
<div
class=
"clear"
></div>
</div>
{/
crmScope
}
templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl
View file @
11671073
...
...
@@ -17,7 +17,11 @@
{
foreach
from
=
$filters
key
=
filterName
item
=
filter
}
{
include
file
=
$filter.template
filterName
=
$filter.alias
filter
=
$filter.filter
}
{/
foreach
}
{
if
$additional_criteria_template
}
{
include
file
=
$additional_criteria_template
}
{/
if
}
</table>
<div
class=
"crm-submit-buttons"
>
{
include
file
=
"CRM/common/formButtons.tpl"
location
=
"botton"
}
</div>
</div>
</div>
...
...
templates/CRM/DataprocessorSearch/Form/Criteria/AggregateCriteria.tpl
0 → 100644
View file @
11671073
{
crmScope
extensionKey
=
'dataprocessor'
}
<tr>
<td
class=
"label"
>
{
ts
}
Aggregate
{/
ts
}
</td>
<td>
</td>
<td>
{
$form.aggregateFields.html
}
</td>
</tr>
{/
crmScope
}
templates/CRM/DataprocessorSearch/Form/OutputConfiguration/Search.tpl
View file @
11671073
...
...
@@ -29,6 +29,11 @@
<div
class=
"content"
>
{
$form.expanded_search.html
}
</div>
<div
class=
"clear"
></div>
</div>
<div
class=
"crm-section"
>
<div
class=
"label"
>
{
$form.expose_aggregate.label
}
</div>
<div
class=
"content"
>
{
$form.expose_aggregate.html
}
</div>
<div
class=
"clear"
></div>
</div>
<div
class=
"crm-section"
>
<div
class=
"label"
>
{
$form.help_text.label
}
</div>
<div
class=
"content"
>
{
$form.help_text.html
}
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment