Course category: Add tests, fix CRUD course category asset + add migration

pull/3965/head
Julio 4 years ago
parent b091efd370
commit 4cd9798949
  1. 8
      public/main/admin/course_category.php
  2. 51
      public/main/inc/lib/course_category.lib.php
  3. 30
      src/CoreBundle/Entity/CourseCategory.php
  4. 7
      src/CoreBundle/EventListener/AssetListener.php
  5. 61
      src/CoreBundle/Migrations/Schema/V200/Version20191101132000.php
  6. 11
      src/CoreBundle/Repository/CourseCategoryRepository.php
  7. 141
      tests/CoreBundle/Repository/CourseCategoryRepositoryTest.php

@ -92,11 +92,11 @@ switch ($action) {
// Delete Picture Category // Delete Picture Category
$deletePicture = $_POST['delete_picture'] ?? ''; $deletePicture = $_POST['delete_picture'] ?? '';
var_dump($deletePicture);
if ($deletePicture) { if ($deletePicture && $categoryEntity) {
CourseCategory::deleteImage($categoryEntity); $categoryRepo->deleteAsset($categoryEntity);
} }
exit;
if (isset($_FILES['image']) && $categoryEntity) { if (isset($_FILES['image']) && $categoryEntity) {
$crop = $_POST['picture_crop_result'] ?? ''; $crop = $_POST['picture_crop_result'] ?? '';
CourseCategory::saveImage($categoryEntity, $_FILES['image'], $crop); CourseCategory::saveImage($categoryEntity, $_FILES['image'], $crop);

@ -203,27 +203,15 @@ class CourseCategory
Database::query($sql); Database::query($sql);
} }
public static function delete($categoryId): bool public static function edit($categoryId, $name, $canHaveCourses, $code, $description): ?CourseCategoryEntity
{ {
$repo = Container::getCourseCategoryRepository(); $repo = Container::getCourseCategoryRepository();
$category = $repo->find($categoryId); $category = $repo->find($categoryId);
if (null === $category) { if (null === $category) {
return false; return null;
} }
$repo->delete($category); $name = trim($name);
return true;
}
public static function edit($categoryId, $name, $canHaveCourses, $code, $description): CourseCategoryEntity
{
$name = trim(Database::escape_string($name));
$canHaveCourses = Database::escape_string($canHaveCourses);
$repo = Container::getCourseCategoryRepository();
$category = $repo->find($categoryId);
$category $category
->setCode($name) ->setCode($name)
->setName($name) ->setName($name)
@ -837,26 +825,6 @@ class CourseCategory
return $nameTools; return $nameTools;
} }
public static function deleteImage(CourseCategoryEntity $category)
{
$assetId = $category->getImage();
if (empty($assetId)) {
return false;
}
$assetRepo = Container::getAssetRepository();
/** @var Asset $asset */
$asset = $assetRepo->find($assetId);
if (null !== $asset) {
$category->setImage('');
$assetRepo->delete($asset);
$repo = Container::getCourseCategoryRepository();
$repo->save($category);
}
return true;
}
/** /**
* Save image for a course category. * Save image for a course category.
* *
@ -865,19 +833,18 @@ class CourseCategory
public static function saveImage(CourseCategoryEntity $category, $fileData, $crop = '') public static function saveImage(CourseCategoryEntity $category, $fileData, $crop = '')
{ {
if (isset($fileData['tmp_name']) && !empty($fileData['tmp_name'])) { if (isset($fileData['tmp_name']) && !empty($fileData['tmp_name'])) {
self::deleteImage($category); $repo = Container::getCourseCategoryRepository();
$repo->deleteAsset($category);
$repo = Container::getAssetRepository(); $assetRepo = Container::getAssetRepository();
$asset = new Asset(); $asset = (new Asset())
$asset
->setCategory(Asset::COURSE_CATEGORY) ->setCategory(Asset::COURSE_CATEGORY)
->setTitle($fileData['name']) ->setTitle($fileData['name'])
->setCrop($crop) ->setCrop($crop)
; ;
$asset = $repo->createFromRequest($asset, $fileData); $asset = $assetRepo->createFromRequest($asset, $fileData);
$category->setImage($asset->getId()); $category->setAsset($asset);
$repo = Container::getCourseCategoryRepository();
$repo->save($category); $repo->save($category);
} }
} }

@ -57,17 +57,17 @@ class CourseCategory
protected Collection $children; protected Collection $children;
/** /**
* @Assert\NotBlank()
* @Groups({"course_category:read", "course_category:write", "course:read"}) * @Groups({"course_category:read", "course_category:write", "course:read"})
* @ORM\Column(name="name", type="text", nullable=false) * @ORM\Column(name="name", type="text", nullable=false)
*/ */
#[Assert\NotBlank]
protected string $name; protected string $name;
/** /**
* @Assert\NotBlank()
* @Groups({"course_category:read", "course_category:write", "course:read"}) * @Groups({"course_category:read", "course_category:write", "course:read"})
* @ORM\Column(name="code", type="string", length=40, nullable=false) * @ORM\Column(name="code", type="string", length=40, nullable=false)
*/ */
#[Assert\NotBlank]
protected string $code; protected string $code;
/** /**
@ -97,9 +97,10 @@ class CourseCategory
protected ?string $authCatChild = null; protected ?string $authCatChild = null;
/** /**
* @ORM\Column(name="image", type="string", length=255, nullable=true) * @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Asset", inversedBy="courseCategories", cascade={"remove"} )
* @ORM\JoinColumn(name="asset_id", referencedColumnName="id", onDelete="SET NULL")
*/ */
protected ?string $image = null; protected ?Asset $asset = null;
/** /**
* @Groups({"course_category:read", "course_category:write"}) * @Groups({"course_category:read", "course_category:write"})
@ -265,26 +266,31 @@ class CourseCategory
return $this->authCatChild; return $this->authCatChild;
} }
public function getImage(): ?string public function getDescription(): ?string
{ {
return $this->image; return $this->description;
} }
public function setImage(string $image): self public function setDescription(string $description): self
{ {
$this->image = $image; $this->description = $description;
return $this; return $this;
} }
public function getDescription(): ?string public function getAsset(): ?Asset
{ {
return $this->description; return $this->asset;
} }
public function setDescription(string $description): self public function hasAsset(): bool
{ {
$this->description = $description; return null !== $this->asset;
}
public function setAsset(?Asset $asset): self
{
$this->asset = $asset;
return $this; return $this;
} }

@ -25,13 +25,14 @@ class AssetListener
$asset = $event->getObject(); $asset = $event->getObject();
if ($asset instanceof Asset) { if ($asset instanceof Asset) {
$mapping = $event->getMapping(); $mapping = $event->getMapping();
$folder = $mapping->getFile($asset)->getFilename(); $filePath = $asset->getCategory().'/'.$asset->getFile()->getFilename();
$this->assetRepository->getFileSystem()->deleteDirectory($filePath);
// Deletes scorm folder: example: assets/scorm/myABC . // Deletes scorm folder: example: assets/scorm/myABC .
if (!empty($folder) && Asset::SCORM === $asset->getCategory()) { /*if (!empty($folder) && Asset::SCORM === $asset->getCategory()) {
$folder = Asset::SCORM.'/'.$folder; $folder = Asset::SCORM.'/'.$folder;
$this->assetRepository->getFileSystem()->deleteDirectory($folder); $this->assetRepository->getFileSystem()->deleteDirectory($folder);
} }*/
} }
} }
} }

