diff --git a/public/main/admin/settings.lib.php b/public/main/admin/settings.lib.php index 227c08b966..bd0331503d 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; use Chamilo\CoreBundle\Component\Utils\ActionIcon; use Chamilo\CoreBundle\Component\Utils\ObjectIcon; use Chamilo\CoreBundle\Component\Utils\StateIcon; @@ -1031,7 +1033,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); @@ -1078,10 +1080,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(SystemTemplate::class, $id); + + $assetRepo = Container::getAssetRepository(); + $imageUrl = $assetRepo->getAssetUrl($template->getImage()); + + if (!empty($imageUrl)) { + return ''.get_lang('Template preview').''; } else { return ''.get_lang('NoTemplate preview').''; } @@ -1102,8 +1112,10 @@ 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(); + $template = $id ? $em->find(SystemTemplate::class, $id) : new SystemTemplate(); $form = new FormValidator( 'template', @@ -1133,11 +1145,18 @@ 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. + // Setting the form elements: a little bit of information about the template image. $form->addElement('static', 'file_comment', '', get_lang('This image will represent the template in the templates list. It should be no larger than 100x70 pixels')); // Getting all the information of the template when editing a template. @@ -1153,12 +1172,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')
                     .'' ); @@ -1179,7 +1199,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'), @@ -1196,38 +1216,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); } } @@ -1242,7 +1247,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(); @@ -1262,8 +1267,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); @@ -1284,6 +1289,25 @@ function addEditTemplate() } } +/** + * Deletes the template picture as asset. + * + * @param int $id + */ +function deleteTemplateImage($id) +{ + $em = Database::getManager(); + + /** @var SystemTemplate $template */ + $template = $em->find(SystemTemplate::class, $id); + + if ($template && $template->hasImage()) { + $image = $template->getImage(); + $em->remove($image); + $em->flush(); + } +} + /** * Delete a template. * @@ -1311,6 +1335,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 13d45a54cc..9f2770e5b4 100644 --- a/src/CoreBundle/Entity/Asset.php +++ b/src/CoreBundle/Entity/Asset.php @@ -36,6 +36,7 @@ class Asset implements Stringable public const SKILL = 'skill'; public const EXERCISE_ATTEMPT = 'exercise_attempt'; public const EXERCISE_FEEDBACK = 'exercise_feedback'; + public const SYSTEM_TEMPLATE = 'system_template'; public const SESSION = 'session'; #[ORM\Id] diff --git a/src/CoreBundle/Entity/SystemTemplate.php b/src/CoreBundle/Entity/SystemTemplate.php index 86322af8d9..1f29242b71 100644 --- a/src/CoreBundle/Entity/SystemTemplate.php +++ b/src/CoreBundle/Entity/SystemTemplate.php @@ -26,8 +26,10 @@ class SystemTemplate #[ORM\Column(name: 'comment', type: 'text', nullable: false)] protected string $comment; - #[ORM\Column(name: 'image', type: 'string', length: 250, nullable: false)] - protected string $image; + #[ORM\ManyToOne(targetEntity: Asset::class, cascade: ['persist'])] + #[ORM\JoinColumn(name: 'image_id', referencedColumnName: 'id', onDelete: 'SET NULL')] + protected ?Asset $image = null; + #[ORM\Column(name: 'content', type: 'text', nullable: false)] protected string $content; @@ -74,21 +76,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 + { + + } +}