mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-04-02 01:52:10 +09:00
Merge branch 'rhymix:master' into master
This commit is contained in:
commit
e5b729f8e9
152 changed files with 2348 additions and 792 deletions
|
|
@ -133,6 +133,11 @@ require_once RX_BASEDIR . 'common/framework/DateTime.php';
|
|||
require_once RX_BASEDIR . 'common/framework/Debug.php';
|
||||
require_once RX_BASEDIR . 'common/framework/Lang.php';
|
||||
|
||||
/**
|
||||
* Load system configuration.
|
||||
*/
|
||||
Rhymix\Framework\Config::init();
|
||||
|
||||
/**
|
||||
* Load user configuration.
|
||||
*/
|
||||
|
|
@ -141,11 +146,6 @@ if(file_exists(RX_BASEDIR . 'config/config.user.inc.php'))
|
|||
require_once RX_BASEDIR . 'config/config.user.inc.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load system configuration.
|
||||
*/
|
||||
Rhymix\Framework\Config::init();
|
||||
|
||||
/**
|
||||
* Install the debugger.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/**
|
||||
* RX_VERSION is the version number of the Rhymix CMS.
|
||||
*/
|
||||
define('RX_VERSION', '2.1.19');
|
||||
define('RX_VERSION', '2.1.21');
|
||||
|
||||
/**
|
||||
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
* Copyright (c) Rhymix Developers and Contributors
|
||||
*/
|
||||
return array(
|
||||
|
||||
// YouTube
|
||||
'www.youtube.com/',
|
||||
'www.youtube-nocookie.com/',
|
||||
|
|
@ -19,43 +18,17 @@ return array(
|
|||
|
||||
// Google Maps
|
||||
'www.google.com/maps/embed',
|
||||
'maps.google.com/',
|
||||
'maps.google.co.kr/',
|
||||
|
||||
// Daum
|
||||
'flvs.daum.net/',
|
||||
'videofarm.daum.net/',
|
||||
'api.v.daum.net/',
|
||||
'videofarm.daum.net/',
|
||||
|
||||
|
||||
// Giphy
|
||||
'giphy.com/',
|
||||
|
||||
// Sooplive
|
||||
'vod.sooplive.co.kr/',
|
||||
|
||||
// Kakao TV
|
||||
'tv.kakao.com/',
|
||||
'play-tv.kakao.com/',
|
||||
|
||||
// Naver
|
||||
'serviceapi.rmcnmv.naver.com/',
|
||||
'serviceapi.nmv.naver.com/',
|
||||
'scrap.ad.naver.com/',
|
||||
'static.campaign.naver.com/',
|
||||
'musicplayer.naver.com/naverPlayer/posting/',
|
||||
'player.music.naver.com/naverPlayer/posting/',
|
||||
|
||||
// Pandora TV
|
||||
'www.pandora.tv/view/',
|
||||
'flvr.pandora.tv/flv2pan/',
|
||||
|
||||
// Cyworld
|
||||
'dbi.video.cyworld.com/v.sk/',
|
||||
|
||||
// Egloos
|
||||
'v.egloos.com/v.sk/',
|
||||
|
||||
// Nate
|
||||
'v.nate.com/v.sk/',
|
||||
'w.blogdoc.nate.com/',
|
||||
|
||||
// SBS
|
||||
'netv.sbs.co.kr/sbox/',
|
||||
'news.sbs.co.kr/',
|
||||
'wizard2.sbs.co.kr/',
|
||||
'sbsplayer.sbs.co.kr/',
|
||||
|
||||
// Afreeca
|
||||
'afree.ca/',
|
||||
'chzzk.naver.com/',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -487,9 +487,9 @@ class DB
|
|||
}
|
||||
|
||||
// Collect various counts used in the page calculation.
|
||||
list($is_expression, $list_count) = $query->navigation->list_count->getValue($args);
|
||||
list($is_expression, $page_count) = $query->navigation->page_count->getValue($args);
|
||||
list($is_expression, $page) = $query->navigation->page->getValue($args);
|
||||
$list_count = $query->navigation->list_count->getValue($args)[0];
|
||||
$page_count = $query->navigation->page_count->getValue($args)[0];
|
||||
$page = $query->navigation->page->getValue($args)[0];
|
||||
$total_count = intval($count);
|
||||
$total_page = max(1, intval(ceil($total_count / $list_count)));
|
||||
$last_index = $total_count - (($page - 1) * $list_count);
|
||||
|
|
@ -531,6 +531,7 @@ class DB
|
|||
$result = array();
|
||||
$index = $last_index;
|
||||
$step = $last_index !== 0 ? -1 : 1;
|
||||
$count = 0;
|
||||
$result_class = ($result_class && $result_class !== 'master') ? $result_class : 'stdClass';
|
||||
if (!class_exists($result_class))
|
||||
{
|
||||
|
|
@ -540,6 +541,11 @@ class DB
|
|||
{
|
||||
$result[$index] = $row;
|
||||
$index += $step;
|
||||
$count++;
|
||||
if ($count === 10000 && $this->_query_id !== '')
|
||||
{
|
||||
trigger_error('XML query ' . $this->_query_id . ' returned 10000 rows or more', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->closeCursor();
|
||||
|
|
|
|||
|
|
@ -968,7 +968,7 @@ class Debug
|
|||
case \E_USER_ERROR: return 'User Error';
|
||||
case \E_USER_WARNING: return 'Warning';
|
||||
case \E_USER_NOTICE: return 'Notice';
|
||||
case \E_STRICT: return 'Strict Standards';
|
||||
case 2048: return 'Strict Standards'; /* E_STRICT is deprecated */
|
||||
case \E_PARSE: return 'Parse Error';
|
||||
case \E_DEPRECATED: return 'Deprecated';
|
||||
case \E_USER_DEPRECATED: return 'User Deprecated';
|
||||
|
|
|
|||
|
|
@ -215,7 +215,10 @@ class HTTP
|
|||
$proxy = parse_url($proxy);
|
||||
$proxy_scheme = preg_match('/^(https|socks)/', $proxy['scheme'] ?? '') ? ($proxy['scheme'] . '://') : 'http://';
|
||||
$proxy_auth = (!empty($proxy['user']) && !empty($proxy['pass'])) ? ($proxy['user'] . ':' . $proxy['pass'] . '@') : '';
|
||||
$settings['proxy'] = sprintf('%s%s%s:%s', $proxy_scheme, $proxy_auth, $proxy['host'], $proxy['port']);
|
||||
if (!empty($proxy['host']) && !empty($proxy['port']))
|
||||
{
|
||||
$settings['proxy'] = sprintf('%s%s%s:%s', $proxy_scheme, $proxy_auth, $proxy['host'], $proxy['port']);
|
||||
}
|
||||
}
|
||||
|
||||
self::$_client = new \GuzzleHttp\Client($settings);
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Queue
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the default driver.
|
||||
* Get a Queue driver instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @return ?Drivers\QueueInterface
|
||||
|
|
@ -49,6 +49,16 @@ class Queue
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DB driver instance, for managing scheduled tasks.
|
||||
*
|
||||
* @return Drivers\Queue\DB
|
||||
*/
|
||||
public static function getDbDriver(): Drivers\Queue\DB
|
||||
{
|
||||
return self::getDriver('db');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of supported Queue drivers.
|
||||
*
|
||||
|
|
@ -86,7 +96,9 @@ class Queue
|
|||
}
|
||||
|
||||
/**
|
||||
* Add a task.
|
||||
* Add a task to the queue.
|
||||
*
|
||||
* The queued task will be executed as soon as possible.
|
||||
*
|
||||
* The handler can be in one of the following formats:
|
||||
* - Global function, e.g. myHandler
|
||||
|
|
@ -128,29 +140,82 @@ class Queue
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the first task to execute immediately.
|
||||
* Add a task to be executed at a specific time.
|
||||
*
|
||||
* If no tasks are pending, this method will return null.
|
||||
* Detailed scheduling of tasks will be handled by each driver.
|
||||
* The queued task will be executed once at the configured time.
|
||||
* The rest is identical to addTask().
|
||||
*
|
||||
* @param int $blocking
|
||||
* @param int $time
|
||||
* @param string $handler
|
||||
* @param ?object $args
|
||||
* @param ?object $options
|
||||
* @return int
|
||||
*/
|
||||
public static function addTaskAt(int $time, string $handler, ?object $args = null, ?object $options = null): int
|
||||
{
|
||||
if (!config('queue.enabled'))
|
||||
{
|
||||
throw new Exceptions\FeatureDisabled('Queue not configured');
|
||||
}
|
||||
|
||||
// This feature always uses the DB driver.
|
||||
$driver = self::getDbDriver();
|
||||
return $driver->addTaskAt($time, $handler, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a task to be executed at an interval.
|
||||
*
|
||||
* The queued task will be executed repeatedly at the scheduled interval.
|
||||
* The synax for specifying the interval is the same as crontab.
|
||||
* The rest is identical to addTask().
|
||||
*
|
||||
* @param string $interval
|
||||
* @param string $handler
|
||||
* @param ?object $args
|
||||
* @param ?object $options
|
||||
* @return int
|
||||
*/
|
||||
public static function addTaskAtInterval(string $interval, string $handler, ?object $args = null, ?object $options = null): int
|
||||
{
|
||||
if (!config('queue.enabled'))
|
||||
{
|
||||
throw new Exceptions\FeatureDisabled('Queue not configured');
|
||||
}
|
||||
|
||||
// Validate the interval syntax.
|
||||
if (!self::checkIntervalSyntax($interval))
|
||||
{
|
||||
throw new Exceptions\InvalidRequest('Invalid interval syntax: ' . $interval);
|
||||
}
|
||||
|
||||
// This feature always uses the DB driver.
|
||||
$driver = self::getDbDriver();
|
||||
return $driver->addTaskAtInterval($interval, $handler, $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a scheduled task if it exists.
|
||||
*
|
||||
* @param int $task_srl
|
||||
* @return ?object
|
||||
*/
|
||||
public static function getTask(int $blocking = 0): ?object
|
||||
public static function getScheduledTask(int $task_srl): ?object
|
||||
{
|
||||
$driver_name = config('queue.driver');
|
||||
if (!$driver_name)
|
||||
{
|
||||
throw new Exceptions\FeatureDisabled('Queue not configured');
|
||||
}
|
||||
$driver = self::getDbDriver();
|
||||
return $driver->getScheduledTask($task_srl);
|
||||
}
|
||||
|
||||
$driver = self::getDriver($driver_name);
|
||||
if (!$driver)
|
||||
{
|
||||
throw new Exceptions\FeatureDisabled('Queue not configured');
|
||||
}
|
||||
|
||||
return $driver->getTask($blocking);
|
||||
/**
|
||||
* Cancel a scheduled task.
|
||||
*
|
||||
* @param int $task_srl
|
||||
* @return bool
|
||||
*/
|
||||
public static function cancelScheduledTask(int $task_srl): bool
|
||||
{
|
||||
$driver = self::getDbDriver();
|
||||
return $driver->cancelScheduledTask($task_srl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -165,7 +230,80 @@ class Queue
|
|||
}
|
||||
|
||||
/**
|
||||
* Process the queue.
|
||||
* Check the interval syntax.
|
||||
*
|
||||
* This method returns true if the interval string is well-formed,
|
||||
* and false otherwise. However, it does not check that all the numbers
|
||||
* are in the correct range (e.g. 0-59 for minutes).
|
||||
*
|
||||
* @param string $interval
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkIntervalSyntax(string $interval): bool
|
||||
{
|
||||
$parts = preg_split('/\s+/', $interval);
|
||||
if (!$parts || count($parts) !== 5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
foreach ($parts as $part)
|
||||
{
|
||||
if (!preg_match('!^(?:\\*(?:/\d+)?|\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*)$!', $part))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an interval string check it against a timestamp.
|
||||
*
|
||||
* This method returns true if the interval covers the given timestamp,
|
||||
* and false otherwise.
|
||||
*
|
||||
* @param string $interval
|
||||
* @param ?int $time
|
||||
* @return bool
|
||||
*/
|
||||
public static function parseInterval(string $interval, ?int $time): bool
|
||||
{
|
||||
$parts = preg_split('/\s+/', $interval);
|
||||
if (!$parts || count($parts) !== 5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$current_time = explode(' ', date('i G j n w', $time ?? time()));
|
||||
foreach ($parts as $i => $part)
|
||||
{
|
||||
$subparts = explode(',', $part);
|
||||
foreach ($subparts as $subpart)
|
||||
{
|
||||
if ($subpart === '*' || ltrim($subpart, '0') === ltrim($current_time[$i], '0'))
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
if ($subpart === '7' && $i === 4 && intval($current_time[$i], 10) === 0)
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
if (preg_match('!^\\*/(\d+)?$!', $subpart, $matches) && ($div = intval($matches[1], 10)) && (intval($current_time[$i], 10) % $div === 0))
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
if (preg_match('!^(\d+)-(\d+)$!', $subpart, $matches) && intval($current_time[$i], 10) >= intval($matches[1], 10) && intval($current_time[$i], 10) <= intval($matches[2], 10))
|
||||
{
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process queued and scheduled tasks.
|
||||
*
|
||||
* This will usually be called by a separate script, run every minute
|
||||
* through an external scheduler such as crontab or systemd.
|
||||
|
|
@ -173,115 +311,54 @@ class Queue
|
|||
* If you are on a shared hosting service, you may also call a URL
|
||||
* using a "web cron" service provider.
|
||||
*
|
||||
* @param int $index
|
||||
* @param int $count
|
||||
* @param int $timeout
|
||||
* @return void
|
||||
*/
|
||||
public static function process(int $timeout): void
|
||||
public static function process(int $index, int $count, int $timeout): void
|
||||
{
|
||||
// This part will run in a loop until timeout.
|
||||
$process_start_time = microtime(true);
|
||||
|
||||
// Get default driver instance.
|
||||
$driver_name = config('queue.driver');
|
||||
$driver = self::getDriver($driver_name);
|
||||
if (!$driver_name || !$driver)
|
||||
{
|
||||
throw new Exceptions\FeatureDisabled('Queue not configured');
|
||||
}
|
||||
|
||||
// Process scheduled tasks.
|
||||
if ($index === 0)
|
||||
{
|
||||
$db_driver = self::getDbDriver();
|
||||
$tasks = $db_driver->getScheduledTasks('once');
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
self::_executeTask($task);
|
||||
}
|
||||
}
|
||||
if ($index === 1 || $count < 2)
|
||||
{
|
||||
$db_driver = self::getDbDriver();
|
||||
$tasks = $db_driver->getScheduledTasks('interval');
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
$db_driver->updateLastRunTimestamp($task);
|
||||
self::_executeTask($task);
|
||||
}
|
||||
}
|
||||
|
||||
// Process queued tasks.
|
||||
while (true)
|
||||
{
|
||||
// Get a task from the driver.
|
||||
// Get a task from the driver, with a 1 second delay at maximum.
|
||||
$loop_start_time = microtime(true);
|
||||
$task = self::getTask(1);
|
||||
|
||||
// Wait 1 second and loop back.
|
||||
$task = $driver->getNextTask(1);
|
||||
if ($task)
|
||||
{
|
||||
// Find the handler for the task.
|
||||
$task->handler = trim($task->handler, '\\()');
|
||||
$handler = null;
|
||||
try
|
||||
{
|
||||
if (preg_match('/^(?:\\\\)?([\\\\\\w]+)::(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$method_name = $matches[2];
|
||||
if (class_exists($class_name) && method_exists($class_name, $method_name))
|
||||
{
|
||||
$handler = [$class_name, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^(?:\\\\)?([\\\\\\w]+)::(\\w+)(?:\(\))?->(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$initializer_name = $matches[2];
|
||||
$method_name = $matches[3];
|
||||
if (class_exists($class_name) && method_exists($class_name, $initializer_name))
|
||||
{
|
||||
$obj = $class_name::$initializer_name();
|
||||
if (method_exists($obj, $method_name))
|
||||
{
|
||||
$handler = [$obj, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^new (?:\\\\)?([\\\\\\w]+)(?:\(\))?->(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$method_name = $matches[2];
|
||||
if (class_exists($class_name) && method_exists($class_name, $method_name))
|
||||
{
|
||||
$obj = new $class_name();
|
||||
$handler = [$obj, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function_exists('\\' . $task->handler))
|
||||
{
|
||||
$handler = '\\' . $task->handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Throwable $th)
|
||||
{
|
||||
error_log(vsprintf('RxQueue: task handler %s could not be accessed: %s in %s:%d', [
|
||||
$task->handler,
|
||||
get_class($th),
|
||||
$th->getFile(),
|
||||
$th->getLine(),
|
||||
]));
|
||||
}
|
||||
|
||||
// Call the handler.
|
||||
try
|
||||
{
|
||||
if ($handler)
|
||||
{
|
||||
call_user_func($handler, $task->args, $task->options);
|
||||
}
|
||||
}
|
||||
catch (\Throwable $th)
|
||||
{
|
||||
error_log(vsprintf('RxQueue: task handler %s threw %s in %s:%d', [
|
||||
$task->handler,
|
||||
get_class($th),
|
||||
$th->getFile(),
|
||||
$th->getLine(),
|
||||
]));
|
||||
}
|
||||
self::_executeTask($task);
|
||||
}
|
||||
|
||||
// If the timeout is imminent, break the loop.
|
||||
|
|
@ -299,4 +376,107 @@ class Queue
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a task.
|
||||
*
|
||||
* @param object $task
|
||||
* @return void
|
||||
*/
|
||||
protected static function _executeTask(object $task): void
|
||||
{
|
||||
// Find the handler for the task.
|
||||
$task->handler = trim($task->handler, '\\()');
|
||||
$handler = null;
|
||||
try
|
||||
{
|
||||
if (preg_match('/^(?:\\\\)?([\\\\\\w]+)::(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$method_name = $matches[2];
|
||||
if (class_exists($class_name) && method_exists($class_name, $method_name))
|
||||
{
|
||||
$handler = [$class_name, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^(?:\\\\)?([\\\\\\w]+)::(\\w+)(?:\(\))?->(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$initializer_name = $matches[2];
|
||||
$method_name = $matches[3];
|
||||
if (class_exists($class_name) && method_exists($class_name, $initializer_name))
|
||||
{
|
||||
$obj = $class_name::$initializer_name();
|
||||
if (method_exists($obj, $method_name))
|
||||
{
|
||||
$handler = [$obj, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/^new (?:\\\\)?([\\\\\\w]+)(?:\(\))?->(\\w+)$/', $task->handler, $matches))
|
||||
{
|
||||
$class_name = '\\' . $matches[1];
|
||||
$method_name = $matches[2];
|
||||
if (class_exists($class_name) && method_exists($class_name, $method_name))
|
||||
{
|
||||
$obj = new $class_name();
|
||||
$handler = [$obj, $method_name];
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function_exists('\\' . $task->handler))
|
||||
{
|
||||
$handler = '\\' . $task->handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_log('RxQueue: task handler not found: ' . $task->handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Throwable $th)
|
||||
{
|
||||
error_log(vsprintf('RxQueue: task handler %s could not be accessed: %s in %s:%d', [
|
||||
$task->handler,
|
||||
get_class($th),
|
||||
$th->getFile(),
|
||||
$th->getLine(),
|
||||
]));
|
||||
}
|
||||
|
||||
// Call the handler.
|
||||
try
|
||||
{
|
||||
if ($handler)
|
||||
{
|
||||
call_user_func($handler, $task->args, $task->options);
|
||||
}
|
||||
}
|
||||
catch (\Throwable $th)
|
||||
{
|
||||
error_log(vsprintf('RxQueue: task handler %s threw %s in %s:%d', [
|
||||
$task->handler,
|
||||
get_class($th),
|
||||
$th->getFile(),
|
||||
$th->getLine(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ class Session
|
|||
\Context::displayErrorPage('SSO Error', 'ERR_INVALID_SSO_REQUEST', 400);
|
||||
exit;
|
||||
}
|
||||
if (!URL::isInternalUrl($sso_request) || !URL::isInternalURL($_SERVER['HTTP_REFERER']))
|
||||
if (!URL::isInternalUrl($sso_request) || !URL::isInternalURL($_SERVER['HTTP_REFERER'] ?? ''))
|
||||
{
|
||||
\Context::displayErrorPage('SSO Error', 'ERR_INVALID_SSO_REQUEST', 400);
|
||||
exit;
|
||||
|
|
|
|||
|
|
@ -260,10 +260,10 @@ class Storage
|
|||
* @param string $filename
|
||||
* @param string|resource $content
|
||||
* @param string $mode (optional)
|
||||
* @param int $perms (optional)
|
||||
* @param ?int $perms (optional)
|
||||
* @return string|false
|
||||
*/
|
||||
public static function write(string $filename, $content, string $mode = 'w', int $perms = null)
|
||||
public static function write(string $filename, $content, string $mode = 'w', ?int $perms = null)
|
||||
{
|
||||
$filename = rtrim($filename, '/\\');
|
||||
$destination_dir = dirname($filename);
|
||||
|
|
|
|||
|
|
@ -694,12 +694,12 @@ class Template
|
|||
}
|
||||
|
||||
// If any of the variables seems to be an array or object, it's $vars.
|
||||
if (!is_scalar($media_type))
|
||||
if (!is_scalar($media_type ?? ''))
|
||||
{
|
||||
$vars = $media_type;
|
||||
$media_type = null;
|
||||
}
|
||||
if (!is_scalar($index))
|
||||
if (!is_scalar($index ?? ''))
|
||||
{
|
||||
$vars = $index;
|
||||
$index = null;
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ interface QueueInterface
|
|||
public function addTask(string $handler, ?object $args = null, ?object $options = null): int;
|
||||
|
||||
/**
|
||||
* Get the first task.
|
||||
* Get the next task from the queue.
|
||||
*
|
||||
* @param int $blocking
|
||||
* @return ?object
|
||||
*/
|
||||
public function getTask(int $blocking = 0): ?object;
|
||||
public function getNextTask(int $blocking = 0): ?object;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace Rhymix\Framework\Drivers\Queue;
|
|||
|
||||
use Rhymix\Framework\DB as RFDB;
|
||||
use Rhymix\Framework\Drivers\QueueInterface;
|
||||
use Rhymix\Framework\Queue;
|
||||
|
||||
/**
|
||||
* The DB queue driver.
|
||||
|
|
@ -99,12 +100,72 @@ class DB implements QueueInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the first task.
|
||||
* Add a task to be executed at a specific time.
|
||||
*
|
||||
* @param int $time
|
||||
* @param string $handler
|
||||
* @param ?object $args
|
||||
* @param ?object $options
|
||||
* @return int
|
||||
*/
|
||||
public function addTaskAt(int $time, string $handler, ?object $args = null, ?object $options = null): int
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$task_srl = getNextSequence();
|
||||
$stmt = $oDB->prepare(trim(<<<END
|
||||
INSERT INTO task_schedule
|
||||
(task_srl, task_type, first_run, handler, args, options, regdate)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
END));
|
||||
$result = $stmt->execute([
|
||||
$task_srl,
|
||||
'once',
|
||||
date('Y-m-d H:i:s', $time),
|
||||
$handler,
|
||||
serialize($args),
|
||||
serialize($options),
|
||||
date('Y-m-d H:i:s'),
|
||||
]);
|
||||
return $result ? $task_srl : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a task to be executed at an interval.
|
||||
*
|
||||
* @param string $interval
|
||||
* @param string $handler
|
||||
* @param ?object $args
|
||||
* @param ?object $options
|
||||
* @return int
|
||||
*/
|
||||
public function addTaskAtInterval(string $interval, string $handler, ?object $args = null, ?object $options = null): int
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$task_srl = getNextSequence();
|
||||
$stmt = $oDB->prepare(trim(<<<END
|
||||
INSERT INTO task_schedule
|
||||
(task_srl, task_type, run_interval, handler, args, options, regdate)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
END));
|
||||
$result = $stmt->execute([
|
||||
$task_srl,
|
||||
'interval',
|
||||
$interval,
|
||||
$handler,
|
||||
serialize($args),
|
||||
serialize($options),
|
||||
date('Y-m-d H:i:s'),
|
||||
]);
|
||||
return $result ? $task_srl : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next task from the queue.
|
||||
*
|
||||
* @param int $blocking
|
||||
* @return ?object
|
||||
*/
|
||||
public function getTask(int $blocking = 0): ?object
|
||||
public function getNextTask(int $blocking = 0): ?object
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$oDB->beginTransaction();
|
||||
|
|
@ -128,4 +189,123 @@ class DB implements QueueInterface
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a scheduled task by its task_srl.
|
||||
*
|
||||
* @param int $task_srl
|
||||
* @return ?object
|
||||
*/
|
||||
public function getScheduledTask(int $task_srl): ?object
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$stmt = $oDB->query('SELECT * FROM task_schedule WHERE task_srl = ?', [$task_srl]);
|
||||
$task = $stmt->fetchObject();
|
||||
$stmt->closeCursor();
|
||||
|
||||
if ($task)
|
||||
{
|
||||
$task->args = unserialize($task->args);
|
||||
$task->options = unserialize($task->options);
|
||||
return $task;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get scheduled tasks.
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function getScheduledTasks(string $type): array
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$tasks = [];
|
||||
$task_srls = [];
|
||||
|
||||
// Get tasks to be executed once at the current time.
|
||||
if ($type === 'once')
|
||||
{
|
||||
$oDB->beginTransaction();
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
$stmt = $oDB->query("SELECT * FROM task_schedule WHERE task_type = 'once' AND first_run <= ? ORDER BY first_run FOR UPDATE", [$timestamp]);
|
||||
while ($task = $stmt->fetchObject())
|
||||
{
|
||||
$task->args = unserialize($task->args);
|
||||
$task->options = unserialize($task->options);
|
||||
$tasks[] = $task;
|
||||
$task_srls[] = $task->task_srl;
|
||||
}
|
||||
if (count($task_srls))
|
||||
{
|
||||
$stmt = $oDB->prepare('DELETE FROM task_schedule WHERE task_srl IN (' . implode(', ', array_fill(0, count($task_srls), '?')) . ')');
|
||||
$stmt->execute($task_srls);
|
||||
}
|
||||
$oDB->commit();
|
||||
}
|
||||
|
||||
// Get tasks to be executed at an interval.
|
||||
if ($type === 'interval')
|
||||
{
|
||||
$stmt = $oDB->query("SELECT task_srl, run_interval FROM task_schedule WHERE task_type = 'interval' ORDER BY task_srl");
|
||||
while ($task = $stmt->fetchObject())
|
||||
{
|
||||
if (Queue::parseInterval($task->run_interval, time()))
|
||||
{
|
||||
$task_srls[] = $task->task_srl;
|
||||
}
|
||||
}
|
||||
if (count($task_srls))
|
||||
{
|
||||
$stmt = $oDB->prepare('SELECT * FROM task_schedule WHERE task_srl IN (' . implode(', ', array_fill(0, count($task_srls), '?')) . ')');
|
||||
$stmt->execute($task_srls);
|
||||
while ($task = $stmt->fetchObject())
|
||||
{
|
||||
$task->args = unserialize($task->args);
|
||||
$task->options = unserialize($task->options);
|
||||
$tasks[] = $task;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the last executed timestamp of a scheduled task.
|
||||
*
|
||||
* @param object $task
|
||||
* @return void
|
||||
*/
|
||||
public function updateLastRunTimestamp(object $task): void
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
if ($task->first_run)
|
||||
{
|
||||
$stmt = $oDB->prepare('UPDATE task_schedule SET last_run = ?, run_count = run_count + 1 WHERE task_srl = ?');
|
||||
$stmt->execute([date('Y-m-d H:i:s'), $task->task_srl]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$stmt = $oDB->prepare('UPDATE task_schedule SET first_run = ?, last_run = ?, run_count = run_count + 1 WHERE task_srl = ?');
|
||||
$stmt->execute([date('Y-m-d H:i:s'), date('Y-m-d H:i:s'), $task->task_srl]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a scheduled task.
|
||||
*
|
||||
* @param int $task_srl
|
||||
* @return bool
|
||||
*/
|
||||
public function cancelScheduledTask(int $task_srl): bool
|
||||
{
|
||||
$oDB = RFDB::getInstance();
|
||||
$stmt = $oDB->query('DELETE FROM task_schedule WHERE task_srl = ?', [$task_srl]);
|
||||
return ($stmt && $stmt->rowCount()) ? true : false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,12 +105,12 @@ class Dummy implements QueueInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the first task.
|
||||
* Get the next task from the queue.
|
||||
*
|
||||
* @param int $blocking
|
||||
* @return ?object
|
||||
*/
|
||||
public function getTask(int $blocking = 0): ?object
|
||||
public function getNextTask(int $blocking = 0): ?object
|
||||
{
|
||||
$result = $this->_dummy_queue;
|
||||
$this->_dummy_queue = null;
|
||||
|
|
|
|||
|
|
@ -155,12 +155,12 @@ class Redis implements QueueInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the first task.
|
||||
* Get the next task from the queue.
|
||||
*
|
||||
* @param int $blocking
|
||||
* @return ?object
|
||||
*/
|
||||
public function getTask(int $blocking = 0): ?object
|
||||
public function getNextTask(int $blocking = 0): ?object
|
||||
{
|
||||
if ($this->_conn)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -101,8 +101,8 @@ class FilenameFilter
|
|||
{
|
||||
$images = 'gif|jpe?g|jfif|png|webp';
|
||||
$audios = 'mp3|wav|ogg|flac|aac';
|
||||
$videos = 'mp4|webm|ogv';
|
||||
$legacy = 'avi|as[fx]|flv|m4[av]|midi?|mkv|moo?v|mpe?g|qt|r[am]m?|wm[av]';
|
||||
$videos = 'mp4|webm';
|
||||
$legacy = 'avi|as[fx]|flv|m4[av]|midi?|mkv|moo?v|mpe?g|qt|r[am]m?|wm[av]|ogv';
|
||||
|
||||
if ($include_multimedia)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class IpFilter
|
|||
*/
|
||||
public static function getCloudFlareRealIP()
|
||||
{
|
||||
if (!isset($_SERVER['HTTP_CF_CONNECTING_IP']))
|
||||
if (!isset($_SERVER['HTTP_CF_CONNECTING_IP']) || isset($_SERVER['HTTP_CF_WORKER']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ class DBQueryParser extends BaseParser
|
|||
$orderby->default = ($attribs['default'] ?? null) ?: null;
|
||||
$orderby->order_var = ($attribs['order'] ?? null) ?: null;
|
||||
$orderby->order_default = strtoupper($attribs['orderdefault'] ?? '') === 'DESC' ? 'DESC' : 'ASC';
|
||||
$orderby->ifvar = trim($attribs['if'] ?? '') ?: null;
|
||||
$query->navigation->orderby[] = $orderby;
|
||||
}
|
||||
foreach (['list_count', 'page_count', 'page', 'offset'] as $key)
|
||||
|
|
@ -207,6 +208,7 @@ class DBQueryParser extends BaseParser
|
|||
$query->navigation->{$key} = new DBQuery\VariableBase;
|
||||
$query->navigation->{$key}->var = trim($tag['var'] ?? '') ?: null;
|
||||
$query->navigation->{$key}->default = trim($tag['default'] ?? '') ?: null;
|
||||
$query->navigation->{$key}->ifvar = trim($tag['if'] ?? '') ?: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,4 +11,5 @@ class OrderBy extends VariableBase
|
|||
public $default;
|
||||
public $order_var;
|
||||
public $order_default = 'ASC';
|
||||
public $ifvar;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,11 @@ class Query extends VariableBase
|
|||
// Compose the ORDER BY clause.
|
||||
if ($this->navigation && count($this->navigation->orderby) && !$count_only)
|
||||
{
|
||||
$result .= ' ORDER BY ' . $this->_arrangeOrderBy($this->navigation);
|
||||
$order_by = $this->_arrangeOrderBy($this->navigation);
|
||||
if ($order_by !== '')
|
||||
{
|
||||
$result .= ' ORDER BY ' . $order_by;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the LIMIT/OFFSET clause.
|
||||
|
|
@ -607,9 +611,15 @@ class Query extends VariableBase
|
|||
// Process each column definition.
|
||||
foreach ($navigation->orderby as $orderby)
|
||||
{
|
||||
// Skip
|
||||
if ($orderby->ifvar && empty($this->_args[$orderby->ifvar]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the name of the column or expression to order by.
|
||||
$column_name = '';
|
||||
list($is_expression, $column_name) = $orderby->getValue($this->_args);
|
||||
list($column_name, $is_expression, $is_default_value) = $orderby->getValue($this->_args);
|
||||
if (!$column_name)
|
||||
{
|
||||
continue;
|
||||
|
|
@ -618,6 +628,10 @@ class Query extends VariableBase
|
|||
{
|
||||
$column_name = self::quoteName($column_name);
|
||||
}
|
||||
elseif (!$is_default_value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the ordering (ASC or DESC).
|
||||
if (preg_match('/^(ASC|DESC)$/i', $orderby->order_var ?: '', $matches))
|
||||
|
|
@ -648,23 +662,34 @@ class Query extends VariableBase
|
|||
*/
|
||||
protected function _arrangeLimitOffset(Navigation $navigation): string
|
||||
{
|
||||
$list_count = 0;
|
||||
$page = 0;
|
||||
$offset = 0;
|
||||
|
||||
// Get the list count.
|
||||
list($is_expression, $list_count) = $navigation->list_count->getValue($this->_args);
|
||||
if (!$navigation->list_count->ifvar || !empty($this->_args[$navigation->list_count->ifvar]))
|
||||
{
|
||||
$list_count = $navigation->list_count->getValue($this->_args)[0];
|
||||
}
|
||||
if ($list_count <= 0)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
$page = 0;
|
||||
$offset = 0;
|
||||
|
||||
// Get the offset from the page or offset variable.
|
||||
if ($navigation->page)
|
||||
{
|
||||
list($is_expression, $page) = $navigation->page->getValue($this->_args);
|
||||
if (!$navigation->page->ifvar || !empty($this->_args[$navigation->page->ifvar]))
|
||||
{
|
||||
$page = $navigation->page->getValue($this->_args)[0];
|
||||
}
|
||||
}
|
||||
if ($navigation->offset)
|
||||
{
|
||||
list($is_expression, $offset) = $navigation->offset->getValue($this->_args);
|
||||
if (!$navigation->offset->ifvar || !empty($this->_args[$navigation->offset->ifvar]))
|
||||
{
|
||||
$offset = $navigation->offset->getValue($this->_args)[0];
|
||||
}
|
||||
}
|
||||
|
||||
// If page is available, set the offset and require pagination for this query.
|
||||
|
|
|
|||
|
|
@ -281,11 +281,17 @@ class VariableBase
|
|||
/**
|
||||
* Get the current value, falling back to the default value if necessary.
|
||||
*
|
||||
* Format of return value: [value, is_expression, is_default_value]
|
||||
*
|
||||
* @param array $args
|
||||
* @return array
|
||||
*/
|
||||
public function getValue(array $args): array
|
||||
{
|
||||
$value = null;
|
||||
$is_expression = false;
|
||||
$is_default_value = false;
|
||||
|
||||
if ($this->var && Query::isValidVariable($args[$this->var] ?? null, $this instanceof ColumnWrite))
|
||||
{
|
||||
if ($args[$this->var] === '')
|
||||
|
|
@ -293,35 +299,32 @@ class VariableBase
|
|||
if ($this instanceof ColumnWrite)
|
||||
{
|
||||
$value = $args[$this->var];
|
||||
$is_expression = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
$is_default_value = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$is_expression = false;
|
||||
$value = $args[$this->var];
|
||||
}
|
||||
}
|
||||
elseif ($this->default !== null)
|
||||
{
|
||||
list($is_expression, $value) = $this->getDefaultValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
$is_expression = null;
|
||||
$value = null;
|
||||
$is_default_value = true;
|
||||
}
|
||||
|
||||
return [$is_expression, $value];
|
||||
return [$value, $is_expression, $is_default_value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value of this variable.
|
||||
*
|
||||
* Format of return value: [is_expression, value]
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultValue(): array
|
||||
|
|
|
|||
|
|
@ -692,7 +692,7 @@ function utf8_normalize_spaces($str, bool $multiline = false): string
|
|||
*/
|
||||
function utf8_trim($str): string
|
||||
{
|
||||
return preg_replace('/^[\s\pZ\pC]+|[\s\pZ\pC]+$/u', '', (string)$str);
|
||||
return preg_replace('/^[\s\pZ\pC]+|[\s\pZ\pC]+$/u', '', (string)$str) ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@
|
|||
else if (filename.match(/\.(mp3|wav|ogg|flac|aac)$/i) && opt.autoinsertTypes.audio) {
|
||||
temp_code = self.generateHtml($container, result);
|
||||
}
|
||||
else if (filename.match(/\.(mp4|webm|ogv)$/i) && opt.autoinsertTypes.video) {
|
||||
else if (filename.match(/\.(mp4|webm)$/i) && opt.autoinsertTypes.video) {
|
||||
temp_code = self.generateHtml($container, result);
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +365,7 @@
|
|||
html = '<audio src="' + file.download_url + '" controls' +
|
||||
' data-file-srl="' + file.file_srl + '" />';
|
||||
}
|
||||
else if (filename.match(/\.(mp4|webm|ogv)$/i)) {
|
||||
else if (filename.match(/\.(mp4|webm)$/i)) {
|
||||
if (file.original_type === 'image/gif') {
|
||||
html = '<video src="' + file.download_url + '"'
|
||||
+ ' autoplay loop muted playsinline data-file-srl="' + file.file_srl + '" />';
|
||||
|
|
@ -519,7 +519,7 @@
|
|||
|
||||
if(file.thumbnail_filename) {
|
||||
file.thumbnail_url = file.thumbnail_filename;
|
||||
if(/\.(mp4|webm|ogv)$/i.test(file.source_filename)) {
|
||||
if(/\.(mp4|webm)$/i.test(file.source_filename)) {
|
||||
result_image.push(template_fileimte_video(file));
|
||||
} else {
|
||||
result_image.push(template_fileimte_image(file));
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ $lang->cmd_vote = 'Upvote';
|
|||
$lang->cmd_vote_down = 'Downvote';
|
||||
$lang->cmd_declare = 'Report';
|
||||
$lang->cmd_cancel_declare = 'Cancel Report';
|
||||
$lang->cmd_cancel_vote = 'Cancel Upvote';
|
||||
$lang->cmd_cancel_vote_down = 'Cancel Downvote';
|
||||
$lang->cmd_vote_config = 'Voting Configuration';
|
||||
$lang->cmd_declare_config = 'Reporting Configuration';
|
||||
$lang->cmd_declared_list = 'Reported List';
|
||||
|
|
@ -150,6 +152,7 @@ $lang->colorset = 'Colorset';
|
|||
$lang->mobile_colorset = 'Mobile Colorset';
|
||||
$lang->extra_vars = 'Extra Input Fields';
|
||||
$lang->domain = 'Domain Name';
|
||||
$lang->deleted_domain = 'Deleted Domain';
|
||||
$lang->url = 'URL';
|
||||
$lang->document_url = 'Article URL';
|
||||
$lang->trackback_url = 'Trackback URL';
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ $lang->colorset = '컬러셋';
|
|||
$lang->mobile_colorset = '모바일 컬러셋';
|
||||
$lang->extra_vars = '확장 변수';
|
||||
$lang->domain = '도메인';
|
||||
$lang->deleted_domain = '삭제된 도메인';
|
||||
$lang->url = 'URL';
|
||||
$lang->document_url = '게시글 주소';
|
||||
$lang->trackback_url = '엮인글 주소';
|
||||
|
|
|
|||
|
|
@ -495,7 +495,8 @@ function cut_str($string, $cut_size = 0, $tail = '...'): string
|
|||
if(isset($GLOBALS['use_mb_strimwidth']) || function_exists('mb_strimwidth'))
|
||||
{
|
||||
$GLOBALS['use_mb_strimwidth'] = TRUE;
|
||||
return mb_strimwidth($string, 0, $cut_size + 4, $tail, 'utf-8');
|
||||
$string = html_entity_decode($string);
|
||||
return escape(mb_strimwidth($string, 0, $cut_size + 4, $tail, 'utf-8'));
|
||||
}
|
||||
|
||||
$chars = array(12, 4, 3, 5, 7, 7, 11, 8, 4, 5, 5, 6, 6, 4, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 6, 8, 6, 10, 8, 8, 9, 8, 8, 7, 9, 8, 3, 6, 7, 7, 11, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 8, 6, 11, 6, 6, 6, 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 7, 3, 7, 6, 10, 6, 6, 7, 6, 6, 6, 9);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ if (PHP_SAPI === 'cli' && $process_count > 1 && function_exists('pcntl_fork') &&
|
|||
}
|
||||
elseif ($pid == 0)
|
||||
{
|
||||
Rhymix\Framework\Queue::process($timeout);
|
||||
Rhymix\Framework\Queue::process($i, $process_count, $timeout);
|
||||
exit;
|
||||
}
|
||||
else
|
||||
|
|
@ -96,7 +96,7 @@ if (PHP_SAPI === 'cli' && $process_count > 1 && function_exists('pcntl_fork') &&
|
|||
}
|
||||
else
|
||||
{
|
||||
Rhymix\Framework\Queue::process($timeout);
|
||||
Rhymix\Framework\Queue::process(0, 1, $timeout);
|
||||
}
|
||||
|
||||
// If called over the network, display a simple OK message to indicate success.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<!-- JS -->
|
||||
@foreach (Context::getJsFile('head', true) as $js_file)
|
||||
<script src="{!! $js_file['file'] !!}"></script>
|
||||
<script src="{!! $js_file['file'] !!}"{!! $js_file['attrs'] !!}></script>
|
||||
@endforeach
|
||||
|
||||
<!-- RSS -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue