Hi gents
I am currently playing around with backend process handlers. The idea: when typing a ZIP code, a backend handler should query a custom table in the DB and return the city (ie: typing 8000, should result in “Zurich”). I tried to follow the documentation here: Adding a Process Handler :: SuiteCRM Documentation
So I added the following code to the public/legacy/custom/modules/Contacts/metadata/editviewdefs.php:
1 =>
array (
0 =>
array (
'name' => 'primary_address_postalcode',
'comment' => 'Postal code for primary address',
'label' => 'LBL_PRIMARY_ADDRESS_POSTALCODE',
),
1 =>
array (
'name' => 'alt_address_postalcode',
'comment' => 'Postal code for alternate address',
'label' => 'LBL_ALT_ADDRESS_POSTALCODE',
),
),
2 =>
array (
0 =>
array (
'name' => 'primary_address_city',
'comment' => 'City for primary address',
'label' => 'LBL_PRIMARY_ADDRESS_CITY',
'logic' => [
'Zip2City' => [
'key' => 'updateValueBackend',
'modes' => ['edit', 'create'],
'params' => [
'fieldDependencies' => ['primary_address_postalcode'],
'process' => 'Zip2City',
'activeOnFields' => [
'primary_address_postalcode' => [
'operator' => 'not-empty',
],
]
]
],
]
),
1 =>
array (
'name' => 'alt_address_city',
'comment' => 'City for alternate address',
'label' => 'LBL_ALT_ADDRESS_CITY',
),
),
Next, I created the handler in config/extensions/defaultExt/modules/Contacts/Service/Fields/Zip2City.php with the following code:
<?php
namespace App\Extension\defaultExt\modules\Contacts\Service\Fields;
use ApiPlatform\Core\Exception\InvalidArgumentException;
use App\Process\Entity\Process;
use App\Process\Service\ProcessHandlerInterface;
class Zip2City implements ProcessHandlerInterface
{
protected const MSG_OPTIONS_NOT_FOUND = 'Process options are not defined';
public const PROCESS_TYPE = 'Zip2City';
/**
* Zip2City constructor.
*/
public function __construct()
{
}
/**
* @inheritDoc
*/
public function getProcessType(): string
{
return self::PROCESS_TYPE;
}
/**
* @inheritDoc
*/
public function requiredAuthRole(): string
{
return 'ROLE_USER';
}
/**
* @inheritDoc
*/
public function getRequiredACLs(Process $process): array
{
$options = $process->getOptions();
$module = $options['module'] ?? '';
$id = $options['id'] ?? '';
$editACLCheck = [
'action' => 'edit',
];
if ($id !== '') {
$editACLCheck['record'] = $id;
}
return [
$module => [
$editACLCheck
],
];
}
/**
* @inheritDoc
*/
public function configure(Process $process): void
{
//This process is synchronous
//We aren't going to store a record on db
//thus we will use process type as the id
$process->setId(self::PROCESS_TYPE);
$process->setAsync(false);
}
/**
* @inheritDoc
*/
public function validate(Process $process): void
{
$options = $process->getOptions();
$type = $options['record']['attributes']['type'] ?? '';
if (empty($type)) {
throw new InvalidArgumentException(self::MSG_OPTIONS_NOT_FOUND);
}
}
/**
* @inheritDoc
*/
public function run(Process $process)
{
global $db;
$options = $process->getOptions();
$zip = $options['record']['attributes']['primary_address_postalcode'] ?? '';
$value = '';
// query the DB
$stmt = $db->prepare('SELECT city FROM zip_to_city WHERE deleted=0 AND zip = ?');
$stmt->bind_param('s', $zip);
$stmt->execute();
$result = $stmt->get_result();
// Return first record and ignor the rest if there are more than 1 records
if ($result && $row = $result->fetch_assoc()) {
$value = $row['city'];
} else {
$value = 'No record found';
}
$responseData = [
'value' => $value
];
$process->setStatus('success');
$process->setMessages([]);
$process->setData($responseData);
}
}
Then I did a Quick Repair & Restore and cleared the Symphony cache (./bin/console cache:clear).
Now, when I enter a ZIP code in the contact form (new or edit) actually nothing happens. I also tried to simplify the handler with a simple “Hello world” but nothing works.
I am quite new with SuiteCRM and would appriciate your help/feedback.
My system: SuiteCRM 8.8 with PHP 8.1.31.
Cheers,
Carsten