Separate input type for Rating,Scale,Slider (#351)
* Separate input type for Rating,Scale,Slider * rating, scale, slider add in test cases * Allow field type change for new types * Added options to db factory * Fix linting --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
@@ -108,7 +108,7 @@ class GenerateTemplate extends Command
|
||||
"color": "#64748b"
|
||||
}
|
||||
```
|
||||
The form properties can only have one of the following types: 'text', 'number', 'select', 'multi_select', 'date', 'files', 'checkbox', 'url', 'email', 'phone_number', 'signature'.
|
||||
The form properties can only have one of the following types: 'text', 'number', 'rating', 'scale','slider', 'select', 'multi_select', 'date', 'files', 'checkbox', 'url', 'email', 'phone_number', 'signature'.
|
||||
All form properties objects need to have the keys 'help', 'name', 'type', 'hidden', 'placeholder', 'prefill'.
|
||||
The placeholder property is optional (can be "null") and is used to display a placeholder text in the input field.
|
||||
The help property is optional (can be "null") and is used to display extra information about the field.
|
||||
@@ -125,14 +125,9 @@ class GenerateTemplate extends Command
|
||||
}
|
||||
```
|
||||
|
||||
For numerical rating inputs, use a "number" type input and set the property "is_rating" to "true" to turn it into a star rating input. Ex:
|
||||
```json
|
||||
{
|
||||
"name":"How would you rate your overall experience?",
|
||||
"type":"number",
|
||||
"is_rating": true
|
||||
}
|
||||
```
|
||||
For "rating" you can set the field property "rating_max_value" to set the maximum value of the rating.
|
||||
For "scale" you can set the field property "scale_min_value", "scale_max_value" and "scale_step_value" to set the minimum, maximum and step value of the scale.
|
||||
For "slider" you can set the field property "slider_min_value", "slider_max_value" and "slider_step_value" to set the minimum, maximum and step value of the slider.
|
||||
|
||||
If the form is too long, you can paginate it by adding a page break block in the list of properties:
|
||||
```json
|
||||
@@ -230,6 +225,7 @@ class GenerateTemplate extends Command
|
||||
['role' => 'user', 'content' => Str::of(self::FORM_STRUCTURE_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString()],
|
||||
]);
|
||||
$formData = $completer->getArray();
|
||||
$formData = self::cleanAiOutput($formData);
|
||||
|
||||
$completer->doesNotExpectJson();
|
||||
$formDescriptionPrompt = Str::of(self::FORM_DESCRIPTION_PROMPT)->replace('[REPLACE]', $this->argument('prompt'))->toString();
|
||||
@@ -284,7 +280,7 @@ class GenerateTemplate extends Command
|
||||
$types,
|
||||
$relatedTemplates
|
||||
);
|
||||
$this->info('/form-templates/'.$template->slug);
|
||||
$this->info('/form-templates/' . $template->slug);
|
||||
|
||||
// Set reverse related Templates
|
||||
$this->setReverseRelatedTemplates($template);
|
||||
@@ -297,7 +293,7 @@ class GenerateTemplate extends Command
|
||||
*/
|
||||
private function getImageCoverUrl($searchQuery): ?string
|
||||
{
|
||||
$url = 'https://api.unsplash.com/search/photos?query='.urlencode($searchQuery).'&client_id='.config('services.unsplash.access_key');
|
||||
$url = 'https://api.unsplash.com/search/photos?query=' . urlencode($searchQuery) . '&client_id=' . config('services.unsplash.access_key');
|
||||
$response = Http::get($url)->json();
|
||||
$photoIndex = rand(0, max(count($response['results']) - 1, 10));
|
||||
if (isset($response['results'][$photoIndex]['urls']['regular'])) {
|
||||
@@ -333,7 +329,6 @@ class GenerateTemplate extends Command
|
||||
|
||||
private function getRelatedTemplates(array $industries, array $types): array
|
||||
{
|
||||
ray($industries, $types);
|
||||
$templateScore = [];
|
||||
Template::chunk(100, function ($otherTemplates) use ($industries, $types, &$templateScore) {
|
||||
foreach ($otherTemplates as $otherTemplate) {
|
||||
@@ -361,24 +356,6 @@ class GenerateTemplate extends Command
|
||||
array $types,
|
||||
array $relatedTemplates
|
||||
) {
|
||||
// Add property uuids, improve form with options
|
||||
foreach ($formData['properties'] as &$property) {
|
||||
$property['id'] = Str::uuid()->toString(); // Column ID
|
||||
|
||||
// Fix ratings
|
||||
if ($property['type'] == 'number' && ($property['is_rating'] ?? false)) {
|
||||
$property['rating_max_value'] = 5;
|
||||
}
|
||||
|
||||
if (($property['type'] == 'select' && count($property['select']['options']) <= 4)
|
||||
|| ($property['type'] == 'multi_select' && count($property['multi_select']['options']) <= 4)) {
|
||||
$property['without_dropdown'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean data
|
||||
$formTitle = Str::of($formTitle)->replace('"', '')->toString();
|
||||
|
||||
return Template::create([
|
||||
'name' => $formTitle,
|
||||
'description' => $formDescription,
|
||||
@@ -395,7 +372,7 @@ class GenerateTemplate extends Command
|
||||
|
||||
private function setReverseRelatedTemplates(Template $newTemplate)
|
||||
{
|
||||
if (! $newTemplate || count($newTemplate->related_templates) === 0) {
|
||||
if (!$newTemplate || count($newTemplate->related_templates) === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -406,4 +383,36 @@ class GenerateTemplate extends Command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function cleanAiOutput(array $formData): array
|
||||
{
|
||||
// Add property uuids, improve form with options
|
||||
foreach ($formData['properties'] as &$property) {
|
||||
$property['id'] = Str::uuid()->toString(); // Column ID
|
||||
|
||||
// Fix types
|
||||
if ($property['type'] == 'rating') {
|
||||
$property['rating_max_value'] = $property['rating_max_value'] ?? 5;
|
||||
} elseif ($property['type'] == 'scale') {
|
||||
$property['scale_min_value'] = $property['scale_min_value'] ?? 1;
|
||||
$property['scale_max_value'] = $property['scale_max_value'] ?? 5;
|
||||
$property['scale_step_value'] = $property['scale_step_value'] ?? 1;
|
||||
} elseif ($property['type'] == 'slider') {
|
||||
$property['slider_min_value'] = $property['slider_min_value'] ?? 0;
|
||||
$property['slider_max_value'] = $property['slider_max_value'] ?? 100;
|
||||
$property['slider_step_value'] = $property['slider_step_value'] ?? 1;
|
||||
}
|
||||
|
||||
if (($property['type'] == 'select' && count($property['select']['options']) <= 4)
|
||||
|| ($property['type'] == 'multi_select' && count($property['multi_select']['options']) <= 4)
|
||||
) {
|
||||
$property['without_dropdown'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Clean data
|
||||
$formData['title'] = Str::of($formData['title'])->replace('"', '')->toString();
|
||||
|
||||
return $formData;
|
||||
}
|
||||
}
|
||||
|
||||
69
app/Console/Commands/InputNumberMigration.php
Normal file
69
app/Console/Commands/InputNumberMigration.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Forms\Form;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class InputNumberMigration extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'forms:input-number-migration';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'One Time Only -- Separate input type for number (rating, scale, slider)';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Form::chunk(
|
||||
100,
|
||||
function ($forms) {
|
||||
foreach ($forms as $form) {
|
||||
$this->line('Process For Form: ' . $form->id . ' - ' . $form->slug);
|
||||
|
||||
$form->properties = collect($form->properties)->map(function ($property) {
|
||||
if ($property['type'] === 'number') {
|
||||
// Rating
|
||||
if (isset($property['is_rating']) && $property['is_rating']) {
|
||||
$this->line('Rating Field');
|
||||
$property['type'] = 'rating';
|
||||
unset($property['is_rating']);
|
||||
}
|
||||
|
||||
// Scale
|
||||
if (isset($property['is_scale']) && $property['is_scale']) {
|
||||
$this->line('Scale Field');
|
||||
$property['type'] = 'scale';
|
||||
unset($property['is_scale']);
|
||||
}
|
||||
|
||||
// Slider
|
||||
if (isset($property['is_slider']) && $property['is_slider']) {
|
||||
$this->line('Slider Field');
|
||||
$property['type'] = 'slider';
|
||||
unset($property['is_slider']);
|
||||
}
|
||||
}
|
||||
return $property;
|
||||
})->toArray();
|
||||
$form->update();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$this->line('Migration Done');
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class AnswerFormRequest extends FormRequest
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return ! $this->form->is_closed && ! $this->form->max_number_of_submissions_reached && $this->form->visibility === 'public';
|
||||
return !$this->form->is_closed && !$this->form->max_number_of_submissions_reached && $this->form->visibility === 'public';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ class AnswerFormRequest extends FormRequest
|
||||
if ($property['type'] == 'checkbox') {
|
||||
// Required for checkboxes means true
|
||||
$rules[] = 'accepted';
|
||||
} elseif ($property['type'] == 'number' && isset($property['is_rating']) && $property['is_rating']) {
|
||||
} elseif ($property['type'] == 'rating') {
|
||||
// For star rating, needs a minimum of 1 star
|
||||
$rules[] = 'min:1';
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class AnswerFormRequest extends FormRequest
|
||||
$propertyId = $property['id'];
|
||||
if (in_array($property['type'], ['multi_select'])) {
|
||||
$rules[] = 'array';
|
||||
$this->requestRules[$propertyId.'.*'] = $this->getPropertyRules($property);
|
||||
$this->requestRules[$propertyId . '.*'] = $this->getPropertyRules($property);
|
||||
} else {
|
||||
$rules = array_merge($rules, $this->getPropertyRules($property));
|
||||
}
|
||||
@@ -137,12 +137,12 @@ class AnswerFormRequest extends FormRequest
|
||||
$messages = [];
|
||||
foreach ($this->form->properties as $property) {
|
||||
if ($property['type'] == 'date' && isset($property['date_range']) && $property['date_range']) {
|
||||
$messages[$property['id'].'.0.required_with'] = 'From date is required';
|
||||
$messages[$property['id'].'.1.required_with'] = 'To date is required';
|
||||
$messages[$property['id'].'.0.before_or_equal'] = 'From date must be before or equal To date';
|
||||
$messages[$property['id'] . '.0.required_with'] = 'From date is required';
|
||||
$messages[$property['id'] . '.1.required_with'] = 'To date is required';
|
||||
$messages[$property['id'] . '.0.before_or_equal'] = 'From date must be before or equal To date';
|
||||
}
|
||||
if ($property['type'] == 'number' && isset($property['is_rating']) && $property['is_rating']) {
|
||||
$messages[$property['id'].'.min'] = 'A rating must be selected';
|
||||
if ($property['type'] == 'rating') {
|
||||
$messages[$property['id'] . '.min'] = 'A rating must be selected';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,10 +159,9 @@ class AnswerFormRequest extends FormRequest
|
||||
case 'signature':
|
||||
return ['string'];
|
||||
case 'number':
|
||||
if ($property['is_rating'] ?? false) {
|
||||
return ['numeric'];
|
||||
}
|
||||
|
||||
case 'rating':
|
||||
case 'scale':
|
||||
case 'slider':
|
||||
return ['numeric'];
|
||||
case 'select':
|
||||
case 'multi_select':
|
||||
@@ -175,7 +174,7 @@ class AnswerFormRequest extends FormRequest
|
||||
return ['boolean'];
|
||||
case 'url':
|
||||
if (isset($property['file_upload']) && $property['file_upload']) {
|
||||
$this->requestRules[$property['id'].'.*'] = [new StorageFile($this->maxFileSize, [], $this->form)];
|
||||
$this->requestRules[$property['id'] . '.*'] = [new StorageFile($this->maxFileSize, [], $this->form)];
|
||||
|
||||
return ['array'];
|
||||
}
|
||||
@@ -183,7 +182,7 @@ class AnswerFormRequest extends FormRequest
|
||||
return [new ValidUrl()];
|
||||
case 'files':
|
||||
$allowedFileTypes = [];
|
||||
if (! empty($property['allowed_file_types'])) {
|
||||
if (!empty($property['allowed_file_types'])) {
|
||||
$allowedFileTypes = explode(',', $property['allowed_file_types']);
|
||||
}
|
||||
$this->requestRules[$property['id'] . '.*'] = [new StorageFile($this->getFieldMaxFileSize($property), $allowedFileTypes, $this->form)];
|
||||
@@ -193,9 +192,9 @@ class AnswerFormRequest extends FormRequest
|
||||
return ['email:filter'];
|
||||
case 'date':
|
||||
if (isset($property['date_range']) && $property['date_range']) {
|
||||
$this->requestRules[$property['id'].'.*'] = $this->getRulesForDate($property);
|
||||
$this->requestRules[$property['id'].'.0'] = ['required_with:'.$property['id'].'.1', 'before_or_equal:'.$property['id'].'.1'];
|
||||
$this->requestRules[$property['id'].'.1'] = ['required_with:'.$property['id'].'.0'];
|
||||
$this->requestRules[$property['id'] . '.*'] = $this->getRulesForDate($property);
|
||||
$this->requestRules[$property['id'] . '.0'] = ['required_with:' . $property['id'] . '.1', 'before_or_equal:' . $property['id'] . '.1'];
|
||||
$this->requestRules[$property['id'] . '.1'] = ['required_with:' . $property['id'] . '.0'];
|
||||
|
||||
return ['array', 'min:2'];
|
||||
}
|
||||
@@ -226,7 +225,7 @@ class AnswerFormRequest extends FormRequest
|
||||
private function getSelectPropertyOptions($property): array
|
||||
{
|
||||
$type = $property['type'];
|
||||
if (! isset($property[$type])) {
|
||||
if (!isset($property[$type])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -242,7 +241,7 @@ class AnswerFormRequest extends FormRequest
|
||||
$receivedValue = $receivedData[$property['id']] ?? null;
|
||||
|
||||
// Escape all '\' in select options
|
||||
if (in_array($property['type'], ['select', 'multi_select']) && ! is_null($receivedValue)) {
|
||||
if (in_array($property['type'], ['select', 'multi_select']) && !is_null($receivedValue)) {
|
||||
if (is_array($receivedValue)) {
|
||||
$mergeData[$property['id']] = collect($receivedValue)->map(function ($value) {
|
||||
$value = Str::of($value);
|
||||
@@ -261,7 +260,7 @@ class AnswerFormRequest extends FormRequest
|
||||
}
|
||||
}
|
||||
|
||||
if ($property['type'] === 'phone_number' && (! isset($property['use_simple_text_input']) || ! $property['use_simple_text_input']) && $receivedValue && in_array($receivedValue, $countryCodeMapper)) {
|
||||
if ($property['type'] === 'phone_number' && (!isset($property['use_simple_text_input']) || !$property['use_simple_text_input']) && $receivedValue && in_array($receivedValue, $countryCodeMapper)) {
|
||||
$mergeData[$property['id']] = null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -53,7 +53,7 @@ class GenerateAiForm implements ShouldQueue
|
||||
|
||||
$this->completion->update([
|
||||
'status' => AiFormCompletion::STATUS_COMPLETED,
|
||||
'result' => $this->cleanOutput($completer->getArray()),
|
||||
'result' => GenerateTemplate::cleanAiOutput($completer->getArray())
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
$this->onError($e);
|
||||
@@ -61,16 +61,6 @@ class GenerateAiForm implements ShouldQueue
|
||||
|
||||
}
|
||||
|
||||
private function cleanOutput($formData)
|
||||
{
|
||||
// Add property uuids
|
||||
foreach ($formData['properties'] as &$property) {
|
||||
$property['id'] = Str::uuid()->toString();
|
||||
}
|
||||
|
||||
return $formData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a job failure.
|
||||
*/
|
||||
|
||||
@@ -288,6 +288,168 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
],
|
||||
],
|
||||
],
|
||||
'rating' => [
|
||||
'comparators' => [
|
||||
'equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'is_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'is_not_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'content_length_equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
],
|
||||
],
|
||||
'scale' => [
|
||||
'comparators' => [
|
||||
'equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'is_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'is_not_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'content_length_equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
],
|
||||
],
|
||||
'slider' => [
|
||||
'comparators' => [
|
||||
'equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'is_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'is_not_empty' => [
|
||||
'expected_type' => 'boolean',
|
||||
'format' => [
|
||||
'type' => 'enum',
|
||||
'values' => [true],
|
||||
],
|
||||
],
|
||||
'content_length_equals' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_does_not_equal' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_greater_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
'content_length_less_than_or_equal_to' => [
|
||||
'expected_type' => 'number',
|
||||
],
|
||||
],
|
||||
],
|
||||
'checkbox' => [
|
||||
'comparators' => [
|
||||
'equals' => [
|
||||
@@ -484,35 +646,35 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
private function checkBaseCondition($condition)
|
||||
{
|
||||
|
||||
if (! isset($condition['value'])) {
|
||||
if (!isset($condition['value'])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'missing condition body';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($condition['value']['property_meta'])) {
|
||||
if (!isset($condition['value']['property_meta'])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'missing condition property';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($condition['value']['property_meta']['type'])) {
|
||||
if (!isset($condition['value']['property_meta']['type'])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'missing condition property type';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($condition['value']['operator'])) {
|
||||
if (!isset($condition['value']['operator'])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'missing condition operator';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset($condition['value']['value'])) {
|
||||
if (!isset($condition['value']['value'])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'missing condition value';
|
||||
|
||||
@@ -523,14 +685,14 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
$operator = $condition['value']['operator'];
|
||||
$value = $condition['value']['value'];
|
||||
|
||||
if (! isset(self::CONDITION_MAPPING[$typeField])) {
|
||||
if (!isset(self::CONDITION_MAPPING[$typeField])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'configuration not found for condition type';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! isset(self::CONDITION_MAPPING[$typeField]['comparators'][$operator])) {
|
||||
if (!isset(self::CONDITION_MAPPING[$typeField]['comparators'][$operator])) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'configuration not found for condition operator';
|
||||
|
||||
@@ -546,11 +708,11 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
$foundCorrectType = true;
|
||||
}
|
||||
}
|
||||
if (! $foundCorrectType) {
|
||||
if (!$foundCorrectType) {
|
||||
$this->isConditionCorrect = false;
|
||||
}
|
||||
} else {
|
||||
if (! $this->valueHasCorrectType($type, $value)) {
|
||||
if (!$this->valueHasCorrectType($type, $value)) {
|
||||
$this->isConditionCorrect = false;
|
||||
$this->conditionErrors[] = 'wrong type of condition value';
|
||||
}
|
||||
@@ -561,9 +723,9 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
{
|
||||
if (
|
||||
($type === 'string' && gettype($value) !== 'string') ||
|
||||
($type === 'boolean' && ! is_bool($value)) ||
|
||||
($type === 'number' && ! is_numeric($value)) ||
|
||||
($type === 'object' && ! is_array($value))
|
||||
($type === 'boolean' && !is_bool($value)) ||
|
||||
($type === 'number' && !is_numeric($value)) ||
|
||||
($type === 'object' && !is_array($value))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@@ -588,7 +750,7 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
return;
|
||||
}
|
||||
|
||||
if (! is_array($conditions['children'])) {
|
||||
if (!is_array($conditions['children'])) {
|
||||
$this->conditionErrors[] = 'wrong sub-condition type';
|
||||
$this->isConditionCorrect = false;
|
||||
|
||||
@@ -607,11 +769,12 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
{
|
||||
if (is_array($actions) && count($actions) > 0) {
|
||||
foreach ($actions as $val) {
|
||||
if (! in_array($val, static::ACTIONS_VALUES) ||
|
||||
(in_array($this->field['type'], ['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image']) && ! in_array($val, ['hide-block', 'show-block'])) ||
|
||||
(isset($this->field['hidden']) && $this->field['hidden'] && ! in_array($val, ['show-block', 'require-answer'])) ||
|
||||
(isset($this->field['required']) && $this->field['required'] && ! in_array($val, ['make-it-optional', 'hide-block', 'disable-block'])) ||
|
||||
(isset($this->field['disabled']) && $this->field['disabled'] && ! in_array($val, ['enable-block', 'require-answer', 'make-it-optional']))
|
||||
if (
|
||||
!in_array($val, static::ACTIONS_VALUES) ||
|
||||
(in_array($this->field['type'], ['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image']) && !in_array($val, ['hide-block', 'show-block'])) ||
|
||||
(isset($this->field['hidden']) && $this->field['hidden'] && !in_array($val, ['show-block', 'require-answer'])) ||
|
||||
(isset($this->field['required']) && $this->field['required'] && !in_array($val, ['make-it-optional', 'hide-block', 'disable-block'])) ||
|
||||
(isset($this->field['disabled']) && $this->field['disabled'] && !in_array($val, ['enable-block', 'require-answer', 'make-it-optional']))
|
||||
) {
|
||||
$this->isActionCorrect = false;
|
||||
break;
|
||||
@@ -646,13 +809,13 @@ class FormPropertyLogicRule implements DataAwareRule, Rule
|
||||
public function message()
|
||||
{
|
||||
$message = null;
|
||||
if (! $this->isConditionCorrect) {
|
||||
$message = 'The logic conditions for '.$this->field['name'].' are not complete.';
|
||||
} elseif (! $this->isActionCorrect) {
|
||||
$message = 'The logic actions for '.$this->field['name'].' are not valid.';
|
||||
if (!$this->isConditionCorrect) {
|
||||
$message = 'The logic conditions for ' . $this->field['name'] . ' are not complete.';
|
||||
} elseif (!$this->isActionCorrect) {
|
||||
$message = 'The logic actions for ' . $this->field['name'] . ' are not valid.';
|
||||
}
|
||||
if (count($this->conditionErrors) > 0) {
|
||||
return $message.' Error detail(s): '.implode(', ', $this->conditionErrors);
|
||||
return $message . ' Error detail(s): ' . implode(', ', $this->conditionErrors);
|
||||
}
|
||||
|
||||
return $message;
|
||||
|
||||
@@ -15,19 +15,19 @@ class FormLogicConditionChecker
|
||||
|
||||
private function conditionsAreMet(?array $conditions, array $formData): bool
|
||||
{
|
||||
if (! $conditions) {
|
||||
if (!$conditions) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's not a group, just a single condition
|
||||
if (! isset($conditions['operatorIdentifier'])) {
|
||||
if (!isset($conditions['operatorIdentifier'])) {
|
||||
return $this->propertyConditionMet($conditions['value'], $formData[$conditions['value']['property_meta']['id']] ?? null);
|
||||
}
|
||||
|
||||
if ($conditions['operatorIdentifier'] === 'and') {
|
||||
$isvalid = true;
|
||||
foreach ($conditions['children'] as $childrenCondition) {
|
||||
if (! $this->conditionsMet($childrenCondition, $formData)) {
|
||||
if (!$this->conditionsMet($childrenCondition, $formData)) {
|
||||
$isvalid = false;
|
||||
break;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ class FormLogicConditionChecker
|
||||
return $isvalid;
|
||||
}
|
||||
|
||||
throw new \Exception('Unexcepted operatorIdentifier:'.$conditions['operatorIdentifier']);
|
||||
throw new \Exception('Unexcepted operatorIdentifier:' . $conditions['operatorIdentifier']);
|
||||
}
|
||||
|
||||
private function propertyConditionMet(array $propertyCondition, $value): bool
|
||||
@@ -58,6 +58,9 @@ class FormLogicConditionChecker
|
||||
case 'phone_number':
|
||||
return $this->textConditionMet($propertyCondition, $value);
|
||||
case 'number':
|
||||
case 'rating':
|
||||
case 'scale':
|
||||
case 'slider':
|
||||
return $this->numberConditionMet($propertyCondition, $value);
|
||||
case 'checkbox':
|
||||
return $this->checkboxConditionMet($propertyCondition, $value);
|
||||
@@ -90,7 +93,7 @@ class FormLogicConditionChecker
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! is_array($fieldValue)) {
|
||||
if (!is_array($fieldValue)) {
|
||||
return $this->checkEquals($condition, $fieldValue);
|
||||
}
|
||||
|
||||
@@ -117,7 +120,7 @@ class FormLogicConditionChecker
|
||||
return count($fieldValue) === 0;
|
||||
}
|
||||
|
||||
return $fieldValue == '' || $fieldValue == null || ! $fieldValue;
|
||||
return $fieldValue == '' || $fieldValue == null || !$fieldValue;
|
||||
}
|
||||
|
||||
private function checkGreaterThan($condition, $fieldValue): bool
|
||||
@@ -162,7 +165,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkPastWeek($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -172,7 +175,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkPastMonth($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -182,7 +185,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkPastYear($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -192,7 +195,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkNextWeek($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -202,7 +205,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkNextMonth($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -212,7 +215,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkNextYear($condition, $fieldValue): bool
|
||||
{
|
||||
if (! $fieldValue) {
|
||||
if (!$fieldValue) {
|
||||
return false;
|
||||
}
|
||||
$fieldDate = date('Y-m-d', strtotime($fieldValue));
|
||||
@@ -222,7 +225,7 @@ class FormLogicConditionChecker
|
||||
|
||||
private function checkLength($condition, $fieldValue, $operator = '==='): bool
|
||||
{
|
||||
if (! $fieldValue || strlen($fieldValue) === 0) {
|
||||
if (!$fieldValue || strlen($fieldValue) === 0) {
|
||||
return false;
|
||||
}
|
||||
switch ($operator) {
|
||||
@@ -249,11 +252,11 @@ class FormLogicConditionChecker
|
||||
case 'equals':
|
||||
return $this->checkEquals($propertyCondition, $value);
|
||||
case 'does_not_equal':
|
||||
return ! $this->checkEquals($propertyCondition, $value);
|
||||
return !$this->checkEquals($propertyCondition, $value);
|
||||
case 'contains':
|
||||
return $this->checkContains($propertyCondition, $value);
|
||||
case 'does_not_contain':
|
||||
return ! $this->checkContains($propertyCondition, $value);
|
||||
return !$this->checkContains($propertyCondition, $value);
|
||||
case 'starts_with':
|
||||
return $this->checkStartsWith($propertyCondition, $value);
|
||||
case 'ends_with':
|
||||
@@ -261,7 +264,7 @@ class FormLogicConditionChecker
|
||||
case 'is_empty':
|
||||
return $this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'is_not_empty':
|
||||
return ! $this->checkIsEmpty($propertyCondition, $value);
|
||||
return !$this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'content_length_equals':
|
||||
return $this->checkLength($propertyCondition, $value, '===');
|
||||
case 'content_length_does_not_equal':
|
||||
@@ -285,7 +288,7 @@ class FormLogicConditionChecker
|
||||
case 'equals':
|
||||
return $this->checkEquals($propertyCondition, $value);
|
||||
case 'does_not_equal':
|
||||
return ! $this->checkEquals($propertyCondition, $value);
|
||||
return !$this->checkEquals($propertyCondition, $value);
|
||||
case 'greater_than':
|
||||
return $this->checkGreaterThan($propertyCondition, $value);
|
||||
case 'less_than':
|
||||
@@ -297,7 +300,7 @@ class FormLogicConditionChecker
|
||||
case 'is_empty':
|
||||
return $this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'is_not_empty':
|
||||
return ! $this->checkIsEmpty($propertyCondition, $value);
|
||||
return !$this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'content_length_equals':
|
||||
return $this->checkLength($propertyCondition, $value, '===');
|
||||
case 'content_length_does_not_equal':
|
||||
@@ -321,7 +324,7 @@ class FormLogicConditionChecker
|
||||
case 'equals':
|
||||
return $this->checkEquals($propertyCondition, $value);
|
||||
case 'does_not_equal':
|
||||
return ! $this->checkEquals($propertyCondition, $value);
|
||||
return !$this->checkEquals($propertyCondition, $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -333,11 +336,11 @@ class FormLogicConditionChecker
|
||||
case 'equals':
|
||||
return $this->checkEquals($propertyCondition, $value);
|
||||
case 'does_not_equal':
|
||||
return ! $this->checkEquals($propertyCondition, $value);
|
||||
return !$this->checkEquals($propertyCondition, $value);
|
||||
case 'is_empty':
|
||||
return $this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'is_not_empty':
|
||||
return ! $this->checkIsEmpty($propertyCondition, $value);
|
||||
return !$this->checkIsEmpty($propertyCondition, $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -381,11 +384,11 @@ class FormLogicConditionChecker
|
||||
case 'contains':
|
||||
return $this->checkListContains($propertyCondition, $value);
|
||||
case 'does_not_contain':
|
||||
return ! $this->checkListContains($propertyCondition, $value);
|
||||
return !$this->checkListContains($propertyCondition, $value);
|
||||
case 'is_empty':
|
||||
return $this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'is_not_empty':
|
||||
return ! $this->checkIsEmpty($propertyCondition, $value);
|
||||
return !$this->checkIsEmpty($propertyCondition, $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -397,7 +400,7 @@ class FormLogicConditionChecker
|
||||
case 'is_empty':
|
||||
return $this->checkIsEmpty($propertyCondition, $value);
|
||||
case 'is_not_empty':
|
||||
return ! $this->checkIsEmpty($propertyCondition, $value);
|
||||
return !$this->checkIsEmpty($propertyCondition, $value);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user