@ -6,8 +6,13 @@ declare(strict_types=1);
namespace Chamilo\CoreBundle\Migrations\Schema\V200; namespace Chamilo\CoreBundle\Migrations\Schema\V200;
use Chamilo\CoreBundle\Entity\Asset;
use Chamilo\CoreBundle\Entity\CourseCategory;
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo;
use Chamilo\CoreBundle\Repository\CourseCategoryRepository;
use Chamilo\Kernel;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class Version20191101132000 extends AbstractMigrationChamilo class Version20191101132000 extends AbstractMigrationChamilo
{ {
@ -81,8 +86,12 @@ class Version20191101132000 extends AbstractMigrationChamilo
if (!$table->hasIndex('course_rel_user_c_id_user_id')) { if (!$table->hasIndex('course_rel_user_c_id_user_id')) {
$this->addSql('CREATE INDEX course_rel_user_c_id_user_id ON course_rel_user (id, c_id, user_id)'); $this->addSql('CREATE INDEX course_rel_user_c_id_user_id ON course_rel_user (id, c_id, user_id)');
} }
$table = $schema->getTable('course_category');
//$this->addSql('ALTER TABLE course DROP category_code'); //$this->addSql('ALTER TABLE course DROP category_code');
$connection = $this->getEntityManager()->getConnection(); $em = $this->getEntityManager();
$connection = $em->getConnection();
$sql = 'SELECT * FROM course_category'; $sql = 'SELECT * FROM course_category';
$result = $connection->executeQuery($sql); $result = $connection->executeQuery($sql);
$all = $result->fetchAllAssociative(); $all = $result->fetchAllAssociative();
@ -102,15 +111,57 @@ class Version20191101132000 extends AbstractMigrationChamilo
$this->addSql('ALTER TABLE course_category CHANGE parent_id parent_id INT DEFAULT NULL;'); $this->addSql('ALTER TABLE course_category CHANGE parent_id parent_id INT DEFAULT NULL;');
$table = $schema->getTable('course_category');
if (false === $table->hasForeignKey('FK_AFF87497727ACA70')) { if (false === $table->hasForeignKey('FK_AFF87497727ACA70')) {
$this->addSql( $this->addSql(
'ALTER TABLE course_category ADD CONSTRAINT FK_AFF87497727ACA70 FOREIGN KEY (parent_id) REFERENCES course_category (id) ON DELETE CASCADE' 'ALTER TABLE course_category ADD CONSTRAINT FK_AFF87497727ACA70 FOREIGN KEY (parent_id) REFERENCES course_category (id) ON DELETE SET NULL '
); );
} }
if (!$table->hasColumn('image')) {
$this->addSql('ALTER TABLE course_category ADD image VARCHAR(255) DEFAULT NULL'); if (!$table->hasColumn('asset_id')) {
$this->addSql('ALTER TABLE course_category ADD asset_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE course_category ADD CONSTRAINT FK_AFF874975DA1941 FOREIGN KEY (asset_id) REFERENCES asset (id)');
$this->addSql('CREATE INDEX IDX_AFF874975DA1941 ON course_category (asset_id);');
} }
$container = $this->getContainer();
/** @var Kernel $kernel */
$kernel = $container->get('kernel');
$rootPath = $kernel->getProjectDir();
$repo = $container->get(CourseCategoryRepository::class);
if ($table->hasColumn('image')) {
foreach ($all as $category) {
if (!empty($category['image'])) {
/** @var CourseCategory $categoryEntity */
$categoryEntity = $repo->find($category['id']);
if ($categoryEntity->hasAsset()) {
continue;
}
$filePath = $rootPath.'/app/upload/course_category/'.$category['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::COURSE_CATEGORY)
->setTitle($fileName)
->setFile($file)
;
$em->persist($asset);
$em->flush();
$categoryEntity->setAsset($asset);
$em->persist($categoryEntity);
$em->flush();
}
}
}
}
if (!$table->hasColumn('description')) { if (!$table->hasColumn('description')) {
$this->addSql('ALTER TABLE course_category ADD description LONGTEXT DEFAULT NULL'); $this->addSql('ALTER TABLE course_category ADD description LONGTEXT DEFAULT NULL');
} }

@ -135,10 +135,21 @@ class CourseCategoryRepository extends ServiceEntityRepository
$em->flush(); $em->flush();
} }
public function deleteAsset(CourseCategory $category): void
{
$em = $this->getEntityManager();
if ($category->hasAsset()) {
$asset = $category->getAsset();
$em->remove($asset);
$em->flush();
}
}
public function delete(CourseCategory $category): void public function delete(CourseCategory $category): void
{ {
$em = $this->getEntityManager(); $em = $this->getEntityManager();
$em->remove($category); $em->remove($category);
$this->deleteAsset($category);
$em->flush(); $em->flush();
} }

