luyadev / luya-module-cms

The LUYA CMS module provides a full functional CMS for adding contents based on blocks.
https://luya.io
MIT License
33 stars 46 forks source link

Injection of a menu item throws 404 error #58

Closed nick-denry closed 7 months ago

nick-denry commented 6 years ago

Hi!

I'm trying to inject menu item like it described in guide via placing following config to components section of the env-local.php

'menu' => [
    'class' => 'luya\cms\Menu',
    'on eventAfterLoad'  => function($event) {
        $event->sender->injectItem(new \luya\cms\menu\InjectItem([
            'childOf' => 1,
            'title' => 'Inject Title',
            'alias' => 'inject-title',
        ]));
    }
],

Then I get error

Not Found (#404)
Unable to find item with id 1

The above error occurred while the Web server was processing your request.

Please contact us if you think this is a server error. Thank you.
2018-04-04 20:58:06 

That's what I got in log:

yii\web\NotFoundHttpException: Unable to find item with id 1 in /var/www/project/vendor/luyadev/luya-module-cms/src/frontend/controllers/DefaultController.php:68

Stack trace and DB Queries: trace-1.txt

This is my real cms_nav_item table

2018-04-04 22 18 34

Assume that https://github.com/luyadev/luya-module-cms/blob/8fdc0d3cfa7ea0d03fd29cec91e21146ca39c861/src/frontend/controllers/DefaultController.php#L59 is not set somehow.

The problem related to this query: https://github.com/luyadev/luya-module-cms/blob/8fdc0d3cfa7ea0d03fd29cec91e21146ca39c861/src/menu/InjectItem.php#L108

if nav_id used instead of id menu item injected well but appears in left sidebar.

nadar commented 6 years ago

Maybe you are right, as nav_id would be language independent.

nick-denry commented 6 years ago

The query should be changed to respect a current page language then, isn't it?

hbugdoll commented 8 months ago

yii\web\NotFoundHttpException: Unable to find item with id 1 in /var/www/project/vendor/luyadev/luya-module-cms/src/frontend/controllers/DefaultController.php:68

Stack trace and DB Queries: trace-1.txt

Recap: The error occurs because there is no nav item of lang_id=2 (current language) and id=1, compare SQL query in trace-1.txt. The nav item with id=1 has lang_id=1 in your DB.

So in this case the use of 'childOf' => 2 would lead to the goal.

$this->_item = Yii::$app->menu->find()->where(['id' => $this->childOf])->with('hidden')->one(); if nav_id used instead of id menu item injected well but appears in left sidebar.

This is only possible due to your specific DB situation regarding nav_id=1.

Maybe you are right, as nav_id would be language independent.

But then childOf would have be transformed from a "childOfNavItem" to "childOfNav" property.

nadar commented 8 months ago

@hbugdoll what would you suggest?

hbugdoll commented 8 months ago

On second thought, I think a Nav-related childOf would fit better to be more versatile and then equal to menu item´s parent_nav_id.

A typical use-case could be a submenu:

  1. Inject an item into the submenu...
    new InjectItem([
    'childOf' => $parentNavId,
    ...
    ])
  2. Accessing all items in the submenu...
    Yii::$app->menu->find()->where(['parent_nav_id' => $parentNavId])->all();

Another use-case could be injecting at root level, e.g. for offline items in PreviewController::actionIndex():

new InjectItem([
   'childOf' => 0, // parent_nav_id = 0
   ...
])
nadar commented 8 months ago

:+1:

hbugdoll commented 8 months ago

👍

After examining the source code of InjectItem I see that the concept of inject item is based on a "real" parent menu item/NavItem (needed e.g. for alias concatenation or getting language). So finding a parent menu item/NavItem is unfortunately not unambiguous from a Nav-related childOf.

hbugdoll commented 8 months ago

We should stay with status quo, but give a hint to the developer that the $parentItem must be available for current language.

And add the alternative (and useful) inject option via parent item object

https://github.com/luyadev/luya-module-cms/blob/75a2afee6ca57e02ca5fe0df70eb077bdd0a7902/src/menu/InjectItem.php#L29-L37 to the guide https://luya.io/guide/cms/menu#menu-item-injection.

The submenu example above would become:

new InjectItem([
   'childOf' => $parentItem.id
   ...
])

// or

new InjectItem([
   'item' => $parentItem,
   ...
])

with access via

Yii::$app->menu->find()->where(['==', 'parent_nav_id', $parentItem.navId])->all();
hbugdoll commented 7 months ago

@nadar When you agree with the above ⬆️, issues https://github.com/luyadev/luya-module-cms/issues/58 and https://github.com/luyadev/luya-module-cms/issues/62 could be closed.

nadar commented 7 months ago

sounds good :+1: