MVC - VPN / IPsec. Move array search method to more generic searchRecordsetBase() in ApiControllerBase, which is modelled similar to how searchBase() is implemented in ApiMutableModelControllerBase.

could help https://github.com/opnsense/core/pull/5465
This commit is contained in:
Ad Schellevis 2022-03-25 21:35:43 +01:00
parent 0d5d9f9ba9
commit 2e747acda9
3 changed files with 66 additions and 46 deletions

View File

@ -39,6 +39,68 @@ use OPNsense\Auth\AuthenticationFactory;
*/
class ApiControllerBase extends ControllerRoot
{
/***
* Recordset (array in array) search wrapper
* @param string $path path to search, relative to this model
* @param array $fields fieldnames to search through in result
* @param string|null $defaultSort default sort field name
* @param null|function $filter_funct additional filter callable
* @param int $sort_flags sorting behavior
* @return array
*/
protected function searchRecordsetBase(
$records,
$fields = null,
$defaultSort = null,
$filter_funct = null,
$sort_flags = SORT_NATURAL)
{
$itemsPerPage = intval($this->request->getPost('rowCount', 'int', 9999));
$currentPage = intval($this->request->getPost('current', 'int', 1));
$offset = ($currentPage - 1) * $itemsPerPage;
$entry_keys = array_keys($records);
$searchPhrase = (string)$this->request->getPost('searchPhrase', null, '');
$entry_keys = array_filter($entry_keys, function ($key) use ($searchPhrase, $filter_funct, $fields, $records) {
if (is_callable($filter_funct) && !$filter_funct($record)) {
// not applicable according to $filter_funct()
return false;
} elseif (!empty($searchPhrase)) {
foreach ($records[$key] as $itemkey => $itemval) {
if (stripos($itemval, $searchPhrase) !== false && (empty($fields) || in_array($itemkey, $fields))) {
return true;
}
}
return false;
} else {
return true;
}
});
$formatted = array_map(function ($value) use (&$records) {
foreach ($records[$value] as $ekey => $evalue) {
$item[$ekey] = $evalue;
}
return $item;
}, array_slice($entry_keys, $offset, $itemsPerPage));
if ($this->request->hasPost('sort') && is_array($this->request->getPost('sort'))) {
$keys = array_keys($this->request->getPost('sort'));
$order = $this->request->getPost('sort')[$keys[0]];
$keys = array_column($formatted, $keys[0]);
array_multisort($keys, $order == 'asc' ? SORT_ASC : SORT_DESC, $sort_flags, $formatted);
} elseif (!empty($defaultSort)) {
$keys = array_column($formatted, $defaultSort);
array_multisort($keys, SORT_ASC, $sort_flags, $formatted);
}
return [
'total' => count($entry_keys),
'rowCount' => $itemsPerPage,
'current' => $currentPage,
'rows' => $formatted,
];
}
/**
* parse raw json type content to POST data depending on content type
* (only for api calls)

View File

@ -1,8 +1,8 @@
<?php
/*
* Copyright (C) 2016-2022 Deciso B.V.
* Copyright (C) 2016 IT-assistans Sverige AB
* Copyright (C) 2016 Deciso B.V.
* Copyright (C) 2018 Fabian Franz
* All rights reserved.
*

View File

@ -1,7 +1,7 @@
<?php
/*
* Copyright (C) 2021 Deciso B.V.
* Copyright (C) 2021-2022 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,48 +38,6 @@ use OPNsense\Core\Config;
*/
class TunnelController extends ApiControllerBase
{
/***
* generic legacy search action, reads post variables for filters and page navigation.
*/
private function search($records)
{
$itemsPerPage = intval($this->request->getPost('rowCount', 'int', 9999));
$currentPage = intval($this->request->getPost('current', 'int', 1));
$offset = ($currentPage - 1) * $itemsPerPage;
$entry_keys = array_keys($records);
if ($this->request->hasPost('searchPhrase') && $this->request->getPost('searchPhrase') !== '') {
$searchPhrase = (string)$this->request->getPost('searchPhrase');
$entry_keys = array_filter($entry_keys, function ($key) use ($searchPhrase, $records) {
foreach ($records[$key] as $itemval) {
if (stripos($itemval, $searchPhrase) !== false) {
return true;
}
}
return false;
});
}
$formatted = array_map(function ($value) use (&$records) {
foreach ($records[$value] as $ekey => $evalue) {
$item[$ekey] = $evalue;
}
return $item;
}, array_slice($entry_keys, $offset, $itemsPerPage));
if ($this->request->hasPost('sort') && is_array($this->request->getPost('sort'))) {
$keys = array_keys($this->request->getPost('sort'));
$order = $this->request->getPost('sort')[$keys[0]];
$keys = array_column($formatted, $keys[0]);
array_multisort($keys, $order == 'asc' ? SORT_ASC : SORT_DESC, $formatted);
}
return [
'total' => count($entry_keys),
'rowCount' => $itemsPerPage,
'current' => $currentPage,
'rows' => $formatted,
];
}
/***
* search phase 1 entries in legacy config returning a standard structure as we use in the mvc variant
*/
@ -160,7 +118,7 @@ class TunnelController extends ApiControllerBase
$idx++;
}
}
return $this->search($items);
return $this->searchRecordsetBase($items);
}
/***
@ -292,7 +250,7 @@ class TunnelController extends ApiControllerBase
$p2idx++;
}
}
return $this->search($items);
return $this->searchRecordsetBase($items);
}
/**