Commit a4b390b3 authored by Karamel's avatar Karamel
Browse files

Change payment mode value image modelId, add orphaned images removal and tests.

parent d33ac7b1
......@@ -55,7 +55,7 @@ class ImageAPI extends APIHelper implements API
case Image::MODEL_PAYMENTMODE_VALUE:
// composite primary key,
// Doctrine requires to use the full model instead of just id.
$realId = json_decode($id, true);
$realId = Image::getPMVIdFromModelId($id);
$pmId = $realId['paymentMode'];
$realId['paymentMode'] = $this->dao->read(PaymentMode::class,
$pmId);
......@@ -67,11 +67,14 @@ class ImageAPI extends APIHelper implements API
default:
$model = $this->dao->read(Image::getModelClass($modelName), $id);
}
if ($model === null) {
if ($model === null && $hasImage == true) {
// If the model is not found but the image was removed, it's not a problem
throw new \BadMethodCallException(sprintf('%s:%d not found', $modelName, $id));
}
$model->setHasImage($hasImage);
$this->dao->write($model);
if ($model !== null) {
$model->setHasImage($hasImage);
$this->dao->write($model);
}
}
public function write($data) {
......
......@@ -22,6 +22,7 @@
namespace Pasteque\Server\API;
use \Pasteque\Server\Model\Image;
use \Pasteque\Server\Model\PaymentMode;
use \Pasteque\Server\Model\PaymentModeReturn;
use \Pasteque\Server\Model\PaymentModeValue;
......@@ -39,7 +40,7 @@ class PaymentmodeAPI extends APIRefHelper
$arrayArgs = is_array($data);
$data = ($arrayArgs) ? $data : array($data);
// Keep track of PaymentModeValue images to restore them after
$images = [];
$imageIds = [];
foreach ($data as $d) {
if ($d->getId() == null) {
// New payment mode, it cannot have an image.
......@@ -47,38 +48,36 @@ class PaymentmodeAPI extends APIRefHelper
}
$snapPm = $this->dao->readSnapshot(PaymentMode::class, $d->getId());
foreach ($snapPm->getValues() as $pmv) {
$images[$d->getId()] = [];
if ($pmv->hasImage()) {
$images[$d->getId()][] = $pmv->getValue();
$imageIds[] = Image::getPMVModelId($pmv);
}
}
}
/* Delete unlinked value images:
* remove from $images all those which still exists,
* remove from $imageIds all those which still exists,
* all the remaining are orphaned images. */
foreach($images as $pmId => $values) {
$imageIdsToKeep = [];
foreach($imageIds as $imgId) {
$arrayId = Image::getPMVIdFromModelId($imgId);
foreach ($data as $d) {
if ($pmId == $d->getId()) {
foreach ($d->getValues() as $pmv) {
for($i = 0; $i < count($values); $i++) {
if ($pmv->getValue() == $values[$i]) {
if (!$pmv->hasImage()) {
$pmv->setHasImage(true);
}
array_splice($images[$pmId], $i, 1);
break;
}
if ($d->getId() != $arrayId['paymentMode']) {
continue;
}
foreach ($d->getValues() as $pmv) {
if (Image::getPMVModelId($pmv) == $imgId) {
if (!$pmv->hasImage()) {
$pmv->setHasImage(true);
}
$imageIdsToKeep[] = $imgId;
break;
}
}
}
}
$deleteImgIds = [];
foreach ($images as $pmId => $pmvs) {
foreach ($pmvs as $pmv) {
$deleteImgIds[] = ['model' => 'paymentmodevalue',
'modelId' => json_encode(['paymentMode' => $pmId, 'value' => $pmv])];
}
foreach (array_diff($imageIds, $imageIdsToKeep) as $imgId) {
$deleteImgIds[] = ['model' => Image::MODEL_PAYMENTMODE_VALUE,
'modelId' => $imgId];
}
if (count($deleteImgIds) > 0) {
$imgApi = new ImageAPI(null, $this->dao);
......@@ -98,33 +97,45 @@ class PaymentmodeAPI extends APIRefHelper
$keptValues = [];
$keptReturns = [];
foreach ($d->getValues() as $value) {
$keptValues[] = $value->getValue();
$keptValues[] = $value;
}
foreach ($d->getReturns() as $return) {
$keptReturns[] = $return->getMinAmount();
$keptReturns[] = $return;
}
$em = $this->dao->getEntityManager();
$dqlVal = 'delete \Pasteque\Server\Model\PaymentModeValue p '
. 'where p.paymentMode = ?1';
$dqlValImg = 'delete \Pasteque\Server\Model\Image i '
. 'where i.model = ?1 and i.modelId like ?2';
$qVal = null;
$qValImg = null;
if (count($keptValues) > 0) {
$dqlVal .= ' and (p.value not in (';
$dqlValImg .= ' and (i.modelId not in (';
$params = [];
$paramsImg = [];
for ($i = 0; $i < count($keptValues); $i++) {
$params[] = '?' . ($i + 2);
$paramsImg[] = '?' . ($i + 3);
}
$dqlVal .= implode(', ', $params);
$dqlVal .= '))';
$dqlValImg .= implode(', ', $paramsImg);
$dqlValImg .= '))';
$qVal = $em->createQuery($dqlVal);
$qValImg = $em->createQuery($dqlValImg);
for ($i = 0; $i < count($keptValues); $i++) {
$qVal->setParameter($i + 2, $keptValues[$i]);
$qVal->setParameter($i + 2, $keptValues[$i]->getValue());
$qValImg->setParameter($i + 3, Image::getPMVModelId($keptValues[$i]));
}
} else {
$qVal = $em->createQuery($dql);
$qValImg = $em->createQuery($dql);
}
// TODO: payment mode value images are not deleted.
$qVal->setParameter(1, $d);
$qVal->execute();
$qValImg->setParameter(1, Image::MODEL_PAYMENTMODE_VALUE);
$qValImg->setParameter(2, Image::getPMVModelIdWildcard($d));
$dqlRet = 'delete \Pasteque\Server\Model\PaymentModeReturn p '
. 'where p.paymentMode = ?1';
$qRet = null;
......@@ -138,7 +149,7 @@ class PaymentmodeAPI extends APIRefHelper
$dqlRet .= '))';
$qRet = $em->createQuery($dqlRet);
for ($i = 0; $i < count($keptReturns); $i++) {
$qRet->setParameter($i + 2, $keptReturns[$i]);
$qRet->setParameter($i + 2, $keptReturns[$i]->getMinAmount());
}
} else {
$qRet = $em->createQuery($dqlRet);
......
......@@ -21,6 +21,8 @@
namespace Pasteque\Server\Model;
use \Pasteque\Server\Model\PaymentMode;
use \Pasteque\Server\Model\PaymentModeValue;
use \Pasteque\Server\System\DAO\DoctrineModel;
/**
......@@ -71,6 +73,32 @@ class Image extends DoctrineModel
return [];
}
/** Get the modelId for a PaymentModeValue. */
public static function getPMVModelId($value) {
$pm = $value->getPaymentMode();
if ($pm->getId() == null || $value->getValue() == null) {
return null;
}
return sprintf('%d-%f', $pm->getId(), $value->getValue());
}
/** Get the PaymentModeValue id from the modelId. */
public static function getPMVIdFromModelId($modelId) {
$split = explode('-', $modelId);
if (count($split) != 2) {
return null;
}
return ['paymentMode' => intVal($split[0]), 'value' => round(floatVal($split[1]), 5)];
}
/** Get the dql wildcard to match all modelId for the given payment mode. */
public static function getPMVModelIdWildcard($paymentMode) {
if ($paymentMode->getId() === null) {
return null;
}
return sprintf('%d-*', $paymentMode->getId());
}
public function getId() {
return ['model' => $this->getModel(), 'modelId' => $this->getModelId()];
}
......
......@@ -199,15 +199,15 @@ class ImageAPITest extends TestCase
'modelId' => $this->paymentMode->getId()]);
$this->assertNotNull($snapImg);
// Set payment mode value image
$img = $this->sampleImage(Image::MODEL_PAYMENTMODE_VALUE,
$this->paymentMode->getValues()->get(0)->getId());
$pmvImgId = Image::getPMVModelId($this->paymentMode->getValues()->first());
$img = $this->sampleImage(Image::MODEL_PAYMENTMODE_VALUE, $pmvImgId);
$this->api->write($img);
$snap = $this->dao->readSnapshot(PaymentModeValue::class,
$this->paymentMode->getValues()->get(0)->getId());
$this->paymentMode->getValues()->first()->getId());
$this->assertTrue($snap->hasImage());
$snapImg = $this->dao->readSnapshot(Image::class,
['model' => Image::MODEL_PAYMENTMODE_VALUE,
'modelId' => json_encode($this->paymentMode->getValues()->get(0)->getId())]);
'modelId' => $pmvImgId]);
$this->assertNotNull($snapImg);
}
......@@ -271,15 +271,16 @@ class ImageAPITest extends TestCase
'modelId' => $this->paymentMode->getId()]);
$this->assertNull($snapImg);
// Set and delete payment mode value image
$img = $this->sampleImage(Image::MODEL_PAYMENTMODE_VALUE,
$this->paymentMode->getValues()->get(0)->getId());
$pmvImgId = Image::getPMVModelId($this->paymentMode->getValues()->get(0));
$img = $this->sampleImage(Image::MODEL_PAYMENTMODE_VALUE, $pmvImgId);
$this->api->write($img);
$this->api->delete($img->getId());
$snap = $this->dao->readSnapshot(PaymentModeValue::class,
$this->paymentMode->getValues()->get(0)->getId());
$this->paymentMode->getValues()->first()->getId());
$this->assertFalse($snap->hasImage());
$snapImg = $this->dao->readSnapshot(Image::class, ['model' => Image::MODEL_PAYMENTMODE_VALUE,
'modelId' => json_encode($this->paymentMode->getValues()->get(0)->getId())]);
$snapImg = $this->dao->readSnapshot(Image::class,
['model' => Image::MODEL_PAYMENTMODE_VALUE,
'modelId' => $pmvImgId]);
$this->assertNull($snapImg);
}
......@@ -290,10 +291,9 @@ class ImageAPITest extends TestCase
$this->api->delete($img->getId());
}
/** @expectedException BadMethodCallException
* @expectedExceptionMessage category:-1 not found */
public function testDeleteImageInexistingModel() {
$img = $this->sampleImage(Image::MODEL_CATEGORY, -1);
$this->api->delete($img->getId());
// It should do nothing
}
}
......@@ -300,7 +300,8 @@ class PaymentModeAPITest extends TestCase
$img->setImage(file_get_contents(__DIR__ . '/../res/image.png'));
$img->setMimeType('image/png');
$img->setModel(Image::MODEL_PAYMENTMODE_VALUE);
$img->setModelId($imgJsId);
$modelId = Image::getPMVModelId($value);
$img->setModelId($modelId);
$imgApi = new ImageAPI(null, $this->dao);
$imgApi->write($img);
// Update payment mode
......@@ -308,17 +309,24 @@ class PaymentModeAPITest extends TestCase
$value2->setValue(5.0);
$pm->addValue($value2);
$this->api->write($pm);
$readPm = $this->dao->readSnapshot(PaymentMode::class, $pm->getId());
foreach ($readPm->getValues() as $v) {
if ($v->getValue() == $value->getValue()) {
$this->assertTrue($v->hasImage());
} else {
$this->assertFalse($v->hasImage());
}
}
$readImg = $this->dao->readSnapshot(Image::class,
['model' => Image::MODEL_PAYMENTMODE_VALUE, 'modelId' => $imgJsId]);
['model' => Image::MODEL_PAYMENTMODE_VALUE, 'modelId' => $modelId]);
$this->assertNotNull($readImg);
$readValue = $this->dao->readSnapshot(PaymentModeValue::class, $value->getId());
$this->assertTrue($readValue->hasImage());
}
public function testPMVImageOrphaned() {
// Write an image for a payment mode value
// Update the payment mode with a new value
// The image must be deleted
// Other payment modes must remain untouched
$pm = new PaymentMode();
$pm->setReference('mode');
$pm->setLabel('Mode');
......@@ -326,22 +334,46 @@ class PaymentModeAPITest extends TestCase
$value->setValue(10.0);
$pm->addValue($value);
$this->api->write($pm);
$imgJsId = json_encode($value->getId());
$img = new Image();
$img->setImage(file_get_contents(__DIR__ . '/../res/image.png'));
$img->setMimeType('image/png');
$img->setModel(Image::MODEL_PAYMENTMODE_VALUE);
$img->setModelId($imgJsId);
$modelId = Image::getPMVModelId($value);
$img->setModelId($modelId);
$imgApi = new ImageAPI(null, $this->dao);
$imgApi->write($img);
$pm2 = new PaymentMode();
$pm2->setReference('mode2');
$pm2->setLabel('Mode2');
$valuePm2 = new PaymentModeValue();
$valuePm2->setValue(10.0);
$pm2->addValue($valuePm2);
$this->api->write($pm2);
$img2 = new Image();
$img2->setImage(file_get_contents(__DIR__ . '/../res/image.png'));
$img2->setMimeType('image/png');
$img2->setModel(Image::MODEL_PAYMENTMODE_VALUE);
$modelId2 = Image::getPMVModelId($valuePm2);
$img2->setModelId($modelId2);
$imgApi = new ImageAPI(null, $this->dao);
$imgApi->write($img2);
// Update payment mode
$pm->clearValues();
$value2 = new PaymentModeValue();
$value2->setValue(5.0);
$pm->addValue($value2);
$this->api->write($pm);
$readPm = $this->dao->readSnapshot(PaymentMode::class, $pm->getId());
$this->assertEquals(1, count($readPm->getValues()));
$this->assertFalse($readPm->getValues()->first()->hasImage());
$readPm2 = $this->dao->readSnapshot(PaymentMode::class, $pm2->getId());
$this->assertEquals(1, count($readPm2->getValues()));
$this->assertTrue($readPm2->getValues()->first()->hasImage());
$readImg = $this->dao->readSnapshot(Image::class,
['model' => Image::MODEL_PAYMENTMODE_VALUE, 'modelId' => $imgJsId]);
['model' => Image::MODEL_PAYMENTMODE_VALUE, 'modelId' => $modelId]);
$this->assertNull($readImg);
$readImg2 = $this->dao->readSnapshot(Image::class,
['model' => Image::MODEL_PAYMENTMODE_VALUE, 'modelId' => $modelId2]);
$this->assertNotNull($readImg2);
}
}
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