Skip to content

Commit b21a924

Browse files
committed
Merge branch 'master'
2 parents f78589f + 770838c commit b21a924

File tree

12 files changed

+520
-1
lines changed

12 files changed

+520
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<input type="password" {*
2+
*}id="{@$field->getPrefixedId()}" {*
3+
*}name="{@$field->getPrefixedId()}" {*
4+
*}value="{$field->getValue()}" {*
5+
*}class="long"{*
6+
*}{if $field->isAutofocused()} autofocus{/if}{*
7+
*}{if $field->isRequired()} required{/if}{*
8+
*}{if $field->isImmutable()} disabled{/if}{*
9+
*}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
10+
*}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
11+
*}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
12+
*}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
13+
*}>
14+
15+
{if $field->getMinimumPasswordStrength() !== null}
16+
<script data-relocate="true">
17+
require(['WoltLabSuite/Core/Ui/User/PasswordStrength', 'Language'], function (PasswordStrength, Language) {
18+
{if !$passwordStrengthLanguageSet|isset}
19+
{include file='passwordStrengthLanguage'}
20+
{assign var=passwordStrengthLanguageSet value=true}
21+
{/if}
22+
23+
new PasswordStrength(elById('{@$field->getPrefixedId()}'), {
24+
staticDictionary: [
25+
// TODO
26+
]
27+
});
28+
})
29+
</script>
30+
{/if}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<div id="{@$field->getPrefixedId()}">
2+
{if $field->supportsHTML()}
3+
{@$field->getText()}
4+
{else}
5+
{$field->getText()}
6+
{/if}
7+
</div>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Data handler for a form builder field in an Ajax form that stores its value in an input's value
3+
* attribute.
4+
*
5+
* @author Florian Gail
6+
* @copyright 2020 - Florian Gail - www.mysterycode.de
7+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
8+
* @module WoltLabSuite/Core/Form/Builder/Field/Password
9+
*/
10+
define(['Core', './Field'], function(Core, FormBuilderField) {
11+
"use strict";
12+
13+
/**
14+
* @constructor
15+
*/
16+
function FormBuilderFieldPassword(fieldId) {
17+
this.init(fieldId);
18+
};
19+
Core.inherit(FormBuilderFieldPassword, FormBuilderField, {
20+
/**
21+
* @see WoltLabSuite/Core/Form/Builder/Field/Field#_getData
22+
*/
23+
_getData: function() {
24+
var data = {};
25+
26+
data[this._fieldId] = this._field.value;
27+
if (this._verdict !== null) {
28+
data[this._fieldId + '_passwordStrengthVerdict'] = this._verdict.value;
29+
}
30+
31+
return data;
32+
},
33+
34+
/**
35+
* @see WoltLabSuite/Core/Form/Builder/Field/Field#_readField
36+
*/
37+
_readField: function() {
38+
this._field = elById(this._fieldId);
39+
40+
if (this._field === null) {
41+
throw new Error("Unknown field with id '" + this._fieldId + "'.");
42+
}
43+
44+
this._verdict = elById(this._fieldId + '_passwordStrengthVerdict');
45+
},
46+
});
47+
48+
return FormBuilderFieldPassword;
49+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\container;
4+
5+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
6+
use wcf\system\form\builder\IFormDocument;
7+
8+
class RecurringElementsFormContainer extends FormContainer {
9+
/**
10+
* @inheritDoc
11+
*/
12+
public function populate() {
13+
parent::populate();
14+
15+
$this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor($this->getId(), function(IFormDocument $document, array $parameters) {
16+
return $parameters;
17+
}));
18+
19+
return $this;
20+
}
21+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\container;
4+
5+
class RegisterFormContainer extends FormContainer {
6+
/**
7+
* @inheritDoc
8+
*/
9+
public function populate() {
10+
$this->appendChildren([
11+
12+
]);
13+
}
14+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\data\processor;
4+
5+
use wcf\data\IStorableObject;
6+
use wcf\system\form\builder\IFormDocument;
7+
8+
class RecurringElementsFormDataProcessor extends AbstractFormDataProcessor {
9+
/**
10+
* processor id primarily used for error messages
11+
* @var string
12+
*/
13+
protected $id;
14+
15+
/**
16+
* @var string
17+
*/
18+
protected $wrapperProperty;
19+
20+
/**
21+
* Initializes a new RecurringElementsFormDataProcessor object.
22+
*
23+
* @param string $id processor id primarily used for error messages, does not have to be unique
24+
* @param string $wrapperProperty
25+
*
26+
* @throws \InvalidArgumentException if either id or processor callable are invalid
27+
*/
28+
public function __construct($id, $wrapperProperty) {
29+
if (preg_match('~^[a-z][A-z0-9-]*$~', $id) !== 1) {
30+
throw new \InvalidArgumentException("Invalid id '{$id}' given.");
31+
}
32+
33+
$this->id = $id;
34+
$this->wrapperProperty = $wrapperProperty;
35+
}
36+
37+
/**
38+
* @inheritDoc
39+
*/
40+
public function processFormData(IFormDocument $document, array $parameters) {
41+
wcfDebug($document, $parameters);
42+
43+
return $parameters;
44+
}
45+
46+
/**
47+
* @inheritDoc
48+
*/
49+
public function processObjectData(IFormDocument $document, array $data, IStorableObject $object) {
50+
wcfDebug($document, $data, $object);
51+
52+
return $data;
53+
}
54+
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
namespace wcf\system\form\builder\field;
3+
use wcf\system\form\builder\data\processor\CustomFormDataProcessor;
4+
use wcf\system\form\builder\field\validation\FormFieldValidationError;
5+
use wcf\system\form\builder\IFormDocument;
6+
use wcf\util\ArrayUtil;
7+
use wcf\util\JSON;
8+
use wcf\util\StringUtil;
9+
10+
/**
11+
* Implementation of a form field for single-line text values.
12+
*
13+
* @author Matthias Schmidt
14+
* @copyright 2001-2019 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @package WoltLabSuite\Core\System\Form\Builder\Field
17+
* @since 5.2
18+
*/
19+
class PasswordFormField extends AbstractFormField implements IAutoFocusFormField, IImmutableFormField, IMaximumLengthFormField, IMinimumLengthFormField, IPlaceholderFormField {
20+
use TAutoFocusFormField;
21+
use TImmutableFormField;
22+
use TMaximumLengthFormField;
23+
use TMinimumLengthFormField;
24+
use TPlaceholderFormField;
25+
26+
/**
27+
* @inheritDoc
28+
*/
29+
protected $javaScriptDataHandlerModule = 'WoltLabSuite/Core/Form/Builder/Field/Value';
30+
31+
/**
32+
* @inheritDoc
33+
*/
34+
protected $templateName = '__passwordFormField';
35+
36+
/**
37+
* @var integer
38+
*/
39+
protected $minimumPasswordStrength;
40+
41+
/**
42+
* @var mixed[]
43+
*/
44+
protected $passwordStrength;
45+
46+
/**
47+
* @inheritDoc
48+
*/
49+
public function validate() {
50+
if ($this->isRequired() && ($this->getValue() === null || $this->getValue() === '')) {
51+
$this->addValidationError(new FormFieldValidationError('empty'));
52+
}
53+
else {
54+
$this->validateText($this->getValue());
55+
}
56+
57+
parent::validate();
58+
}
59+
60+
/**
61+
* Checks the length of the given password.
62+
*
63+
* @param string $text validated password
64+
*/
65+
protected function validateText($text) {
66+
$this->validateMinimumLength($text);
67+
$this->validateMaximumLength($text);
68+
$this->validateMinimumStrength($text);
69+
}
70+
71+
/**
72+
* @inheritDoc
73+
*/
74+
public function readValue() {
75+
if ($this->getDocument()->hasRequestData($this->getPrefixedId())) {
76+
$value = $this->getDocument()->getRequestData($this->getPrefixedId());
77+
78+
if (is_string($value)) {
79+
$this->value = StringUtil::trim($value);
80+
}
81+
}
82+
if ($this->getDocument()->hasRequestData($this->getPrefixedId() . '_passwordStrengthVerdict')) {
83+
$strength = $this->getDocument()->getRequestData($this->getPrefixedId() . '_passwordStrengthVerdict');
84+
85+
if (is_string($strength)) {
86+
$this->passwordStrength = ArrayUtil::trim(JSON::decode($strength));
87+
}
88+
else if (is_array($strength)) {
89+
$this->passwordStrength = ArrayUtil::trim($strength);
90+
}
91+
}
92+
93+
return $this;
94+
}
95+
96+
/**
97+
* Validates the minimum password strengh of the given password.
98+
*
99+
* @param string $text validated password
100+
* @param string $errorLanguageItem
101+
*/
102+
public function validateMinimumStrength($text, $errorLanguageItem = 'wcf.user.password.error.notSecure') {
103+
if ($this->getMinimumPasswordStrength() !== null && (empty($this->passwordStrength['score']) || $this->passwordStrength['score'] < $this->getMinimumPasswordStrength())) {
104+
$this->addValidationError(new FormFieldValidationError('notSecure', $errorLanguageItem));
105+
}
106+
}
107+
108+
/**
109+
* @param integer $minValue
110+
*/
111+
public function minimumPasswordStrength($minValue = PASSWORD_MIN_SCORE) {
112+
$this->minimumPasswordStrength = $minValue;
113+
}
114+
115+
/**
116+
* @return integer
117+
*/
118+
public function getMinimumPasswordStrength() : int {
119+
return $this->minimumPasswordStrength;
120+
}
121+
122+
/**
123+
* @inheritDoc
124+
*/
125+
public function populate() {
126+
parent::populate();
127+
128+
$this->getDocument()->getDataHandler()->addProcessor(new CustomFormDataProcessor('passwordStrengthVerdict', function(IFormDocument $document, array $parameters) {
129+
if (isset($parameters['data'][$this->getObjectProperty() . '_passwordStrengthVerdict'])) {
130+
$parameters[$this->getObjectProperty() . '_passwordStrengthVerdict'] = is_string($parameters['data'][$this->getObjectProperty() . '_passwordStrengthVerdict']) ? JSON::decode($parameters['data'][$this->getObjectProperty() . '_passwordStrengthVerdict']) : $parameters['data'][$this->getObjectProperty() . '_passwordStrengthVerdict'];
131+
}
132+
133+
return $parameters;
134+
}));
135+
}
136+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace wcf\system\form\builder\field;
4+
5+
use wcf\data\IStorableObject;
6+
use wcf\system\file\upload\UploadFile;
7+
use wcf\util\ImageUtil;
8+
9+
/**
10+
* Implementation of a form field for to uploads.
11+
* This extension supports UploadFile-objects and strings for file-locations.
12+
*
13+
* @author Joshua Ruesweg, Florian Gail
14+
* @copyright 2001-2019 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @package WoltLabSuite\Core\System\Form\Builder\Field
17+
* @since 5.2
18+
*/
19+
class PreviewedUploadFormField extends UploadFormField {
20+
/**
21+
* @inheritDoc
22+
*
23+
* @throws \InvalidArgumentException if the getter for the value provides invalid values
24+
*/
25+
public function updatedObject(array $data, IStorableObject $object, $loadValues = true) {
26+
if ($loadValues) {
27+
// first check, whether an getter for the field exists
28+
if (\method_exists($object, 'get' . \ucfirst($this->getObjectProperty()) . 'UploadFileLocations')) {
29+
$value = \call_user_func([
30+
$object,
31+
'get' . \ucfirst($this->getObjectProperty()) . 'UploadFileLocations',
32+
]);
33+
$method = "method '" . \get_class($object) . "::get" . \ucfirst($this->getObjectProperty()) . "UploadFileLocations()'";
34+
}
35+
elseif (\method_exists($object, 'get' . \ucfirst($this->getObjectProperty()))) {
36+
$value = \call_user_func([
37+
$object,
38+
'get' . \ucfirst($this->getObjectProperty())
39+
]);
40+
$method = "method '" . \get_class($object) . "::get" . \ucfirst($this->getObjectProperty()) . "()'";
41+
}
42+
else {
43+
$value = $data[$this->getObjectProperty()];
44+
$method = "variable '" . \get_class($object) . "::$" . $this->getObjectProperty() . "'";
45+
}
46+
47+
if (\is_array($value)) {
48+
$value = \array_map(function ($v) use ($method) {
49+
if ($v instanceof UploadFile) {
50+
if (!file_exists($v->getLocation())) {
51+
throw new \InvalidArgumentException("The " . $method . " must return an array of strings or object of class '" . UploadFile::class . "' with the valid file locations.");
52+
}
53+
54+
return $v;
55+
}
56+
else {
57+
if (!\is_string($v) || !\file_exists($v)) {
58+
throw new \InvalidArgumentException("The " . $method . " must return an array of strings or object of class '" . UploadFile::class . "' with the valid file locations.");
59+
}
60+
61+
return new UploadFile(
62+
$v,
63+
\basename($v),
64+
ImageUtil::isImage($v, \basename($v), $this->svgImageAllowed()),
65+
true,
66+
$this->svgImageAllowed()
67+
);
68+
}
69+
}, $value);
70+
71+
$this->value($value);
72+
}
73+
else {
74+
throw new \InvalidArgumentException("The " . $method . " must return an array of strings with the file locations.");
75+
}
76+
}
77+
78+
return $this;
79+
}
80+
}

0 commit comments

Comments
 (0)