mirror of
https://github.com/slawkens/myaac.git
synced 2026-01-02 05:07:11 +01:00
Merge branch 'develop' into feature/refactor-account-lost
This commit is contained in:
@@ -26,6 +26,7 @@ use MyAAC\Cache\Cache;
|
||||
*/
|
||||
class OTS_DB_MySQL extends OTS_Base_DB
|
||||
{
|
||||
private bool $hasCacheChanged = false;
|
||||
private array $has_table_cache = [];
|
||||
private array $has_column_cache = [];
|
||||
private array $get_column_info_cache = [];
|
||||
@@ -164,7 +165,7 @@ class OTS_DB_MySQL extends OTS_Base_DB
|
||||
$cache->delete('database_columns_info');
|
||||
$cache->delete('database_checksum');
|
||||
}
|
||||
else {
|
||||
else if ($this->hasCacheChanged) {
|
||||
$cache->set('database_tables', serialize($this->has_table_cache), 3600);
|
||||
$cache->set('database_columns', serialize($this->has_column_cache), 3600);
|
||||
$cache->set('database_columns_info', serialize($this->get_column_info_cache), 3600);
|
||||
@@ -228,6 +229,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
|
||||
|
||||
private function hasTableInternal($name): bool
|
||||
{
|
||||
$this->hasCacheChanged = true;
|
||||
|
||||
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
|
||||
}
|
||||
|
||||
@@ -241,6 +244,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
|
||||
}
|
||||
|
||||
private function hasColumnInternal($table, $column): bool {
|
||||
$this->hasCacheChanged = true;
|
||||
|
||||
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0);
|
||||
}
|
||||
|
||||
@@ -272,6 +277,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->hasCacheChanged = true;
|
||||
|
||||
$formatResult = function ($result) {
|
||||
return [
|
||||
'field' => $result['Field'],
|
||||
|
||||
16
system/migrations/48.php
Normal file
16
system/migrations/48.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* @var OTS_DB_MySQL $db
|
||||
*/
|
||||
|
||||
$up = function () use ($db) {
|
||||
if (!$db->hasColumn(TABLE_PREFIX . 'menu', 'access')) {
|
||||
$db->addColumn(TABLE_PREFIX . 'menu', 'access', 'TINYINT NOT NULL DEFAULT 0 AFTER `link`');
|
||||
}
|
||||
};
|
||||
|
||||
$down = function () use ($db) {
|
||||
if ($db->hasColumn(TABLE_PREFIX . 'menu', 'access')) {
|
||||
$db->dropColumn(TABLE_PREFIX . 'menu', 'access');
|
||||
}
|
||||
};
|
||||
@@ -9,7 +9,7 @@ $up = function () use ($db) {
|
||||
}
|
||||
};
|
||||
|
||||
$up = function () use ($db) {
|
||||
$down = function () use ($db) {
|
||||
if (!$db->hasColumn(TABLE_PREFIX . 'screenshots', 'name')) {
|
||||
$db->addColumn(TABLE_PREFIX . 'screenshots', 'name', 'VARCHAR(30) NOT NULL');
|
||||
}
|
||||
|
||||
@@ -176,7 +176,9 @@ if (empty($highscores)) {
|
||||
POT::SKILL_FISH => 'skill_fishing',
|
||||
);
|
||||
|
||||
$query->addSelect($skill_ids[$skill] . ' as value');
|
||||
$query
|
||||
->addSelect($skill_ids[$skill] . ' as value')
|
||||
->orderByDesc($skill_ids[$skill] . '_tries');
|
||||
} else {
|
||||
$query
|
||||
->join('player_skills', 'player_skills.player_id', '=', 'players.id')
|
||||
@@ -198,11 +200,11 @@ if (empty($highscores)) {
|
||||
if ($skill == POT::SKILL__MAGLEVEL) {
|
||||
$query
|
||||
->addSelect('players.maglevel as value', 'players.maglevel')
|
||||
->orderBy('manaspent');
|
||||
->orderByDesc('manaspent');
|
||||
} else { // level
|
||||
$query
|
||||
->addSelect('players.level as value', 'players.experience')
|
||||
->orderBy('experience');
|
||||
->orderByDesc('experience');
|
||||
$list = 'experience';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @link https://my-aac.org
|
||||
*/
|
||||
|
||||
use MyAAC\Models\Menu;
|
||||
use MyAAC\Models\Pages;
|
||||
use MyAAC\Plugins;
|
||||
|
||||
@@ -331,7 +332,20 @@ else {
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
$tmpPageOriginal = $page;
|
||||
$pagesWithDynamicPart = ['characters', 'forum', 'highscores', 'monsters'];
|
||||
foreach ($pagesWithDynamicPart as $_page) {
|
||||
if (str_contains($page, $_page)) {
|
||||
$tmpPageOriginal = $_page;
|
||||
}
|
||||
}
|
||||
|
||||
$themeMenu = Menu::select(['name'])
|
||||
->where('template', $template_name)
|
||||
->where('link', $tmpPageOriginal)
|
||||
->where('access', '>', $logged_access);
|
||||
|
||||
if (!$found || $themeMenu->count() >= 1) {
|
||||
$page = '404';
|
||||
$file = SYSTEM . 'pages/404.php';
|
||||
}
|
||||
|
||||
@@ -219,7 +219,14 @@ return [
|
||||
'cache_engine' => [
|
||||
'name' => 'Cache Engine',
|
||||
'type' => 'options',
|
||||
'options' => ['auto' => 'Auto', 'file' => 'Files', 'apc' => 'APC', 'apcu' => 'APCu', 'disable' => 'Disable'],
|
||||
'options' => [
|
||||
'auto' => 'Auto',
|
||||
'file' => 'Files',
|
||||
'apc' => 'APC',
|
||||
'apcu' => 'APCu',
|
||||
'php' => 'PHP',
|
||||
'disable' => 'Disable',
|
||||
],
|
||||
'desc' => 'Auto is most reasonable. It will detect the best cache engine',
|
||||
'default' => 'auto',
|
||||
'is_config' => true,
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
|
||||
|
||||
class APC
|
||||
{
|
||||
private $prefix;
|
||||
private $enabled;
|
||||
private string $prefix;
|
||||
private bool $enabled;
|
||||
|
||||
public function __construct($prefix = '')
|
||||
{
|
||||
@@ -22,14 +22,14 @@ class APC
|
||||
$this->enabled = function_exists('apc_fetch');
|
||||
}
|
||||
|
||||
public function set($key, $var, $ttl = 0)
|
||||
public function set($key, $var, $ttl = 0): void
|
||||
{
|
||||
$key = $this->prefix . $key;
|
||||
apc_delete($key);
|
||||
apc_store($key, $var, $ttl);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
public function get($key): string
|
||||
{
|
||||
$tmp = '';
|
||||
if ($this->fetch($this->prefix . $key, $tmp)) {
|
||||
@@ -39,18 +39,15 @@ class APC
|
||||
return '';
|
||||
}
|
||||
|
||||
public function fetch($key, &$var)
|
||||
{
|
||||
public function fetch($key, &$var): bool {
|
||||
return ($var = apc_fetch($this->prefix . $key)) !== false;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
public function delete($key): void {
|
||||
apc_delete($this->prefix . $key);
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
|
||||
|
||||
class APCu
|
||||
{
|
||||
private $prefix;
|
||||
private $enabled;
|
||||
private string $prefix;
|
||||
private bool $enabled;
|
||||
|
||||
public function __construct($prefix = '')
|
||||
{
|
||||
@@ -22,14 +22,14 @@ class APCu
|
||||
$this->enabled = function_exists('apcu_fetch');
|
||||
}
|
||||
|
||||
public function set($key, $var, $ttl = 0)
|
||||
public function set($key, $var, $ttl = 0): void
|
||||
{
|
||||
$key = $this->prefix . $key;
|
||||
apcu_delete($key);
|
||||
apcu_store($key, $var, $ttl);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
public function get($key): string
|
||||
{
|
||||
$tmp = '';
|
||||
if ($this->fetch($this->prefix . $key, $tmp)) {
|
||||
@@ -39,18 +39,15 @@ class APCu
|
||||
return '';
|
||||
}
|
||||
|
||||
public function fetch($key, &$var)
|
||||
{
|
||||
public function fetch($key, &$var): bool {
|
||||
return ($var = apcu_fetch($this->prefix . $key)) !== false;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
public function delete($key): void {
|
||||
apcu_delete($this->prefix . $key);
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,35 +47,15 @@ class Cache
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
switch (strtolower($engine)) {
|
||||
case 'apc':
|
||||
self::$instance = new APC($prefix);
|
||||
break;
|
||||
|
||||
case 'apcu':
|
||||
self::$instance = new APCu($prefix);
|
||||
break;
|
||||
|
||||
case 'xcache':
|
||||
self::$instance = new XCache($prefix);
|
||||
break;
|
||||
|
||||
case 'file':
|
||||
self::$instance = new File($prefix, CACHE);
|
||||
break;
|
||||
|
||||
case 'php':
|
||||
self::$instance = new PHP($prefix, CACHE);
|
||||
break;
|
||||
|
||||
case 'auto':
|
||||
self::$instance = self::generateInstance(self::detect(), $prefix);
|
||||
break;
|
||||
|
||||
default:
|
||||
self::$instance = new self();
|
||||
break;
|
||||
}
|
||||
self::$instance = match (strtolower($engine)) {
|
||||
'apc' => new APC($prefix),
|
||||
'apcu' => new APCu($prefix),
|
||||
'xcache' => new XCache($prefix),
|
||||
'file' => new File($prefix, CACHE),
|
||||
'php' => new PHP($prefix, CACHE),
|
||||
'auto' => self::generateInstance(self::detect(), $prefix),
|
||||
default => new self(),
|
||||
};
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
@@ -83,7 +63,7 @@ class Cache
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function detect()
|
||||
public static function detect(): string
|
||||
{
|
||||
if (function_exists('apc_fetch'))
|
||||
return 'apc';
|
||||
@@ -98,8 +78,7 @@ class Cache
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,18 +12,22 @@ namespace MyAAC\Cache;
|
||||
|
||||
class File
|
||||
{
|
||||
private $prefix;
|
||||
private $dir;
|
||||
private $enabled;
|
||||
private string $prefix;
|
||||
private string $dir;
|
||||
private bool $enabled;
|
||||
|
||||
public function __construct($prefix = '', $dir = '')
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
$this->dir = $dir;
|
||||
|
||||
ensureFolderExists($this->dir);
|
||||
ensureIndexExists($this->dir);
|
||||
|
||||
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
|
||||
}
|
||||
|
||||
public function set($key, $var, $ttl = 0)
|
||||
public function set($key, $var, $ttl = 0): void
|
||||
{
|
||||
$file = $this->_name($key);
|
||||
file_put_contents($file, $var);
|
||||
@@ -35,7 +39,7 @@ class File
|
||||
touch($file, time() + $ttl);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
public function get($key): string
|
||||
{
|
||||
$tmp = '';
|
||||
if ($this->fetch($key, $tmp)) {
|
||||
@@ -45,7 +49,7 @@ class File
|
||||
return '';
|
||||
}
|
||||
|
||||
public function fetch($key, &$var)
|
||||
public function fetch($key, &$var): bool
|
||||
{
|
||||
$file = $this->_name($key);
|
||||
if (!file_exists($file) || filemtime($file) < time()) {
|
||||
@@ -56,7 +60,7 @@ class File
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
public function delete($key): void
|
||||
{
|
||||
$file = $this->_name($key);
|
||||
if (file_exists($file)) {
|
||||
@@ -64,13 +68,11 @@ class File
|
||||
}
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
private function _name($key)
|
||||
{
|
||||
private function _name($key): string {
|
||||
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,39 +12,40 @@ namespace MyAAC\Cache;
|
||||
|
||||
class PHP
|
||||
{
|
||||
private $prefix;
|
||||
private $dir;
|
||||
private $enabled;
|
||||
private string $prefix;
|
||||
private string $dir;
|
||||
private bool $enabled;
|
||||
|
||||
public function __construct($prefix = '', $dir = '')
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
$this->dir = $dir;
|
||||
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
|
||||
}
|
||||
|
||||
public function set($key, $var, $ttl = 0)
|
||||
{
|
||||
$var = var_export($var, true);
|
||||
|
||||
ensureFolderExists($this->dir);
|
||||
ensureIndexExists($this->dir);
|
||||
|
||||
// Write to temp file first to ensure atomicity
|
||||
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
|
||||
file_put_contents($tmp, '<?php $var = ' . $var . ';', LOCK_EX);
|
||||
$this->enabled = (file_exists($this->dir) && is_dir($this->dir) && is_writable($this->dir));
|
||||
}
|
||||
|
||||
$file = $this->_name($key);
|
||||
rename($tmp, $file);
|
||||
public function set($key, $var, $ttl = 0): void
|
||||
{
|
||||
$var = var_export($var, true);
|
||||
|
||||
if ($ttl === 0) {
|
||||
$ttl = 365 * 24 * 60 * 60; // 365 days
|
||||
}
|
||||
|
||||
touch($file, time() + $ttl);
|
||||
$expires = time() + $ttl;
|
||||
|
||||
// Write to temp file first to ensure atomicity
|
||||
$tmp = $this->dir . "tmp_$key." . uniqid('', true) . '.tmp';
|
||||
file_put_contents($tmp, "<?php return ['expires' => $expires, 'var' => $var];", LOCK_EX);
|
||||
|
||||
$file = $this->_name($key);
|
||||
rename($tmp, $file);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
public function get($key): string
|
||||
{
|
||||
$tmp = '';
|
||||
if ($this->fetch($key, $tmp)) {
|
||||
@@ -54,19 +55,23 @@ class PHP
|
||||
return '';
|
||||
}
|
||||
|
||||
public function fetch($key, &$var)
|
||||
public function fetch($key, &$var): bool
|
||||
{
|
||||
$file = $this->_name($key);
|
||||
if (!file_exists($file) || filemtime($file) < time()) {
|
||||
if (!file_exists($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@include $file;
|
||||
$var = isset($var) ? $var : null;
|
||||
$content = include $file;
|
||||
if (!isset($content) || $content['expires'] < time()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$var = $content['var'];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
public function delete($key): void
|
||||
{
|
||||
$file = $this->_name($key);
|
||||
if (file_exists($file)) {
|
||||
@@ -74,13 +79,11 @@ class PHP
|
||||
}
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
private function _name($key)
|
||||
{
|
||||
private function _name($key): string {
|
||||
return sprintf('%s%s%s', $this->dir, $this->prefix, sha1($key) . '.php');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace MyAAC\Cache;
|
||||
|
||||
class XCache
|
||||
{
|
||||
private $prefix;
|
||||
private $enabled;
|
||||
private string $prefix;
|
||||
private bool $enabled;
|
||||
|
||||
public function __construct($prefix = '')
|
||||
{
|
||||
@@ -22,14 +22,14 @@ class XCache
|
||||
$this->enabled = function_exists('xcache_get') && ini_get('xcache.var_size');
|
||||
}
|
||||
|
||||
public function set($key, $var, $ttl = 0)
|
||||
public function set($key, $var, $ttl = 0): void
|
||||
{
|
||||
$key = $this->prefix . $key;
|
||||
xcache_unset($key);
|
||||
xcache_set($key, $var, $ttl);
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
public function get($key): string
|
||||
{
|
||||
$tmp = '';
|
||||
if ($this->fetch($this->prefix . $key, $tmp)) {
|
||||
@@ -39,7 +39,7 @@ class XCache
|
||||
return '';
|
||||
}
|
||||
|
||||
public function fetch($key, &$var)
|
||||
public function fetch($key, &$var): bool
|
||||
{
|
||||
$key = $this->prefix . $key;
|
||||
if (!xcache_isset($key)) {
|
||||
@@ -50,13 +50,11 @@ class XCache
|
||||
return true;
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
public function delete($key): void {
|
||||
xcache_unset($this->prefix . $key);
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
public function enabled(): bool {
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ class Forum
|
||||
if(!is_int($rows / 2)) { $bgcolor = 'ABED25'; } else { $bgcolor = '23ED25'; } $rows++;
|
||||
$text = str_ireplace('[code]'.$code.'[/code]', '<i>Code:</i><br /><table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #CCCCCC; border-width: 2px"><tr><td>'.$code.'</td></tr></table>', $text);
|
||||
}
|
||||
|
||||
$rows = 0;
|
||||
while(stripos($text, '[quote]') !== false && stripos($text, '[/quote]') !== false )
|
||||
{
|
||||
@@ -238,11 +239,31 @@ class Forum
|
||||
if(!is_int($rows / 2)) { $bgcolor = 'AAAAAA'; } else { $bgcolor = 'CCCCCC'; } $rows++;
|
||||
$text = str_ireplace('[quote]'.$quote.'[/quote]', '<table cellpadding="0" style="background-color: #'.$bgcolor.'; width: 480px; border-style: dotted; border-color: #007900; border-width: 2px"><tr><td>'.$quote.'</td></tr></table>', $text);
|
||||
}
|
||||
$rows = 0;
|
||||
while(stripos($text, '[url]') !== false && stripos($text, '[/url]') !== false )
|
||||
{
|
||||
$url = substr($text, stripos($text, '[url]')+5, stripos($text, '[/url]') - stripos($text, '[url]') - 5);
|
||||
$text = str_ireplace('[url]'.$url.'[/url]', '<a href="'.$url.'" target="_blank">'.$url.'</a>', $text);
|
||||
|
||||
$tagsToParse = [
|
||||
'url' => function ($str) {
|
||||
return '<a href="'.$str.'" target="_blank">'.$str.'</a>';
|
||||
},
|
||||
'player' => function ($str) {
|
||||
return generateLink(getPlayerLink($str, false), $str, true);
|
||||
},
|
||||
'guild' => function ($str) {
|
||||
return generateLink(getGuildLink($str, false), $str, true);
|
||||
},
|
||||
'house' => function ($str) {
|
||||
return generateLink(getHouseLink($str, false), $str, true);
|
||||
}
|
||||
];
|
||||
|
||||
foreach ($tagsToParse as $tag => $callback) {
|
||||
while(stripos($text, "[$tag]") !== false && stripos($text, "[/$tag]") !== false
|
||||
&& stripos($text, "[$tag]") < stripos($text, "[/$tag]"))
|
||||
{
|
||||
$length = strlen("[$tag]");
|
||||
$substr = substr($text, stripos($text, "[$tag]") + $length, stripos($text, "[/$tag]") - stripos($text, "[$tag]") - $length);
|
||||
|
||||
$text = str_ireplace('[' . $tag . ']' . $substr . '[/' . $tag . ']', $callback($substr), $text);
|
||||
}
|
||||
}
|
||||
|
||||
$xhtml = false;
|
||||
@@ -252,9 +273,6 @@ class Forum
|
||||
'#\[u\](.*?)\[/u\]#si' => ($xhtml ? '<span style="text-decoration: underline;">\\1</span>' : '<u>\\1</u>'),
|
||||
'#\[s\](.*?)\[/s\]#si' => ($xhtml ? '<strike>\\1</strike>' : '<s>\\1</s>'),
|
||||
|
||||
'#\[guild\](.*?)\[/guild\]#si' => urldecode(generateLink(getGuildLink('$1', false), '$1', true)),
|
||||
'#\[house\](.*?)\[/house\]#si' => urldecode(generateLink(getHouseLink('$1', false), '$1', true)),
|
||||
'#\[player\](.*?)\[/player\]#si' => urldecode(generateLink(getPlayerLink('$1', false), '$1', true)),
|
||||
// TODO: [poll] tag
|
||||
|
||||
'#\[color=(.*?)\](.*?)\[/color\]#si' => ($xhtml ? '<span style="color: \\1;">\\2</span>' : '<span style="color: \\1">\\2</span>'),
|
||||
|
||||
@@ -9,6 +9,6 @@ class Menu extends Model {
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = ['template', 'name', 'link', 'blank', 'color', 'category', 'ordering', 'enabled'];
|
||||
protected $fillable = ['template', 'name', 'link', 'access', 'blank', 'color', 'category', 'ordering', 'enabled'];
|
||||
|
||||
}
|
||||
|
||||
@@ -342,6 +342,16 @@ class Validator
|
||||
}
|
||||
}
|
||||
|
||||
global $hooks;
|
||||
|
||||
$params = ['name' => $name, 'error' => ''];
|
||||
$hooks->triggerFilter(HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME, $params);
|
||||
|
||||
if (!empty($params['error'])) {
|
||||
self::$lastError = $params['error'];
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ define('HOOK_FILTER_ROUTES', ++$i);
|
||||
define('HOOK_FILTER_TWIG_DISPLAY', ++$i);
|
||||
define('HOOK_FILTER_TWIG_RENDER', ++$i);
|
||||
define('HOOK_FILTER_THEME_FOOTER', ++$i);
|
||||
define('HOOK_FILTER_VALIDATE_CHARACTER_NEW_NAME', ++$i);
|
||||
|
||||
const HOOK_FIRST = HOOK_INIT;
|
||||
define('HOOK_LAST', $i);
|
||||
|
||||
@@ -146,10 +146,10 @@ if($twig_loader) {
|
||||
|
||||
function get_template_menus(): array
|
||||
{
|
||||
global $template_name;
|
||||
global $template_name, $logged_access;
|
||||
|
||||
$result = Cache::remember('template_menus_' . $template_name, 10 * 60, function () use ($template_name) {
|
||||
$result = Menu::select(['name', 'link', 'blank', 'color', 'category'])
|
||||
$result = Menu::select(['name', 'link', 'access', 'blank', 'color', 'category'])
|
||||
->where('template', $template_name)
|
||||
->orderBy('category')
|
||||
->orderBy('ordering')
|
||||
@@ -163,6 +163,10 @@ function get_template_menus(): array
|
||||
|
||||
$menus = [];
|
||||
foreach($result as $menu) {
|
||||
if ($menu['access'] > $logged_access) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($menu['link'])) {
|
||||
$menu['link'] = 'news';
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<p class="note">You are editing: {{ template }}<br/><br/>
|
||||
Hint: You can drag menu items.<br/>
|
||||
Hint: Add links to external sites using: <b>http://</b> or <b>https://</b> prefix.<br/>
|
||||
Not all templates support blank and colorful links.
|
||||
Not all templates support blank and colorful links.<br/>
|
||||
* Guest means everyone will see the link. Player means registered and logged-in user.
|
||||
</p>
|
||||
<div class="row text-center">
|
||||
<div class="col-md-2 col-sm-1"></div>
|
||||
|
||||
@@ -14,42 +14,62 @@
|
||||
colors[{{ cat }}] = '{{ options['default_links_color'] ?? (menuDefaultLinksColor ?? config('menu_default_color')) }}';
|
||||
{% endfor %}
|
||||
|
||||
function confirmRemoveMenuItem(that)
|
||||
{
|
||||
let id = $(that).attr("id");
|
||||
if (confirm('Are you sure, that you want to remove this element?')) {
|
||||
$('#list-' + id.replace('remove-button-', '')).remove();
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
const $sortable = $(".sortable");
|
||||
$sortable.sortable();
|
||||
$sortable.disableSelection();
|
||||
|
||||
$(".remove-button").on('click', function () {
|
||||
var id = $(this).attr("id");
|
||||
$('#list-' + id.replace('remove-button-', '')).remove();
|
||||
confirmRemoveMenuItem(this);
|
||||
});
|
||||
|
||||
$(".add-button").on('click', function () {
|
||||
var cat = $(this).attr("id").replace('add-button-', '');
|
||||
var id = last_id[cat];
|
||||
let cat = $(this).attr("id").replace('add-button-', '');
|
||||
let id = last_id[cat];
|
||||
last_id[cat]++;
|
||||
const color = colors[cat];
|
||||
$('#sortable-' + cat).append('<li class="ui-state-default" id="list-' + cat + '-' + id + '"><label>Name:</label> <input type="text" name="menu[' + cat + '][]" value=""/> <label>Link:</label> <input type="text" name="menu_link[' + cat + '][]" value=""/><input type="hidden" name="menu_blank[' + cat + '][]" value="0" /> <label><input class="blank-checkbox" type="checkbox"/><span title="Open in New Window">New Window</span></label> <input class="color-picker" type="text" name="menu_color[' + cat + '][]" value="#' + color + '" /> <a class="remove-button" id="remove-button-' + cat + '-' + id + '"><i class="fas fa-trash"></i></a></li>'); //add input bo
|
||||
$('#remove-button-' + cat + '-' + id).on('click', function () {
|
||||
$('#list-' + $(this).attr("id").replace('remove-button-', '')).remove();
|
||||
});
|
||||
|
||||
initializeSpectrum();
|
||||
let copy = $('.ui-state-default:first').clone();
|
||||
|
||||
copy.attr('id', 'list-' + cat + '-' + id);
|
||||
|
||||
copy.find('.menu-name').val('').attr('name', 'menu[' + cat + '][]');
|
||||
copy.find('.menu-link').val('').attr('name', 'menu_link[' + cat + '][]');
|
||||
copy.find('.menu-access').val('0').attr('name', 'menu_access[' + cat + '][]');
|
||||
copy.find('.menu-color').val(color).attr('name', 'menu_color[' + cat + '][]');
|
||||
copy.find('.menu-blank').attr('name', 'menu_blank[' + cat + '][]');
|
||||
copy.find('.menu-blank-checkbox').prop('checked', false);
|
||||
|
||||
copy.find('.remove-button').attr('id', 'remove-button-' + cat + '-' + id);
|
||||
|
||||
$('#sortable-' + cat).append(copy);
|
||||
|
||||
$('#remove-button-' + cat + '-' + id).on('click', function () {
|
||||
confirmRemoveMenuItem(this);
|
||||
});
|
||||
});
|
||||
|
||||
$("#menus-form").on('submit', function (e) {
|
||||
$('.blank-checkbox:not(:checked)').each(function (i, obj) {
|
||||
$('.menu-blank-checkbox:not(:checked)').each(function (i, obj) {
|
||||
$(obj).parent().prev().val("off");
|
||||
});
|
||||
|
||||
$('.blank-checkbox:checked').each(function (i, obj) {
|
||||
$('.menu-blank-checkbox:checked').each(function (i, obj) {
|
||||
$(obj).parent().prev().val("on");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
.sortable {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
@@ -60,24 +80,16 @@
|
||||
.remove-button, .add-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/js/spectrum.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="{{ constant('BASE_URL') }}tools/css/spectrum.css"/>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
initializeSpectrum();
|
||||
});
|
||||
|
||||
function initializeSpectrum() {
|
||||
$(".color-picker").spectrum({
|
||||
preferredFormat: "hex",
|
||||
showInput: true,
|
||||
showPalette: true,
|
||||
palette: [
|
||||
['black', 'white', 'blanchedalmond',
|
||||
'rgb(255, 128, 0);', 'hsv 100 70 50'],
|
||||
['red', 'yellow', 'green', 'blue', 'violet']
|
||||
]
|
||||
});
|
||||
.ui-sortable-handle {
|
||||
padding: 10px;
|
||||
}
|
||||
</script>
|
||||
|
||||
.label_menu_name, .label_menu_link {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.menu-name, .menu-link {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user