diff --git a/lib/Froxlor/Ajax/Ajax.php b/lib/Froxlor/Ajax/Ajax.php index 11aa92e6..90b2d885 100644 --- a/lib/Froxlor/Ajax/Ajax.php +++ b/lib/Froxlor/Ajax/Ajax.php @@ -4,6 +4,7 @@ namespace Froxlor\Ajax; use Exception; use Froxlor\Http\HttpClient; +use Froxlor\PhpHelper; use Froxlor\Settings; use Froxlor\UI\Panel\UI; @@ -24,160 +25,190 @@ use Froxlor\UI\Panel\UI; */ class Ajax { - protected string $session; - protected string $action; - protected string $theme; + protected string $session; + protected string $action; + protected string $theme; - /** - * @throws Exception - */ - public function __construct() - { - $this->session = $_GET['s'] ?? $_POST['s'] ?? null; - $this->action = $_GET['action'] ?? $_POST['action'] ?? null; - $this->theme = $_GET['theme'] ?? 'Froxlor'; - } + /** + * @throws Exception + */ + public function __construct() + { + $this->session = $_GET['s'] ?? $_POST['s'] ?? null; + $this->action = $_GET['action'] ?? $_POST['action'] ?? null; + $this->theme = $_GET['theme'] ?? 'Froxlor'; + } - /** - * @throws Exception - */ - public function handle() - { - $session = $this->getValidatedSession(); + /** + * @throws Exception + */ + public function handle() + { + $session = $this->getValidatedSession(); - switch ($this->action) { - case 'newsfeed': - return $this->getNewsfeed(); - case 'updatecheck': - return $this->getUpdateCheck($session); - default: - return $this->errorResponse('Action not found!'); - } - } + switch ($this->action) { + case 'newsfeed': + return $this->getNewsfeed(); + case 'updatecheck': + return $this->getUpdateCheck(); + case 'searchsetting': + return $this->searchSetting(); + default: + return $this->errorResponse('Action not found!'); + } + } - public function errorResponse($message, int $response_code = 500) - { - return \Froxlor\Api\Response::jsonErrorResponse($message, $response_code); - } + public function errorResponse($message, int $response_code = 500) + { + return \Froxlor\Api\Response::jsonErrorResponse($message, $response_code); + } - public function jsonResponse($value, int $response_code = 200) - { - return \Froxlor\Api\Response::jsonResponse($value, $response_code); - } + public function jsonResponse($value, int $response_code = 200) + { + return \Froxlor\Api\Response::jsonResponse($value, $response_code); + } - /** - * @throws Exception - */ - private function getValidatedSession(): array - { - $remote_addr = $_SERVER['REMOTE_ADDR']; - if (empty($_SERVER['HTTP_USER_AGENT'])) { - $http_user_agent = 'unknown'; - } else { - $http_user_agent = $_SERVER['HTTP_USER_AGENT']; - } + /** + * @throws Exception + */ + private function getValidatedSession(): array + { + $remote_addr = $_SERVER['REMOTE_ADDR']; + if (empty($_SERVER['HTTP_USER_AGENT'])) { + $http_user_agent = 'unknown'; + } else { + $http_user_agent = $_SERVER['HTTP_USER_AGENT']; + } - $timediff = time() - \Froxlor\Settings::Get('session.sessiontimeout'); - $sel_stmt = \Froxlor\Database\Database::prepare(" + $timediff = time() - \Froxlor\Settings::Get('session.sessiontimeout'); + $sel_stmt = \Froxlor\Database\Database::prepare(" SELECT * FROM `" . TABLE_PANEL_SESSIONS . "` WHERE `hash` = :hash AND `ipaddress` = :ipaddr AND `useragent` = :ua AND `lastactivity` > :timediff "); - $session = \Froxlor\Database\Database::pexecute_first($sel_stmt, [ - 'hash' => $this->session, - 'ipaddr' => $remote_addr, - 'ua' => $http_user_agent, - 'timediff' => $timediff - ]); + $session = \Froxlor\Database\Database::pexecute_first($sel_stmt, [ + 'hash' => $this->session, + 'ipaddr' => $remote_addr, + 'ua' => $http_user_agent, + 'timediff' => $timediff + ]); - if (!$session) { - throw new Exception('Session is not defined!'); - } + if (!$session) { + throw new Exception('Session is not defined!'); + } - return $session; - } + return $session; + } - /** - * @throws Exception - */ - private function getNewsfeed() - { - UI::initTwig(); + /** + * @throws Exception + */ + private function getNewsfeed() + { + UI::initTwig(); - $feed = "https://inside.froxlor.org/news/"; + $feed = "https://inside.froxlor.org/news/"; - // Set custom feed if provided - if (isset($_GET['role']) && $_GET['role'] == "customer") { - $custom_feed = Settings::Get("customer.news_feed_url"); - if (!empty(trim($custom_feed))) { - $feed = $custom_feed; - } - } + // Set custom feed if provided + if (isset($_GET['role']) && $_GET['role'] == "customer") { + $custom_feed = Settings::Get("customer.news_feed_url"); + if (!empty(trim($custom_feed))) { + $feed = $custom_feed; + } + } - // Check for simplexml_load_file - if (!function_exists("simplexml_load_file")) { - return $this->errorResponse( - "Newsfeed not available due to missing php-simplexml extension", - "Please install the php-simplexml extension in order to view our newsfeed." - ); - } + // Check for simplexml_load_file + if (!function_exists("simplexml_load_file")) { + return $this->errorResponse( + "Newsfeed not available due to missing php-simplexml extension", + "Please install the php-simplexml extension in order to view our newsfeed." + ); + } - // Check for curl_version - if (!function_exists('curl_version')) { - return $this->errorResponse( - "Newsfeed not available due to missing php-curl extension", - "Please install the php-curl extension in order to view our newsfeed." - ); - } + // Check for curl_version + if (!function_exists('curl_version')) { + return $this->errorResponse( + "Newsfeed not available due to missing php-curl extension", + "Please install the php-curl extension in order to view our newsfeed." + ); + } - $output = HttpClient::urlGet($feed); - $news = simplexml_load_string(trim($output)); + $output = HttpClient::urlGet($feed); + $news = simplexml_load_string(trim($output)); - // Handle items - if ($news) { - $items = null; + // Handle items + if ($news) { + $items = null; - for ($i = 0; $i < 3; $i++) { - $item = $news->channel->item[$i]; + for ($i = 0; $i < 3; $i++) { + $item = $news->channel->item[$i]; - $title = (string)$item->title; - $link = (string)$item->link; - $date = date("d.m.Y", strtotime($item->pubDate)); - $content = preg_replace("/[\r\n]+/", " ", strip_tags($item->description)); - $content = substr($content, 0, 150) . "..."; + $title = (string)$item->title; + $link = (string)$item->link; + $date = date("d.m.Y", strtotime($item->pubDate)); + $content = preg_replace("/[\r\n]+/", " ", strip_tags($item->description)); + $content = substr($content, 0, 150) . "..."; - $items .= UI::twig()->render($this->theme . '/user/newsfeeditem.html.twig', [ - 'link' => $link, - 'title' => $title, - 'date' => $date, - 'content' => $content - ]); - } + $items .= UI::twig()->render($this->theme . '/user/newsfeeditem.html.twig', [ + 'link' => $link, + 'title' => $title, + 'date' => $date, + 'content' => $content + ]); + } - return $items; - } else { - return $this->errorResponse('No Newsfeeds available at the moment.'); - } - } + return $items; + } else { + return $this->errorResponse('No Newsfeeds available at the moment.'); + } + } - private function getUpdateCheck(array $session) - { - UI::initTwig(); - UI::twig()->addGlobal('s', $this->session); + private function getUpdateCheck() + { + UI::initTwig(); + UI::twig()->addGlobal('s', $this->session); - // TODO: set variables from current session - try { - $json_result = \Froxlor\Api\Commands\Froxlor::getLocal([ - 'adminid' => 1, - 'adminsession' => 1, - 'change_serversettings' => 1, - 'loginname' => 'updatecheck' - ])->checkUpdate(); - $result = json_decode($json_result, true)['data']; - echo UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result); - exit; - } catch (Exception $e) { - \Froxlor\UI\Response::dynamic_error($e->getMessage()); - } - } + // TODO: set variables from current session + try { + $json_result = \Froxlor\Api\Commands\Froxlor::getLocal([ + 'adminid' => 1, + 'adminsession' => 1, + 'change_serversettings' => 1, + 'loginname' => 'updatecheck' + ])->checkUpdate(); + $result = json_decode($json_result, true)['data']; + echo UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result); + exit; + } catch (Exception $e) { + \Froxlor\UI\Response::dynamic_error($e->getMessage()); + } + } + + private function searchSetting() + { + $searchtext = isset($_POST['searchtext']) ? $_POST['searchtext'] : ""; + + $result = []; + if (strlen($searchtext) > 2) { + $settings_data = PhpHelper::loadConfigArrayDir(\Froxlor\Froxlor::getInstallDir() . '/actions/admin/settings/'); + $results = array(); + PhpHelper::recursive_array_search($searchtext, $settings_data, $results); + $processed_setting = array(); + foreach ($results as $pathkey) { + $pk = explode(".", $pathkey); + if (count($pk) > 4) { + $settingkey = $pk[0] . '.' . $pk[1] . '.' . $pk[2] . '.' . $pk[3]; + if (!array_key_exists($settingkey, $processed_setting)) { + $processed_setting[$settingkey] = true; + $sresult = $settings_data[$pk[0]][$pk[1]][$pk[2]][$pk[3]]; + $result[] = [ + 'href' => 'admin_settings.php?page=overview&part=' . $pk[1] . '&em=' . $pk[3], + 'title' => (is_array($sresult['label']) ? $sresult['label']['title'] : $sresult['label']) + ]; + } + } + } + } + echo json_encode($result); + } } diff --git a/lib/Froxlor/PhpHelper.php b/lib/Froxlor/PhpHelper.php index bb9d01af..e135b0d0 100644 --- a/lib/Froxlor/PhpHelper.php +++ b/lib/Froxlor/PhpHelper.php @@ -409,6 +409,19 @@ class PhpHelper return $returnval; } + public static function recursive_array_search($needle, $haystack, &$keys = array(), $currentKey = '') + { + foreach ($haystack as $key => $value) { + $pathkey = empty($currentKey) ? $key : $currentKey . '.' . $key; + if (is_array($value)) { + self::recursive_array_search($needle, $value, $keys, $pathkey); + } else if (stripos($value, $needle) !== false) { + $keys[] = $pathkey; + } + } + return true; + } + /** * function to check a super-global passed by reference * so it gets automatically updated