Trying to get my head around plugin development. Sorry if this is a super basic question. How do you add a method to an existing element? I’m trying to get any active Commerce 2 subscriptions for a user. I figured out how to add it as a variable to my plugin.

public function getActiveSubscriptions(int $userId): array
{
    return Subscription::find()
        ->userId($userId)
        ->status(Subscription::STATUS_ACTIVE)
        ->all();
}

It’s called by {% set subscriptions = craft.myPlugin.getActiveSubscriptions(currentUser.id) %}

That works, but I feel like the “right” way is to be able to do this {% set subscriptions = currentUser.getActiveSubscriptions() %} How do I do that?

up vote 2 down vote accepted

You can do that with Behaviors. There is a good Working example made by Pixel and Tonic team within their Git for the DotAll workshop

namespace ontherocks\behaviors;

use craft\elements\db\EntryQuery;
use craft\elements\Entry;
use craft\elements\User;
use yii\base\Behavior;

/**
 * Class UserBehavior
 *
 * @property User $owner
 * @property EntryQuery $recipes
 */
class UserBehavior extends Behavior
{
    public function getRecipes(): EntryQuery
    {
        if (!$this->owner->id) {
            // just return a query that is doomed to fail
            return Entry::find()
                ->id(false);
        }
        return Entry::find()
            ->section('recipes')
            ->authorId($this->owner->id);
    }
}

See how to attach behaviors

// define user behavior
Event::on(User::class, Element::EVENT_DEFINE_BEHAVIORS, function(DefineBehaviorsEvent $event) {
    $event->behaviors[$this->id] = UserBehavior::class;
});

You can attach your custom behavior to the user class as well exactly like the code above and do

{% set user = currentUser %}
{% set subscriptions = user.getActiveSubscriptions() %}

Or you attach the behavior to the SubscriptionQuery and do

{% set subscriptions = craft.subcriptions.activeSubscriptions(currentUser).all() %}
  • Worked like a charm, thanks! – Simon Kuran Oct 25 at 23:48

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.