Roots Discourse

Using one function with ACF from one Controller in another

I have a Press Page that has its own Template, and a Repeater ACF:

Controllers/TemplatePress.php

namespace App\Controllers;

use Sober\Controller\Controller;

class TemplatePress extends Controller
{
  public function PressList(){

// Get Repeater
$pressRepeater = get_field('press_stories');    

//Return an array
   return array_map(function ($item) { 
    return [
        'title'       => $item['title'],          
        'description' => $item['description'],
        'link'        => $item['link'],
        'date'        => $item['date'],
    ];
}, $pressRepeater ?? [] );

  }
}

template-press.blade.php

@foreach($press_list as $item )
  @include('partials.press' , $item)
@endforeach

This works well for the press Page. However, I also have another page, Parent to Press, that has to show the First 4 items in the the repeater.

What would be best practice to do this? Should I make the function (PressList) inside the controller static so I can call it from the other controller? or duplicate that function entirely and place it inside the TemplateWho Controller?

Secondly, to limit it to only 4 iterations, would this be the proper way:

template.who.blade.php

$i = 1;
@foreach($press_funnel as $item )

  $i++;

  @include('partials.press' , $item)

  @if($i == 4)
    @break
 @endif
@endforeach

Maybe you can take a look at this:

By creating a PHP trait for it you can reuse the code :slight_smile:

Thanks for that link! If both templates had the repeater field, this, this would have worked perfectly. I might refactor some code using that.

Unfortunately, the Press Template/Page is the only one that has the repeater. The Who template doesn’t have the repeater, rather it pulls the repeater data from the press page, currently I’m doing this:

public function PressFunnel(){

    //Get Press Page ID
    $press = get_page_by_title( 'Press' ); //as an e.g.

    // Get Repeater
    $pressRepeater = get_field('press_stories',$press->ID);    

    //Return an array
    return array_map(function ($item) { 
      return [
          'title'       => $item['title'],          
          'description' => $item['description'],
          'link'        => $item['link'],
          'date'        => $item['date'],
        ];
    }, $pressRepeater ?? [] );
}

You can do something like this:

public function PressFunnel() {
    $pressId = get_the_ID();
    if (get_the_title !== 'Press') {
        $press = get_page_by_title( 'Press' );
        $pressId = $press->ID;
    }
    
    // Get Repeater
    $pressRepeater = get_field('press_stories', $pressId);    

    //Return an array
    return array_map(function ($item) { 
      return [
          'title'       => $item['title'],          
          'description' => $item['description'],
          'link'        => $item['link'],
          'date'        => $item['date'],
        ];
    }, $pressRepeater ?? [] );
}
1 Like

Or maybe even something like this (havent tested this, just a quick example):

trait PressFunnel 
{
    public function PressFunnel($id = false) {
        $pressRepeater = get_field( 'press_stories', $id );  // false equals to current post

        //Maybe do something with a limit here
        return array_map(function ($item) { 
            return [
                'title'       => $item['title'],          
                'description' => $item['description'],
                'link'        => $item['link'],
                'date'        => $item['date'],
            ];
        }, $pressRepeater ?? [] );
    }
}
class TemplatePress extends Controller
{
    use PressFunnel ;
}
class TemplateWho extends Controller
{
    use PressFunnel {
        PressFunnel as ParentPressFunnel
    );

    public function PressFunnel($id = false) {
        $press = get_page_by_title( 'Press' );
        return $this->ParentPressFunnel($press->ID);
    }
}

Using $post_id false in the AFC get_field equals to current post.

Info about Overriding & Extending a PHP Trait Method:

1 Like

Perfect that works perfectly! :+1:

Nice which one did you use :)?

I Combined a little of both, heres a breakdown for all the future people:

Controllers/Partials/PressFunnel.php

namespace App\Controllers\Partials;

trait PressFunnel
{
    public function PressFunnel() {

      $pressId = get_the_ID();
      
      //If We Are not on the Press Page, lets go Find it and get that ID;
      if (get_the_title() !== 'Press') {
          $press = get_page_by_title( 'Press' );
          $pressId = $press->ID;
      }

        $pressRepeater = get_field( 'press_stories', $pressId );  // false equals to current post

        //Maybe do something with a limit here
        return array_map(function ($item) {
            return [
                'title'       => $item['title'],
                'description' => $item['description'],
                'link'        => $item['link'],
                'date'        => $item['date'],
            ];
        }, $pressRepeater ?? [] );
    }
}

So the Partial handles all the Data, then you just use the Parital in the regular files as:

Controller/TemplatePress.php

use Sober\Controller\Controller;

class TemplatePress extends Controller
{
    use Partials\PressFunnel;
}

Controller/TemplateWho.php

use Sober\Controller\Controller;

class TemplateWho extends Controller
{
  public function StaffBlock(){
  //Bla bla lots of Code
  }

  public function AnnualReport(){
  //Bla bla lots of Code
  }

  use Partials\PressFunnel;

}

Very nice :slight_smile:

Hello!
I’ll add that you can use the variable $loop available in your foreach loop (in your blade template)

1 Like

I had no idea that existed, that is brilliant. I can use that instead of my own counter

1 Like

Ohhhh yes :slight_smile: Enjoy it!