├── .gitignore
├── credentials
└── .gitignore
├── index.php
├── composer.json
├── static
└── style.css
├── classes
├── Init.php
└── Meet.php
├── views
└── view.php
├── index-raw.php
└── composer.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | vendor/
--------------------------------------------------------------------------------
/credentials/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
--------------------------------------------------------------------------------
/index.php:
--------------------------------------------------------------------------------
1 | start();
14 |
15 | require_once 'views/view.php' ;
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "google/meet",
3 | "type": "library",
4 | "description": "Google Meet Integration",
5 | "minimum-stability": "beta",
6 | "require": {
7 | "php": ">=5.4",
8 | "google/auth": "^1.10",
9 | "google/apiclient-services": "~0.13",
10 | "google/apiclient": "^2.10"
11 | },
12 | "scripts": {
13 | "pre-autoload-dump": "Google\\Task\\Composer::cleanup"
14 | },
15 | "extra": {
16 | "branch-alias": {
17 | "dev-master": "2.x-dev"
18 | },
19 | "google/apiclient-services": [
20 | "Calendar"
21 | ]
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/static/style.css:
--------------------------------------------------------------------------------
1 | #google-meet-wrapper{
2 | margin-right:15px
3 | }
4 | #google-meet-wrapper .consent-screen{
5 | margin:0 auto;
6 | width:600px;
7 | padding:15px;
8 | border-radius:6px;
9 | border:1px solid white;
10 | max-width:calc(100% - 48px);
11 | background:white
12 | }
13 | #google-meet-wrapper .consent-screen.google-consent-screen-redirect{
14 | text-align:center;
15 | width:450px
16 | }
17 | #google-meet-wrapper .gm-upload-area{
18 | border:2px dashed #BABABA;
19 | border-radius:6px;
20 | text-align:center;
21 | padding:30px 10px;
22 | margin-bottom:15px
23 | }
24 | #google-meet-wrapper .gm-upload-area span.file_name{
25 | display:block;
26 | margin-top:10px
27 | }
28 | #google-meet-wrapper .gm-upload-area button{
29 | background:#3E64DE;
30 | color:white;
31 | display:inline-block
32 | }
33 | #google-meet-wrapper .gm-upload-area.dragover{
34 | border:2px dashed #525252
35 | }
36 |
37 | #google-meet-wrapper table {
38 | width: 100%;
39 | border-collapse: collapse;
40 | }
41 |
42 | #google-meet-wrapper td, #google-meet-wrapper th{
43 | border: 1px solid gray;
44 | padding: 5px;
45 | }
--------------------------------------------------------------------------------
/classes/Init.php:
--------------------------------------------------------------------------------
1 | meet = new Meet;
10 | }
11 |
12 | public function start() {
13 | // Save token if the request comes from google
14 | $this->saveToken();
15 |
16 | // Save credential if upload file exists
17 | $this->saveCredential();
18 |
19 | // CRUD
20 | $this->CRUDOperation();
21 |
22 | return $this->meet;
23 | }
24 |
25 | public function saveToken() {
26 | if(isset($_GET['code'])) {
27 | $this->meet->saveToken($_GET['code']);
28 | header('Location: '.ROOT_URL);
29 | exit;
30 | }
31 | }
32 |
33 | public function saveCredential(){
34 | if(isset($_FILES['credential']) && $_FILES['credential']['error']==0) {
35 |
36 | // Save credential file if exist and no error
37 | $this->meet->saveCredential($_FILES['credential']);
38 |
39 | header('Location: '.ROOT_URL);
40 | exit;
41 | }
42 | }
43 |
44 | public function CRUDOperation() {
45 | if(isset($_GET['action'])) {
46 | $now = time();
47 | $start_time = rand($now+86400, $now+(86400*6));
48 | $end_time = $start_time+3600;
49 |
50 | switch($_GET['action']) {
51 | case 'create' :
52 | $this->meet->createMeeting(array(
53 | 'title' => 'Title New ' . microtime(true),
54 | 'description' => 'Description New ' . microtime(true),
55 | 'start' => date("Y-m-d H:i:s", $start_time),
56 | 'end' => date("Y-m-d H:i:s", $end_time),
57 | 'timezone' => 'America/Los_Angeles'
58 | ));
59 | break;
60 |
61 | case 'delete' :
62 | $this->meet->deleteMeeting($_GET['id']);
63 | break;
64 |
65 | case 'update' :
66 | $this->meet->updateMeeting($_GET['id'], array(
67 | 'title' => 'Title Update ' . microtime(true),
68 | 'description' => 'Description Update ' . microtime(true),
69 | 'start' => date("Y-m-d H:i:s", $start_time),
70 | 'end' => date("Y-m-d H:i:s", $end_time),
71 | 'timezone' => 'America/Los_Angeles'
72 | ));
73 | break;
74 | }
75 |
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/views/view.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | isCredentialLoaded()){
10 | ?>
11 |
19 | isAppPermitted()){
21 | ?>
22 |
28 | getMeetingList();
31 |
32 | if(!count($meetings)) {
33 | echo '
No meeting found
';
34 | } else {
35 | echo '
';
36 | foreach($meetings as $meeting) {
37 | echo '
38 | | ' . $meeting['title'] . ' |
39 | ' . $meeting['meeting_link'] . ' |
40 | ' . $meeting['start'] . ' |
41 | Delete |
42 | Update with Random Data |
43 |
';
44 | }
45 | echo '
';
46 | }
47 |
48 | ?>
49 |
Create Meeting with Random Data
50 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/classes/Meet.php:
--------------------------------------------------------------------------------
1 | current_calendar = $current_calendar;
23 |
24 | $this->credential_path = CREDENTIAL_PATH . '/credential.json';
25 | $this->token_path = CREDENTIAL_PATH . '/token.json';
26 | $this->google_callback_url = ROOT_URL;
27 |
28 | if($this->isCredentialLoaded()) {
29 | $this->client = new Google_Client();
30 | $this->client->setApplicationName($this->app_name);
31 | $this->client->setAuthConfig($this->credential_path);
32 | $this->client->setRedirectUri($this->google_callback_url);
33 | $this->client->addScope($this->required_scopes);
34 | $this->client->setAccessType("offline");
35 | $this->client->setApprovalPrompt('force');
36 | $assigned = !($this->assignTokenToClient()===false);
37 |
38 | if($assigned) {
39 | // Create service if the token assigned
40 | $this->service = new Google_Service_Calendar($this->client);
41 | }
42 | }
43 | }
44 |
45 | // Return consent screen url
46 | public function get_consent_screen_url(){
47 | return $this->client->createAuthUrl();
48 | }
49 |
50 | // Upload credential file
51 | public function saveCredential($file){
52 | move_uploaded_file($file['tmp_name'], $this->credential_path);
53 | }
54 |
55 | // Check if credential file uploaded
56 | public function isCredentialLoaded(){
57 | return file_exists($this->credential_path);
58 | }
59 |
60 | // Assign the existing token, or try to refresh if expired.
61 | public function assignTokenToClient(){
62 |
63 | if (file_exists($this->token_path)) {
64 | $accessToken = json_decode(file_get_contents($this->token_path), true);
65 | $this->client->setAccessToken($accessToken);
66 | }
67 |
68 | // Check if token expired
69 | if ($this->client->isAccessTokenExpired()) {
70 |
71 | $refresh_token = $this->client->getRefreshToken();
72 |
73 | if(!$refresh_token){
74 | return false;
75 | }
76 |
77 | $new_token = null;
78 |
79 | try {
80 | $new_token = $this->client->fetchAccessTokenWithRefreshToken($refresh_token);
81 | } catch(\Exception $e) {
82 | if($e) {
83 | return false;
84 | }
85 | }
86 |
87 | $this->saveToken(null, $new_token);
88 | }
89 | }
90 |
91 |
92 | // Save token provided by google
93 | public function saveToken($code=null, $token=null){
94 |
95 | if(!$token){
96 | $token = $this->client->fetchAccessTokenWithAuthCode($code);
97 | $this->client->setAccessToken($token);
98 | $token = $this->client->getAccessToken();
99 | }
100 |
101 | file_put_contents($this->token_path, json_encode($token));
102 | }
103 |
104 |
105 | // Check if the app is permitted by user via consent screen
106 | public function isAppPermitted(){
107 | return $this->assignTokenToClient()===false ? false : true;
108 | }
109 |
110 | private function get_calendar_list($optParams=array()) {
111 | $list = array();
112 | $calendarList = $this->service->calendarList->listCalendarList($optParams);
113 | $pageToken = $calendarList->getNextPageToken();
114 |
115 | foreach ($calendarList->getItems() as $calendarListEntry) {
116 | $id = $calendarListEntry->getId();
117 | $list[] = array(
118 | 'id' => $id,
119 | 'summary' => $calendarListEntry->getSummary()
120 | );
121 | }
122 |
123 | if ($pageToken) {
124 | $optParams = array('pageToken' => $pageToken);
125 | $calendarList = $this->get_calendar_list($optParams);
126 | is_array($calendarList) ? $list = array_merge($list, $calendarList) : 0;
127 | }
128 |
129 | return $list;
130 | }
131 |
132 | public function getMeetingList() {
133 |
134 | $optParams = array(
135 | 'maxResults' => 50,
136 | 'orderBy' => 'startTime',
137 | 'singleEvents' => true,
138 | 'timeMin' => date('c'),
139 | );
140 |
141 | $results = $this->service->events->listEvents($this->current_calendar, $optParams);
142 | $pageToken = $results->getNextPageToken();
143 | $list = array();
144 |
145 | foreach ($results->getItems() as $event) {
146 | $start = $event->start->dateTime;
147 | if (empty($start)) {
148 | $start = $event->start->date;
149 | }
150 |
151 | // var_dump($event);
152 |
153 | $id = $event->getId();
154 | $list[] = array(
155 | 'id' => $id,
156 | 'title' => $event->getSummary(),
157 | 'start' => $start,
158 | 'meeting_link' => $event->hangoutLink
159 | );
160 | }
161 |
162 | return $list;
163 | }
164 |
165 | public function createMeeting(array $payload) {
166 |
167 | // Prepare attendees array
168 | $attendees = isset($payload['attendees']) ? $payload['attendees'] : array();
169 | $attendees = array_map(function($attendee){
170 | return is_string($attendee) ? array('email' => $attendee) : $attendee;
171 | }, $attendees);
172 |
173 | // Mak the create request
174 | $event = new Google_Service_Calendar_Event(array(
175 | 'summary' => $payload['title'],
176 | 'description' => $payload['description'],
177 | 'start' => array(
178 | 'dateTime' => (new DateTime($payload['start']))->format('c'),
179 | 'timeZone' => (new DateTime($payload['timezone']))->format('c'),
180 | ),
181 | 'end' => array(
182 | 'dateTime' => (new DateTime($payload['end']))->format('c'),
183 | 'timeZone' => (new DateTime($payload['timezone']))->format('c'),
184 | ),
185 | 'attendees' => $attendees,
186 | 'conferenceData' => array(
187 | 'createRequest' => array(
188 | 'requestId' => 'meet_demo_' . microtime(true),
189 | )
190 | )
191 | ));
192 |
193 | $event = $this->service->events->insert($this->current_calendar, $event, array('conferenceDataVersion' => 1));
194 |
195 | return array(
196 | 'event_id' => $event->getId(),
197 | 'event_link' => $event->htmlLink,
198 | 'conference_id' => $event->conferenceData->conferenceId,
199 | 'conference_link' => $event->hangoutLink,
200 | );
201 | }
202 |
203 | public function deleteMeeting($event_id) {
204 | try {
205 | $this->service->events->delete($this->current_calendar, $event_id);
206 | } catch(\Exception $e) {
207 |
208 | }
209 | }
210 |
211 | public function updateMeeting($event_id, array $payload) {
212 | $event = $this->service->events->get($this->current_calendar, $event_id);
213 |
214 | foreach($payload as $key=>$value) {
215 | $key=='title' ? $key='summary' : 0;
216 | $method = 'set' . ucfirst($key);
217 |
218 | switch($key) {
219 | case 'summary' :
220 | case 'description' :
221 | $event->$method($value);
222 | break;
223 |
224 | case 'start' :
225 | case 'end' :
226 | $date_time = new Google_Service_Calendar_EventDateTime();
227 | $date_time->setDateTime((new DateTime($value))->format('c'));
228 | $date_time->setTimeZone($payload['timezone']);
229 | $event->$method($date_time);
230 | break;
231 | }
232 | }
233 |
234 | $this->service->events->update($this->current_calendar, $event->getId(), $event);
235 | }
236 | }
--------------------------------------------------------------------------------
/index-raw.php:
--------------------------------------------------------------------------------
1 | client_id = $client_id;
34 | $this->client_secret = $client_secret;
35 |
36 | $this->token_dir = __DIR__ . '/credentials/';
37 | $this->token_path = $this->token_dir . 'token.json';
38 | }
39 |
40 | public function getTokenURL() {
41 | return "https://accounts.google.com/o/oauth2/auth?" . http_build_query([
42 | 'response_type' => 'code',
43 | 'client_id' => $this->client_id,
44 | 'redirect_uri' => $this->redirect_uri,
45 | 'scope' => $this->scope,
46 | 'access_type' => 'offline',
47 | 'prompt' => 'consent'
48 | ]);
49 | }
50 |
51 | public function saveToken( $code ) {
52 |
53 | $data = [
54 | 'code' => $code,
55 | 'client_id' => $this->client_id,
56 | 'client_secret' => $this->client_secret,
57 | 'redirect_uri' => $this->redirect_uri,
58 | 'grant_type' => 'authorization_code'
59 | ];
60 |
61 | $ch = curl_init($this->token_url);
62 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
63 | curl_setopt($ch, CURLOPT_POST, true);
64 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
65 | $response = curl_exec($ch);
66 | curl_close($ch);
67 |
68 | $token_data = json_decode($response, true);
69 |
70 | if (isset($token_data['access_token'])) {
71 |
72 | if ( ! file_exists( $this->token_dir ) ) {
73 | mkdir( $this->token_dir );
74 | }
75 |
76 | $token_data['expires_in'] = time() + $token_data['expires_in'];
77 |
78 | file_put_contents( $this->token_path, json_encode($token_data));
79 | header( 'Location: ' . $this->redirect_uri );
80 | exit;
81 | } else {
82 | echo "Error getting access token!";
83 | }
84 | }
85 |
86 | public function createMeeting() {
87 |
88 | $access_token_data = $this->getToken();
89 | $access_token = $access_token_data['access_token'];
90 | $time = date('Y-m-d\TH:i:s-07:00', strtotime('tomorrow') + rand(0, 86399));
91 | $endTime = date('Y-m-d\TH:i:s-07:00', strtotime($time) + 3600);
92 |
93 | $event = [
94 | 'summary' => 'Demo Meeting - ' . microtime(true),
95 | 'location' => 'Online (Google Meet)',
96 | 'description' => 'Discussing project updates',
97 | 'start' => ['dateTime' => $time],
98 | 'end' => ['dateTime' => $endTime],
99 | 'conferenceData' => [
100 | 'createRequest' => [
101 | 'requestId' => uniqid(),
102 | 'conferenceSolutionKey' => ['type' => 'hangoutsMeet']
103 | ]
104 | ]
105 | ];
106 |
107 | $ch = curl_init('https://www.googleapis.com/calendar/v3/calendars/primary/events?conferenceDataVersion=1');
108 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
109 | curl_setopt($ch, CURLOPT_POST, true);
110 | curl_setopt($ch, CURLOPT_HTTPHEADER, [
111 | 'Authorization: Bearer ' . $access_token,
112 | 'Content-Type: application/json'
113 | ]);
114 |
115 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($event));
116 | $response = curl_exec($ch);
117 | curl_close($ch);
118 |
119 | header( 'Location: ' . $this->redirect_uri );
120 | exit;
121 | }
122 |
123 | public function deleteMeeting( $event_id ) {
124 |
125 | $access_token_data = $this->getToken();
126 | $access_token = $access_token_data['access_token'];
127 |
128 | $calendar_id = 'primary'; // Default calendar
129 |
130 | $api_url = "https://www.googleapis.com/calendar/v3/calendars/{$calendar_id}/events/{$event_id}";
131 |
132 | $ch = curl_init();
133 | curl_setopt($ch, CURLOPT_URL, $api_url);
134 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
135 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
136 | curl_setopt($ch, CURLOPT_HTTPHEADER, [
137 | 'Authorization: Bearer ' . $access_token,
138 | 'Content-Type: application/json'
139 | ]);
140 |
141 | $response = curl_exec($ch);
142 | $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
143 | curl_close($ch);
144 |
145 | // Check response
146 | if ($http_code === 204) {
147 | header('Location: ' . $this->redirect_uri);
148 | exit;
149 | } else {
150 | echo "Failed to delete event. Response: " . $response;
151 | }
152 | }
153 |
154 | public function getMeetings() {
155 |
156 | $access_token_data = $this->getToken();
157 | $access_token = $access_token_data['access_token'];
158 |
159 | $calendar_id = 'primary'; // Use 'primary' for the default calendar
160 | $api_url = "https://www.googleapis.com/calendar/v3/calendars/{$calendar_id}/events?" . http_build_query([
161 | 'maxResults' => 50,
162 | 'timeMin' => date('c'),
163 | ]);
164 |
165 | $ch = curl_init();
166 | curl_setopt($ch, CURLOPT_URL, $api_url);
167 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
168 | curl_setopt($ch, CURLOPT_HTTPHEADER, [
169 | 'Authorization: Bearer ' . $access_token,
170 | 'Content-Type: application/json'
171 | ]);
172 |
173 | $response = curl_exec($ch);
174 | curl_close($ch);
175 |
176 | $events = json_decode($response, true);
177 | $events = isset( $events['items'] ) ? $events['items'] : array();
178 | $meetEvents = array();
179 |
180 |
181 | foreach ( $events as $event ) {
182 | if (
183 | isset($event['hangoutLink']) ||
184 | (
185 | isset($event['conferenceData']['conferenceId']) &&
186 | isset($event['conferenceData']['conferenceSolution']['name']) &&
187 | strpos(strtolower($event['conferenceData']['conferenceSolution']['name']), 'meet') !== false
188 | )
189 | ) {
190 | $meetEvents[] = $event;
191 | }
192 | }
193 |
194 |
195 | return $meetEvents;
196 | }
197 |
198 | private function refreshToken( $old_token ) {
199 |
200 | // Request payload
201 | $data = [
202 | 'client_id' => $this->client_id,
203 | 'client_secret' => $this->client_secret,
204 | 'refresh_token' => $old_token['refresh_token'],
205 | 'grant_type' => 'refresh_token'
206 | ];
207 |
208 | $ch = curl_init();
209 | curl_setopt($ch, CURLOPT_URL, $this->token_url);
210 | curl_setopt($ch, CURLOPT_POST, true);
211 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
212 | curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
213 | curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
214 |
215 | $response = curl_exec($ch);
216 | curl_close($ch);
217 |
218 | $new_token = json_decode($response, true);
219 |
220 | if (isset($new_token['access_token'])) {
221 |
222 | // Update token file with new access_token
223 | $old_token['access_token'] = $new_token['access_token'];
224 | $old_token['expires_in'] = time() + $new_token['expires_in']; // Expiration time
225 | file_put_contents( $this->token_path, json_encode($old_token));
226 |
227 | return $old_token;
228 | } else {
229 | echo "Failed to refresh token: " . $response;
230 | exit;
231 | }
232 | }
233 |
234 | private function getToken() {
235 | $token = json_decode(file_get_contents($this->token_path), true);
236 | if ( time() >= $token['expires_in'] ) {
237 | $token = $this->refreshToken( $token );
238 | }
239 | return $token;
240 | }
241 | }
242 |
243 | // Follow the instructions here to get your credentials https://docs.themeum.com/tutor-lms/addons/google-meet-integration/#configuring-app-credentials
244 | $gm = new GM( 'YOUR_CLIENT_ID', 'YOUR_CLIENT_SECRET' );
245 |
246 | if ( $gm->client_id === 'YOUR_CLIENT_ID' || $gm->client_secret === 'YOUR_CLIENT_SECRET' ) {
247 | echo '
248 | You need to provide your client ID and client secret.
249 |
';
250 | exit;
251 | }
252 |
253 | // Accept code from consent response back
254 | if ( ! empty( $_GET['code'] ) ) {
255 | $gm->saveToken( $_GET['code'] );
256 | }
257 |
258 | // Show consent link
259 | if ( ! file_exists( $gm->token_path ) ) {
260 | echo '';
263 | exit;
264 | }
265 |
266 | // Create meeting
267 | if ( ! empty( $_GET['create'] ) ) {
268 | $gm->createMeeting();
269 | }
270 |
271 | // Delete meeting
272 | if ( ! empty( $_GET['delete'] ) && ! empty( $_GET['id'] ) ) {
273 | $gm->deleteMeeting( $_GET['id'] );
274 | }
275 |
276 | ?>
277 |
280 |
281 |
282 |
283 |
284 | | Meeting title |
285 | Start |
286 | End |
287 | Link |
288 | Delete |
289 |
290 |
291 |
292 | getMeetings() as $event): ?>
293 |
294 | |
295 | |
296 | |
297 | |
298 | Delete |
299 |
300 |
301 |
302 |
303 | =5.3.0"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": ">=4.8 <=9"
28 | },
29 | "suggest": {
30 | "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
31 | },
32 | "type": "library",
33 | "autoload": {
34 | "psr-4": {
35 | "Firebase\\JWT\\": "src"
36 | }
37 | },
38 | "notification-url": "https://packagist.org/downloads/",
39 | "license": [
40 | "BSD-3-Clause"
41 | ],
42 | "authors": [
43 | {
44 | "name": "Neuman Vong",
45 | "email": "neuman+pear@twilio.com",
46 | "role": "Developer"
47 | },
48 | {
49 | "name": "Anant Narayanan",
50 | "email": "anant@php.net",
51 | "role": "Developer"
52 | }
53 | ],
54 | "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
55 | "homepage": "https://github.com/firebase/php-jwt",
56 | "keywords": [
57 | "jwt",
58 | "php"
59 | ],
60 | "support": {
61 | "issues": "https://github.com/firebase/php-jwt/issues",
62 | "source": "https://github.com/firebase/php-jwt/tree/v5.4.0"
63 | },
64 | "time": "2021-06-23T19:00:23+00:00"
65 | },
66 | {
67 | "name": "google/apiclient",
68 | "version": "v2.11.0",
69 | "source": {
70 | "type": "git",
71 | "url": "https://github.com/googleapis/google-api-php-client.git",
72 | "reference": "7db9eb40c8ba887e81c0fe84f2888a967396cdfb"
73 | },
74 | "dist": {
75 | "type": "zip",
76 | "url": "https://api.github.com/repos/googleapis/google-api-php-client/zipball/7db9eb40c8ba887e81c0fe84f2888a967396cdfb",
77 | "reference": "7db9eb40c8ba887e81c0fe84f2888a967396cdfb",
78 | "shasum": ""
79 | },
80 | "require": {
81 | "firebase/php-jwt": "~2.0||~3.0||~4.0||~5.0",
82 | "google/apiclient-services": "~0.200",
83 | "google/auth": "^1.10",
84 | "guzzlehttp/guzzle": "~5.3.3||~6.0||~7.0",
85 | "guzzlehttp/psr7": "^1.7||^2.0.0",
86 | "monolog/monolog": "^1.17||^2.0",
87 | "php": "^5.6|^7.0|^8.0",
88 | "phpseclib/phpseclib": "~2.0||^3.0.2"
89 | },
90 | "require-dev": {
91 | "cache/filesystem-adapter": "^0.3.2|^1.1",
92 | "composer/composer": "^1.10.22",
93 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
94 | "phpcompatibility/php-compatibility": "^9.2",
95 | "phpspec/prophecy-phpunit": "^1.1||^2.0",
96 | "phpunit/phpunit": "^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0",
97 | "squizlabs/php_codesniffer": "~2.3",
98 | "symfony/css-selector": "~2.1",
99 | "symfony/dom-crawler": "~2.1",
100 | "yoast/phpunit-polyfills": "^1.0"
101 | },
102 | "suggest": {
103 | "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)"
104 | },
105 | "type": "library",
106 | "extra": {
107 | "branch-alias": {
108 | "dev-master": "2.x-dev"
109 | }
110 | },
111 | "autoload": {
112 | "psr-4": {
113 | "Google\\": "src/"
114 | },
115 | "files": [
116 | "src/aliases.php"
117 | ],
118 | "classmap": [
119 | "src/aliases.php"
120 | ]
121 | },
122 | "notification-url": "https://packagist.org/downloads/",
123 | "license": [
124 | "Apache-2.0"
125 | ],
126 | "description": "Client library for Google APIs",
127 | "homepage": "http://developers.google.com/api-client-library/php",
128 | "keywords": [
129 | "google"
130 | ],
131 | "support": {
132 | "issues": "https://github.com/googleapis/google-api-php-client/issues",
133 | "source": "https://github.com/googleapis/google-api-php-client/tree/v2.11.0"
134 | },
135 | "time": "2021-09-20T21:15:55+00:00"
136 | },
137 | {
138 | "name": "google/apiclient-services",
139 | "version": "v0.213.0",
140 | "source": {
141 | "type": "git",
142 | "url": "https://github.com/googleapis/google-api-php-client-services.git",
143 | "reference": "260311821505438eb9208b068da0d849b8ea9baa"
144 | },
145 | "dist": {
146 | "type": "zip",
147 | "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/260311821505438eb9208b068da0d849b8ea9baa",
148 | "reference": "260311821505438eb9208b068da0d849b8ea9baa",
149 | "shasum": ""
150 | },
151 | "require": {
152 | "php": ">=5.6"
153 | },
154 | "require-dev": {
155 | "phpunit/phpunit": "^5.7||^8.5.13"
156 | },
157 | "type": "library",
158 | "autoload": {
159 | "psr-4": {
160 | "Google\\Service\\": "src"
161 | },
162 | "files": [
163 | "autoload.php"
164 | ]
165 | },
166 | "notification-url": "https://packagist.org/downloads/",
167 | "license": [
168 | "Apache-2.0"
169 | ],
170 | "description": "Client library for Google APIs",
171 | "homepage": "http://developers.google.com/api-client-library/php",
172 | "keywords": [
173 | "google"
174 | ],
175 | "support": {
176 | "issues": "https://github.com/googleapis/google-api-php-client-services/issues",
177 | "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.213.0"
178 | },
179 | "time": "2021-09-19T11:18:26+00:00"
180 | },
181 | {
182 | "name": "google/auth",
183 | "version": "v1.18.0",
184 | "source": {
185 | "type": "git",
186 | "url": "https://github.com/googleapis/google-auth-library-php.git",
187 | "reference": "21dd478e77b0634ed9e3a68613f74ed250ca9347"
188 | },
189 | "dist": {
190 | "type": "zip",
191 | "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/21dd478e77b0634ed9e3a68613f74ed250ca9347",
192 | "reference": "21dd478e77b0634ed9e3a68613f74ed250ca9347",
193 | "shasum": ""
194 | },
195 | "require": {
196 | "firebase/php-jwt": "~2.0|~3.0|~4.0|~5.0",
197 | "guzzlehttp/guzzle": "^5.3.1|^6.2.1|^7.0",
198 | "guzzlehttp/psr7": "^1.7|^2.0",
199 | "php": ">=5.4",
200 | "psr/cache": "^1.0|^2.0",
201 | "psr/http-message": "^1.0"
202 | },
203 | "require-dev": {
204 | "guzzlehttp/promises": "0.1.1|^1.3",
205 | "kelvinmo/simplejwt": "^0.2.5|^0.5.1",
206 | "phpseclib/phpseclib": "^2.0.31",
207 | "phpunit/phpunit": "^4.8.36|^5.7",
208 | "sebastian/comparator": ">=1.2.3"
209 | },
210 | "suggest": {
211 | "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2."
212 | },
213 | "type": "library",
214 | "autoload": {
215 | "psr-4": {
216 | "Google\\Auth\\": "src"
217 | }
218 | },
219 | "notification-url": "https://packagist.org/downloads/",
220 | "license": [
221 | "Apache-2.0"
222 | ],
223 | "description": "Google Auth Library for PHP",
224 | "homepage": "http://github.com/google/google-auth-library-php",
225 | "keywords": [
226 | "Authentication",
227 | "google",
228 | "oauth2"
229 | ],
230 | "support": {
231 | "docs": "https://googleapis.github.io/google-auth-library-php/master/",
232 | "issues": "https://github.com/googleapis/google-auth-library-php/issues",
233 | "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.18.0"
234 | },
235 | "time": "2021-08-24T18:03:18+00:00"
236 | },
237 | {
238 | "name": "guzzlehttp/guzzle",
239 | "version": "7.3.0",
240 | "source": {
241 | "type": "git",
242 | "url": "https://github.com/guzzle/guzzle.git",
243 | "reference": "7008573787b430c1c1f650e3722d9bba59967628"
244 | },
245 | "dist": {
246 | "type": "zip",
247 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
248 | "reference": "7008573787b430c1c1f650e3722d9bba59967628",
249 | "shasum": ""
250 | },
251 | "require": {
252 | "ext-json": "*",
253 | "guzzlehttp/promises": "^1.4",
254 | "guzzlehttp/psr7": "^1.7 || ^2.0",
255 | "php": "^7.2.5 || ^8.0",
256 | "psr/http-client": "^1.0"
257 | },
258 | "provide": {
259 | "psr/http-client-implementation": "1.0"
260 | },
261 | "require-dev": {
262 | "bamarni/composer-bin-plugin": "^1.4.1",
263 | "ext-curl": "*",
264 | "php-http/client-integration-tests": "^3.0",
265 | "phpunit/phpunit": "^8.5.5 || ^9.3.5",
266 | "psr/log": "^1.1"
267 | },
268 | "suggest": {
269 | "ext-curl": "Required for CURL handler support",
270 | "ext-intl": "Required for Internationalized Domain Name (IDN) support",
271 | "psr/log": "Required for using the Log middleware"
272 | },
273 | "type": "library",
274 | "extra": {
275 | "branch-alias": {
276 | "dev-master": "7.3-dev"
277 | }
278 | },
279 | "autoload": {
280 | "psr-4": {
281 | "GuzzleHttp\\": "src/"
282 | },
283 | "files": [
284 | "src/functions_include.php"
285 | ]
286 | },
287 | "notification-url": "https://packagist.org/downloads/",
288 | "license": [
289 | "MIT"
290 | ],
291 | "authors": [
292 | {
293 | "name": "Michael Dowling",
294 | "email": "mtdowling@gmail.com",
295 | "homepage": "https://github.com/mtdowling"
296 | },
297 | {
298 | "name": "Márk Sági-Kazár",
299 | "email": "mark.sagikazar@gmail.com",
300 | "homepage": "https://sagikazarmark.hu"
301 | }
302 | ],
303 | "description": "Guzzle is a PHP HTTP client library",
304 | "homepage": "http://guzzlephp.org/",
305 | "keywords": [
306 | "client",
307 | "curl",
308 | "framework",
309 | "http",
310 | "http client",
311 | "psr-18",
312 | "psr-7",
313 | "rest",
314 | "web service"
315 | ],
316 | "support": {
317 | "issues": "https://github.com/guzzle/guzzle/issues",
318 | "source": "https://github.com/guzzle/guzzle/tree/7.3.0"
319 | },
320 | "funding": [
321 | {
322 | "url": "https://github.com/GrahamCampbell",
323 | "type": "github"
324 | },
325 | {
326 | "url": "https://github.com/Nyholm",
327 | "type": "github"
328 | },
329 | {
330 | "url": "https://github.com/alexeyshockov",
331 | "type": "github"
332 | },
333 | {
334 | "url": "https://github.com/gmponos",
335 | "type": "github"
336 | }
337 | ],
338 | "time": "2021-03-23T11:33:13+00:00"
339 | },
340 | {
341 | "name": "guzzlehttp/promises",
342 | "version": "1.4.1",
343 | "source": {
344 | "type": "git",
345 | "url": "https://github.com/guzzle/promises.git",
346 | "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d"
347 | },
348 | "dist": {
349 | "type": "zip",
350 | "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d",
351 | "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d",
352 | "shasum": ""
353 | },
354 | "require": {
355 | "php": ">=5.5"
356 | },
357 | "require-dev": {
358 | "symfony/phpunit-bridge": "^4.4 || ^5.1"
359 | },
360 | "type": "library",
361 | "extra": {
362 | "branch-alias": {
363 | "dev-master": "1.4-dev"
364 | }
365 | },
366 | "autoload": {
367 | "psr-4": {
368 | "GuzzleHttp\\Promise\\": "src/"
369 | },
370 | "files": [
371 | "src/functions_include.php"
372 | ]
373 | },
374 | "notification-url": "https://packagist.org/downloads/",
375 | "license": [
376 | "MIT"
377 | ],
378 | "authors": [
379 | {
380 | "name": "Michael Dowling",
381 | "email": "mtdowling@gmail.com",
382 | "homepage": "https://github.com/mtdowling"
383 | }
384 | ],
385 | "description": "Guzzle promises library",
386 | "keywords": [
387 | "promise"
388 | ],
389 | "support": {
390 | "issues": "https://github.com/guzzle/promises/issues",
391 | "source": "https://github.com/guzzle/promises/tree/1.4.1"
392 | },
393 | "time": "2021-03-07T09:25:29+00:00"
394 | },
395 | {
396 | "name": "guzzlehttp/psr7",
397 | "version": "2.0.0",
398 | "source": {
399 | "type": "git",
400 | "url": "https://github.com/guzzle/psr7.git",
401 | "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7"
402 | },
403 | "dist": {
404 | "type": "zip",
405 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/1dc8d9cba3897165e16d12bb13d813afb1eb3fe7",
406 | "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7",
407 | "shasum": ""
408 | },
409 | "require": {
410 | "php": "^7.2.5 || ^8.0",
411 | "psr/http-factory": "^1.0",
412 | "psr/http-message": "^1.0",
413 | "ralouphie/getallheaders": "^3.0"
414 | },
415 | "provide": {
416 | "psr/http-factory-implementation": "1.0",
417 | "psr/http-message-implementation": "1.0"
418 | },
419 | "require-dev": {
420 | "bamarni/composer-bin-plugin": "^1.4.1",
421 | "http-interop/http-factory-tests": "^0.9",
422 | "phpunit/phpunit": "^8.5.8 || ^9.3.10"
423 | },
424 | "suggest": {
425 | "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
426 | },
427 | "type": "library",
428 | "extra": {
429 | "branch-alias": {
430 | "dev-master": "2.0-dev"
431 | }
432 | },
433 | "autoload": {
434 | "psr-4": {
435 | "GuzzleHttp\\Psr7\\": "src/"
436 | }
437 | },
438 | "notification-url": "https://packagist.org/downloads/",
439 | "license": [
440 | "MIT"
441 | ],
442 | "authors": [
443 | {
444 | "name": "Michael Dowling",
445 | "email": "mtdowling@gmail.com",
446 | "homepage": "https://github.com/mtdowling"
447 | },
448 | {
449 | "name": "Tobias Schultze",
450 | "homepage": "https://github.com/Tobion"
451 | },
452 | {
453 | "name": "Márk Sági-Kazár",
454 | "email": "mark.sagikazar@gmail.com",
455 | "homepage": "https://sagikazarmark.hu"
456 | }
457 | ],
458 | "description": "PSR-7 message implementation that also provides common utility methods",
459 | "keywords": [
460 | "http",
461 | "message",
462 | "psr-7",
463 | "request",
464 | "response",
465 | "stream",
466 | "uri",
467 | "url"
468 | ],
469 | "support": {
470 | "issues": "https://github.com/guzzle/psr7/issues",
471 | "source": "https://github.com/guzzle/psr7/tree/2.0.0"
472 | },
473 | "time": "2021-06-30T20:03:07+00:00"
474 | },
475 | {
476 | "name": "monolog/monolog",
477 | "version": "2.3.4",
478 | "source": {
479 | "type": "git",
480 | "url": "https://github.com/Seldaek/monolog.git",
481 | "reference": "437e7a1c50044b92773b361af77620efb76fff59"
482 | },
483 | "dist": {
484 | "type": "zip",
485 | "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437e7a1c50044b92773b361af77620efb76fff59",
486 | "reference": "437e7a1c50044b92773b361af77620efb76fff59",
487 | "shasum": ""
488 | },
489 | "require": {
490 | "php": ">=7.2",
491 | "psr/log": "^1.0.1 || ^2.0 || ^3.0"
492 | },
493 | "provide": {
494 | "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
495 | },
496 | "require-dev": {
497 | "aws/aws-sdk-php": "^2.4.9 || ^3.0",
498 | "doctrine/couchdb": "~1.0@dev",
499 | "elasticsearch/elasticsearch": "^7",
500 | "graylog2/gelf-php": "^1.4.2",
501 | "mongodb/mongodb": "^1.8",
502 | "php-amqplib/php-amqplib": "~2.4",
503 | "php-console/php-console": "^3.1.3",
504 | "phpspec/prophecy": "^1.6.1",
505 | "phpstan/phpstan": "^0.12.91",
506 | "phpunit/phpunit": "^8.5",
507 | "predis/predis": "^1.1",
508 | "rollbar/rollbar": "^1.3",
509 | "ruflin/elastica": ">=0.90@dev",
510 | "swiftmailer/swiftmailer": "^5.3|^6.0"
511 | },
512 | "suggest": {
513 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
514 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
515 | "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
516 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
517 | "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
518 | "ext-mbstring": "Allow to work properly with unicode symbols",
519 | "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
520 | "ext-openssl": "Required to send log messages using SSL",
521 | "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
522 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
523 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
524 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
525 | "php-console/php-console": "Allow sending log messages to Google Chrome",
526 | "rollbar/rollbar": "Allow sending log messages to Rollbar",
527 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
528 | },
529 | "type": "library",
530 | "extra": {
531 | "branch-alias": {
532 | "dev-main": "2.x-dev"
533 | }
534 | },
535 | "autoload": {
536 | "psr-4": {
537 | "Monolog\\": "src/Monolog"
538 | }
539 | },
540 | "notification-url": "https://packagist.org/downloads/",
541 | "license": [
542 | "MIT"
543 | ],
544 | "authors": [
545 | {
546 | "name": "Jordi Boggiano",
547 | "email": "j.boggiano@seld.be",
548 | "homepage": "https://seld.be"
549 | }
550 | ],
551 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
552 | "homepage": "https://github.com/Seldaek/monolog",
553 | "keywords": [
554 | "log",
555 | "logging",
556 | "psr-3"
557 | ],
558 | "support": {
559 | "issues": "https://github.com/Seldaek/monolog/issues",
560 | "source": "https://github.com/Seldaek/monolog/tree/2.3.4"
561 | },
562 | "funding": [
563 | {
564 | "url": "https://github.com/Seldaek",
565 | "type": "github"
566 | },
567 | {
568 | "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
569 | "type": "tidelift"
570 | }
571 | ],
572 | "time": "2021-09-15T11:27:21+00:00"
573 | },
574 | {
575 | "name": "paragonie/constant_time_encoding",
576 | "version": "v2.4.0",
577 | "source": {
578 | "type": "git",
579 | "url": "https://github.com/paragonie/constant_time_encoding.git",
580 | "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c"
581 | },
582 | "dist": {
583 | "type": "zip",
584 | "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
585 | "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
586 | "shasum": ""
587 | },
588 | "require": {
589 | "php": "^7|^8"
590 | },
591 | "require-dev": {
592 | "phpunit/phpunit": "^6|^7|^8|^9",
593 | "vimeo/psalm": "^1|^2|^3|^4"
594 | },
595 | "type": "library",
596 | "autoload": {
597 | "psr-4": {
598 | "ParagonIE\\ConstantTime\\": "src/"
599 | }
600 | },
601 | "notification-url": "https://packagist.org/downloads/",
602 | "license": [
603 | "MIT"
604 | ],
605 | "authors": [
606 | {
607 | "name": "Paragon Initiative Enterprises",
608 | "email": "security@paragonie.com",
609 | "homepage": "https://paragonie.com",
610 | "role": "Maintainer"
611 | },
612 | {
613 | "name": "Steve 'Sc00bz' Thomas",
614 | "email": "steve@tobtu.com",
615 | "homepage": "https://www.tobtu.com",
616 | "role": "Original Developer"
617 | }
618 | ],
619 | "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
620 | "keywords": [
621 | "base16",
622 | "base32",
623 | "base32_decode",
624 | "base32_encode",
625 | "base64",
626 | "base64_decode",
627 | "base64_encode",
628 | "bin2hex",
629 | "encoding",
630 | "hex",
631 | "hex2bin",
632 | "rfc4648"
633 | ],
634 | "support": {
635 | "email": "info@paragonie.com",
636 | "issues": "https://github.com/paragonie/constant_time_encoding/issues",
637 | "source": "https://github.com/paragonie/constant_time_encoding"
638 | },
639 | "time": "2020-12-06T15:14:20+00:00"
640 | },
641 | {
642 | "name": "paragonie/random_compat",
643 | "version": "v9.99.100",
644 | "source": {
645 | "type": "git",
646 | "url": "https://github.com/paragonie/random_compat.git",
647 | "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
648 | },
649 | "dist": {
650 | "type": "zip",
651 | "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
652 | "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
653 | "shasum": ""
654 | },
655 | "require": {
656 | "php": ">= 7"
657 | },
658 | "require-dev": {
659 | "phpunit/phpunit": "4.*|5.*",
660 | "vimeo/psalm": "^1"
661 | },
662 | "suggest": {
663 | "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
664 | },
665 | "type": "library",
666 | "notification-url": "https://packagist.org/downloads/",
667 | "license": [
668 | "MIT"
669 | ],
670 | "authors": [
671 | {
672 | "name": "Paragon Initiative Enterprises",
673 | "email": "security@paragonie.com",
674 | "homepage": "https://paragonie.com"
675 | }
676 | ],
677 | "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
678 | "keywords": [
679 | "csprng",
680 | "polyfill",
681 | "pseudorandom",
682 | "random"
683 | ],
684 | "support": {
685 | "email": "info@paragonie.com",
686 | "issues": "https://github.com/paragonie/random_compat/issues",
687 | "source": "https://github.com/paragonie/random_compat"
688 | },
689 | "time": "2020-10-15T08:29:30+00:00"
690 | },
691 | {
692 | "name": "phpseclib/phpseclib",
693 | "version": "3.0.10",
694 | "source": {
695 | "type": "git",
696 | "url": "https://github.com/phpseclib/phpseclib.git",
697 | "reference": "62fcc5a94ac83b1506f52d7558d828617fac9187"
698 | },
699 | "dist": {
700 | "type": "zip",
701 | "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/62fcc5a94ac83b1506f52d7558d828617fac9187",
702 | "reference": "62fcc5a94ac83b1506f52d7558d828617fac9187",
703 | "shasum": ""
704 | },
705 | "require": {
706 | "paragonie/constant_time_encoding": "^1|^2",
707 | "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
708 | "php": ">=5.6.1"
709 | },
710 | "require-dev": {
711 | "phing/phing": "~2.7",
712 | "phpunit/phpunit": "^5.7|^6.0|^9.4",
713 | "squizlabs/php_codesniffer": "~2.0"
714 | },
715 | "suggest": {
716 | "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
717 | "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
718 | "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
719 | "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
720 | },
721 | "type": "library",
722 | "autoload": {
723 | "files": [
724 | "phpseclib/bootstrap.php"
725 | ],
726 | "psr-4": {
727 | "phpseclib3\\": "phpseclib/"
728 | }
729 | },
730 | "notification-url": "https://packagist.org/downloads/",
731 | "license": [
732 | "MIT"
733 | ],
734 | "authors": [
735 | {
736 | "name": "Jim Wigginton",
737 | "email": "terrafrost@php.net",
738 | "role": "Lead Developer"
739 | },
740 | {
741 | "name": "Patrick Monnerat",
742 | "email": "pm@datasphere.ch",
743 | "role": "Developer"
744 | },
745 | {
746 | "name": "Andreas Fischer",
747 | "email": "bantu@phpbb.com",
748 | "role": "Developer"
749 | },
750 | {
751 | "name": "Hans-Jürgen Petrich",
752 | "email": "petrich@tronic-media.com",
753 | "role": "Developer"
754 | },
755 | {
756 | "name": "Graham Campbell",
757 | "email": "graham@alt-three.com",
758 | "role": "Developer"
759 | }
760 | ],
761 | "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
762 | "homepage": "http://phpseclib.sourceforge.net",
763 | "keywords": [
764 | "BigInteger",
765 | "aes",
766 | "asn.1",
767 | "asn1",
768 | "blowfish",
769 | "crypto",
770 | "cryptography",
771 | "encryption",
772 | "rsa",
773 | "security",
774 | "sftp",
775 | "signature",
776 | "signing",
777 | "ssh",
778 | "twofish",
779 | "x.509",
780 | "x509"
781 | ],
782 | "support": {
783 | "issues": "https://github.com/phpseclib/phpseclib/issues",
784 | "source": "https://github.com/phpseclib/phpseclib/tree/3.0.10"
785 | },
786 | "funding": [
787 | {
788 | "url": "https://github.com/terrafrost",
789 | "type": "github"
790 | },
791 | {
792 | "url": "https://www.patreon.com/phpseclib",
793 | "type": "patreon"
794 | },
795 | {
796 | "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
797 | "type": "tidelift"
798 | }
799 | ],
800 | "time": "2021-08-16T04:24:45+00:00"
801 | },
802 | {
803 | "name": "psr/cache",
804 | "version": "1.0.1",
805 | "source": {
806 | "type": "git",
807 | "url": "https://github.com/php-fig/cache.git",
808 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
809 | },
810 | "dist": {
811 | "type": "zip",
812 | "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
813 | "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
814 | "shasum": ""
815 | },
816 | "require": {
817 | "php": ">=5.3.0"
818 | },
819 | "type": "library",
820 | "extra": {
821 | "branch-alias": {
822 | "dev-master": "1.0.x-dev"
823 | }
824 | },
825 | "autoload": {
826 | "psr-4": {
827 | "Psr\\Cache\\": "src/"
828 | }
829 | },
830 | "notification-url": "https://packagist.org/downloads/",
831 | "license": [
832 | "MIT"
833 | ],
834 | "authors": [
835 | {
836 | "name": "PHP-FIG",
837 | "homepage": "http://www.php-fig.org/"
838 | }
839 | ],
840 | "description": "Common interface for caching libraries",
841 | "keywords": [
842 | "cache",
843 | "psr",
844 | "psr-6"
845 | ],
846 | "support": {
847 | "source": "https://github.com/php-fig/cache/tree/master"
848 | },
849 | "time": "2016-08-06T20:24:11+00:00"
850 | },
851 | {
852 | "name": "psr/http-client",
853 | "version": "1.0.1",
854 | "source": {
855 | "type": "git",
856 | "url": "https://github.com/php-fig/http-client.git",
857 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
858 | },
859 | "dist": {
860 | "type": "zip",
861 | "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
862 | "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
863 | "shasum": ""
864 | },
865 | "require": {
866 | "php": "^7.0 || ^8.0",
867 | "psr/http-message": "^1.0"
868 | },
869 | "type": "library",
870 | "extra": {
871 | "branch-alias": {
872 | "dev-master": "1.0.x-dev"
873 | }
874 | },
875 | "autoload": {
876 | "psr-4": {
877 | "Psr\\Http\\Client\\": "src/"
878 | }
879 | },
880 | "notification-url": "https://packagist.org/downloads/",
881 | "license": [
882 | "MIT"
883 | ],
884 | "authors": [
885 | {
886 | "name": "PHP-FIG",
887 | "homepage": "http://www.php-fig.org/"
888 | }
889 | ],
890 | "description": "Common interface for HTTP clients",
891 | "homepage": "https://github.com/php-fig/http-client",
892 | "keywords": [
893 | "http",
894 | "http-client",
895 | "psr",
896 | "psr-18"
897 | ],
898 | "support": {
899 | "source": "https://github.com/php-fig/http-client/tree/master"
900 | },
901 | "time": "2020-06-29T06:28:15+00:00"
902 | },
903 | {
904 | "name": "psr/http-factory",
905 | "version": "1.0.1",
906 | "source": {
907 | "type": "git",
908 | "url": "https://github.com/php-fig/http-factory.git",
909 | "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
910 | },
911 | "dist": {
912 | "type": "zip",
913 | "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
914 | "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
915 | "shasum": ""
916 | },
917 | "require": {
918 | "php": ">=7.0.0",
919 | "psr/http-message": "^1.0"
920 | },
921 | "type": "library",
922 | "extra": {
923 | "branch-alias": {
924 | "dev-master": "1.0.x-dev"
925 | }
926 | },
927 | "autoload": {
928 | "psr-4": {
929 | "Psr\\Http\\Message\\": "src/"
930 | }
931 | },
932 | "notification-url": "https://packagist.org/downloads/",
933 | "license": [
934 | "MIT"
935 | ],
936 | "authors": [
937 | {
938 | "name": "PHP-FIG",
939 | "homepage": "http://www.php-fig.org/"
940 | }
941 | ],
942 | "description": "Common interfaces for PSR-7 HTTP message factories",
943 | "keywords": [
944 | "factory",
945 | "http",
946 | "message",
947 | "psr",
948 | "psr-17",
949 | "psr-7",
950 | "request",
951 | "response"
952 | ],
953 | "support": {
954 | "source": "https://github.com/php-fig/http-factory/tree/master"
955 | },
956 | "time": "2019-04-30T12:38:16+00:00"
957 | },
958 | {
959 | "name": "psr/http-message",
960 | "version": "1.0.1",
961 | "source": {
962 | "type": "git",
963 | "url": "https://github.com/php-fig/http-message.git",
964 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
965 | },
966 | "dist": {
967 | "type": "zip",
968 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
969 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
970 | "shasum": ""
971 | },
972 | "require": {
973 | "php": ">=5.3.0"
974 | },
975 | "type": "library",
976 | "extra": {
977 | "branch-alias": {
978 | "dev-master": "1.0.x-dev"
979 | }
980 | },
981 | "autoload": {
982 | "psr-4": {
983 | "Psr\\Http\\Message\\": "src/"
984 | }
985 | },
986 | "notification-url": "https://packagist.org/downloads/",
987 | "license": [
988 | "MIT"
989 | ],
990 | "authors": [
991 | {
992 | "name": "PHP-FIG",
993 | "homepage": "http://www.php-fig.org/"
994 | }
995 | ],
996 | "description": "Common interface for HTTP messages",
997 | "homepage": "https://github.com/php-fig/http-message",
998 | "keywords": [
999 | "http",
1000 | "http-message",
1001 | "psr",
1002 | "psr-7",
1003 | "request",
1004 | "response"
1005 | ],
1006 | "support": {
1007 | "source": "https://github.com/php-fig/http-message/tree/master"
1008 | },
1009 | "time": "2016-08-06T14:39:51+00:00"
1010 | },
1011 | {
1012 | "name": "psr/log",
1013 | "version": "1.1.4",
1014 | "source": {
1015 | "type": "git",
1016 | "url": "https://github.com/php-fig/log.git",
1017 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
1018 | },
1019 | "dist": {
1020 | "type": "zip",
1021 | "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
1022 | "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
1023 | "shasum": ""
1024 | },
1025 | "require": {
1026 | "php": ">=5.3.0"
1027 | },
1028 | "type": "library",
1029 | "extra": {
1030 | "branch-alias": {
1031 | "dev-master": "1.1.x-dev"
1032 | }
1033 | },
1034 | "autoload": {
1035 | "psr-4": {
1036 | "Psr\\Log\\": "Psr/Log/"
1037 | }
1038 | },
1039 | "notification-url": "https://packagist.org/downloads/",
1040 | "license": [
1041 | "MIT"
1042 | ],
1043 | "authors": [
1044 | {
1045 | "name": "PHP-FIG",
1046 | "homepage": "https://www.php-fig.org/"
1047 | }
1048 | ],
1049 | "description": "Common interface for logging libraries",
1050 | "homepage": "https://github.com/php-fig/log",
1051 | "keywords": [
1052 | "log",
1053 | "psr",
1054 | "psr-3"
1055 | ],
1056 | "support": {
1057 | "source": "https://github.com/php-fig/log/tree/1.1.4"
1058 | },
1059 | "time": "2021-05-03T11:20:27+00:00"
1060 | },
1061 | {
1062 | "name": "ralouphie/getallheaders",
1063 | "version": "3.0.3",
1064 | "source": {
1065 | "type": "git",
1066 | "url": "https://github.com/ralouphie/getallheaders.git",
1067 | "reference": "120b605dfeb996808c31b6477290a714d356e822"
1068 | },
1069 | "dist": {
1070 | "type": "zip",
1071 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
1072 | "reference": "120b605dfeb996808c31b6477290a714d356e822",
1073 | "shasum": ""
1074 | },
1075 | "require": {
1076 | "php": ">=5.6"
1077 | },
1078 | "require-dev": {
1079 | "php-coveralls/php-coveralls": "^2.1",
1080 | "phpunit/phpunit": "^5 || ^6.5"
1081 | },
1082 | "type": "library",
1083 | "autoload": {
1084 | "files": [
1085 | "src/getallheaders.php"
1086 | ]
1087 | },
1088 | "notification-url": "https://packagist.org/downloads/",
1089 | "license": [
1090 | "MIT"
1091 | ],
1092 | "authors": [
1093 | {
1094 | "name": "Ralph Khattar",
1095 | "email": "ralph.khattar@gmail.com"
1096 | }
1097 | ],
1098 | "description": "A polyfill for getallheaders.",
1099 | "support": {
1100 | "issues": "https://github.com/ralouphie/getallheaders/issues",
1101 | "source": "https://github.com/ralouphie/getallheaders/tree/develop"
1102 | },
1103 | "time": "2019-03-08T08:55:37+00:00"
1104 | }
1105 | ],
1106 | "packages-dev": [],
1107 | "aliases": [],
1108 | "minimum-stability": "beta",
1109 | "stability-flags": [],
1110 | "prefer-stable": false,
1111 | "prefer-lowest": false,
1112 | "platform": {
1113 | "php": ">=5.4"
1114 | },
1115 | "platform-dev": [],
1116 | "plugin-api-version": "2.1.0"
1117 | }
1118 |
--------------------------------------------------------------------------------