Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user