diff --git a/src/Analytics/Adapter.php b/src/Analytics/Adapter.php index cbb3f79..f368c40 100644 --- a/src/Analytics/Adapter.php +++ b/src/Analytics/Adapter.php @@ -3,7 +3,6 @@ namespace Utopia\Analytics; use Exception; -use Utopia\CLI\Console; abstract class Adapter { @@ -95,16 +94,12 @@ public function setUserAgent(string $userAgent): self /** * Creates an Event on the remote analytics platform. + * + * @throws Exception */ public function createEvent(Event $event): bool { - try { - return $this->send($event); - } catch (\Exception $e) { - $this->logError($e); - - return false; - } + return $this->send($event); } /** @@ -212,20 +207,4 @@ protected function flatten(array $data, string $prefix = ''): array return $output; } - - /** - * Log Error - * - * @return void - */ - protected function logError(Exception $e) - { - Console::error('[Error] '.$this->getName().' Error: '); - Console::error('[Error] Type: '.get_class($e)); - Console::error('[Error] Message: '.$e->getMessage()); - Console::error('[Error] File: '.$e->getFile()); - Console::error('[Error] Line: '.$e->getLine()); - Console::error('[Error] Trace: '); - Console::error($e->getTraceAsString()); - } } diff --git a/src/Analytics/Adapter/HubSpot.php b/src/Analytics/Adapter/HubSpot.php index 7677398..f26c000 100644 --- a/src/Analytics/Adapter/HubSpot.php +++ b/src/Analytics/Adapter/HubSpot.php @@ -56,31 +56,25 @@ public function getName(): string */ public function contactExists(string $email): bool|int { - try { - $result = $this->call('POST', '/crm/v3/objects/contacts/search', [ - 'Content-Type' => 'application/json', - ], [ - 'filterGroups' => [[ - 'filters' => [ - [ - 'value' => $email, - 'propertyName' => 'email', - 'operator' => 'EQ', - ], + $result = $this->call('POST', '/crm/v3/objects/contacts/search', [ + 'Content-Type' => 'application/json', + ], [ + 'filterGroups' => [[ + 'filters' => [ + [ + 'value' => $email, + 'propertyName' => 'email', + 'operator' => 'EQ', ], - ], ], - ]); + ], + ], ], + ]); - $result = json_decode($result, true); - - if ($result && $result['total'] > 0 && count($result['results']) > 0) { - return $result['results'][0]['id']; - } else { - return false; - } - } catch (\Exception $e) { - $this->logError($e); + $result = json_decode($result, true); + if ($result && $result['total'] > 0 && count($result['results']) > 0) { + return $result['results'][0]['id']; + } else { return false; } } @@ -97,17 +91,11 @@ public function createContact(string $email, string $firstName = '', string $las 'phone' => $phone, ]]; - try { - $this->call('POST', '/crm/v3/objects/contacts', [ - 'Content-Type' => 'application/json', - ], $body); + $this->call('POST', '/crm/v3/objects/contacts', [ + 'Content-Type' => 'application/json', + ], $body); - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } + return true; } /** @@ -126,18 +114,14 @@ public function updateContact(string $contactId, string $email, string $firstNam $this->call('PATCH', '/crm/v3/objects/contacts/'.$contactId, [ 'Content-Type' => 'application/json', ], $body); - - return true; } catch (\Exception $e) { if ($e->getCode() == 400) { // No changes to make return true; } - - $this->logError($e); - - return false; } + + return true; } /** @@ -151,17 +135,11 @@ public function deleteContact(string $email): bool return false; } - try { - $this->call('DELETE', '/crm/v3/objects/contacts/'.$contact, [ - 'Content-Type' => 'application/json', - ]); - - return true; - } catch (\Exception $e) { - $this->logError($e); + $this->call('DELETE', '/crm/v3/objects/contacts/'.$contact, [ + 'Content-Type' => 'application/json', + ]); - return false; - } + return true; } /** @@ -169,31 +147,25 @@ public function deleteContact(string $email): bool */ public function accountExists(string $name): bool|int { - try { - $result = $this->call('POST', '/crm/v3/objects/companies/search', [ - 'Content-Type' => 'application/json', - ], [ - 'filterGroups' => [[ - 'filters' => [ - [ - 'value' => $name, - 'propertyName' => 'name', - 'operator' => 'EQ', - ], + $result = $this->call('POST', '/crm/v3/objects/companies/search', [ + 'Content-Type' => 'application/json', + ], [ + 'filterGroups' => [[ + 'filters' => [ + [ + 'value' => $name, + 'propertyName' => 'name', + 'operator' => 'EQ', ], - ]], - ]); - - $result = json_decode($result, true); + ], + ]], + ]); - if ($result && $result['total'] > 0 && count($result['results']) > 0) { - return $result['results'][0]['id']; - } else { - return false; - } - } catch (\Exception $e) { - $this->logError($e); + $result = json_decode($result, true); + if ($result && $result['total'] > 0 && count($result['results']) > 0) { + return $result['results'][0]['id']; + } else { return false; } } @@ -208,17 +180,11 @@ public function createAccount(string $name, string $url = ''): bool 'domain' => $url, ]]; - try { - $this->call('POST', '/crm/v3/objects/companies', [ - 'Content-Type' => 'application/json', - ], $body); + $this->call('POST', '/crm/v3/objects/companies', [ + 'Content-Type' => 'application/json', + ], $body); - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } + return true; } /** @@ -235,18 +201,14 @@ public function updateAccount(string $accountId, string $name, string $url = '', $this->call('PATCH', '/crm/v3/objects/companies/'.$accountId, [ 'Content-Type' => 'application/json', ], $body); - - return true; } catch (\Exception $e) { if ($e->getCode() == 400) { // No changes to make return true; } - - $this->logError($e); - - return false; } + + return true; } /** @@ -254,17 +216,11 @@ public function updateAccount(string $accountId, string $name, string $url = '', */ public function deleteAccount(string $accountId): bool { - try { - $this->call('DELETE', '/crm/v3/objects/companies/'.$accountId, [ - 'Content-Type' => 'application/json', - ]); - - return true; - } catch (\Exception $e) { - $this->logError($e); + $this->call('DELETE', '/crm/v3/objects/companies/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); - return false; - } + return true; } /** @@ -275,39 +231,32 @@ public function deleteAccount(string $accountId): bool public function syncAssociation(string $accountId, string $contactId, string $role = ''): bool { // See if the association already exists + $response = $this->call('GET', '/crm/v4/objects/contact/'.$accountId.'/associations/company'); - try { - $response = $this->call('GET', '/crm/v4/objects/contact/'.$accountId.'/associations/company'); + $response = json_decode($response, true); - $response = json_decode($response, true); + $associationId = null; - $associationId = null; - - foreach ($response['results'] as $association) { - if ($association['from']['id'] == $contactId) { - $associationId = $association['id']; - } + foreach ($response['results'] as $association) { + if ($association['from']['id'] == $contactId) { + $associationId = $association['id']; } + } - if (empty($associationId)) { - // Create the association - $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ - 'Content-Type' => 'application/json', - ]); - } else { - // Delete and recreate the association - $this->call('DELETE', '/crm/v4/objects/contact/'.$contactId.'/associations/company/'.$accountId, [ - 'Content-Type' => 'application/json', - ]); - - $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ - 'Content-Type' => 'application/json', - ]); - } - } catch (\Exception $e) { - $this->logError($e); + if (empty($associationId)) { + // Create the association + $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); + } else { + // Delete and recreate the association + $this->call('DELETE', '/crm/v4/objects/contact/'.$contactId.'/associations/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); - return false; + $this->call('PUT', '/crm/v4/objects/contact/'.$contactId.'/associations/default/company/'.$accountId, [ + 'Content-Type' => 'application/json', + ]); } return true; @@ -318,16 +267,10 @@ public function syncAssociation(string $accountId, string $contactId, string $ro */ public function addToList(int $listId, int $contactId): bool { - try { - $this->call('PUT', '/crm/v3/lists/'.$listId.'/memberships/add', [ - 'Content-Type' => 'application/json', - ], [$contactId]); + $this->call('PUT', '/crm/v3/lists/'.$listId.'/memberships/add', [ + 'Content-Type' => 'application/json', + ], [$contactId]); - return true; - } catch (\Exception $e) { - $this->logError($e); - - return false; - } + return true; } } diff --git a/src/Analytics/Adapter/Orbit.php b/src/Analytics/Adapter/Orbit.php index 33477ce..744cf3d 100644 --- a/src/Analytics/Adapter/Orbit.php +++ b/src/Analytics/Adapter/Orbit.php @@ -40,6 +40,30 @@ public function __construct(string $workspaceId, string $apiKey, string $dataOri $this->dataOrigin = $dataOrigin; } + public function cleanup(array $props): array + { + $props = array_filter($props, fn ($value) => ! is_null($value) && $value !== ''); + + // Flatten arrays + $flatten = function ($array) use (&$flatten) { + $return = []; + + foreach ($array as $key => $value) { + if (is_array($value)) { + $return = array_merge($return, $flatten($value)); + } else { + $return[$key] = $value; + } + } + + return $return; + }; + + $props = $flatten($props); + + return $props; + } + /** * Creates an Event on the remote analytics platform. Requires email prop. */ @@ -59,6 +83,23 @@ public function send(Event $event): bool $tags[] = $event->getProp('code'); } + $props = $this->cleanup($event->getProps()); + + $properties = array_map(function ($value) { + if (is_array($value)) { + var_dump($value); + $value = implode(',', $value); + } + + // Allow only alphanumeric characters and commas + $value = preg_replace('/[^a-zA-Z0-9,]/', '', $value); + + return $value; + }, $props); + + unset($properties['email']); + unset($properties['name']); + $activity = [ 'title' => $event->getName(), 'activity_type_key' => $event->getType(), @@ -68,18 +109,9 @@ public function send(Event $event): bool 'name' => $event->getProp('name'), 'tags_to_add' => $tags, ], - 'properties' => array_map(function ($value) { - if (is_array($value)) { - return json_encode($value); - } - - return $value; - }, array_filter($event->getProps(), fn ($value) => ! is_null($value) && $value !== '')), + 'properties' => $properties ?? [], ]; - unset($activity['properties']['email']); - unset($activity['properties']['name']); - $activity = array_filter($activity, fn ($value) => ! is_null($value) && $value !== ''); $this->call('POST', $this->endpoint.'/activities', [ diff --git a/tests/Analytics/AnalyticsTest.php b/tests/Analytics/AnalyticsTest.php index 5efd84c..bc2fdae 100644 --- a/tests/Analytics/AnalyticsTest.php +++ b/tests/Analytics/AnalyticsTest.php @@ -217,7 +217,7 @@ public function testOrbit(): void $event->setType('testEvent') ->setName('testEvent') ->setUrl('https://www.appwrite.io/docs/installation') - ->setProps(['category' => 'testEvent', 'email' => 'analytics@utopiaphp.com', 'tags' => ['test', 'test2']]); + ->setProps(['category' => 'testEvent', 'email' => 'analytics@utopiaphp.com', 'tags' => ['test', 'test2', ['test3' => 'test4', ['test5' => 'test6']]]]); $this->assertTrue($this->orbit->send($event)); $this->assertTrue($this->orbit->validate($event));