Create new Controller accessible by URI in OXID 6 with namespaces

I want to create a module with a controller, that is accessible by URI like this:

https://shopuri.com/index.php?cl=myvendor_mymodule_mycontroller&fnc=helloWorld

So I created a module with this metadata.php (shortened):

$sMetadataVersion = '2.0';
$aModule = array(
     'id'           => 'mymodule',

     'controllers' => [
        'myvendor_mymodule_mycontroller' => MyVendor\MyModule\MyController::class,
    ],
);

Then I created my Controller MyController in ./source/modules/myvendor/mymodule/Controller/MyController.php (complete Controller, just one function):

<?php

namespace MyVendor\MyModule\Controller

class MyController
{
    public function helloWorld()
    {
        echo "Hello world!";
    }
}

After that, I added the following lines to oxid’s composer.json

"autoload": {
    "psr-4": {
        "MyVendor\\MyModule\\": "./source/modules/myvendor/mymodule"
    }
},

Finally, I called composer dump-autoload in order to publish my Controller to the autoloader (if I got that right). Then I activated my module in the admin backend.

What I expected: When calling the URL above, I’d like to see the “Hello world!” on screen.

What I got: Redirect to Shop.

The oxideshop.log has logged an exception: EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND MyVendor\MyModule\MyController

What am I doing wrong?

Possible that helps:

metadata.php:

'controllers' => [
'myvendor_mymodule_mycontroller' => \MyVendor\MyModule\MyController::class,
],

Then in your Controller:

class MyController extends \OxidEsales\Eshop\Application\Controller\FrontendController

And in your composer.json

 "psr-4": {
 "MyVendor\\": "./source/modules/myvendor"
 }

–>composer dump-autoload

Thank you! But that didn’t help. It’s still the same error message in logfile and still a redirect to shop. :frowning:

Any further ideas?

I think the code you posted first is almost correct except:

  • there should be a semicolon in the controller after the namespace
  • in metadata, the “Controller”-Folder is missing in the namespace. Should be the same as in the Controller: MyVendor\MyModule\Controller\MyController::class
  • As mentioned the Controller should extend the default frontend controller
1 Like

After these corrections it works! Thank you!

FYI the critical lines of code:

metadata.php:

'extend'      => [
    \OxidEsales\Eshop\Application\Controller\FrontendController::class => \MyVendor\MyModule\Controller\MyController::class,
],

'controllers' => [
    'myvendor_mymodule_mycontroller' => \MyVendor\MyModule\Controller\MyController::class,
],

MyController.php:

<?php

namespace MyVendor\MyModule\Controller;

class MyController extends \OxidEsales\Eshop\Application\Controller\FrontendController
{
    public function helloWorld()
    {
        echo "Hello world!";
    }
}

Again, thank you! :slight_smile:

1 Like

Btw. it’s a PITA to post source code snippets in the forum. Or am I’m doing it wrong? :smiley:

you are probably doing it right, but cloudflare firewall is blocking it very often.
Thats a common problem also with other forums, too, but there is no solution so far (except disabling firewall and opening our virtual doors for all the spam bots.)
In the meantime i suggest using external services like pastebin or gists

1 Like

One more thing i noticed: you do not need the ‘extend’-Array in metadata in this case.

1 Like

Right! Everything is better with namespaces!

One question left: Now my controller no longer appears in this list where you can sort the order of the modules:

Is the order of extending controllers in modules not relevant anymore with namespaces?

That’s because you didn’t modify an existing controller (e.g. ArticleListController), but you created a new one. If you modify an existing class, you have to use the “extends” array in metadata. If you create your own class, this used to be registered in the “files” array. “Files” is not needed anymore (autoloading), so now you have “controllers” to define a name for the “cl”-parameter. Your own classes (in “files” or in “controllers”) do not appear in the “loaded modules” list, only the ones that modify an existing class.

2 Likes

Of course you’re right. I was confused because of extending (not modifying) the default frontend controller. Thanks for the explanation! :grinning: