Commit 46a696b0 by Qiang Xue

Merge branch 'master' into split-find-into-find-findOne-findAll

parents 0e143338 c8d17099
...@@ -32,9 +32,9 @@ There are multiple severity levels and corresponding methods available: ...@@ -32,9 +32,9 @@ There are multiple severity levels and corresponding methods available:
Log targets Log targets
----------- -----------
When one of the logging methods is called, message is passed to [[yii\log\Logger]] component also accessible as When one of the logging methods is called, message is passed to [[yii\log\Logger]] component accessible as
`Yii::$app->log`. Logger accumulates messages in memory and then when there are enough messages or when current `Yii::getLogger()`. Logger accumulates messages in memory and then when there are enough messages
request finishes, sends them to different log targets, such as file or email. or when the current request finishes, sends them to different log targets, such as file or email.
You may configure the targets in application configuration, like the following: You may configure the targets in application configuration, like the following:
......
Debug toolbar and debugger Debug toolbar and debugger
========================== ==========================
Yii2 includes a handy toolbar to aid faster development and debugging as well as debugger. Toolbar displays information Yii2 includes a handy toolbar, and built-in debugger, for faster development and debugging of your applications. The toolbar displays information
about currently opened page while using debugger you can analyze data collected before. about the currently opened page, while the debugger can be used to analyze data you've previously collected (i.e., to confirm the values of variables).
Out of the box it allows you to: Out of the box these tools allow you to:
- Quickly getting framework version, PHP version, response status, current controller and action, performance info and - Quickly get the framework version, PHP version, response status, current controller and action, performance info and
more via toolbar. more via toolbar
- Browsing application and PHP configuration. - Browse the application and PHP configuration
- Browsing request data, request and response headers, session data and environment. - View the request data, request and response headers, session data, and environment variables
- Viewing, searching, filtering logs. - See, search, and filter the logs
- View profiling results. - View any profiling results
- View database queries. - View the database queries executed by the page
- View emails sent. - View the emails sent by the application
All these are available per request so you can browse past requests as well. All of this information will be available per request, allowing you to revisit the information for past requests as well.
Installing and configuring Installing and configuring
-------------------------- --------------------------
Add these lines to your config file: To enable these features, add these lines to your configuration file to enable the debug module:
```php ```php
'preload' => ['debug'], 'preload' => ['debug'],
...@@ -29,8 +29,7 @@ Add these lines to your config file: ...@@ -29,8 +29,7 @@ Add these lines to your config file:
] ]
``` ```
> Note: by default the debug module only works when browsing the website from the localhost. If you want to use it By default, the debug module only works when browsing the website from localhost. If you want to use it on a remote (staging) server, add the parameter `allowedIPs` to the configuration to whitelist your IP:
> on a remote (staging) server, add the parameter allowedIPs to the config to whitelist your IP, e.g. :**
```php ```php
'preload' => ['debug'], 'preload' => ['debug'],
...@@ -54,16 +53,18 @@ If you are using `enableStrictParsing` URL manager option, add the following to ...@@ -54,16 +53,18 @@ If you are using `enableStrictParsing` URL manager option, add the following to
], ],
``` ```
### Extra config for logging and profiling ### Extra configuration for logging and profiling
Logging and profiling are simple but very powerful tools that may help you to understand execution flow of both the Logging and profiling are simple but powerful tools that may help you to understand the execution flow of both the
framework and the application. These are useful both for development and production environments. framework and the application. These tools are useful for development and production environments alike.
While in production environment you should log only important enough messages manually as described in While in a production environment, you should log only significantly important messages manually, as described in
[logging guide section](logging.md), in development environment it's especially useful to get execution trace. [logging guide section](logging.md). It hurts performance too much to continue to log all messages in production.
In order to get trace messages that help you to understand what happens under the hood of the framework, you need to set In a development environment, the more logging the better, and it's especially useful to record the execution trace.
trace level in the config:
In order to see the trace messages that will help you to understand what happens under the hood of the framework, you need to set the
trace level in the configuration file:
```php ```php
return [ return [
...@@ -73,24 +74,27 @@ return [ ...@@ -73,24 +74,27 @@ return [
'traceLevel' => YII_DEBUG ? 3 : 0, // <-- here 'traceLevel' => YII_DEBUG ? 3 : 0, // <-- here
``` ```
By default it's automatically set to `3` if Yii is run in debug mode i.e. your `index.php` file contains the following: By default, the trace level is automatically set to `3` if Yii is running in debug mode, as determined by the presence of the following line in your `index.php` file:
```php ```php
defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_DEBUG') or define('YII_DEBUG', true);
``` ```
> Note: Make sure to disable debug mode on production since it may have significan performance effect and expose sensible > Note: Make sure to disable debug mode in production environments since it may have a significant and adverse performance effect. Further, the debug mode may expose sensitive information to end users.
information to end users.
Creating your own panels Creating your own panels
------------------------ ------------------------
Both toolbar and debugger are highly configurable and customizable. You can create your own panels that could collect Both the toolbar and debugger are highly configurable and customizable. To do so, you can create your own panels that collect
and display extra data. Below we'll describe a process of creation of a simple custom panel that collects views rendered and display the specific data you want. Below we'll describe the process of creating a simple custom panel that:
during request, shows a number in the toolbar and allows you checking view names in debugger. Below we're assuming
basic application template. - Collects the views rendered during a request
- Shows the number of views rendered in the toolbar
- Allows you to check the view names in the debugger
The assumption is that you're using the basic application template.
First we need to implement panel class in `panels/ViewsPanel.php`: First we need to implement the `Panel` class in `panels/ViewsPanel.php`:
```php ```php
<?php <?php
...@@ -151,18 +155,16 @@ class ViewsPanel extends Panel ...@@ -151,18 +155,16 @@ class ViewsPanel extends Panel
} }
``` ```
The workflow for the code above is the following: The workflow for the code above is:
1. `init` is executed before running any controller action. Best place to attach handlers that will collect data. 1. `init` is executed before any controller action is run. This method is the best place to attach handlers that will collect data during the controller action's execution.
2. `save` is called after controller action is executed. Data returned is stored in data file. If nothing returned panel 2. `save` is called after controller action is executed. The data returned by this method will be stored in a data file. If nothing is returned by this method, the panel
won't render. won't be rendered.
3. Data from data file is loaded into `$this->data`. For toolbar it's always latest data, for debugger it may be selected 3. The data from the data file is loaded into `$this->data`. For the toolbar, this will always represent the latest data, For the debugger, this property may be set to be read from any previous data file as well.
to be read from any previous data file. 4. The toolbar takes its contents from `getSummary`. There, we're showing the number of view files rendered. The debugger uses
4. Toolbar takes its contents from `getSummary`. There we're showing a number of view files rendered. Debugger uses
`getDetail` for the same purpose. `getDetail` for the same purpose.
Now it's time to tell debugger to use our new panel. In `config/web.php` debug configuration is modified to be the Now it's time to tell the debugger to use the new panel. In `config/web.php`, the debug configuration is modified to:
following:
```php ```php
if (YII_ENV_DEV) { if (YII_ENV_DEV) {
......
...@@ -209,7 +209,6 @@ class AuthAction extends Action ...@@ -209,7 +209,6 @@ class AuthAction extends Action
if ($response instanceof Response) { if ($response instanceof Response) {
return $response; return $response;
} }
return $this->redirectSuccess(); return $this->redirectSuccess();
} }
...@@ -233,7 +232,6 @@ class AuthAction extends Action ...@@ -233,7 +232,6 @@ class AuthAction extends Action
]; ];
$response = Yii::$app->getResponse(); $response = Yii::$app->getResponse();
$response->content = Yii::$app->getView()->renderFile($viewFile, $viewData); $response->content = Yii::$app->getView()->renderFile($viewFile, $viewData);
return $response; return $response;
} }
...@@ -247,7 +245,6 @@ class AuthAction extends Action ...@@ -247,7 +245,6 @@ class AuthAction extends Action
if ($url === null) { if ($url === null) {
$url = $this->getSuccessUrl(); $url = $this->getSuccessUrl();
} }
return $this->redirect($url); return $this->redirect($url);
} }
...@@ -261,7 +258,6 @@ class AuthAction extends Action ...@@ -261,7 +258,6 @@ class AuthAction extends Action
if ($url === null) { if ($url === null) {
$url = $this->getCancelUrl(); $url = $this->getCancelUrl();
} }
return $this->redirect($url, false); return $this->redirect($url, false);
} }
...@@ -292,7 +288,6 @@ class AuthAction extends Action ...@@ -292,7 +288,6 @@ class AuthAction extends Action
} }
} else { } else {
$url = $client->buildAuthUrl(); $url = $client->buildAuthUrl();
return Yii::$app->getResponse()->redirect($url); return Yii::$app->getResponse()->redirect($url);
} }
...@@ -325,7 +320,6 @@ class AuthAction extends Action ...@@ -325,7 +320,6 @@ class AuthAction extends Action
} else { } else {
// Upgrade to access token. // Upgrade to access token.
$client->fetchAccessToken(); $client->fetchAccessToken();
return $this->authSuccess($client); return $this->authSuccess($client);
} }
} }
...@@ -366,7 +360,6 @@ class AuthAction extends Action ...@@ -366,7 +360,6 @@ class AuthAction extends Action
} }
} else { } else {
$url = $client->buildAuthUrl(); $url = $client->buildAuthUrl();
return Yii::$app->getResponse()->redirect($url); return Yii::$app->getResponse()->redirect($url);
} }
} }
......
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\authclient\clients;
use yii\authclient\OAuth2;
/**
* Live allows authentication via Microsoft Live OAuth.
*
* In order to use Microsoft Live OAuth you must register your application at <https://account.live.com/developers/applications>
*
* Example application configuration:
*
* ~~~
* 'components' => [
* 'authClientCollection' => [
* 'class' => 'yii\authclient\Collection',
* 'clients' => [
* 'live' => [
* 'class' => 'yii\authclient\clients\Live',
* 'clientId' => 'live_client_id',
* 'clientSecret' => 'live_client_secret',
* ],
* ],
* ]
* ...
* ]
* ~~~
*
* @see https://account.live.com/developers/applications
* @see http://msdn.microsoft.com/en-us/library/live/hh243647.aspx
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
class Live extends OAuth2
{
/**
* @inheritdoc
*/
public $authUrl = 'https://login.live.com/oauth20_authorize.srf';
/**
* @inheritdoc
*/
public $tokenUrl = 'https://login.live.com/oauth20_token.srf';
/**
* @inheritdoc
*/
public $apiBaseUrl = 'https://apis.live.net/v5.0';
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if ($this->scope === null) {
$this->scope = implode(',', [
'wl.basic',
'wl.emails',
]);
}
}
/**
* @inheritdoc
*/
protected function initUserAttributes()
{
return $this->api('me', 'GET');
}
/**
* @inheritdoc
*/
protected function defaultName()
{
return 'live';
}
/**
* @inheritdoc
*/
protected function defaultTitle()
{
return 'Live';
}
}
\ No newline at end of file
...@@ -14,7 +14,7 @@ use yii\helpers\Html; ...@@ -14,7 +14,7 @@ use yii\helpers\Html;
use yii\authclient\ClientInterface; use yii\authclient\ClientInterface;
/** /**
* Choice prints buttons for authentication via various auth clients. * AuthChoice prints buttons for authentication via various auth clients.
* It opens a popup window for the client authentication process. * It opens a popup window for the client authentication process.
* By default this widget relies on presence of [[\yii\authclient\Collection]] among application components * By default this widget relies on presence of [[\yii\authclient\Collection]] among application components
* to get auth clients information. * to get auth clients information.
...@@ -22,7 +22,7 @@ use yii\authclient\ClientInterface; ...@@ -22,7 +22,7 @@ use yii\authclient\ClientInterface;
* Example: * Example:
* *
* ~~~php * ~~~php
* <?= yii\authclient\widgets\Choice::widget([ * <?= yii\authclient\widgets\AuthChoice::widget([
* 'baseAuthUrl' => ['site/auth'] * 'baseAuthUrl' => ['site/auth']
* ]); ?> * ]); ?>
* ~~~ * ~~~
...@@ -33,17 +33,17 @@ use yii\authclient\ClientInterface; ...@@ -33,17 +33,17 @@ use yii\authclient\ClientInterface;
* *
* ~~~php * ~~~php
* <?php * <?php
* use yii\authclient\widgets\Choice; * use yii\authclient\widgets\AuthChoice;
* ?> * ?>
* <?php $authChoice = Choice::begin([ * <?php $authAuthChoice = AuthChoice::begin([
* 'baseAuthUrl' => ['site/auth'] * 'baseAuthUrl' => ['site/auth']
* ]); ?> * ]); ?>
* <ul> * <ul>
* <?php foreach ($authChoice->getClients() as $client): ?> * <?php foreach ($authAuthChoice->getClients() as $client): ?>
* <li><?= $authChoice->clientLink($client) ?></li> * <li><?= $authAuthChoice->clientLink($client) ?></li>
* <?php endforeach; ?> * <?php endforeach; ?>
* </ul> * </ul>
* <?php Choice::end(); ?> * <?php AuthChoice::end(); ?>
* ~~~ * ~~~
* *
* This widget supports following keys for [[ClientInterface::getViewOptions()]] result: * This widget supports following keys for [[ClientInterface::getViewOptions()]] result:
...@@ -58,7 +58,7 @@ use yii\authclient\ClientInterface; ...@@ -58,7 +58,7 @@ use yii\authclient\ClientInterface;
* @author Paul Klimov <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class Choice extends Widget class AuthChoice extends Widget
{ {
/** /**
* @var string name of the auth client collection application component. * @var string name of the auth client collection application component.
...@@ -226,7 +226,7 @@ class Choice extends Widget ...@@ -226,7 +226,7 @@ class Choice extends Widget
{ {
if ($this->popupMode) { if ($this->popupMode) {
$view = Yii::$app->getView(); $view = Yii::$app->getView();
ChoiceAsset::register($view); AuthChoiceAsset::register($view);
$view->registerJs("\$('#" . $this->getId() . "').authchoice();"); $view->registerJs("\$('#" . $this->getId() . "').authchoice();");
} }
$this->options['id'] = $this->getId(); $this->options['id'] = $this->getId();
......
...@@ -10,12 +10,12 @@ namespace yii\authclient\widgets; ...@@ -10,12 +10,12 @@ namespace yii\authclient\widgets;
use yii\web\AssetBundle; use yii\web\AssetBundle;
/** /**
* ChoiceAsset is an asset bundle for [[Choice]] widget. * AuthChoiceAsset is an asset bundle for [[AuthChoice]] widget.
* *
* @author Paul Klimov <klimov.paul@gmail.com> * @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class ChoiceAsset extends AssetBundle class AuthChoiceAsset extends AssetBundle
{ {
public $sourcePath = '@yii/authclient/widgets/assets'; public $sourcePath = '@yii/authclient/widgets/assets';
public $js = [ public $js = [
......
.clients { .clients {
overflow:auto; overflow:auto;
} }
.auth-icon { .auth-icon {
display: block; display: block;
width: 32px; width: 32px;
height: 32px; height: 32px;
background: url(authchoice.png) no-repeat; background: url(authchoice.png) no-repeat;
} }
.auth-icon.google, .auth-icon.google,
.auth-icon.google_openid, .auth-icon.google_openid,
.auth-icon.google_oauth { .auth-icon.google_oauth {
background-position: 0 -34px; background-position: 0 -34px;
} }
.auth-icon.twitter { .auth-icon.twitter {
background-position: 0 -68px; background-position: 0 -68px;
} }
.auth-icon.yandex, .auth-icon.yandex,
.auth-icon.yandex_openid, .auth-icon.yandex_openid,
.auth-icon.yandex_oauth { .auth-icon.yandex_oauth {
background-position: 0 -102px; background-position: 0 -102px;
} }
.auth-icon.vkontakte { .auth-icon.vkontakte {
background-position: 0 -136px; background-position: 0 -136px;
} }
.auth-icon.facebook { .auth-icon.facebook {
background-position: 0 -170px; background-position: 0 -170px;
} }
.auth-icon.mailru { .auth-icon.mailru {
background-position: 0 -204px; background-position: 0 -204px;
} }
.auth-icon.moikrug { .auth-icon.moikrug {
background-position: 0 -238px; background-position: 0 -238px;
} }
.auth-icon.odnoklassniki { .auth-icon.odnoklassniki {
background-position: 0 -272px; background-position: 0 -272px;
} }
.auth-icon.linkedin { .auth-icon.linkedin {
background-position: 0 -306px; background-position: 0 -306px;
} }
.auth-icon.github { .auth-icon.github {
background-position: 0 -340px; background-position: 0 -340px;
} }
.auth-icon.live { .auth-icon.live {
background-position: 0 -372px; background-position: 0 -372px;
} }
.auth-link:hover .auth-icon i, .auth-link:hover .auth-icon i,
.auth-link:focus .auth-icon i { .auth-link:focus .auth-icon i {
display: block; display: block;
width: 32px; width: 32px;
height: 32px; height: 32px;
background: url(authchoice.png) 0 0 no-repeat; background: url(authchoice.png) 0 0 no-repeat;
} }
.auth-clients { .auth-clients {
margin: 0 0 1em; margin: 0 0 1em;
list-style: none; list-style: none;
overflow: auto; overflow: auto;
} }
.auth-client { .auth-client {
float: left; float: left;
margin: 0 1em 0 0; margin: 0 1em 0 0;
} }
.auth-clients .auth-client .auth-link { .auth-clients .auth-client .auth-link {
display: block; display: block;
width: 58px; width: 58px;
} }
.auth-client .auth-link .auth-icon { .auth-client .auth-link .auth-icon {
margin: 0 auto; margin: 0 auto;
} }
.auth-client .auth-link .auth-title { .auth-client .auth-link .auth-title {
display: block; display: block;
margin-top: 0.4em; margin-top: 0.4em;
text-align: center; text-align: center;
} }
\ No newline at end of file
/** /**
* Yii auth choice widget. * Yii auth choice widget.
* *
* This is the JavaScript widget used by the yii\authclient\widgets\Choice widget. * This is the JavaScript widget used by the yii\authclient\widgets\AuthChoice widget.
* *
* @link http://www.yiiframework.com/ * @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC * @copyright Copyright (c) 2008 Yii Software LLC
...@@ -10,59 +10,59 @@ ...@@ -10,59 +10,59 @@
* @since 2.0 * @since 2.0
*/ */
jQuery(function($) { jQuery(function($) {
$.fn.authchoice = function(options) { $.fn.authchoice = function(options) {
options = $.extend({ options = $.extend({
popup: { popup: {
resizable: 'yes', resizable: 'yes',
scrollbars: 'no', scrollbars: 'no',
toolbar: 'no', toolbar: 'no',
menubar: 'no', menubar: 'no',
location: 'no', location: 'no',
directories: 'no', directories: 'no',
status: 'yes', status: 'yes',
width: 450, width: 450,
height: 380 height: 380
} }
}, options); }, options);
return this.each(function() { return this.each(function() {
var $container = $(this); var $container = $(this);
$container.find('a').on('click', function(e) { $container.find('a').on('click', function(e) {
e.preventDefault(); e.preventDefault();
var authChoicePopup = null; var authChoicePopup = null;
if (authChoicePopup = $container.data('authChoicePopup')) { if (authChoicePopup = $container.data('authChoicePopup')) {
authChoicePopup.close(); authChoicePopup.close();
} }
var url = this.href; var url = this.href;
var popupOptions = options.popup; var popupOptions = options.popup;
var localPopupWidth = this.getAttribute('data-popup-width'); var localPopupWidth = this.getAttribute('data-popup-width');
if (localPopupWidth) { if (localPopupWidth) {
popupOptions.width = localPopupWidth; popupOptions.width = localPopupWidth;
} }
var localPopupHeight = this.getAttribute('data-popup-height'); var localPopupHeight = this.getAttribute('data-popup-height');
if (localPopupWidth) { if (localPopupWidth) {
popupOptions.height = localPopupHeight; popupOptions.height = localPopupHeight;
} }
popupOptions.left = (window.screen.width - options.popup.width) / 2; popupOptions.left = (window.screen.width - options.popup.width) / 2;
popupOptions.top = (window.screen.height - options.popup.height) / 2; popupOptions.top = (window.screen.height - options.popup.height) / 2;
var popupFeatureParts = []; var popupFeatureParts = [];
for (var propName in popupOptions) { for (var propName in popupOptions) {
popupFeatureParts.push(propName + '=' + popupOptions[propName]); popupFeatureParts.push(propName + '=' + popupOptions[propName]);
} }
var popupFeature = popupFeatureParts.join(','); var popupFeature = popupFeatureParts.join(',');
authChoicePopup = window.open(url, 'yii_auth_choice', popupFeature); authChoicePopup = window.open(url, 'yii_auth_choice', popupFeature);
authChoicePopup.focus(); authChoicePopup.focus();
$container.data('authChoicePopup', authChoicePopup); $container.data('authChoicePopup', authChoicePopup);
}); });
}); });
}; };
}); });
...@@ -655,6 +655,9 @@ class DbManager extends Manager ...@@ -655,6 +655,9 @@ class DbManager extends Manager
*/ */
public function getRule($name) public function getRule($name)
{ {
if ($name === null) {
return null;
}
$query = new Query; $query = new Query;
$query->select(['data'])->from($this->ruleTable)->where(['name' => $name]); $query->select(['data'])->from($this->ruleTable)->where(['name' => $name]);
$row = $query->createCommand($this->db)->queryOne(); $row = $query->createCommand($this->db)->queryOne();
......
...@@ -628,11 +628,7 @@ class PhpManager extends Manager ...@@ -628,11 +628,7 @@ class PhpManager extends Manager
*/ */
public function getRule($name) public function getRule($name)
{ {
if (!isset($this->_rules[$name])) { return $name !== null && isset($this->_rules[$name]) ? $this->_rules[$name] : null;
return null;
}
return $this->_rules[$name];
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment