Fix track e exercise

pull/4001/head
Julio 5 years ago
parent 2d3465d319
commit ec71e7b0e2
  1. 2
      src/CoreBundle/Entity/AnnouncementRelGroup.php
  2. 2
      src/CoreBundle/Entity/Asset.php
  3. 54
      src/CoreBundle/Entity/AttemptFeedback.php
  4. 42
      src/CoreBundle/Entity/AttemptFile.php
  5. 7
      src/CoreBundle/Entity/Course.php
  6. 80
      src/CoreBundle/Entity/TrackEAttempt.php
  7. 15
      src/CoreBundle/Entity/TrackExercise.php
  8. 15
      src/CoreBundle/Migrations/Schema/V200/Version20180904175500.php
  9. 6
      src/CoreBundle/Repository/TrackExerciseRepository.php
  10. 96
      tests/CoreBundle/Repository/TrackExerciseRepositoryTest.php

@ -9,8 +9,6 @@ namespace Chamilo\CoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* AnnouncementRelGroup.
*
* @ORM\Table(name="announcement_rel_group")
* @ORM\Entity
*/

@ -33,6 +33,8 @@ class Asset
public const EXTRA_FIELD = 'ef';
public const COURSE_CATEGORY = 'course_category';
public const SKILL = 'skill';
public const EXERCISE_ATTEMPT = 'exercise_attempt';
public const EXERCISE_FEEDBACK = 'exercise_feedback';
/**
* @ORM\Id

@ -54,6 +54,60 @@ class AttemptFeedback
public function __construct()
{
$this->id = Uuid::v4();
$this->comment = '';
}
public function getId(): Uuid
{
return $this->id;
}
public function getAttempt(): TrackEAttempt
{
return $this->attempt;
}
public function setAttempt(TrackEAttempt $attempt): self
{
$this->attempt = $attempt;
return $this;
}
public function getUser(): User
{
return $this->user;
}
public function setUser(User $user): self
{
$this->user = $user;
return $this;
}
public function getAsset(): ?Asset
{
return $this->asset;
}
public function setAsset(?Asset $asset): self
{
$this->asset = $asset;
return $this;
}
public function getComment(): string
{
return $this->comment;
}
public function setComment(string $comment): self
{
$this->comment = $comment;
return $this;
}
}

@ -47,6 +47,48 @@ class AttemptFile
public function __construct()
{
$this->id = Uuid::v4();
$this->comment = '';
}
public function getId(): Uuid
{
return $this->id;
}
public function getAttempt(): TrackEAttempt
{
return $this->attempt;
}
public function setAttempt(TrackEAttempt $attempt): self
{
$this->attempt = $attempt;
return $this;
}
public function getAsset(): ?Asset
{
return $this->asset;
}
public function setAsset(?Asset $asset): self
{
$this->asset = $asset;
return $this;
}
public function getComment(): string
{
return $this->comment;
}
public function setComment(string $comment): self
{
$this->comment = $comment;
return $this;
}
}

@ -473,9 +473,10 @@ class Course extends AbstractResource implements ResourceInterface, ResourceWith
public function addAccessUrl(AccessUrl $url): self
{
$urlRelCourse = new AccessUrlRelCourse();
$urlRelCourse->setCourse($this);
$urlRelCourse->setUrl($url);
$urlRelCourse = (new AccessUrlRelCourse())
->setCourse($this)
->setUrl($url)
;
$this->addUrlRelCourse($urlRelCourse);
return $this;

@ -42,13 +42,14 @@ class TrackEAttempt
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\TrackExercise", inversedBy="attempts")
* @ORM\JoinColumn(name="exe_id", referencedColumnName="exe_id", nullable=false)
*/
#[Assert\NotNull]
protected TrackExercise $trackExercise;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\User", inversedBy="trackEAttempts")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
*/
#[Assert\NotBlank]
#[Assert\NotNull]
protected User $user;
/**
@ -98,19 +99,19 @@ class TrackEAttempt
*
* @ORM\OneToMany(targetEntity="AttemptFile", mappedBy="attempt", cascade={"persist"}, orphanRemoval=true)
*/
protected Collection $files;
protected Collection $attemptFiles;
/**
* @var Collection|AttemptFeedback[]
*
* @ORM\OneToMany(targetEntity="AttemptFeedback", mappedBy="attempt", cascade={"persist"}, orphanRemoval=true)
*/
protected Collection $feedbacks;
protected Collection $attemptFeedbacks;
public function __construct()
{
$this->files = new ArrayCollection();
$this->feedbacks = new ArrayCollection();
$this->attemptFiles = new ArrayCollection();
$this->attemptFeedbacks = new ArrayCollection();
$this->teacherComment = '';
$this->secondsSpent = 0;
}
@ -261,63 +262,82 @@ class TrackEAttempt
return $this;
}
/**
* @return AttemptFile[]|Collection
*/
public function getFiles()
public function getTrackExercise(): TrackExercise
{
return $this->files;
return $this->trackExercise;
}
/**
* @param AttemptFile[]|Collection $files
*/
public function setFiles($files): self
public function setTrackExercise(TrackExercise $trackExercise): self
{
$this->files = $files;
$this->trackExercise = $trackExercise;
return $this;
}
public function getSecondsSpent(): int
{
return $this->secondsSpent;
}
public function setSecondsSpent(int $secondsSpent): self
{
$this->secondsSpent = $secondsSpent;
return $this;
}
/**
* @return AttemptFeedback[]|Collection
* @return AttemptFile[]|Collection
*/
public function getFeedbacks()
public function getAttemptFiles()
{
return $this->feedbacks;
return $this->attemptFiles;
}
/**
* @param AttemptFeedback[]|Collection $feedbacks
* @param AttemptFile[]|Collection $attemptFiles
*/
public function setFeedbacks($feedbacks): self
public function setAttemptFiles($attemptFiles): self
{
$this->feedbacks = $feedbacks;
$this->attemptFiles = $attemptFiles;
return $this;
}
public function getTrackExercise(): TrackExercise
/**
* @return AttemptFeedback[]|Collection
*/
public function getAttemptFeedbacks()
{
return $this->trackExercise;
return $this->attemptFeedbacks;
}
public function setTrackExercise(TrackExercise $trackExercise): self
/**
* @param AttemptFeedback[]|Collection $attemptFeedbacks
*/
public function setAttemptFeedbacks($attemptFeedbacks): self
{
$trackExercise->getAttempts()->add($this);
$this->trackExercise = $trackExercise;
$this->attemptFeedbacks = $attemptFeedbacks;
return $this;
}
public function getSecondsSpent(): int
public function addAttemptFeedback(AttemptFeedback $attemptFeedback): self
{
return $this->secondsSpent;
if (!$this->attemptFeedbacks->contains($attemptFeedback)) {
$this->attemptFeedbacks[] = $attemptFeedback;
$attemptFeedback->setAttempt($this);
}
return $this;
}
public function setSecondsSpent(int $secondsSpent): self
public function addAttemptFile(AttemptFile $attemptFile): self
{
$this->secondsSpent = $secondsSpent;
if (!$this->attemptFiles->contains($attemptFile)) {
$this->attemptFiles[] = $attemptFile;
$attemptFile->setAttempt($this);
}
return $this;
}

@ -35,13 +35,14 @@ class TrackExercise
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\User")
* @ORM\JoinColumn(name="exe_user_id", referencedColumnName="id", nullable=false)
*/
#[Assert\NotBlank]
#[Assert\NotNull]
protected User $user;
/**
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Course")
* @ORM\JoinColumn(name="c_id", referencedColumnName="id", nullable=false)
*/
#[Assert\NotNull]
protected Course $course;
/**
@ -100,6 +101,7 @@ class TrackExercise
/**
* @ORM\Column(name="steps_counter", type="smallint", nullable=false)
*/
#[Assert\NotNull]
protected int $stepsCounter;
/**
@ -115,6 +117,7 @@ class TrackExercise
/**
* @ORM\Column(name="exe_duration", type="integer", nullable=false)
*/
#[Assert\NotNull]
protected int $exeDuration;
/**
@ -446,6 +449,16 @@ class TrackExercise
return $this;
}
public function addAttempt(TrackEAttempt $attempt): self
{
if (!$this->attempts->contains($attempt)) {
$this->attempts[] = $attempt;
$attempt->setTrackExercise($this);
}
return $this;
}
public function getSession(): ?Session
{
return $this->session;

@ -24,23 +24,24 @@ class Version20180904175500 extends AbstractMigrationChamilo
$this->addSql('DELETE FROM track_e_exercises WHERE exe_user_id = 0 OR exe_user_id IS NULL');
$this->addSql('ALTER TABLE track_e_exercises CHANGE exe_user_id exe_user_id INT NOT NULL');
$this->addSql('UPDATE track_e_exercises SET session_id = 0 WHERE session_id IS NULL');
$this->addSql('UPDATE track_e_exercises SET session_id = NULL WHERE session_id = 0');
$this->addSql('DELETE FROM track_e_exercises WHERE session_id IS NOT NULL AND session_id NOT IN (SELECT id FROM session)');
$this->addSql('ALTER TABLE track_e_exercises CHANGE session_id session_id INT NOT NULL');
if (!$schema->hasTable('attempt_file')) {
$this->addSql("CREATE TABLE attempt_file (id BINARY(16) NOT NULL COMMENT '(DC2Type:uuid)', attempt_id INT DEFAULT NULL, asset_id BINARY(16) DEFAULT NULL COMMENT '(DC2Type:uuid)', comment LONGTEXT NOT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', updated_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', INDEX IDX_4F22BDF0B191BE6B (attempt_id), INDEX IDX_4F22BDF05DA1941 (asset_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC;");
$this->addSql("ALTER TABLE attempt_file ADD CONSTRAINT FK_4F22BDF0B191BE6B FOREIGN KEY (attempt_id) REFERENCES track_e_attempt (id) ON DELETE CASCADE;");
$this->addSql("ALTER TABLE attempt_file ADD CONSTRAINT FK_4F22BDF05DA1941 FOREIGN KEY (asset_id) REFERENCES asset (id) ON DELETE CASCADE;");
$this->addSql('ALTER TABLE attempt_file ADD CONSTRAINT FK_4F22BDF0B191BE6B FOREIGN KEY (attempt_id) REFERENCES track_e_attempt (id) ON DELETE CASCADE;');
$this->addSql('ALTER TABLE attempt_file ADD CONSTRAINT FK_4F22BDF05DA1941 FOREIGN KEY (asset_id) REFERENCES asset (id) ON DELETE CASCADE;');
}
if (!$schema->hasTable('attempt_feedback')) {
$this->addSql("CREATE TABLE attempt_feedback (id BINARY(16) NOT NULL COMMENT '(DC2Type:uuid)', attempt_id INT DEFAULT NULL, user_id INT DEFAULT NULL, asset_id BINARY(16) DEFAULT NULL COMMENT '(DC2Type:uuid)', comment LONGTEXT NOT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', updated_at DATETIME NOT NULL COMMENT '(DC2Type:datetime)', INDEX IDX_BA30B2FEB191BE6B (attempt_id), INDEX IDX_BA30B2FEA76ED395 (user_id), INDEX IDX_BA30B2FE5DA1941 (asset_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC;");
$this->addSql("ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FEB191BE6B FOREIGN KEY (attempt_id) REFERENCES track_e_attempt (id) ON DELETE CASCADE;");
$this->addSql("ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FEA76ED395 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE;");
$this->addSql("ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FE5DA1941 FOREIGN KEY (asset_id) REFERENCES asset (id) ON DELETE CASCADE;");
$this->addSql('ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FEB191BE6B FOREIGN KEY (attempt_id) REFERENCES track_e_attempt (id) ON DELETE CASCADE;');
$this->addSql('ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FEA76ED395 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE;');
$this->addSql('ALTER TABLE attempt_feedback ADD CONSTRAINT FK_BA30B2FE5DA1941 FOREIGN KEY (asset_id) REFERENCES asset (id) ON DELETE CASCADE;');
}
$table = $schema->getTable('track_e_login');
if (!$table->hasIndex('idx_track_e_login_date')) {
$this->addSql('CREATE INDEX idx_track_e_login_date ON track_e_login (login_date)');

@ -16,4 +16,10 @@ class TrackExerciseRepository extends ServiceEntityRepository
{
parent::__construct($registry, TrackExercise::class);
}
public function delete(TrackExercise $track): void
{
$this->getEntityManager()->remove($track);
$this->getEntityManager()->flush();
}
}

@ -6,12 +6,15 @@ declare(strict_types=1);
namespace Chamilo\Tests\CoreBundle\Repository;
use Chamilo\CoreBundle\Entity\ExtraField;
use Chamilo\CoreBundle\Entity\Tag;
use Chamilo\CoreBundle\Entity\Asset;
use Chamilo\CoreBundle\Entity\AttemptFeedback;
use Chamilo\CoreBundle\Entity\AttemptFile;
use Chamilo\CoreBundle\Entity\TrackEAttempt;
use Chamilo\CoreBundle\Entity\TrackExercise;
use Chamilo\CoreBundle\Repository\AssetRepository;
use Chamilo\CoreBundle\Repository\TrackExerciseRepository;
use Chamilo\CourseBundle\Entity\CQuiz;
use Chamilo\CourseBundle\Repository\CQuizRepository;
use Chamilo\Tests\AbstractApiTest;
use Chamilo\Tests\ChamiloTestTrait;
use DateTime;
@ -29,6 +32,8 @@ class TrackExerciseRepositoryTest extends AbstractApiTest
$teacher = $this->createUser('teacher');
$student = $this->createUser('student');
$repo = self::getContainer()->get(TrackExerciseRepository::class);
$exerciseRepo = self::getContainer()->get(CQuizRepository::class);
$exercise = (new CQuiz())
->setTitle('exercise')
->setParent($course)
@ -60,6 +65,13 @@ class TrackExerciseRepositoryTest extends AbstractApiTest
$em->persist($trackExercise);
$this->assertHasNoEntityViolations($trackExercise);
$em->flush();
$this->assertSame(1, $repo->count([]));
$this->assertSame(1, $exerciseRepo->count([]));
$repo->delete($trackExercise);
$this->assertSame(0, $repo->count([]));
$this->assertSame(1, $exerciseRepo->count([]));
}
public function testCreateWithAttempt(): void
@ -68,6 +80,7 @@ class TrackExerciseRepositoryTest extends AbstractApiTest
$em = $this->getEntityManager();
$repo = self::getContainer()->get(TrackExerciseRepository::class);
$exerciseRepo = self::getContainer()->get(CQuizRepository::class);
$course = $this->createCourse('new');
$teacher = $this->createUser('teacher');
@ -81,6 +94,15 @@ class TrackExerciseRepositoryTest extends AbstractApiTest
$em->persist($exercise);
$em->flush();
$attempt = (new TrackEAttempt())
->setTms(new DateTime())
->setQuestionId(1)
->setPosition(1)
->setAnswer('great')
->setMarks(100)
->setUser($student)
;
$trackExercise = (new TrackExercise())
->setQuestionsToCheck('')
->setExeDate(new DateTime())
@ -98,27 +120,77 @@ class TrackExerciseRepositoryTest extends AbstractApiTest
->setExeDuration(10)
->setExpiredTimeControl(new DateTime())
->setExeExoId($exercise->getIid())
->addAttempt($attempt)
;
$em->persist($attempt);
$em->persist($trackExercise);
$this->assertHasNoEntityViolations($attempt);
$this->assertHasNoEntityViolations($trackExercise);
$em->flush();
$this->assertSame(0, $trackExercise->getAttempts()->count());
//$trackExercise = $repo->find($trackExercise->getExeId());
$this->assertSame(1, $trackExercise->getAttempts()->count());
$attempt = (new TrackEAttempt())
->setTrackExercise($trackExercise)
->setTms(new DateTime())
->setQuestionId(1)
->setPosition(1)
->setAnswer('great')
->setMarks(100)
$file = $this->getUploadedFile();
$assetRepo = self::getContainer()->get(AssetRepository::class);
$em = $this->getEntityManager();
// Create asset.
$asset = (new Asset())
->setTitle('test')
->setCategory(Asset::EXERCISE_ATTEMPT)
->setFile($file)
;
$em->persist($asset);
$em->flush();
$feedback = (new AttemptFeedback())
->setUser($student)
->setComment('great!')
->setAsset($asset)
;
$this->assertHasNoEntityViolations($attempt);
$em->persist($attempt);
$attempt->addAttemptFeedback($feedback);
$this->assertHasNoEntityViolations($feedback);
$em->persist($feedback);
$em->flush();
$this->assertNotNull($feedback->getId());
$this->assertNotNull($feedback->getAsset());
$this->assertNotNull($feedback->getUser());
$this->assertNotNull($feedback->getAttempt());
$this->assertNotNull($feedback->getCreatedAt());
$this->assertNotNull($feedback->getUpdatedAt());
$asset = (new Asset())
->setTitle('test')
->setCategory(Asset::EXERCISE_ATTEMPT)
->setFile($file)
;
$em->persist($asset);
$em->flush();
$attemptFile = (new AttemptFile())
->setComment('great!')
->setAsset($asset)
;
$attempt->addAttemptFile($attemptFile);
$this->assertHasNoEntityViolations($attemptFile);
$em->persist($attemptFile);
$em->flush();
$this->assertNotNull($attemptFile->getId());
$this->assertNotNull($attemptFile->getAsset());
$this->assertNotNull($attemptFile->getAttempt());
$this->assertNotNull($attemptFile->getCreatedAt());
$this->assertNotNull($attemptFile->getUpdatedAt());
$this->assertSame(1, $trackExercise->getAttempts()->count());
$this->assertSame(1, $attempt->getAttemptFeedbacks()->count());
$this->assertSame(1, $attempt->getAttemptFiles()->count());
$this->assertSame(1, $repo->count([]));
$this->assertSame(1, $exerciseRepo->count([]));
}
}

Loading…
Cancel
Save