mirror of
https://github.com/openvk/openvk
synced 2025-02-02 21:15:42 +03:00
Alexander Minkin
6ec54a379d
* feat(lint): add php-cs-fixer for linting Removing previous CODE_STYLE as it was not enforced anyway and using PER-CS 2.0. This is not the reformatting commit. * style: format code according to PER-CS 2.0 with php-cs-fixer * ci(actions): add lint action Resolves #1132.
120 lines
3.3 KiB
PHP
120 lines
3.3 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace openvk\Web\Themes;
|
||
|
||
use Nette\InvalidStateException as ISE;
|
||
use Chandler\Session\Session;
|
||
use Chandler\Patterns\TSimpleSingleton;
|
||
|
||
class Themepacks implements \ArrayAccess
|
||
{
|
||
use TSimpleSingleton;
|
||
public const THEMPACK_ENGINE_VERSION = 1;
|
||
public const DEFAULT_THEME_ID = "ovk"; # блин было бы смешно если было бы Fore, потому что Лунка, а Luna это название дефолт темы винхп
|
||
|
||
private $loadedThemepacks = [];
|
||
|
||
public function __construct()
|
||
{
|
||
foreach (glob(OPENVK_ROOT . "/themepacks/*", GLOB_ONLYDIR) as $themeDir) {
|
||
try {
|
||
$theme = Themepack::themepackFromDir($themeDir);
|
||
$tid = $theme->getId();
|
||
if (isset($this->loadedThemepacks[$tid])) {
|
||
trigger_error("Duplicate theme $tid found at $themeDir, skipping...", E_USER_WARNING);
|
||
} else {
|
||
$this->loadedThemepacks[$tid] = $theme;
|
||
}
|
||
} catch (\Exception $e) {
|
||
trigger_error("Could not load theme at $themeDir. Exception: $e", E_USER_WARNING);
|
||
}
|
||
}
|
||
}
|
||
|
||
private function installUnpacked(string $path): bool
|
||
{
|
||
try {
|
||
$theme = Themepack::themepackFromDir($path);
|
||
$tid = $theme->getId();
|
||
if (isset($this->loadedThemepacks[$tid])) {
|
||
return false;
|
||
}
|
||
|
||
rename($path, OPENVK_ROOT . "/themepacks/$tid");
|
||
$this->loadedThemepacks[$tid] = $theme;
|
||
return true;
|
||
} catch (\Exception $e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public function getThemeList(): \Traversable
|
||
{
|
||
foreach ($this->loadedThemepacks as $id => $theme) {
|
||
if ($theme->isEnabled()) {
|
||
yield $id => ($theme->getName(Session::i()->get("lang", "ru")));
|
||
}
|
||
}
|
||
}
|
||
|
||
public function getAllThemes(): array
|
||
{
|
||
return $this->loadedThemepacks;
|
||
}
|
||
|
||
/* ArrayAccess */
|
||
|
||
public function offsetExists($offset): bool
|
||
{
|
||
return $offset === Themepacks::DEFAULT_THEME_ID ? false : isset($this->loadedThemepacks[$offset]);
|
||
}
|
||
|
||
public function offsetGet($offset): mixed
|
||
{
|
||
return $this->loadedThemepacks[$offset];
|
||
}
|
||
|
||
public function offsetSet($offset, $value): void
|
||
{
|
||
throw new ISE("Theme substitution in runtime is prohbited");
|
||
}
|
||
|
||
public function offsetUnset($offset): void
|
||
{
|
||
$this->uninstall($offset);
|
||
}
|
||
|
||
/* /ArrayAccess */
|
||
|
||
public function install(string $archivePath): bool
|
||
{
|
||
if (!file_exists($archivePath)) {
|
||
return false;
|
||
}
|
||
|
||
$tmpDir = mkdir(tempnam(OPENVK_ROOT . "/tmp/themepack_artifacts/", "themex_"));
|
||
try {
|
||
$archive = new \CabArchive($archivePath);
|
||
$archive->extract($tmpDir);
|
||
|
||
return $this->installUnpacked($tmpDir);
|
||
} catch (\Exception $e) {
|
||
return false;
|
||
} finally {
|
||
rmdir($tmpDir);
|
||
}
|
||
}
|
||
|
||
public function uninstall(string $id): bool
|
||
{
|
||
if (!isset($loadedThemepacks[$id])) {
|
||
return false;
|
||
}
|
||
|
||
rmdir(OPENVK_ROOT . "/themepacks/$id");
|
||
unset($loadedThemepacks[$id]);
|
||
return true;
|
||
}
|
||
}
|