Skip to content
  1. Extras
  2. MiniShop3
  3. Development
  4. Events
  5. Product

Product events (catalog)

Events for modifying product price, weight and fields when output in the catalog.

Feature

These events support a plugin chain — each plugin can read the previous result via $modx->eventData and pass its result to the next.

msOnGetProductPrice

Fired when getting product price. Lets you modify the price on the fly.

Parameters

ParameterTypeDescription
msProductDatamsProductDataProduct data object
dataarrayExtra product data
pricefloatCurrent price

Modifying data (with chain support)

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductPrice':
        $price = $modx->eventData['msOnGetProductPrice']['price']
            ?? $scriptProperties['price'];
        $data = $scriptProperties['data'];

        if ($data['parent'] == 5) {
            $price = $price * 0.85;
        }

        $modx->eventData['msOnGetProductPrice']['price'] = $price;

        $values = &$modx->event->returnedValues;
        $values['price'] = $price;
        break;
}

Personal prices

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductPrice':
        $price = $modx->eventData['msOnGetProductPrice']['price']
            ?? $scriptProperties['price'];
        $productData = $scriptProperties['msProductData'];

        if ($modx->user->isMember('VIP')) {
            $price = $price * 0.8; // -20%
        }

        if ($modx->user->isMember('Wholesale')) {
            $wholesalePrice = $productData->get('wholesale_price');
            if ($wholesalePrice > 0) {
                $price = $wholesalePrice;
            }
        }

        $modx->eventData['msOnGetProductPrice']['price'] = $price;
        $values = &$modx->event->returnedValues;
        $values['price'] = $price;
        break;
}

Dynamic markup by currency rate

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductPrice':
        $price = $modx->eventData['msOnGetProductPrice']['price']
            ?? $scriptProperties['price'];

        $rate = $modx->cacheManager->get('usd_rate') ?? 90;

        $productData = $scriptProperties['msProductData'];
        if ($productData->get('currency') === 'USD') {
            $price = $price * $rate;
        }

        $modx->eventData['msOnGetProductPrice']['price'] = $price;
        $values = &$modx->event->returnedValues;
        $values['price'] = round($price, 2);
        break;
}

msOnGetProductWeight

Fired when getting product weight. Lets you modify weight on the fly.

Parameters

ParameterTypeDescription
msProductDatamsProductDataProduct data object
dataarrayExtra product data
weightfloatCurrent weight

Modifying data

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductWeight':
        $weight = $modx->eventData['msOnGetProductWeight']['weight']
            ?? $scriptProperties['weight'];
        $data = $scriptProperties['data'];

        $packagingWeight = 0.5;
        $weight = $weight + $packagingWeight;

        $modx->eventData['msOnGetProductWeight']['weight'] = $weight;
        $values = &$modx->event->returnedValues;
        $values['weight'] = $weight;
        break;
}

Volumetric weight

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductWeight':
        $weight = $modx->eventData['msOnGetProductWeight']['weight']
            ?? $scriptProperties['weight'];
        $productData = $scriptProperties['msProductData'];

        $length = $productData->get('length') ?? 0;
        $width = $productData->get('width') ?? 0;
        $height = $productData->get('height') ?? 0;

        if ($length > 0 && $width > 0 && $height > 0) {
            $volumeWeight = ($length * $width * $height) / 5000;
            $weight = max($weight, $volumeWeight);
        }

        $modx->eventData['msOnGetProductWeight']['weight'] = $weight;
        $values = &$modx->event->returnedValues;
        $values['weight'] = $weight;
        break;
}

msOnGetProductFields

Fired when getting product fields. Lets you add or modify any fields.

Parameters

ParameterTypeDescription
msProductDatamsProductDataProduct data object
dataarrayProduct fields array

Modifying data

