diff --git a/config/Migrations/20251101150009_AllowProductIdToBeNullInProductPhotos.php b/config/Migrations/20251101150009_AllowProductIdToBeNullInProductPhotos.php index a18fb7c..a1200b8 100644 --- a/config/Migrations/20251101150009_AllowProductIdToBeNullInProductPhotos.php +++ b/config/Migrations/20251101150009_AllowProductIdToBeNullInProductPhotos.php @@ -12,7 +12,7 @@ class AllowProductIdToBeNullInProductPhotos extends BaseMigration * https://book.cakephp.org/migrations/4/en/migrations.html#the-change-method * @return void */ - public function change(): void + public function up(): void { $table = $this->table('product_photos'); $table->changeColumn('product_id', 'uuid', [ @@ -20,6 +20,34 @@ class AllowProductIdToBeNullInProductPhotos extends BaseMigration 'limit' => 11, 'null' => true, ]); + $table->changeColumn('product_category_id', 'uuid', [ + 'default' => null, + 'limit' => 11, + 'null' => false, + ]); + $table->update(); + } + + /** + * Change Method. + * + * More information on this method is available here: + * https://book.cakephp.org/migrations/4/en/migrations.html#the-change-method + * @return void + */ + public function down(): void + { + $table = $this->table('product_photos'); + $table->changeColumn('product_id', 'uuid', [ + 'default' => null, + 'limit' => 11, + 'null' => false, + ]); + $table->changeColumn('product_category_id', 'uuid', [ + 'default' => null, + 'limit' => 11, + 'null' => true, + ]); $table->update(); } } diff --git a/src/Controller/ProductPhotosController.php b/src/Controller/ProductPhotosController.php index c4e25fb..be6c113 100644 --- a/src/Controller/ProductPhotosController.php +++ b/src/Controller/ProductPhotosController.php @@ -71,11 +71,33 @@ class ProductPhotosController extends AppController $postData = $this->request->getData(); $postData['id'] = $uuid; $baseDir = Configure::readOrFail('CakeProducts.photos.directory'); - $product = $productPhotosTable->Products->get($this->request->getData('product_id')); - $path = $product->id; + $path = ''; if ($this->request->getData('product_sku_id')) { - $productSku = $productPhotosTable->ProductSkus->find()->where(['ProductSkus.id' => $this->request->getData('product_sku_id'), 'ProductSkus.product_id' => $product->id])->first(); - $path = $productSku ? $path . DS . 'skus' . DS . $productSku->id : $path; + $productSku = $productPhotosTable->ProductSkus + ->find() + ->contain(['Products', 'Products.ProductCategories']) + ->where([ + 'ProductSkus.id' => $this->request->getData('product_sku_id'), + ]) + ->first(); + $path = $productSku ? $productSku->product_id . DS . 'skus' . DS . $productSku->id : $path; + } else if ($this->request->getData('product_id')) { + $product = $productPhotosTable->Products + ->find() + ->contain(['ProductCategories']) + ->where([ + 'Products.id' => $this->request->getData('product_id'), + ]) + ->first(); + $path = $product ? $product->id : $path; + } else if ($this->request->getData('product_category_id')) { + $productCategoryPosted = $productPhotosTable->ProductCategories + ->find() + ->where([ + 'ProductCategories.internal_id' => $this->request->getData('product_category_id'), + ]) + ->first(); + $path = $productCategoryPosted ? 'categories' : $path; } /** * @var UploadedFileInterface $photoObject @@ -95,7 +117,7 @@ class ProductPhotosController extends AppController if (!file_exists($destination)) { throw new ForbiddenException('Failed to move the uploaded image to the appropriate folder. Please try again.'); } - $postData['product_category_id'] = $product->product_category_id ?? null; + $postData['photo_dir'] = $path; $postData['photo_filename'] = $uuid; @@ -105,6 +127,7 @@ class ProductPhotosController extends AppController return $this->redirect(['action' => 'index']); } + dd($productPhoto->getErrors()); $this->Flash->error(__('The product photo could not be saved. Please, try again.')); } $productCategory = $productPhoto->product_category_id ? $productPhotosTable->ProductCategories->find()->where(['internal_id' => $productPhoto->product_category_id ?? '-1'])->first() : null; diff --git a/src/Model/Behavior/SecondToggleBehavior.php b/src/Model/Behavior/SecondToggleBehavior.php index 91b7b64..64c6b79 100644 --- a/src/Model/Behavior/SecondToggleBehavior.php +++ b/src/Model/Behavior/SecondToggleBehavior.php @@ -34,4 +34,24 @@ class SecondToggleBehavior extends ToggleBehavior { 'findOrder' => null, // null = autodetect modified/created, false to disable 'implementedMethods' => [], // to prevent conflict with public toggleField method ]; + + /** + * @param \Cake\Datasource\EntityInterface $entity + * + * @return array + */ + protected function buildConditions(EntityInterface $entity) { + $conditions = $this->getConfig('scope'); + $scopeFields = (array)$this->getConfig('scopeFields'); + + foreach ($scopeFields as $scopeField) { + if ($entity->get($scopeField) === null) { + continue; + } + $conditions[$scopeField] = $entity->get($scopeField); + } +// dd($conditions); + + return $conditions; + } } diff --git a/src/Model/Table/ProductPhotosTable.php b/src/Model/Table/ProductPhotosTable.php index 3653cf0..d89e565 100644 --- a/src/Model/Table/ProductPhotosTable.php +++ b/src/Model/Table/ProductPhotosTable.php @@ -60,6 +60,13 @@ class ProductPhotosTable extends Table $this->addBehavior('Timestamp'); $this->addBehavior('Tools.Toggle', [ + 'field' => 'primary_category_photo', + 'scopeFields' => ['product_category_id'], + 'scope' => [ + 'deleted IS' => null, + ], + ]); + $this->addBehavior('CakeProducts.SecondToggle', [ 'field' => 'primary_photo', 'scopeFields' => ['product_id'], 'scope' => [ @@ -67,14 +74,6 @@ class ProductPhotosTable extends Table 'product_id IS NOT' => null, ], ]); - $this->addBehavior('CakeProducts.SecondToggle', [ - 'field' => 'primary_category_photo', - 'scopeFields' => ['product_category_id'], - 'scope' => [ - 'deleted IS' => null, - 'product_category_id IS NOT' => null, - ], - ]); $this->addBehavior('CakeProducts.ThirdToggle', [ 'field' => 'primary_sku_photo', 'scopeFields' => ['product_sku_id'], @@ -92,7 +91,7 @@ class ProductPhotosTable extends Table $this->belongsTo('ProductCategories', [ 'foreignKey' => 'product_category_id', 'bindingKey' => 'internal_id', - 'joinType' => 'LEFT', + 'joinType' => 'INNER', 'className' => 'CakeProducts.ProductCategories', ]); @@ -121,7 +120,8 @@ class ProductPhotosTable extends Table $validator ->uuid('product_category_id') - ->allowEmptyString('product_category_id'); + ->requirePresence('product_category_id', 'create') + ->notEmptyString('product_category_id'); $validator ->scalar('photo_dir') diff --git a/tests/TestCase/Controller/ProductPhotosControllerTest.php b/tests/TestCase/Controller/ProductPhotosControllerTest.php index 71a41b3..73a064e 100644 --- a/tests/TestCase/Controller/ProductPhotosControllerTest.php +++ b/tests/TestCase/Controller/ProductPhotosControllerTest.php @@ -166,6 +166,7 @@ class ProductPhotosControllerTest extends BaseControllerTest if (!copy($file, $toUseFile)) { $this->fail('Failed to copy test image'); } + $categoryId = '6d223283-361b-4f9f-a7f1-c97aa0ca4c23'; $productId = 'cfc98a9a-29b2-44c8-b587-8156adc05317'; $primaryPhotosCountBefore = $this->ProductPhotos->find()->where(['product_id' => $productId, 'primary_photo' => true])->count(); $primaryPhotoBefore = $this->ProductPhotos->find()->where(['product_id' => $productId, 'primary_photo' => true])->first(); @@ -186,6 +187,7 @@ class ProductPhotosControllerTest extends BaseControllerTest ]); $data = [ 'product_id' => $productId, + 'product_category_id' => $categoryId, 'primary_photo' => 1, 'primary_category_photo' => 0, 'primary_sku_photo' => 0, @@ -265,7 +267,7 @@ class ProductPhotosControllerTest extends BaseControllerTest ], ]); $data = [ - 'product_id' => $productId, + 'product_id' => '', 'product_category_id' => $categoryId, 'product_sku_id' => '', 'primary_photo' => 0, @@ -327,7 +329,7 @@ class ProductPhotosControllerTest extends BaseControllerTest } $productId = 'cfc98a9a-29b2-44c8-b587-8156adc05317'; $skuId = '3a477e3e-7977-4813-81f6-f85949613979'; - + $categoryId = '6d223283-361b-4f9f-a7f1-c97aa0ca4c23'; $primarySkuPhotosCountBefore = $this->ProductPhotos->find()->where(['product_sku_id' => $skuId, 'primary_sku_photo' => true])->count(); $primarySkuPhotoBefore = $this->ProductPhotos->find()->where(['product_sku_id' => $skuId, 'primary_sku_photo' => true])->first(); @@ -349,6 +351,7 @@ class ProductPhotosControllerTest extends BaseControllerTest $data = [ 'product_id' => $productId, 'product_sku_id' => $skuId, + 'product_category_id' => $categoryId, 'primary_photo' => 0, 'primary_category_photo' => 0, 'primary_sku_photo' => 1, @@ -356,7 +359,7 @@ class ProductPhotosControllerTest extends BaseControllerTest 'enabled' => 1, ]; $this->post($url, $data); - +// dd($this->_response); $this->assertResponseCode(302); $this->assertRedirectContains('product-photos');