pluginDescription->name = 'Universal filters in automations';
$this->pluginDescription->category = 'User management';
$this->pluginDescription->description = '- Filter AcyMailing subscribers based on any data from your database
- Filter users based on email addresses in a specified text';
}
public function getColumnsForSelectedTable()
{
$defaultSelect = acym_select(
[],
acym_getVar('string', 'name', ''),
acym_getVar('string', 'value', 'user_id'),
[
'class' => 'acym__select',
]
);
$table = acym_getVar('string', 'table', '');
if (empty($table)) {
echo wp_kses(
$defaultSelect,
[
'select' => ['class' => [], 'name' => [], 'id' => []],
'option' => ['value' => [], 'selected' => [], 'disabled' => []],
'optgroup' => ['label' => []],
]
);
exit;
}
$elements = acym_getColumns($table, false, false);
if (empty($elements)) {
echo wp_kses(
$defaultSelect,
[
'select' => ['class' => [], 'name' => [], 'id' => []],
'option' => ['value' => [], 'selected' => [], 'disabled' => []],
'optgroup' => ['label' => []],
]
);
exit;
}
$columns = [];
$columns[0] = acym_getVar('string', 'defaultValue', '');
foreach ($elements as $key => $value) {
$columns[$value] = $value;
}
echo wp_kses(
acym_select(
$columns,
acym_getVar('string', 'name', ''),
acym_getVar('string', 'value', 'user_id'),
[
'class' => 'acym__select',
]
),
[
'select' => ['class' => [], 'name' => [], 'id' => []],
'option' => ['value' => [], 'selected' => [], 'disabled' => []],
'optgroup' => ['label' => []],
]
);
exit;
}
public function onAcymDeclareConditions(array &$conditions): void
{
$operator = new OperatorType();
$conditions['classic']['universalfilter'] = new stdClass();
$conditions['classic']['universalfilter']->name = acym_translation('ACYM_SIMPLE_QUERY');
$conditions['classic']['universalfilter']->option = '
';
$firstTable = new stdClass();
$firstTable->text = acym_translation('ACYM_SELECT_TABLE');
$firstTable->value = 0;
$tableChoices = [];
$tableChoices[] = $firstTable;
$tables = acym_getTableList();
foreach ($tables as $oneTable) {
$oneChoice = new stdClass();
$oneChoice->text = $oneTable;
$oneChoice->value = $oneTable;
$tableChoices[] = $oneChoice;
}
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= acym_translation('ACYM_TABLE_NAME');
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= acym_select(
$tableChoices,
'acym_condition[conditions][__numor__][__numand__][universalfilter][conn_table]',
null,
[
'class' => 'acym__select',
'acym-automation-reload' => [
[
'plugin' => __CLASS__,
'trigger' => 'getColumnsForSelectedTable',
'change' => '#universalfilter_column_tochange___numor_____numand__',
'name' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][column]',
'paramFields' => [
'table' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][conn_table]',
'defaultValue' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][column]',
],
],
[
'plugin' => __CLASS__,
'trigger' => 'getColumnsForSelectedTable',
'change' => '#universalfilter_where_tochange___numor_____numand__',
'name' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][wherefield]',
'paramFields' => [
'table' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][conn_table]',
'defaultValue' => 'acym_condition[conditions][__numor__][__numand__][universalfilter][wherefield]',
],
],
],
]
);
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
ob_start();
acym_info(['textShownInTooltip' => 'ACYM_IDENTIFIER_DESC']);
$tooltip = ob_get_clean();
$conditions['classic']['universalfilter']->option .= acym_translation('ACYM_IDENTIFIER').$tooltip;
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
ob_start();
acym_info(['textShownInTooltip' => 'ACYM_CONDITION_DESC']);
$tooltip = ob_get_clean();
$conditions['classic']['universalfilter']->option .= acym_translation('ACYM_CONDITION').$tooltip;
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= $operator->display('acym_condition[conditions][__numor__][__numand__][universalfilter][operator]');
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['universalfilter']->option .= '
';
$conditions['classic']['sqladvanced'] = new stdClass();
$conditions['classic']['sqladvanced']->name = acym_translation('ACYM_ADVANCED_QUERY');
$conditions['classic']['sqladvanced']->option = '';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= acym_select(
[
'email' => 'ACYM_EMAIL',
'cms_id' => 'ACYM_USER_CMSID',
'id' => 'ACYM_USER_ID',
],
'acym_condition[conditions][__numor__][__numand__][sqladvanced][source]',
null,
['class' => 'acym__select'],
'value',
'text',
false,
true
);
$conditions['classic']['sqladvanced']->option .= '
';
$operatorIn = new OperatorInType();
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= $operatorIn->display('acym_condition[conditions][__numor__][__numand__][sqladvanced][type]');
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
'.acym_translation('ACYM_EXTERNAL_SERVER_DESC').'
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['sqladvanced']->option .= '
';
$conditions['classic']['extractaddresses'] = new stdClass();
$conditions['classic']['extractaddresses']->name = acym_translation('ACYM_EXTRACT_ADDRESSES');
$conditions['classic']['extractaddresses']->option = '';
$conditions['classic']['extractaddresses']->option .= '
';
$conditions['classic']['extractaddresses']->option .= '';
$conditions['classic']['extractaddresses']->option .= '
';
$conditions['classic']['extractaddresses']->option .= '
';
}
public function onAcymProcessCondition_universalfilter(&$query, $options, $num, &$conditionNotValid)
{
$this->processConditionFilter_universalfilter($query, $options, $num);
$affectedRows = $query->count();
if (empty($affectedRows)) $conditionNotValid++;
}
private function processConditionFilter_universalfilter(&$query, $options, $num)
{
if (empty($options['conn_table']) || !in_array($options['conn_table'], acym_getTableList()) || empty($options['column'])) return;
$columns = acym_getColumns($options['conn_table'], false, false);
if (empty($columns) || !in_array($options['column'], $columns)) return;
$acyOperator = in_array(strtolower($options['column']), ['email', 'e-mail', 'mail', 'e_mail', 'courriel', 'user_email']) ? 'email' : 'cms_id';
$options['conn_table'] = acym_secureDBColumn($options['conn_table']);
$options['column'] = acym_secureDBColumn($options['column']);
$query->join['universalfilter'.$num] = $options['conn_table'].' AS universalfiltertable'.$num.' ON universalfiltertable'.$num.'.'.$options['column'].' = user.'.$acyOperator;
if (!empty($options['wherefield']) && in_array($options['wherefield'], $columns)) {
$options['wherevalue'] = acym_replaceDate($options['wherevalue']);
$query->where[] = $query->convertQuery('universalfiltertable'.$num, $options['wherefield'], $options['operator'], $options['wherevalue']);
}
}
public function onAcymProcessCondition_sqladvanced(&$query, $options, $num, &$conditionNotValid)
{
$this->processConditionFilter_sqladvanced($query, $options, $num);
$affectedRows = $query->count();
if (empty($affectedRows)) $conditionNotValid++;
}
private function filterError(&$query, $options, $message)
{
if (empty($options['countTotal'])) {
acym_display(acym_translation($message), 'error');
}
$query->where[] = '1 = 0';
}
private function processConditionFilter_sqladvanced(&$query, $options, $num)
{
if (empty($options['query'])) return;
$sqlQuery = strtolower($options['query']);
if (strpos($sqlQuery, 'select') !== 0) {
$this->filterError($query, $options, 'ACYM_WRONG_SQL_QUERY');
return;
}
$blacklistedTerms = ['truncate', 'drop', 'alter', 'update', 'insert'];
foreach ($blacklistedTerms as $blacklistedTerm) {
if (strpos($sqlQuery, $blacklistedTerm) !== false) {
$this->filterError($query, $options, 'ACYM_WRONG_SQL_QUERY');
return;
}
}
if (!in_array($options['source'], ['id', 'email', 'cms_id'])) $options['source'] = 'cms_id';
$options['query'] = acym_replaceDate($options['query']);
$where = 'user.'.$options['source'];
$where .= $options['type'] == 'in' ? ' IN ' : ' NOT IN ';
// Connecting to the current db
if (empty($options['conn_host'])) {
$query->where[] = $where.'('.$options['query'].')';
return;
}
if (empty($options['conn_db']) || empty($options['conn_login']) || empty($options['conn_pwd'])) {
$this->filterError($query, $options, 'ACYM_MISSING_PARAMETERS');
return;
}
// We need to connect to another database
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_connect
$conn = @mysqli_connect($options['conn_host'], $options['conn_login'], $options['conn_pwd'], $options['conn_db']);
if (empty($conn)) {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_connect_error
$this->filterError($query, $options, acym_translationSprintf('ACYM_ERROR_CONNECTING', $options['conn_host'].' '.$options['conn_db']).': '.mysqli_connect_error());
return;
}
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_query
$myQuery = mysqli_query($conn, $options['query']);
if (!$myQuery) {
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_error
$this->filterError($query, $options, acym_translation('ACYM_ERROR').': '.mysqli_error($conn));
return;
}
$resultArray = [];
// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_fetch_row
while ($row = mysqli_fetch_row($myQuery)) {
$resultArray[] = acym_escapeDB($row[0]);
}
if (empty($resultArray)) $resultArray = ['"-1"'];
$myQuery->close();
$conn->close();
$query->where[] = $where.' ('.implode(',', $resultArray).') ';
}
public function onAcymProcessCondition_extractaddresses(&$query, $options, $num, &$conditionNotValid)
{
$this->processConditionFilter_extractaddresses($query, $options, $num);
$affectedRows = $query->count();
if (empty($affectedRows)) $conditionNotValid++;
}
private function processConditionFilter_extractaddresses(&$query, $options, $num)
{
if (empty($options['text'])) return;
preg_match_all('/'.acym_getEmailRegex().'/i', $options['text'], $results);
$allEmails = empty($results[0]) ? ['-1'] : $results[0];
$query->where[] = 'user.email IN ("'.implode('","', $allEmails).'")';
}
public function onAcymDeclareSummary_conditions(&$automationCondition)
{
$this->summaryConditionFilters($automationCondition);
}
private function summaryConditionFilters(&$automationCondition)
{
if (!empty($automationCondition['universalfilter'])) {
$finalText = acym_translationSprintf('ACYM_UNIVERSAL_FILTER_SUMMARY', $automationCondition['universalfilter']['conn_table']);
if (!empty($automationCondition['universalfilter']['wherefield'])) {
$finalText .= '
'.acym_translationSprintf(
'ACYM_CONDITION_ACY_FIELD_SUMMARY',
$automationCondition['universalfilter']['wherefield'],
$automationCondition['universalfilter']['operator'],
$automationCondition['universalfilter']['wherevalue']
);
}
$automationCondition = $finalText;
}
if (!empty($automationCondition['sqladvanced'])) {
$automationCondition = acym_translation('ACYM_ADVANCED_QUERY_SUMMARY');
}
if (!empty($automationCondition['extractaddresses'])) {
$automationCondition = acym_translation('ACYM_EXTRACT_ADDRESSES_SUMMARY');
}
if (!empty($automationCondition['import'])) {
$automationCondition = acym_translation('ACYM_IMPORT_FILTER_SUMMARY');
}
}
public function onAcymDeclareFilters(array &$filters): void
{
$this->filtersFromConditions($filters);
$filters['import'] = new stdClass();
$filters['import']->name = acym_translation('ACYM_IMPORT_DATABASE');
$filters['import']->option = '';
$filters['import']->option .= '
';
$filters['import']->option .= '
'.acym_translation('ACYM_IMPORT_DATABASE').'
';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= acym_translation('ACYM_TABLE_NAME').'*';
$filters['import']->option .= '
';
// When selecting the table, all the dropdowns will be loaded to let the user select the column he wants
$tableSelectRefresh = [
[
'plugin' => __CLASS__,
'trigger' => 'getColumnsForSelectedTable',
'change' => '#import_where_tochange___numor_____numand__',
'name' => 'acym_action[filters][__numor__][__numand__][import][wherefield]',
'paramFields' => [
'table' => 'acym_action[filters][__numor__][__numand__][import][conn_table]',
'defaultValue' => 'acym_action[filters][__numor__][__numand__][import][wherefield]',
],
],
];
$columnsAssignmentOptions = '';
$userFields = acym_getColumns('user');
// Show the email field first
unset($userFields[array_search('email', $userFields)]);
array_unshift($userFields, 'email');
foreach ($userFields as $oneUserField) {
if (in_array($oneUserField, ['id', 'key', 'automation'])) continue;
$tableSelectRefresh[] = [
'plugin' => __CLASS__,
'trigger' => 'getColumnsForSelectedTable',
'change' => '#import_'.$oneUserField.'_tochange___numor_____numand__',
'name' => 'acym_action[filters][__numor__][__numand__][import]['.$oneUserField.']',
'paramFields' => [
'table' => 'acym_action[filters][__numor__][__numand__][import][conn_table]',
'defaultValue' => 'acym_action[filters][__numor__][__numand__][import]['.$oneUserField.']',
],
];
$columnsAssignmentOptions .= '
';
$columnsAssignmentOptions .= '
';
$columnsAssignmentOptions .= $oneUserField.($oneUserField === 'email' ? '*' : '');
$columnsAssignmentOptions .= '
';
$columnsAssignmentOptions .= '
';
$columnsAssignmentOptions .= '';
$columnsAssignmentOptions .= '
';
$columnsAssignmentOptions .= '
';
}
$firstTable = new stdClass();
$firstTable->text = acym_translation('ACYM_SELECT_TABLE');
$firstTable->value = 0;
$tableChoices = [];
$tableChoices[] = $firstTable;
$tables = acym_getTableList();
foreach ($tables as $oneTable) {
$oneChoice = new stdClass();
$oneChoice->text = $oneTable;
$oneChoice->value = $oneTable;
$tableChoices[] = $oneChoice;
}
$filters['import']->option .= '
';
$filters['import']->option .= acym_select(
$tableChoices,
'acym_action[filters][__numor__][__numand__][import][conn_table]',
null,
[
'class' => 'acym__select',
'acym-automation-reload' => $tableSelectRefresh,
]
);
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= acym_translation('ACYM_WHERE');
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$operator = new OperatorType();
$filters['import']->option .= $operator->display('acym_action[filters][__numor__][__numand__][import][operator]');
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '
';
$filters['import']->option .= '
'.acym_translation('ACYM_FIELD_MATCHING').'
';
$filters['import']->option .= '
';
$filters['import']->option .= $columnsAssignmentOptions;
$filters['import']->option .= '
';
}
public function onAcymProcessFilterCount_universalfilter(&$query, $options, $num)
{
$this->onAcymProcessFilter_universalfilter($query, $options, $num);
return acym_translationSprintf('ACYM_SELECTED_USERS', $query->count());
}
public function onAcymProcessFilter_universalfilter(&$query, $options, $num)
{
$this->processConditionFilter_universalfilter($query, $options, $num);
}
public function onAcymProcessFilterCount_sqladvanced(&$query, $options, $num)
{
$this->onAcymProcessFilter_sqladvanced($query, $options, $num);
return acym_translationSprintf('ACYM_SELECTED_USERS', $query->count());
}
public function onAcymProcessFilter_sqladvanced(&$query, $options, $num)
{
$this->processConditionFilter_sqladvanced($query, $options, $num);
}
public function onAcymProcessFilterCount_extractaddresses(&$query, $options, $num)
{
$this->onAcymProcessFilter_extractaddresses($query, $options, $num);
return acym_translationSprintf('ACYM_SELECTED_USERS', $query->count());
}
public function onAcymProcessFilter_extractaddresses(&$query, $options, $num)
{
$this->processConditionFilter_extractaddresses($query, $options, $num);
}
public function onAcymProcessFilterCount_import(&$query, $options, $num)
{
return acym_translation('ACYM_NO_PREVIEW_AVAILABLE');
}
public function onAcymProcessFilter_import(&$query, $options, $num)
{
// Make sure we have the needed information
if (empty($options['conn_table']) || empty($options['email']) || !empty($options['countTotal'])) {
$query->where[] = '1 = 0';
return;
}
$columns = acym_getColumns($options['conn_table'], false, false);
if (empty($columns)) {
$query->where[] = '1 = 0';
return;
}
$importHelper = new ImportHelper();
$importHelper->tableName = acym_secureDBColumn($options['conn_table']);
// Filter the imported users in case the user selected some actions
$newFilter = [];
$newFilter['query'] = 'SELECT import.`'.acym_secureDBColumn($options['email']).'` FROM '.acym_secureDBColumn($options['conn_table']).' AS import ';
$newFilter['query'] .= 'WHERE import.`'.acym_secureDBColumn($options['email']).'` LIKE "%@%"';
$newFilter['type'] = 'in';
$newFilter['source'] = 'email';
if (!empty($options['wherefield']) && in_array($options['wherefield'], $columns)) {
$options['wherevalue'] = acym_replaceDate($options['wherevalue']);
$newFilter['query'] .= ' AND '.$query->convertQuery('import', $options['wherefield'], $options['operator'], $options['wherevalue']);
$importHelper->dbWhere[] = $query->convertQuery('', $options['wherefield'], $options['operator'], $options['wherevalue']);
}
// Only keep the fields mapping options
unset($options['conn_table']);
unset($options['wherefield']);
unset($options['operator']);
unset($options['wherevalue']);
$importHelper->fieldsMap = $options;
if (!$importHelper->database(true)) {
$query->where[] = '1 = 0';
return;
}
$this->onAcymProcessFilter_sqladvanced($query, $newFilter, $num);
}
public function onAcymDeclareSummary_filters(&$automationFilter)
{
$this->summaryConditionFilters($automationFilter);
}
}