wiki-grav/plugins/login/classes/Invitations/Invitations.php
2022-06-23 14:34:01 +02:00

166 lines
3.7 KiB
PHP

<?php
/**
* @package Grav\Plugin\Login
*
* @copyright Copyright (C) 2014 - 2021 RocketTheme, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Plugin\Login\Invitations;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Utils;
use RocketTheme\Toolbox\ArrayTraits\ArrayAccess;
use RocketTheme\Toolbox\ArrayTraits\Countable;
use RocketTheme\Toolbox\ArrayTraits\Iterator;
/**
* Invite users to the site.
*
* Tools to send emails for invites and handle invite registrations.
*/
class Invitations implements \Countable, \Iterator, \ArrayAccess
{
use ArrayAccess;
use Countable;
use Iterator;
/** @var static */
public static $instance;
/** @var string */
private $inviteFile = 'user-data://accounts/invites.yaml';
/** @var array|null */
private $items;
/** @var array|null */
private $emails;
public static function getInstance()
{
if (null === static::$instance) {
static::$instance = new static();
}
return static::$instance;
}
public function __construct()
{
$this->items = $this->load();
}
public function offsetGet($offset): ?Invitation
{
$data = $this->items[$offset] ?? null;
return $data ? new Invitation($offset, $data) :null;
}
public function offsetSet($offset, $value): void
{
if (!$value instanceof Invitation) {
throw new \RuntimeException('Value has to be instance of Invitation');
}
if (null === $offset) {
$offset = $value->token;
}
$this->items[$offset] = $value->toArray();
}
public function current(): ?Invitation
{
return $this->offsetGet($this->key());
}
public function get(string $token): ?Invitation
{
return $this->offsetGet($token);
}
public function getByEmail(string $email): ?Invitation
{
if (null === $this->emails) {
$this->emails = [];
foreach ($this->items as $token => $invite) {
$this->emails[$invite['email']] = $token;
}
}
if (isset($this->emails[$email])) {
return $this->offsetGet($this->emails[$email]);
}
return null;
}
public function getByIssuer(string $email): array
{
$list = [];
foreach ($this->items as $token => $invite) {
$test = $invite['email'] ?? null;
if ($email === $test) {
$list[] = $this->offsetGet($token);
}
}
return $list;
}
public function add(Invitation $invitation): void
{
$this->offsetSet(null, $invitation);
}
public function remove(Invitation $invitation): void
{
$this->offsetUnset($invitation->token);
}
public function removeExpired(): int
{
$now = time();
$count = 0;
foreach ($this->items as $token => $invite) {
if ($invite['expiration_timestamp'] < $now) {
$this->offsetUnset($token);
$count++;
}
}
return $count;
}
public function save(): void
{
$file = $this->getFile();
$file->save($this->items);
}
public function generateToken(): string
{
do {
$id = Utils::uniqueId(24);
} while (isset($this->items[$id]));
return $id;
}
private function load(): array
{
$file = $this->getFile();
$data = $file->content();
$file->free();
return $data;
}
private function getFile(): CompiledYamlFile
{
return CompiledYamlFile::instance($this->inviteFile);
}
}