From 2f60d0a4699a97c2d6c311eefcefe71b65a81727 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 15 Mar 2023 12:19:15 -0500 Subject: [PATCH] System template: Template image file location in v2 - refs #3804 --- public/main/admin/settings.lib.php | 104 +++++++++++------- src/CoreBundle/Entity/Asset.php | 1 + src/CoreBundle/Entity/SystemTemplate.php | 21 ++-- .../Schema/V200/Version20230315111019.php | 36 ++++++ .../Schema/V200/Version20230315115019.php | 71 ++++++++++++ 5 files changed, 184 insertions(+), 49 deletions(-) create mode 100644 src/CoreBundle/Migrations/Schema/V200/Version20230315111019.php create mode 100644 src/CoreBundle/Migrations/Schema/V200/Version20230315115019.php diff --git a/public/main/admin/settings.lib.php b/public/main/admin/settings.lib.php index 7787cddd5a..c58528afe9 100644 --- a/public/main/admin/settings.lib.php +++ b/public/main/admin/settings.lib.php @@ -5,6 +5,8 @@ use Chamilo\CoreBundle\Component\Utils\ChamiloApi; use Chamilo\CoreBundle\Entity\SystemTemplate; use ChamiloSession as Session; use Symfony\Component\Filesystem\Filesystem; +use Chamilo\CoreBundle\Framework\Container; +use Chamilo\CoreBundle\Entity\Asset; /** * Library of the settings.php file. @@ -1030,7 +1032,7 @@ function getTemplateData($from, $number_of_items, $column, $direction) $column = (int) $column; $direction = !in_array(strtolower(trim($direction)), ['asc', 'desc']) ? 'asc' : $direction; // The sql statement. - $sql = "SELECT image as col0, title as col1, id as col2 FROM $table_system_template"; + $sql = "SELECT id as col0, title as col1, id as col2 FROM $table_system_template"; $sql .= " ORDER BY col$column $direction "; $sql .= " LIMIT $from,$number_of_items"; $result = Database::query($sql); @@ -1077,10 +1079,18 @@ function actionsFilter($id) * * @since v1.8.6 */ -function searchImageFilter($image) +function searchImageFilter($id) { - if (!empty($image)) { - return ''.get_lang('Template preview').''; + $em = Database::getManager(); + + /** @var SystemTemplate $template */ + $template = $em->find('ChamiloCoreBundle:SystemTemplate', $id); + + $assetRepo = Container::getAssetRepository(); + $imageUrl = $assetRepo->getAssetUrl($template->getImage()); + + if (!empty($imageUrl)) { + return ''.get_lang('Template preview').''; } else { return ''.get_lang('NoTemplate preview').''; } @@ -1101,6 +1111,8 @@ function addEditTemplate() $em = Database::getManager(); $id = isset($_GET['id']) ? (int) $_GET['id'] : 0; + $assetRepo = Container::getAssetRepository(); + /** @var SystemTemplate $template */ $template = $id ? $em->find('ChamiloCoreBundle:SystemTemplate', $id) : new SystemTemplate(); @@ -1132,8 +1144,15 @@ function addEditTemplate() ); // Setting the form elements: the form to upload an image to be used with the template. - if (empty($template->getImage())) { - $form->addElement('file', 'template_image', get_lang('Image'), ''); + if (!$template->hasImage()) { + // Picture + $form->addFile( + 'template_image', + get_lang('Add image'), + ['id' => 'picture', 'class' => 'picture-form', 'crop_image' => true, 'crop_ratio' => '1 / 1'] + ); + $allowedPictureTypes = api_get_supported_image_extensions(false); + $form->addRule('template_image', get_lang('Only PNG, JPG or GIF images allowed').' ('.implode(',', $allowedPictureTypes).')', 'filetype', $allowedPictureTypes); } // Setting the form elements: a little bit information about the template image. @@ -1152,12 +1171,13 @@ function addEditTemplate() // Adding an extra field: a preview of the image that is currently used. - if (!empty($template->getImage())) { + if ($template->hasImage()) { + $imageUrl = $assetRepo->getAssetUrl($template->getImage()); $form->addElement( 'static', 'template_image_preview', '', - ''.get_lang('Template preview')
                     .'' ); @@ -1178,7 +1198,7 @@ function addEditTemplate() $form->addButtonSave(get_lang('Validate'), 'submit'); // Setting the rules: the required fields. - if (empty($template->getImage())) { + if (!$template->hasImage()) { $form->addRule( 'template_image', get_lang('Required field'), @@ -1195,38 +1215,23 @@ function addEditTemplate() if ($check) { // Exporting the values. $values = $form->exportValues(); - $isDelete = null; - if (isset($values['delete_image'])) { - $isDelete = $values['delete_image']; + $asset = null; + if (isset($values['delete_image']) && !empty($id)) { + deleteTemplateImage($id); } // Upload the file. if (!empty($_FILES['template_image']['name'])) { - $upload_ok = process_uploaded_file($_FILES['template_image']); - - if ($upload_ok) { - // Try to add an extension to the file if it hasn't one. - $new_file_name = add_ext_on_mime(stripslashes($_FILES['template_image']['name']), $_FILES['template_image']['type']); - - // The upload directory. - // todo - - $upload_dir = api_get_path(SYS_PATH).'home/default_platform_document/template_thumb/'; - - // Create the directory if it does not exist. - if (!is_dir($upload_dir)) { - mkdir($upload_dir, api_get_permissions_for_new_directories()); + $picture = $_FILES['template_image']; + if (!empty($picture['name'])) { + $asset = (new Asset()) + ->setCategory(Asset::SYSTEM_TEMPLATE) + ->setTitle($picture['name']) + ; + if (!empty($values['picture_crop_result'])) { + $asset->setCrop($values['picture_crop_result']); } - - // Resize the preview image to max default and upload. - $temp = new Image($_FILES['template_image']['tmp_name']); - $picture_info = $temp->get_image_info(); - - $max_width_for_picture = 100; - if ($picture_info['width'] > $max_width_for_picture) { - $temp->resize($max_width_for_picture); - } - $temp->send_image($upload_dir.$new_file_name); + $asset = $assetRepo->createFromRequest($asset, $picture); } } @@ -1241,7 +1246,7 @@ function addEditTemplate() ->setTitle($values['title']) ->setComment(Security::remove_XSS($values['comment'])) ->setContent(Security::remove_XSS($templateContent, COURSEMANAGERLOWSECURITY)) - ->setImage($new_file_name); + ->setImage($asset); $em->persist($template); $em->flush(); @@ -1261,8 +1266,8 @@ function addEditTemplate() ->setTitle($values['title']) ->setContent(Security::remove_XSS($templateContent, COURSEMANAGERLOWSECURITY)); - if (!empty($new_file_name)) { - $template->setImage($new_file_name); + if ($asset) { + $template->setImage($asset); } $em->persist($template); @@ -1283,6 +1288,25 @@ function addEditTemplate() } } +/** + * Deletes the template picture as asset. + * + * @param int $id + */ +function deleteTemplateImage($id) +{ + $em = Database::getManager(); + + /** @var SystemTemplate $template */ + $template = $em->find('ChamiloCoreBundle:SystemTemplate', $id); + + if ($template && $template->hasImage()) { + $image = $template->getImage(); + $em->remove($image); + $em->flush(); + } +} + /** * Delete a template. * @@ -1310,6 +1334,8 @@ function deleteTemplate($id) $sql = "DELETE FROM $table WHERE id = $id"; Database::query($sql); + deleteTemplateImage($id); + // Display a feedback message. echo Display::return_message(get_lang('Template deleted'), 'confirm'); } diff --git a/src/CoreBundle/Entity/Asset.php b/src/CoreBundle/Entity/Asset.php index 7b0be59ce1..2ea5a61f4a 100644 --- a/src/CoreBundle/Entity/Asset.php +++ b/src/CoreBundle/Entity/Asset.php @@ -35,6 +35,7 @@ class Asset public const SKILL = 'skill'; public const EXERCISE_ATTEMPT = 'exercise_attempt'; public const EXERCISE_FEEDBACK = 'exercise_feedback'; + public const SYSTEM_TEMPLATE = 'system_template'; /** * @ORM\Id diff --git a/src/CoreBundle/Entity/SystemTemplate.php b/src/CoreBundle/Entity/SystemTemplate.php index 8ae1dd5985..a696b58dd9 100644 --- a/src/CoreBundle/Entity/SystemTemplate.php +++ b/src/CoreBundle/Entity/SystemTemplate.php @@ -34,9 +34,10 @@ class SystemTemplate protected string $comment; /** - * @ORM\Column(name="image", type="string", length=250, nullable=false) + * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Asset", cascade={"persist"} ) + * @ORM\JoinColumn(name="image_id", referencedColumnName="id", onDelete="SET NULL") */ - protected string $image; + protected ?Asset $image = null; /** * @ORM\Column(name="content", type="text", nullable=false) @@ -82,21 +83,21 @@ class SystemTemplate return $this->comment; } - public function setImage(string $image): self + public function getImage(): ?Asset + { + return $this->image; + } + + public function setImage(?Asset $image): self { $this->image = $image; return $this; } - /** - * Get image. - * - * @return string - */ - public function getImage() + public function hasImage(): bool { - return $this->image; + return null !== $this->image; } public function setContent(string $content): self diff --git a/src/CoreBundle/Migrations/Schema/V200/Version20230315111019.php b/src/CoreBundle/Migrations/Schema/V200/Version20230315111019.php new file mode 100644 index 0000000000..3d89961c30 --- /dev/null +++ b/src/CoreBundle/Migrations/Schema/V200/Version20230315111019.php @@ -0,0 +1,36 @@ +getTable('system_template'); + if (false === $table->hasColumn('image_id')) { + $this->addSql("ALTER TABLE system_template ADD image_id BINARY(16) DEFAULT NULL COMMENT '(DC2Type:uuid)', DROP image;"); + $this->addSql("ALTER TABLE system_template ADD CONSTRAINT FK_FE8AAE013DA5256D FOREIGN KEY (image_id) REFERENCES asset(id) ON DELETE SET NULL;"); + $this->addSql("CREATE INDEX IDX_FE8AAE013DA5256D ON system_template (image_id);"); + } + } + + public function down(Schema $schema): void + { + $table = $schema->getTable('system_template'); + if (false !== $table->hasColumn('image_id')) { + $this->addSql("ALTER TABLE system_template DROP FOREIGN KEY FK_FE8AAE013DA5256D;"); + $this->addSql("ALTER TABLE system_template DROP INDEX IDX_FE8AAE013DA5256D;"); + $this->addSql("ALTER TABLE system_template CHANGE image_id image varchar(250) NOT NULL COMMENT '(DC2Type:uuid)';"); + } + } +} diff --git a/src/CoreBundle/Migrations/Schema/V200/Version20230315115019.php b/src/CoreBundle/Migrations/Schema/V200/Version20230315115019.php new file mode 100644 index 0000000000..e06c5b9cf4 --- /dev/null +++ b/src/CoreBundle/Migrations/Schema/V200/Version20230315115019.php @@ -0,0 +1,71 @@ +getContainer(); + + /** @var Kernel $kernel */ + $kernel = $container->get('kernel'); + $rootPath = $kernel->getProjectDir(); + + $em = $this->getEntityManager(); + $connection = $em->getConnection(); + $sql = 'SELECT * FROM system_template'; + $result = $connection->executeQuery($sql); + $all = $result->fetchAllAssociative(); + + $table = $schema->getTable('system_template'); + + if ($table->hasColumn('image')) { + foreach ($all as $systemTemplate) { + if (!empty($systemTemplate['image'])) { + + /** @var SystemTemplate $template */ + $template = $em->find('ChamiloCoreBundle:SystemTemplate', $systemTemplate['id']); + if ($template->hasImage()) { + continue; + } + + $filePath = $rootPath.'/app/home/default_platform_document/template_thumb/'.$systemTemplate['image']; + if ($this->fileExists($filePath)) { + $fileName = basename($filePath); + $mimeType = mime_content_type($filePath); + $file = new UploadedFile($filePath, $fileName, $mimeType, null, true); + $asset = (new Asset()) + ->setCategory(Asset::SYSTEM_TEMPLATE) + ->setTitle($fileName) + ->setFile($file) + ; + $em->persist($asset); + $em->flush(); + $template->setImage($asset); + + $em->persist($template); + $em->flush(); + } + } + } + } + } + + public function down(Schema $schema): void + { + + } +}