From 62ab667ddb5e371dede0048ca4dfb049ef73b72f Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 22 May 2025 16:23:01 +0200 Subject: [PATCH 1/2] Attempt to fix multi value handling with placeholders This partly reverts and augments 131fd50 The validator call is needed to transform the given value into to proper format (eg. an array for multivalues or an array of array for multi-page values). This has to be done after applying place holders. This might also fix #729 It might also break other usecase so it needs more real world testing. Overall the bureaucracy handling is a mess, because bureaucracy is a mess. Until splitbrain/dokuwiki-plugin-bureaucracy#303 has been addressed, there is no good way to fix this. --- helper/field.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/helper/field.php b/helper/field.php index af8b8f9f..408d6e53 100644 --- a/helper/field.php +++ b/helper/field.php @@ -49,8 +49,8 @@ protected function setVal($value) { if (!$this->column) { $value = ''; - //don't validate placeholders here - } elseif ($this->replace($value) == $value) { + } else { + $value = $this->replace($value); $validator = new ValueValidator(); $this->error = !$validator->validateValue($this->column, $value); if ($this->error) { @@ -158,6 +158,16 @@ public function replacementMultiValueCallback($matches) */ protected function createValue() { + /* + $preparedValue = $this->opt['value'] ?? ''; + if($this->column->isMulti()) { + // multi-value fields are treated as comma-separated lists + $preparedValue = explode(',', $preparedValue); + $preparedValue = array_map('trim', $preparedValue); + $preparedValue = array_filter($preparedValue); + } + */ + // input value or appropriately initialized empty value $preparedValue = $this->opt['value'] ?? ($this->column->isMulti() ? [] : ''); From 1dcc3dbe1e4bb0dd8f19e8051d14a2d1a7fed849 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Thu, 24 Jul 2025 12:00:58 +0200 Subject: [PATCH 2/2] Try to fix placeholder application for bureaucracy fields We were applying replacements in setVal() but that is weirdly called during parsing and then gets cached. But it's also called again when the validation fails... It's all a mess. This tries to work around the issue, but I am far from sure this hits all the (edge) cases. Really without a refactoring of bureaucracy it's nearly impossible to interface cleanly with it. --- helper/field.php | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/helper/field.php b/helper/field.php index 408d6e53..c73516dd 100644 --- a/helper/field.php +++ b/helper/field.php @@ -47,15 +47,25 @@ public function initialize($args) */ protected function setVal($value) { + global $INPUT; + if (!$this->column) { $value = ''; } else { - $value = $this->replace($value); - $validator = new ValueValidator(); - $this->error = !$validator->validateValue($this->column, $value); - if ($this->error) { - foreach ($validator->getErrors() as $error) { - msg(hsc($error), -1); + + // This method is called at parsing time, and again on action submit + // we really only want to validate the value on action submit + // + // At parsing time, the value might still be a placeholder. Ideally + // bureaucracy would already handle this. But well... + if($INPUT->post->has('bureaucracy')) { + $validator = new ValueValidator(); + + $this->error = !$validator->validateValue($this->column, $value); + if ($this->error) { + foreach ($validator->getErrors() as $error) { + msg(hsc($error), -1); + } } } } @@ -154,22 +164,23 @@ public function replacementMultiValueCallback($matches) * Returns a Value object for the current column. * Special handling for Page and Lookup literal form values. * + * Used for rendering the field only. + * * @return Value */ protected function createValue() { - /* + // The value in bureaucracy is always a string, if unset init it. $preparedValue = $this->opt['value'] ?? ''; - if($this->column->isMulti()) { - // multi-value fields are treated as comma-separated lists - $preparedValue = explode(',', $preparedValue); - $preparedValue = array_map('trim', $preparedValue); - $preparedValue = array_filter($preparedValue); - } - */ - // input value or appropriately initialized empty value - $preparedValue = $this->opt['value'] ?? ($this->column->isMulti() ? [] : ''); + // apply placeholder replacements + $preparedValue = $this->replace($preparedValue); + + // Validating here is actually not a validation, that will happen again in setVal() when + // the form is submitted. instead, here we're using it's data cleanup functionality on the value. + $validator = new ValueValidator(); + $validator->validateValue($this->column, $preparedValue); + /** @var string|array $preparedValue is now an array or a string */ // page fields might need to be JSON encoded depending on usetitles config if (