AuthChoice.php 7.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\authclient\widgets;

use yii\base\Widget;
use Yii;
12
use yii\helpers\Url;
13
use yii\helpers\Html;
14
use yii\authclient\ClientInterface;
15 16

/**
17
 * AuthChoice prints buttons for authentication via various auth clients.
18
 * It opens a popup window for the client authentication process.
19 20 21 22
 * By default this widget relies on presence of [[\yii\authclient\Collection]] among application components
 * to get auth clients information.
 *
 * Example:
Qiang Xue committed
23 24
 *
 * ~~~php
25
 * <?= yii\authclient\widgets\AuthChoice::widget([
26 27 28 29
 *     'baseAuthUrl' => ['site/auth']
 * ]); ?>
 * ~~~
 *
30
 * You can customize the widget appearance by using [[begin()]] and [[end()]] syntax
31 32 33
 * along with using method {@link clientLink()} or {@link createClientUrl()}.
 * For example:
 *
Qiang Xue committed
34
 * ~~~php
35
 * <?php
36
 * use yii\authclient\widgets\AuthChoice;
37
 * ?>
38
 * <?php $authAuthChoice = AuthChoice::begin([
39 40
 *     'baseAuthUrl' => ['site/auth']
 * ]); ?>
41
 * <ul>
42 43
 * <?php foreach ($authAuthChoice->getClients() as $client): ?>
 *     <li><?= $authAuthChoice->clientLink($client) ?></li>
44 45
 * <?php endforeach; ?>
 * </ul>
46
 * <?php AuthChoice::end(); ?>
47
 * ~~~
48
 *
49 50 51 52
 * This widget supports following keys for [[ClientInterface::getViewOptions()]] result:
 *  - popupWidth - integer width of the popup window in pixels.
 *  - popupHeight - integer height of the popup window in pixels.
 *
53 54
 * @see \yii\authclient\AuthAction
 *
Qiang Xue committed
55 56
 * @property array $baseAuthUrl Base auth URL configuration. This property is read-only.
 * @property ClientInterface[] $clients Auth providers. This property is read-only.
57
 *
58 59 60
 * @author Paul Klimov <klimov.paul@gmail.com>
 * @since 2.0
 */
61
class AuthChoice extends Widget
62
{
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    /**
     * @var string name of the auth client collection application component.
     * This component will be used to fetch services value if it is not set.
     */
    public $clientCollection = 'authClientCollection';
    /**
     * @var string name of the GET param , which should be used to passed auth client id to URL
     * defined by [[baseAuthUrl]].
     */
    public $clientIdGetParamName = 'authclient';
    /**
     * @var array the HTML attributes that should be rendered in the div HTML tag representing the container element.
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = [
        'class' => 'auth-clients'
    ];
    /**
     * @var boolean indicates if popup window should be used instead of direct links.
     */
    public $popupMode = true;
    /**
     * @var boolean indicates if widget content, should be rendered automatically.
86
     * Note: this value automatically set to 'false' at the first call of [[createClientUrl()]]
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
     */
    public $autoRender = true;

    /**
     * @var array configuration for the external clients base authentication URL.
     */
    private $_baseAuthUrl;
    /**
     * @var ClientInterface[] auth providers list.
     */
    private $_clients;

    /**
     * @param ClientInterface[] $clients auth providers
     */
    public function setClients(array $clients)
    {
        $this->_clients = $clients;
    }

    /**
     * @return ClientInterface[] auth providers
     */
    public function getClients()
    {
        if ($this->_clients === null) {
            $this->_clients = $this->defaultClients();
        }

        return $this->_clients;
    }

    /**
     * @param array $baseAuthUrl base auth URL configuration.
     */
    public function setBaseAuthUrl(array $baseAuthUrl)
    {
        $this->_baseAuthUrl = $baseAuthUrl;
    }

    /**
     * @return array base auth URL configuration.
     */
    public function getBaseAuthUrl()
    {
        if (!is_array($this->_baseAuthUrl)) {
            $this->_baseAuthUrl = $this->defaultBaseAuthUrl();
        }

        return $this->_baseAuthUrl;
    }

    /**
     * Returns default auth clients list.
     * @return ClientInterface[] auth clients list.
     */
    protected function defaultClients()
    {
        /** @var $collection \yii\authclient\Collection */
146
        $collection = Yii::$app->get($this->clientCollection);
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

        return $collection->getClients();
    }

    /**
     * Composes default base auth URL configuration.
     * @return array base auth URL configuration.
     */
    protected function defaultBaseAuthUrl()
    {
        $baseAuthUrl = [
            Yii::$app->controller->getRoute()
        ];
        $params = $_GET;
        unset($params[$this->clientIdGetParamName]);
        $baseAuthUrl = array_merge($baseAuthUrl, $params);

        return $baseAuthUrl;
    }

    /**
     * Outputs client auth link.
169 170 171
     * @param ClientInterface $client external auth client instance.
     * @param string $text link text, if not set - default value will be generated.
     * @param array $htmlOptions link HTML options.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
     */
    public function clientLink($client, $text = null, array $htmlOptions = [])
    {
        if ($text === null) {
            $text = Html::tag('span', '', ['class' => 'auth-icon ' . $client->getName()]);
            $text .= Html::tag('span', $client->getTitle(), ['class' => 'auth-title']);
        }
        if (!array_key_exists('class', $htmlOptions)) {
            $htmlOptions['class'] = 'auth-link ' . $client->getName();
        }
        if ($this->popupMode) {
            $viewOptions = $client->getViewOptions();
            if (isset($viewOptions['popupWidth'])) {
                $htmlOptions['data-popup-width'] = $viewOptions['popupWidth'];
            }
            if (isset($viewOptions['popupHeight'])) {
                $htmlOptions['data-popup-height'] = $viewOptions['popupHeight'];
            }
        }
        echo Html::a($text, $this->createClientUrl($client), $htmlOptions);
    }

    /**
     * Composes client auth URL.
196 197
     * @param ClientInterface $provider external auth client instance.
     * @return string auth URL.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
     */
    public function createClientUrl($provider)
    {
        $this->autoRender = false;
        $url = $this->getBaseAuthUrl();
        $url[$this->clientIdGetParamName] = $provider->getId();

        return Url::to($url);
    }

    /**
     * Renders the main content, which includes all external services links.
     */
    protected function renderMainContent()
    {
        echo Html::beginTag('ul', ['class' => 'auth-clients clear']);
        foreach ($this->getClients() as $externalService) {
            echo Html::beginTag('li', ['class' => 'auth-client']);
            $this->clientLink($externalService);
            echo Html::endTag('li');
        }
        echo Html::endTag('ul');
    }

    /**
     * Initializes the widget.
     */
    public function init()
    {
        if ($this->popupMode) {
            $view = Yii::$app->getView();
229
            AuthChoiceAsset::register($view);
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
            $view->registerJs("\$('#" . $this->getId() . "').authchoice();");
        }
        $this->options['id'] = $this->getId();
        echo Html::beginTag('div', $this->options);
    }

    /**
     * Runs the widget.
     */
    public function run()
    {
        if ($this->autoRender) {
            $this->renderMainContent();
        }
        echo Html::endTag('div');
    }
Qiang Xue committed
246
}