username = Env::getInstance()->getProperty(Env::PROPERTY_PACKAGIST_USERNAME); $packagist->apiToken = Env::getInstance()->getProperty(Env::PROPERTY_PACKAGIST_APITOKEN); } catch (Throwable $e) { $this->exitError('Invalid environment: [' . get_class($e) . '] ' . $e->getMessage()); } //endregion //region Check request method and content type $requestMethod = mb_strtoupper(trim($_SERVER['REQUEST_METHOD'] ?? '')); if ($requestMethod !== 'POST') { $this->exitError('Invalid request method: ' . $requestMethod); } $contentType = mb_strtolower(trim($_SERVER['CONTENT_TYPE'] ?? '')); if ($contentType != 'application/json') { $this->exitError('Invalid content type: ' . $contentType); } //endregion //region Check payload $payload = trim(file_get_contents("php://input")); if (empty($payload)) { $this->exitError('No Gitea payload'); } $payloadSignatureExpected = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? ''; if (empty($payloadSignatureExpected)) { $this->exitError('No Gitea payload signature'); } $payloadSignature = hash_hmac('sha256', $payload, $packagist->apiToken, false); if ($payloadSignatureExpected !== $payloadSignature) { $this->exitError('Gitea payload signatures don\'t match'); } $giteaData = new stdClass(); try { $giteaData = json_decode($payload, false, 512, JSON_THROW_ON_ERROR); } catch (Throwable $e) { $this->exitError('Invalid Gitea payload (JSON decoding failed): [' . get_class($e) . '] ' . $e->getMessage()); } //endregion //region Build Packagist data $packagistData = new stdClass(); $packagistData->repository = new stdClass(); $packagistData->repository->url = $giteaData->repository->html_url; $packagistDataJSON = null; try { $packagistDataJSON = json_encode($packagistData, JSON_THROW_ON_ERROR); } catch (Throwable $e) { $this->exitError('Invalid Packagist payload (JSON encoding failed): [' . get_class($e) . '] ' . $e->getMessage()); } //endregion //region Send data to Packagist $response = null; try { $request = new Client(); $response = $request->post( 'https://packagist.org/api/update-package', [ RequestOptions::QUERY => [ 'username' => $packagist->username, 'apiToken' => $packagist->apiToken, ], RequestOptions::HTTP_ERRORS => false, RequestOptions::HEADERS => [ 'Content-Type' => 'application/json', ], RequestOptions::BODY => $packagistDataJSON, ] ); } catch (Throwable $e) { $this->exitError('Failed to send data: ' . $e->getMessage()); } //endregion //region Return the Packagist response header('Content-Type: application/json', true, $response->getStatusCode()); echo $response->getBody(); exit; //endregion } private function exitError (string $msg) { header('Content-Type: text/plain; charset=UTF-8', true, 500); echo $msg; exit; } }