allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s

This commit is contained in:
2026-03-30 14:54:57 +07:00
parent 66aed7c4e8
commit b5e3a778ce
21316 changed files with 2777892 additions and 13 deletions

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Kreait\Firebase\Request;
use Kreait\Firebase\Exception\InvalidArgumentException;
use Kreait\Firebase\Request;
final class CreateUser implements Request
{
/** @phpstan-use EditUserTrait<self> */
use EditUserTrait;
private function __construct()
{
}
public static function new(): self
{
return new self();
}
/**
* @param array<string, mixed> $properties
*
* @throws InvalidArgumentException when invalid properties have been provided
*/
public static function withProperties(array $properties): self
{
return self::withEditableProperties(new self(), $properties);
}
public function jsonSerialize(): array
{
return $this->prepareJsonSerialize();
}
}

View File

@@ -0,0 +1,274 @@
<?php
declare(strict_types=1);
namespace Kreait\Firebase\Request;
use Kreait\Firebase\Exception\InvalidArgumentException;
use Kreait\Firebase\Value\ClearTextPassword;
use Kreait\Firebase\Value\Email;
use Kreait\Firebase\Value\Uid;
use Kreait\Firebase\Value\Url;
use Stringable;
use function array_filter;
use function mb_strtolower;
use function preg_replace;
/**
* @template T
*/
trait EditUserTrait
{
protected ?string $uid = null;
protected ?string $email = null;
protected ?string $displayName = null;
protected ?bool $emailIsVerified = null;
protected ?string $phoneNumber = null;
protected ?string $photoUrl = null;
protected ?bool $markAsEnabled = null;
protected ?bool $markAsDisabled = null;
protected ?string $clearTextPassword = null;
/** @var array<string, mixed>|null */
protected ?array $multiFactor = null;
/**
* @param Stringable|mixed $uid
*/
public function withUid($uid): self
{
$request = clone $this;
$request->uid = Uid::fromString($uid)->value;
return $request;
}
public function withEmail(Stringable|string $email): self
{
$request = clone $this;
$request->email = Email::fromString((string) $email)->value;
return $request;
}
public function withVerifiedEmail(Stringable|string $email): self
{
$request = clone $this;
$request->email = Email::fromString((string) $email)->value;
$request->emailIsVerified = true;
return $request;
}
public function withUnverifiedEmail(Stringable|string $email): self
{
$request = clone $this;
$request->email = Email::fromString((string) $email)->value;
$request->emailIsVerified = false;
return $request;
}
public function withDisplayName(string $displayName): self
{
$request = clone $this;
$request->displayName = $displayName;
return $request;
}
/**
* @param Stringable|string|null $phoneNumber
*/
public function withPhoneNumber($phoneNumber): self
{
$phoneNumber = $phoneNumber !== null ? (string) $phoneNumber : null;
$request = clone $this;
$request->phoneNumber = $phoneNumber;
return $request;
}
public function withPhotoUrl(Stringable|string $url): self
{
$request = clone $this;
$request->photoUrl = Url::fromString($url)->value;
return $request;
}
public function markAsDisabled(): self
{
$request = clone $this;
$request->markAsEnabled = null;
$request->markAsDisabled = true;
return $request;
}
public function markAsEnabled(): self
{
$request = clone $this;
$request->markAsDisabled = null;
$request->markAsEnabled = true;
return $request;
}
public function markEmailAsVerified(): self
{
$request = clone $this;
$request->emailIsVerified = true;
return $request;
}
public function markEmailAsUnverified(): self
{
$request = clone $this;
$request->emailIsVerified = false;
return $request;
}
public function withClearTextPassword(Stringable|string $clearTextPassword): self
{
$request = clone $this;
$request->clearTextPassword = ClearTextPassword::fromString($clearTextPassword)->value;
return $request;
}
/**
* @return array<string, mixed>
*/
public function prepareJsonSerialize(): array
{
$disableUser = null;
if ($this->markAsDisabled === true) {
$disableUser = true;
} elseif ($this->markAsEnabled === true) {
$disableUser = false;
}
return array_filter([
'localId' => $this->uid,
'disableUser' => $disableUser,
'displayName' => $this->displayName,
'email' => $this->email,
'emailVerified' => $this->emailIsVerified,
'phoneNumber' => $this->phoneNumber,
'photoUrl' => $this->photoUrl,
'password' => $this->clearTextPassword,
'mfa' => $this->multiFactor,
], static fn($value): bool => $value !== null);
}
public function hasUid(): bool
{
return (bool) $this->uid;
}
/**
* @param T $request
* @param array<string, mixed> $properties
*
* @throws InvalidArgumentException when invalid properties have been provided
*
* @return T
*/
protected static function withEditableProperties(self $request, array $properties): self
{
foreach ($properties as $key => $value) {
switch (mb_strtolower((string) preg_replace('/[^a-z]/i', '', $key))) {
case 'uid':
case 'localid':
$request = $request->withUid($value);
break;
case 'email':
$request = $request->withEmail($value);
break;
case 'unverifiedemail':
$request = $request->withUnverifiedEmail($value);
break;
case 'verifiedemail':
$request = $request->withVerifiedEmail($value);
break;
case 'emailverified':
if ($value === true) {
$request = $request->markEmailAsVerified();
} elseif ($value === false) {
$request = $request->markEmailAsUnverified();
}
break;
case 'displayname':
$request = $request->withDisplayName($value);
break;
case 'phone':
case 'phonenumber':
$request = $request->withPhoneNumber($value);
break;
case 'photo':
case 'photourl':
$request = $request->withPhotoUrl($value);
break;
case 'disableuser':
case 'disabled':
case 'isdisabled':
if ($value === true) {
$request = $request->markAsDisabled();
} elseif ($value === false) {
$request = $request->markAsEnabled();
}
break;
case 'enableuser':
case 'enabled':
case 'isenabled':
if ($value === true) {
$request = $request->markAsEnabled();
} elseif ($value === false) {
$request = $request->markAsDisabled();
}
break;
case 'password':
case 'cleartextpassword':
$request = $request->withClearTextPassword($value);
break;
}
}
return $request;
}
}

