Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
36 / 38
80.00% covered (success)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractOffice365
94.74% covered (success)
94.74%
36 / 38
80.00% covered (success)
80.00%
4 / 5
17.04
0.00% covered (danger)
0.00%
0 / 1
 createClient
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
 setTenantId
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getTenantId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasTenantId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 requestToken
90.00% covered (success)
90.00%
18 / 20
0.00% covered (danger)
0.00%
0 / 1
11.12
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Mail\Api;
15
16use Pop\Http;
17
18/**
19 * Abstract Office 365 Mail API class
20 *
21 * @category   Pop
22 * @package    Pop\Mail
23 * @author     Nick Sagona, III <dev@nolainteractive.com>
24 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
25 * @license    http://www.popphp.org/license     New BSD License
26 * @version    4.0.0
27 */
28abstract class AbstractOffice365 extends AbstractHttpClient
29{
30
31    /**
32     * Tenant ID
33     * @var ?string
34     */
35    protected ?string $tenantId = null;
36
37    /**
38     * Token request URI
39     * @var ?string
40     */
41    protected ?string $tokenRequestUri = 'https://login.microsoftonline.com/[{tenant_id}]/oauth2/v2.0/token';
42
43    /**
44     * Base URL
45     * @var ?string
46     */
47    protected ?string $baseUri = 'https://graph.microsoft.com/v1.0/users';
48
49    /**
50     * Create client
51     *
52     * @param  array|string $options
53     * @throws Exception
54     * @return AbstractOffice365
55     */
56    public function createClient(array|string $options): AbstractOffice365
57    {
58        if (is_string($options)) {
59            $options = $this->parseOptions($options);
60        }
61
62        $this->clientId     = $options['client_id'] ?? null;
63        $this->clientSecret = $options['client_secret'] ?? null;
64        $this->scope        = $options['scope'] ?? null;
65        $this->tenantId     = $options['tenant_id'] ?? null;
66        $this->accountId    = $options['account_id'] ?? null;
67        $this->username     = $options['username'] ?? null;
68
69        if ($this->accountId === null) {
70            throw new Exception('Error: The account ID is required to create the client object.');
71        }
72
73        $this->client = new Http\Client([
74            'base_uri' => $this->baseUri
75        ]);
76
77        return $this;
78    }
79
80    /**
81     * Set tenant ID
82     *
83     * @param  string $tenantId
84     * @return AbstractOffice365
85     */
86    public function setTenantId(string $tenantId): AbstractOffice365
87    {
88        $this->tenantId = $tenantId;
89        return $this;
90    }
91
92    /**
93     * Get tenant ID
94     *
95     * @return ?string
96     */
97    public function getTenantId(): ?string
98    {
99        return $this->tenantId;
100    }
101
102    /**
103     * Has tenant ID
104     *
105     * @return bool
106     */
107    public function hasTenantId(): bool
108    {
109        return ($this->tenantId !== null);
110    }
111
112    /**
113     * Request token
114     *
115     * @throws Exception|Http\Exception|Http\Client\Exception|Http\Client\Handler\Exception
116     * @return AbstractOffice365
117     */
118    public function requestToken(): AbstractOffice365
119    {
120        if (empty($this->tenantId) || empty($this->clientId) || empty($this->scope) || empty($this->clientSecret)) {
121            throw new Exception('Error: The required credentials have not been set.');
122        } else {
123            if (isset($this->token) && isset($this->tokenExpires) && !$this->isTokenExpired()) {
124                return $this;
125            }
126        }
127
128        $tokenRequestUri = str_replace('[{tenant_id}]', $this->tenantId, $this->tokenRequestUri);
129
130        $client = new Http\Client($tokenRequestUri, [
131            'method' => 'POST',
132            'auto'   => true,
133            'data'   => [
134                'grant_type'    => 'client_credentials',
135                'client_id'     => $this->clientId,
136                'scope'         => $this->scope,
137                'client_secret' => $this->clientSecret,
138            ]
139        ]);
140
141        $response = $client->send();
142
143        if (is_array($response) && isset($response['access_token']) && isset($response['expires_in'])) {
144            $this->setToken($response['access_token'])
145                ->setTokenExpires(time() + $response['expires_in']);
146        }
147
148        return $this;
149    }
150
151}