Skip to content

Commit

Permalink
Add user condition for matching by user attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
MrRonbot committed Aug 25, 2022
1 parent cea9eff commit eaf5680
Show file tree
Hide file tree
Showing 10 changed files with 108 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

## 4.0.5 - 2022-08-26
### Added
- Add user condition for matching by user attributes

## 4.0.4 - 2022-05-26
### Added
- Optimise querying product labels for products
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "thepixelage/craft-productlabels",
"description": "Product Labels is a Craft Commerce plugin for creating labels for products",
"type": "craft-plugin",
"version": "4.0.4",
"version": "4.0.5",
"keywords": [
"craft",
"cms",
Expand Down
2 changes: 1 addition & 1 deletion src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Plugin extends \craft\base\Plugin
{
public static Plugin $plugin;

public string $schemaVersion = '1.0.0';
public string $schemaVersion = '1.0.1';

/**
* @throws Exception
Expand Down
8 changes: 6 additions & 2 deletions src/behaviors/ProductBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace thepixelage\productlabels\behaviors;

use craft\commerce\elements\Product;
use thepixelage\productlabels\elements\ProductLabel;
use thepixelage\productlabels\Plugin;
use yii\base\Behavior;
Expand All @@ -10,10 +11,13 @@ class ProductBehavior extends Behavior
{
public function getProductLabels(): array
{
/** @var Product $product */
$product = $this->owner;
$productLabels = Plugin::getInstance()->productLabels->getAllProductLabels();

return array_filter($productLabels, function (ProductLabel $productLabel) {
return in_array($this->owner->id, $productLabel->getMatchedProductIds());
return array_filter($productLabels, function (ProductLabel $productLabel) use ($product) {
return in_array($product->id, $productLabel->getMatchedProductIds()) &&
$productLabel->getMatchCurrentUser();
});
}
}
1 change: 1 addition & 0 deletions src/controllers/ProductLabelsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ public function actionSave(): ?Response
$productLabel->setFieldValuesFromRequest($this->request->getParam('fieldsLocation', 'fields'));

$productLabel->setProductCondition($this->request->getBodyParam('productCondition'));
$productLabel->setUserCondition($this->request->getBodyParam('userCondition'));

$dateFromParams = $this->request->getBodyParam('dateFrom');
$dateToParams = $this->request->getBodyParam('dateTo');
Expand Down
40 changes: 40 additions & 0 deletions src/elements/ProductLabel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use craft\elements\actions\Restore;
use craft\elements\actions\SetStatus;
use craft\elements\conditions\ElementConditionInterface;
use craft\elements\conditions\users\UserCondition;
use craft\elements\db\ElementQuery;
use craft\elements\db\ElementQueryInterface;
use craft\elements\User;
Expand All @@ -36,7 +37,9 @@ class ProductLabel extends Element
public ?DateTime $dateFrom = null;
public ?DateTime $dateTo = null;
private ElementConditionInterface|null $_productCondition = null;
private ElementConditionInterface|null $_userCondition = null;
private array $matchedProductIds = [];
private bool $matchCurrentUser = false;

public function __construct($config = [])
{
Expand Down Expand Up @@ -100,6 +103,31 @@ public function setProductCondition(ElementConditionInterface|string|array|null
$this->_productCondition = $condition;
}

public function getUserCondition(): ElementConditionInterface
{
$condition = $this->_userCondition ?? new UserCondition();
$condition->mainTag = 'div';
$condition->name = 'userCondition';

return $condition;
}

/**
* @throws InvalidConfigException
*/
public function setUserCondition(ElementConditionInterface|string|array|null $condition): void
{
if (is_string($condition)) {
$condition = Json::decodeIfJson($condition);
}

$condition['class'] = UserCondition::class;
$condition = Craft::$app->getConditions()->createCondition($condition);
$condition->forProjectConfig = false;

$this->_userCondition = $condition;
}

public function getMatchedProductIds(): array
{
return $this->matchedProductIds;
Expand All @@ -110,6 +138,16 @@ public function setMatchedProductIds($ids)
$this->matchedProductIds = $ids;
}

public function getMatchCurrentUser(): bool
{
return $this->matchCurrentUser;
}

public function setMatchCurrentUser($match)
{
$this->matchCurrentUser = $match;
}

public static function find(): ElementQueryInterface
{
return new ProductLabelQuery(static::class);
Expand Down Expand Up @@ -287,6 +325,7 @@ public function afterSave(bool $isNew): void
->insert('{{%productlabels}}', [
'id' => $this->id,
'productCondition' => Json::encode($this->getProductCondition()->getConfig()),
'userCondition' => Json::encode($this->getUserCondition()->getConfig()),
'dateFrom' => $this->dateFrom ? $this->dateFrom->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s') : null,
'dateTo' => $this->dateTo ? $this->dateTo->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s') : null,
])
Expand All @@ -295,6 +334,7 @@ public function afterSave(bool $isNew): void
Craft::$app->db->createCommand()
->update('{{%productlabels}}', [
'productCondition' => Json::encode($this->getProductCondition()->getConfig()),
'userCondition' => Json::encode($this->getUserCondition()->getConfig()),
'dateFrom' => $this->dateFrom ? $this->dateFrom->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s') : null,
'dateTo' => $this->dateTo ? $this->dateTo->setTimezone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s') : null,
], ['id' => $this->id])
Expand Down
1 change: 1 addition & 0 deletions src/elements/db/ProductLabelQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ protected function beforePrepare(): bool
$this->joinElementTable($productLabelsTableName);
$this->query->select([
sprintf('%s.productCondition', $productLabelsTableName),
sprintf('%s.userCondition', $productLabelsTableName),
sprintf('%s.dateFrom', $productLabelsTableName),
sprintf('%s.dateTo', $productLabelsTableName),
]);
Expand Down
35 changes: 35 additions & 0 deletions src/migrations/m220825_081136_add_user_condition_column.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace thepixelage\productlabels\migrations;

use Craft;
use craft\db\Migration;
use thepixelage\productlabels\db\Table;

/**
* m220825_081136_add_user_condition_column migration.
*/
class m220825_081136_add_user_condition_column extends Migration
{
/**
* @inheritdoc
*/
public function safeUp(): bool
{
$this->addColumn(Table::PRODUCTLABELS,
'userCondition',
$this->text()->after('productCondition'));

return true;
}

/**
* @inheritdoc
*/
public function safeDown(): bool
{
$this->dropColumn(Table::PRODUCTLABELS, 'userCondition');

return false;
}
}
10 changes: 9 additions & 1 deletion src/services/ProductLabels.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use craft\base\Component;
use craft\base\MemoizableArray;
use craft\commerce\elements\Product;
use craft\elements\User;
use craft\errors\BusyResourceException;
use craft\errors\StaleResourceException;
use craft\errors\StructureNotFoundException;
Expand Down Expand Up @@ -180,17 +181,24 @@ private function _productLabels(): MemoizableArray
{
if (!isset($this->_productLabels)) {
$productLabels = ProductLabel::find()->all();
$currentUser = Craft::$app->user->id ? User::find()->id(Craft::$app->user->id)->one() : null;

/** @var ProductLabel $productLabel */
foreach ($productLabels as $productLabel) {
$productCondition = $productLabel->getProductCondition();
if (count($productCondition->getConditionRules()) > 0) {
foreach ($productCondition->getConditionRules() as $rule) {
$query = Product::find();
$productCondition->modifyQuery($query);

$productLabel->setMatchedProductIds($query->ids());
}
}

$userCondition = $productLabel->getUserCondition();
$productLabel->setMatchCurrentUser(
$userCondition->conditionRules == 0 ||
($currentUser && $userCondition->matchElement($currentUser))
);
}

$this->_productLabels = new MemoizableArray(array_values($productLabels));
Expand Down
10 changes: 10 additions & 0 deletions src/templates/productlabels/_edit.twig
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,22 @@
{{ productLabel.productCondition.getBuilderHtml()|raw }}
{% endset %}

{% set userConditionInput %}
{{ productLabel.userCondition.getBuilderHtml()|raw }}
{% endset %}

{{ forms.field({
label: 'Match Product'|t('commerce'),
instructions: 'Create rules that allow this product label to match the product. If no rules are added, this product label will match all products.'|t('productlabels'),
errors: productLabel.getErrors('productCondition')
}, productConditionInput) }}

{{ forms.field({
label: 'Match User'|t('commerce'),
instructions: 'Create rules that allow this product label to match the user. If no rules are added, this product label will match all users.'|t('productlabels'),
errors: productLabel.getErrors('userCondition')
}, userConditionInput) }}

</div>
</div>
{% endblock %}
Expand Down

0 comments on commit eaf5680

Please sign in to comment.