Choice.php 6.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
<?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;
use yii\helpers\Html;
13
use yii\authclient\ClientInterface;
14 15

/**
16
 * Choice prints buttons for authentication via various auth clients.
17
 * It opens a popup window for the client authentication process.
18 19 20 21
 * By default this widget relies on presence of [[\yii\authclient\Collection]] among application components
 * to get auth clients information.
 *
 * Example:
Qiang Xue committed
22 23 24
 *
 * ~~~php
 * <?= yii\authclient\widgets\Choice::widget([
25 26 27 28
 *     'baseAuthUrl' => ['site/auth']
 * ]); ?>
 * ~~~
 *
29
 * You can customize the widget appearance by using [[begin()]] and [[end()]] syntax
30 31 32
 * along with using method {@link clientLink()} or {@link createClientUrl()}.
 * For example:
 *
Qiang Xue committed
33
 * ~~~php
34 35 36 37
 * <?php
 * use yii\authclient\widgets\Choice;
 * ?>
 * <?php $authChoice = Choice::begin([
38 39
 *     'baseAuthUrl' => ['site/auth']
 * ]); ?>
40 41 42 43 44
 * <ul>
 * <?php foreach ($authChoice->getClients() as $client): ?>
 *     <li><?= $authChoice->clientLink($client); ?></li>
 * <?php endforeach; ?>
 * </ul>
45
 * <?php Choice::end(); ?>
46
 * ~~~
47
 *
48 49 50 51
 * 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.
 *
52 53
 * @see \yii\authclient\AuthAction
 *
Qiang Xue committed
54 55
 * @property array $baseAuthUrl Base auth URL configuration. This property is read-only.
 * @property ClientInterface[] $clients Auth providers. This property is read-only.
56
 *
57 58 59 60 61 62
 * @author Paul Klimov <klimov.paul@gmail.com>
 * @since 2.0
 */
class Choice extends Widget
{
	/**
63
	 * @var string name of the auth client collection application component.
Qiang Xue committed
64
	 * This component will be used to fetch services value if it is not set.
65
	 */
66
	public $clientCollection = 'authClientCollection';
67
	/**
68
	 * @var string name of the GET param , which should be used to passed auth client id to URL
Qiang Xue committed
69
	 * defined by [[baseAuthUrl]].
70
	 */
71
	public $clientIdGetParamName = 'authclient';
72 73 74
	/**
	 * @var array the HTML attributes that should be rendered in the div HTML tag representing the container element.
	 */
Qiang Xue committed
75
	public $options = [
76
		'class' => 'auth-clients'
77 78 79 80 81 82 83 84 85 86 87
	];
	/**
	 * @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.
	 * Note: this value automatically set to 'false' at the first call of [[createProviderUrl()]]
	 */
	public $autoRender = true;

Qiang Xue committed
88 89 90 91 92 93 94 95 96
	/**
	 * @var array configuration for the external clients base authentication URL.
	 */
	private $_baseAuthUrl;
	/**
	 * @var ClientInterface[] auth providers list.
	 */
	private $_clients;

97
	/**
98
	 * @param ClientInterface[] $clients auth providers
99
	 */
100
	public function setClients(array $clients)
101
	{
102
		$this->_clients = $clients;
103 104 105
	}

	/**
106
	 * @return ClientInterface[] auth providers
107
	 */
108
	public function getClients()
109
	{
110 111
		if ($this->_clients === null) {
			$this->_clients = $this->defaultClients();
112
		}
113
		return $this->_clients;
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	}

	/**
	 * @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;
	}

	/**
136 137
	 * Returns default auth clients list.
	 * @return ClientInterface[] auth clients list.
138
	 */
139
	protected function defaultClients()
140
	{
141 142 143
		/** @var $collection \yii\authclient\Collection */
		$collection = Yii::$app->getComponent($this->clientCollection);
		return $collection->getClients();
144 145 146 147 148 149 150 151 152 153 154 155
	}

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

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

	/**
189 190
	 * Composes client auth URL.
	 * @param ClientInterface $provider external auth client instance.
191 192
	 * @return string auth URL.
	 */
193
	public function createClientUrl($provider)
194 195 196
	{
		$this->autoRender = false;
		$url = $this->getBaseAuthUrl();
197
		$url[$this->clientIdGetParamName] = $provider->getId();
198 199 200 201 202 203 204 205
		return Html::url($url);
	}

	/**
	 * Renders the main content, which includes all external services links.
	 */
	protected function renderMainContent()
	{
206
		echo Html::beginTag('ul', ['class' => 'auth-clients clear']);
207
		foreach ($this->getClients() as $externalService) {
208
			echo Html::beginTag('li', ['class' => 'auth-client']);
209
			$this->clientLink($externalService);
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
			echo Html::endTag('li');
		}
		echo Html::endTag('ul');
	}

	/**
	 * Initializes the widget.
	 */
	public function init()
	{
		if ($this->popupMode) {
			$view = Yii::$app->getView();
			ChoiceAsset::register($view);
			$view->registerJs("\$('#" . $this->getId() . "').authchoice();");
		}
Qiang Xue committed
225 226
		$this->options['id'] = $this->getId();
		echo Html::beginTag('div', $this->options);
227 228 229 230 231 232 233 234 235 236 237 238
	}

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