Jump to content

Modules that execute PHP via ajax


owzim
 Share

Recommended Posts

Let's say I have an Inputfield module InputfieldAwesome, it has some custom JS as well and from there I want to execute some PHP via an ajax call.

My question here is not how to implement the ajax and JS stuff, but where I would put the PHP that is called?

I thought about creating a separate Process Module ProcessAwesome, which then resides as a page within /processwire (or custom admin url) (so /processwire/awesome would have the process of ProcessAwesome assigned to it) and has its execute methods (like executeDosomething()), so that I can then call it via ajax like /processwire/awesome/dosomething ...

But it seems awkward to create extra process pages to have an input field execute some PHP via ajax, and it would clutter the admin page tree (although it would be hidden of course).

Is that the way to go? I couldn't find any useful hints in existing modules.

Link to comment
Share on other sites

Well, you do need a url where to run the code, and in pw urls are pages. I don't think it's strange to create a page hidden in the admin for this.

  • Like 1
Link to comment
Share on other sites

Or simple the same page as called to load the initial page? 

<?php
if($config->ajax) {
    // page was requested from ajax
}

The initial (not ajax page load) should be the "else" to that if...

Or I missing something?

Link to comment
Share on other sites

What diogo said. If you really need a fieldtype to do ajax internally you best create a hidden admin page with a process module to handle all that. Not overkill but a well streamlined approach, and makes it solid and easy, also the admin URL that way is sure to be unique throughout the system. Gives an interface that is well defined. Process pages are meant for that and PW uses it also in some places like Page tree and fieldtypes. 

If you will you can of course always catch and bypass the requested url in a module init. Something like

   public function init() {
        $adminUrl = ltrim($this->config->urls->admin, "/");
        if($this->input->get->it == $adminUrl . "testmodule/load"){
            echo $this->executeLoad();
            exit;
        }
    }
    protected function executeLoad(){
        $id = $this->input->get->id;
        return $this->pages->get((int)$id)->title;
    }

And a js ajax request might look like

$(function(){
    $.ajax({
        type: 'get',
        url: "/processwire/testmodule/load",
        data: "id=1001",
        success: function(data){
            alert(data);
        }
    });
});

But I don't know if that's really a good idea at all. Just because you can doesn't mean it's good.

  • Like 4
Link to comment
Share on other sites

Thanks @diogo and @Soma, I'll fiddle around with the process module approach then.

@pwFoo thanks but the method you're talking about is used in templates, even if it's callable in modules (perhaps it is) with $this->config->ajax, all modules other than process modules don't have a page/url per se, so neither do input fields, that's why I asked how to have some code logic that's callable via url.

  • Like 1
Link to comment
Share on other sites

Here's my way of organizing AJAX. It's just another way of doing it.

There's a module with some functions for handling AJAX requests. Mine's called 'fjax' and has some extra code for optionally sanitizing arguments to the functions.

There's a 'fjax' template too. The fjax page (using fjax template) can be very minimal. I suggest putting it in /tools/fjax/ and setting tools as hidden. Having a Page gives us a handy URL to send requests to and the template file becomes the place to put the application's server-side AJAX code. The fjax template doesn't need anything more than the required title field. On the client side we use jQuery's AJAX tools.

If you POST the data, use the query string on the URL to indicate the function you want to call (tools/fjax/?fn=function) and the module will simply pass the POST array to the function and return the result JSON encoded. If you use GET you pass the arguments on the query string too (tools/fjax/?fn=function&arg1=foo).

In the template file you have 5 lines of code plus your function definitions. It's a simple PHP file so you can easily pull in code from reusable files etc.

The fact that it's used with a Page means you can use Page fields as easily configurable data for your server-side AJAX functions.

  • Like 4
Link to comment
Share on other sites

  • 1 year later...

Hello all,

I know this topic is pretty old, but hopefully there will still be an answer.

I have a page that reloads some images by ajax call to be used in lightbox slideshow. So I took the ProcessHello module from Ryan and adapted it as he described. I then created a page under admin with the admin template and assigned my processmodule. Put my code in the ___execute() function and off it went:

public function ___execute() {

        $pageid = $this->input->get->pageid;
        $page = $this->pages->get($pageid);

	$out = "<div class='sliderContainer'>";
        $out .= "<div class=\"royalSlider rsDefault sliderInLightbox\">";
        foreach($page->solution_img as $image) {
            $out .= "<a class='rsImg' href='{$image->url}'></a>";
        }
        $out .= "</div>";
        $out .= "
          <script>
          jQuery(document).ready(function($) {
            /* initialize slider as usual */
            $('.sliderInLightbox').royalSlider({
              imageScaleMode: 'fill',
              keyboardNavEnabled: true,
              video: {
                autoHideControlNav: true
              }
            });
          });
          </script>
        ";
        $out .= "</div>";

	return $out;
}	

However, only when I am logged in as admin. As a guest user, I get redirected to the login page. Is this supposed to be for admin tasks only? Can I have Processmodules in userspace? Or should I go the way SteveB described?

Regards Oliver

Link to comment
Share on other sites

Just adding and summarize again:

Like @owzim above described, I setup:

  • a ProcessModule named ProcessSlider
  • created an admin page 'slider' with the above Processmodule assigned
  • I set the permission of the module (getModuleInfo) to 'page-view'
  • the '___execute' method delivers my ajax requested html content
  • the page get called by '/admin/slider/?pageid=<id>'

So my question is:

Why I keep getting redirected to login page, when not logged in as superuser? I was under the impression, that setting the module permission to 'page-view' is sufficient. And technically speaking, I'm always logged in as guest, if I'm not logged as someone else, am I not?

To clarify, I don't want to extend my admin interface, just want to deliver ajax content to everyone that looks up that particular page.

Regards Oliver

Link to comment
Share on other sites

Thank you for clarification, @soma!

I solved my problem by creating an 'ajax' template which contains my code and a page using this template that is a child of a hidden tools page. So this is something along the lines of what @SteveB described.

Cheers Oliver

Link to comment
Share on other sites

  • 6 years later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...