Roots Discourse

Sage 10, add_action in Composer controller constructor

Hi everyone, I need to use the functions I have in the controller, in my ajax call, but if I declare it this way (inside the controller)

<?php 

namespace App\View\Composers;

use Roots\Acorn\View\Composer;

class News extends Composer
{

    public function __construct()
    {  
        add_action('wp_ajax_news_filter', [$this, 'news_filter'] );
        add_action('wp_ajax_nopriv_news_filter', [$this, 'news_filter'] ); 
    }

    public static function news_filter()
    { 
      
        var_dump("news_filter");
    }
 ....

I get an error 400, it seems that it does not find the action, do you have solutions?

Many thanks

Composers are only executed when the view they are connected to is used. Your view almost certainly isn’t being called during an AJAX request, so this code is inaccessible.

Composers are not meant to be a place where you collect functionality. They are for “composing” data for the view only. If you have functionality you want to use in a Composer and somewhere else, you should extract that functionality from the Composer and put it somewhere else. Then you can call it in the Composer, in an AJAX request, or anywhere else that you might need to use it.

1 Like

hI @alwaysblank, thanks a lot for your advice, I created another file:

ajax-news-filter.php
<?php

use Roots\Acorn\View\Composer;

add_action('wp_ajax_news_filter', 'news_filter');
add_action('wp_ajax_nopriv_news_filter', 'news_filter');
function news_filter()
{ 
 $test = new News(); 
var_dump(   $test );
}

But I get an error message: Class ‘News’ not found. Did I take the wrong approach to access the class?

Many thanks

Probably? Make sure you’ve read up on PSR-4.

It seems like maybe there was a disconnect, though: You’re still trying to access the Composer class for your AJAX filters. Generally you should never be accessing or using your Composers directly. If you find yourself doing that, something about your approach is probably wrong.

I don’t know what the exactly functionality you’re try to implement here is, but you should be pulling the functionality out of the Composer and into something else, i.e.:

// sage/app/helpers.php
namespace App;

function get_some_news() {
  return get_news_posts();
}

// sage/app/View/Composers/News.php
namespace App\View\Composers;
use Roots\Acorn\View\Composer;
class News extends Composer {
  public function with() {
    return [ 'news' => \App\get_some_news() ];
  }
}

// sage/app/filters.php
namespace App;

add_action('wp_ajax_news_filter', __NAMESPACE__ . '\\get_some_news' );
add_action('wp_ajax_nopriv_news_filter', __NAMESPACE__ . '\\get_some_news' ); 
1 Like