set correct category url_path in multiple root categories environment
This commit is contained in:
parent
f4499b4728
commit
c065631a58
|
|
@ -23,9 +23,8 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
|
|||
BEGIN
|
||||
|
||||
DECLARE urlPath VARCHAR(255);
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS root_categories AS (SELECT id FROM categories where parent_id IS NULL);
|
||||
|
||||
IF categoryId NOT IN (SELECT id FROM root_categories)
|
||||
-- Category with id 1 is root by default
|
||||
IF categoryId <> 1
|
||||
THEN
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
|
||||
|
|
@ -37,20 +36,14 @@ class AddStoredFunctionToGetUrlPathOfCategory extends Migration
|
|||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = categoryId
|
||||
AND parent.id NOT IN (SELECT id FROM root_categories)
|
||||
AND parent.id <> 1
|
||||
AND parent_translations.locale = localeCode
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
||||
IF urlPath IS NULL
|
||||
THEN
|
||||
SET urlPath = (
|
||||
SELECT slug
|
||||
FROM category_translations
|
||||
WHERE
|
||||
category_translations.category_id = categoryId
|
||||
AND category_translations.locale = localeCode
|
||||
);
|
||||
SET urlPath = (SELECT slug FROM category_translations WHERE category_translations.category_id = categoryId);
|
||||
END IF;
|
||||
ELSE
|
||||
SET urlPath = '';
|
||||
|
|
|
|||
|
|
@ -63,9 +63,8 @@ SQL;
|
|||
DECLARE parentUrlPath varchar(255);
|
||||
DECLARE urlPath varchar(255);
|
||||
|
||||
CREATE TEMPORARY TABLE IF NOT EXISTS root_categories AS (SELECT id FROM categories where parent_id IS NULL);
|
||||
|
||||
IF NEW.category_id NOT IN (SELECT id FROM root_categories)
|
||||
-- Category with id 1 is root by default
|
||||
IF NEW.category_id <> 1
|
||||
THEN
|
||||
|
||||
SELECT
|
||||
|
|
@ -78,8 +77,7 @@ SQL;
|
|||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = (SELECT parent_id FROM categories WHERE id = NEW.category_id)
|
||||
AND node.parent_id IS NOT NULL
|
||||
AND parent.parent_id IS NOT NULL
|
||||
AND parent.id <> 1
|
||||
AND parent_translations.locale = NEW.locale
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ SQL;
|
|||
WHERE category_id = NEW.id);
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
|
||||
|
||||
|
||||
IF EXISTS (
|
||||
SELECT *
|
||||
FROM category_translations
|
||||
|
|
@ -78,29 +79,21 @@ SQL;
|
|||
|
||||
OPEN curs;
|
||||
|
||||
SET done = 0;
|
||||
SET done = 0;
|
||||
REPEAT
|
||||
FETCH curs INTO localeCode;
|
||||
FETCH curs INTO localeCode;
|
||||
|
||||
SELECT get_url_path_of_category(NEW.id, localeCode) INTO urlPath;
|
||||
|
||||
IF NEW.parent_id IS NULL
|
||||
THEN
|
||||
SET urlPath = '';
|
||||
END IF;
|
||||
|
||||
UPDATE category_translations
|
||||
SET url_path = urlPath
|
||||
WHERE
|
||||
category_translations.category_id = NEW.id
|
||||
AND category_translations.locale = localeCode;
|
||||
WHERE category_translations.category_id = NEW.id;
|
||||
|
||||
UNTIL done END REPEAT;
|
||||
|
||||
CLOSE curs;
|
||||
|
||||
END IF;
|
||||
|
||||
SQL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AlterTriggerCategoryTranslations extends Migration
|
||||
{
|
||||
private const TRIGGER_NAME_INSERT = 'trig_category_translations_insert';
|
||||
private const TRIGGER_NAME_UPDATE = 'trig_category_translations_update';
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$triggerBody = $this->getTriggerBody();
|
||||
$insertTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
BEFORE INSERT ON category_translations
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$updateTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
BEFORE UPDATE ON category_translations
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$this->dropTriggers();
|
||||
|
||||
DB::unprepared(sprintf($insertTrigger, self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf($updateTrigger, self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$this->dropTriggers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the triggers
|
||||
*/
|
||||
private function dropTriggers()
|
||||
{
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns trigger body as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTriggerBody()
|
||||
{
|
||||
return <<<SQL
|
||||
DECLARE parentUrlPath varchar(255);
|
||||
DECLARE urlPath varchar(255);
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT id
|
||||
FROM categories
|
||||
WHERE
|
||||
id = NEW.category_id
|
||||
AND parent_id IS NULL
|
||||
)
|
||||
THEN
|
||||
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO parentUrlPath
|
||||
FROM
|
||||
categories AS node,
|
||||
categories AS parent
|
||||
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
|
||||
WHERE
|
||||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = (SELECT parent_id FROM categories WHERE id = NEW.category_id)
|
||||
AND node.parent_id IS NOT NULL
|
||||
AND parent.parent_id IS NOT NULL
|
||||
AND parent_translations.locale = NEW.locale
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
||||
IF parentUrlPath IS NULL
|
||||
THEN
|
||||
SET urlPath = NEW.slug;
|
||||
ELSE
|
||||
SET urlPath = concat(parentUrlPath, '/', NEW.slug);
|
||||
END IF;
|
||||
|
||||
SET NEW.url_path = urlPath;
|
||||
|
||||
END IF;
|
||||
SQL;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AlterStoredFunctionUrlPathCategory extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$functionSQL = <<< SQL
|
||||
DROP FUNCTION IF EXISTS `get_url_path_of_category`;
|
||||
CREATE FUNCTION get_url_path_of_category(
|
||||
categoryId INT,
|
||||
localeCode VARCHAR(255)
|
||||
)
|
||||
RETURNS VARCHAR(255)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
|
||||
DECLARE urlPath VARCHAR(255);
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT id
|
||||
FROM categories
|
||||
WHERE
|
||||
id = categoryId
|
||||
AND parent_id IS NULL
|
||||
)
|
||||
THEN
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
|
||||
FROM
|
||||
categories AS node,
|
||||
categories AS parent
|
||||
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
|
||||
WHERE
|
||||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = categoryId
|
||||
AND node.parent_id IS NOT NULL
|
||||
AND parent.parent_id IS NOT NULL
|
||||
AND parent_translations.locale = localeCode
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
||||
IF urlPath IS NULL
|
||||
THEN
|
||||
SET urlPath = (SELECT slug FROM category_translations WHERE category_translations.category_id = categoryId);
|
||||
END IF;
|
||||
ELSE
|
||||
SET urlPath = '';
|
||||
END IF;
|
||||
|
||||
RETURN urlPath;
|
||||
END;
|
||||
SQL;
|
||||
|
||||
DB::unprepared($functionSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
DB::unprepared('DROP FUNCTION IF EXISTS `get_url_path_of_category`;');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AlterTriggerOnCategories extends Migration
|
||||
{
|
||||
private const TRIGGER_NAME_INSERT = 'trig_categories_insert';
|
||||
private const TRIGGER_NAME_UPDATE = 'trig_categories_update';
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$triggerBody = $this->getTriggerBody();
|
||||
|
||||
$insertTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
AFTER INSERT ON categories
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$updateTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
AFTER UPDATE ON categories
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$this->dropTriggers();
|
||||
|
||||
DB::unprepared(sprintf($insertTrigger, self::TRIGGER_NAME_INSERT));
|
||||
|
||||
DB::unprepared(sprintf($updateTrigger, self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$this->dropTriggers();
|
||||
}
|
||||
|
||||
private function dropTriggers()
|
||||
{
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns trigger body as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTriggerBody(): string
|
||||
{
|
||||
return <<< SQL
|
||||
DECLARE urlPath VARCHAR(255);
|
||||
DECLARE localeCode VARCHAR(255);
|
||||
DECLARE done INT;
|
||||
DECLARE curs CURSOR FOR (SELECT category_translations.locale
|
||||
FROM category_translations
|
||||
WHERE category_id = NEW.id);
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
|
||||
|
||||
|
||||
IF EXISTS (
|
||||
SELECT *
|
||||
FROM category_translations
|
||||
WHERE category_id = NEW.id
|
||||
)
|
||||
THEN
|
||||
|
||||
OPEN curs;
|
||||
|
||||
SET done = 0;
|
||||
REPEAT
|
||||
FETCH curs INTO localeCode;
|
||||
|
||||
SELECT get_url_path_of_category(NEW.id, localeCode) INTO urlPath;
|
||||
|
||||
IF NEW.parent_id IS NULL
|
||||
THEN
|
||||
SET urlPath = '';
|
||||
END IF;
|
||||
|
||||
UPDATE category_translations
|
||||
SET url_path = urlPath
|
||||
WHERE
|
||||
category_translations.category_id = NEW.id
|
||||
AND category_translations.locale = localeCode;
|
||||
|
||||
UNTIL done END REPEAT;
|
||||
|
||||
CLOSE curs;
|
||||
|
||||
END IF;
|
||||
SQL;
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +122,8 @@ class DatabaseLogicCest
|
|||
])->first();
|
||||
$root2Category->save();
|
||||
|
||||
$I->assertNull($root2Category->refresh()->parent_id);
|
||||
|
||||
$urlPathQueryResult = DB::selectOne($sqlStoredFunction, [
|
||||
'category_id' => $root2Category->id,
|
||||
'locale_code' => $this->localeEn->code,
|
||||
|
|
|
|||
|
|
@ -179,7 +179,6 @@ class TriggerCest
|
|||
'locale' => $this->localeDe->code,
|
||||
'url_path' => strtolower($this->parentCategoryName) . '/' . strtolower($this->categoryName)
|
||||
]);
|
||||
//eval(\psy\sh()); // TODO REMOVE
|
||||
$I->seeRecord(CategoryTranslation::class, [
|
||||
'category_id' => $this->root2Category->id,
|
||||
'name' => $this->root2CategoryName,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class CategoryCest
|
|||
'locale_id' => $this->localeEn->id,
|
||||
],
|
||||
];
|
||||
$this->grandChildCategory = $I->make(Category::class, $this->grandChildCategoryAttributes);
|
||||
$this->grandChildCategory = $I->make(Category::class, $this->grandChildCategoryAttributes)->first();
|
||||
$this->childCategory->prependNode($this->grandChildCategory);
|
||||
$I->assertNotNull($this->grandChildCategory);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue