commit
da79516766
49 changed files with 1665 additions and 12 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
/app/config/main.php
|
||||
/app/config/_*
|
||||
/app/config/db/*
|
||||
/app/config/ext/*
|
||||
/app/cache/**/*.php
|
||||
/app/cache/**/*.lock
|
||||
/app/cache/**/*.tmp
|
||||
|
|
|
@ -838,6 +838,18 @@ class Routing
|
|||
'AdminAntispam:view',
|
||||
'AdminAntispam'
|
||||
);
|
||||
$r->add(
|
||||
$r::GET,
|
||||
'/admin/extensions',
|
||||
'AdminExtensions:info',
|
||||
'AdminExtensions'
|
||||
);
|
||||
$r->add(
|
||||
$r::PST,
|
||||
'/admin/extensions/action',
|
||||
'AdminExtensions:action',
|
||||
'AdminExtensionsAction'
|
||||
);
|
||||
}
|
||||
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
|
|
|
@ -171,7 +171,7 @@ class Compiler
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use function \ForkBB\{__, num, dt, size};
|
||||
use function \ForkBB\{__, num, dt, size, url};
|
||||
|
||||
?>
|
||||
EOD;
|
||||
|
|
191
app/Models/Extension/Extension.php
Normal file
191
app/Models/Extension/Extension.php
Normal file
|
@ -0,0 +1,191 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of the ForkBB <https://github.com/forkbb>.
|
||||
*
|
||||
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
|
||||
* @license The MIT License (MIT)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ForkBB\Models\Extension;
|
||||
|
||||
use ForkBB\Models\Model;
|
||||
use RuntimeException;
|
||||
|
||||
class Extension extends Model
|
||||
{
|
||||
const NOT_INSTALLED = 0;
|
||||
const DISABLED = 4;
|
||||
const DISABLED_DOWN = 5;
|
||||
const DISABLED_UP = 6;
|
||||
const ENABLED = 8;
|
||||
const ENABLED_DOWN = 9;
|
||||
const ENABLED_UP = 10;
|
||||
const CRASH = 12;
|
||||
|
||||
/**
|
||||
* Ключ модели для контейнера
|
||||
*/
|
||||
protected string $cKey = 'Extension';
|
||||
|
||||
protected array $prepareData;
|
||||
|
||||
protected function getdispalyName(): string
|
||||
{
|
||||
return $this->dbData['extra']['display-name'] ?? $this->fileData['extra']['display-name'];
|
||||
}
|
||||
|
||||
protected function getversion(): string
|
||||
{
|
||||
return $this->dbData['version'] ?? $this->fileData['version'];
|
||||
}
|
||||
|
||||
protected function getfileVersion(): string
|
||||
{
|
||||
return $this->fileData['version'] ?? '-';
|
||||
}
|
||||
|
||||
protected function getname(): string
|
||||
{
|
||||
return $this->dbData['name'] ?? $this->fileData['name'];
|
||||
}
|
||||
|
||||
protected function getid(): string
|
||||
{
|
||||
return 'ext-' . \trim(\preg_replace('%\W+%', '-', $this->name), '-');
|
||||
}
|
||||
|
||||
protected function getdescription(): string
|
||||
{
|
||||
return $this->dbData['description'] ?? $this->fileData['description'];
|
||||
}
|
||||
|
||||
protected function gettime(): ?string
|
||||
{
|
||||
return $this->dbData['time'] ?? $this->fileData['time'];
|
||||
}
|
||||
|
||||
protected function gethomepage(): ?string
|
||||
{
|
||||
return $this->dbData['homepage'] ?? $this->fileData['homepage'];
|
||||
}
|
||||
|
||||
protected function getlicense(): ?string
|
||||
{
|
||||
return $this->dbData['license'] ?? $this->fileData['license'];
|
||||
}
|
||||
|
||||
protected function getrequirements(): array
|
||||
{
|
||||
return $this->dbData['extra']['requirements'] ?? $this->fileData['extra']['requirements'];
|
||||
}
|
||||
|
||||
protected function getauthors(): array
|
||||
{
|
||||
return $this->dbData['authors'] ?? $this->fileData['authors'];
|
||||
}
|
||||
|
||||
protected function getstatus(): int
|
||||
{
|
||||
if (null === $this->dbStatus) {
|
||||
return self::NOT_INSTALLED;
|
||||
} elseif (empty($this->fileData['version'])) {
|
||||
return self::CRASH;
|
||||
}
|
||||
|
||||
switch (
|
||||
\version_compare($this->fileData['version'], $this->dbData['version'])
|
||||
+ 4 * (1 === $this->dbStatus)
|
||||
) {
|
||||
case -1:
|
||||
return self::DISABLED_DOWN;
|
||||
case 0:
|
||||
return self::DISABLED;
|
||||
case 1:
|
||||
return self::DISABLED_UP;
|
||||
case 3:
|
||||
return self::ENABLED_DOWN;
|
||||
case 4:
|
||||
return self::ENABLED;
|
||||
case 5:
|
||||
return self::ENABLED_UP;
|
||||
default:
|
||||
throw new RuntimeException("Error in {$this->name} extension status");
|
||||
}
|
||||
}
|
||||
|
||||
protected function getcanInstall(): bool
|
||||
{
|
||||
return self::NOT_INSTALLED === $this->status;
|
||||
}
|
||||
|
||||
protected function getcanUninstall(): bool
|
||||
{
|
||||
return \in_array($this->status, [self::DISABLED, self::DISABLED_DOWN, self::DISABLED_UP], true);
|
||||
}
|
||||
|
||||
protected function getcanUpdate(): bool
|
||||
{
|
||||
return \in_array($this->status, [self::DISABLED_UP, self::ENABLED_UP], true);
|
||||
}
|
||||
|
||||
protected function getcanDowndate(): bool
|
||||
{
|
||||
return \in_array($this->status, [self::DISABLED_DOWN, self::ENABLED_DOWN], true);
|
||||
}
|
||||
|
||||
protected function getcanEnable(): bool
|
||||
{
|
||||
return self::DISABLED === $this->status;
|
||||
}
|
||||
|
||||
protected function getcanDisable(): bool
|
||||
{
|
||||
return \in_array($this->status, [self::ENABLED, self::ENABLED_DOWN, self::ENABLED_UP, self::CRASH], true);
|
||||
}
|
||||
|
||||
public function prepare(): bool|string|array
|
||||
{
|
||||
$this->prepareData = [];
|
||||
|
||||
if ($this->fileData['extra']['templates']) {
|
||||
foreach ($this->fileData['extra']['templates'] as $cur) {
|
||||
switch($cur['type']) {
|
||||
case 'pre':
|
||||
if (empty($cur['name'])) {
|
||||
return 'PRE name not found';
|
||||
} elseif (empty($cur['file'])) {
|
||||
return ['Template file \'%s\' not found', $cur['file']];
|
||||
}
|
||||
|
||||
$path = $this->fileData['path'] . '/' . \ltrim($cur['file'], '\\/');
|
||||
|
||||
if (! \is_file($path)) {
|
||||
return ['Template file \'%s\' not found', $cur['file']];
|
||||
}
|
||||
|
||||
$data = \file_get_contents($path);
|
||||
|
||||
foreach (\explode(',', $cur['template']) as $template) {
|
||||
$this->prepareData['templates']['pre'][$template][$cur['name']][] = [
|
||||
'priority' => $cur['priority'] ?: 0,
|
||||
'data' => $data,
|
||||
];
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return 'Invalid template type';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function prepareData(): array
|
||||
{
|
||||
return $this->prepareData;
|
||||
}
|
||||
}
|
547
app/Models/Extension/Extensions.php
Normal file
547
app/Models/Extension/Extensions.php
Normal file
|
@ -0,0 +1,547 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of the ForkBB <https://github.com/forkbb>.
|
||||
*
|
||||
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
|
||||
* @license The MIT License (MIT)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ForkBB\Models\Extension;
|
||||
|
||||
use ForkBB\Models\Extension\Extension;
|
||||
use ForkBB\Models\Manager;
|
||||
use FilesystemIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use RegexIterator;
|
||||
use RuntimeException;
|
||||
|
||||
class Extensions extends Manager
|
||||
{
|
||||
/**
|
||||
* Ключ модели для контейнера
|
||||
*/
|
||||
protected string $cKey = 'Extensions';
|
||||
|
||||
/**
|
||||
* Список отсканированных папок
|
||||
*/
|
||||
protected array $folders = [];
|
||||
|
||||
/**
|
||||
* Текст ошибки
|
||||
*/
|
||||
protected string|array $error = '';
|
||||
|
||||
protected string $commonFile;
|
||||
protected string $preFile;
|
||||
|
||||
/**
|
||||
* Возвращает action (или свойство) по его имени
|
||||
*/
|
||||
public function __get(string $name): mixed
|
||||
{
|
||||
return 'error' === $name ? $this->error : parent::__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализирует менеджер
|
||||
*/
|
||||
public function init(): Extensions
|
||||
{
|
||||
$this->commonFile = $this->c->DIR_CONFIG . '/ext/common.php';
|
||||
$this->preFile = $this->c->DIR_CONFIG . '/ext/pre.php';
|
||||
|
||||
$this->fromDB();
|
||||
|
||||
$list = $this->scan($this->c->DIR_EXT);
|
||||
|
||||
$this->fromList($this->prepare($list));
|
||||
|
||||
\uasort($this->repository, function (Extension $a, Extension $b) {
|
||||
return $a->dispalyName <=> $b->dispalyName;
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает в репозиторий из БД список расширений
|
||||
*/
|
||||
protected function fromDB(): void
|
||||
{
|
||||
$query = 'SELECT ext_name, ext_status, ext_data
|
||||
FROM ::extensions
|
||||
ORDER BY ext_name';
|
||||
|
||||
$stmt = $this->c->DB->query($query);
|
||||
|
||||
while ($row = $stmt->fetch()) {
|
||||
$model = $this->c->ExtensionModel->setModelAttrs([
|
||||
'name' => $row['ext_name'],
|
||||
'dbStatus' => $row['ext_status'],
|
||||
'dbData' => \json_decode($row['ext_data'], true, 512, \JSON_THROW_ON_ERROR),
|
||||
]);
|
||||
|
||||
$this->set($row['ext_name'], $model);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Заполняет массив данными из файлов composer.json
|
||||
*/
|
||||
protected function scan(string $folder, array $result = []): array
|
||||
{
|
||||
$folder = \rtrim($folder, '\\/');
|
||||
|
||||
if (
|
||||
empty($folder)
|
||||
|| ! \is_dir($folder)
|
||||
) {
|
||||
throw new RuntimeException("Not a directory: {$folder}");
|
||||
}
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($folder, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
$files = new RegexIterator($iterator, '%[\\\\/]composer\.json$%i', RegexIterator::MATCH);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$data = \file_get_contents($file->getPathname());
|
||||
|
||||
if (\is_string($data)) {
|
||||
$data = \json_decode($data, true);
|
||||
}
|
||||
|
||||
$result[$file->getPath()] = $data;
|
||||
}
|
||||
|
||||
$this->folders[] = $folder;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Подготавливает данные для моделей
|
||||
*/
|
||||
protected function prepare(array $files): array
|
||||
{
|
||||
$v = clone $this->c->Validator;
|
||||
$v = $v->reset()
|
||||
->addValidators([
|
||||
])->addRules([
|
||||
'name' => 'required|string|regex:%^[a-z0-9](?:[_.-]?[a-z0-9]+)*/[a-z0-9](?:[_.-]?[a-z0-9]+)*$%',
|
||||
'type' => 'required|string|in:forkbb-extension',
|
||||
'description' => 'required|string',
|
||||
'homepage' => 'string',
|
||||
'version' => 'required|string',
|
||||
'time' => 'string',
|
||||
'license' => 'string',
|
||||
'authors' => 'required|array',
|
||||
'authors.*.name' => 'required|string',
|
||||
'authors.*.email' => 'string',
|
||||
'authors.*.homepage' => 'string',
|
||||
'authors.*.role' => 'string',
|
||||
'autoload.psr-4' => 'array',
|
||||
'autoload.psr-4.*' => 'required|string',
|
||||
'require' => 'array',
|
||||
'extra' => 'required|array',
|
||||
'extra.display-name' => 'required|string',
|
||||
'extra.requirements' => 'array',
|
||||
'extra.templates' => 'array',
|
||||
'extra.templates.*.type' => 'required|string|in:pre',
|
||||
'extra.templates.*.template' => 'required|string',
|
||||
'extra.templates.*.name' => 'string',
|
||||
'extra.templates.*.priority' => 'integer',
|
||||
'extra.templates.*.file' => 'string',
|
||||
])->addAliases([
|
||||
])->addArguments([
|
||||
])->addMessages([
|
||||
]);
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($files as $path => $file) {
|
||||
if (! \is_array($file)) {
|
||||
continue;
|
||||
} elseif (! $v->validation($file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = $v->getData(true);
|
||||
$data['path'] = $path;
|
||||
$result[$v->name] = $data;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Дополняет репозиторий данными из файлов composer.json
|
||||
*/
|
||||
protected function fromList(array $list): void
|
||||
{
|
||||
foreach ($list as $name => $data) {
|
||||
$model = $this->get($name);
|
||||
|
||||
if (! $model instanceof Extension) {
|
||||
$model = $this->c->ExtensionModel->setModelAttrs([
|
||||
'name' => $name,
|
||||
'fileData' => $data,
|
||||
]);
|
||||
|
||||
$this->set($name, $model);
|
||||
} else {
|
||||
$model->setModelAttr('fileData', $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает расширение
|
||||
*/
|
||||
public function install(Extension $ext): bool
|
||||
{
|
||||
if (true !== $ext->canInstall) {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $ext->prepare();
|
||||
|
||||
if (true !== $result) {
|
||||
$this->error = $result;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':name' => $ext->name,
|
||||
':data' => \json_encode($ext->fileData, FORK_JSON_ENCODE),
|
||||
];
|
||||
$query = 'INSERT INTO ::extensions (ext_name, ext_status, ext_data)
|
||||
VALUES(?s:name, 1, ?s:data)';
|
||||
|
||||
$ext->setModelAttrs([
|
||||
'name' => $ext->name,
|
||||
'dbStatus' => 1,
|
||||
'dbData' => $ext->fileData,
|
||||
'fileData' => $ext->fileData,
|
||||
]);
|
||||
|
||||
if (true !== $this->updateCommon($ext)) {
|
||||
$this->error = 'An error occurred in updateCommon';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->updateIndividual();
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляет расширение
|
||||
*/
|
||||
public function uninstall(Extension $ext): bool
|
||||
{
|
||||
if (true !== $ext->canUninstall) {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$oldStatus = $ext->dbStatus;
|
||||
|
||||
$vars = [
|
||||
':name' => $ext->name,
|
||||
];
|
||||
$query = 'DELETE
|
||||
FROM ::extensions
|
||||
WHERE ext_name=?s:name';
|
||||
|
||||
$ext->setModelAttrs([
|
||||
'name' => $ext->name,
|
||||
'dbStatus' => null,
|
||||
'dbData' => null,
|
||||
'fileData' => $ext->fileData,
|
||||
]);
|
||||
|
||||
if (true !== $this->updateCommon($ext)) {
|
||||
$this->error = 'An error occurred in updateCommon';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($oldStatus) {
|
||||
$this->updateIndividual();
|
||||
}
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет расширение
|
||||
*/
|
||||
public function update(Extension $ext): bool
|
||||
{
|
||||
if (true === $ext->canUpdate) {
|
||||
return $this->updown($ext);
|
||||
} else {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет расширение
|
||||
*/
|
||||
public function downdate(Extension $ext): bool
|
||||
{
|
||||
if (true === $ext->canDowndate) {
|
||||
return $this->updown($ext);
|
||||
} else {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updown(Extension $ext): bool
|
||||
{
|
||||
$oldStatus = $ext->dbStatus;
|
||||
$result = $ext->prepare();
|
||||
|
||||
if (true !== $result) {
|
||||
$this->error = $result;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':name' => $ext->name,
|
||||
':data' => \json_encode($ext->fileData, FORK_JSON_ENCODE),
|
||||
];
|
||||
$query = 'UPDATE ::extensions SET ext_data=?s:data
|
||||
WHERE ext_name=?s:name';
|
||||
|
||||
$ext->setModelAttrs([
|
||||
'name' => $ext->name,
|
||||
'dbStatus' => $ext->dbStatus,
|
||||
'dbData' => $ext->fileData,
|
||||
'fileData' => $ext->fileData,
|
||||
]);
|
||||
|
||||
if (true !== $this->updateCommon($ext)) {
|
||||
$this->error = 'An error occurred in updateCommon';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($oldStatus) {
|
||||
$this->updateIndividual();
|
||||
}
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Включает расширение
|
||||
*/
|
||||
public function enable(Extension $ext): bool
|
||||
{
|
||||
if (true !== $ext->canEnable) {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':name' => $ext->name,
|
||||
];
|
||||
$query = 'UPDATE ::extensions SET ext_status=1
|
||||
WHERE ext_name=?s:name';
|
||||
|
||||
$ext->setModelAttrs([
|
||||
'name' => $ext->name,
|
||||
'dbStatus' => 1,
|
||||
'dbData' => $ext->dbData,
|
||||
'fileData' => $ext->fileData,
|
||||
]);
|
||||
|
||||
$this->updateIndividual();
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Выключает расширение
|
||||
*/
|
||||
public function disable(Extension $ext): bool
|
||||
{
|
||||
if (true !== $ext->canDisable) {
|
||||
$this->error = 'Invalid action';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':name' => $ext->name,
|
||||
];
|
||||
$query = 'UPDATE ::extensions SET ext_status=0
|
||||
WHERE ext_name=?s:name';
|
||||
|
||||
$ext->setModelAttrs([
|
||||
'name' => $ext->name,
|
||||
'dbStatus' => 0,
|
||||
'dbData' => $ext->dbData,
|
||||
'fileData' => $ext->fileData,
|
||||
]);
|
||||
|
||||
$this->updateIndividual();
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает данные из файла с общими данными по расширениям
|
||||
*/
|
||||
protected function loadDataFromFile(string $file): array
|
||||
{
|
||||
if (\is_file($file)) {
|
||||
return include $file;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет файл с общими данными по расширениям
|
||||
*/
|
||||
protected function updateCommon(Extension $ext): bool
|
||||
{
|
||||
$data = $this->loadDataFromFile($this->commonFile);
|
||||
|
||||
if ($ext::NOT_INSTALLED === $ext->status) {
|
||||
unset($data[$ext->name]);
|
||||
} else {
|
||||
$data[$ext->name] = $ext->prepareData();
|
||||
}
|
||||
|
||||
return $this->putData($this->commonFile, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Записывает данные в указанный файл
|
||||
*/
|
||||
protected function putData(string $file, mixed $data): bool
|
||||
{
|
||||
$content = "<?php\n\nreturn " . \var_export($data, true) . ";\n";
|
||||
|
||||
if (false === \file_put_contents($file, $content, \LOCK_EX)) {
|
||||
return false;
|
||||
} else {
|
||||
if (\function_exists('\\opcache_invalidate')) {
|
||||
\opcache_invalidate($file, true);
|
||||
} elseif (\function_exists('\\apc_delete_file')) {
|
||||
\apc_delete_file($file);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет индивидуальные файлы с данными по расширениям
|
||||
*/
|
||||
protected function updateIndividual(): bool
|
||||
{
|
||||
$oldPre = $this->loadDataFromFile($this->preFile);
|
||||
$templates = [];
|
||||
$commonData = $this->loadDataFromFile($this->commonFile);
|
||||
$pre = [];
|
||||
$newPre = [];
|
||||
|
||||
// выделение данных
|
||||
foreach ($this->repository as $ext) {
|
||||
if (1 !== $ext->dbStatus) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($commonData[$ext->name]['templates']['pre'])) {
|
||||
$pre = \array_merge_recursive($pre, $commonData[$ext->name]['templates']['pre']);
|
||||
}
|
||||
}
|
||||
|
||||
// PRE-данные шаблонов
|
||||
foreach ($pre as $template => $names) {
|
||||
$templates[$template] = $template;
|
||||
|
||||
foreach ($names as $name => $list) {
|
||||
\uasort($list, function (array $a, array $b) {
|
||||
return $b['priority'] <=> $a['priority'];
|
||||
});
|
||||
|
||||
$result = '';
|
||||
|
||||
foreach ($list as $value) {
|
||||
$result .= $value['data'];
|
||||
}
|
||||
|
||||
$newPre[$template][$name] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
$this->putData($this->preFile, $newPre);
|
||||
|
||||
// удаление скомпилированных шаблонов
|
||||
foreach (\array_merge($this->diffPre($oldPre, $newPre), $this->diffPre($newPre, $oldPre)) as $template) {
|
||||
$this->c->View->delete($template);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Вычисляет расхождение для PRE-данных
|
||||
*/
|
||||
protected function diffPre(array $a, array $b): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($a as $template => $names) {
|
||||
if (! isset($b[$template])) {
|
||||
$result[$template] = $template;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($names as $name => $value) {
|
||||
if (
|
||||
! isset($b[$template][$name])
|
||||
|| $value !== $b[$template][$name]
|
||||
) {
|
||||
$result[$template] = $template;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -82,6 +82,7 @@ abstract class Admin extends Page
|
|||
'uploads' => [$r->link('AdminUploads'), 'Uploads'],
|
||||
'antispam' => [$r->link('AdminAntispam'), 'Antispam'],
|
||||
'logs' => [$r->link('AdminLogs'), 'Logs'],
|
||||
'extensions' => [$r->link('AdminExtensions'), 'Extensions'],
|
||||
'maintenance' => [$r->link('AdminMaintenance'), 'Maintenance'],
|
||||
];
|
||||
}
|
||||
|
|
84
app/Models/Pages/Admin/Extensions.php
Normal file
84
app/Models/Pages/Admin/Extensions.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of the ForkBB <https://github.com/forkbb>.
|
||||
*
|
||||
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
|
||||
* @license The MIT License (MIT)
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ForkBB\Models\Pages\Admin;
|
||||
|
||||
use ForkBB\Models\Extension\Extension;
|
||||
use ForkBB\Models\Page;
|
||||
use ForkBB\Models\Pages\Admin;
|
||||
use Throwable;
|
||||
use function \ForkBB\__;
|
||||
|
||||
class Extensions extends Admin
|
||||
{
|
||||
/**
|
||||
* Подготавливает данные для шаблона
|
||||
*/
|
||||
public function info(array $args, string $method): Page
|
||||
{
|
||||
$this->c->Lang->load('admin_extensions');
|
||||
|
||||
$this->nameTpl = 'admin/extensions';
|
||||
$this->aIndex = 'extensions';
|
||||
$this->extensions = $this->c->extensions->repository;
|
||||
$this->actionLink = $this->c->Router->link('AdminExtensionsAction');
|
||||
$this->formsToken = $this->c->Csrf->create('AdminExtensionsAction');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function action(array $args, string $method): Page
|
||||
{
|
||||
$this->c->Lang->load('admin_extensions');
|
||||
|
||||
$v = $this->c->Validator->reset()
|
||||
->addRules([
|
||||
'token' => 'token:AdminExtensionsAction',
|
||||
'name' => 'required|string',
|
||||
'confirm' => 'required|string|in:1',
|
||||
'install' => 'string',
|
||||
'uninstall' => 'string',
|
||||
'update' => 'string',
|
||||
'downdate' => 'string',
|
||||
'enable' => 'string',
|
||||
'disable' => 'string',
|
||||
])->addAliases([
|
||||
])->addMessages([
|
||||
'confirm' => [FORK_MESS_WARN, 'No confirm redirect'],
|
||||
])->addArguments([
|
||||
]);
|
||||
|
||||
if (! $v->validation($_POST)) {
|
||||
$message = $this->c->Message;
|
||||
$message->fIswev = $v->getErrors();
|
||||
|
||||
return $message->message('');
|
||||
}
|
||||
|
||||
$ext = $this->c->extensions->get($v->name);
|
||||
|
||||
if (! $ext instanceof Extension) {
|
||||
return $this->c->Message->message('Extension not found');
|
||||
}
|
||||
|
||||
$actions = $v->getData(false, ['token', 'name', 'confirm']);
|
||||
$action = \array_key_first($actions);
|
||||
|
||||
if (empty($action)) {
|
||||
return $this->c->Message->message('Invalid action');
|
||||
}
|
||||
|
||||
if (true !== $this->c->extensions->{$action}($ext)) {
|
||||
return $this->c->Message->message($this->c->extensions->error);
|
||||
}
|
||||
|
||||
return $this->c->Redirect->page('AdminExtensions', ['#' => $ext->id])->message("Redirect {$action}", FORK_MESS_SUCC);
|
||||
}
|
||||
}
|
|
@ -114,9 +114,12 @@ class Install extends Admin
|
|||
$folders = [
|
||||
$this->c->DIR_CONFIG,
|
||||
$this->c->DIR_CONFIG . '/db',
|
||||
$this->c->DIR_CONFIG . '/ext',
|
||||
$this->c->DIR_CACHE,
|
||||
$this->c->DIR_CACHE . '/polls',
|
||||
$this->c->DIR_PUBLIC . '/img/avatars',
|
||||
$this->c->DIR_PUBLIC . '/upload',
|
||||
$this->c->DIR_LOG,
|
||||
];
|
||||
|
||||
foreach ($folders as $folder) {
|
||||
|
@ -805,6 +808,18 @@ class Install extends Admin
|
|||
];
|
||||
$this->c->DB->createTable('::config', $schema);
|
||||
|
||||
// extensions
|
||||
$schema = [
|
||||
'FIELDS' => [
|
||||
'ext_name' => ['VARCHAR(190)', false, ''],
|
||||
'ext_status' => ['TINYINT', false, 0],
|
||||
'ext_data' => ['TEXT', false],
|
||||
],
|
||||
'PRIMARY KEY' => ['ext_name'],
|
||||
'ENGINE' => $this->DBEngine,
|
||||
];
|
||||
$this->c->DB->createTable('::extensions', $schema);
|
||||
|
||||
// forum_perms
|
||||
$schema = [
|
||||
'FIELDS' => [
|
||||
|
|
|
@ -25,7 +25,7 @@ class Update extends Admin
|
|||
{
|
||||
const PHP_MIN = '8.0.0';
|
||||
const REV_MIN_FOR_UPDATE = 53;
|
||||
const LATEST_REV_WITH_DB_CHANGES = 68;
|
||||
const LATEST_REV_WITH_DB_CHANGES = 70;
|
||||
const LOCK_NAME = 'lock_update';
|
||||
const LOCK_TTL = 1800;
|
||||
const CONFIG_FILE = 'main.php';
|
||||
|
@ -921,4 +921,62 @@ class Update extends Admin
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* rev.69 to rev.70
|
||||
*/
|
||||
protected function stageNumber69(array $args): ?int
|
||||
{
|
||||
$coreConfig = new CoreConfig($this->configFile);
|
||||
|
||||
$coreConfig->add(
|
||||
'shared=>%DIR_EXT%',
|
||||
'\'%DIR_ROOT%/ext\'',
|
||||
'%DIR_VIEWS%'
|
||||
);
|
||||
|
||||
$coreConfig->add(
|
||||
'multiple=>ExtensionModel',
|
||||
'\\ForkBB\\Models\\Extension\\Extension::class',
|
||||
'DBMapModel'
|
||||
);
|
||||
|
||||
$coreConfig->add(
|
||||
'multiple=>ExtensionManager',
|
||||
'\\ForkBB\\Models\\Extension\\Extensions::class',
|
||||
'ExtensionModel'
|
||||
);
|
||||
|
||||
$coreConfig->add(
|
||||
'shared=>extensions',
|
||||
'\'@ExtensionManager:init\'',
|
||||
'attachments'
|
||||
);
|
||||
|
||||
$coreConfig->add(
|
||||
'multiple=>AdminExtensions',
|
||||
'\\ForkBB\\Models\\Pages\\Admin\\Extensions::class',
|
||||
'AdminAntispam'
|
||||
);
|
||||
|
||||
$coreConfig->add(
|
||||
'shared=>View=>config=>preFile',
|
||||
'\'%DIR_CONFIG%/ext/pre.php\''
|
||||
);
|
||||
|
||||
$coreConfig->save();
|
||||
|
||||
// extensions
|
||||
$schema = [
|
||||
'FIELDS' => [
|
||||
'ext_name' => ['VARCHAR(190)', false, ''],
|
||||
'ext_status' => ['TINYINT', false, 0],
|
||||
'ext_data' => ['TEXT', false],
|
||||
],
|
||||
'PRIMARY KEY' => ['ext_name'],
|
||||
];
|
||||
$this->c->DB->createTable('::extensions', $schema);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,7 @@ define('FORK_GEN_FEM', 2);
|
|||
|
||||
define('FORK_JSON_ENCODE', \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR);
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$loader = require __DIR__ . '/../vendor/autoload.php';
|
||||
$errorHandler = new ErrorHandler();
|
||||
|
||||
if (\is_file(__DIR__ . '/config/main.php')) {
|
||||
|
@ -54,6 +53,8 @@ if (\is_file(__DIR__ . '/config/main.php')) {
|
|||
throw new RuntimeException('Application is not configured');
|
||||
}
|
||||
|
||||
$c->autoloader = $loader;
|
||||
|
||||
$errorHandler->setContainer($c);
|
||||
|
||||
require __DIR__ . '/functions.php';
|
||||
|
@ -69,7 +70,7 @@ if (
|
|||
$c->BASE_URL = \str_replace('https://', 'http://', $c->BASE_URL);
|
||||
}
|
||||
|
||||
$c->FORK_REVISION = 69;
|
||||
$c->FORK_REVISION = 70;
|
||||
$c->START = $forkStart;
|
||||
$c->PUBLIC_URL = $c->BASE_URL . $forkPublicPrefix;
|
||||
|
||||
|
|
0
app/config/ext/.gitkeep
Normal file
0
app/config/ext/.gitkeep
Normal file
|
@ -84,6 +84,7 @@ return [
|
|||
'%DIR_LANG%' => '%DIR_APP%/lang',
|
||||
'%DIR_LOG%' => '%DIR_APP%/log',
|
||||
'%DIR_VIEWS%' => '%DIR_APP%/templates',
|
||||
'%DIR_EXT%' => '%DIR_ROOT%/ext',
|
||||
|
||||
'DB' => [
|
||||
'class' => \ForkBB\Core\DB::class,
|
||||
|
@ -109,6 +110,7 @@ return [
|
|||
'cache' => '%DIR_CACHE%',
|
||||
'defaultDir' => '%DIR_VIEWS%/_default',
|
||||
'userDir' => '%DIR_VIEWS%/_user',
|
||||
'preFile' => '%DIR_CONFIG%/ext/pre.php',
|
||||
],
|
||||
],
|
||||
'Router' => [
|
||||
|
@ -185,6 +187,7 @@ return [
|
|||
],
|
||||
'providerUser' => \ForkBB\Models\ProviderUser\ProviderUser::class,
|
||||
'attachments' => \ForkBB\Models\Attachment\Attachments::class,
|
||||
'extensions' => '@ExtensionManager:init',
|
||||
|
||||
'Csrf' => [
|
||||
'class' => \ForkBB\Core\Csrf::class,
|
||||
|
@ -409,6 +412,7 @@ return [
|
|||
'AdminLogs' => \ForkBB\Models\Pages\Admin\Logs::class,
|
||||
'AdminUploads' => \ForkBB\Models\Pages\Admin\Uploads::class,
|
||||
'AdminAntispam' => \ForkBB\Models\Pages\Admin\Antispam::class,
|
||||
'AdminExtensions' => \ForkBB\Models\Pages\Admin\Extensions::class,
|
||||
|
||||
'AdminListModel' => \ForkBB\Models\AdminList\AdminList::class,
|
||||
'BanListModel' => \ForkBB\Models\BanList\BanList::class,
|
||||
|
@ -417,6 +421,8 @@ return [
|
|||
'CensorshipModel' => \ForkBB\Models\Censorship\Censorship::class,
|
||||
'ConfigModel' => \ForkBB\Models\Config\Config::class,
|
||||
'DBMapModel' => \ForkBB\Models\DBMap\DBMap::class,
|
||||
'ExtensionModel' => \ForkBB\Models\Extension\Extension::class,
|
||||
'ExtensionManager' => \ForkBB\Models\Extension\Extensions::class,
|
||||
'ForumModel' => \ForkBB\Models\Forum\Forum::class,
|
||||
'ForumManager' => \ForkBB\Models\Forum\Forums::class,
|
||||
'GroupModel' => \ForkBB\Models\Group\Group::class,
|
||||
|
|
|
@ -86,3 +86,6 @@ msgstr "Antispam"
|
|||
|
||||
msgid "Maintenance only"
|
||||
msgstr "Available only in maintenance mode."
|
||||
|
||||
msgid "Extensions"
|
||||
msgstr "Расширения"
|
||||
|
|
118
app/lang/en/admin_extensions.po
Normal file
118
app/lang/en/admin_extensions.po
Normal file
|
@ -0,0 +1,118 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Project-Id-Version: ForkBB\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: en\n"
|
||||
|
||||
msgid "Details"
|
||||
msgstr "Details:"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Name of package"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgid "Release date"
|
||||
msgstr "Release date"
|
||||
|
||||
msgid "Homepage"
|
||||
msgstr "Homepage"
|
||||
|
||||
msgid "Licence"
|
||||
msgstr "Licence"
|
||||
|
||||
msgid "Requirements"
|
||||
msgstr "Requirements:"
|
||||
|
||||
msgid "Authors"
|
||||
msgstr "Author(s):"
|
||||
|
||||
msgid "php"
|
||||
msgstr "PHP version"
|
||||
|
||||
msgid "forkbb"
|
||||
msgstr "ForkBB revision"
|
||||
|
||||
msgid "Not installed"
|
||||
msgstr "Not installed"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Disabled"
|
||||
|
||||
msgid "Disabled, package changed"
|
||||
msgstr "Disabled, package changed"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Enabled"
|
||||
|
||||
msgid "Enabled, package changed"
|
||||
msgstr "Enabled, but package changed!"
|
||||
|
||||
msgid "Crash"
|
||||
msgstr "Crash, package not found!"
|
||||
|
||||
msgid "Install_"
|
||||
msgstr "Install"
|
||||
|
||||
msgid "Uninstall_"
|
||||
msgstr "Uninstall"
|
||||
|
||||
msgid "Enable_"
|
||||
msgstr "Enable"
|
||||
|
||||
msgid "Disable_"
|
||||
msgstr "Disable"
|
||||
|
||||
msgid "Update_"
|
||||
msgstr "Update"
|
||||
|
||||
msgid "Downdate_"
|
||||
msgstr "Downdate"
|
||||
|
||||
msgid "Package version"
|
||||
msgstr "Package version"
|
||||
|
||||
msgid "Extension not found"
|
||||
msgstr "Extension not found."
|
||||
|
||||
msgid "Invalid action"
|
||||
msgstr "Invalid action."
|
||||
|
||||
msgid "Redirect install"
|
||||
msgstr "The extension is installed."
|
||||
|
||||
msgid "Redirect uninstall"
|
||||
msgstr "The extension has been uninstalled."
|
||||
|
||||
msgid "Redirect update"
|
||||
msgstr "The extension has been updated."
|
||||
|
||||
msgid "Redirect downdate"
|
||||
msgstr "The extension version has been downgraded."
|
||||
|
||||
msgid "Redirect enable"
|
||||
msgstr "The extension is enabled."
|
||||
|
||||
msgid "Redirect disable"
|
||||
msgstr "The extension is disabled."
|
||||
|
||||
msgid "Invalid template type"
|
||||
msgstr "Invalid template type."
|
||||
|
||||
msgid "PRE name not found"
|
||||
msgstr "PRE name not found."
|
||||
|
||||
msgid "Template file '%s' not found"
|
||||
msgstr "Template file '%s' not found."
|
||||
|
||||
msgid "An error occurred in updateCommon"
|
||||
msgstr "An error occurred in updateCommon."
|
|
@ -86,3 +86,6 @@ msgstr "Антиспам"
|
|||
|
||||
msgid "Maintenance only"
|
||||
msgstr "Доступно только в режиме обслуживания."
|
||||
|
||||
msgid "Extensions"
|
||||
msgstr "Расширения"
|
||||
|
|
118
app/lang/ru/admin_extensions.po
Normal file
118
app/lang/ru/admin_extensions.po
Normal file
|
@ -0,0 +1,118 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"Project-Id-Version: ForkBB\n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: ForkBB <mio.visman@yandex.ru>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: ru\n"
|
||||
|
||||
msgid "Details"
|
||||
msgstr "Подробности:"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Имя пакета"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Описание"
|
||||
|
||||
msgid "Release date"
|
||||
msgstr "Дата выпуска"
|
||||
|
||||
msgid "Homepage"
|
||||
msgstr "Домашняя страница"
|
||||
|
||||
msgid "Licence"
|
||||
msgstr "Лицензия"
|
||||
|
||||
msgid "Requirements"
|
||||
msgstr "Требования:"
|
||||
|
||||
msgid "Authors"
|
||||
msgstr "Автор(ы):"
|
||||
|
||||
msgid "php"
|
||||
msgstr "Версия PHP"
|
||||
|
||||
msgid "forkbb"
|
||||
msgstr "Ревизия ForkBB"
|
||||
|
||||
msgid "Not installed"
|
||||
msgstr "Не установлено"
|
||||
|
||||
msgid "Disabled"
|
||||
msgstr "Выключено"
|
||||
|
||||
msgid "Disabled, package changed"
|
||||
msgstr "Выключено, пакет изменен"
|
||||
|
||||
msgid "Enabled"
|
||||
msgstr "Включено"
|
||||
|
||||
msgid "Enabled, package changed"
|
||||
msgstr "Включено, но пакет изменен!"
|
||||
|
||||
msgid "Crash"
|
||||
msgstr "Сломано, пакет не найден!"
|
||||
|
||||
msgid "Install_"
|
||||
msgstr "Установить"
|
||||
|
||||
msgid "Uninstall_"
|
||||
msgstr "Удалить"
|
||||
|
||||
msgid "Enable_"
|
||||
msgstr "Включить"
|
||||
|
||||
msgid "Disable_"
|
||||
msgstr "Выключить"
|
||||
|
||||
msgid "Update_"
|
||||
msgstr "Обновить"
|
||||
|
||||
msgid "Downdate_"
|
||||
msgstr "Откатить"
|
||||
|
||||
msgid "Package version"
|
||||
msgstr "Версия пакета"
|
||||
|
||||
msgid "Extension not found"
|
||||
msgstr "Расширение не найдено."
|
||||
|
||||
msgid "Invalid action"
|
||||
msgstr "Недопустимое действие."
|
||||
|
||||
msgid "Redirect install"
|
||||
msgstr "Расширение установлено."
|
||||
|
||||
msgid "Redirect uninstall"
|
||||
msgstr "Расширение деинсталлировано."
|
||||
|
||||
msgid "Redirect update"
|
||||
msgstr "Расширение обновлено."
|
||||
|
||||
msgid "Redirect downdate"
|
||||
msgstr "Версия расширения понижена."
|
||||
|
||||
msgid "Redirect enable"
|
||||
msgstr "Расширение включено."
|
||||
|
||||
msgid "Redirect disable"
|
||||
msgstr "Расширение выключено."
|
||||
|
||||
msgid "Invalid template type"
|
||||
msgstr "Неверный тип шаблона."
|
||||
|
||||
msgid "PRE name not found"
|
||||
msgstr "PRE-имя не найдено."
|
||||
|
||||
msgid "Template file '%s' not found"
|
||||
msgstr "Файл шаблона '%s' не найден."
|
||||
|
||||
msgid "An error occurred in updateCommon"
|
||||
msgstr "Возникла ошибка в updateCommon."
|
148
app/templates/_default/admin/extensions.forkbb.php
Normal file
148
app/templates/_default/admin/extensions.forkbb.php
Normal file
|
@ -0,0 +1,148 @@
|
|||
@extends ('layouts/admin')
|
||||
@isset ($p->extensions)
|
||||
<section id="fork-extsinfo" class="f-admin">
|
||||
<h2>{!! __('Extensions') !!}</h2>
|
||||
<div>
|
||||
<fieldset>
|
||||
<ol>
|
||||
@foreach ($p->extensions as $ext)
|
||||
<li id="{{ $ext->id }}" class="f-extli f-ext-status{{ $ext->status }}">
|
||||
<details class="f-extdtl">
|
||||
<summary class="f-extsu">
|
||||
<span>{{ $ext->dispalyName }}</span>
|
||||
-
|
||||
<span>{{ $ext->version }}</span>
|
||||
<span>/
|
||||
@switch ($ext->status)
|
||||
@case ($ext::NOT_INSTALLED)
|
||||
{!! __('Not installed') !!}
|
||||
@break
|
||||
@case ($ext::DISABLED)
|
||||
{!! __('Disabled') !!}
|
||||
@break
|
||||
@case ($ext::DISABLED_DOWN)
|
||||
@case ($ext::DISABLED_UP)
|
||||
{!! __('Disabled, package changed') !!}
|
||||
@break
|
||||
@case ($ext::ENABLED)
|
||||
{!! __('Enabled') !!}
|
||||
@break
|
||||
@case ($ext::ENABLED_DOWN)
|
||||
@case ($ext::ENABLED_UP)
|
||||
{!! __('Enabled, package changed') !!}
|
||||
@break
|
||||
@case ($ext::CRASH)
|
||||
{!! __('Crash') !!}
|
||||
@break
|
||||
@endswitch
|
||||
/<span>
|
||||
</summary>
|
||||
<div class="f-extdata f-fdiv">
|
||||
<form class="f-form" method="post" action="{{ $p->actionLink }}">
|
||||
<fieldset class="f-extfs-details">
|
||||
<legend class="f-fleg">{!! __('Details') !!}</legend>
|
||||
<dl>
|
||||
<dt>{!! __('Name') !!}</dt>
|
||||
<dd>{{ $ext->name }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>{!! __('Package version') !!}</dt>
|
||||
<dd>{{ $ext->fileVersion }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>{!! __('Description') !!}</dt>
|
||||
<dd>{{ $ext->description }}</dd>
|
||||
</dl>
|
||||
@if ($ext->time)
|
||||
<dl>
|
||||
<dt>{!! __('Release date') !!}</dt>
|
||||
<dd>{{ $ext->time }}</dd>
|
||||
</dl>
|
||||
@endif
|
||||
@if ($ext->homepage)
|
||||
<dl>
|
||||
<dt>{!! __('Homepage') !!}</dt>
|
||||
<dd><a href="{{ url($ext->homepage) }}">{{ $ext->homepage }}</a></dd>
|
||||
</dl>
|
||||
@endif
|
||||
@if ($ext->license)
|
||||
<dl>
|
||||
<dt>{!! __('Licence') !!}</dt>
|
||||
<dd>{{ $ext->license }}</dd>
|
||||
</dl>
|
||||
@endif
|
||||
</fieldset>
|
||||
<fieldset class="f-extfs-requirements">
|
||||
<legend class="f-fleg">{!! __('Requirements') !!}</legend>
|
||||
@foreach ($ext->requirements as $k => $v)
|
||||
<dl>
|
||||
<dt>{!! __($k) !!}</dt>
|
||||
<dd>{{ $v }}</dd>
|
||||
</dl>
|
||||
@endforeach
|
||||
</fieldset>
|
||||
<fieldset class="f-extfs-authors">
|
||||
<legend class="f-fleg">{!! __('Authors') !!}</legend>
|
||||
@foreach ($ext->authors as $author)
|
||||
<dl>
|
||||
<dd class="f-extdd-author">
|
||||
<span>{{ $author['name'] }}</span>
|
||||
@if (! empty($author['email']) || ! empty($author['homepage']))
|
||||
(
|
||||
@if ($author['email'])
|
||||
<a href="{{ url('mailto:'.$author['email']) }}">{{ $author['email'] }}</a>
|
||||
@endif
|
||||
@if ($author['homepage'])
|
||||
@if ($author['email'])
|
||||
|
|
||||
@endif
|
||||
<a href="{{ url($author['homepage']) }}">{{ $author['homepage'] }}</a>
|
||||
@endif
|
||||
)
|
||||
@endif
|
||||
@if ($author['role'])
|
||||
[ {{ $author['role'] }} ]
|
||||
@endif
|
||||
</dd>
|
||||
</dl>
|
||||
@endforeach
|
||||
</fieldset>
|
||||
<fieldset calss="f-extfs-confirm">
|
||||
<dl>
|
||||
<dd>
|
||||
<label class="f-flblch"><input name="confirm" class="f-ychk" type="checkbox" value="1">{!! __('Confirm action') !!}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
<input type="hidden" name="name" value="{{ $ext->name }}">
|
||||
<input type="hidden" name="token" value="{{ $p->formsToken }}">
|
||||
<p class="f-btns">
|
||||
@if ($ext->canInstall)
|
||||
<button class="f-btn f-fbtn" name="install" value="install" title="{{ __('Install_') }}"><span>{!! __('Install_') !!}</span></button>
|
||||
@endif
|
||||
@if ($ext->canUninstall)
|
||||
<button class="f-btn f-fbtn" name="uninstall" value="uninstall" title="{{ __('Uninstall_') }}"><span>{!! __('Uninstall_') !!}</span></button>
|
||||
@endif
|
||||
@if ($ext->canUpdate)
|
||||
<button class="f-btn f-fbtn" name="update" value="update" title="{{ __('Update_') }}"><span>{!! __('Update_') !!}</span></button>
|
||||
@endif
|
||||
@if ($ext->canDowndate)
|
||||
<button class="f-btn f-fbtn" name="downdate" value="downdate" title="{{ __('Downdate_') }}"><span>{!! __('Downdate_') !!}</span></button>
|
||||
@endif
|
||||
@if ($ext->canEnable)
|
||||
<button class="f-btn f-fbtn" name="enable" value="enable" title="{{ __('Enable_') }}"><span>{!! __('Enable_') !!}</span></button>
|
||||
@endif
|
||||
@if ($ext->canDisable)
|
||||
<button class="f-btn f-fbtn" name="disable" value="disable" title="{{ __('Disable_') }}"><span>{!! __('Disable_') !!}</span></button>
|
||||
@endif
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</details>
|
||||
</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
@endisset
|
|
@ -1,7 +1,11 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('Info') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE mainBefore -->
|
||||
<div id="fork-ban" class="f-main">
|
||||
@if ($p->bannedIp)
|
||||
<p>{!! __('Your IP is blocked') !!}</p>
|
||||
|
@ -17,3 +21,5 @@
|
|||
@endif
|
||||
<p>{!! __(['Ban message contact %s', $p->adminEmail]) !!}</p>
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-changepass" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<h2>{!! __('Change pass') !!}</h2>
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->legend) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-sendemail" class="f-post-form">
|
||||
<!-- PRE mainStart -->
|
||||
<h2>{!! __('Send email title') !!}</h2>
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
@endif
|
||||
@endsection
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
@if (\is_array($p->model->name))
|
||||
<h1 id="fork-h1">{!! __($p->model->name) !!}</h1>
|
||||
|
@ -31,10 +33,14 @@
|
|||
<p class="f-fdesc">{!! $p->model->forum_desc !!}</p>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
@if ($forums = $p->model->subforums)
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
<!-- PRE subforumsBefore -->
|
||||
<section id="fork-subforums">
|
||||
<ol class="f-ftlist">
|
||||
<li id="id-subforums{{ $p->model->id }}" class="f-category">
|
||||
|
@ -50,7 +56,9 @@
|
|||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<!-- PRE subforumsAfter -->
|
||||
@endif
|
||||
<!-- PRE linksBBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
@if ($p->model->canCreateTopic || $p->model->pagination)
|
||||
|
@ -66,7 +74,9 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE linksBAfter -->
|
||||
@if ($p->topics)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-forum" class="f-main">
|
||||
<h2>{!! __('Topic list') !!}</h2>
|
||||
<div class="f-ftlist">
|
||||
|
@ -172,6 +182,8 @@
|
|||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE linksABefore -->
|
||||
<div class="f-nav-links">
|
||||
@if ($p->model->canCreateTopic || $p->model->pagination || $p->model->canMarkRead || $p->model->canSubscription)
|
||||
<div class="f-nlinks-a">
|
||||
|
@ -201,12 +213,16 @@
|
|||
@endif
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAAfter -->
|
||||
@endif
|
||||
@if ($p->enableMod && $form = $p->formMod)
|
||||
<!-- PRE modBefore -->
|
||||
<aside id="fork-mod" class="f-moderate">
|
||||
<h2>{!! __('Moderate') !!}</h2>
|
||||
<div class="f-fdivm">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
</aside>
|
||||
<!-- PRE modAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($p->categoryes)
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('Forum list') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE mainBefore -->
|
||||
<div class="f-main">
|
||||
<ol class="f-ftlist">
|
||||
@foreach ($p->categoryes as $id => $forums)
|
||||
|
@ -20,7 +24,9 @@
|
|||
@endforeach
|
||||
</ol>
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
@if ($p->linkMarkRead)
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
<div class="f-nlinks">
|
||||
<div class="f-actions-links">
|
||||
|
@ -30,6 +36,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@endif
|
||||
@endif
|
||||
<!-- PRE statsBefore -->
|
||||
@include ('layouts/stats')
|
||||
<!-- PRE statsafter -->
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->adminHeader) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links f-nav-admin{{ $p->mainSuffix or '' }}-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<div class="f-main f-main-admin{{ $p->mainSuffix or '' }}">
|
||||
<!-- PRE menuBefore -->
|
||||
<div id="fork-a-menu">
|
||||
@if ($p->aNavigation)
|
||||
<nav id="fork-a-nav" class="f-menu">
|
||||
|
@ -20,7 +27,12 @@
|
|||
</nav>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE menuAfter -->
|
||||
<!-- PRE contentBefore -->
|
||||
<div id="forka">
|
||||
@yield ('content')
|
||||
</div>
|
||||
<!-- PRE contentAfter -->
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
@section ('crumbs')
|
||||
<!-- PRE start -->
|
||||
<nav class="f-nav-crumbs">
|
||||
<ol class="f-crumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
|
||||
@foreach ($p->crumbs as $cur)
|
||||
<!-- PRE foreachStart -->
|
||||
@if (\is_object($cur[0]))
|
||||
<li class="f-crumb @if ($cur[0]->is_subscribed) f-subscribed @endif" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><!-- inline -->
|
||||
<a class="f-crumb-a @if ($cur[2]) active" aria-current="page @endif" href="{{ $cur[0]->link }}" itemprop="item">
|
||||
|
@ -27,7 +29,9 @@
|
|||
<meta itemprop="position" content="{!! @iteration !!}">
|
||||
</li><!-- endinline -->
|
||||
@endif
|
||||
<!-- PRE foreachEnd -->
|
||||
@endforeach
|
||||
</ol>
|
||||
</nav>
|
||||
<!-- PRE end -->
|
||||
@endsection
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<!-- PRE start -->
|
||||
<aside id="fork-debug">
|
||||
<!-- PRE inStart -->
|
||||
<p class="f-sim-header">{!! __('Debug table') !!}</p>
|
||||
<p id="id-fdebugtime">[ {!! __(['Generated in %1$s, %2$s queries', num(\microtime(true) - $p->start, 3), $p->numQueries]) !!} - {!! __(['Memory %1$s, Peak %2$s', size(\memory_get_usage()), size(\memory_get_peak_usage())]) !!} ]</p>
|
||||
@if ($p->queries)
|
||||
|
@ -23,4 +25,6 @@
|
|||
</tbody>
|
||||
</table>
|
||||
@endif
|
||||
<!-- PRE inEnd -->
|
||||
</aside>
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<!-- PRE start -->
|
||||
@if ($form['action'])
|
||||
<form @if ($form['id']) id="{{ $form['id'] }}" @endif class="f-form" method="post" action="{{ $form['action'] }}" @if ($form['enctype']) enctype="{{ $form['enctype'] }}" @endif>
|
||||
<!-- PRE formStart -->
|
||||
@endif
|
||||
@foreach ($form['sets'] as $setKey => $setVal)
|
||||
@if ($setVal['inform'])
|
||||
|
@ -31,6 +33,7 @@
|
|||
</dt>
|
||||
<dd>
|
||||
@switch ($cur['type'])
|
||||
<!-- PRE switchStart -->
|
||||
@case ('text')
|
||||
@case ('email')
|
||||
@case ('number')
|
||||
|
@ -97,6 +100,7 @@
|
|||
</dd>
|
||||
</dl>
|
||||
@break
|
||||
<!-- PRE switchEnd -->
|
||||
@endswitch
|
||||
@endforeach
|
||||
</fieldset>
|
||||
|
@ -116,12 +120,16 @@
|
|||
@endif
|
||||
<p class="f-btns">
|
||||
@foreach ($form['btns'] as $key => $cur)
|
||||
<!-- PRE btnsForeachStart -->
|
||||
@if ('submit' === $cur['type'])
|
||||
<button class="f-btn f-fbtn @if($cur['class']) {{ \implode(' ', $cur['class']) }} @endif" name="{{ $key }}" value="{{ $cur['value'] }}" @isset ($cur['accesskey']) accesskey="{{ $cur['accesskey'] }}" @endisset title="{{ $cur['value'] }}" @if ($cur['disabled']) disabled @endif><span>{{ $cur['value'] }}</span></button>
|
||||
@elseif ('btn'=== $cur['type'])
|
||||
<a class="f-btn f-fbtn @if($cur['class']) {{ \implode(' ', $cur['class']) }} @endif" data-name="{{ $key }}" href="{{ $cur['href'] }}" @isset ($cur['accesskey']) accesskey="{{ $cur['accesskey'] }}" @endisset title="{{ $cur['value'] }}"><span>{{ $cur['value'] }}</span></a>
|
||||
@endif
|
||||
<!-- PRE btnsForeachEnd -->
|
||||
@endforeach
|
||||
</p>
|
||||
<!-- PRE formEnd -->
|
||||
</form>
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<!-- PRE start -->
|
||||
<aside class="f-iswev-wrap">
|
||||
<!-- PRE inStart -->
|
||||
@if ($iswev[FORK_MESS_INFO])
|
||||
<div class="f-iswev f-info">
|
||||
<p class="f-sim-header">Info message:</p>
|
||||
|
@ -49,4 +51,6 @@
|
|||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<!-- PRE inEnd -->
|
||||
</aside>
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ __('lang_identifier') }}" dir="{{ __('lang_direction') }}">
|
||||
<head>
|
||||
<!-- PRE headStart -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{! $p->pageTitle !}}</title>
|
||||
|
@ -36,28 +37,39 @@
|
|||
<{{ $pageHeader['type'] }} @foreach ($pageHeader['values'] as $key => $val) {{ $key }}="{{ $val }}" @endforeach>
|
||||
@endif
|
||||
@endforeach
|
||||
<!-- PRE headEnd -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- PRE bodyStart -->
|
||||
<div id="fork" class="@if ($p->fNavigation)f-with-nav @endif @if($p->fPMFlash) f-pm-flash @endif">
|
||||
<!-- PRE headerBefore -->
|
||||
<header id="fork-header">
|
||||
<p id="id-fhth1"><a id="id-fhtha" rel="home" href="{{ $p->fRootLink }}">{{ $p->fTitle }}</a></p>
|
||||
@if ('' != $p->fDescription)
|
||||
<p id="id-fhtdesc">{!! $p->fDescription !!}</p>
|
||||
@endif
|
||||
</header>
|
||||
<!-- PRE headerAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<main id="fork-main">
|
||||
@if ($p->fAnnounce)
|
||||
<aside id="fork-announce">
|
||||
<!-- PRE announceStart -->
|
||||
<p class="f-sim-header">{!! __('Announcement') !!}</p>
|
||||
<p id="id-facontent">{!! $p->fAnnounce !!}</p>
|
||||
<!-- PRE announceEnd -->
|
||||
</aside>
|
||||
@endif
|
||||
@if ($iswev = $p->fIswev)
|
||||
@include ('layouts/iswev')
|
||||
@endif
|
||||
<!-- PRE contentBefore -->
|
||||
@yield ('content')
|
||||
<!-- PRE contentAfter -->
|
||||
</main>
|
||||
<!-- PRE mainAfter -->
|
||||
@if ($p->fNavigation)
|
||||
<!-- PRE navBefore -->
|
||||
<nav id="fork-nav" class="f-menu @if ($p->fNavigation['search']) f-main-nav-search @endif">
|
||||
<div id="fork-navdir">
|
||||
<input id="id-mn-checkbox" class="f-menu-checkbox" type="checkbox">
|
||||
|
@ -114,16 +126,27 @@
|
|||
@endif
|
||||
</div>
|
||||
</nav>
|
||||
<!-- PRE navAfter -->
|
||||
@endif
|
||||
<!-- PRE footerBefore -->
|
||||
<footer id="fork-footer">
|
||||
<p class="f-sim-header">{!! __('Board footer') !!}</p>
|
||||
<div id="fork-footer-in">
|
||||
<div></div>
|
||||
<div><p id="id-fpoweredby">{!! __('Powered by') !!}</p></div>
|
||||
<div>
|
||||
<!-- PRE footerFirstStart -->
|
||||
<!-- PRE footerFirstEnd -->
|
||||
</div>
|
||||
<div>
|
||||
<!-- PRE footerSecondStart -->
|
||||
<p id="id-fpoweredby">{!! __('Powered by') !!}</p>
|
||||
<!-- PRE footerSecondEnd -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- debuginfo -->
|
||||
</footer>
|
||||
<!-- PRE footerAfter -->
|
||||
</div>
|
||||
<!-- PRE scriptsBefore -->
|
||||
@foreach ($p->pageHeaders as $pageHeader)
|
||||
@if ('script' === $pageHeader['type'])
|
||||
@empty ($pageHeader['values']['inline'])
|
||||
|
@ -133,5 +156,7 @@
|
|||
@endempty
|
||||
@endif
|
||||
@endforeach
|
||||
<!-- PRE scriptsAfter -->
|
||||
<!-- PRE bodyEnd -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->pmHeader) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links f-nav-pm-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<div class="f-main f-main-pm">
|
||||
<!-- PRE menuBefore -->
|
||||
<div id="fork-pm-menu">
|
||||
@if ($p->pmNavigation)
|
||||
<nav id="fork-pm-nav" class="f-menu">
|
||||
|
@ -38,7 +45,12 @@
|
|||
</nav>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE menuAfter -->
|
||||
<!-- PRE contentBefore -->
|
||||
<div id="forkpm">
|
||||
@yield ('content')
|
||||
</div>
|
||||
<!-- PRE contentAfter -->
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<!-- PRE start -->
|
||||
<div class="f-post-poll">
|
||||
<!-- PRE inStart -->
|
||||
@if ($poll->canVote)
|
||||
<form class="f-form" method="post" action="{{ $poll->link }}">
|
||||
<!-- PRE formStart -->
|
||||
<input type="hidden" name="token" value="{{ $poll->token }}">
|
||||
@endif
|
||||
@foreach ($poll->question as $q => $question)
|
||||
|
@ -41,8 +44,11 @@
|
|||
<p class="f-poll-btns">
|
||||
<button class="f-btn" name="vote" value="{{ __('Vote') }}" title="{{ __('Vote') }}"><span>{!! __('Vote') !!}</span></button>
|
||||
</p>
|
||||
<!-- PRE formEnd -->
|
||||
</form>
|
||||
@elseif (null !== $poll->status)
|
||||
<p class="f-poll-status"><span>{!! __($poll->status) !!}</span></p>
|
||||
@endif
|
||||
<!-- PRE inEnd -->
|
||||
</div>
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ __('lang_identifier') }}" dir="{{ __('lang_direction') }}">
|
||||
<head>
|
||||
<!-- PRE headStart -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="refresh" content="{{ $p->timeout }}; URL={{ $p->link }}">
|
||||
|
@ -16,9 +17,12 @@
|
|||
<{{ $pageHeader['type'] }} @foreach ($pageHeader['values'] as $key => $val) {{ $key }}="{{ $val }}" @endforeach>
|
||||
@endif
|
||||
@endforeach
|
||||
<!-- PRE headEnd -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- PRE bodyStart -->
|
||||
<div id="fork">
|
||||
<!-- PRE mainBefore -->
|
||||
<main id="fork-main">
|
||||
<aside id="fork-rdrct" class="f-main">
|
||||
<h2 id="id-rdrct-h2">{!! __('Redirecting') !!}</h2>
|
||||
|
@ -27,9 +31,13 @@
|
|||
@endif
|
||||
</aside>
|
||||
</main>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE footerBefore -->
|
||||
<footer id="fork-footer">
|
||||
<!-- debuginfo -->
|
||||
</footer>
|
||||
<!-- PRE footerAfter -->
|
||||
</div>
|
||||
<!-- PRE bodyEnd -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<!-- PRE start -->
|
||||
<aside id="fork-stats">
|
||||
<!-- PRE inStart -->
|
||||
<p class="f-sim-header">{!! __('Stats info') !!}</p>
|
||||
@if ($p->stats)
|
||||
<dl id="fork-stboard">
|
||||
|
@ -36,4 +38,6 @@
|
|||
@endforeach
|
||||
</dl><!-- endinline -->
|
||||
@endif
|
||||
<!-- PRE inEnd -->
|
||||
</aside>
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,25 +1,39 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-login" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<h2>{!! __('Login') !!}</h2>
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
@if ($form = $p->formOAuth)
|
||||
<!-- PRE oauthBefore -->
|
||||
<div id="fork-oauth" class="f-main">
|
||||
<!-- PRE oauthStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE oauthEnd -->
|
||||
</div>
|
||||
<!-- PRE oauthAfter -->
|
||||
@endif
|
||||
@if ($p->regLink)
|
||||
<!-- PRE lgrgBefore -->
|
||||
<div id="fork-lgrglnk" class="f-main">
|
||||
<!-- PRE lgrgStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<div class="f-btns">
|
||||
<a class="f-btn f-fbtn" href="{{ $p->regLink }}">{!! __('Not registered') !!}</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRE lgrgEnd -->
|
||||
</div>
|
||||
<!-- PRE lgrgAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<div class="f-iswev-wrap">
|
||||
<section class="f-iswev f-info">
|
||||
<h2>Info message</h2>
|
||||
|
@ -7,3 +8,4 @@
|
|||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($p->back)
|
||||
<div id="fork-bcklnk">
|
||||
<p id="id-bcklnk-p"><a class="f-go-back" href="{{ $p->fRootLink }}">{!! __('Go back') !!}</a></p>
|
||||
</div>
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->formTitle) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<div id="fork-modform" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-resetpass" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<h2>{!! __('Passphrase reset') !!}</h2>
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->formTitle) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($p->previewHtml)
|
||||
<!-- PRE previewBefore -->
|
||||
<section class="f-preview">
|
||||
<h2>{!! __('Post preview') !!}</h2>
|
||||
<div class="f-post-body">
|
||||
|
@ -18,16 +24,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PRE previewAfter -->
|
||||
@endif
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section class="f-post-form">
|
||||
<!-- PRE mainStart -->
|
||||
<h2>{!! __($p->formTitle) !!}</h2>
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
@if ($p->posts)
|
||||
<!-- PRE postsBefore -->
|
||||
<section id="fork-view-posts">
|
||||
<h2>{!! __($p->postsTitle) !!}</h2>
|
||||
@foreach ($p->posts as $post)
|
||||
|
@ -58,4 +70,6 @@
|
|||
@endif
|
||||
@endforeach
|
||||
</section>
|
||||
<!-- PRE postsAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
@section ('avatar')<img class="f-avatar-img" src="{{ $p->curUser->avatar }}" alt="{{ $p->curUser->username }}"> @endsection
|
||||
@section ('signature') @if ($p->signatureSection){!! $p->curUser->htmlSign !!} @endif @endsection
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __(['%s\'s profile', $p->curUser->username]) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
@if ($p->actionBtns)
|
||||
|
@ -19,19 +23,29 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-profile{{ $p->profileIdSuffix or '' }}" class="f-main f-main-profile">
|
||||
<!-- PRE mainStart -->
|
||||
<h2>@if ($p->profileHeader === $p->curUser->username){{ $p->profileHeader }} @else{!! __($p->profileHeader) !!} @endif</h2>
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
@if ($form = $p->formOAuth)
|
||||
<!-- PRE oauthBefore -->
|
||||
<div id="fork-oauth" class="f-main">
|
||||
<!-- PRE oauthStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<h2>{!! __('Add account') !!}</h2>
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE oauthEnd -->
|
||||
</div>
|
||||
<!-- PRE oauthAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-reg" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
<h2>{!! __('Register') !!}</h2>
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
@if ($form = $p->formOAuth)
|
||||
<!-- PRE oauthBefore -->
|
||||
<div id="fork-oauth" class="f-main">
|
||||
<!-- PRE oauthStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE oauthEnd -->
|
||||
</div>
|
||||
<!-- PRE oauthAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('Report post') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<div id="fork-report" class="f-post-form">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('Forum rules') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<div id="fork-rules" class="f-main">
|
||||
<div id="id-rules">{!! $p->rules !!}</div>
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE regBefore -->
|
||||
<div id="fork-rconf" class="f-main">
|
||||
<!-- PRE regStart -->
|
||||
<div class="f-fdiv f-lrdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE regEnd -->
|
||||
</div>
|
||||
<!-- PRE regAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
@include ('layouts/crumbs')
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('Search') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAfter -->
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE mainBefore -->
|
||||
<div id="fork-search" class="f-main">
|
||||
<!-- PRE mainStart -->
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
<!-- PRE mainEnd -->
|
||||
</div>
|
||||
<!-- PRE mainAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
@endif
|
||||
@endsection
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{{ $p->model->name }}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
@if ($p->model->canReply || $p->model->closed || $p->model->pagination)
|
||||
|
@ -45,6 +49,8 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE linksBAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-topic" class="f-main">
|
||||
<h2>{!! __('Post list') !!}</h2>
|
||||
@foreach ($p->posts as $id => $post)
|
||||
|
@ -166,6 +172,8 @@
|
|||
@endif
|
||||
@endforeach
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE linksABefore -->
|
||||
<div class="f-nav-links">
|
||||
@if ($p->model->canReply || $p->model->pagination || $p->model->canSubscription)
|
||||
<div class="f-nlinks-a">
|
||||
|
@ -191,22 +199,30 @@
|
|||
@endif
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAAfter -->
|
||||
@if ($p->enableMod && $form = $p->formMod)
|
||||
<!-- PRE modBefore -->
|
||||
<aside id="fork-mod" class="f-moderate">
|
||||
<h2>{!! __('Moderate') !!}</h2>
|
||||
<div class="f-fdivm">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
</aside>
|
||||
<!-- PRE modAfter -->
|
||||
@endif
|
||||
@if ($p->online)
|
||||
<!-- PRE statsBefore -->
|
||||
@include ('layouts/stats')
|
||||
<!-- PRE statsAfter -->
|
||||
@endif
|
||||
@if ($form = $p->form)
|
||||
<!-- PRE quickBefore -->
|
||||
<section class="f-post-form">
|
||||
<h2>{!! __('Quick post') !!}</h2>
|
||||
<div class="f-fdiv">
|
||||
@include ('layouts/form')
|
||||
</div>
|
||||
</section>
|
||||
<!-- PRE quickAfter -->
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
@endif
|
||||
@endsection
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __($p->model->name) !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
@if ($p->model->pagination)
|
||||
|
@ -32,6 +36,8 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE linksBAfter -->
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-topic-ins" class="f-main">
|
||||
<h2>{!! __('Post list') !!}</h2>
|
||||
@foreach ($p->posts as $id => $post)
|
||||
|
@ -95,6 +101,8 @@
|
|||
@endif
|
||||
@endforeach
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
<!-- PRE linksABefore -->
|
||||
<div class="f-nav-links">
|
||||
@if ($p->model->pagination)
|
||||
<div class="f-nlinks-a">
|
||||
|
@ -103,3 +111,5 @@
|
|||
@endif
|
||||
@yield ('crumbs')
|
||||
</div>
|
||||
<!-- PRE linksAAfter -->
|
||||
<!-- PRE end -->
|
||||
|
|
|
@ -21,9 +21,13 @@
|
|||
@endif
|
||||
@endsection
|
||||
@extends ('layouts/main')
|
||||
<!-- PRE start -->
|
||||
<!-- PRE h1Before -->
|
||||
<div class="f-mheader">
|
||||
<h1 id="fork-h1">{!! __('User list') !!}</h1>
|
||||
</div>
|
||||
<!-- PRE h1After -->
|
||||
<!-- PRE linksBBefore -->
|
||||
<div class="f-nav-links">
|
||||
@yield ('crumbs')
|
||||
@if ($p->pagination)
|
||||
|
@ -32,8 +36,10 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<!-- PRE linksBAfter -->
|
||||
@if ($form = $p->form)
|
||||
<section id="fork-usrlstform" class="f-main">
|
||||
<!-- PRE searchBefore -->
|
||||
<section id="fork-usrlstform" class="f-main">
|
||||
<h2>{!! __($p->userRules->searchUsers ? 'User search head' : 'User sort head') !!}</h2>
|
||||
<details>
|
||||
<summary>{!! __($p->userRules->searchUsers ? 'User search head' : 'User sort head') !!}</summary>
|
||||
|
@ -42,8 +48,10 @@
|
|||
</div>
|
||||
</details>
|
||||
</section>
|
||||
<!-- PRE searchAfter -->
|
||||
@endif
|
||||
@if ($p->userList)
|
||||
<!-- PRE mainBefore -->
|
||||
<section id="fork-usrlst" class="f-main">
|
||||
<h2>{!! __('User_list') !!}</h2>
|
||||
<div class="f-ulist">
|
||||
|
@ -96,11 +104,15 @@
|
|||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
<!-- PRE mainAfter -->
|
||||
@if ($p->pagination)
|
||||
<!-- PRE linksABefore -->
|
||||
<div class="f-nav-links">
|
||||
<div class="f-nlinks">
|
||||
@yield ('pagination')
|
||||
</div>
|
||||
</div>
|
||||
<!-- PRE linksAAfter -->
|
||||
@endif
|
||||
@endif
|
||||
<!-- PRE end -->
|
||||
|
|
0
ext/.gitkeep
Normal file
0
ext/.gitkeep
Normal file
|
@ -1,5 +1,5 @@
|
|||
#forka {
|
||||
--c-log-in-c: hsl(220,5%,12%);
|
||||
--c-log-in-c: hsl(0,0%,0%);
|
||||
}
|
||||
|
||||
/******************/
|
||||
|
@ -110,6 +110,7 @@
|
|||
|
||||
#forka .f-fleg {
|
||||
margin-bottom: 0.3125rem;
|
||||
background: linear-gradient(var(--bg-like-nav), var(--bg-fprimary), var(--bg-like-nav));
|
||||
}
|
||||
|
||||
#forka .f-flblch {
|
||||
|
@ -410,7 +411,7 @@
|
|||
/* Админка/Пользователи */
|
||||
/************************/
|
||||
#fork-ausersrch-rs .f-btns {
|
||||
text-align: end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
#fork-ausersrch-rs .f-btns .f-fbtn,
|
||||
|
@ -1056,9 +1057,9 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#fork #fork-logview summary.f-lgsu {
|
||||
/*#fork #fork-logview summary.f-lgsu {
|
||||
margin: 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
#fork #fork-logview summary.f-lgsu::after {
|
||||
content: none;
|
||||
|
@ -1269,3 +1270,69 @@
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
/* Админка/РАсширения */
|
||||
/****************************************/
|
||||
#forka #fork-extsinfo summary.f-extsu::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-extli:first-child {
|
||||
border-top: 0.0625rem dotted var(--br-fprimary);
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-extli {
|
||||
border-bottom: 0.0625rem dotted var(--br-fprimary);
|
||||
padding: 0.625rem;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-extsu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-extdata {
|
||||
color: var(--c-fprimary);
|
||||
border: 0.0625rem solid var(--br-fprimary);
|
||||
padding: 0.3125rem;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-extdd-author {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-ext-status0 {
|
||||
color: var(--c-log-in-c);
|
||||
background-color: #90CAF9;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-ext-status4,
|
||||
#fork-extsinfo .f-ext-status5,
|
||||
#fork-extsinfo .f-ext-status6 {
|
||||
color: var(--c-log-in-c);
|
||||
background-color: #1976D2;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-ext-status8 {
|
||||
color: var(--c-log-in-c);
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-ext-status9,
|
||||
#fork-extsinfo .f-ext-status10 {
|
||||
color: var(--c-log-in-c);
|
||||
background-color: #FF5722;
|
||||
}
|
||||
|
||||
#fork-extsinfo .f-ext-status12 {
|
||||
color: var(--c-log-in-c);
|
||||
background-color: #D32F2F;
|
||||
}
|
||||
|
||||
#forka #fork-extsinfo .f-fbtn {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#forka .f-fbtn[data-name="uninstall"]:not(.origin) {
|
||||
color: red;
|
||||
}
|
||||
|
|
|
@ -232,6 +232,9 @@ body,
|
|||
|
||||
#fork summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fork details[open] > summary {
|
||||
margin-bottom: 0.625rem;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue