Completed
Pull Request — master (#17)
by Vladimir
04:09
created

SocialShare::getLinkList()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
/**
3
 * @link https://github.com/yiimaker/yii2-social-share
4
 * @copyright Copyright (c) 2017-2018 Yii Maker
5
 * @license BSD 3-Clause License
6
 */
7
8
namespace ymaker\social\share\widgets;
9
10
use Yii;
11
use yii\base\Widget;
12
use yii\di\Instance;
13
use yii\helpers\ArrayHelper;
14
use yii\helpers\Html;
15
use yii\helpers\Inflector;
16
use yii\helpers\Url;
17
use ymaker\social\share\assets\SocialIconsAsset;
18
use ymaker\social\share\configurators\Configurator;
19
use ymaker\social\share\configurators\ConfiguratorInterface;
20
use ymaker\social\share\configurators\IconsConfigInterface;
21
22
/**
23
 * Widget for rendering the share links.
24
 *
25
 * @author Vladimir Kuprienko <[email protected]>
26
 * @since 1.0
27
 */
28
class SocialShare extends Widget
29
{
30
    /**
31
     * @var array|ConfiguratorInterface|IconsConfigInterface|string
32
     */
33
    public $configurator;
34
    /**
35
     * Absolute URL to the page.
36
     *
37
     * @var string
38
     */
39
    public $url = '';
40
    /**
41
     * Title for share.
42
     *
43
     * @var string
44
     */
45
    public $title = '';
46
    /**
47
     * Description for share.
48
     *
49
     * @var string
50
     */
51
    public $description = '';
52
    /**
53
     * Absolute URL to the image for share.
54
     *
55
     * @var string
56
     */
57
    public $imageUrl = '';
58
    /**
59
     * Special properties for specific driver.
60
     *
61
     * @var array
62
     *
63
     * @since 1.4.0
64
     */
65
    public $driverProperties = [];
66
    /**
67
     * HTML options for links container tag.
68
     * If you won't to use it - set `tag` option to `false`.
69
     *
70
     * @var array
71
     */
72
    public $containerOptions = ['tag' => 'ul', 'class' => 'social-share'];
73
    /**
74
     * HTML options for link container tag.
75
     * If you won't to use it - set `tag` option to `false`.
76
     *
77
     * @var array
78
     */
79
    public $linkContainerOptions = ['tag' => 'li'];
80
81
82
    /**
83
     * Initialize the widget: gets configurator instance,
84
     * sets [[url]] property if empty. Triggers [[EVENT_INIT]] event after initialization.
85
     *
86
     * @throws \yii\base\InvalidConfigException
87
     */
88
    public function init()
89
    {
90
        $this->configurator = Instance::ensure($this->configurator, ConfiguratorInterface::class);
91
92
        if (empty($this->url)) {
93
            $this->url = Url::to('', true);
94
        }
95
96
        parent::init();
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function run()
103
    {
104
        if ($this->isDefaultIconsAssetEnabled()) {
105
            $this->getView()->registerAssetBundle(SocialIconsAsset::class);
106
        }
107
108
        if ($this->isSeoEnabled()) {
109
            echo '<!--noindex-->';
110
        }
111
112
        $containerTag = ArrayHelper::remove($this->containerOptions, 'tag', false);
113
114
        if ($containerTag) {
115
            echo Html::beginTag($containerTag, $this->containerOptions);
116
        }
117
118
        $wrapTag = ArrayHelper::remove($this->linkContainerOptions, 'tag', false);
119
120
        foreach ($this->getLinkList() as $link) {
121
            echo $wrapTag ? Html::tag($wrapTag, $link, $this->linkContainerOptions) : $link;
122
        }
123
124
        if ($containerTag) {
125
            echo Html::endTag($containerTag);
126
        }
127
128
        if ($this->isSeoEnabled()) {
129
            echo '<!--/noindex-->';
130
        }
131
    }
132
133
    /**
134
     * @return bool
135
     */
136
    final protected function isDefaultIconsAssetEnabled()
137
    {
138
        return $this->configurator instanceof IconsConfigInterface &&
139
            $this->configurator->isDefaultAssetEnabled();
140
    }
141
142
    /**
143
     * @return bool
144
     */
145
    final protected function isIconsEnabled()
146
    {
147
        return $this->configurator instanceof IconsConfigInterface &&
148
            $this->configurator->isIconsEnabled();
149
    }
150
151
    /**
152
     * @return bool
153
     *
154
     * @since 1.4.1
155
     */
156
    final protected function isSeoEnabled()
157
    {
158
        return $this->configurator instanceof Configurator &&
159
            $this->configurator->enableSeoOptions;
160
    }
161
162
    /**
163
     * @return bool
164
     *
165
     * @since 2.1
166
     */
167
    final protected function registerMetaTags()
168
    {
169
        return $this->configurator instanceof Configurator &&
170
            $this->configurator->registerMetaTags;
171
    }
172
173
    /**
174
     * Build label for driver.
175
     *
176
     * @param array     $driverConfig
177
     * @param string    $defaultLabel
178
     *
179
     * @return string
180
     */
181
    protected function getLinkLabel($driverConfig, $defaultLabel)
182
    {
183
        return $this->isIconsEnabled()
184
            ? Html::tag('i', '', ['class' => $this->configurator->getIconSelector($driverConfig['class'])])
185
            : (isset($driverConfig['label']) ? $driverConfig['label'] : $defaultLabel);
186
    }
187
188
    /**
189
     * Creates driver instance.
190
     *
191
     * @param array $config Configuration for driver.
192
     *
193
     * @return \ymaker\social\share\base\AbstractDriver
194
     *
195
     * @throws \yii\base\InvalidConfigException
196
     */
197
    private function createDriver($config)
198
    {
199
        $fullConfig = ArrayHelper::merge(
200
            [
201
                'class' => $config['class'],
202
                'url' => $this->url,
203
                'title' => $this->title,
204
                'description' => $this->description,
205
                'imageUrl' => $this->imageUrl,
206
                'registerMetaTags' => $this->registerMetaTags(),
207
            ],
208
            isset($config['config']) ? $config['config'] : [],
209
            isset($this->driverProperties[$config['class']]) ? $this->driverProperties[$config['class']] : []
210
        );
211
212
        return Yii::createObject($fullConfig);
213
    }
214
215
    /**
216
     * Combine global and custom HTML options.
217
     *
218
     * @param array $driverConfig
219
     *
220
     * @return array
221
     */
222
    private function combineOptions($driverConfig)
223
    {
224
        $options = isset($driverConfig['options']) ? $driverConfig['options'] : [];
225
226
        $globalOptions = $this->configurator->getOptions();
0 ignored issues
show
Bug introduced by
The method getOptions() does not exist on ymaker\social\share\conf...rs\IconsConfigInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to ymaker\social\share\conf...rs\IconsConfigInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

226
        /** @scrutinizer ignore-call */ 
227
        $globalOptions = $this->configurator->getOptions();
Loading history...
227
228
        if (empty($globalOptions)) {
229
            return $options;
230
        }
231
232
        if (isset($options['class'])) {
233
            Html::addCssClass($globalOptions, $options['class']);
234
            unset($options['class']);
235
        }
236
237
        return ArrayHelper::merge($globalOptions, $options);
238
    }
239
240
    /**
241
     * Returns array with share links in <a> HTML tag.
242
     *
243
     * @return array
244
     *
245
     * @throws \yii\base\InvalidConfigException
246
     */
247
    private function getLinkList()
248
    {
249
        $linkList = [];
250
251
        foreach ($this->configurator->getSocialNetworks() as $key => $socialNetwork) {
0 ignored issues
show
Bug introduced by
The method getSocialNetworks() does not exist on ymaker\social\share\conf...rs\IconsConfigInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to ymaker\social\share\conf...rs\IconsConfigInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

251
        foreach ($this->configurator->/** @scrutinizer ignore-call */ getSocialNetworks() as $key => $socialNetwork) {
Loading history...
252
            if (isset($socialNetwork['class'])) {
253
                $linkOptions = $this->combineOptions($socialNetwork);
254
                $linkOptions['href'] = $this->createDriver($socialNetwork)->getLink();
255
                $linkList[] = Html::tag('a', $this->getLinkLabel($socialNetwork, Inflector::camel2words($key)), $linkOptions);
256
            }
257
        }
258
259
        return $linkList;
260
    }
261
}
262