mirror of
https://github.com/openvk/openvk
synced 2024-12-22 16:42:32 +03:00
Add themepack support
This commit is contained in:
parent
3eb5b6b4fc
commit
d509096d46
14 changed files with 330 additions and 171 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -6,5 +6,8 @@ Web/static/js/node_modules
|
||||||
|
|
||||||
tmp/*
|
tmp/*
|
||||||
!tmp/.gitkeep
|
!tmp/.gitkeep
|
||||||
|
!tmp/themepack_artifacts/.gitkeep
|
||||||
|
themepacks/*
|
||||||
|
!themepacks/.gitkeep
|
||||||
storage/*
|
storage/*
|
||||||
!storage/.gitkeep
|
!storage/.gitkeep
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
namespace openvk\Web\Models\Entities;
|
namespace openvk\Web\Models\Entities;
|
||||||
|
use openvk\Web\Themes\{Themepack, Themepacks};
|
||||||
use openvk\Web\Util\DateTime;
|
use openvk\Web\Util\DateTime;
|
||||||
use openvk\Web\Models\RowModel;
|
use openvk\Web\Models\RowModel;
|
||||||
use openvk\Web\Models\Entities\{Photo, Message, Correspondence};
|
use openvk\Web\Models\Entities\{Photo, Message, Correspondence};
|
||||||
|
@ -53,11 +54,16 @@ class User extends RowModel
|
||||||
return $this->getRecord()->id;
|
return $this->getRecord()->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStyle(): int
|
function getStyle(): string
|
||||||
{
|
{
|
||||||
return $this->getRecord()->style;
|
return $this->getRecord()->style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTheme(): ?Themepack
|
||||||
|
{
|
||||||
|
return Themepacks::i()[$this->getStyle()] ?? NULL;
|
||||||
|
}
|
||||||
|
|
||||||
function getStyleAvatar(): int
|
function getStyleAvatar(): int
|
||||||
{
|
{
|
||||||
return $this->getRecord()->style_avatar;
|
return $this->getRecord()->style_avatar;
|
||||||
|
|
35
Web/Presenters/ThemepacksPresenter.php
Normal file
35
Web/Presenters/ThemepacksPresenter.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Presenters;
|
||||||
|
use openvk\Web\Themes\Themepacks;
|
||||||
|
|
||||||
|
final class ThemepacksPresenter extends OpenVKPresenter
|
||||||
|
{
|
||||||
|
protected $banTolerant = true;
|
||||||
|
|
||||||
|
function renderResource(string $themepack, string $version, string $resClass, string $resource): void
|
||||||
|
{
|
||||||
|
if(!isset(Themepacks::i()[$themepack]))
|
||||||
|
$this->notFound();
|
||||||
|
else
|
||||||
|
$theme = Themepacks::i()[$themepack];
|
||||||
|
|
||||||
|
if($resClass === "resource") {
|
||||||
|
$data = $theme->fetchStaticResource($resource);
|
||||||
|
} else if($resClass === "stylesheet") {
|
||||||
|
if($resource !== "styles.css")
|
||||||
|
$this->notFound();
|
||||||
|
else
|
||||||
|
$data = $theme->fetchStyleSheet();
|
||||||
|
} else {
|
||||||
|
$this->notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$data)
|
||||||
|
$this->notFound();
|
||||||
|
|
||||||
|
header("Content-Type: " . system_extension_mime_type($resource));
|
||||||
|
header("Content-Size: " . strlen($data));
|
||||||
|
header("Cache-Control: public, no-transform, max-age=31536000");
|
||||||
|
exit($data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
<?php declare(strict_types=1);
|
<?php declare(strict_types=1);
|
||||||
namespace openvk\Web\Presenters;
|
namespace openvk\Web\Presenters;
|
||||||
use openvk\Web\Util\Sms;
|
use openvk\Web\Util\Sms;
|
||||||
|
use openvk\Web\Themes\Themepacks;
|
||||||
use openvk\Web\Models\Entities\Photo;
|
use openvk\Web\Models\Entities\Photo;
|
||||||
use openvk\Web\Models\Repositories\Users;
|
use openvk\Web\Models\Repositories\Users;
|
||||||
use openvk\Web\Models\Repositories\Albums;
|
use openvk\Web\Models\Repositories\Albums;
|
||||||
|
@ -91,7 +92,7 @@ final class UserPresenter extends OpenVKPresenter
|
||||||
|
|
||||||
if(!$id)
|
if(!$id)
|
||||||
$this->notFound();
|
$this->notFound();
|
||||||
else
|
|
||||||
$user = $this->users->get($id);
|
$user = $this->users->get($id);
|
||||||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
if($_GET['act'] === "main" || $_GET['act'] == NULL) {
|
if($_GET['act'] === "main" || $_GET['act'] == NULL) {
|
||||||
|
@ -215,7 +216,7 @@ final class UserPresenter extends OpenVKPresenter
|
||||||
|
|
||||||
if(!$id)
|
if(!$id)
|
||||||
$this->notFound();
|
$this->notFound();
|
||||||
else
|
|
||||||
$user = $this->users->get($id);
|
$user = $this->users->get($id);
|
||||||
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
if($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||||
if($_GET['act'] === "main" || $_GET['act'] == NULL) {
|
if($_GET['act'] === "main" || $_GET['act'] == NULL) {
|
||||||
|
@ -247,8 +248,8 @@ final class UserPresenter extends OpenVKPresenter
|
||||||
$user->setPrivacySetting($setting, min(3, abs($input ?? $user->getPrivacySetting($setting))));
|
$user->setPrivacySetting($setting, min(3, abs($input ?? $user->getPrivacySetting($setting))));
|
||||||
}
|
}
|
||||||
}elseif($_GET['act'] === "interface") {
|
}elseif($_GET['act'] === "interface") {
|
||||||
if ($this->postParam("style") <= 20 && $this->postParam("style") >= 0)
|
if (isset(Themepacks::i()[$this->postParam("style")]) || $this->postParam("style") === Themepacks::DEFAULT_THEME_ID)
|
||||||
$user->setStyle((int)$this->postParam("style"));
|
$user->setStyle($this->postParam("style"));
|
||||||
|
|
||||||
if ($this->postParam("style_avatar") <= 2 && $this->postParam("style_avatar") >= 0)
|
if ($this->postParam("style_avatar") <= 2 && $this->postParam("style_avatar") >= 0)
|
||||||
$user->setStyle_Avatar((int)$this->postParam("style_avatar"));
|
$user->setStyle_Avatar((int)$this->postParam("style_avatar"));
|
||||||
|
@ -288,5 +289,6 @@ final class UserPresenter extends OpenVKPresenter
|
||||||
]) ? $this->queryParam("act")
|
]) ? $this->queryParam("act")
|
||||||
: "main";
|
: "main";
|
||||||
$this->template->user = $user;
|
$this->template->user = $user;
|
||||||
|
$this->template->themes = Themepacks::i()->getThemeList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,74 +12,9 @@
|
||||||
{script "js/node_modules/umbrellajs/umbrella.min.js"}
|
{script "js/node_modules/umbrellajs/umbrella.min.js"}
|
||||||
{script "js/openvk.cls.js"}
|
{script "js/openvk.cls.js"}
|
||||||
{ifset $thisUser}
|
{ifset $thisUser}
|
||||||
{var style = (int) ($_GET['__ovkStyleOverride'] ?? $thisUser->getStyle())}
|
{if !is_null($thisUser->getTheme())}
|
||||||
|
{var theme = $thisUser->getTheme()}
|
||||||
{if $style == 1}
|
<link rel="stylesheet" href="/themepack/{$theme->getId()}/{$theme->getVersion()}/stylesheet/styles.css" />
|
||||||
{css "css/vkontakte.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 2}
|
|
||||||
{css "css/ovkdan.5.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 3}
|
|
||||||
{css "css/vkontakte.css"}
|
|
||||||
{css "css/vkontakte2006.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 4}
|
|
||||||
{css "css/ovkg.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 5}
|
|
||||||
{css "css/black.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 6}
|
|
||||||
{css "css/ash_oss_themes/vk2015.2.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 7}
|
|
||||||
{css "css/spacepink.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 9}
|
|
||||||
{css "css/vriska.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 8}
|
|
||||||
{css "css/ash_oss_themes/vk2015.2.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 10}
|
|
||||||
{css "css/ash_oss_themes/ВСоюзе.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 11}
|
|
||||||
{css "css/ash_oss_themes/fb2005.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 12}
|
|
||||||
{css "css/ooer.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 13}
|
|
||||||
{css "css/ash_oss_themes/Twitter2007.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 14}
|
|
||||||
{css "css/kos.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 15}
|
|
||||||
{css "css/ash_oss_themes/pager.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 16}
|
|
||||||
{css "css/ash_oss_themes/vkdark.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 17}
|
|
||||||
{css "css/ash_oss_themes/vtlenu.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 18}
|
|
||||||
{css "css/ash_oss_themes/Fb2006.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 19}
|
|
||||||
{css "css/ash_oss_themes/vkdefenders08.css"}
|
|
||||||
{/if}
|
|
||||||
{if $style == 20}
|
|
||||||
{css "css/ash_oss_themes/tlenta.css"}
|
|
||||||
{/if}
|
|
||||||
{if $thisUser->getStyleAvatar() == 1}
|
|
||||||
{css "css/avatar.1.css"}
|
|
||||||
{/if}
|
|
||||||
{if $thisUser->getStyleAvatar() == 2}
|
|
||||||
{css "css/avatar.2.css"}
|
|
||||||
{/if}
|
{/if}
|
||||||
{/ifset}
|
{/ifset}
|
||||||
|
|
||||||
|
@ -105,11 +40,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
{ifset $thisUser}
|
|
||||||
{if in_array($thisUser->getStyle(), [4, 5, 6, 20])}
|
|
||||||
<div id="xhead" class="dm"></div>
|
<div id="xhead" class="dm"></div>
|
||||||
{/if}
|
|
||||||
{/ifset}
|
|
||||||
<div class="page_header">
|
<div class="page_header">
|
||||||
<a href="/" class="home_button" title="OpenVK">openvk</a>
|
<a href="/" class="home_button" title="OpenVK">openvk</a>
|
||||||
<div n:if="isset($thisUser) ? !$thisUser->isBanned() : true" class="header_navigation">
|
<div n:if="isset($thisUser) ? !$thisUser->isBanned() : true" class="header_navigation">
|
||||||
|
|
|
@ -305,33 +305,12 @@ Block chain PRIZM был запущен 17 февраля 2017-го года. П
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select name="style">
|
<select name="style">
|
||||||
<optgroup label="OpenVK">
|
<option value="ovk" {if $user->getStyle() == 'ovk'}selected{/if}>OpenVK ({_"default"})</option>
|
||||||
<option value="0" {if $user->getStyle() == 0}selected{/if}>OpenVK ({_"default"})</option>
|
<option n:foreach="$themes as $id => $theme"
|
||||||
<option value="2" {if $user->getStyle() == 2}selected{/if}>OpenVK [by Daniel Myslivets]</option>
|
n:attr="selected => $user->getStyle() === $id"
|
||||||
<option value="16" {if $user->getStyle() == 16}selected{/if}>OpenVK Night [by Ash Defenders]</option>
|
value="{$id}">
|
||||||
<option value="5" {if $user->getStyle() == 5}selected{/if}>OpenVK Black [by Daniel Myslivets]</option>
|
{$theme}
|
||||||
<option value="7" {if $user->getStyle() == 7}selected{/if}>OpenVK SpacePink [by Ash Defenders]</option>
|
</option>
|
||||||
</optgroup>
|
|
||||||
<optgroup label="VKontakte">
|
|
||||||
<option value="3" {if $user->getStyle() == 3}selected{/if}>ВКонтакте (2006)</option>
|
|
||||||
<option value="1" {if $user->getStyle() == 1}selected{/if}>ВКонтакте (2007)</option>
|
|
||||||
<option value="8" {if $user->getStyle() == 8}selected{/if}>ВКонтакте (2015) [by Ash Defenders]</option>
|
|
||||||
<option value="19" {if $user->getStyle() == 19}selected{/if}>VK.COM [by Ash Defenders]</option>
|
|
||||||
<option value="6" {if $user->getStyle() == 6}selected{/if} disabled>VK.com (не работает)</option>
|
|
||||||
<option value="10" {if $user->getStyle() == 10}selected{/if}>ВСоюзе</option>
|
|
||||||
<option value="17" {if $user->getStyle() == 17}selected{/if}>ВТлену [by Ash Defenders]</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="Сайты">
|
|
||||||
<option value="11" {if $user->getStyle() == 11}selected{/if}>TheFacebook (2005) [by Ash Defenders]</option>
|
|
||||||
<option value="18" {if $user->getStyle() == 18}selected{/if}>Facebook (2006) [by Ash Defenders]</option>
|
|
||||||
<option value="13" {if $user->getStyle() == 13}selected{/if}>Twitter (2007) [by Ash Defenders]</option>
|
|
||||||
<option value="4" {if $user->getStyle() == 4}selected{/if}>IVinete.ru [by Daniel Myslivets]</option>
|
|
||||||
<option value="15" {if $user->getStyle() == 15}selected{/if}>Пейджер [by Ash Defenders]</option>
|
|
||||||
<option value="20" {if $user->getStyle() == 20}selected{/if}>TLENTA.RU [by Ash Defenders]</option>
|
|
||||||
<option value="14" {if $user->getStyle() == 14}selected{/if}>kosSpace</option>
|
|
||||||
<option value="9" {if $user->getStyle() == 9}selected{/if}>vriska.ru</option>
|
|
||||||
<option value="12" {if $user->getStyle() == 12}selected{/if}>r/Ooer</option>
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
5
Web/Themes/Exceptions/IncompatibleThemeException.php
Normal file
5
Web/Themes/Exceptions/IncompatibleThemeException.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Themes\Exceptions;
|
||||||
|
|
||||||
|
final class IncompatibleThemeException extends \Exception
|
||||||
|
{}
|
5
Web/Themes/Exceptions/MalformedManifestException.php
Normal file
5
Web/Themes/Exceptions/MalformedManifestException.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Themes\Exceptions;
|
||||||
|
|
||||||
|
final class MalformedManifestException extends \Exception
|
||||||
|
{}
|
5
Web/Themes/Exceptions/NotThemeDirectoryException.php
Normal file
5
Web/Themes/Exceptions/NotThemeDirectoryException.php
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Themes\Exceptions;
|
||||||
|
|
||||||
|
final class NotThemeDirectoryException extends \Exception
|
||||||
|
{}
|
76
Web/Themes/Themepack.php
Normal file
76
Web/Themes/Themepack.php
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
namespace openvk\Web\Themes;
|
||||||
|
|
||||||
|
class Themepack
|
||||||
|
{
|
||||||
|
private $id;
|
||||||
|
private $ver;
|
||||||
|
private $meta;
|
||||||
|
private $home;
|
||||||
|
|
||||||
|
function __construct(string $id, string $ver, object $meta)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
$this->ver = $ver;
|
||||||
|
$this->meta = $meta;
|
||||||
|
$this->home = OPENVK_ROOT . "/themepacks/$id";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getId(): string
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName(?string $lang = NULL): string
|
||||||
|
{
|
||||||
|
if(!$this->meta->name)
|
||||||
|
return $this->getId() . " theme";
|
||||||
|
else if(is_array($this->meta->name))
|
||||||
|
return $this->meta->name[$lang ?? "_"] ?? $this->getId() . " theme";
|
||||||
|
else
|
||||||
|
return $this->meta->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVersion(): string
|
||||||
|
{
|
||||||
|
return $this->ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDescription(): string
|
||||||
|
{
|
||||||
|
return $this->meta->description ?? "A theme with name \"" . $this->getName() . "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAuthor(): string
|
||||||
|
{
|
||||||
|
return $this->meta->author ?? $this->getName() . " authors";
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchStyleSheet(): ?string
|
||||||
|
{
|
||||||
|
$file = "$this->home/stylesheet.css";
|
||||||
|
return file_exists($file) ? file_get_contents($file) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchStaticResource(string $name): ?string
|
||||||
|
{
|
||||||
|
$file = "$this->home/res/$name";
|
||||||
|
return file_exists($file) ? file_get_contents($file) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function themepackFromDir(string $dirname): Themepack
|
||||||
|
{
|
||||||
|
$manifestFile = "$dirname/theme.yml";
|
||||||
|
if(!file_exists($manifestFile))
|
||||||
|
throw new Exceptions\NotThemeDirectoryException("Could not locate manifest at $dirname");
|
||||||
|
|
||||||
|
$manifest = (object) chandler_parse_yaml($manifestFile);
|
||||||
|
if(!isset($manifest->id) || !isset($manifest->version) || !isset($manifest->openvk_version) || !isset($manifest->metadata))
|
||||||
|
throw new Exceptions\MalformedManifestException("Manifest is missing required information");
|
||||||
|
|
||||||
|
if($manifest->openvk_version > Themepacks::THEMPACK_ENGINE_VERSION)
|
||||||
|
throw new Exceptions\IncompatibleThemeException("Theme is built for newer OVK (themeEngine" . $manifest->openvk_version . ")");
|
||||||
|
|
||||||
|
return new static($manifest->id, $manifest->version, (object) $manifest->metadata);
|
||||||
|
}
|
||||||
|
}
|
105
Web/Themes/Themepacks.php
Normal file
105
Web/Themes/Themepacks.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?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)
|
||||||
|
yield $id => ($theme->getName(Session::i()->get("lang", "ru")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ services:
|
||||||
- openvk\Web\Presenters\SupportPresenter
|
- openvk\Web\Presenters\SupportPresenter
|
||||||
- openvk\Web\Presenters\AdminPresenter
|
- openvk\Web\Presenters\AdminPresenter
|
||||||
- openvk\Web\Presenters\MessengerPresenter
|
- openvk\Web\Presenters\MessengerPresenter
|
||||||
|
- openvk\Web\Presenters\ThemepacksPresenter
|
||||||
- openvk\Web\Models\Repositories\Users
|
- openvk\Web\Models\Repositories\Users
|
||||||
- openvk\Web\Models\Repositories\Posts
|
- openvk\Web\Models\Repositories\Posts
|
||||||
- openvk\Web\Models\Repositories\Photos
|
- openvk\Web\Models\Repositories\Photos
|
||||||
|
|
|
@ -91,6 +91,12 @@ routes:
|
||||||
handler: "Wall->delete"
|
handler: "Wall->delete"
|
||||||
- url: "/blob_{text}/{text}.{text}"
|
- url: "/blob_{text}/{text}.{text}"
|
||||||
handler: "Blob->file"
|
handler: "Blob->file"
|
||||||
|
- url: "/themepack/{text}/{?version}/{?resClass}/{?any}"
|
||||||
|
handler: "Themepacks->resource"
|
||||||
|
placeholders:
|
||||||
|
version: "(?:[0-9]+\\.?)+"
|
||||||
|
resClass: "stylesheet|resource"
|
||||||
|
any: ".+"
|
||||||
- url: "/albums{num}"
|
- url: "/albums{num}"
|
||||||
handler: "Photos->albumList"
|
handler: "Photos->albumList"
|
||||||
- url: "/albums/create"
|
- url: "/albums/create"
|
||||||
|
|
0
themepacks/.gitkeep
Normal file
0
themepacks/.gitkeep
Normal file
Loading…
Reference in a new issue