Passed
Push — master ( 8f49c3...a13c2d )
by Matt
07:30
created

SaasLinkField::getElementValidationRules()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 0
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * SaaS Link plugin for Craft CMS 3.x
4
 *
5
 * @link      https://workingconcept.com
6
 * @copyright Copyright (c) 2018 Working Concept Inc.
7
 */
8
9
namespace workingconcept\saaslink\fields;
10
11
use workingconcept\saaslink\SaasLink;
12
use Craft;
13
use craft\fields\data\SingleOptionFieldData;
14
use craft\fields\BaseOptionsField;
15
use craft\base\ElementInterface;
16
use yii\db\Schema;
17
18
class SaasLinkField extends BaseOptionsField
19
{
20
    // Public Properties
21
    // =========================================================================
22
23
    public $service;
24
    public $relationshipType;
25
26
    private $defaultService;
27
28
29
    // Static Methods
30
    // =========================================================================
31
32
    /**
33
     * @inheritdoc
34
     */
35
    public static function displayName(): string
36
    {
37
        return Craft::t('saas-link', 'SaaS Link');
38
    }
39
40
41
    // Public Methods
42
    // =========================================================================
43
44
    /**
45
     * @inheritdoc
46
     */
47
    public function rules(): array
48
    {
49
        return [
50
            [['service', 'relationshipType'], 'string'],
51
            [['service', 'relationshipType'], 'required'],
52
        ];
53
    }
54
55
    /**
56
     * @inheritdoc
57
     */
58
    public function getContentColumnType(): string
59
    {
60
        return Schema::TYPE_STRING;
61
    }
62
63
    /**
64
     * @return array
65
     */
66
    public function getAvailableServices(): array
67
    {
68
        $options = [];
69
70
        foreach (SaasLink::$plugin->getEnabledServices() as $service)
71
        {
72
            $options[] = [
73
                'label' => $service->serviceName,
74
                'value' => $service->serviceSlug
75
            ];
76
        }
77
78
        return $options;
79
    }
80
81
    /**
82
     * @return array
83
     */
84
    public function getAvailableRelationshipTypes(): array
85
    {
86
        if ($serviceInstance = $this->getServiceInstance())
87
        {
88
            return $serviceInstance->getAvailableRelationshipTypes();
89
        }
90
91
        // pass the first set of options if this is a new field without a Service
92
        if (isset($this->defaultService))
93
        {
94
            return $this->defaultService->getAvailableRelationshipTypes();
95
        }
96
97
        return [];
98
    }
99
100
    /**
101
     * Get options from the relevant service based on field settings.
102
     * @return array
103
     */
104
    public function getOptions(): array
105
    {
106
        if (empty($this->options))
107
        {
108
            if ($serviceInstance = $this->getServiceInstance())
109
            {
110
                $this->options = $serviceInstance->getOptions($this->relationshipType);
111
            }
112
        }
113
114
        return $this->options;
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function getElementValidationRules(): array
121
    {
122
        // Get all of the acceptable values
123
        $range = [];
124
125
        if ($options = $this->getOptions()) {
126
            foreach ($options as $option) {
127
                $range[] = $option['value'];
128
            }
129
        }
130
131
        return [
132
            ['in', 'range' => $range, 'allowArray' => false],
133
        ];
134
    }
135
136
137
    /**
138
     * @inheritdoc
139
     */
140
    public function getInputHtml($value, ElementInterface $element = null): string
141
    {
142
        // If this is a new entry, look for a default option
143
        if ($this->isFresh($element))
144
        {
145
            $value = $this->defaultValue();
146
        }
147
148
        $options = $this->getOptions();
149
150
        // add an empty first item
151
        array_unshift($options, [
152
                'label'   => '',
153
                'value'   => '',
154
                'link'    => null,
155
                'default' => null,
156
            ]
157
        );
158
159
        return Craft::$app->getView()->renderTemplate('saas-link/select',
160
            [
161
                'name'       => $this->handle,
162
                'value'      => $value,
163
                'optionLink' => $this->getLinkFromValue($value),
164
                'options'    => $options,
165
            ]
166
        );
167
    }
168
169
    /**
170
     * Get a convenient URL for the selected record to show next to the selection.
171
     *
172
     * @param mixed $value Stored field value.
173
     *
174
     * @return string|null
175
     */
176
    public function getLinkFromValue($value)
177
    {
178
        if ( ! empty($value))
179
        {
180
            $compareValue = $value->value ?? $value;
181
182
            foreach	($this->getOptions() as $option)
183
            {
184
                if ($option['value'] === $compareValue)
185
                {
186
                    return $option['link'];
187
                }
188
            }
189
        }
190
191
        return null;
192
    }
193
194
    /**
195
     * @inheritdoc
196
     */
197
    public function normalizeValue($value, ElementInterface $element = null)
198
    {
199
        if (!$value)
200
        {
201
            $value = $this->defaultValue();
202
        }
203
204
        // Normalize to an array
205
        $selectedValues = (array)$value;
206
        $value = reset($selectedValues) ?: null;
207
        $label = $this->optionLabel($value);
208
        $value = new SingleOptionFieldData($label, $value, true);
209
210
        return $value;
211
    }
212
213
    public function getSettingsHtml()
214
    {
215
        return Craft::$app->getView()->renderTemplate('saas-link/field-settings', [
216
            'settings' => SaasLink::$plugin->getSettings(),
217
            'field' => $this
218
        ]);
219
    }
220
221
222
    // Private Methods
223
    // =========================================================================
224
225
    private function getServiceInstance()
226
    {
227
        foreach (SaasLink::$plugin->getEnabledServices() as $service)
228
        {
229
            if ( ! isset($this->defaultService))
230
            {
231
                // default to the first one in case we don't get a match (new field)
232
                $this->defaultService = $service;
233
            }
234
235
            if ($this->service === $service->serviceSlug)
236
            {
237
                return $service;
238
            }
239
        }
240
    }
241
242
    // Protected Methods
243
    // =========================================================================
244
245
    /**
246
     * @inheritdoc
247
     */
248
    protected function optionsSettingLabel(): string
249
    {
250
        return Craft::t('saas-link', 'SaaS Link');
251
    }
252
253
}
254