Create first search draft

This commit is contained in:
Dennis Eichhorn 2019-06-01 20:49:59 +02:00
commit ff25d0f72c
16 changed files with 808 additions and 0 deletions

87
Admin/Installer.php Normal file
View File

@ -0,0 +1,87 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search\Admin
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Admin;
use phpOMS\DataStorage\Database\DatabasePool;
use phpOMS\Module\InfoManager;
use phpOMS\Module\InstallerAbstract;
use phpOMS\System\File\PathException;
use phpOMS\System\File\PermissionException;
use phpOMS\Utils\Parser\Php\ArrayParser;
/**
* Installer class.
*
* @package Modules\Search\Admin
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class Installer extends InstallerAbstract
{
/**
* {@inheritdoc}
*/
public static function install(DatabasePool $dbPool, InfoManager $info) : void
{
if (\file_exists(__DIR__ . '/../Search.php')) {
\unlink(__DIR__ . '/../Search.php');
}
parent::install($dbPool, $info);
}
/**
* Install data from providing modules.
*
* @param DatabasePool $dbPool Database pool
* @param array $data Module info
*
* @return void
*
* @throws PathException This exception is thrown if the Search install file couldn't be found
* @throws \Exception This exception is thrown if the Search install file is invalid json
*
* @since 1.0.0
*/
public static function installExternal(DatabasePool $dbPool, array $data) : void
{
if (!\file_exists(__DIR__ . '/../SearchCommands.php')) {
\file_put_contents(__DIR__ . '/../SearchCommands.php', '<?php return [];');
}
if (!\file_exists($data['path'] ?? '')) {
return;
}
if (!\file_exists(__DIR__ . '/../SearchCommands.php')) {
throw new PathException(__DIR__ . '/../SearchCommands.php');
}
if (!\is_writable(__DIR__ . '/../SearchCommands.php')) {
throw new PermissionException(__DIR__ . '/../SearchCommands.php');
}
/** @noinspection PhpIncludeInspection */
$appRoutes = include __DIR__ . '/../SearchCommands.php';
/** @noinspection PhpIncludeInspection */
$moduleRoutes = include $data['path'];
$appRoutes = \array_merge_recursive($appRoutes, $moduleRoutes);
\file_put_contents(__DIR__ . '/../SearchCommands.php', '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
}
}

20
Admin/Routes/Web/Api.php Normal file
View File

@ -0,0 +1,20 @@
<?php declare(strict_types=1);
use Modules\Search\Controller\ApiController;
use Modules\Search\Models\PermissionState;
use phpOMS\Account\PermissionType;
use phpOMS\Router\RouteVerb;
return [
'^.*/search(\?.*|$)' => [
[
'dest' => '\Modules\Search\Controller\ApiController:routeSearch',
'verb' => RouteVerb::ANY,
'permission' => [
'module' => ApiController::MODULE_NAME,
'type' => PermissionType::READ,
'state' => PermissionState::SEARCH,
],
],
],
];

View File

@ -0,0 +1,3 @@
<?php declare(strict_types=1);
return [];

