Skip to content

Commit 404111b

Browse files
committed
fix(fieldsfield): instanciation error when fields plugin disabled
1 parent 1e95fe2 commit 404111b

File tree

6 files changed

+192
-34
lines changed

6 files changed

+192
-34
lines changed

inc/field/fieldsfield.class.php

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,11 @@
3838
use Dropdown;
3939
use DbUtils;
4040
use Plugin;
41-
use Ticket;
42-
use Change;
43-
use Problem;
4441
use Session;
4542
use Html;
4643
use OperatingSystem;
4744
use PluginFieldsDropdown;
4845
use PluginFieldsField;
49-
use PluginFormcreatorQuestion;
5046
use Toolbox;
5147
use User;
5248

@@ -59,19 +55,20 @@ class FieldsField extends PluginFormcreatorAbstractField
5955
public $field = null;
6056

6157
/**
58+
* Get the additional field object lined to this formcreator field
6259
*
63-
* @param array $question PluginFormcreatorQuestion instance
60+
* @return null|PluginFieldsField
6461
*/
65-
public function __construct(PluginFormcreatorQuestion $question) {
66-
$this->question = $question;
67-
if (isset($this->question->fields['values'])) {
62+
public function getField(): ?PluginFieldsField {
63+
if ($this->field === null && isset($this->question->fields['values'])) {
6864
$decodedValues = json_decode($this->question->fields['values'], JSON_OBJECT_AS_ARRAY);
6965
$field_name = $decodedValues['dropdown_fields_field'] ?? '';
7066
$fieldObj = new PluginFieldsField();
7167
if ($fieldObj->getFromDBByCrit(['name' => $field_name])) {
72-
$this->field = $fieldObj;
68+
$this->field = $fieldObj;
7369
}
7470
}
71+
return $this->field;
7572
}
7673

7774
public function isPrerequisites(): bool {
@@ -152,16 +149,24 @@ public function getBlocks(): array {
152149
}
153150

154151
public function showForm(array $options): void {
152+
if (!\Plugin::isPluginActive('fields')) {
153+
$options['error'] = __('Warning: Additional Fields plugin is disabled or missing', 'formcreator');
154+
$template = '@formcreator/field/undefinedfield.html.twig';
155+
TemplateRenderer::getInstance()->display($template, [
156+
'item' => $this->question,
157+
'params' => $options,
158+
]);
159+
return;
160+
}
155161

156162
$template = '@formcreator/field/' . $this->question->fields['fieldtype'] . 'field.html.twig';
157-
158163
$decodedValues = json_decode($this->question->fields['values'], JSON_OBJECT_AS_ARRAY);
159164
$this->question->fields['_block_id'] = $decodedValues['blocks_field'] ?? 0;
160165
$this->question->fields['_block_list'] = $this->getBlocks();
161166
$this->question->fields['_drodpdown_block_label'] = __("Block", "fields");
162167

163-
$this->question->fields['_field_name'] = $decodedValues['dropdown_fields_field'] ?? '';
164-
$this->question->fields['_field_list'] = FieldsField::getFieldsFromBlock($this->question->fields['_block_id']);
168+
$this->question->fields['_field_name'] = $decodedValues['dropdown_fields_field'] ?? '';
169+
$this->question->fields['_field_list'] = FieldsField::getFieldsFromBlock($this->question->fields['_block_id']);
165170
$this->question->fields['_drodpdown_field_label'] = __("Field", "fields");
166171

167172
TemplateRenderer::getInstance()->display($template, [
@@ -190,7 +195,7 @@ public function getRenderedHtml($domain, $canEdit = true): string {
190195

191196
public function prepareHtmlField($fieldName, $canedit = true, $value = '') {
192197

193-
if (empty($this->field->fields)) {
198+
if ($this->getField() === null || empty($this->getField()->fields)) {
194199
return false;
195200
}
196201

@@ -201,10 +206,10 @@ public function prepareHtmlField($fieldName, $canedit = true, $value = '') {
201206
$field['value'] = $value;
202207
} else {
203208
//get default value
204-
if ($this->field->fields['default_value'] !== "") {
205-
$value = $this->field->fields['default_value'];
209+
if ($this->getField()->fields['default_value'] !== "") {
210+
$value = $this->getField()->fields['default_value'];
206211
// shortcut for date/datetime
207-
if (in_array($this->field->fields['type'], ['date', 'datetime'])
212+
if (in_array($this->getField()->fields['type'], ['date', 'datetime'])
208213
&& $value == 'now') {
209214
$value = $_SESSION["glpi_currenttime"];
210215
}
@@ -213,10 +218,10 @@ public function prepareHtmlField($fieldName, $canedit = true, $value = '') {
213218
}
214219

215220
$html = "";
216-
$readonly = ($this->field->fields['is_readonly'] || !$canedit);
217-
$this->question->fields['required'] = $this->field->fields['mandatory'];
221+
$readonly = ($this->getField()->fields['is_readonly'] || !$canedit);
222+
$this->question->fields['required'] = $this->getField()->fields['mandatory'];
218223

219-
switch ($this->field->fields['type']) {
224+
switch ($this->getField()->fields['type']) {
220225
case 'number':
221226
case 'text':
222227
$value = Html::cleanInputText($value);
@@ -263,19 +268,19 @@ public function prepareHtmlField($fieldName, $canedit = true, $value = '') {
263268
break;
264269
case 'dropdown':
265270
if ($canedit && !$readonly) {
266-
if (strpos($this->field->fields['name'], "dropdowns_id") !== false) {
271+
if (strpos($this->getField()->fields['name'], "dropdowns_id") !== false) {
267272
$dropdown_itemtype = getItemTypeForTable(
268-
getTableNameForForeignKeyField($this->field->fields['name']));
273+
getTableNameForForeignKeyField($this->getField()->fields['name']));
269274
} else {
270-
$dropdown_itemtype = PluginFieldsDropdown::getClassname($this->field->fields['name']);
275+
$dropdown_itemtype = PluginFieldsDropdown::getClassname($this->getField()->fields['name']);
271276
}
272277
$html.= Dropdown::show($dropdown_itemtype,
273278
['value' => $value,
274279
'name' => $fieldName,
275280
'entity' => $_SESSION['glpiactiveentities'],
276281
'display' => false]);
277282
} else {
278-
$dropdown_table = "glpi_plugin_fields_".$this->field->fields['name']."dropdowns";
283+
$dropdown_table = "glpi_plugin_fields_".$this->getField()->fields['name']."dropdowns";
279284
$html.= Dropdown::getDropdownName($dropdown_table, $value);
280285
}
281286

@@ -417,18 +422,18 @@ public function getValueForApi(): string {
417422

418423
public function isValidValue($value): bool {
419424

420-
if (is_null($this->field)) {
425+
if (is_null($this->getField())) {
421426
return false;
422427
}
423428

424429
//check data type for input number / url
425430
$valid = true;
426-
if ($this->field->fields['type'] == 'number' && !empty($this->value) && !is_numeric($this->value)) {
427-
$number_errors[] = $this->field->fields['label'];
431+
if ($this->getField()->fields['type'] == 'number' && !empty($this->value) && !is_numeric($this->value)) {
432+
$number_errors[] = $this->getField()->fields['label'];
428433
$valid = false;
429-
} else if ($this->field->fields['type'] == 'url' && !empty($this->value)) {
434+
} else if ($this->getField()->fields['type'] == 'url' && !empty($this->value)) {
430435
if (filter_var($this->value, FILTER_VALIDATE_URL) === false) {
431-
$url_errors[] = $this->field->fields['label'];
436+
$url_errors[] = $this->getField()->fields['label'];
432437
$valid = false;
433438
}
434439
}
@@ -452,9 +457,9 @@ public function isValidValue($value): bool {
452457
}
453458

454459
public function isValid(): bool {
455-
if (!is_null($this->field)) {
460+
if (!is_null($this->getField())) {
456461
// If the field is required it can't be empty
457-
if ($this->field->fields['mandatory'] && $this->value == '') {
462+
if ($this->getField()->fields['mandatory'] && $this->value == '') {
458463
Session::addMessageAfterRedirect(
459464
__('A required field is empty:', 'formcreator') . ' ' . $this->getLabel(),
460465
false,

inc/field/tagfield.class.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ public function isPrerequisites(): bool {
4646
}
4747

4848
public function showForm(array $options): void {
49+
if (!\Plugin::isPluginActive('tag')) {
50+
$options['error'] = __('Warning: Tag plugin is disabled or missing', 'formcreator');
51+
$template = '@formcreator/field/undefinedfield.html.twig';
52+
TemplateRenderer::getInstance()->display($template, [
53+
'item' => $this->question,
54+
'params' => $options,
55+
]);
56+
return;
57+
}
58+
4959
$template = '@formcreator/field/' . $this->question->fields['fieldtype'] . 'field.html.twig';
5060
$this->question->fields['default_values'] = Html::entities_deep($this->question->fields['default_values']);
5161
$this->deserializeValue($this->question->fields['default_values']);

inc/field/undefinedfield.class.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
/**
4+
* ---------------------------------------------------------------------
5+
* Formcreator is a plugin which allows creation of custom forms of
6+
* easy access.
7+
* ---------------------------------------------------------------------
8+
* LICENSE
9+
*
10+
* This file is part of Formcreator.
11+
*
12+
* Formcreator is free software; you can redistribute it and/or modify
13+
* it under the terms of the GNU General Public License as published by
14+
* the Free Software Foundation; either version 2 of the License, or
15+
* (at your option) any later version.
16+
*
17+
* Formcreator is distributed in the hope that it will be useful,
18+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20+
* GNU General Public License for more details.
21+
*
22+
* You should have received a copy of the GNU General Public License
23+
* along with Formcreator. If not, see <http://www.gnu.org/licenses/>.
24+
* ---------------------------------------------------------------------
25+
* @copyright Copyright © 2011 - 2020 Teclib'
26+
* @license http://www.gnu.org/licenses/gpl.txt GPLv3+
27+
* @link https://github.com/pluginsGLPI/formcreator/
28+
* @link https://pluginsglpi.github.io/formcreator/
29+
* @link http://plugins.glpi-project.org/#/plugin/formcreator
30+
* ---------------------------------------------------------------------
31+
*/
32+
33+
namespace GlpiPlugin\Formcreator\Field;
34+
35+
use PluginFormcreatorAbstractField;
36+
use Html;
37+
use GlpiPlugin\Formcreator\Exception\ComparisonException;
38+
use Glpi\Application\View\TemplateRenderer;
39+
40+
class UndefinedField extends PluginFormcreatorAbstractField
41+
{
42+
public static function getName(): string {
43+
return __('Undefined', 'formcreator');
44+
}
45+
46+
public static function canRequire(): bool {
47+
return false;
48+
}
49+
50+
public function serializeValue(): string {
51+
return '';
52+
}
53+
54+
public function deserializeValue($value) {
55+
}
56+
57+
public function getValueForDesign(): string {
58+
return '';
59+
}
60+
61+
public function getValueForTargetText($domain, $richText): ?string {
62+
return null;
63+
}
64+
65+
public function getValueForApi() {
66+
return '';
67+
}
68+
69+
public function moveUploads() {
70+
}
71+
72+
public function getDocumentsForTarget(): array {
73+
return [];
74+
}
75+
76+
public function isPrerequisites(): bool {
77+
return true;
78+
}
79+
80+
public function isPublicFormCompatible(): bool {
81+
return true;
82+
}
83+
84+
public function showForm(array $options): void {
85+
$template = '@formcreator/field/undefinedfield.html.twig';
86+
$this->question->fields['default_values'] = Html::entities_deep($this->question->fields['default_values']);
87+
$this->deserializeValue($this->question->fields['default_values']);
88+
TemplateRenderer::getInstance()->display($template, [
89+
'item' => $this->question,
90+
'params' => $options,
91+
]);
92+
}
93+
public function isValid(): bool {
94+
return true;
95+
}
96+
public function isValidValue($value): bool {
97+
return true;
98+
}
99+
100+
public function hasInput($input): bool {
101+
return false;
102+
}
103+
104+
public function parseAnswerValues($input, $nonDestructive = false): bool {
105+
return true;
106+
}
107+
108+
public function isEditableField(): bool {
109+
return true;
110+
}
111+
112+
public function getHtmlIcon(): string {
113+
return '<i class="fa fa-question" aria-hidden="true"></i>';
114+
}
115+
116+
public function equals($value): bool {
117+
throw new ComparisonException('Meaningless comparison');
118+
}
119+
120+
public function notEquals($value): bool {
121+
throw new ComparisonException('Meaningless comparison');
122+
}
123+
124+
public function greaterThan($value): bool {
125+
throw new ComparisonException('Meaningless comparison');
126+
}
127+
128+
public function lessThan($value): bool {
129+
throw new ComparisonException('Meaningless comparison');
130+
}
131+
132+
public function regex($value): bool {
133+
throw new ComparisonException('Meaningless comparison');
134+
}
135+
136+
public function isVisibleField(): bool {
137+
return false;
138+
}
139+
}

inc/fields.class.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*/
3131

3232
use GlpiPlugin\Formcreator\Exception\ComparisonException;
33+
use GlpiPlugin\Formcreator\Field\UndefinedField;
3334
use Xylemical\Expressions\Math\BcMath;
3435
use Xylemical\Expressions\Context;
3536
use Xylemical\Expressions\ExpressionFactory;
@@ -107,7 +108,7 @@ public static function getNames() {
107108
// Get localized names of field types
108109
foreach (PluginFormcreatorFields::getClasses() as $field_type => $classname) {
109110
$classname = self::getFieldClassname($field_type);
110-
if ($classname == PluginFormcreatorTagField::class && !$plugin->isActivated('tag')) {
111+
if ($classname == UndefinedField::class) {
111112
continue;
112113
}
113114

inc/question.class.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
use GlpiPlugin\Formcreator\Exception\ImportFailureException;
3333
use GlpiPlugin\Formcreator\Exception\ExportFailureException;
34+
use GlpiPlugin\Formcreator\Field\UndefinedField;
3435
use Glpi\Application\View\TemplateRenderer;
3536

3637
if (!defined('GLPI_ROOT')) {
@@ -205,6 +206,7 @@ public function getDesignHtml() : string {
205206
$questionId = $this->getID();
206207
$sectionId = $this->fields[PluginFormcreatorSection::getForeignKeyField()];
207208
$fieldType = PluginFormcreatorFields::getFieldClassname($this->fields['fieldtype']);
209+
/** @var PluginFormcreatorFieldInterface $field */
208210
$field = new $fieldType($this);
209211

210212
$html .= '<div class="grid-stack-item"'
@@ -725,7 +727,7 @@ public function showForm($ID, $options = []) {
725727
$options['target'] = "javascript:;";
726728
$options['formoptions'] = sprintf('onsubmit="plugin_formcreator.submitQuestion(this)" data-itemtype="%s" data-id="%s"', self::getType(), $this->getID());
727729

728-
$template = '@formcreator/field/undefined.html.twig';
730+
$template = '@formcreator/field/undefinedfield.html.twig';
729731
if (!$this->loadField($this->fields['fieldtype'])) {
730732
TemplateRenderer::getInstance()->display($template, [
731733
'item' => $this,
@@ -1186,7 +1188,7 @@ public function post_getFromDB() {
11861188
}
11871189

11881190
/**
1189-
* load instance if field associated to the question
1191+
* load instance of field associated to the question
11901192
*
11911193
* @return bool true on sucess, false otherwise
11921194
*/

templates/field/undefined.html.twig renamed to templates/field/undefinedfield.html.twig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@
3636
{% import '@formcreator/components/form/fields_macros.html.twig' as formcreatorFields %}
3737

3838
{% block questionFields %}
39-
{% endblock %}
39+
{{ fields.smallTitle(params.error) }}
40+
{% endblock %}

0 commit comments

Comments
 (0)