@ -6,10 +6,13 @@ declare(strict_types=1);
namespace Chamilo\Tests\CoreBundle\Repository; namespace Chamilo\Tests\CoreBundle\Repository;
use Chamilo\CoreBundle\Entity\Asset;
use Chamilo\CoreBundle\Entity\CourseCategory; use Chamilo\CoreBundle\Entity\CourseCategory;
use Chamilo\CoreBundle\Repository\AssetRepository;
use Chamilo\CoreBundle\Repository\CourseCategoryRepository; use Chamilo\CoreBundle\Repository\CourseCategoryRepository;
use Chamilo\Tests\AbstractApiTest; use Chamilo\Tests\AbstractApiTest;
use Chamilo\Tests\ChamiloTestTrait; use Chamilo\Tests\ChamiloTestTrait;
use Symfony\Component\HttpFoundation\Response;
class CourseCategoryRepositoryTest extends AbstractApiTest class CourseCategoryRepositoryTest extends AbstractApiTest
{ {
@ -21,6 +24,7 @@ class CourseCategoryRepositoryTest extends AbstractApiTest
$em = $this->getManager(); $em = $this->getManager();
$repo = self::getContainer()->get(CourseCategoryRepository::class); $repo = self::getContainer()->get(CourseCategoryRepository::class);
$defaultCount = $repo->count([]);
$item = (new CourseCategory()) $item = (new CourseCategory())
->setCode('Course cat') ->setCode('Course cat')
@ -32,6 +36,141 @@ class CourseCategoryRepositoryTest extends AbstractApiTest
// On a fresh installation there are already 3 categories. // On a fresh installation there are already 3 categories.
// See the src/CoreBundle/DataFixtures/CourseCategoryFixtures.php // See the src/CoreBundle/DataFixtures/CourseCategoryFixtures.php
$this->assertSame(4, $repo->count([])); $this->assertSame($defaultCount + 1, $repo->count([]));
}
public function testCreateWithAsset(): void
{
self::bootKernel();
$em = $this->getManager();
/** @var CourseCategoryRepository $repoCourseCategory */
$repoCourseCategory = self::getContainer()->get(CourseCategoryRepository::class);
$defaultCount = $repoCourseCategory->count([]);
/** @var AssetRepository $assetRepo */
$assetRepo = self::getContainer()->get(AssetRepository::class);
$file = $this->getUploadedFile();
// Create asset.
$asset = (new Asset())
->setTitle('file')
->setCategory(Asset::COURSE_CATEGORY)
->setFile($file)
;
$em->persist($asset);
$item = (new CourseCategory())
->setCode('cat')
->setName('cat')
->setAsset($asset)
;
$this->assertHasNoEntityViolations($item);
$repoCourseCategory->save($item);
$this->assertSame($defaultCount + 1, $repoCourseCategory->count([]));
$this->assertTrue($item->hasAsset());
$this->assertSame(1, $assetRepo->count([]));
$repoCourseCategory->delete($item);
$this->assertSame($defaultCount, $repoCourseCategory->count([]));
}
public function testDelete(): void
{
self::bootKernel();
$em = $this->getManager();
/** @var CourseCategoryRepository $repoCourseCategory */
$repoCourseCategory = self::getContainer()->get(CourseCategoryRepository::class);
$defaultCount = $repoCourseCategory->count([]);
/** @var AssetRepository $assetRepo */
$assetRepo = self::getContainer()->get(AssetRepository::class);
$file = $this->getUploadedFile();
// Create asset.
$asset = (new Asset())
->setTitle('file')
->setCategory(Asset::COURSE_CATEGORY)
->setFile($file)
;
$em->persist($asset);
$courseCategory = (new CourseCategory())
->setCode('cat')
->setName('cat')
->setAsset($asset)
;
$repoCourseCategory->save($courseCategory);
$url = $assetRepo->getAssetUrl($asset);
$this->assertNotEmpty($url);
$content = $assetRepo->getAssetContent($asset);
$this->assertNotEmpty($content);
$client = static::createClient();
$client->request('GET', $url);
$this->assertSame(Response::HTTP_OK, $client->getResponse()->getStatusCode());
$this->assertSame(1, $assetRepo->count([]));
$em->clear();
$courseCategory = $repoCourseCategory->find($courseCategory->getId());
$repoCourseCategory->delete($courseCategory);
$this->assertSame(0, $assetRepo->count([]));
$this->assertSame($defaultCount, $repoCourseCategory->count([]));
$content = $assetRepo->getAssetContent($asset);
$this->assertEmpty($content);
}
public function testEditAndDeleteAsset(): void
{
self::bootKernel();
$em = $this->getManager();
/** @var CourseCategoryRepository $repoCourseCategory */
$repoCourseCategory = self::getContainer()->get(CourseCategoryRepository::class);
$defaultCount = $repoCourseCategory->count([]);
/** @var AssetRepository $assetRepo */
$assetRepo = self::getContainer()->get(AssetRepository::class);
$file = $this->getUploadedFile();
// Create asset.
$asset = (new Asset())
->setTitle('file')
->setCategory(Asset::COURSE_CATEGORY)
->setFile($file)
;
$em->persist($asset);
$courseCategory = (new CourseCategory())
->setCode('cat')
->setName('cat')
->setAsset($asset)
;
$repoCourseCategory->save($courseCategory);
$this->assertSame($defaultCount + 1, $repoCourseCategory->count([]));
$this->assertSame(1, $assetRepo->count([]));
$courseCategory = $repoCourseCategory->find($courseCategory->getId());
$repoCourseCategory->deleteAsset($courseCategory);
$this->assertSame(0, $assetRepo->count([]));
$this->assertSame($defaultCount + 1, $repoCourseCategory->count([]));
} }
} }

Loading…
Cancel
Save