View File

@@ -0,0 +1,292 @@
<?php
declare(strict_types=1);
namespace Kreait\Firebase\Request;
use Beste\Json;
use Kreait\Firebase\Exception\InvalidArgumentException;
use Kreait\Firebase\Request;
use Stringable;
use function array_reduce;
use function array_unique;
use function is_array;
use function is_string;
use function mb_strtolower;
use function preg_replace;
final class UpdateUser implements Request
{
/** @phpstan-use EditUserTrait<self> */
use EditUserTrait;
public const DISPLAY_NAME = 'DISPLAY_NAME';
public const PHOTO_URL = 'PHOTO_URL';
public const EMAIL = 'EMAIL';
/**
* @var list<non-empty-string>
*/
private array $attributesToDelete = [];
/**
* @var list<non-empty-string>
*/
private array $providersToDelete = [];
/**
* @var array<string, mixed>|null
*/
private ?array $customAttributes = null;
private function __construct()
{
}
public static function new(): self
{
return new self();
}
/**
* @param array<string, mixed> $properties
*
* @throws InvalidArgumentException when invalid properties have been provided
*/
public static function withProperties(array $properties): self
{
$request = self::withEditableProperties(new self(), $properties);
foreach ($properties as $key => $value) {
switch (mb_strtolower((string) preg_replace('/[^a-z]/i', '', $key))) {
case 'deletephoto':
case 'deletephotourl':
case 'removephoto':
case 'removephotourl':
$request = $request->withRemovedPhotoUrl();
break;
case 'deletedisplayname':
case 'removedisplayname':
$request = $request->withRemovedDisplayName();
break;
case 'deleteemail':
case 'removeemail':
$request = $request->withRemovedEmail();
break;
case 'deleteattribute':
case 'deleteattributes':
foreach ((array) $value as $deleteAttribute) {
if (!is_string($deleteAttribute)) {
continue;
}
if ($deleteAttribute === '') {
continue;
}
$deleteAttribute = preg_replace('/[^a-z]/i', '', $deleteAttribute);
if ($deleteAttribute === null) {
continue;
}
switch (mb_strtolower($deleteAttribute)) {
case 'displayname':
$request = $request->withRemovedDisplayName();
break;
case 'photo':
case 'photourl':
$request = $request->withRemovedPhotoUrl();
break;
case 'email':
$request = $request->withRemovedEmail();
break;
}
}
break;
case 'customattributes':
case 'customclaims':
$request = $request->withCustomAttributes($value);
break;
case 'phonenumber':
case 'phone':
if (in_array($value, [false, null, ''], true)) {
$request = $request->withRemovedPhoneNumber();
}
break;
case 'deletephone':
case 'deletephonenumber':
case 'removephone':
case 'removephonenumber':
$request = $request->withRemovedPhoneNumber();
break;
case 'deleteprovider':
case 'deleteproviders':
case 'removeprovider':
case 'removeproviders':
$request = array_reduce(
(array) $value,
static fn(self $request, $provider): UpdateUser => $request->withRemovedProvider($provider),
$request,
);
break;
case 'resetmultifactor':
if ($value === true) {
$request = $request->resetMultiFactor();
}
break;
case 'multifactors':
$request = $request->withMultiFactors($value);
break;
}
}
return $request;
}
public function withRemovedPhoneNumber(): self
{
$request = clone $this;
$request->phoneNumber = null;
return $request->withRemovedProvider('phone');
}
/**
* @param Stringable|string $provider
*/
public function withRemovedProvider($provider): self
{
$providerString = trim((string) $provider);
if ($providerString === '') {
return $this;
}
$request = clone $this;
$request->providersToDelete[] = $providerString;
return $request;
}
public function withRemovedDisplayName(): self
{
$request = clone $this;
$request->displayName = null;
$request->attributesToDelete[] = self::DISPLAY_NAME;
return $request;
}
public function withRemovedPhotoUrl(): self
{
$request = clone $this;
$request->photoUrl = null;
$request->attributesToDelete[] = self::PHOTO_URL;
return $request;
}
public function withRemovedEmail(): self
{
$request = clone $this;
$request->email = null;
$request->attributesToDelete[] = self::EMAIL;
return $request;
}
/**
* @param array<array-key, array{
* 'mfaEnrollmentId'?: string,
* 'displayName': string,
* 'phoneInfo': string,
* 'enrolledAt'?: string,
* }> $enrollments
*/
public function withMultiFactors(array $enrollments): self
{
$request = clone $this;
$request->multiFactor ??= [];
$request->multiFactor['enrollments'] = $enrollments;
return $request;
}
public function resetMultiFactor(): self
{
$request = clone $this;
$request->multiFactor ??= [];
$request->multiFactor['enrollments'] = [];
return $request;
}
/**
* @param array<string, mixed> $customAttributes
*/
public function withCustomAttributes(array $customAttributes): self
{
$request = clone $this;
$request->customAttributes = $customAttributes;
return $request;
}
/**
* @return array{
* customAttributes?: string,
* deleteAttribute?: list<non-empty-string>,
* deleteProvider?: list<non-empty-string>,
* }
*/
public function jsonSerialize(): array
{
if (!$this->hasUid()) {
throw new InvalidArgumentException('A uid is required to update an existing user.');
}
$data = $this->prepareJsonSerialize();
if (is_array($this->customAttributes)) {
$data['customAttributes'] = $this->customAttributes === [] ? '{}' : Json::encode($this->customAttributes);
}
if ($this->attributesToDelete !== []) {
$data['deleteAttribute'] = array_unique($this->attributesToDelete);
}
if ($this->providersToDelete !== []) {
$data['deleteProvider'] = $this->providersToDelete;
}
return $data;
}
}