/** * Displays the scale levels of a given competency framework for selection. * * @EXT\Route("/framework/{id}/levels", name="hevinci_pick_level") * @EXT\Template * * @param Competency $framework * @return array * @throws \LogicException if the competency is not a framework root */ public function levelsAction(Competency $framework) { if ($framework->getRoot() !== $framework->getId()) { throw new \LogicException('Scales are only linked to root competencies'); } return ['scale' => $framework->getScale()]; }
private function walkJsonNodes(\stdClass $parentData, Competency $parentCompetency, Scale $scale) { if (isset($parentData->competencies)) { foreach ($parentData->competencies as $competency) { $newCompetency = new Competency(); $newCompetency->setName($competency->name); $newCompetency->setParent($parentCompetency, true); $this->walkJsonNodes($competency, $newCompetency, $scale); } } else { foreach ($parentData->abilities as $ability) { $newAbility = new Ability(); $newAbility->setName($ability->name); $level = null; foreach ($scale->getLevels() as $scaleLevel) { if ($scaleLevel->getName() === $ability->level) { $level = $scaleLevel; break; } } $link = new CompetencyAbility(); $link->setCompetency($parentCompetency); $link->setAbility($newAbility); $link->setLevel($level); } } return $parentCompetency; }
public function testSubmitValidData() { $scale = new Scale(); $scale->setName('Scale 1'); $level = new Level(); $level->setName('Level 1'); $level->setValue(0); $level->setScale($scale); $parent = new Competency(); $parent->setName('Competency 1'); $parent->setScale($scale); $om = $this->client->getContainer()->get('claroline.persistence.object_manager'); $om->persist($scale); $om->persist($level); $om->persist($parent); $om->flush(); $formData = ['name' => 'Foo', 'level' => $level->getId(), 'minActivityCount' => 2]; $form = $this->factory->create(new AbilityType(), null, ['competency' => $parent]); $form->submit($formData); $this->assertTrue($form->isSynchronized()); $ability = $form->getData(); $this->assertInstanceOf('HeVinci\\CompetencyBundle\\Entity\\Ability', $ability); $this->assertEquals('Foo', $ability->getName()); $this->assertEquals($level, $ability->getLevel()); $this->assertEquals(2, $ability->getMinActivityCount()); $this->assertViewIsValid($form, $formData); }
public function testSubmitValidData() { $scale = new Scale(); $scale->setName('Scale 1'); $level = new Level(); $level->setName('Level 1'); $level->setValue(0); $level->setScale($scale); $parent = new Competency(); $parent->setName('Competency 1'); $parent->setScale($scale); $ability = new Ability(); $ability->setName('Foo'); $this->om->persist($scale); $this->om->persist($level); $this->om->persist($parent); $this->om->persist($ability); $this->om->flush(); $formData = ['ability' => 'Foo', 'level' => $level->getId()]; $form = $this->factory->create(new AbilityImportType($this->om), null, ['competency' => $parent]); $form->submit($formData); $this->assertTrue($form->isSynchronized()); $this->assertEquals($ability, $form->getData()); $this->assertEquals($level, $ability->getLevel()); $this->assertViewIsValid($form, $formData); }
/** * Returns the association between a competency and an ability. * * @param Competency $parent * @param Ability $ability * * @return null|object * * @throws \Exception if the ability is not linked to the competency */ public function findOneByTerms(Competency $parent, Ability $ability) { $link = $this->findOneBy(['competency' => $parent, 'ability' => $ability]); if (!$link) { throw new \RuntimeException("Competency {$parent->getId()} is not linked to ability {$ability->getId()}"); } return $link; }
/** * Returns all the competency nodes that must be taken into * account when computing level/percentage of parent nodes * from a given start node. It includes the node's siblings * and parent, and the parent's siblings and parent, and so on. * * @param Competency $startNode * @return array */ public function findForProgressComputing(Competency $startNode) { if (!($parent = $startNode->getParent())) { return []; } $qb = $this->createQueryBuilder('c'); return $qb->select('c')->where('c != :startNode')->andWhere('c.root = :root')->andWhere($qb->expr()->orX($qb->expr()->andX('c.lft > :parentLft', 'c.rgt < :parentRgt', 'c.lvl = :childLvl'), 'c.lvl < :childLvl'))->setParameters([':startNode' => $startNode, ':root' => $parent->getRoot(), ':childLvl' => $parent->getLevel() + 1, ':parentLft' => $parent->getLeft(), ':parentRgt' => $parent->getRight()])->getQuery()->getResult(); }
public function testListFrameworksAsShortArrays() { $c1 = new Competency(); $c1->setName('Foo'); $c1->setDescription('Foo desc'); $c2 = new Competency(); $c2->setName('Bar'); $c2->setDescription('Bar desc'); $this->competencyRepo->expects($this->once())->method('findBy')->with(['parent' => null])->willReturn([$c1, $c2]); $expected = [['id' => null, 'name' => 'Foo', 'description' => 'Foo desc'], ['id' => null, 'name' => 'Bar', 'description' => 'Bar desc']]; $this->assertEquals($expected, $this->manager->listFrameworks(true)); }
public function testValidationFailure() { $parent = $this->mock('HeVinci\\CompetencyBundle\\Entity\\Competency'); $parent->expects($this->once())->method('getRoot')->willReturn(1); $competency = new Competency(); $competency->setName('CHILD'); $constraint = new UniqueCompetency(); $constraint->parentCompetency = $parent; $this->repo->expects($this->once())->method('findOneBy')->with(['name' => 'CHILD', 'root' => 1])->willReturn('MATCH'); $this->context->expects($this->once())->method('addViolationAt')->with('name', $constraint->message); $this->validator->validate($competency, $constraint); }
protected function persistCompetency($name, Competency $parent = null, Scale $scale = null) { $competency = new Competency(); $competency->setName($name); if ($parent) { $competency->setParent($parent); } if ($scale) { $competency->setScale($scale); } $this->om->persist($competency); return $competency; }
/** * Creates an association between an objective and a competency, * with an expected level. Returns a full array representation of * the newly associated competency if the link doesn't already exist. * Otherwise, returns false. * * @param Objective $objective * @param Competency $competency * @param Level $level * * @return mixed array|bool * * @throws \LogicException if the level doesn't belong to the root competency scale */ public function linkCompetency(Objective $objective, Competency $competency, Level $level) { $link = $this->objectiveCompetencyRepo->findOneBy(['competency' => $competency, 'objective' => $objective]); if ($link) { return false; } $framework = $this->competencyRepo->findOneBy(['root' => $competency->getRoot()]); if ($level->getScale() !== $framework->getScale()) { throw new \LogicException('Objective level must belong to the root competency scale'); } $link = new ObjectiveCompetency(); $link->setObjective($objective); $link->setCompetency($competency); $link->setLevel($level); $link->setFramework($framework); $this->om->persist($link); $this->om->flush(); $this->progressManager->recomputeObjectiveProgress($objective); $competency = $this->competencyManager->loadCompetency($competency); $competency['id'] = $link->getId(); // link is treated as the competency itself on client-side $competency['framework'] = $framework->getName(); $competency['level'] = $level->getName(); return $competency; }
/** * @param Competency $parent The parent competency * @param boolean $isImport Whether we're in a framework import context */ public function setParent(Competency $parent = null, $isImport = false) { $this->parent = $parent; if ($parent && $isImport) { // allow child to be persisted by cascade $parent->addChild($this); } }
/** * Returns an array representation of activity evaluation data for * a given user and a given competency, including information about * the activity and the related abilities. * * @param Competency $competency * @param User $user * * @return array * * @throws \Exception */ public function findEvaluationsByCompetency(Competency $competency, User $user) { if ($competency->getRight() - $competency->getLeft() > 1) { throw new \Exception('Expected leaf competency'); } $activityQb = $this->createQueryBuilder('a1')->select('ac1.id')->join('a1.activities', 'ac1')->join('a1.competencyAbilities', 'ca')->where('ca.competency = :competency'); return $this->_em->createQueryBuilder()->select('e.id AS evaluationId', 'e.status', 'e.date', 'ac.id AS activityId', 'n.name AS activityName', 'a.id AS abilityId', 'a.name AS abilityName', 'l.name AS levelName')->from('Claroline\\CoreBundle\\Entity\\Activity\\Evaluation', 'e')->join('e.user', 'u')->join('e.activityParameters', 'ap')->join('ap.activity', 'ac')->join('ac.resourceNode', 'n')->join('HeVinci\\CompetencyBundle\\Entity\\Ability', 'a', 'WITH', 'ac IN (SELECT ac2 FROM HeVinci\\CompetencyBundle\\Entity\\Ability a2 JOIN a2.activities ac2 WHERE a2 = a)')->join('a.competencyAbilities', 'ca2')->join('ca2.level', 'l')->join('ca2.competency', 'c2')->where('c2 = :competency')->where($activityQb->expr()->in('ac', $activityQb->getQuery()->getDQL()))->andWhere('u = :user')->orderBy('e.date, e.id, a.id', 'ASC')->setParameters([':competency' => $competency, ':user' => $user])->getQuery()->getArrayResult(); }
/** * @param Competency $competency */ public function setCompetency(Competency $competency) { $this->competency = $competency; $this->competencyName = $competency->getName(); }
private function getSiblingNodes(Competency $startNode, Competency $parent, array $related) { return array_filter($related, function ($node) use($startNode, $parent) { return $node !== $startNode && $node->getLevel() === $startNode->getLevel() && $node->getLeft() > $parent->getLeft() && $node->getRight() < $parent->getRight(); }); }
/** * Displays the competency creation form. * * @EXT\Route("/{id}/sub", name="hevinci_new_competency") * @EXT\Template("HeVinciCompetencyBundle:Competency:competencyForm.html.twig") * * @param Competency $parent * @return array */ public function newSubCompetencyAction(Competency $parent) { return ['form' => $this->formHandler->getView('hevinci_form_competency', null, ['parent_competency' => $parent]), 'parentId' => $parent->getId()]; }
private function loadCompetency(Competency $competency) { return ['id' => $competency->getId(), 'name' => $competency->getName(), 'type' => 'competency_', 'paths' => [['level' => '-', 'steps' => array_map(function ($step) { return $step->getName(); }, $this->competencyRepo->getPath($competency))]]]; }
/** * Returns the builder needed to find the levels associated * to a competency (or its ancestor). * * Note: this method is used in the ability form type. * * @param Competency $competency * @return \Doctrine\ORM\QueryBuilder */ public function getFindByCompetencyBuilder(Competency $competency) { return $this->createQueryBuilder('l')->join('l.scale', 's')->join('s.competencies', 'c')->where('c.root = :compRoot')->setParameter(':compRoot', $competency->getRoot()); }
/** * Creates a link between a competency and an existing ability. * * @param Competency $parent * @param Ability $ability * @param Level $level * @return Ability * @throws \LogicException if a link already exists */ public function linkAbilityToCompetency(Competency $parent, Ability $ability, Level $level) { $link = $this->competencyAbilityRepo->findOneBy(['competency' => $parent, 'ability' => $ability]); if ($link) { throw new \LogicException("Ability {$ability->getId()} is already linked to competency {$parent->getId()}"); } $link = new CompetencyAbility(); $link->setCompetency($parent); $link->setAbility($ability); $link->setLevel($level); $this->om->persist($link); $this->om->flush(); return $ability; }
/** * @param Competency $competency */ public function setCompetency(Competency $competency) { $this->competency = $competency; $competency->addCompetencyAbility($this); }