Commit c0a3a02d authored by Karamel's avatar Karamel
Browse files

Move loadTags from DotrineMainModel to DoctrineDAO, add tests.

This fixes tags not being loaded when reading from the database
parent 1ba21a89
......@@ -26,6 +26,9 @@ use \Doctrine\Common\Collections\Criteria;
use \Doctrine\ORM\EntityManager;
use \Doctrine\ORM\Tools\Setup;
use \Pasteque\Server\Model\Attribute\Taggable;
use \Pasteque\Server\Model\Tag;
/** DAO using Doctrine. */
class DoctrineDAO implements DAO
{
......@@ -138,6 +141,26 @@ class DoctrineDAO implements DAO
$this->em->persist($model);
}
/**
* Mid-level function to automatically fill up tags when reading or
* searching records.
*/
protected function loadTags($record, $em) {
if ($record == null || !is_a($record, Taggable::class)) {
return;
}
$tagKeys = $record->getTagKey();
$qb = $em->createQueryBuilder();
$qb->select('model')->from(Tag::class, 'model');
$this->setupQueryBuilder($qb,
[new DAOCondition('model', '=', $tagKeys['model']),
new DAOCondition('modelId', '=', $tagKeys['modelId'])],
null, null, ['group', 'value']);
$tags = $qb->getQuery()->getResult();
$record->setTags($tags);
}
/**
* Read from database. May use caching.
* @param string $modelName The class name of the model. See MODEL_NAME
......@@ -148,7 +171,11 @@ class DoctrineDAO implements DAO
*/
public function read($modelName, $id) {
if ($id === null) { return null; }
return $this->em->find($modelName, $id);
$record = $this->em->find($modelName, $id);
if ($record != null) {
$this->loadTags($record, $this->em);
}
return $record;
}
/**
......@@ -165,6 +192,7 @@ class DoctrineDAO implements DAO
if ($id === null) { return null; }
$entity = $this->roEm->find($modelName, $id);
if ($entity !== null) {
$this->loadTags($entity, $this->roEm);
$this->roEm->detach($entity);
}
return $entity;
......@@ -286,7 +314,11 @@ class DoctrineDAO implements DAO
$qb->select('model')->from($modelName, 'model');
$this->setupQueryBuilder($qb, $conditions, $count, $offset, $order);
$query = $qb->getQuery();
return $query->getResult();
$results = $query->getResult();
foreach ($results as $record) {
$this->loadTags($record, $this->em);
}
return $results;
}
// Optimize pagination by fetching id to hydrate only the relevant
// records instead of everything then skipping anwanted one.
......@@ -307,8 +339,11 @@ class DoctrineDAO implements DAO
$qb2->select('model')->from($modelName, 'model');
$qb2->where($qb->expr()->in('model.id', $ids));
$query2 = $qb2->getQuery();
return $query2->getResult();
$results = $query2->getResult();
foreach ($results as $record) {
$this->loadTags($record, $this->em);
}
return $results;
}
/**
......
......@@ -60,18 +60,6 @@ abstract class DoctrineMainModel extends DoctrineModel
}
}
protected static function loadTags($record, $dao) {
if ($record == null || !is_a($record, Taggable::class)) {
return;
}
$tagKeys = $record->getTagKey();
$tags = $dao->search(Tag::class,
[new DAOCondition('model', '=', $tagKeys['model']),
new DAOCondition('modelId', '=', $tagKeys['modelId'])],
null, null, ['group', 'value']);
$record->setTags($tags);
}
/** Get The internal id from an external id. Null if not found. */
protected static function getIdFromExternalId($extId, $dao) {
if (!is_a(static::class, Externalizable::class, true)) {
......@@ -114,7 +102,6 @@ abstract class DoctrineMainModel extends DoctrineModel
*/
public static function loadFromId($id, $dao) {
$record = $dao->read(static::class, $id);
static::loadTags($record, $dao);
return $record;
}
......@@ -146,7 +133,6 @@ abstract class DoctrineMainModel extends DoctrineModel
$search = $dao->search(static::class, $conditions, 1);
if (count($search) > 0) {
$record = $search[0];
static::loadTags($record, $dao);
return $record;
} else {
return null;
......@@ -220,6 +206,21 @@ abstract class DoctrineMainModel extends DoctrineModel
}
}
/**
* @Override from DoctrineModel->toStruct
*/
public function toStruct() {
$struct = parent::toStruct();
if (is_a($this, Taggable::class)) {
$struct['tags'] = [];
foreach ($this->getTags() as $tag) {
$struct['tags'][] = $tag->toStruct();
}
}
return $struct;
}
/**
* @Override from DoctrineModel->equals
*/
......
......@@ -156,15 +156,6 @@ class CategoryTest extends TestCase
$this->assertEquals($cat->getDispOrder(), $parent->getDispOrder());
}
public function testMergeTags() {
$cat = new Category();
$struct = ['reference' => 'ref', 'label' => 'test', 'parent' => null, 'tags' => [['group' => 'grp', 'value' => 'testval']]];
$cat->merge($struct, $this->dao);
$this->assertEquals(1, count($cat->getTags()));
$this->assertEquals('grp', $cat->getTags()[0]->getGroup());
$this->assertEquals('testval', $cat->getTags()[0]->getValue());
}
public function testGetLoadKey() {
$valid = ['reference' => 'ref'];
$validLoad = Category::getLoadKey($valid);
......
<?php
// Pasteque server testing
//
// Copyright (C)
// 2012 Scil (http://scil.coop)
// 2017 Karamel, Association Pastèque (karamel@creativekara.fr, https://pasteque.org)
//
// This file is part of Pasteque.
//
// Pasteque is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Pasteque is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Pasteque. If not, see <http://www.gnu.org/licenses/>.
namespace Pasteque\Server;
use \Pasteque\Server\Exception\InvalidFieldException;
use \Pasteque\Server\Model\Category;
use \Pasteque\Server\Model\Tag;
use \Pasteque\Server\System\DAO\DAOFactory;
use \PHPUnit\Framework\TestCase;
require_once(dirname(dirname(__FILE__)) . "/common_load.php");
/** Test Tag functions through Category */
class TaggableTest extends TestCase
{
private $dao;
protected function setUp(): void {
global $dbInfo;
$this->dao = DAOFactory::getDAO($dbInfo, ['debug' => true]);
}
protected function tearDown(): void {
$tags = $this->dao->search(Tag::class);
foreach ($tags as $tag) {
$this->dao->delete($tag);
}
$cats = $this->dao->search(Category::class);
foreach ($cats as $cat) {
$this->dao->delete($cat);
}
$this->dao->commit();
$this->dao->close();
}
public function testMergeTags() {
$cat = new Category();
$struct = ['reference' => 'ref', 'label' => 'test', 'parent' => null, 'tags' => [['group' => 'grp', 'value' => 'testval']]];
$cat->merge($struct, $this->dao);
$this->assertEquals(1, count($cat->getTags()));
$this->assertEquals('grp', $cat->getTags()[0]->getGroup());
$this->assertEquals('testval', $cat->getTags()[0]->getValue());
}
public function testReadTags() {
$cat = new Category();
$cat->setReference('cat');
$cat->setLabel('Category');
$this->dao->write($cat);
$this->dao->commit();
$tag = new Tag();
$tag->assignKey($cat->getTagKey());
$tag->setGroup('grp');
$tag->setValue('value');
$this->dao->write($tag);
$this->dao->commit();
$em = $this->dao->getEntityManager();
$em->detach($cat);
$em->detach($tag);
$dbCat = $this->dao->read(Category::class, $cat->getId());
$this->assertNotNull($dbCat);
$this->assertEquals(1, count($dbCat->getTags()));
$this->assertEquals('grp', $dbCat->getTags()[0]->getGroup());
$this->assertEquals('value', $dbCat->getTags()[0]->getValue());
}
public function testReadSnapshotTags() {
$cat = new Category();
$cat->setReference('cat');
$cat->setLabel('Category');
$this->dao->write($cat);
$this->dao->commit();
$tag = new Tag();
$tag->assignKey($cat->getTagKey());
$tag->setGroup('grp');
$tag->setValue('value');
$this->dao->write($tag);
$this->dao->commit();
$em = $this->dao->getEntityManager();
$em->detach($cat);
$em->detach($tag);
$dbCat = $this->dao->readSnapshot(Category::class, $cat->getId());
$this->assertNotNull($dbCat);
$this->assertEquals(1, count($dbCat->getTags()));
$this->assertEquals('grp', $dbCat->getTags()[0]->getGroup());
$this->assertEquals('value', $dbCat->getTags()[0]->getValue());
}
public function testSearchTags() {
$cat = new Category();
$cat->setReference('cat');
$cat->setLabel('Category');
$this->dao->write($cat);
$this->dao->commit();
$tag = new Tag();
$tag->assignKey($cat->getTagKey());
$tag->setGroup('grp');
$tag->setValue('value');
$this->dao->write($tag);
$this->dao->commit();
$em = $this->dao->getEntityManager();
$em->detach($cat);
$em->detach($tag);
$dbCat = $this->dao->search(Category::class);
$this->assertEquals(1, count($dbCat));
$this->assertEquals(1, count($dbCat[0]->getTags()));
$this->assertEquals('grp', $dbCat[0]->getTags()[0]->getGroup());
$this->assertEquals('value', $dbCat[0]->getTags()[0]->getValue());
}
public function testToStructTags() {
$cat = new Category();
$cat->setReference('cat');
$cat->setLabel('Category');
$tag = new Tag();
$tag->assignKey($cat->getTagKey());
$tag->setGroup('grp');
$tag->setValue('value');
$cat->setTags([$tag]);
$struct = $cat->toStruct();
$this->assertTrue(array_key_exists('tags', $struct));
$this->assertEquals(1, count($struct['tags']));
$this->assertEquals('grp', $struct['tags'][0]['group']);
$this->assertEquals('value', $struct['tags'][0]['value']);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment