mautic / app /bundles /WebhookBundle /Helper /CampaignHelper.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
raw
history blame contribute delete
5.9 kB
<?php
namespace Mautic\WebhookBundle\Helper;
use Doctrine\Common\Collections\Collection;
use GuzzleHttp\Client;
use Mautic\CoreBundle\Helper\AbstractFormFieldHelper;
use Mautic\LeadBundle\Entity\Lead;
use Mautic\LeadBundle\Helper\TokenHelper;
use Mautic\LeadBundle\Model\CompanyModel;
use Mautic\WebhookBundle\Event\WebhookRequestEvent;
use Mautic\WebhookBundle\WebhookEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class CampaignHelper
{
/**
* Cached contact values in format [contact_id => [key1 => val1, key2 => val1]].
*/
private array $contactsValues = [];
public function __construct(
protected Client $client,
protected CompanyModel $companyModel,
private EventDispatcherInterface $dispatcher
) {
}
/**
* Prepares the neccessary data transformations and then makes the HTTP request.
*/
public function fireWebhook(array $config, Lead $contact): void
{
$payload = $this->getPayload($config, $contact);
$headers = $this->getHeaders($config, $contact);
$url = rawurldecode(TokenHelper::findLeadTokens($config['url'], $this->getContactValues($contact), true));
$webhookRequestEvent = new WebhookRequestEvent($contact, $url, $headers, $payload);
$this->dispatcher->dispatch($webhookRequestEvent, WebhookEvents::WEBHOOK_ON_REQUEST);
$this->makeRequest(
$webhookRequestEvent->getUrl(),
$config['method'],
$config['timeout'],
$webhookRequestEvent->getHeaders(),
$webhookRequestEvent->getPayload()
);
}
/**
* Gets the payload fields from the config and if there are tokens it translates them to contact values.
*/
private function getPayload(array $config, Lead $contact): array
{
$payload = !empty($config['additional_data']['list']) ? $config['additional_data']['list'] : '';
$payload = array_flip(AbstractFormFieldHelper::parseList($payload));
return $this->getTokenValues($payload, $contact);
}
/**
* Gets the payload fields from the config and if there are tokens it translates them to contact values.
*/
private function getHeaders(array $config, Lead $contact): array
{
$headers = !empty($config['headers']['list']) ? $config['headers']['list'] : '';
$headers = array_flip(AbstractFormFieldHelper::parseList($headers));
return $this->getTokenValues($headers, $contact);
}
/**
* @param string $url
* @param string $method
* @param int $timeout
*
* @throws \InvalidArgumentException
* @throws \OutOfRangeException
*/
private function makeRequest($url, $method, $timeout, array $headers, array $payload): void
{
switch ($method) {
case 'get':
$payload = $url.(parse_url($url, PHP_URL_QUERY) ? '&' : '?').http_build_query($payload);
$response = $this->client->get($payload, [
\GuzzleHttp\RequestOptions::HEADERS => $headers,
\GuzzleHttp\RequestOptions::TIMEOUT => $timeout,
]);
break;
case 'post':
case 'put':
case 'patch':
$headers = array_change_key_case($headers);
$options = [
\GuzzleHttp\RequestOptions::HEADERS => $headers,
\GuzzleHttp\RequestOptions::TIMEOUT => $timeout,
];
if (array_key_exists('content-type', $headers) && 'application/json' == strtolower($headers['content-type'])) {
$options[\GuzzleHttp\RequestOptions::BODY] = json_encode($payload);
} else {
$options[\GuzzleHttp\RequestOptions::FORM_PARAMS] = $payload;
}
$response = $this->client->request($method, $url, $options);
break;
case 'delete':
$response = $this->client->delete($url, [
\GuzzleHttp\RequestOptions::HEADERS => $headers,
\GuzzleHttp\RequestOptions::TIMEOUT => $timeout,
]);
break;
default:
throw new \InvalidArgumentException('HTTP method "'.$method.' is not supported."');
}
if (!in_array($response->getStatusCode(), [200, 201])) {
throw new \OutOfRangeException('Campaign webhook response returned error code: '.$response->getStatusCode());
}
}
/**
* Translates tokens to values.
*/
private function getTokenValues(array $rawTokens, Lead $contact): array
{
$values = [];
$contactValues = $this->getContactValues($contact);
foreach ($rawTokens as $key => $value) {
$values[$key] = rawurldecode(TokenHelper::findLeadTokens($value, $contactValues, true));
}
return $values;
}
/**
* Gets array of contact values.
*
* @return array
*/
private function getContactValues(Lead $contact)
{
if (empty($this->contactsValues[$contact->getId()])) {
$this->contactsValues[$contact->getId()] = $contact->getProfileFields();
$this->contactsValues[$contact->getId()]['ipAddress'] = $this->ipAddressesToCsv($contact->getIpAddresses());
$this->contactsValues[$contact->getId()]['companies'] = $this->companyModel->getRepository()->getCompaniesByLeadId($contact->getId());
}
return $this->contactsValues[$contact->getId()];
}
private function ipAddressesToCsv(Collection $ipAddresses): string
{
$addresses = [];
foreach ($ipAddresses as $ipAddress) {
$addresses[] = $ipAddress->getIpAddress();
}
return implode(',', $addresses);
}
}