putyourlightson / craft-campaign

Send and manage email campaigns, contacts and mailing lists in Craft CMS.
https://putyourlightson.com/plugins/campaign
Other
63 stars 25 forks source link

Building a Condition Module #379

Closed AdamChlan closed 1 year ago

AdamChlan commented 1 year ago

I'm working on building a condition module which will only send if new entries have been published since the last sendout. I did notice you have an example of that functionality here:

https://github.com/putyourlightson/craft-campaign/blob/develop/examples/conditions/sendouts/RecentEntriesPublishedConditionRule.php

As far as the Module or Plugin that processes that rule, I see you have an example of the plugin code here: https://putyourlightson.com/plugins/campaign#condition-rules

I created a module based on this code, and overall Craft seems happy with the module, but I'm not seeing the condition available to me when I create the recurring sendout. Below is the module code.


namespace modules\emailsendmodule;

use Craft;
use craft\base\conditions\BaseCondition;
use craft\events\RegisterConditionRuleTypesEvent;
use modules\emailsendmodule\conditions\RecentEntriesPublishedConditionRule;
use yii\base\Event;
use yii\base\Module;    

/**
 * emailsend module
 *
 * @method static Module getInstance()
 */
class EmailSendModule extends Module
{
    public function init(): void
    {
        parent::init();

        Event::on(
            SendoutScheduleCondition::class,
            BaseCondition::EVENT_REGISTER_CONDITION_RULE_TYPES,
            function (RegisterConditionRuleTypesEvent $event) {
                $event->conditionRuleTypes[] = RecentEntriesPublishedConditionRule::class;
            }
        );
    }
}

I notice that the example you shared in the docs, is a plugin. Is it required that this be a plugin vs a module? Any areas you suggest I look to troubleshoot why this condition is not available to select? Thank you.

bencroker commented 1 year ago

Are you bootstrapping the module in app.php? See https://craftcms.com/docs/4.x/extend/module-guide.html#update-the-application-config

If the module is bootstrapped, then it should appear under Modules at /admin/utilities/system-report.

AdamChlan commented 1 year ago

Yes, I am bootstrapping it, and I can see it under the Modules area of system report.

bencroker commented 1 year ago

Hmm, in that case I’m not sure why it is not showing up. Are you running the latest version 2.6.0 of the Campaign plugin?

AdamChlan commented 1 year ago

Thanks for the follow up, Ben. I was running 2.5.5, but just updated to 2.6.0 and the latest Craft and it's still not a Condition option for me when building a recurring sendout. If it's any help, I'll drop in a screenshot of my module directory structure: Screenshot 2023-04-26 at 11 20 05 AM

The RecentEntriesPublishedConditionRule.php is the file that is the example you share in the plugin:

/**
 * @copyright Copyright (c) PutYourLightsOn
 */

namespace modules\emailsendmodule\conditions;

use craft\base\conditions\BaseSelectConditionRule;
use craft\base\ElementInterface;
use craft\elements\conditions\ElementConditionRuleInterface;
use craft\elements\db\ElementQueryInterface;
use craft\elements\Entry;
use DateTime;

class RecentEntriesPublishedConditionRule extends BaseSelectConditionRule implements ElementConditionRuleInterface
{
    /**
     * @inheritdoc
     */
    public string $operator = '';

    /**
     * @inheritdoc
     */
    protected function options(): array
    {
        return [
            'week' => 'week',
            'month' => 'month',
            'year' => 'year',
        ];
    }

    /**
     * @inheritdoc
     */
    public function getLabel(): string
    {
        return 'Send only if an entry was published in the past';
    }

    /**
     * @inheritdoc
     */
    public function getExclusiveQueryParams(): array
    {
        return [self::class];
    }

    /**
     * @inheritdoc
     */
    public function modifyQuery(ElementQueryInterface $query): void
    {
    }

    /**
     * @inheritdoc
     */
    public function matchElement(ElementInterface $element): bool
    {
        // Return whether any entries were published in the previous period
        $date = (new DateTime())->modify('-1 '. $this->value);

        return Entry::find()
            ->after($date)
            ->exists();
    }
}
bencroker commented 1 year ago

Let’s take a step back and try to debug this. Please add this to the EmailSendModule::init() method and ensure that the dd outputs what you would expect.

        Event::on(
            SendoutScheduleCondition::class,
            BaseCondition::EVENT_REGISTER_CONDITION_RULE_TYPES,
            function (RegisterConditionRuleTypesEvent $event) {
                $event->conditionRuleTypes[] = RecentEntriesPublishedConditionRule::class;
                // Should output an array that contains the `RecentEntriesPublishedConditionRule` class
                \Craft::dd($event->conditionRuleTypes);
            }
        );

Assuming it does, add this to the RecentEntriesPublishedConditionRule::matchElement method.


        // Return whether any entries were published in the previous period
        $date = (new DateTime())->modify('-1 '. $this->value);

        // Should output `true`
        \Craft::dd(Entry::find()->after($date)->exists());

        return Entry::find()
            ->after($date)
            ->exists();
AdamChlan commented 1 year ago

Okay, thanks for the tip. I added the code, and did a simple {% dd %} in one of my templates, and from what I can tell, there is no reference to RecentEntriesPublishedConditionRule in that output. I'm guessing this may mean that the module may not be mapping everything correctly?

bencroker commented 1 year ago

Can you ensure that your module is indeed being bootstrapped?


class EmailSendModule extends Module
{
    public function init(): void
    {
        parent::init();
        \Craft::dd('Bootstrapped.');
AdamChlan commented 1 year ago

I do indeed see "Bootstrapped."

AdamChlan commented 1 year ago

@bencroker thanks for your guidance on troubleshooting. using these methods I was able to figure out where I went wrong.

bencroker commented 1 year ago

That’s great @AdamChlan! Can you share what the problem was, in case anyone else ends up here with the same issue?