createNestedStructure
Metoda Database::createNestedStructure() převede ploché výsledky z JOIN dotazů do vnořené struktury. Nachází se v Moony\bootstrap\core\helpers\Database.
Lze ji volat přímo nebo přes QueryBuilder: ->createNestedStructure($structure)->getResult()
Příklad — SQL dotaz
Uživatelé → objednávky → logy a změny:
SELECT
users.id as users_id,
users.email,
orders.id as orders_id,
orders.product_id,
orderslogs.id as orderslogs_id,
orderslogs.action as log_action,
orderschanges.id as orderschanges_id,
orderschanges.action as change_action,
orderschanges.old_value,
orderschanges.new_value
FROM users
LEFT JOIN orders ON orders.user_id = users.id
LEFT JOIN orderslogs ON orderslogs.order_id = orders.id
LEFT JOIN orderschanges ON orderschanges.order_id = orders.id
WHERE users.id = 1
Definice struktury
use Moony\bootstrap\core\helpers\Database;
$nested = Database::createNestedStructure($rows, [
'users_id',
'email',
'orders' => [
'orders_id',
'product_id',
'logs' => [
'orderslogs_id',
'log_action'
],
'changes' => [
'orderschanges_id',
'change_action',
'old_value',
'new_value'
]
]
]);
Výsledek
Array
(
[241] => Array
(
[email] => muj@mail.com
[orders] => Array
(
[5] => Array
(
[product_id] => 12411
[logs] => Array
(
[344] => Array ([log_action] => Packet)
[345] => Array ([log_action] => Shipped)
)
[changes] => Array
(
[8452] => Array ([change_action] => Changed price, [old_value] => 299, [new_value] => 199)
)
)
[12] => Array
(
[product_id] => 32541
[logs] => Array (...)
[changes] => Array ()
)
)
)
)
Wildcards
Místo výpisu všech sloupců lze použít wildcard patterny:
* — všechny zbývající sloupce
Na root úrovni zahrne všechny sloupce, které nejsou použité ve vnořených strukturách:
$nested = Database::createNestedStructure($rows, [
'*', // všechny sloupce kromě těch ve vnořených
'orders' => [
'orders_id',
'product_id'
]
]);
prefix_* — sloupce podle prefixu
Zahrne všechny sloupce začínající daným prefixem. Prefix se automaticky odstraní z názvu klíče ve výsledku:
// SQL: SELECT comment_id, comment_text, comment_author, comment_date ...
$nested = Database::createNestedStructure($rows, [
'post_id',
'title',
'comments' => [
'comment_*' // zahrne comment_id, comment_text, ... jako id, text, ...
]
]);
// Výsledek: comments[1] => ['id' => 5, 'text' => '...', 'author' => '...', 'date' => '...']
? — volitelné vnořené struktury
Prefix ? před názvem vnořeného pole potlačí chybu pokud sloupce neexistují (LEFT JOIN kde může být NULL):
$nested = Database::createNestedStructure($rows, [
'users_id',
'email',
'?profile' => [ // nepovinné — nevyhodí chybu pokud sloupce chybí
'profile_id',
'bio'
]
]);
Přes QueryBuilder
Nested structure lze definovat přímo v QueryBuilderu:
$users = UsersRepository::queryBuilder()
->join('LEFT JOIN orders ON orders.user_id = users.id')
->setColumns(['users.id as users_id', 'users.email', 'orders.id as orders_id', 'orders.product_id'])
->createNestedStructure([
'users_id',
'email',
'orders' => [
'orders_id',
'product_id'
]
])
->getResult();
// getSingleResult() vrátí jeden vnořený záznam
$user = UsersRepository::queryBuilder()
->criterion([['[users].[id] = ?', $userId]])
->join('LEFT JOIN orders ON orders.user_id = users.id')
->createNestedStructure([...])
->getSingleResult();
Přejmenování sloupců
Sloupce lze přejmenovat pomocí string klíče — klíč je název sloupce z DB, hodnota je název ve výsledku:
$nested = Database::createNestedStructure($rows, [
'users_id',
'email' => 'userEmail', // users.email → userEmail ve výsledku
'orders' => [
'orders_id',
'product_id' => 'pid' // orders.product_id → pid ve výsledku
]
]);
generateUniqueKey
Metoda Database::generateUniqueKey() generuje unikátní slug/klíč pro danou tabulku. Pokud hodnota již existuje, automaticky přidá číslo na konec.
use Moony\bootstrap\core\helpers\Database;
// Automatické číslování: "my-article", "my-article2", "my-article3"
$slug = Database::generateUniqueKey(
Str::slug($title), // hodnota
'articles', // tabulka
'slug' // sloupec
);
// Vlastní callback pro formát
$slug = Database::generateUniqueKey(
Str::slug($title),
'articles',
'slug',
static function(string $original, int $iteration) {
return $original . '-' . $iteration; // "my-article-2", "my-article-3"
}
);
| $value | Výchozí hodnota (slug, klíč) |
| $table | Tabulka v DB |
| $column | Sloupec který musí být unikátní |
| $callback | Volitelný — dostane originál + číslo iterace, vrátí novou hodnotu k ověření |
