diff --git a/src/Model/Entity/WebAnalytics/Page.php b/src/Model/Entity/WebAnalytics/Page.php new file mode 100644 index 0000000..64b7c85 --- /dev/null +++ b/src/Model/Entity/WebAnalytics/Page.php @@ -0,0 +1,51 @@ +") + * @JMS\SerializedName("pages") + */ + public $pages; + + /** + * @var string + * + * @JMS\Type("string") + * @JMS\SerializedName("clientId") + */ + public $clientId; + + /** + * @var string + * + * @JMS\Type("string") + * @JMS\SerializedName("site") + */ + public $site; +} diff --git a/src/Model/Request/WebAnalytics/VisitsUploadRequest.php b/src/Model/Request/WebAnalytics/VisitsUploadRequest.php new file mode 100644 index 0000000..afb9323 --- /dev/null +++ b/src/Model/Request/WebAnalytics/VisitsUploadRequest.php @@ -0,0 +1,41 @@ +") + * @Form\SerializedName("visits") + * @Form\JsonField() + */ + public $visits; + + /** + * VisitsUploadRequest constructor. + * + * @param \RetailCrm\Api\Model\Entity\WebAnalytics\Visit[]|null $visits + */ + public function __construct(?array $visits = null) + { + if (null !== $visits) { + $this->visits = $visits; + } + } +} diff --git a/src/Model/Response/WebAnalytics/VisitsUploadResponse.php b/src/Model/Response/WebAnalytics/VisitsUploadResponse.php new file mode 100644 index 0000000..8343cfc --- /dev/null +++ b/src/Model/Response/WebAnalytics/VisitsUploadResponse.php @@ -0,0 +1,30 @@ +") + * @JMS\SerializedName("failedVisits") + */ + public $failedVisits; +} diff --git a/src/ResourceGroup/WebAnalytics.php b/src/ResourceGroup/WebAnalytics.php index b15356f..b654977 100644 --- a/src/ResourceGroup/WebAnalytics.php +++ b/src/ResourceGroup/WebAnalytics.php @@ -12,8 +12,10 @@ namespace RetailCrm\Api\ResourceGroup; use RetailCrm\Api\Enum\RequestMethod; use RetailCrm\Api\Model\Request\WebAnalytics\ClientIdUploadRequest; use RetailCrm\Api\Model\Request\WebAnalytics\SourcesUploadRequest; +use RetailCrm\Api\Model\Request\WebAnalytics\VisitsUploadRequest; use RetailCrm\Api\Model\Response\WebAnalytics\ClientIdUploadResponse; use RetailCrm\Api\Model\Response\WebAnalytics\SourcesUploadResponse; +use RetailCrm\Api\Model\Response\WebAnalytics\VisitsUploadResponse; /** * Class WebAnalytics @@ -173,4 +175,97 @@ class WebAnalytics extends AbstractApiResourceGroup return $response; } + + /** + * + * Makes POST "/api/v5/web-analytics/client-ids/upload" request. + * + * Example: + * ```php + * use RetailCrm\Api\Factory\SimpleClientFactory; + * use RetailCrm\Api\Interfaces\ApiExceptionInterface; + * use RetailCrm\Api\Model\Entity\WebAnalytics\Visit; + * use RetailCrm\Api\Model\Entity\WebAnalytics\Customer; + * use RetailCrm\Api\Model\Request\WebAnalytics\VisitsUploadRequest; + * + * $client = SimpleClientFactory::createClient('https://test.retailcrm.pro', 'apiKey'); + * + * $entity = new Visit(); + * $dateTime = new \DateTime('2023-12-06T12:00:00'); + * $entity->createdAt = $dateTime->format('Y-m-d H:i:s'); + * $entity->visitLength = 10; + * $entity->exitPage = '/exit-page'; + * $entity->landingPage = '/landing-page'; + * $entity->pageViews = 5; + * $entity->pageDepth = 3; + * $entity->customer = new Customer(); + * $entity->customer->id = 10; + * $entity->customer->externalId = 'externalId'; + * $entity->source = new Source(); + * $entity->source = "sourse"; + * $entity->medium = "medium"; + * $entity->campaign = "campaign"; + * $entity->keyword = "keyword"; + * $entity->content = "content"; + * $page1 = new Page(); + * $page1->url = ('/page1'); + * $page1->title = ('Page 1'); + * $page1->countViews = 2; + * $page1->timeOnPage = 60; + * $page2 = new Page(); + * $page2->url = ('/page2'); + * $page2->title = ('Page 2'); + * $page2->countViews = 3; + * $page2->timeOnPage = 45; + * $pages = [$page1, $page2]; + * $entity->pages = $pages; + * $entity->clientId = '123456'; + * $entity->site = 'example.com'; + * + * $request = new VisitsUploadRequest([$entity]); + * + * try { + * $response = $client->webAnalytics->visitsUpload($request); + * } catch (ApiExceptionInterface $exception) { + * echo sprintf( + * 'Error from RetailCRM API (status code: %d): %s', + * $exception->getStatusCode(), + * $exception->getMessage() + * ); + * + * if (count($exception->getErrorResponse()->errors) > 0) { + * echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors); + * } + * + * return; + * } + * + * echo 'Upload is successful'; + * ``` + * + * @param \RetailCrm\Api\Model\Request\WebAnalytics\VisitsUploadRequest $request + * + * @return \RetailCrm\Api\Model\Response\WebAnalytics\VisitsUploadResponse + * @throws \RetailCrm\Api\Interfaces\ApiExceptionInterface + * @throws \RetailCrm\Api\Interfaces\ClientExceptionInterface + * @throws \RetailCrm\Api\Exception\Api\AccountDoesNotExistException + * @throws \RetailCrm\Api\Exception\Api\ApiErrorException + * @throws \RetailCrm\Api\Exception\Api\MissingCredentialsException + * @throws \RetailCrm\Api\Exception\Api\MissingParameterException + * @throws \RetailCrm\Api\Exception\Api\ValidationException + * @throws \RetailCrm\Api\Exception\Client\HandlerException + * @throws \RetailCrm\Api\Exception\Client\HttpClientException + */ + public function visitsUpload(VisitsUploadRequest $request): VisitsUploadResponse + { + /** @var VisitsUploadResponse $response */ + $response = $this->sendRequest( + RequestMethod::POST, + 'web-analytics/visits/upload', + $request, + VisitsUploadResponse::class + ); + + return $response; + } } diff --git a/tests/src/ResourceGroup/WebAnalyticsTest.php b/tests/src/ResourceGroup/WebAnalyticsTest.php index dd08fa0..ea13a64 100644 --- a/tests/src/ResourceGroup/WebAnalyticsTest.php +++ b/tests/src/ResourceGroup/WebAnalyticsTest.php @@ -15,9 +15,12 @@ use RetailCrm\Api\Interfaces\ApiExceptionInterface; use RetailCrm\Api\Model\Entity\WebAnalytics\ClientId; use RetailCrm\Api\Model\Entity\WebAnalytics\Customer; use RetailCrm\Api\Model\Entity\WebAnalytics\Order; +use RetailCrm\Api\Model\Entity\WebAnalytics\Page; use RetailCrm\Api\Model\Entity\WebAnalytics\Source; +use RetailCrm\Api\Model\Entity\WebAnalytics\Visit; use RetailCrm\Api\Model\Request\WebAnalytics\ClientIdUploadRequest; use RetailCrm\Api\Model\Request\WebAnalytics\SourcesUploadRequest; +use RetailCrm\Api\Model\Request\WebAnalytics\VisitsUploadRequest; use RetailCrm\TestUtils\Factory\TestClientFactory; use RetailCrm\TestUtils\TestCase\AbstractApiResourceGroupTestCase; @@ -97,4 +100,54 @@ EOF; self::assertModelEqualsToResponse($json, $response); } + + public function testVisitsUpload(): void + { + $json = '{"success": true}'; + + $entity = new Visit(); + $dateTime = new \DateTime('2023-12-06T12:00:00'); + $entity->createdAt = $dateTime->format('Y-m-d H:i:s'); + $entity->visitLength = 10; + $entity->exitPage = '/exit-page'; + $entity->landingPage = '/landing-page'; + $entity->pageViews = 5; + $entity->pageDepth = 3; + $entity->customer = new Customer(); + $entity->customer->id = 10; + $entity->customer->externalId = 'externalId'; + $entity->source = new Source(); + $entity->source->source = "source"; + $entity->source->medium = "medium"; + $entity->source->campaign = "campaign"; + $entity->source->keyword = "keyword"; + $entity->source->content = "content"; + $page1 = new Page(); + $page1->url = ('/page1'); + $page1->title = ('Page 1'); + $page1->countViews = 2; + $page1->timeOnPage = 60; + $page2 = new Page(); + $page2->url = ('/page2'); + $page2->title = ('Page 2'); + $page2->countViews = 3; + $page2->timeOnPage = 45; + $pages = [$page1, $page2]; + $entity->pages = $pages; + $entity->clientId = '123456'; + $entity->site = 'example.com'; + + $request = new VisitsUploadRequest([$entity]); + + $mock = static::createApiMockBuilder('web-analytics/visits/upload'); + $mock->matchMethod(RequestMethod::POST) + ->matchBody(self::encodeForm($request)) + ->reply(201) + ->withBody($json); + + $client = TestClientFactory::createClient($mock->getClient()); + $response = $client->webAnalytics->visitsUpload($request); + + self::assertModelEqualsToResponse($json, $response); + } }