How to properly use classes in a sage 10 theme

I am a bit confused about using classes in sage 10. The last project I did was very complex, in a sense that I had to use lots of hooks to customise the functionality of woocommerce, so I ended up with a woocommerce.php file with over 1000 lines, in the app folder. My next project will be even more complex, and I don’t want to create a plugin or write everything in a single file, I would like to use classes, as in a plugin. For example, a class in my Controllers folder would look like this :

<?php

namespace app\Controllers;

class WooController
{
    public function __construct()
    {
        add_action('init', [$this, 'register_roles']);
        add_action('wc_hook_1', [$this, 'something_1']);
        add_action('wc_hook_2', [$this, 'something_2']);
        add_action('wc_hook_3', [$this, 'something_3']);
        // ...
    }

    public function register_roles()
    {
        //  ...
    }
}


I would use this class to contain every hook that is woocommerce related. In a separate Utilities folder, I’d create a WooUtility class with static methods to keep my class cleaner. However for this to work, I need to create an instance of the WooController class. For now, inspired from another post, I added this function, but it feels wrong to do it this way:

function load_controllers($ns = 'App\Controllers') {
    foreach(glob(__dir__ . '/Controllers/*.php') as $fn) {
        $class = $ns . '\\' . basename($fn, '.php');
        new $class();
    }
}
load_controllers();

I was going to use Service Providers, but I asked a Laravel dev, and they told me I shouldn’t use a Service Provider for this, so now I’m a bit confused about the role of Service Providers in wordpress.

Where should I add the hooks? How should I structure the theme if I don’t want to write a separate plugin?

I’d do this in a mu-plugin.

I did it like that in my previous projects, but since the theme comes with so many useful stuff like collections, array methods, blade templates, etc. it would be a waste not to use them. I feel like only using the view composers is a waste, but this is just my personal opinion, which is probably wrong.

Since wordpress hooks are similar to Laravel events, I decided to use a combination of Service Providers and custom classes to achieve what I want. Here’s what I did so far:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Controllers\UserController;

class UserAccountServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register(): void
    {
        $this->app->singleton('user', function ($app) {
            return new UserController();
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot(): void
    {
        $userController = $this->app->make('user');

        add_action('init', [$userController, 'register_custom_user_roles']);
    }
}

I’m still not sure this is the best way, but maybe at least I will learn something new

I use all of those in my mu-plugins, too

That looks great :+1:

1 Like

This question is pretty open-ended: Very rarely is there an “objectively-best” way to do things, usually the best way is going to be the best way for your specific situation. How can you narrow down this question? How can you make it more specific? If you’re trying to optimize, what are you optimizing for? If you want to reduce complexity, why? What type of complexity are you trying to reduce?

In my experience, if you’re doing something you don’t like (i.e. in this case a single huge file with tons of logic) it’s helpful to think through why it’s making you uncomfortable, and what alternative(s) would “feel” better to you–generally your instincts will be a pretty good guide. Looking around for someone else’s solution can sometimes keep you from engaging deeply with the problem, and instead of getting something better you just get something different.

Personally, though, I’d recommend against doing this sort of thing:

It’ll make it a lot more difficult for any static analysis tools (i.e. your IDE) to find and analyze things.

2 Likes