Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rich text format for custom fields #18481

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/Glpi/Asset/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use Dropdown;
use Entity;
use Glpi\Application\View\TemplateRenderer;
use Glpi\Asset\CustomFieldType\TextType;
use Glpi\CustomObject\CustomObjectTrait;
use Group;
use Group_Item;
Expand All @@ -55,6 +56,7 @@ abstract class Asset extends CommonDBTM
use \Glpi\Features\AssignableItem {
getEmpty as getEmptyFromAssignableItem;
post_getFromDB as post_getFromDBFromAssignableItem;
post_addItem as post_addItemFromAssignableItem;
post_updateItem as post_updateItemFromAssignableItem;
}
use \Glpi\Features\Clonable;
Expand Down Expand Up @@ -440,6 +442,13 @@ public function pre_updateInDB()
}
}

public function post_addItem()
{
$this->post_addItemFromAssignableItem();

$this->addFilesFromRichTextCustomFields();
}

public function post_updateItem($history = true)
{
$this->post_updateItemFromAssignableItem($history);
Expand All @@ -465,6 +474,44 @@ public function post_updateItem($history = true)
}
}
}
$this->addFilesFromRichTextCustomFields();
}

/**
* Add files from rich text custom fields.
*/
private function addFilesFromRichTextCustomFields(): void
{
$need_update = false;
foreach (static::getDefinition()->getCustomFieldDefinitions() as $custom_field) {
if (
$custom_field->fields['type'] !== TextType::class
|| ($custom_field->fields['field_options']['enable_richtext'] ?? false) === false
|| ($custom_field->fields['field_options']['enable_images'] ?? false) === false
) {
continue;
}

$custom_field_name = sprintf('custom_%s', $custom_field->fields['system_name']);
$current_value = $this->input[$custom_field_name];

$this->input = $this->addFiles(
$this->input,
[
'force_update' => false,
'name' => $custom_field_name,
'content_field' => $custom_field_name,
]
);

if ($this->input[$custom_field_name] !== $current_value) {
$need_update = true;
}
}

if ($need_update) {
(new static())->update($this->input, history: false);
}
}

public function getNonLoggedFields(): array
Expand Down
13 changes: 12 additions & 1 deletion src/Glpi/Asset/Capacity/HasDocumentsCapacity.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ public function getCloneRelations(): array

public function isUsed(string $classname): bool
{
// TODO filter using 'timeline_position' => 0 criteria
return parent::isUsed($classname)
&& $this->countAssetsLinkedToPeerItem($classname, Document_Item::class) > 0;
}

public function getCapacityUsageDescription(string $classname): string
{
// TODO filter using 'timeline_position' => 0 criteria
return sprintf(
__('%1$s documents attached to %2$s assets'),
$this->countPeerItemsUsage($classname, Document_Item::class),
Expand All @@ -95,7 +97,16 @@ public function onCapacityDisabled(string $classname): void

// Delete relations to documents
$document_item = new Document_Item();
$document_item->deleteByCriteria(['itemtype' => $classname], force: true, history: false);
$document_item->deleteByCriteria(
[
'itemtype' => $classname,
// 0 is the value when a document is attached manually
// filtering on this value prevents removal of documents attached from rich text fields
'timeline_position' => 0,
],
force: true,
history: false
);

// Clean history related to documents
$this->deleteRelationLogs($classname, Document::class);
Expand Down
11 changes: 10 additions & 1 deletion src/Glpi/Asset/CustomFieldType/TextType.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
namespace Glpi\Asset\CustomFieldType;

use Glpi\Application\View\TemplateRenderer;
use Glpi\Asset\CustomFieldOption\BooleanOption;

class TextType extends AbstractType
{
Expand All @@ -43,6 +44,14 @@ public static function getName(): string
return __('Text');
}

public function getOptions(): array
{
$opts = parent::getOptions();
$opts[] = new BooleanOption($this->custom_field, 'enable_richtext', __('Rich text'), true, false);
$opts[] = new BooleanOption($this->custom_field, 'enable_images', __('Allow images'), false, false);
return $opts;
}

public function getFormInput(string $name, mixed $value, ?string $label = null, bool $for_default = false): string
{
$twig_params = [
Expand All @@ -54,7 +63,7 @@ public function getFormInput(string $name, mixed $value, ?string $label = null,
// language=Twig
return TemplateRenderer::getInstance()->renderFromStringTemplate(<<<TWIG
{% import 'components/form/fields_macros.html.twig' as fields %}
{{ fields.textareaField(name, value, label, field_options) }}
{{ fields.textareaField(name, field_options.enable_richtext ? value : value|html_to_text, label, field_options) }}
TWIG, $twig_params);
}

Expand Down
3 changes: 2 additions & 1 deletion src/autoload/CFG_GLPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@
]
],
'assets' => [
'tinymce',
'dashboard' => ['dashboard'],
'rack' => ['gridstack', 'rack'],
'printer' => ['dashboard'],
Expand Down Expand Up @@ -541,7 +542,7 @@
],
],
'config' => [
'assetdefinition' => ['sortable'],
'glpi\asset\assetdefinition' => ['sortable', 'tinymce'],
'commondropdown' => [
'ITILFollowupTemplate' => ['tinymce'],
'ProjectTaskTemplate' => ['tinymce'],
Expand Down
7 changes: 7 additions & 0 deletions tests/cypress/e2e/Asset/custom_fields.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,12 @@ describe("Custom Assets - Custom Fields", () => {
if (options.has('mandatory')) {
cy.findByLabelText('Mandatory').check();
}
if (options.has('enable_richtext')) {
cy.findByLabelText('Rich text').check();
}
if (options.has('enable_images')) {
cy.findByLabelText('Allow images').check();
}

cy.findByRole('button', {name: 'Add'}).click();
});
Expand All @@ -175,6 +181,7 @@ describe("Custom Assets - Custom Fields", () => {
createField('Test MultiDropdown', 'Dropdown', new Map([['item_type', 'Monitor'], ['multiple_values', true]]));
createField('Test URL', 'URL');
createField('Test YesNo', 'Yes/No');
createField('Test RichText', 'Text', new Map([['enable_richtext', true], ['enable_images', true]]));

// Intercept form submission to check the form display values sent
cy.intercept('POST', '/front/asset/assetdefinition.form.php').as('saveFieldsDisplay');
Expand Down