2020-06-11 23:21:49 +03:00
|
|
|
|
<?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
|
|
|
|
|
{
|
|
|
|
|
const THEMPACK_ENGINE_VERSION = 1;
|
|
|
|
|
const DEFAULT_THEME_ID = "ovk"; # блин было бы смешно если было бы Fore, потому что Лунка, а Luna это название дефолт темы винхп
|
|
|
|
|
|
|
|
|
|
private $loadedThemepacks = [];
|
|
|
|
|
|
|
|
|
|
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, skipping...", 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getThemeList(): \Traversable
|
|
|
|
|
{
|
|
|
|
|
foreach($this->loadedThemepacks as $id => $theme)
|
2020-06-14 14:08:50 +03:00
|
|
|
|
if($theme->isEnabled())
|
|
|
|
|
yield $id => ($theme->getName(Session::i()->get("lang", "ru")));
|
2020-06-11 23:21:49 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ArrayAccess */
|
|
|
|
|
|
|
|
|
|
function offsetExists($offset): bool
|
|
|
|
|
{
|
|
|
|
|
return $offset === Themepacks::DEFAULT_THEME_ID ? false : isset($this->loadedThemepacks[$offset]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function offsetGet($offset)
|
|
|
|
|
{
|
|
|
|
|
return $this->loadedThemepacks[$offset];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function offsetSet($offset, $value): void
|
|
|
|
|
{
|
|
|
|
|
throw new ISE("Theme substitution in runtime is prohbited");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function offsetUnset($offset): void
|
|
|
|
|
{
|
|
|
|
|
$this->uninstall($offset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* /ArrayAccess */
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function uninstall(string $id): bool
|
|
|
|
|
{
|
|
|
|
|
if(!isset($loadedThemepacks[$id]))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
rmdir(OPENVK_ROOT . "/themepacks/$id");
|
|
|
|
|
unset($loadedThemepacks[$id]);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use TSimpleSingleton;
|
|
|
|
|
}
|