Completed
Push — master ( a20c7b...d885ca )
by Nate
02:36
created

DissociateFromElementAction::getTriggerLabel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-element-lists/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-element-lists/
7
 */
8
9
namespace flipbox\craft\element\lists\elements\actions;
10
11
use Craft;
12
use craft\base\ElementAction;
13
use craft\base\Field;
14
use craft\base\FieldInterface;
15
use craft\elements\db\ElementQueryInterface;
16
use craft\elements\db\UserQuery;
17
use craft\helpers\ArrayHelper;
18
use flipbox\craft\element\lists\ElementList;
19
use flipbox\craft\element\lists\records\Association;
20
use yii\base\Exception;
21
22
/**
23
 * @author Flipbox Factory <[email protected]>
24
 * @since 1.0.0
25
 */
26
class DissociateFromElementAction extends ElementAction
27
{
28
    /**
29
     * @var string|int
30
     */
31
    public $sourceId;
32
33
    /**
34
     * @var string|int
35
     */
36
    public $fieldId;
37
38
    /**
39
     * @return array
40
     */
41
    public function settingsAttributes(): array
42
    {
43
        return array_merge(
44
            parent::settingsAttributes(),
45
            [
46
                'sourceId',
47
                'fieldId'
48
            ]
49
        );
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55
    public static function isDestructive(): bool
56
    {
57
        return true;
58
    }
59
60
    /**
61
     * @inheritdoc
62
     */
63
    public function getTriggerLabel(): string
64
    {
65
        return ElementList::t('Remove');
66
    }
67
68
    /**
69
     * @inheritdoc
70
     * @throws \Throwable
71
     * @throws \craft\errors\SiteNotFoundException
72
     * @throws \yii\db\StaleObjectException
73
     */
74
    public function performAction(ElementQueryInterface $query): bool
75
    {
76
        /** @var Field $field */
77
        if (null === ($field = Craft::$app->getFields()->getFieldById($this->fieldId))) {
78
            throw new Exception(sprintf(
79
                "Field %s must be an instance of '%s'",
80
                (string)$this->fieldId,
81
                (string)FieldInterface::class
82
            ));
83
        }
84
85
        if (null === ($source = Craft::$app->getElements()->getElementById($this->sourceId))) {
86
            throw new Exception("Element does not exist with the identifier '{$this->sourceId}'");
87
        }
88
89
        $siteId = Craft::$app->getSites()->getCurrentSite()->id;
90
91
        // Get the count because it's cleared when dissociated
92
        $count = $query->count();
93
94
        foreach ($query->all() as $target) {
95
            if (!$record = Association::find()
96
                ->fieldId($field->id)
97
                ->sourceId($source->getId())
98
                ->targetId($target->getId())
99
                ->siteId($siteId)
100
                ->one()
101
            ) {
102
                continue;
103
            }
104
105
            if (!$record->delete()) {
106
                $this->setMessage(
107
                    $this->assembleFailMessage($query)
108
                );
109
            }
110
        }
111
112
        $this->setMessage($this->assembleSuccessMessage($count));
113
        return true;
114
    }
115
116
    /**
117
     * @param ElementQueryInterface|UserQuery $query
118
     * @return string
119
     */
120
    private function assembleFailMessage(ElementQueryInterface $query): string
121
    {
122
        $message = 'Failed to remove element: ';
123
124
        $users = $query->all();
125
        $badEmails = ArrayHelper::index($users, 'id');
126
127
        $message .= implode(", ", $badEmails);
128
129
        return ElementList::t($message);
130
    }
131
132
    /**
133
     * @param int $count
134
     * @return string
135
     */
136
    private function assembleSuccessMessage(int $count): string
137
    {
138
        $message = 'Element';
139
140
        if ($count != 1) {
141
            $message = '{count} ' . $message . 's';
142
        }
143
144
        $message .= ' dissociated.';
145
146
        return ElementList::t($message, ['count' => $count]);
147
    }
148
}
149