php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductFields':
        $data = $modx->eventData['msOnGetProductFields']['data']
            ?? $scriptProperties['data'];

        $data['discount_percent'] = 0;
        if ($data['old_price'] > 0 && $data['price'] > 0) {
            $data['discount_percent'] = round(
                (($data['old_price'] - $data['price']) / $data['old_price']) * 100
            );
        }

        $remains = $data['remains'] ?? 0;
        if ($remains <= 0) {
            $data['availability'] = 'out_of_stock';
            $data['availability_text'] = 'Out of stock';
        } elseif ($remains < 5) {
            $data['availability'] = 'low_stock';
            $data['availability_text'] = 'Low stock';
        } else {
            $data['availability'] = 'in_stock';
            $data['availability_text'] = 'In stock';
        }

        $modx->eventData['msOnGetProductFields']['data'] = $data;
        $values = &$modx->event->returnedValues;
        $values['data'] = $data;
        break;
}
php
<?php
switch ($modx->event->name) {
    case 'msOnGetProductFields':
        $data = $modx->eventData['msOnGetProductFields']['data']
            ?? $scriptProperties['data'];
        $productData = $scriptProperties['msProductData'];

        $reviewCount = $modx->getCount('msProductReview', [
            'product_id' => $data['id'],
            'published' => 1,
        ]);
        $data['review_count'] = $reviewCount;

        $c = $modx->newQuery('msProductReview');
        $c->where(['product_id' => $data['id'], 'published' => 1]);
        $c->select('AVG(rating) as avg_rating');
        if ($c->prepare() && $c->stmt->execute()) {
            $data['avg_rating'] = round($c->stmt->fetchColumn(), 1);
        }

        $modx->eventData['msOnGetProductFields']['data'] = $data;
        $values = &$modx->event->returnedValues;
        $values['data'] = $data;
        break;
}

Full example: discounts and promotions

php
<?php
/**
 * Plugin: Discounts and promotions
 * Events: msOnGetProductPrice, msOnGetProductFields
 */

switch ($modx->event->name) {

    case 'msOnGetProductPrice':
        $price = $modx->eventData['msOnGetProductPrice']['price']
            ?? $scriptProperties['price'];
        $data = $scriptProperties['data'];

        $discounts = [];

        $categoryDiscounts = [
            5 => 10,
            10 => 15,
        ];
        if (isset($categoryDiscounts[$data['parent']])) {
            $discount = $categoryDiscounts[$data['parent']];
            $price = $price * (1 - $discount / 100);
            $discounts['category'] = $discount;
        }

        if ($modx->user->isAuthenticated()) {
            $price = $price * 0.95;
            $discounts['member'] = 5;
        }

        if ($modx->user->isMember('VIP')) {
            $price = $price * 0.9;
            $discounts['vip'] = 10;
        }

        $modx->eventData['discounts'] = $discounts;
        $modx->eventData['msOnGetProductPrice']['price'] = $price;

        $values = &$modx->event->returnedValues;
        $values['price'] = round($price, 2);
        break;

    case 'msOnGetProductFields':
        $data = $modx->eventData['msOnGetProductFields']['data']
            ?? $scriptProperties['data'];

        $discounts = $modx->eventData['discounts'] ?? [];
        if (!empty($discounts)) {
            $data['applied_discounts'] = $discounts;
            $data['total_discount'] = array_sum($discounts);
        }

        $badges = [];
        if ($data['new']) {
            $badges[] = ['type' => 'new', 'text' => 'New'];
        }
        if ($data['popular']) {
            $badges[] = ['type' => 'popular', 'text' => 'Bestseller'];
        }
        if (!empty($data['total_discount'])) {
            $badges[] = [
                'type' => 'sale',
                'text' => '-' . $data['total_discount'] . '%',
            ];
        }
        $data['badges'] = $badges;

        $modx->eventData['msOnGetProductFields']['data'] = $data;
        $values = &$modx->event->returnedValues;
        $values['data'] = $data;
        break;
}