30
Admin/Status.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search\Admin
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Admin;
use phpOMS\Module\StatusAbstract;
/**
* Search class.
*
* @package Modules\Search\Admin
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class Status extends StatusAbstract
{
}

29
Admin/Uninstaller.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search\Admin
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Admin;
use phpOMS\Module\UninstallerAbstract;
/**
* Uninstaller class.
*
* @package Modules\Search\Admin
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class Uninstaller extends UninstallerAbstract
{
}

30
Admin/Updater.php Normal file
View File

@ -0,0 +1,30 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search\Admin
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Admin;
use phpOMS\Module\UpdaterAbstract;
/**
* Updater class.
*
* @package Modules\Search\Admin
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class Updater extends UpdaterAbstract
{
}

125
Controller.js Normal file
View File

@ -0,0 +1,125 @@
import { Autoloader } from '../../jsOMS/Autoloader.js';
import { Application } from '../../Web/Backend/js/backend.js';
import { Search } from './Models/Search.js';
Autoloader.defineNamespace('jsOMS.Modules');
/**
* Search controller.
*
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @since 1.0.0
*/
jsOMS.Modules.Search = class {
/**
* Constructor
*
* @since 1.0.0
*/
constructor() {
this.navigation = {};
/** global: jsOMS */
/** global: localStorage */
this.rawNavData = JSON.parse(window.localStorage.getItem(Search.MODULE_NAME));
this.rawNavData = this.rawNavData !== null ? this.rawNavData : {};
};
/**
* Bind navigation
*
* @param {string} id Search to bind (optional)
*
* @return {void}
*
* @since 1.0.0
*/
bind (id) {
const e = typeof id === 'undefined' ? document.getElementsByClassName('nav') : [document.getElementById(id)],
length = e.length;
for (let i = 0; i < length; ++i) {
this.bindElement(e[i]);
}
};
/**
* Bind navigation element
*
* @param {Element} e Element to bind
*
* @return {void}
*
* @since 1.0.0
*/
bindElement (e) {
if (typeof e === 'undefined' || !e) {
// todo: do logging here
return;
}
const extend = e.querySelectorAll('li label'),
self = this;
this.navigation[e.id] = new Search(this.rawNavData[e.id]);
// On load
const open = this.navigation[e.id].getOpen();
let ele = null;
for (let key in open) {
if (open.hasOwnProperty(key) && (ele = document.getElementById(key)) !== null) {
ele.checked = open[key];
}
}
if (!this.navigation[e.id].isVisible()) {
let width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
// todo: still buggy maybe always set true if < 800 and only call this if if >= 800
e.nextElementSibling.checked = width < 800;
}
e.scrollTop = this.navigation[e.id].getScrollPosition().y;
e.scrollLeft = this.navigation[e.id].getScrollPosition().x;
// Bind minimize/maximize
jsOMS.addEventListenerToAll(extend, 'click', function () {
let box = document.getElementById(this.getAttribute('for'));
if (!box.checked) {
self.navigation[e.id].setOpen(box.id);
} else {
self.navigation[e.id].setClose(box.id);
}
localStorage.setItem(Search.MODULE_NAME, JSON.stringify(self.navigation));
});
// Bind show/hide
e.addEventListener('change', function () {
self.navigation[e.id].setVisible(this.checked);
localStorage.setItem(Search.MODULE_NAME, JSON.stringify(self.navigation));
});
// Bind scroll
e.addEventListener('scroll', function () {
self.navigation[e.id].setScrollPosition(this.scrollLeft, this.scrollTop);
localStorage.setItem(Search.MODULE_NAME, JSON.stringify(self.navigation));
});
};
};
/**
* Module id
*
* @var {string}
* @since 1.0.0
*/
Search.MODULE_NAME = '1000500001';
window.omsApp.moduleManager.get('Search').bind('nav-side');

View File

@ -0,0 +1,81 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Controller;
use phpOMS\ApplicationAbstract;
use phpOMS\Router\Router;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\System\MimeType;
use phpOMS\Message\NotificationLevel;
/**
* Api controller for the tasks module.
*
* @package Modules\Search
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
final class ApiController extends Controller
{
private $router = null;
/**
* {@inheritdoc}
*/
public function __construct(ApplicationAbstract $app)
{
parent::__construct($app);
$this->router = new Router();
$this->router->importFromFile(__DIR__ . '/../SearchCommands.php');
}
/**
* Api method to handle basic search request
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function routeSearch(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
$searchResults = $this->app->dispatcher->dispatch(
$this->router->route(
$request->getData('search') ?? '',
$request->getData('CSRF'),
$request->getRouteVerb(),
$this->app->appName,
$this->app->orgId,
$this->app->accountManager->get($request->getHeader()->getAccount())
),
$request,
$response
);
$response->getHeader()->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
$response->set($request->getUri()->__toString(), [
'status' => NotificationLevel::HIDDEN,
'response' => $searchResults,
]);
}
}

80
Controller/Controller.php Normal file
View File

@ -0,0 +1,80 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Controller;
use Modules\Search\Models\Search;
use phpOMS\Module\ModuleAbstract;
use phpOMS\Module\WebInterface;
/**
* Search class.
*
* @package Modules\Search
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
class Controller extends ModuleAbstract implements WebInterface
{
/**
* Module path.
*
* @var string
* @since 1.0.0
*/
public const MODULE_PATH = __DIR__ . '/../';
/**
* Module version.
*
* @var string
* @since 1.0.0
*/
public const MODULE_VERSION = '1.0.0';
/**
* Module name.
*
* @var string
* @since 1.0.0
*/
public const MODULE_NAME = 'Search';
/**
* Module id.
*
* @var int
* @since 1.0.0
*/
public const MODULE_ID = 1007600000;
/**
* Providing.
*
* @var string[]
* @since 1.0.0
*/
protected static $providing = [
];
/**
* Dependencies.
*
* @var string[]
* @since 1.0.0
*/
protected static $dependencies = [];
}

13
Docs/introduction.md Normal file
View File

