8

I'm trying to figure out how to do the following:

  1. Person registers as new user
  2. User creates a new entry with a front-end entry form
  3. Entry is saved as disabled so it's not publicly visible
  4. User has the option to make entry public by making a payment with Craft Commerce.
  5. When the Craft order is complete it updates the entry in step 3 to enabled so that is will be publicly visible.

I think I should be able to use this event commerce_orders.onOrderComplete but I'm not sure how to pass the entry ID into this event and also how to check if the order that has just been completed is the order that applies to this event checkout.

Any thoughts on how to accomplish this?

1 Answer 1

11

You will need to write a plugin with three responsibilities:

  1. Keep track of which entries have been purchased
  2. Set an entry to enabled when it has been purchased
  3. Ensure that entries always have the correct status (enabled/disabled) whenever they are saved

For the first one, you will need to create a new DB table that can store records of which entries have been purchased.

In your plugin, create a records/ table with a MyPlugin_EntryPurchaseRecord.php file:

<?php
namespace Craft;

class MyPlugin_EntryPurchaseRecord extends BaseRecord
{
    public function getTableName()
    {
        return 'myplugin_entrypurchases';
    }

    public function defineRelations()
    {
        return array(
            'entry' => array(static::BELONGS_TO, 'EntryRecord'),
            'order' => array(static::BELONGS_TO, 'Commerce_OrderRecord'),
        );
    }
}

With that in place, the table will automatically get created when you install your plugin.

Next, give your primary plugin class an init() method where you can set up some event listeners:

<?php
namespace Craft;

class MyPluginPlugin extends BasePlugin
{
    // ...

    public function init()
    {
        craft()->on('commerce_orders.orderComplete', array($this, 'onOrderComplete'));
        craft()->on('entries.beforeSaveEntry', array($this, 'onBeforeSaveEntry'));
    }
}

Your onOrderComplete function will be responsible for recording the purchase in your entrypurchases table, and updating the entry’s status to enabled:

public function onOrderComplete(Event $event)
{
    /* @var Commerce_OrderModel $order */
    $order = $event->params['order'];

    // Look for a line item with an entryId option
    foreach ($order->lineItems as $lineItem)
    {
        if (!empty($lineItem->options['entryId']))
        {
            // Validate the entry ID
            $entryId = $lineItem->options['entryId'];
            $entry = craft()->entries->getEntryById($entryId);
            if (!$entry) continue;

            // Record the purchase
            $purchaseRecord = new MyPlugin_EntryPurchaseRecord();
            $purchaseRecord->entryId = $entryId;
            $purchaseRecord->orderId = $order->id;
            $purchaseRecord->save();

            // Enable the entry
            $entry->enabled = true;
            craft()->entries->saveEntry($entry);
        }
    }
}

And your onBeforeSaveEntry function will be responsible for making sure entries’ statuses are set correctly depending on whether they’ve been purchased:

public function onBeforeSaveEntry(Event $event)
{
    // Ignore for new entries
    if (!empty($event->params['isNewEntry']))
    {
        return;
    }

    /* @var EntryModel $entry */
    $entry = $event->params['entry'];

    // Ignore entries in other sections
    if ($entry->section->handle != 'mySection')
    {
        return;
    }

    // Has the entry been purchased?
    $purchaseCount = MyPlugin_EntryPurchaseRecord::model()->countByAttributes(array(
        'entryId' => $entry->id
    ));

    $entry->enabled = ($purchaseCount != 0);
}

Last but not least, you will need to update your entry purchase form to record the entry ID being purchased. We’ll do that as an option on the line item.

(If you look at the onOrderComplete function, we’re actually combing through the purchased order’s line items to look for these entryId options. This is where it gets set.)

<form method="POST">
    <input type="hidden" name="action" value="commerce/cart/updateCart">
    <input type="hidden" name="redirect" value="commerce/cart">
    <input type="hidden" name="qty" value="1">
    <input type="hidden" name="purchasableId" value="{{ variant.purchasableId }}">

    <!-- Associate the line item with this entry ID -->
    <input type="hidden" name="options[entryId]" value="{{ entry.id }}">

    <input type="submit" value="Buy Now">
</form>

Baring any typos, that should do it!

2
  • I'll check this out this evening or tomorrow. Thanks! Really appreciate it. Commented Jan 13, 2016 at 0:50
  • I just got a chance to check out this plugin today. It didn't work at first because I had missed the underscore when I was renaming the class in the records file. Once I searched through the Craft plugin documentation and saw that it was needed I made the correction and everything worked excellent. Thanks again for the help! Commented Jan 18, 2016 at 23:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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