assembleSuccessMessage()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 9
cp 0
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
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\Element;
13
use craft\base\ElementAction;
14
use craft\base\FieldInterface;
15
use craft\elements\db\ElementQuery;
16
use craft\elements\db\ElementQueryInterface;
17
use craft\elements\db\UserQuery;
18
use craft\fields\BaseRelationField;
19
use craft\helpers\ArrayHelper;
20
use flipbox\craft\element\lists\ElementList;
21
use flipbox\craft\element\lists\records\Association;
22
use yii\base\Exception;
23
24
/**
25
 * @author Flipbox Factory <[email protected]>
26
 * @since 1.0.0
27
 */
28
class DissociateFromElementAction extends ElementAction
29
{
30
    /**
31
     * @var string|int
32
     */
33
    public $sourceId;
34
35
    /**
36
     * @var string|int
37
     */
38
    public $fieldId;
39
40
    /**
41
     * @return array
42
     */
43
    public function settingsAttributes(): array
44
    {
45
        return array_merge(
46
            parent::settingsAttributes(),
47
            [
48
                'sourceId',
49
                'fieldId'
50
            ]
51
        );
52
    }
53
54
    /**
55
     * @inheritdoc
56
     */
57
    public static function isDestructive(): bool
58
    {
59
        return true;
60
    }
61
62
    /**
63
     * @inheritdoc
64
     */
65
    public function getTriggerLabel(): string
66
    {
67
        return ElementList::t('Remove');
68
    }
69
70
    /**
71
     * @inheritdoc
72
     * @throws \Throwable
73
     * @throws \yii\db\StaleObjectException
74
     */
75
    public function performAction(ElementQueryInterface $query): bool
76
    {
77
        /** @var ElementQuery $query */
78
79
        /** @var BaseRelationField $field */
80
        if (null === ($field = Craft::$app->getFields()->getFieldById($this->fieldId))) {
81
            throw new Exception(sprintf(
82
                "Field %s must be an instance of '%s'",
83
                (string)$this->fieldId,
84
                (string)FieldInterface::class
85
            ));
86
        }
87
88
        if (null === ($source = Craft::$app->getElements()->getElementById($this->sourceId))) {
89
            throw new Exception("Element does not exist with the identifier '{$this->sourceId}'");
90
        }
91
92
        $siteId = $query->siteId;
0 ignored issues
show
Bug introduced by
Accessing siteId on the interface craft\elements\db\ElementQueryInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
93
94
        /** @var Element $source */
95
96
        // Get the count because it's cleared when dissociated
97
        $targets = $query->all();
98
        $count = count($targets);
99
100
        foreach ($targets as $target) {
101
            $associationQuery = Association::find()
102
                ->fieldId($field->id)
103
                ->sourceId($source->getId())
104
                ->targetId($target->getId());
105
106
            if ($field->localizeRelations) {
107
                $associationQuery->sourceSiteId($siteId);
108
            }
109
110
            if (!$record = $associationQuery->one()) {
111
                continue;
112
            }
113
114
            if (!$record->delete()) {
115
                $this->setMessage(
116
                    $this->assembleFailMessage($query)
117
                );
118
            }
119
        }
120
121
        $this->setMessage($this->assembleSuccessMessage($count));
122
        return true;
123
    }
124
125
    /**
126
     * @param ElementQueryInterface|UserQuery $query
127
     * @return string
128
     */
129
    private function assembleFailMessage(ElementQueryInterface $query): string
130
    {
131
        $message = 'Failed to remove element: ';
132
133
        $users = $query->all();
134
        $badEmails = ArrayHelper::index($users, 'id');
135
136
        $message .= implode(", ", $badEmails);
137
138
        return ElementList::t($message);
139
    }
140
141
    /**
142
     * @param int $count
143
     * @return string
144
     */
145
    private function assembleSuccessMessage(int $count): string
146
    {
147
        $message = 'Element';
148
149
        if ($count != 1) {
150
            $message = '{count} ' . $message . 's';
151
        }
152
153
        $message .= ' dissociated.';
154
155
        return ElementList::t($message, ['count' => $count]);
156
    }
157
}
158