Mirsad Batilovic
Mirsad Batilovic

Reputation: 441

Laravel: How to create dynamic functions (methods) (using foreach loop) in class

I'm building some small cms in laravel and now I need dynamic named methods and variables in my controller based on created page in my cms. I create few pages: news, world, sport, business. and now I need methods and variables in that methods named as pages names, dynamic.

This is my AjaxController.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Post;
use App\Tag;
use App\Page;

class AjaxController extends Controller
{
    protected $posts;
    protected $tags;
    protected $pages;
    protected $methods;



    public function __construct(Post $posts, Page $pages, Tag $tags)
    {
        $this->posts = $posts;
        $this->tags = $tags;
        $this->pages = $pages;

        $this->methods = $this->pages->where('parent_id', null)->where('title', '!=', 'Home')->orderBy('lft', 'asc')->get()->all();

    }

    foreach($this->methods as $method) {

        public function {$method->name}()
        {
            ${$method->name} = $this->posts->with('user')->with('category')->with('subcategory')->where('category_id', $method->id)->orderBy('created_at', 'desc')->paginate(3, ['*'], '{$method->name}');

            return view('ajax.'.$method->name, compact('{$method->name}'))->render();
        }

    }
}

This doesnt work for me.

Results that I need to get should look like this

public function news()
    {
        $news = $this->posts->with('user')->with('category')->with('subcategory')->where('category_id', 8)->orderBy('created_at', 'desc')->paginate(3, ['*'], 'news');

        return view('ajax.news', compact('news'))->render();
    }

public function world()
        {
            $world = $this->posts->with('user')->with('category')->with('subcategory')->where('category_id', 10)->orderBy('created_at', 'desc')->paginate(3, ['*'], 'world');

            return view('ajax.world', compact('world'))->render();
        }


public function sport()
    {
        $sport = $this->posts->with('user')->with('category')->with('subcategory')->where('category_id', 12)->orderBy('created_at', 'desc')->paginate(3, ['*'], 'sport');

        return view('ajax.sport', compact('sport'))->render();
    }

...

Please, how to loop and get dynamic methods and variables in class and parse that dynamic variables in laravel compact and paginate method?

Upvotes: 2

Views: 5503

Answers (1)

R. Chappell
R. Chappell

Reputation: 1282

Add a magic call method to your class, you're almost there the following example should be close to what you're thinking:

class AjaxController extends Controller
{

    public function test()
    {
        echo 'Hello world';
    }

    public function __call($name, $arguments)
    {
        $method = $this->pages
            ->where('parent_id', null)
            ->where('title', 'LIKE', $name) // Get method like the name
            ->orderBy('lft', 'asc')
            ->get();

        if (!$method) {
            throw new RuntimeException('Error, page not found');
        }

        ${$method->name} = $this->posts
            ->with('user')
            ->with('category')
            ->with('subcategory')
            ->where('category_id', $method->id)
            ->orderBy('created_at', 'desc')
            ->paginate(3, ['*'], $method->name);

        return view('ajax.' . $method->name, compact($method->name))
            ->render();
    }
}

$test = new AjaxController();
$test->sport(); // this will call the magic __call method with $name = sport
$test->news(); // this will call the magic __call method with $name = news
$test->test(); // this will call the test method

Upvotes: 3

Related Questions