Jump to content

Call to undefined function wire() with Ajax


entschleunigung
 Share

Recommended Posts

hello,

i have a _func.php file with this function. in the documentation i read that some api variables in functions are not available, so i use wire('pages').

function doSomething($u, $p) {
    $p = wire('pages')->get("id=$p");
    $u = wire('pages')->get("id=$u");
    $p->of(false);
    { ... populate repeater field stuff }
    $p->save();
}

if i call this function in my home.php like doSomething(41,1093) (only for testing!) everything is fine, the function works, it add items to a repeater field.

 

the german says "Wenn es dem Esel zu wohl ist, geht er aufs Eis", so i play around with ajax to fire up this function. 

$(document).ready(function() {
	$("#hit").click(function(){
		$.ajax({
                url: '<?= $config->urls->templates?>includes/_func.php/',
                type: 'post',
                data: {userID: "<?= $user->id ?>", pageID: "<?= $page->id ?>"},
                success: function(output){
                	console.log(output);
                }
            })
	})
})

 

i read something about variable scopes and i think i understand it a little bit. but i don't understand why doSomething(41,1093)  works in home.php the ajax call runs into a Call to undefined function wire() ?   also i tried if ($config->ajax) but no luck ...

that's the relevant party of  _func.php. 

function doSomething($u, $p) {
    $p = wire('pages')->get("id=$p");
    $u = wire('pages')->get("id=$u");
    $p->of(false);
    { ... populate repeater field stuff }
    $p->save();
}

if(isset($_POST['userID']) && !empty($_POST['userID']) && isset($_POST['pageID']) && !empty($_POST['pageID'])) {
	$u = $_POST['userID'];
	$p = $_POST['pageID'];
	{ ... }
	echo sendLike($u, $p);
}

 

where is my mistake? any ideas? 

 

thx

 

Link to comment
Share on other sites

Wrap the function with

if(! function_exists('doSomething')) {
    // function doSomething() {...} 
} 

It works when used inside home.php because _func.php was included after the PW took over the request. But when you're calling the function directly apache calls _func.php instead of index.php and PW will not be defined until you include it.

http://php.net/manual/en/function.function-exists.php

  • Like 4
Link to comment
Share on other sites

4 hours ago, entschleunigung said:

url: '<?= $config->urls->templates?>includes/_func.php/',

It's often better to use a PW page for your AJAX url than a standalone PHP file - just create a special template / template file / page for the purpose and call it in your AJAX function. That way everything in PW, init.php, etc, is available just like normal.

  • Like 5
Link to comment
Share on other sites

I certainly agree. I create a template and page called api for basic JSON outputs.

One other method to handle arbitrary urls without using any page/template can be hooking into ProcessPageView::pageNotFound like this

// /site/ready.php

wire()->addHookBefore('ProcessPageView::pageNotFound', function (HookEvent $e) {
    if ($e->input->url === '/api/create/') {
        $pageId = $e->input->post->int('id');
        $content = $e->input->post->text('text');

        // your logic
        // or hand it to another function / class etc.

        header('Content-Type: application/json');
        echo json_encode([
            'pageId' => $pageId,
            'content' => $content
        ]);
        exit();
    }
});

 

  • Like 5
Link to comment
Share on other sites

sorry for the late reply.

i check everything but nothing works for me at this moment, i will try a new installation of pw, perhaps i misconfigured something ... ?!

(abdus, your last tipp i didn't try because i want start with a fresh installation, but thanks for the hint!)

thanks for all tipps.

Link to comment
Share on other sites

Hey enschleunigung,

one way to make this work would be the following:

Instead of sending the Ajax request to your _func.php send it to any normal page. This way all the ProcessWire features will be initialized. Then in your _func.php you can do

 

function doSomething($u, $p) {
	// ...
}

if($config->ajax && $input->post->userID && $input->post->pageID) {
  echo doSomething($input->post->userID, $input->post->pageID);
  
  die(); // just output the content, do not process the templates
}

 

There are better ways to structure the code, but it will get you started.

  • Like 1
Link to comment
Share on other sites

20 hours ago, MrSnoozles said:

die(); // just output the content, do not process the templates

Please do NOT die :) There are other explanations in the forum about why but here is one too: 

https://webdesign.tutsplus.com/tutorials/processwire-tricks-and-tips--cms-28613

<?php
if ($config->ajax) {
 // AJAX content
 echo my content’;
 // Calling halt() stops template rendering but continues towards ProcessWire’s normal shutdown.
 return $this->halt();
}
// non AJAX content below

 

  • Like 4
Link to comment
Share on other sites

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

×
×
  • Create New...