Javascript to call a PHP function

I have an small app at:
/var/www/nextcloud/apps/test2

It has its own section at admin section when user can enter some values.
This section has a Javascript file
/var/www/nextcloud/apps/test2/js/adminsettings.js

I’d like to have a Javascript function “doit()” in “adminsettings.js” which should call a PHP “somefunc” -function in /var/www/nextcloud/apps/test2/lib/AppInfo/Application.php

function doit() {
var whaturl="what is the url to ..Application.php"
$.ajax({
   method: 'POST',
   url: whaturl ,
   contentType: 'application/json',
   data: JSON.stringify(test0),
        success: function(messagesent) {
                     if (messagesent == 'success')
                         {  console.log("success");    }
                     else if (messagesent == 'failure') {
                         console.log('fail!');    }
        },
   error: function() {
           alert('fail2');
   }
});   }

How do I get the url to “/var/www/nextcloud/apps/test2/lib/AppInfo/Application.php” in my Javascript function and call “somefunc” there?

Here is the “/var/www/nextcloud/apps/test2/lib/AppInfo/Application.php”

<?php
declare(strict_types=1);
namespace OCA\test2\AppInfo;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Util;
use OCP\IUser; 

class Application extends App implements IBootstrap {
    public const APP_NAME = 'test2';
    protected $appName;

   public function __construct() {
        parent::__construct(self::APP_NAME);
        }

    public function register(IRegistrationContext $context): void
    {
    }

    public function boot(IBootContext $context): void
    {
   }
}


function somefunc() {
/* do something here */
}


Hi.

That is not how it works.

You can only get what each API function serves you. If you finds a way to do what you are trying to do, please report it as a vulnerability.

1 Like

Can you suggest what would be a better way to pass data from Nexcloud Javascript to PHP

The thing is that you cannot unless you build a url that can accept the payload. JavaScript is front end and PHP is backend.

Please sugest a workaround. Javascript in my code handles a formdata in Nexcloud and input from the form should be handled by my apps PHP.
For example input is person id which is given and should be tested by the PHP code.

When submitting a form, you submits it to a specific url. Standard HTML forms can be submitted as either POST or GET.

With PHP you can access POST and GET data, but it requires that the specific PHP code is executed (typically because the php file is launched):

https://my.domain.ltd/path/myphpfile.php

myphpfile.php

$myVar = $_POST['name-of-field-in-submitted-form'];

This is a VERY crude and VERY outdated example (my own PHP coding experience is from php 5.4, so this is not even the correct commands any longer).

See PHP $_POST

With Javascript today, you typically initiates ajax, which is an entirely different beast. This is also what I notice you are trying to do. Please do some tutorials on building webservices with exposed functions and then ajax to make use of them.

Try this. It is crude, but it MIGHT work.

Please stop this. Do never access the variable _POST directly in Nextcloud unless you are developing in the core. Never ever. This will most probably bring more flaws than you can think of.

I will write some text but this needs some time as I am on mobile. Give me a few minutes.

1 Like

OK, now I am on Desktop. Much better…

First, @Kerasit is right. You cannot call PHP from JS directly (different languages, different machines, etc etc bla bla bla). Instead, you typicaly define a web API that you want to use. That is, as already mentioned, there are multiple verbs (called methods) available. You have to define

  1. Which method to use (depending on the use-case, you should not use GET for altering any data)
  2. Which path to use (plain REST would be e.g. /apps/test2/callSomefunc)
  3. What parameters should be transmitted along the request in what location (your test0 that you never specified in detail)

If you have done this specification (which is mainly prosa, in your head or whatever), you can go to build the backend part. The Nextcloud team has already prepared quite some stuff to simplify this altogether. You might want to have a look at the developer documentation, especially the Basic concepts. There, a small app is created from scratch.

To have this summarized in your case, you need a controller class to be defined, for any HTTP request of your app to be handled. You will most probably have one already. You can use it or define a new one. This depends on your use case. Let’s say, your controller is in OCA\test2\Controller\MainController and has a method called doSomething. You would have to augment your routes.php file with a line like

['name' => 'main#doSomething, 'url' => '/callSomefunc', 'verb' => 'POST'],

This will make any call to /apps/test2/callSomefunc trigger a call to the method in the class. You can call your method/function in question there as this is already inside PHP.

In order to get the correct URL, you can use the JS package @ nextcloud/router.This wouold be something like generateUrl('/apps/test2/callSomefunc').

One more point of warning: Your call using $.axios(...) does not send any authentication headers except for the session cookie. This will by default be rejected from the server for security reasons. You could/should use the preconfigured axios package in order to let the core do the credential handling. Just a word of warning and frustration.

This was a very quick introduction. Feel free to ask for further details.

Christian

2 Likes

I whole heartedly agrees. And thank you for bringing in more and better context, plus actual development advice.

1 Like