Ajax call implementation. How does it works within oxid?

Hello,
Before oxid I was working with mvc php framework where when you had to make an ajax call, you simply had to create the ‘calling’ part in jquery where in url you had to define controllers name and its function. e.g. example.com/mycontroller/ajax_function. And then you should have the Mycontroller.php file with ajax_function() in it.
In oxid eshop, in my module I have created a controller MyController with a function test().
Whithin the js file I make a simple post request on
url: '/index.php?lang=1&cl=MyController&fnc=test'.
It didn’t work.
Then I tryed to extend and existing controller wich was ShopControl with test() function within it and changed appropriately url in .js file. but it also din’t work.
Both attempions having as result Status Code: 302 Found woth Header field
Location: http://oxid.loc/index.php?lang=1&cl=start&redirected=1

Can somebody explain which is the logic? What didn’t I undestand?

Best regards

1 Like

url: '/index.php?lang=1&cl=MyController&fnc=test' is the right way to go,
but “it didn’t work” is not a proper problem description. Check logs for some more exact and meaningful error messages.

Ok, but I don’t receive any error, either exception. log file stays unchanged. I’ve updated the url as you shown, the status code of request is now 200, seems to be ok, but still something is wrong. As responce I recieve html of home page. Nothing relative to this problem in apache log files too. I added die(‘request died’); in test(), but it still continues returning the home page.
Thank you for responce.
General:

  1. Request URL: http://oxid.loc/index.php?lang=1&cl=MyController&fnc=test
  2. Request Method: POST
  3. Status Code: 200 OK
  4. Remote Address: 127.0.0.1:8
  5. Referrer Policy: no-referrer-when-downgrade

Responce headers
Server: Apache/2.4.29 (Ubuntu)
Set-Cookie: language=1; path=/; HttpOnly
Set-Cookie: sid=3bvrleogba61m8q3dr74lr70kb; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 9715
Keep-Alive: timeout=5, max=96
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

Finally an exception apeared. It says
EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND mycontroller ["[object] (OxidEsales\\Eshop\\Core\\Exception\\SystemComponentException(code: 0):
By the way, I have multiple times composer dump-autoload executed. Exception still being thrown.

hard to find without the code, can be some namespace fuckup

$.ajax({
    type: "POST",
    url: '/index.php?lang=1&cl=MyController&fnc=ajax_func',
    success: function (response) {
        if (response.length > 20) {
            console.log('there is a problem CASE 1');
        }
        else {
            console.log(response);
        }
    },
    error: function () {
        console.log('there is a problem CASE 2');
    }
});
<?php

namespace Imoleg\Toaster\Controller;

class MyController
{
	const MESSAGE = 'It is a response';
	
	public function ajax_func()
	{
       	echo json_encode('here I am.');
	}
}
composer autoload line: 
  "autoload": {
    "psr-4": {
      "Imoleg\\Toaster\\Controller\\": "./source/modules/imoleg/imToaster/Controller"
    }
  },

metadata.php

<?php
$sMetadataVersion = '2.0';

/**

* Module information

*/

$aModule = [

'id' =&gt; 'imToaster',

'title' =&gt; 'Toaster',

'description' =&gt; 'Tutorial and testings module',

'thumbnail' =&gt; 'logo.jpg',

'version' =&gt; '1.0.0',

'author' =&gt; 'imoleg',

'url' =&gt; 'https://www.imoleg.com/',

'email' =&gt; '[email protected]',

'extend' =&gt; [],

'controllers' =&gt; [],

'events' =&gt; [],

'templates' =&gt; [],

'blocks' =&gt; [

[

'template' =&gt; 'layout/header.tpl', 'block'=&gt;'layout_header_top', 'file'=&gt;'View/msg.tpl'

]

],

'settings' =&gt; [],

];

Why is metadata so scrambled? In “autoload” should be the base namespace wihtout “Controller”. In your metadata you are not defining the controller, so Oxid cannot know it.

remove the controller from the namespace, the

"Imoleg\\Toaster\\": "./source/modules/imoleg/imToaster/"

and register your controller in the metadata file.

Probably you are right. But what you mean to register my controller in metadata? It is not extending any Namespaced controller. Should I put it within ‘controllers’ var and not in ‘extend’? If so, does the key value matters? e.g. ‘modulscontroller’ => Imoleg\Toaster\Controller\MyController::class?
Thank you for help!

*Metadata file is not scrambled, simply the editor of this forum has replaced the ‘=’ with ‘=&g;’

'controllers' => [
    'MyController => \Imoleg\Toaster\Controller\MyController::class
];

The key is what you put into the url (for the parameter cl=)

Background is that namespaced classes can be found by the autoloader, but since you cannot use the namespaced classname in an url, in controllers array you create an alias for the class: Version 2.0 — OXID eShop developer documentation 6.0.0 documentation

Have registered the controller as you said:
metadata.php:
'immycontroller' = Imoleg\Toaster\Controller\MyController::class
file.js:
url: '/index.php?lang=1&amp;cl=immycontroller&amp;fnc=ajax_func',
composer.json:
"Imoleg\\Toaster\\": "./source/modules/imoleg/imToaster"

executed composer dump-autoload, cleared cache, deactivated-activated module

The result is the same,
Server responces with start page and none exception is thrown.

is the filename Controller/MyController.php?

you can add

“oxid-community/moduleinternals”: “^1.0”,

to your required modules in composer.json and install this modul, here you can see if all classes can be found etc…

Just to be shure, did you add the namespace to composer.json in shop root directory or in module directory?

@leofonic Yes, it’s in the root directory. @Jb123, I will check it! And yes the file name is MyController.php

I don’t mean to resurrect an old form post. The forum seems pretty inactive nowadays anyway.

Does anyone know how to avoid a 302 redirect for an admin AJAX call? when I make a request as outlined here, it still makes a 302 redirect and I am not sure how I can pass an authenticated request to the controller.

This post and another one kept popping up as a solution from Googling - but the answers are not given which can be frustrating for others trying to find the similar resolutions.