File src/www/admin/common/search.php from the latest check-in


<?php
namespace Paheko;

use Paheko\Entities\Search as SE;
use Paheko\Search;
use Paheko\Users\Session;

require_once __DIR__ . '/../_inc.php';

if (!defined('Paheko\CURRENT_SEARCH_TARGET') || !array_key_exists(CURRENT_SEARCH_TARGET, SE::TARGETS)) {
	throw new UserException('Cible inconnue');
}

$access_section = CURRENT_SEARCH_TARGET == SE::TARGET_ACCOUNTING ? $session::SECTION_ACCOUNTING : $session::SECTION_USERS;

$session = Session::getInstance();
$session->requireAccess($access_section, Session::ACCESS_READ);

$is_admin = $session->canAccess($access_section, Session::ACCESS_ADMIN);
$can_sql_unprotected = $session->canAccess(Session::SECTION_CONFIG, Session::ACCESS_ADMIN);

if ($access_section === $session::SECTION_USERS) {
	// Only admins of user section can do custom SQL queries
	// to protect access-restricted user fields from being read
	$can_sql = $is_admin;
}
else {
	// anyone can do custom SQL queries in accounting
	$can_sql = true;
}

$id = f('id') ?: qg('id');

if ($id) {
	$s = Search::get($id);

	if (!$s) {
		throw new UserException('Recherche inconnue ou invalide');
	}
}
else {
	$s = new SE;
	$s->target = CURRENT_SEARCH_TARGET;
	$s->created = new \DateTime();
}

$text_query = trim((string) qg('qt'));
$sql_query = trim((string) f('sql'));
$json_query = f('q') ? json_decode(f('q'), true) : null;
$default = false;

if ($text_query !== '') {
	$s->content = json_encode($s->getAdvancedSearch()->simple($text_query, true));
	$s->type = SE::TYPE_JSON;
}
elseif ($sql_query !== '') {
	// Only admins can run custom queries, others can only run saved queries
	$session->requireAccess($access_section, $session::ACCESS_ADMIN);

	if (Session::getInstance()->canAccess($access_section, Session::ACCESS_ADMIN) && f('unprotected')) {
		$s->type = SE::TYPE_SQL_UNPROTECTED;
	}
	else {
		$s->type = SE::TYPE_SQL;
	}

	$s->content = $sql_query;
}
elseif ($json_query !== null) {
	$s->content = json_encode(['groups' => $json_query]);
	$s->type = SE::TYPE_JSON;
}
elseif (!$s->content) {
	$s->content = json_encode($s->getAdvancedSearch()->defaults());
	$s->type = SE::TYPE_JSON;
	$default = true;
}

if (f('to_sql')) {
	$s->transformToSQL();
}

$form->runIf(f('save') || f('save_new'), function () use ($s) {
	if (f('save_new') || !$s->exists()) {
		$s = clone $s;
		$label = $s->type != $s::TYPE_JSON ? 'Recherche SQL du ' : 'Recherche avancée du ';
		$label .= date('d/m/Y à H:i');
		$s->label = $label;
	}

	$s->save();

	$target = $s->target == $s::TARGET_ACCOUNTING ? 'acc' : 'users';
	Utils::redirect(sprintf('!%s/saved_searches.php?edit=%d', $target, $s->id()));
});

$list = $results = $header = $count = null;

if (!$default) {
	try {
		if ($s->type == $s::TYPE_JSON) {
			$list = $s->getDynamicList();
			$list->loadFromQueryString();
			$count = $list->count();
		}
		else {
			if (!empty($_POST['_export'])) {
				$s->export($_POST['_export']);
				exit;
			}

			$header = $s->getHeader();
			$count = $s->countResults(false);
			$results = $s->iterateResults();
			$tpl->assign('has_limit', $s->hasLimit());
		}
	}
	catch (UserException $e) {
		$form->addError($e->getMessage());
	}
}

$schema = $s->schema();
$columns = $s->getAdvancedSearch()->columns();
$columns = array_filter($columns, fn($c) => $c['label'] ?? null && $c['type'] ?? null); // remove columns only for dynamiclist

$tpl->assign(compact('s', 'list', 'header', 'results', 'columns', 'count', 'is_admin', 'schema', 'can_sql', 'can_sql_unprotected'));

if ($s->target == $s::TARGET_ACCOUNTING) {
	$tpl->display('acc/search.tpl');
}
else {
	$tpl->display('users/search.tpl');
}