@ -0,0 +1,13 @@
# Introduction
The **Search** module is one of the essential core modules that is always installed. This module handles the search across the application and all modules that implement a search.
## Target Group
The target group for this module is everyone, since every application should have this module.
# Setup
This module doesn't have any additional setup requirements since it is installed during the application install process.
The module can be installed through the integrated module downloader and installer or by uploading the module into the `Modules/` directory and executing the installation through the module installer.

131
Models/Navigation.js Normal file
View File

@ -0,0 +1,131 @@
export class Navigation {
/**
* Construct
*
* @param {Object} data Initialization (optional)
*
* @since 1.0.0
*/
constructor (data)
{
if (typeof data === 'undefined') {
this.scrollPosition = {x: 0, y: 0};
this.activeLinks = {};
this.visible = true;
this.openCategories = {};
} else {
this.scrollPosition = typeof data.scrollPosition === 'undefined' ? {x : 0, y : 0} : data.scrollPosition;
this.activeLinks = typeof data.activeLinks === 'undefined' ? {} : data.activeLinks;
this.visible = typeof data.visible === 'undefined' ? true : data.visible;
this.openCategories = typeof data.openCategories === 'undefined' ? {} : data.openCategories;
}
};
/**
* Set scroll position
*
* @param {int} x Horizontal position
* @param {int} y Vertical position
*
* @return {void}
*
* @since 1.0.0
*/
setScrollPosition (x, y)
{
this.scrollPosition.x = x;
this.scrollPosition.y = y;
};
/**
* Get scroll position
*
* @return {Object}
*
* @since 1.0.0
*/
getScrollPosition ()
{
return this.scrollPosition;
};
/**
* Open navigation category
*
* @param {string} id Category id
*
* @return {void}
*
* @since 1.0.0
*/
setOpen (id)
{
this.openCategories[id] = true;
};
/**
* Close navigation category
*
* @param {string} id Category id
*
* @return {void}
*
* @since 1.0.0
*/
setClose (id)
{
delete this.openCategories[id];
};
/**
* Get open navigation elements
*
* @return {Object}
*
* @since 1.0.0
*/
getOpen ()
{
return this.openCategories;
};
active (id)
{
this.allInactive();
};
allInactive ()
{
};
inactive (id)
{
};
/**
* Set navigation visibility
*
* @param {bool} visible Visibility
*
* @return {bool}
*
* @since 1.0.0
*/
setVisible (visible)
{
this.visible = visible;
};
/**
* Is navigation visible
*
* @return {bool}
*
* @since 1.0.0
*/
isVisible ()
{
return this.visible;
};
};

View File

@ -0,0 +1,30 @@
<?php
/**
* Orange Management
*
* PHP Version 7.2
*
* @package Modules\Search
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
declare(strict_types=1);
namespace Modules\Search\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Permision state enum.
*
* @package Modules\Search
* @license OMS License 1.0
* @link http://website.orange-management.de
* @since 1.0.0
*/
abstract class PermissionState extends Enum
{
public const SEARCH = 1;
}

1
README.md Normal file
View File

@ -0,0 +1 @@
# Search

110
SearchCommands.php Normal file
View File

@ -0,0 +1,110 @@
<?php return [
'^:help .*$' => [
0 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
1 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
2 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'verb' => 16,
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
],
'^:help :user .*$' => [
0 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
1 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
2 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'verb' => 16,
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
],
'^:help :dev .*$' => [
0 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 3,
],
],
1 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 3,
],
],
2 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'verb' => 16,
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 3,
],
],
],
'^:help :module .*$' => [
0 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
1 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
2 => [
'dest' => '\Modules\Help\Controller\SearchController:searchHelp',
'verb' => 16,
'permission' => [
'module' => 'Help',
'type' => 2,
'state' => 2,
],
],
],
];

BIN
img/module_teaser_small.png Normal file

Binary file not shown.

38
info.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": {
"id": 1007600000,
"internal": "Search",
"external": "Search"
},
"category": "General",
"version": "1.0.0",
"requirements": {
"phpOMS": "1.0.0",
"phpOMS-db": "1.0.0"
},
"creator": {
"name": "Orange Management",
"website": "www.spl1nes.com"
},
"description": "The search module.",
"directory": "Search",
"dependencies": {
"Admin": "1.0.0"
},
"providing": {
},
"load": [
{
"pid": [
"/"
],
"type": 4,
"for": "Content",
"file": "Search",
"from": "Admin"
}
],
"lang": false,
"js": true,
"css": false
}