2020-03-18 12:29:36 +01:00
|
|
|
<?php
|
|
|
|
|
|
2020-03-19 13:11:06 +01:00
|
|
|
use Lewp\{Module, Resolve, VarFolder};
|
2020-03-18 12:29:36 +01:00
|
|
|
|
2020-03-19 13:11:06 +01:00
|
|
|
return new class extends Module
|
2020-03-18 12:29:36 +01:00
|
|
|
{
|
|
|
|
|
const OPTIONS_ELEMENTS = 'elements';
|
|
|
|
|
const OPTIONS_ELEMENT = 'element';
|
2020-03-19 13:11:06 +01:00
|
|
|
const OPTIONS_LABEL = 'label';
|
2020-03-18 12:29:36 +01:00
|
|
|
|
|
|
|
|
// element specific
|
|
|
|
|
const OPTIONS_SHOW_PLACEHOLDER = 'show_placeholder';
|
|
|
|
|
const OPTIONS_TYPE = 'type';
|
|
|
|
|
const OPTIONS_CONTENT = 'content';
|
|
|
|
|
|
|
|
|
|
// form generics
|
|
|
|
|
const OPTIONS_METHOD = 'method';
|
|
|
|
|
const OPTIONS_ACTION = 'action';
|
|
|
|
|
|
|
|
|
|
private $non_attribute_options = [
|
|
|
|
|
self::OPTIONS_ELEMENTS => false,
|
|
|
|
|
self::OPTIONS_ELEMENT => false,
|
|
|
|
|
self::OPTIONS_CONTENT => false,
|
2020-03-19 13:11:06 +01:00
|
|
|
self::OPTIONS_LABEL => false,
|
2020-03-18 12:29:36 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
private $element_id = 0;
|
|
|
|
|
|
|
|
|
|
private function canContainData(array $element)
|
|
|
|
|
{
|
|
|
|
|
$non_data_elements = [
|
|
|
|
|
[
|
|
|
|
|
self::OPTIONS_ELEMENT => "button"
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
self::OPTIONS_ELEMENT => "input",
|
|
|
|
|
self::OPTIONS_TYPE => "submit",
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
foreach ($non_data_elements as $non) {
|
|
|
|
|
if (count(array_intersect($non, $element)) == count($non)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:11:06 +01:00
|
|
|
private function generateFormElementName(bool $increase_element_id): string
|
|
|
|
|
{
|
|
|
|
|
return implode(
|
|
|
|
|
'-',
|
|
|
|
|
[
|
|
|
|
|
$this->getModuleName(),
|
|
|
|
|
$this->getExecutionCount(),
|
|
|
|
|
($increase_element_id) ? $this->element_id++ : $this->element_id,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function createFormElementGroup(array $element)
|
|
|
|
|
{
|
|
|
|
|
if (!isset($element[self::OPTIONS_LABEL])) {
|
|
|
|
|
return $this->createFormElement($element);
|
|
|
|
|
} else {
|
|
|
|
|
$label = $this->createLabel($element);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$wrapper = $this->createAndSetupElement(
|
|
|
|
|
'div',
|
|
|
|
|
'',
|
|
|
|
|
[
|
|
|
|
|
'class' => 'element-container'
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
$wrapper->appendChild($label);
|
|
|
|
|
|
|
|
|
|
$form_element = $this->createFormElement($element);
|
|
|
|
|
|
|
|
|
|
$wrapper->appendChild($form_element);
|
|
|
|
|
return $wrapper;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-18 12:29:36 +01:00
|
|
|
private function createFormElement(array $element)
|
|
|
|
|
{
|
|
|
|
|
$element += [self::OPTIONS_CONTENT => ''];
|
|
|
|
|
if ($this->canContainData($element)) {
|
2020-03-19 13:11:06 +01:00
|
|
|
// if no label given, the element id should be increased
|
|
|
|
|
$element["name"] = $this->generateFormElementName(
|
|
|
|
|
true//!array_key_exists($element[self::OPTIONS_LABEL])
|
|
|
|
|
);
|
|
|
|
|
$element["id"] = $element["name"];
|
2020-03-18 12:29:36 +01:00
|
|
|
} else {
|
|
|
|
|
unset($element["name"]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form_element = $this->createAndSetupElement(
|
|
|
|
|
$element[self::OPTIONS_ELEMENT],
|
|
|
|
|
$element[self::OPTIONS_CONTENT],
|
|
|
|
|
array_diff_key($element, $this->non_attribute_options)
|
|
|
|
|
);
|
2020-03-19 13:11:06 +01:00
|
|
|
|
2020-03-18 12:29:36 +01:00
|
|
|
foreach ($element[self::OPTIONS_ELEMENTS] as $element) {
|
2020-03-19 13:11:06 +01:00
|
|
|
$form_element->appendChild($this->createFormElementGroup($element));
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
return $form_element;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:11:06 +01:00
|
|
|
private function createLabel(array $element)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
$label = $this->createAndSetupElement(
|
|
|
|
|
'label',
|
|
|
|
|
$element[self::OPTIONS_LABEL],
|
|
|
|
|
[
|
|
|
|
|
'for' => $this->generateFormElementName(false),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
return $label;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-18 12:29:36 +01:00
|
|
|
private function setupForm(array $elements)
|
|
|
|
|
{
|
|
|
|
|
foreach ($elements as $element) {
|
2020-03-19 13:11:06 +01:00
|
|
|
$this->appendChild($this->createFormElementGroup($element));
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-19 13:11:06 +01:00
|
|
|
private function collectFormKeys()
|
|
|
|
|
{
|
2020-03-18 12:29:36 +01:00
|
|
|
return preg_grep(
|
2020-03-19 13:11:06 +01:00
|
|
|
'/' .
|
2020-03-18 12:29:36 +01:00
|
|
|
$this->getModuleName()
|
2020-03-19 13:11:06 +01:00
|
|
|
. '-'
|
|
|
|
|
. $this->getExecutionCount()
|
|
|
|
|
. '-\d+'
|
|
|
|
|
. '/',
|
2020-03-18 12:29:36 +01:00
|
|
|
array_keys($_POST)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief IMPORTANT: Needs to be called AFTER setupForm to work correctly!
|
|
|
|
|
*/
|
|
|
|
|
private function isSubmitted()
|
|
|
|
|
{
|
|
|
|
|
return count($this->collectFormKeys()) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getData()
|
|
|
|
|
{
|
|
|
|
|
if (!$this->isSubmitted()) {
|
2020-03-19 13:11:06 +01:00
|
|
|
return [];
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
$data = [];
|
|
|
|
|
$keys = $this->collectFormKeys();
|
|
|
|
|
sort($keys, SORT_NUMERIC);
|
|
|
|
|
foreach ($keys as $key) {
|
2020-03-19 13:11:06 +01:00
|
|
|
$data [] = $_POST[$key];
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function processAction($action)
|
|
|
|
|
{
|
|
|
|
|
if ($action === '/') {
|
2020-03-19 13:11:06 +01:00
|
|
|
return '/' . $this->getLanguage();
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
if (strpos($action, '/') === 0) {
|
2020-03-19 13:11:06 +01:00
|
|
|
return '/' . $this->getLanguage() . $action;
|
2020-03-18 12:29:36 +01:00
|
|
|
}
|
|
|
|
|
return implode('/', [
|
|
|
|
|
'',
|
|
|
|
|
$this->getLanguage(),
|
|
|
|
|
($action ?? Resolve::idToUri($this->getPageId())),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function run(array $options = []) : bool
|
|
|
|
|
{
|
|
|
|
|
// SETUP FORM ATTRIBUTES
|
|
|
|
|
$this->setAttribute('method', $options[self::OPTIONS_METHOD] ?? 'POST');
|
|
|
|
|
$this->setAttribute(
|
|
|
|
|
'action',
|
|
|
|
|
$this->processAction($options[self::OPTIONS_ACTION]) ?? '/'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->setupForm($options[self::OPTIONS_ELEMENTS]);
|
|
|
|
|
if ($this->isSubmitted()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function onWebsocketRequest(
|
|
|
|
|
\Lewp\Websocket\Message $message
|
|
|
|
|
) : \Lewp\Websocket\Message {
|
|
|
|
|
}
|
|
|
|
|
};
|