PluginProbe
Metricool – Social media and site statistics / trunk
Metricool – Social media and site statistics vtrunk
2.1.0 2.0.2 2.0.1 2.0.0 1.27 trunk
metricool / app / Features / Onboarding / OnboardingService.php

OnboardingService.php in Metricool – Social media and site statistics trunk, at app/Features/Onboarding/OnboardingService.php

105 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Metricool\Features\Onboarding;
4
5 use Metricool\Http\Metricool\Exceptions\ApiException;
6 use Metricool\Features\Onboarding\Exceptions\BrandAccessDeniedException;
7 use Metricool\Http\Metricool\MetricoolApi;
8 use Metricool\Services\DashboardService;
9 use Metricool\Services\MetricoolAccountService;
10 use Metricool\Services\TrackingScriptService;
11
12 class OnboardingService
13 {
14 private MetricoolApi $api;
15 private TrackingScriptService $tracking;
16 private DashboardService $dashboard;
17 private MetricoolAccountService $account;
18
19 public function __construct(MetricoolApi $api, TrackingScriptService $tracking, DashboardService $dashboard, MetricoolAccountService $account)
20 {
21 $this->api = $api;
22 $this->tracking = $tracking;
23 $this->dashboard = $dashboard;
24 $this->account = $account;
25 }
26
27 /**
28 * Attempt to finish the onboarding process. When the necessary information is provided or retrieved,
29 * set the onboarding as completed.
30 *
31 * @throws BrandAccessDeniedException
32 * @throws ApiException
33 */
34 public function finalizeOnboarding(?string $blogId = null): bool
35 {
36 if ($blogId !== null) {
37 // When a blogId is provided, try to connect to the brand
38 $this->connectBrand($blogId);
39 }
40
41 // If the blogId is not set, the onboarding is not completed
42 if ($this->api->hasBlogId() === false) {
43 return false;
44 }
45
46 // Update the metricool user data from the API
47 $this->account->fetch();
48
49 // When all the necessary information is retrieved, set the onboarding as completed
50 return $this->dashboard->setOnboardingCompleted();
51 }
52
53 /**
54 * A brand is connected when it's retrieved from the API and the tracking hash is activated. The blogId is stored for future API calls.
55 *
56 * @throws BrandAccessDeniedException
57 * @throws ApiException
58 */
59 private function connectBrand(string $blogId): void
60 {
61 try {
62 $brand = $this->api->brands()->get($blogId);
63 } catch (ApiException $e) {
64 if ($e->getCode() === 403) {
65 throw new BrandAccessDeniedException();
66 }
67 throw $e;
68 }
69
70 if (!$this->brandCanBeConnected($brand)) {
71 throw new BrandAccessDeniedException();
72 }
73
74 $this->activateTrackingHash($brand);
75 $this->api->storeBlogId($blogId);
76 }
77
78 /**
79 * A brand can only be connected by its owner or by a user whose brand
80 * role includes the editBrand permission. This is the same capability
81 * the Metricool API validates when linking a site to a brand.
82 */
83 private function brandCanBeConnected(array $brand): bool
84 {
85 if (isset($brand['ownerUserId']) && (string) $brand['ownerUserId'] === $this->api->getUserId()) {
86 return true;
87 }
88
89 return isset($brand['brandRole']['actions']['editBrand']) && $brand['brandRole']['actions']['editBrand'] === true;
90 }
91
92 /**
93 * Activate the tracking hash for the given brand and store it in the database
94 */
95 private function activateTrackingHash(array $brand): void
96 {
97 $trackingId = isset($brand['hash']) ? (string) $brand['hash'] : null;
98
99 if ($trackingId !== null) {
100 $this->tracking->storeTrackingHash($trackingId)
101 ->activateTrackingWidget();
102 }
103 }
104 }
105