Commit da2381cb by Alexander Makarov

Merge remote-tracking branch 'origin/master'

Conflicts: framework/CHANGELOG.md
parents 2fc1a382 0b248dff
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\build\controllers;
use Yii;
use yii\console\Controller;
use yii\helpers\VarDumper;
/**
* MimeTypeController generates a map of file extensions to MIME types
*
* It uses `mime.types` file from apache http located under
* http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup
*
* This file has been placed in the public domain for unlimited redistribution,
* so we can use it and ship it with Yii.
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class MimeTypeController extends Controller
{
/**
* @param string $outFile the file to update. Defaults to @yii/helpers/mimeTypes.php
*/
public function actionIndex($outFile = null)
{
if ($outFile === null) {
$outFile = Yii::getAlias('@yii/helpers/mimeTypes.php');
}
if ($content = file_get_contents('http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=co')) {
$mimeMap = [];
foreach(explode("\n", $content) as $line) {
$line = trim($line);
if (empty($line) || $line[0] == '#') { // skip comments and empty lines
continue;
}
$parts = preg_split('/\s+/', $line);
$mime = array_shift($parts);
foreach($parts as $ext) {
if (!empty($ext)) {
$mimeMap[$ext] = $mime;
}
}
}
ksort($mimeMap);
$array = VarDumper::export($mimeMap);
$content = <<<EOD
<?php
/**
* MIME types.
*
* This file contains most commonly used MIME types
* according to file extension names.
* Its content is generated from the apache http mime.types file.
* http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup
* This file has been placed in the public domain for unlimited redistribution.
*/
return $array;
EOD;
file_put_contents($outFile, $content);
} else {
$this->stderr("Failed to download mime.types file from apache SVN.\n");
}
}
}
......@@ -22,7 +22,7 @@ a controller ID and an action ID forms a *route* which takes the format of `Cont
End users can address any controller action through the corresponding route. For example, the URL
`http://hostname/index.php?r=site/index` specifies that the request should be handled by the `site` controller
using its `index` action.
using its `index` action. Please refer to the [Routing](runtime-routing.md) section for more details.
By default, controller and action IDs should contain lower-case alphanumeric characters and dashes only.
For example, `site`, `index`, `post-comment` and `comment2` are all valid controller/action IDs, while
......@@ -89,6 +89,22 @@ property, like the following in an [application configuration](structure-applica
```
### Default Controller
Each application has a default controller specified via the [[yii\base\Application::defaultRoute]] property.
When a request does not specify a [route](#ids-routes), the route specified by this property will be used.
For [[yii\web\Application|Web applications]], its value is `'site'`, while for [[yii\console\Application|console applications]],
it is `help`. Therefore, if a URL is `http://hostname/index.php`, it means the `site` controller will handle the request.
You may change the default controller with the following [application configuration](structure-applications.md#application-configurations):
```php
[
'defaultRoute' => 'main',
]
```
## Creating Actions
You can create actions in two ways: inline actions and standalone actions. An inline action is
......@@ -222,6 +238,7 @@ class SiteController extends Controller
}
```
### Action Parameters
You can define named arguments for an action and these will be automatically populated from corresponding values from
......
......@@ -330,7 +330,7 @@ are triggering page rendering events that are used for registering scripts, link
Always include these in your layout in order for the rendering to work correctly.
By default layout is loaded from `views/layouts/main.php`. You may change it at controller or module level by setting
different value to `layout` propery.
different value to `layout` property.
In order to pass data from controller to layout, that you may need for breadcrumbs or similar elements, use view component
params property. In controller it can be set as:
......@@ -353,6 +353,17 @@ In layout file the value can be used like the following:
]) ?>
```
You may also wrap the view render result into a layout using [[yii\base\View::beginContent()]], [[yii\base\View::endContent()]].
This approach can be used while applying nested layouts:
```php
<?php $this->beginContent('//layouts/overall') ?>
<div class="content">
<?= $content ?>
<div>
<?php $this->endContent() ?>
```
### Partials
Often you need to reuse some HTML markup in many views and often it's too simple to create a full-featured widget for it.
......
......@@ -4,6 +4,7 @@ Yii Framework 2 authclient extension Change Log
2.0.0-rc under development
--------------------------
- Bug #3633: OpenId return URL comparison advanced to prevent url encode problem (klimov-paul)
- Enh #3416: VKontakte OAuth support added (klimov-paul)
......
......@@ -809,7 +809,7 @@ class OpenId extends BaseClient implements ClientInterface
$this->returnUrl .= (strpos($this->returnUrl, '?') ? '&' : '?') . 'openid.claimed_id=' . $claimedId;
}
if ($this->data['openid_return_to'] != $this->returnUrl) {
if (!$this->compareUrl($this->data['openid_return_to'], $this->returnUrl)) {
// The return_to url must match the url of current request.
return false;
}
......@@ -949,4 +949,29 @@ class OpenId extends BaseClient implements ClientInterface
{
return array_merge(['id' => $this->getClaimedId()], $this->fetchAttributes());
}
/**
* Compares 2 URLs taking in account possible GET parameters order miss match and URL encoding inconsistencies.
* @param string $expectedUrl expected URL.
* @param string $actualUrl actual URL.
* @return boolean whether URLs are equal.
*/
protected function compareUrl($expectedUrl, $actualUrl)
{
$expectedUrlInfo = parse_url($expectedUrl);
$actualUrlInfo = parse_url($actualUrl);
foreach ($expectedUrlInfo as $name => $expectedValue) {
if ($name == 'query') {
parse_str($expectedValue, $expectedUrlParams);
parse_str($actualUrlInfo[$name], $actualUrlParams);
$paramsDiff = array_diff_assoc($expectedUrlParams, $actualUrlParams);
if (!empty($paramsDiff)) {
return false;
}
} elseif ($expectedValue != $actualUrlInfo[$name]) {
return false;
}
}
return true;
}
}
......@@ -25,6 +25,7 @@ Yii Framework 2 Change Log
- Bug #3311: Fixed the bug that `yii\di\Container::has()` did not return correct value (mgrechanik, qiangxue)
- Bug #3327: Fixed "Unable to find debug data" when logging objects with circular references (jarekkozak, samdark)
- Bug #3368: Fix for comparing numeric attributes in JavaScript (technixp)
- Bug #3393: Fix `yii\helpers\FileHelper::copyDirectory()` pattern not working (klimov-paul)
- Bug #3431: Allow using extended ErrorHandler class from the app namespace (cebe)
- Bug #3436: Fixed the issue that `ServiceLocator` still returns the old component after calling `set()` with a new definition (qiangxue)
- Bug #3458: Fixed the bug that the image rendered by `CaptchaAction` was using a wrong content type (MDMunir, qiangxue)
......@@ -66,6 +67,7 @@ Yii Framework 2 Change Log
- Enh #3597: Nested array support for HTML5 custom "data-*" attributes (armab)
- Enh #3607: Added support for limit in migrations actions: history, new, redo (Ragazzo)
- Enh #3636: Hide menu container tag with empty items in `yii\widgets\Menu` (arturf)
- Enh #3643: Improved Mime-Type detection by using the `mime.types` file from apache http project to dected mime types by file extension (cebe, pavel-voronin, trejder)
- Enh: Added support for using sub-queries when building a DB query with `IN` condition (qiangxue)
- Enh: Supported adding a new response formatter without the need to reconfigure existing formatters (qiangxue)
- Enh: Added `yii\web\UrlManager::addRules()` to simplify adding new URL rules (qiangxue)
......
......@@ -209,6 +209,9 @@ class BaseFileHelper
if ($handle === false) {
throw new InvalidParamException('Unable to open directory: ' . $src);
}
if (!isset($options['basePath'])) {
$options['basePath'] = realpath($src);
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
......
......@@ -19,6 +19,23 @@ class OpenIdTest extends TestCase
$this->mockApplication($config, '\yii\web\Application');
}
/**
* Invokes the object method even if it is protected.
* @param object $object object instance
* @param string $methodName name of the method to be invoked.
* @param array $args method arguments.
* @return mixed method invoke result.
*/
protected function invokeMethod($object, $methodName, array $args = [])
{
$classReflection = new \ReflectionClass(get_class($object));
$methodReflection = $classReflection->getMethod($methodName);
$methodReflection->setAccessible(true);
$result = $methodReflection->invokeArgs($object, $args);
$methodReflection->setAccessible(false);
return $result;
}
// Tests :
public function testSetGet()
......@@ -58,4 +75,55 @@ class OpenIdTest extends TestCase
$this->assertArrayHasKey('ax', $info);
$this->assertArrayHasKey('sreg', $info);
}
/**
* Data provider for [[testCompareUrl()]]
* @return array test data
*/
public function dataProviderCompareUrl()
{
return [
[
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient',
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient',
true
],
[
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient',
'http://domain.com/index.php?r=site/auth&authclient=myclient',
true
],
[
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient',
'http://domain.com/index.php?r=site/auth&authclient=myclient2',
false
],
[
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient&custom=value',
'http://domain.com/index.php?r=site%2Fauth&custom=value&authclient=myclient',
true
],
[
'https://domain.com/index.php?r=site%2Fauth&authclient=myclient',
'http://domain.com/index.php?r=site%2Fauth&authclient=myclient',
false
],
];
}
/**
* @see https://github.com/yiisoft/yii2/issues/3633
*
* @dataProvider dataProviderCompareUrl
*
* @param string $url1
* @param string $url2
* @param boolean $expectedResult
*/
public function testCompareUrl($url1, $url2, $expectedResult)
{
$client = new OpenId();
$comparisonResult = $this->invokeMethod($client, 'compareUrl', [$url1, $url2]);
$this->assertEquals($expectedResult, $comparisonResult);
}
}
......@@ -407,4 +407,42 @@ class FileHelperTest extends TestCase
FileHelper::localize($viewFile, $currentLanguage, $sourceLanguage)
);
}
/**
* @see https://github.com/yiisoft/yii2/issues/3393
*
* @depends testCopyDirectory
* @depends testFindFiles
*/
public function testCopyDirectoryExclude()
{
$srcDirName = 'test_src_dir';
$textFiles = [
'file1.txt' => 'text file 1 content',
'file2.txt' => 'text file 2 content',
];
$dataFiles = [
'file1.dat' => 'data file 1 content',
'file2.dat' => 'data file 2 content',
];
$this->createFileStructure([
$srcDirName => array_merge($textFiles, $dataFiles)
]);
$basePath = $this->testFilePath;
$srcDirName = $basePath . DIRECTORY_SEPARATOR . $srcDirName;
$dstDirName = $basePath . DIRECTORY_SEPARATOR . 'test_dst_dir';
FileHelper::copyDirectory($srcDirName, $dstDirName, ['only' => ['*.dat']]);
$this->assertFileExists($dstDirName, 'Destination directory does not exist!');
$copiedFiles = FileHelper::findFiles($dstDirName);
$this->assertCount(2, $copiedFiles, 'wrong files count copied');
foreach ($dataFiles as $name => $content) {
$fileName = $dstDirName . DIRECTORY_SEPARATOR . $name;
$this->assertFileExists($fileName);
$this->assertEquals($content, file_get_contents($fileName), 'Incorrect file content!');
}
}
}
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