Commit 3a5f01cb by Antonio Ramirez

Merge branch 'upstream' into 313-Inflector-Helper

* upstream: Enhanced the detection of secure connection. Refactored Modal. < PHP 5.3 compatibility for req checker code style and UI improvements to requirements checker readded accidentally removed .gitignore file Changed Yii.php case in some files where it was wrong Finished bootstrap Widget and Modal. PHP Intl extension has been added to default Yii requirements. moved optional packages to "suggest", updated platform requirements "vendor-dir": "vendor" is default, removed fixed auth manager unit test to not expect generic exception fixed range requests, tests improved
parents 3575b996 b2e7aa31
......@@ -12,9 +12,6 @@
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"config": {
"vendor-dir": "vendor"
},
"minimum-stability": "dev",
"require": {
"php": ">=5.3.0",
......
......@@ -3,7 +3,7 @@
// comment out the following line to disable debug mode
defined('YII_DEBUG') or define('YII_DEBUG', true);
require(__DIR__ . '/../vendor/yiisoft/yii2/yii.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../vendor/autoload.php');
$config = require(__DIR__ . '/../config/main.php');
......
......@@ -13,7 +13,7 @@ defined('YII_DEBUG') or define('YII_DEBUG', true);
// fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
require(__DIR__ . '/vendor/yiisoft/yii2/yii.php');
require(__DIR__ . '/vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/vendor/autoload.php');
$config = require(__DIR__ . '/config/console.php');
......
......@@ -32,7 +32,7 @@ abstract class ManagerTestBase extends TestCase
$this->assertEquals($item2->type, Item::TYPE_ROLE);
// test adding an item with the same name
$this->setExpectedException('Exception');
$this->setExpectedException('\yii\base\Exception');
$this->auth->createItem($name, $type, $description, $bizRule, $data);
}
......@@ -69,14 +69,14 @@ abstract class ManagerTestBase extends TestCase
$this->auth->addItemChild('createPost', 'updatePost');
// test adding upper level item to lower one
$this->setExpectedException('Exception');
$this->setExpectedException('\yii\base\Exception');
$this->auth->addItemChild('readPost', 'reader');
}
public function testAddItemChild2()
{
// test adding inexistent items
$this->setExpectedException('Exception');
$this->setExpectedException('\yii\base\Exception');
$this->assertFalse($this->auth->addItemChild('createPost2', 'updatePost'));
}
......@@ -105,7 +105,7 @@ abstract class ManagerTestBase extends TestCase
$this->assertEquals($auth->bizRule, 'rule');
$this->assertEquals($auth->data, 'data');
$this->setExpectedException('Exception');
$this->setExpectedException('\yii\base\Exception');
$this->auth->assign('new user', 'createPost2', 'rule', 'data');
}
......@@ -158,7 +158,7 @@ abstract class ManagerTestBase extends TestCase
public function testDetectLoop()
{
$this->setExpectedException('Exception');
$this->setExpectedException('\yii\base\Exception');
$this->auth->addItemChild('readPost', 'readPost');
}
......
......@@ -41,7 +41,7 @@ class ResponseTest extends \yiiunit\TestCase
static::$httpResponseCode = 200;
}
public function ranges()
public function rightRanges()
{
// TODO test more cases for range requests and check for rfc compatibility
// http://www.w3.org/Protocols/rfc2616/rfc2616.txt
......@@ -53,14 +53,14 @@ class ResponseTest extends \yiiunit\TestCase
}
/**
* @dataProvider ranges
* @dataProvider rightRanges
*/
public function testSendFileRanges($rangeHeader, $expectedHeader, $length, $expectedFile)
{
$content = $this->generateTestFileContent();
$_SERVER['HTTP_RANGE'] = 'bytes=' . $rangeHeader;
$sent = $this->runSendFile('testFile.txt', $content, null);
$this->assertEquals($expectedFile, $sent);
$this->assertTrue(in_array('HTTP/1.1 206 Partial Content', static::$headers));
$this->assertTrue(in_array('Accept-Ranges: bytes', static::$headers));
......@@ -69,6 +69,30 @@ class ResponseTest extends \yiiunit\TestCase
$this->assertTrue(in_array('Content-Length: ' . $length, static::$headers));
}
public function wrongRanges()
{
// TODO test more cases for range requests and check for rfc compatibility
// http://www.w3.org/Protocols/rfc2616/rfc2616.txt
return array(
array('1-2,3-5,6-10'), // multiple range request not supported
array('5-1'), // last-byte-pos value is less than its first-byte-pos value
array('-100000'), // last-byte-pos bigger then content length
array('10000-'), // first-byte-pos bigger then content length
);
}
/**
* @dataProvider wrongRanges
*/
public function testSendFileWrongRanges($rangeHeader)
{
$this->setExpectedException('yii\base\HttpException', 'Requested Range Not Satisfiable');
$content = $this->generateTestFileContent();
$_SERVER['HTTP_RANGE'] = 'bytes=' . $rangeHeader;
$this->runSendFile('testFile.txt', $content, null);
}
protected function generateTestFileContent()
{
return '12ёжик3456798áèabcdefghijklmnopqrstuvwxyz!"§$%&/(ёжик)=?';
......@@ -83,4 +107,4 @@ class ResponseTest extends \yiiunit\TestCase
$file = ob_get_clean();
return $file;
}
}
\ No newline at end of file
}
......@@ -741,7 +741,7 @@ class View extends Component
$lines[] = Html::script(implode("\n", $this->js[self::POS_END]), array('type' => 'text/javascript'));
}
if (!empty($this->js[self::POS_READY])) {
$js = "jQuery(document).ready(function(){\n{" . implode("\n", $this->js[self::POS_READY]) . "}\n});";
$js = "jQuery(document).ready(function(){\n" . implode("\n", $this->js[self::POS_READY]) . "\n});";
$lines[] = Html::script($js, array('type' => 'text/javascript'));
}
return empty($lines) ? '' : implode("\n", $lines) . "\n";
......
......@@ -9,19 +9,20 @@ namespace yii\bootstrap;
use Yii;
use yii\base\View;
use yii\helpers\Json;
/**
* Bootstrap is the base class for bootstrap widgets.
* \yii\bootstrap\Widget is the base class for all bootstrap widgets.
*
* @author Antonio Ramirez <amigo.cobos@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Widget extends \yii\base\Widget
{
/**
* @var bool whether to register the asset
* @var boolean whether to use the responsive version of Bootstrap.
*/
public static $responsive = true;
......@@ -29,95 +30,75 @@ class Widget extends \yii\base\Widget
* @var array the HTML attributes for the widget container tag.
*/
public $options = array();
/**
* Initializes the widget.
* @var array the options for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible options.
* For example, [this page](http://twitter.github.io/bootstrap/javascript.html#modals) shows
* how to use the "Modal" plugin and the supported options (e.g. "remote").
*/
public function init()
{
// ensure bundle
$this->registerBundle(static::$responsive);
}
public $pluginOptions = array();
/**
* Registers plugin events with the API.
* @param string $selector the CSS selector.
* @param string[] $events the JavaScript event configuration (name=>handler).
* @return boolean whether the events were registered.
* @todo To be discussed
* @var array the event handlers for the underlying Bootstrap JS plugin.
* Please refer to the corresponding Bootstrap plugin Web page for possible events.
* For example, [this page](http://twitter.github.io/bootstrap/javascript.html#modals) shows
* how to use the "Modal" plugin and the supported events (e.g. "shown").
*/
protected function registerEvents($selector, $events = array())
{
if (empty($events))
return;
$script = '';
foreach ($events as $name => $handler) {
$handler = ($handler instanceof JsExpression)
? $handler
: new JsExpression($handler);
public $pluginEvents = array();
$script .= ";jQuery('{$selector}').on('{$name}', {$handler});";
}
if (!empty($script))
$this->view->registerJs($script);
}
/**
* Registers a specific Bootstrap plugin using the given selector and options.
*
* @param string $name the name of the javascript widget to initialize
* @param array $options the Javascript options for the plugin
* Initializes the widget.
* This method will register the bootstrap asset bundle. If you override this method,
* make sure you call the parent implementation first.
*/
public function registerPlugin($name, $options = array())
public function init()
{
$selector = '#' . ArrayHelper::getValue($this->options, 'id');
$options = !empty($options) ? Json::encode($options) : '';
$script = ";jQuery('{$selector}').{$name}({$options});";
$this->view->registerJs($script);
parent::init();
if (!isset($this->options['id'])) {
$this->options['id'] = $this->getId();
}
}
/**
* Registers bootstrap bundle
* @param bool $responsive
* Registers a specific Bootstrap plugin and the related events
* @param string $name the name of the Bootstrap plugin
*/
public function registerBundle($responsive = false)
protected function registerPlugin($name)
{
$bundle = $responsive ? 'yii/bootstrap-responsive' : 'yii/bootstrap';
$this->view->registerAssetBundle($bundle);
}
$id = $this->options['id'];
$view = $this->getView();
$bundle = static::$responsive ? 'yii/bootstrap-responsive' : 'yii/bootstrap';
$view->registerAssetBundle($bundle);
/**
* Adds a new class to options. If the class key does not exists, it will create one, if it exists it will append
* the value and also makes sure the uniqueness of them.
*
* @param string $class
* @return array
*/
protected function addClassName($class)
{
if (isset($this->options['class'])) {
if (!is_array($this->options['class']))
$this->options['class'] = explode(' ', $this->options['class']);
$this->options['class'][] = $class;
$this->options['class'] = array_unique($this->options['class']);
$this->options['class'] = implode(' ', $this->options['class']);
} else
$this->options['class'] = $class;
return $this->options;
if ($this->pluginOptions !== false) {
$options = empty($this->pluginOptions) ? '' : Json::encode($this->pluginOptions);
$js = "jQuery('#$id').$name($options);";
$view->registerJs($js);
}
if (!empty($this->pluginEvents)) {
$js = array();
foreach ($this->pluginEvents as $event => $handler) {
$js[] = "jQuery('#$id').on('$event', $handler);";
}
$view->registerJs(implode("\n", $js));
}
}
/**
* Sets the default value for an item if not set.
* @param string $key the name of the item.
* @param mixed $value the default value.
* @return array
* Adds a CSS class to the specified options.
* This method will ensure that the CSS class is unique and the "class" option is properly formatted.
* @param array $options the options to be modified.
* @param string $class the CSS class to be added
*/
protected function defaultOption($key, $value)
protected function addCssClass(&$options, $class)
{
if (!isset($this->options[$key]))
$this->options[$key] = $value;
return $this->options;
if (isset($options['class'])) {
$classes = preg_split('/\s+/', $options['class'] . ' ' . $class, -1, PREG_SPLIT_NO_EMPTY);
$options['class'] = implode(' ', array_unique($classes));
} else {
$options['class'] = $class;
}
}
}
\ No newline at end of file
}
......@@ -64,10 +64,14 @@
"source": "https://github.com/yiisoft/yii2"
},
"require": {
"php": ">=5.3.0",
"michelf/php-markdown": "1.3",
"twig/twig": "1.12.*",
"smarty/smarty": "3.1.*",
"ezyang/htmlpurifier": "v4.5.0"
"php": ">=5.3.11",
"ext-mbstring": "*",
"lib-pcre": "*"
},
"suggest": {
"michelf/php-markdown": "Required for Markdown helper.",
"twig/twig": "Required for TwigViewRenderer.",
"smarty/smarty": "Required for SmartyViewRenderer.",
"ezyang/htmlpurifier": "Required for Purifier helper."
}
}
......@@ -16,7 +16,7 @@ if (version_compare(PHP_VERSION, '4.3', '<')) {
*
* Example:
*
* ~~~
* ~~~php
* require_once('path/to/YiiRequirementChecker.php');
* $requirementsChecker = new YiiRequirementChecker();
* $requirements = array(
......@@ -62,7 +62,7 @@ class YiiRequirementChecker
* If a string, it is treated as the path of the file, which contains the requirements;
* @return YiiRequirementChecker self instance.
*/
function check($requirements)
public function check($requirements)
{
if (is_string($requirements)) {
$requirements = require($requirements);
......@@ -132,7 +132,7 @@ class YiiRequirementChecker
* )
* </code>
*/
function getResult()
public function getResult()
{
if (isset($this->result)) {
return $this->result;
......@@ -145,7 +145,7 @@ class YiiRequirementChecker
* Renders the requirements check result.
* The output will vary depending is a script running from web or from console.
*/
function render()
public function render()
{
if (!isset($this->result)) {
$this->usageError('Nothing to render!');
......@@ -166,7 +166,7 @@ class YiiRequirementChecker
* @param string $compare comparison operator, by default '>='
* @return boolean if PHP extension version matches.
*/
function checkPhpExtensionVersion($extensionName, $version, $compare = '>=')
public function checkPhpExtensionVersion($extensionName, $version, $compare = '>=')
{
if (!extension_loaded($extensionName)) {
return false;
......@@ -183,7 +183,7 @@ class YiiRequirementChecker
* @param string $name configuration option name.
* @return boolean option is on.
*/
function checkPhpIniOn($name)
public function checkPhpIniOn($name)
{
$value = ini_get($name);
if (empty($value)) {
......@@ -197,7 +197,7 @@ class YiiRequirementChecker
* @param string $name configuration option name.
* @return boolean option is off.
*/
function checkPhpIniOff($name)
public function checkPhpIniOff($name)
{
$value = ini_get($name);
if (empty($value)) {
......@@ -214,7 +214,7 @@ class YiiRequirementChecker
* @param string $compare comparison operator, by default '>='.
* @return boolean comparison result.
*/
function compareByteSize($a, $b, $compare = '>=')
public function compareByteSize($a, $b, $compare = '>=')
{
$compareExpression = '(' . $this->getByteSize($a) . $compare . $this->getByteSize($b) . ')';
return $this->evaluateExpression($compareExpression);
......@@ -226,7 +226,7 @@ class YiiRequirementChecker
* @param string $verboseSize verbose size representation.
* @return integer actual size in bytes.
*/
function getByteSize($verboseSize)
public function getByteSize($verboseSize)
{
if (empty($verboseSize)) {
return 0;
......@@ -265,7 +265,7 @@ class YiiRequirementChecker
* @param string|null $max verbose file size maximum required value, pass null to skip maximum check.
* @return boolean success.
*/
function checkUploadMaxFileSize($min = null, $max = null)
public function checkUploadMaxFileSize($min = null, $max = null)
{
$postMaxSize = ini_get('post_max_size');
$uploadMaxFileSize = ini_get('upload_max_filesize');
......@@ -292,7 +292,7 @@ class YiiRequirementChecker
* @param boolean $_return_ whether the rendering result should be returned as a string
* @return string the rendering result. Null if the rendering result is not required.
*/
function renderViewFile($_viewFile_, $_data_ = null, $_return_ = false)
public function renderViewFile($_viewFile_, $_data_ = null, $_return_ = false)
{
// we use special variable names here to avoid conflict when extracting data
if (is_array($_data_)) {
......@@ -316,7 +316,7 @@ class YiiRequirementChecker
* @param int $requirementKey requirement key in the list.
* @return array normalized requirement.
*/
function normalizeRequirement($requirement, $requirementKey = 0)
public function normalizeRequirement($requirement, $requirementKey = 0)
{
if (!is_array($requirement)) {
$this->usageError('Requirement must be an array!');
......@@ -354,7 +354,7 @@ class YiiRequirementChecker
* This method will then terminate the execution of the current application.
* @param string $message the error message
*/
function usageError($message)
public function usageError($message)
{
echo "Error: $message\n\n";
exit(1);
......@@ -365,7 +365,7 @@ class YiiRequirementChecker
* @param string $expression a PHP expression to be evaluated.
* @return mixed the expression result.
*/
function evaluateExpression($expression)
public function evaluateExpression($expression)
{
return eval('return ' . $expression . ';');
}
......@@ -374,7 +374,7 @@ class YiiRequirementChecker
* Returns the server information.
* @return string server information.
*/
function getServerInfo()
public function getServerInfo()
{
$info = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : '';
return $info;
......@@ -384,7 +384,7 @@ class YiiRequirementChecker
* Returns the now date if possible in string representation.
* @return string now date.
*/
function getNowDate()
public function getNowDate()
{
$nowDate = @strftime('%Y-%m-%d %H:%M', time());
return $nowDate;
......
<?php
/**
* This is the Yii core requirements for the [[YiiRequirementChecker]] instance.
* These are the Yii core requirements for the [[YiiRequirementChecker]] instance.
* These requirements are mandatory for any Yii application.
*
* @var $this YiiRequirementChecker
*/
return array(
array(
......@@ -36,4 +38,11 @@ return array(
'by' => '<a href="http://www.php.net/manual/en/book.mbstring.php">Multibyte string</a> processing',
'memo' => 'Required for multibyte encoding string processing.'
),
array(
'name' => 'Intl extension',
'mandatory' => false,
'condition' => $this->checkPhpExtensionVersion('intl', '1.0.2'),
'by' => '<a href="http://www.php.net/manual/en/book.intl.php">Internationalization</a> support',
'memo' => 'PHP Intl extension 1.0.2 or higher is required when you want to use <abbr title="Internationalized domain names">IDN</abbr>-feature of EmailValidator or UrlValidator.'
),
);
\ No newline at end of file
......@@ -8,7 +8,7 @@
<head>
<meta charset="utf-8"/>
<title>Yii Application Requirement Checker</title>
<?php $this->renderViewFile(dirname(__FILE__).DIRECTORY_SEPARATOR.'css.php'); ?>
<?php $this->renderViewFile(dirname(__FILE__) . '/css.php'); ?>
</head>
<body>
<div class="container">
......@@ -25,14 +25,26 @@
It checks if the server is running the right version of PHP,
if appropriate PHP extensions have been loaded, and if php.ini file settings are correct.
</p>
<p>
There are two kinds of requirements being checked. Mandatory requirements are those that have to be met
to allow Yii to work as expected. There are also some optional requirements beeing checked which will
show you a warning when they do not meet. You can use Yii framework without them but some specific
functionality may be not available in this case.
</p>
<h3>Conclusion</h3>
<?php if ($summary['errors']>0): ?>
<strong class="text-error">Unfortunately your server configuration does not satisfy the requirements by this application.</strong>
<?php elseif ($summary['warnings']>0): ?>
<strong class="text-warning">Your server configuration satisfies the minimum requirements by this application. Please pay attention to the warnings listed below if your application will use the corresponding features.</strong>
<?php if ($summary['errors'] > 0): ?>
<div class="alert alert-error">
<strong>Unfortunately your server configuration does not satisfy the requirements by this application.<br>Please refer to the table below for detailed explanation.</strong>
</div>
<?php elseif ($summary['warnings'] > 0): ?>
<div class="alert alert-info">
<strong>Your server configuration satisfies the minimum requirements by this application.<br>Please pay attention to the warnings listed below and check if your application will use the corresponding features.</strong>
</div>
<?php else: ?>
<strong class="text-success">Congratulations! Your server configuration satisfies all requirements.</strong>
<div class="alert alert-success">
<strong>Congratulations! Your server configuration satisfies all requirements.</strong>
</div>
<?php endif; ?>
<h3>Details</h3>
......@@ -62,7 +74,7 @@
<hr>
<div class="footer">
<p>Server: <?php echo $this->getServerInfo().' '.$this->getNowDate(); ?></p>
<p>Server: <?php echo $this->getServerInfo() . ' ' . $this->getNowDate(); ?></p>
<p>Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a></p>
</div>
</div>
......
......@@ -533,7 +533,8 @@ class Request extends \yii\base\Request
*/
public function getIsSecureConnection()
{
return !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off');
return isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off')
|| isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO']==='https';
}
/**
......
......@@ -15,6 +15,7 @@ use yii\helpers\StringHelper;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class Response extends \yii\base\Response
......@@ -50,7 +51,7 @@ class Response extends \yii\base\Response
if (isset($_SERVER['HTTP_RANGE'])) {
// client sent us a multibyte range, can not hold this one for now
if (strpos(',', $_SERVER['HTTP_RANGE']) !== false) {
if (strpos($_SERVER['HTTP_RANGE'],',') !== false) {
header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
throw new HttpException(416, 'Requested Range Not Satisfiable');
}
......@@ -63,14 +64,18 @@ class Response extends \yii\base\Response
} else {
$range = explode('-', $range);
$contentStart = $range[0];
$contentEnd = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $fileSize - 1;
// check if the last-byte-pos presents in header
if ((isset($range[1]) && is_numeric($range[1]))) {
$contentEnd = $range[1];
}
}
/* Check the range and make sure it's treated according to the specs.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
// End bytes can not be larger than $end.
$contentEnd = ($contentEnd > $fileSize) ? $fileSize : $contentEnd;
$contentEnd = ($contentEnd > $fileSize) ? $fileSize -1 : $contentEnd;
// Validate the requested range and return an error if it's not correct.
$wrongContentStart = ($contentStart > $contentEnd || $contentStart > $fileSize - 1 || $contentStart < 0);
......
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