Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
31ea3f89
Commit
31ea3f89
authored
Oct 29, 2013
by
Paul Klimov
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of github.com:yiisoft/yii2 into email-swift-2
parents
2d537704
155e9c6c
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
641 additions
and
499 deletions
+641
-499
.gitignore
.gitignore
+4
-0
contact.php
apps/advanced/frontend/views/site/contact.php
+2
-2
init
apps/advanced/init
+1
-1
contact.php
apps/basic/views/site/contact.php
+2
-2
login.php
apps/basic/views/site/login.php
+2
-2
PhpDocController.php
build/controllers/PhpDocController.php
+5
-5
controller.md
docs/guide/controller.md
+4
-4
upgrade-from-v1.md
docs/guide/upgrade-from-v1.md
+1
-1
view.md
docs/guide/view.md
+2
-2
BaseYii.php
framework/yii/BaseYii.php
+1
-1
Application.php
framework/yii/base/Application.php
+1
-1
Controller.php
framework/yii/base/Controller.php
+5
-20
Object.php
framework/yii/base/Object.php
+2
-1
View.php
framework/yii/base/View.php
+52
-15
ViewContextInterface.php
framework/yii/base/ViewContextInterface.php
+26
-0
Widget.php
framework/yii/base/Widget.php
+8
-22
Cache.php
framework/yii/caching/Cache.php
+2
-2
RedisCache.php
framework/yii/caching/RedisCache.php
+1
-1
ActiveDataProvider.php
framework/yii/data/ActiveDataProvider.php
+1
-1
Schema.php
framework/yii/db/cubrid/Schema.php
+2
-2
Schema.php
framework/yii/db/pgsql/Schema.php
+1
-0
action.php
framework/yii/gii/generators/form/templates/action.php
+1
-1
view.php
framework/yii/gii/views/default/view.php
+5
-5
FallbackMessageFormatter.php
framework/yii/i18n/FallbackMessageFormatter.php
+0
-306
I18N.php
framework/yii/i18n/I18N.php
+37
-8
MessageFormatter.php
framework/yii/i18n/MessageFormatter.php
+286
-33
Logger.php
framework/yii/log/Logger.php
+2
-2
Connection.php
framework/yii/redis/Connection.php
+3
-3
exception.php
framework/yii/views/errorHandler/exception.php
+2
-2
README.md
tests/README.md
+42
-0
RedisCacheTest.php
tests/unit/framework/caching/RedisCacheTest.php
+2
-2
ConsoleTest.php
tests/unit/framework/helpers/ConsoleTest.php
+1
-1
FallbackMessageFormatterTest.php
tests/unit/framework/i18n/FallbackMessageFormatterTest.php
+36
-19
MessageFormatterTest.php
tests/unit/framework/i18n/MessageFormatterTest.php
+98
-31
UrlValidatorTest.php
tests/unit/framework/validators/UrlValidatorTest.php
+1
-1
No files found.
.gitignore
View file @
31ea3f89
...
...
@@ -20,3 +20,6 @@ composer.phar
# Mac DS_Store Files
.DS_Store
# local phpunit config
/phpunit.xml
\ No newline at end of file
apps/advanced/frontend/views/site/contact.php
View file @
31ea3f89
...
...
@@ -25,10 +25,10 @@ $this->params['breadcrumbs'][] = $this->title;
<?=
$form
->
field
(
$model
,
'email'
)
?>
<?=
$form
->
field
(
$model
,
'subject'
)
?>
<?=
$form
->
field
(
$model
,
'body'
)
->
textArea
([
'rows'
=>
6
])
?>
<?=
$form
->
field
(
$model
,
'verifyCode'
)
->
widget
(
Captcha
::
className
(),
[
<?=
$form
->
field
(
$model
,
'verifyCode'
)
->
widget
(
Captcha
::
className
(),
[
'options'
=>
[
'class'
=>
'form-control'
],
'template'
=>
'<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>'
,
])
;
?>
])
?>
<div
class=
"form-group"
>
<?=
Html
::
submitButton
(
'Submit'
,
[
'class'
=>
'btn btn-primary'
])
?>
</div>
...
...
apps/advanced/init
View file @
31ea3f89
...
...
@@ -21,7 +21,7 @@ if (empty($params['env'])) {
exit
(
1
);
}
if
(
isset
(
$envNames
[
$answer
]))
{
if
(
isset
(
$envNames
[
$answer
]))
{
$envName
=
$envNames
[
$answer
];
}
}
...
...
apps/basic/views/site/contact.php
View file @
31ea3f89
...
...
@@ -33,10 +33,10 @@ $this->params['breadcrumbs'][] = $this->title;
<?=
$form
->
field
(
$model
,
'email'
)
?>
<?=
$form
->
field
(
$model
,
'subject'
)
?>
<?=
$form
->
field
(
$model
,
'body'
)
->
textArea
([
'rows'
=>
6
])
?>
<?=
$form
->
field
(
$model
,
'verifyCode'
)
->
widget
(
Captcha
::
className
(),
[
<?=
$form
->
field
(
$model
,
'verifyCode'
)
->
widget
(
Captcha
::
className
(),
[
'options'
=>
[
'class'
=>
'form-control'
],
'template'
=>
'<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>'
,
])
;
?>
])
?>
<div
class=
"form-group"
>
<?=
Html
::
submitButton
(
'Submit'
,
[
'class'
=>
'btn btn-primary'
])
?>
</div>
...
...
apps/basic/views/site/login.php
View file @
31ea3f89
...
...
@@ -28,9 +28,9 @@ $this->params['breadcrumbs'][] = $this->title;
<?=
$form
->
field
(
$model
,
'password'
)
->
passwordInput
()
?>
<?=
$form
->
field
(
$model
,
'rememberMe'
,
[
<?=
$form
->
field
(
$model
,
'rememberMe'
,
[
'template'
=>
"<div class=
\"
col-lg-offset-1 col-lg-3
\"
>
{
input
}
</div>
\n
<div class=
\"
col-lg-8
\"
>
{
error
}
</div>"
,
])
->
checkbox
()
;
?>
])
->
checkbox
()
?>
<div
class=
"form-group"
>
<div
class=
"col-lg-offset-1 col-lg-11"
>
...
...
build/controllers/PhpDocController.php
View file @
31ea3f89
...
...
@@ -115,7 +115,7 @@ class PhpDocController extends Controller
if
(
trim
(
$lines
[
1
])
==
'*'
||
substr
(
trim
(
$lines
[
1
]),
0
,
3
)
==
'* @'
)
{
$this
->
stderr
(
"[WARN] Class
$className
has no short description.
\n
"
,
Console
::
FG_YELLOW
,
Console
::
BOLD
);
}
foreach
(
$lines
as
$line
)
{
foreach
(
$lines
as
$line
)
{
if
(
substr
(
trim
(
$line
),
0
,
9
)
==
'* @since '
)
{
$seenSince
=
true
;
}
elseif
(
substr
(
trim
(
$line
),
0
,
10
)
==
'* @author '
)
{
...
...
@@ -138,7 +138,7 @@ class PhpDocController extends Controller
$newFileContent
=
[];
$n
=
count
(
$fileContent
);
for
(
$i
=
0
;
$i
<
$n
;
$i
++
)
{
for
(
$i
=
0
;
$i
<
$n
;
$i
++
)
{
if
(
$i
>
$start
||
$i
<
$docStart
)
{
$newFileContent
[]
=
$fileContent
[
$i
];
}
else
{
...
...
@@ -164,7 +164,7 @@ class PhpDocController extends Controller
{
$lines
=
explode
(
"
\n
"
,
$doc
);
$n
=
count
(
$lines
);
for
(
$i
=
0
;
$i
<
$n
;
$i
++
)
{
for
(
$i
=
0
;
$i
<
$n
;
$i
++
)
{
$lines
[
$i
]
=
rtrim
(
$lines
[
$i
]);
if
(
trim
(
$lines
[
$i
])
==
'*'
&&
trim
(
$lines
[
$i
+
1
])
==
'*'
)
{
unset
(
$lines
[
$i
]);
...
...
@@ -184,7 +184,7 @@ class PhpDocController extends Controller
$lines
=
explode
(
"
\n
"
,
$doc
);
$propertyPart
=
false
;
$propertyPosition
=
false
;
foreach
(
$lines
as
$i
=>
$line
)
{
foreach
(
$lines
as
$i
=>
$line
)
{
if
(
substr
(
trim
(
$line
),
0
,
12
)
==
'* @property '
)
{
$propertyPart
=
true
;
}
elseif
(
$propertyPart
&&
trim
(
$line
)
==
'*'
)
{
...
...
@@ -200,7 +200,7 @@ class PhpDocController extends Controller
}
}
$finalDoc
=
''
;
foreach
(
$lines
as
$i
=>
$line
)
{
foreach
(
$lines
as
$i
=>
$line
)
{
$finalDoc
.=
$line
.
"
\n
"
;
if
(
$i
==
$propertyPosition
)
{
$finalDoc
.=
$properties
;
...
...
docs/guide/controller.md
View file @
31ea3f89
...
...
@@ -89,7 +89,7 @@ class BlogController extends Controller
$post
=
Post
::
find
(
$id
);
$text
=
$post
->
text
;
if
(
$version
)
{
if
(
$version
)
{
$text
=
$post
->
getHistory
(
$version
);
}
...
...
@@ -121,13 +121,13 @@ class BlogController extends Controller
public
function
actionUpdate
(
$id
)
{
$post
=
Post
::
find
(
$id
);
if
(
!
$post
)
{
if
(
!
$post
)
{
throw
new
HttpException
(
404
);
}
if
(
\Yii
::
$app
->
request
->
isPost
))
{
if
(
\Yii
::
$app
->
request
->
isPost
))
{
$post
->
load
(
$_POST
);
if
(
$post
->
save
())
{
if
(
$post
->
save
())
{
$this
->
redirect
([
'view'
,
'id'
=>
$post
->
id
]);
}
}
...
...
docs/guide/upgrade-from-v1.md
View file @
31ea3f89
...
...
@@ -179,7 +179,7 @@ $model->save();
$postTags
=
[];
$tagsCount
=
count
(
$_POST
[
'PostTag'
]);
while
(
$tagsCount
--
>
0
)
{
while
(
$tagsCount
--
>
0
)
{
$postTags
[]
=
new
PostTag
([
'post_id'
=>
$model
->
id
]);
}
Model
::
loadMultiple
(
$postTags
,
$_POST
);
...
...
docs/guide/view.md
View file @
31ea3f89
...
...
@@ -28,7 +28,7 @@ as the corresponding key.
So the view for the action above should be in
`views/site/index.php`
and can be something like:
```
php
<p>
Hello,
<?=
$username
?>
!
</p>
<p>
Hello,
<?=
$username
?>
!
</p>
```
Instead of just scalar values you can pass anything else such as arrays or objects.
...
...
@@ -305,7 +305,7 @@ Then we're using it in `index.php` view where we display a list of users:
```
php
<div
class=
"user-index"
>
<?php
foreach
(
$users
as
$user
)
{
foreach
(
$users
as
$user
)
{
echo
$this
->
render
(
'_profile'
,
[
'username'
=>
$user
->
name
,
'tagline'
=>
$user
->
tagline
,
...
...
framework/yii/BaseYii.php
View file @
31ea3f89
...
...
@@ -515,7 +515,7 @@ class BaseYii
return
self
::
$app
->
getI18n
()
->
translate
(
$category
,
$message
,
$params
,
$language
?:
self
::
$app
->
language
);
}
else
{
$p
=
[];
foreach
((
array
)
$params
as
$name
=>
$value
)
{
foreach
((
array
)
$params
as
$name
=>
$value
)
{
$p
[
'{'
.
$name
.
'}'
]
=
$value
;
}
return
(
$p
===
[])
?
$message
:
strtr
(
$message
,
$p
);
...
...
framework/yii/base/Application.php
View file @
31ea3f89
...
...
@@ -20,7 +20,7 @@ use yii\web\HttpException;
* @property \yii\db\Connection $db The database connection. This property is read-only.
* @property ErrorHandler $errorHandler The error handler application component. This property is read-only.
* @property \yii\base\Formatter $formatter The formatter application component. This property is read-only.
* @property \yii\i18n\I18N $i18
N
The internationalization component. This property is read-only.
* @property \yii\i18n\I18N $i18
n
The internationalization component. This property is read-only.
* @property \yii\log\Logger $log The log component. This property is read-only.
* @property \yii\web\Request|\yii\console\Request $request The request component. This property is read-only.
* @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
...
...
framework/yii/base/Controller.php
View file @
31ea3f89
...
...
@@ -25,7 +25,7 @@ use Yii;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Controller
extends
Component
class
Controller
extends
Component
implements
ViewContextInterface
{
/**
* @event ActionEvent an event raised right before executing a controller action.
...
...
@@ -305,8 +305,7 @@ class Controller extends Component
*/
public
function
render
(
$view
,
$params
=
[])
{
$viewFile
=
$this
->
findViewFile
(
$view
);
$output
=
$this
->
getView
()
->
renderFile
(
$viewFile
,
$params
,
$this
);
$output
=
$this
->
getView
()
->
render
(
$view
,
$params
,
$this
);
$layoutFile
=
$this
->
findLayoutFile
();
if
(
$layoutFile
!==
false
)
{
return
$this
->
getView
()
->
renderFile
(
$layoutFile
,
[
'content'
=>
$output
],
$this
);
...
...
@@ -325,8 +324,7 @@ class Controller extends Component
*/
public
function
renderPartial
(
$view
,
$params
=
[])
{
$viewFile
=
$this
->
findViewFile
(
$view
);
return
$this
->
getView
()
->
renderFile
(
$viewFile
,
$params
,
$this
);
return
$this
->
getView
()
->
render
(
$view
,
$params
,
$this
);
}
/**
...
...
@@ -382,22 +380,9 @@ class Controller extends Component
* on how to specify this parameter.
* @return string the view file path. Note that the file may not exist.
*/
p
rotected
function
findViewFile
(
$view
)
p
ublic
function
findViewFile
(
$view
)
{
if
(
strncmp
(
$view
,
'@'
,
1
)
===
0
)
{
// e.g. "@app/views/main"
$file
=
Yii
::
getAlias
(
$view
);
}
elseif
(
strncmp
(
$view
,
'//'
,
2
)
===
0
)
{
// e.g. "//layouts/main"
$file
=
Yii
::
$app
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
===
0
)
{
// e.g. "/site/index"
$file
=
$this
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
else
{
$file
=
$this
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$view
;
}
return
pathinfo
(
$file
,
PATHINFO_EXTENSION
)
===
''
?
$file
.
'.php'
:
$file
;
return
$this
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$view
;
}
/**
...
...
framework/yii/base/Object.php
View file @
31ea3f89
...
...
@@ -63,6 +63,7 @@ class Object implements Arrayable
* @param string $name the property name
* @return mixed the property value
* @throws UnknownPropertyException if the property is not defined
* @throws InvalidCallException if the property is write-only
* @see __set
*/
public
function
__get
(
$name
)
...
...
@@ -85,7 +86,7 @@ class Object implements Arrayable
* @param string $name the property name or the event name
* @param mixed $value the property value
* @throws UnknownPropertyException if the property is not defined
* @throws InvalidCallException if the property is read-only
.
* @throws InvalidCallException if the property is read-only
* @see __get
*/
public
function
__set
(
$name
,
$value
)
...
...
framework/yii/base/View.php
View file @
31ea3f89
...
...
@@ -89,8 +89,7 @@ class View extends Component
/**
* @var object the context under which the [[renderFile()]] method is being invoked.
* This can be a controller, a widget, or any other object.
* @var ViewContextInterface the context under which the [[renderFile()]] method is being invoked.
*/
public
$context
;
/**
...
...
@@ -196,29 +195,67 @@ class View extends Component
/**
* Renders a view.
*
* Th
is method delegates the call to the [[context]] object
:
* Th
e view to be rendered can be specified in one of the following formats
:
*
* - If [[context]] is a controller, the [[Controller::renderPartial()]] method will be called;
* - If [[context]] is a widget, the [[Widget::render()]] method will be called;
* - Otherwise, an InvalidCallException exception will be thrown.
* - path alias (e.g. "@app/views/site/index");
* - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
* The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
* - absolute path within current module (e.g. "/site/index"): the view name starts with a single slash.
* The actual view file will be looked for under the [[Module::viewPath|view path]] of [[module]].
* - resolving any other format will be performed via [[ViewContext::findViewFile()]].
*
* @param string $view the view name. Please refer to [[Controller::findViewFile()]]
* and [[Widget::findViewFile()]] on how to specify this parameter.
* @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
* @param object $context the context that the view should use for rendering the view. If null,
* existing [[context]] will be used.
* @return string the rendering result
* @throws InvalidCallException if [[context]] is neither a controller nor a widget.
* @throws InvalidParamException if the view cannot be resolved or the view file does not exist.
* @see renderFile
*/
public
function
render
(
$view
,
$params
=
[])
public
function
render
(
$view
,
$params
=
[]
,
$context
=
null
)
{
if
(
$this
->
context
instanceof
Controller
)
{
return
$this
->
context
->
renderPartial
(
$view
,
$params
);
}
elseif
(
$this
->
context
instanceof
Widget
)
{
return
$this
->
context
->
render
(
$view
,
$params
);
$viewFile
=
$this
->
findViewFile
(
$view
,
$context
);
return
$this
->
renderFile
(
$viewFile
,
$params
,
$context
);
}
/**
* Finds the view file based on the given view name.
* @param string $view the view name or the path alias of the view file. Please refer to [[render()]]
* on how to specify this parameter.
* @param object $context the context that the view should be used to search the view file. If null,
* existing [[context]] will be used.
* @return string the view file path. Note that the file may not exist.
* @throws InvalidCallException if [[context]] is required and invalid.
*/
protected
function
findViewFile
(
$view
,
$context
=
null
)
{
if
(
strncmp
(
$view
,
'@'
,
1
)
===
0
)
{
// e.g. "@app/views/main"
$file
=
Yii
::
getAlias
(
$view
);
}
elseif
(
strncmp
(
$view
,
'//'
,
2
)
===
0
)
{
// e.g. "//layouts/main"
$file
=
Yii
::
$app
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
===
0
)
{
// e.g. "/site/index"
if
(
Yii
::
$app
->
controller
!==
null
)
{
$file
=
Yii
::
$app
->
controller
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
else
{
throw
new
InvalidCallException
(
"Unable to locate view file for view '
$view
': no active controller."
);
}
}
else
{
throw
new
InvalidCallException
(
'View::render() is not supported for the current context.'
);
// context required
if
(
$context
===
null
)
{
$context
=
$this
->
context
;
}
if
(
$context
instanceof
ViewContextInterface
)
{
$file
=
$context
->
findViewFile
(
$view
);
}
else
{
throw
new
InvalidCallException
(
"Unable to locate view file for view '
$view
': no active view context."
);
}
}
return
pathinfo
(
$file
,
PATHINFO_EXTENSION
)
===
''
?
$file
.
'.php'
:
$file
;
}
/**
...
...
@@ -519,7 +556,7 @@ class View extends Component
$this
->
trigger
(
self
::
EVENT_END_PAGE
);
$content
=
ob_get_clean
();
foreach
(
array_keys
(
$this
->
assetBundles
)
as
$bundle
)
{
foreach
(
array_keys
(
$this
->
assetBundles
)
as
$bundle
)
{
$this
->
registerAssetFiles
(
$bundle
);
}
echo
strtr
(
$content
,
[
...
...
@@ -549,7 +586,7 @@ class View extends Component
return
;
}
$bundle
=
$this
->
assetBundles
[
$name
];
foreach
(
$bundle
->
depends
as
$dep
)
{
foreach
(
$bundle
->
depends
as
$dep
)
{
$this
->
registerAssetFiles
(
$dep
);
}
$bundle
->
registerAssetFiles
(
$this
);
...
...
framework/yii/base/ViewContextInterface.php
0 → 100644
View file @
31ea3f89
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\base
;
/**
* ViewContextInterface is the interface that should implemented by classes who want to support relative view names.
*
* The method [[findViewFile()]] should be implemented to convert a relative view name into a file path.
*
* @author Paul Klimov <klimov.paul@gmail.com>
* @since 2.0
*/
interface
ViewContextInterface
{
/**
* Finds the view file corresponding to the specified relative view name.
* @param string $view a relative view name. The name does NOT start with a slash.
* @return string the view file path. Note that the file may not exist.
*/
public
function
findViewFile
(
$view
);
}
framework/yii/base/Widget.php
View file @
31ea3f89
...
...
@@ -8,6 +8,7 @@
namespace
yii\base
;
use
Yii
;
use
ReflectionClass
;
/**
* Widget is the base class for widgets.
...
...
@@ -20,7 +21,7 @@ use Yii;
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Widget
extends
Component
class
Widget
extends
Component
implements
ViewContextInterface
{
/**
* @var integer a counter used to generate [[id]] for widgets.
...
...
@@ -167,8 +168,7 @@ class Widget extends Component
*/
public
function
render
(
$view
,
$params
=
[])
{
$viewFile
=
$this
->
findViewFile
(
$view
);
return
$this
->
getView
()
->
renderFile
(
$viewFile
,
$params
,
$this
);
return
$this
->
getView
()
->
render
(
$view
,
$params
,
$this
);
}
/**
...
...
@@ -190,32 +190,18 @@ class Widget extends Component
*/
public
function
getViewPath
()
{
$className
=
get_class
(
$this
);
$class
=
new
\ReflectionClass
(
$className
);
$class
=
new
ReflectionClass
(
$this
);
return
dirname
(
$class
->
getFileName
())
.
DIRECTORY_SEPARATOR
.
'views'
;
}
/**
* Finds the view file based on the given view name.
*
@param string $view the view name or the path alias of the view file. Please refer to [[render()]]
*
on how to specify this parameter
.
*
File will be searched under [[viewPath]] directory.
*
@param string $view the view name
.
* @return string the view file path. Note that the file may not exist.
*/
p
rotected
function
findViewFile
(
$view
)
p
ublic
function
findViewFile
(
$view
)
{
if
(
strncmp
(
$view
,
'@'
,
1
)
===
0
)
{
// e.g. "@app/views/main"
$file
=
Yii
::
getAlias
(
$view
);
}
elseif
(
strncmp
(
$view
,
'//'
,
2
)
===
0
)
{
// e.g. "//layouts/main"
$file
=
Yii
::
$app
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
elseif
(
strncmp
(
$view
,
'/'
,
1
)
===
0
&&
Yii
::
$app
->
controller
!==
null
)
{
// e.g. "/site/index"
$file
=
Yii
::
$app
->
controller
->
module
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
else
{
$file
=
$this
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
ltrim
(
$view
,
'/'
);
}
return
pathinfo
(
$file
,
PATHINFO_EXTENSION
)
===
''
?
$file
.
'.php'
:
$file
;
return
$this
->
getViewPath
()
.
DIRECTORY_SEPARATOR
.
$view
;
}
}
framework/yii/caching/Cache.php
View file @
31ea3f89
...
...
@@ -192,7 +192,7 @@ abstract class Cache extends Component implements \ArrayAccess
* If the cache already contains such a key, the existing value and
* expiration time will be replaced with the new ones, respectively.
*
* @param mixed $key a key identifying the value to be cached
value
. This can be a simple string or
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
...
...
@@ -218,7 +218,7 @@ abstract class Cache extends Component implements \ArrayAccess
/**
* Stores a value identified by a key into cache if the cache does not contain this key.
* Nothing will be done if the cache already contains the key.
* @param mixed $key a key identifying the value to be cached
value
. This can be a simple string or
* @param mixed $key a key identifying the value to be cached. This can be a simple string or
* a complex data structure consisting of factors representing the key.
* @param mixed $value the value to be cached
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
...
...
framework/yii/caching/RedisCache.php
View file @
31ea3f89
...
...
@@ -139,7 +139,7 @@ class RedisCache extends Cache
$response
=
$this
->
_connection
->
executeCommand
(
'MGET'
,
$keys
);
$result
=
[];
$i
=
0
;
foreach
(
$keys
as
$key
)
{
foreach
(
$keys
as
$key
)
{
$result
[
$key
]
=
$response
[
$i
++
];
}
return
$result
;
...
...
framework/yii/data/ActiveDataProvider.php
View file @
31ea3f89
...
...
@@ -170,7 +170,7 @@ class ActiveDataProvider extends BaseDataProvider
if
((
$sort
=
$this
->
getSort
())
!==
false
&&
empty
(
$sort
->
attributes
)
&&
$this
->
query
instanceof
ActiveQuery
)
{
/** @var Model $model */
$model
=
new
$this
->
query
->
modelClass
;
foreach
(
$model
->
attributes
()
as
$attribute
)
{
foreach
(
$model
->
attributes
()
as
$attribute
)
{
$sort
->
attributes
[
$attribute
]
=
[
'asc'
=>
[
$attribute
=>
Sort
::
ASC
],
'desc'
=>
[
$attribute
=>
Sort
::
DESC
],
...
...
framework/yii/db/cubrid/Schema.php
View file @
31ea3f89
...
...
@@ -147,7 +147,7 @@ class Schema extends \yii\db\Schema
}
$foreignKeys
=
$this
->
db
->
pdo
->
cubrid_schema
(
\PDO
::
CUBRID_SCH_IMPORTED_KEYS
,
$table
->
name
);
foreach
(
$foreignKeys
as
$key
)
{
foreach
(
$foreignKeys
as
$key
)
{
if
(
isset
(
$table
->
foreignKeys
[
$key
[
'FK_NAME'
]]))
{
$table
->
foreignKeys
[
$key
[
'FK_NAME'
]][
$key
[
'FKCOLUMN_NAME'
]]
=
$key
[
'PKCOLUMN_NAME'
];
}
else
{
...
...
@@ -230,7 +230,7 @@ class Schema extends \yii\db\Schema
$this
->
db
->
open
();
$tables
=
$this
->
db
->
pdo
->
cubrid_schema
(
\PDO
::
CUBRID_SCH_TABLE
);
$tableNames
=
[];
foreach
(
$tables
as
$table
)
{
foreach
(
$tables
as
$table
)
{
// do not list system tables
if
(
$table
[
'TYPE'
]
!=
0
)
{
$tableNames
[]
=
$table
[
'NAME'
];
...
...
framework/yii/db/pgsql/Schema.php
View file @
31ea3f89
...
...
@@ -34,6 +34,7 @@ class Schema extends \yii\db\Schema
public
$typeMap
=
[
'abstime'
=>
self
::
TYPE_TIMESTAMP
,
'bit'
=>
self
::
TYPE_STRING
,
'bool'
=>
self
::
TYPE_BOOLEAN
,
'boolean'
=>
self
::
TYPE_BOOLEAN
,
'box'
=>
self
::
TYPE_STRING
,
'character'
=>
self
::
TYPE_STRING
,
...
...
framework/yii/gii/generators/form/templates/action.php
View file @
31ea3f89
...
...
@@ -17,7 +17,7 @@ public function action<?= Inflector::id2camel(trim(basename($generator->viewName
$model = new
<?=
$generator
->
modelClass
?><?=
empty
(
$generator
->
scenarioName
)
?
""
:
"(['scenario' => '
{
$generator
->
scenarioName
}
'])"
?>
;
if ($model->load($_POST)) {
if($model->validate()) {
if
($model->validate()) {
// form inputs are valid, do something here
return;
}
...
...
framework/yii/gii/views/default/view.php
View file @
31ea3f89
...
...
@@ -34,19 +34,19 @@ foreach ($generator->templates as $name => $path) {
]);
?>
<div
class=
"row"
>
<div
class=
"col-lg-8"
>
<?=
$this
->
renderFile
(
$generator
->
formView
(),
[
<?=
$this
->
renderFile
(
$generator
->
formView
(),
[
'generator'
=>
$generator
,
'form'
=>
$form
,
])
;
?>
<?=
$form
->
field
(
$generator
,
'template'
)
->
sticky
()
])
?>
<?=
$form
->
field
(
$generator
,
'template'
)
->
sticky
()
->
label
(
'Code Template'
)
->
dropDownList
(
$templates
)
->
hint
(
'
Please select which set of the templates should be used to generated the code.
'
)
;
?>
'
)
?>
<div
class=
"form-group"
>
<?=
Html
::
submitButton
(
'Preview'
,
[
'name'
=>
'preview'
,
'class'
=>
'btn btn-primary'
])
?>
<?php
if
(
isset
(
$files
))
:
?>
<?php
if
(
isset
(
$files
))
:
?>
<?=
Html
::
submitButton
(
'Generate'
,
[
'name'
=>
'generate'
,
'class'
=>
'btn btn-success'
])
?>
<?php
endif
;
?>
</div>
...
...
framework/yii/i18n/FallbackMessageFormatter.php
deleted
100644 → 0
View file @
2d537704
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\i18n
;
use
yii\base\NotSupportedException
;
/**
* FallbackMessageFormatter is a fallback implementation for the PHP intl MessageFormatter that is
* used in case PHP intl extension is not installed.
*
* Do not use this class directly. Use [[MessageFormatter]] instead, which will automatically detect
* installed version of PHP intl and use the fallback if it is not installed.
*
* It is highly recommended that you install [PHP intl extension](http://php.net/manual/en/book.intl.php) if you want to use
* MessageFormatter features.
*
* This implementation only supports to following message formats:
* - plural formatting for english
* - select format
* - simple parameters
*
* The pattern also does NOT support the ['apostrophe-friendly' syntax](http://www.php.net/manual/en/messageformatter.formatmessage.php).
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class
FallbackMessageFormatter
{
private
$_locale
;
private
$_pattern
;
private
$_errorMessage
=
''
;
private
$_errorCode
=
0
;
/**
* Constructs a new Message Formatter
* @link http://php.net/manual/en/messageformatter.create.php
* @param string $locale The locale to use when formatting arguments
* @param string $pattern The pattern string to stick arguments into.
*/
public
function
__construct
(
$locale
,
$pattern
)
{
$this
->
_locale
=
$locale
;
$this
->
_pattern
=
$pattern
;
}
/**
* Constructs a new Message Formatter
* @link http://php.net/manual/en/messageformatter.create.php
* @param string $locale The locale to use when formatting arguments
* @param string $pattern The pattern string to stick arguments into.
* @return MessageFormatter The formatter object
*/
public
static
function
create
(
$locale
,
$pattern
)
{
return
new
static
(
$locale
,
$pattern
);
}
/**
* Format the message
* @link http://php.net/manual/en/messageformatter.format.php
* @param array $args Arguments to insert into the format string
* @return string The formatted string, or `FALSE` if an error occurred
*/
public
function
format
(
$args
)
{
return
static
::
formatMessage
(
$this
->
_locale
,
$this
->
_pattern
,
$args
);
}
/**
* Quick format message
* @link http://php.net/manual/en/messageformatter.formatmessage.php
* @param string $locale The locale to use for formatting locale-dependent parts
* @param string $pattern The pattern string to insert things into.
* @param array $args The array of values to insert into the format string
* @return string The formatted pattern string or `FALSE` if an error occurred
*/
public
static
function
formatMessage
(
$locale
,
$pattern
,
$args
)
{
if
((
$tokens
=
static
::
tokenizePattern
(
$pattern
))
===
false
)
{
return
false
;
}
foreach
(
$tokens
as
$i
=>
$token
)
{
if
(
is_array
(
$token
))
{
if
((
$tokens
[
$i
]
=
static
::
parseToken
(
$token
,
$args
,
$locale
))
===
false
)
{
return
false
;
}
}
}
return
implode
(
''
,
$tokens
);
}
/**
* Tokenizes a pattern by separating normal text from replaceable patterns
* @param string $pattern patter to tokenize
* @return array|bool array of tokens or false on failure
*/
private
static
function
tokenizePattern
(
$pattern
)
{
$depth
=
1
;
if
((
$start
=
$pos
=
mb_strpos
(
$pattern
,
'{'
))
===
false
)
{
return
[
$pattern
];
}
$tokens
=
[
mb_substr
(
$pattern
,
0
,
$pos
)];
while
(
true
)
{
$open
=
mb_strpos
(
$pattern
,
'{'
,
$pos
+
1
);
$close
=
mb_strpos
(
$pattern
,
'}'
,
$pos
+
1
);
if
(
$open
===
false
&&
$close
===
false
)
{
break
;
}
if
(
$open
===
false
)
{
$open
=
mb_strlen
(
$pattern
);
}
if
(
$close
>
$open
)
{
$depth
++
;
$pos
=
$open
;
}
else
{
$depth
--
;
$pos
=
$close
;
}
if
(
$depth
==
0
)
{
$tokens
[]
=
explode
(
','
,
mb_substr
(
$pattern
,
$start
+
1
,
$pos
-
$start
-
1
),
3
);
$start
=
$pos
+
1
;
$tokens
[]
=
mb_substr
(
$pattern
,
$start
,
$open
-
$start
);
$start
=
$open
;
}
}
if
(
$depth
!=
0
)
{
return
false
;
}
return
$tokens
;
}
/**
* Parses a token
* @param array $token the token to parse
* @param array $args arguments to replace
* @param string $locale the locale
* @return bool|string parsed token or false on failure
* @throws \yii\base\NotSupportedException when unsupported formatting is used.
*/
private
static
function
parseToken
(
$token
,
$args
,
$locale
)
{
$param
=
trim
(
$token
[
0
]);
if
(
isset
(
$args
[
$param
]))
{
$arg
=
$args
[
$param
];
}
else
{
return
'{'
.
implode
(
','
,
$token
)
.
'}'
;
}
$type
=
isset
(
$token
[
1
])
?
trim
(
$token
[
1
])
:
'none'
;
switch
(
$type
)
{
case
'number'
:
case
'date'
:
case
'time'
:
case
'spellout'
:
case
'ordinal'
:
case
'duration'
:
case
'choice'
:
case
'selectordinal'
:
throw
new
NotSupportedException
(
"Message format '
$type
' is not supported. You have to install PHP intl extension to use this feature."
);
case
'none'
:
return
$arg
;
case
'select'
:
/* http://icu-project.org/apiref/icu4c/classicu_1_1SelectFormat.html
selectStyle = (selector '{' message '}')+
*/
$select
=
static
::
tokenizePattern
(
$token
[
2
]);
$c
=
count
(
$select
);
$message
=
false
;
for
(
$i
=
0
;
$i
+
1
<
$c
;
$i
++
)
{
if
(
is_array
(
$select
[
$i
])
||
!
is_array
(
$select
[
$i
+
1
]))
{
return
false
;
}
$selector
=
trim
(
$select
[
$i
++
]);
if
(
$message
===
false
&&
$selector
==
'other'
||
$selector
==
$arg
)
{
$message
=
implode
(
','
,
$select
[
$i
]);
}
}
if
(
$message
!==
false
)
{
return
static
::
formatMessage
(
$locale
,
$message
,
$args
);
}
break
;
case
'plural'
:
/* http://icu-project.org/apiref/icu4c/classicu_1_1PluralFormat.html
pluralStyle = [offsetValue] (selector '{' message '}')+
offsetValue = "offset:" number
selector = explicitValue | keyword
explicitValue = '=' number // adjacent, no white space in between
keyword = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
message: see MessageFormat
*/
$plural
=
static
::
tokenizePattern
(
$token
[
2
]);
$c
=
count
(
$plural
);
$message
=
false
;
$offset
=
0
;
for
(
$i
=
0
;
$i
+
1
<
$c
;
$i
++
)
{
if
(
is_array
(
$plural
[
$i
])
||
!
is_array
(
$plural
[
$i
+
1
]))
{
return
false
;
}
$selector
=
trim
(
$plural
[
$i
++
]);
if
(
$i
==
1
&&
substr
(
$selector
,
0
,
7
)
==
'offset:'
)
{
$offset
=
(
int
)
trim
(
mb_substr
(
$selector
,
7
,
(
$pos
=
mb_strpos
(
str_replace
([
"
\n
"
,
"
\r
"
,
"
\t
"
],
' '
,
$selector
),
' '
,
7
))
-
7
));
$selector
=
trim
(
mb_substr
(
$selector
,
$pos
+
1
));
}
if
(
$message
===
false
&&
$selector
==
'other'
||
$selector
[
0
]
==
'='
&&
(
int
)
mb_substr
(
$selector
,
1
)
==
$arg
||
$selector
==
'zero'
&&
$arg
-
$offset
==
0
||
$selector
==
'one'
&&
$arg
-
$offset
==
1
||
$selector
==
'two'
&&
$arg
-
$offset
==
2
)
{
$message
=
implode
(
','
,
str_replace
(
'#'
,
$arg
-
$offset
,
$plural
[
$i
]));
}
}
if
(
$message
!==
false
)
{
return
static
::
formatMessage
(
$locale
,
$message
,
$args
);
}
break
;
}
return
false
;
}
/**
* Parse input string according to pattern
* @link http://php.net/manual/en/messageformatter.parse.php
* @param string $value The string to parse
* @return array An array containing the items extracted, or `FALSE` on error
*/
public
function
parse
(
$value
)
{
throw
new
NotSupportedException
(
'You have to install PHP intl extension to use this feature.'
);
}
/**
* Quick parse input string
* @link http://php.net/manual/en/messageformatter.parsemessage.php
* @param string $locale The locale to use for parsing locale-dependent parts
* @param string $pattern The pattern with which to parse the `value`.
* @param string $source The string to parse, conforming to the `pattern`.
* @return array An array containing items extracted, or `FALSE` on error
*/
public
static
function
parseMessage
(
$locale
,
$pattern
,
$source
)
{
throw
new
NotSupportedException
(
'You have to install PHP intl extension to use this feature.'
);
}
/**
* Set the pattern used by the formatter
* @link http://php.net/manual/en/messageformatter.setpattern.php
* @param string $pattern The pattern string to use in this message formatter.
* @return bool `TRUE` on success or `FALSE` on failure.
*/
public
function
setPattern
(
$pattern
)
{
$this
->
_pattern
=
$pattern
;
return
true
;
}
/**
* Get the pattern used by the formatter
* @link http://php.net/manual/en/messageformatter.getpattern.php
* @return string The pattern string for this message formatter
*/
public
function
getPattern
()
{
return
$this
->
_pattern
;
}
/**
* Get the locale for which the formatter was created.
* @link http://php.net/manual/en/messageformatter.getlocale.php
* @return string The locale name
*/
public
function
getLocale
()
{
return
$this
->
_locale
;
}
/**
* Get the error code from last operation
* @link http://php.net/manual/en/messageformatter.geterrorcode.php
* @return int The error code, one of UErrorCode values. Initial value is U_ZERO_ERROR.
*/
public
function
getErrorCode
()
{
return
$this
->
_errorCode
;
}
/**
* Get the error text from the last operation
* @link http://php.net/manual/en/messageformatter.geterrormessage.php
* @return string Description of the last error.
*/
public
function
getErrorMessage
()
{
return
$this
->
_errorMessage
;
}
}
if
(
!
class_exists
(
'MessageFormatter'
,
false
))
{
class_alias
(
'yii\\i18n\\FallbackMessageFormatter'
,
'MessageFormatter'
);
define
(
'YII_INTL_MESSAGE_FALLBACK'
,
true
);
}
framework/yii/i18n/I18N.php
View file @
31ea3f89
...
...
@@ -14,6 +14,10 @@ use yii\base\InvalidConfigException;
/**
* I18N provides features related with internationalization (I18N) and localization (L10N).
*
* @property MessageFormatter $messageFormatter The message formatter to be used to format message via ICU
* message format. Note that the type of this property differs in getter and setter. See
* [[getMessageFormatter()]] and [[setMessageFormatter()]] for details.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
...
...
@@ -69,7 +73,7 @@ class I18N extends Component
* @param string $message the message to be translated.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
* @param string $language the language code (e.g. `en_US`, `en`).
* @return string the translated message.
* @return string the translated
and formatted
message.
*/
public
function
translate
(
$category
,
$message
,
$params
,
$language
)
{
...
...
@@ -78,7 +82,7 @@ class I18N extends Component
}
/**
* Formats a message using
using
[[MessageFormatter]].
* Formats a message using [[MessageFormatter]].
*
* @param string $message the message to be formatted.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
...
...
@@ -93,12 +97,8 @@ class I18N extends Component
}
if
(
preg_match
(
'~{\s*[\d\w]+\s*,~u'
,
$message
))
{
$formatter
=
new
MessageFormatter
(
$language
,
$message
);
if
(
$formatter
===
null
)
{
Yii
::
warning
(
"Unable to format message in language '
$language
':
$message
."
);
return
$message
;
}
$result
=
$formatter
->
format
(
$params
);
$formatter
=
$this
->
getMessageFormatter
();
$result
=
$formatter
->
format
(
$message
,
$params
,
$language
);
if
(
$result
===
false
)
{
$errorMessage
=
$formatter
->
getErrorMessage
();
Yii
::
warning
(
"Formatting message for language '
$language
' failed with error:
$errorMessage
. The message being formatted was:
$message
."
);
...
...
@@ -116,6 +116,35 @@ class I18N extends Component
}
/**
* @var string|array|MessageFormatter
*/
private
$_messageFormatter
;
/**
* Returns the message formatter instance.
* @return MessageFormatter the message formatter to be used to format message via ICU message format.
*/
public
function
getMessageFormatter
()
{
if
(
$this
->
_messageFormatter
===
null
)
{
$this
->
_messageFormatter
=
new
MessageFormatter
();
}
elseif
(
is_array
(
$this
->
_messageFormatter
)
||
is_string
(
$this
->
_messageFormatter
))
{
$this
->
_messageFormatter
=
Yii
::
createObject
(
$this
->
_messageFormatter
);
}
return
$this
->
_messageFormatter
;
}
/**
* @param string|array|MessageFormatter $value the message formatter to be used to format message via ICU message format.
* Can be given as array or string configuration that will be given to [[Yii::createObject]] to create an instance
* or a [[MessageFormatter]] instance.
*/
public
function
setMessageFormatter
(
$value
)
{
$this
->
_messageFormatter
=
$value
;
}
/**
* Returns the message source for the given category.
* @param string $category the category name.
* @return MessageSource the message source for the given category.
...
...
framework/yii/i18n/MessageFormatter.php
View file @
31ea3f89
...
...
@@ -7,17 +7,17 @@
namespace
yii\i18n
;
if
(
!
class_exists
(
'MessageFormatter'
,
false
))
{
require_once
(
__DIR__
.
'/FallbackMessageFormatter.php'
);
}
defined
(
'YII_INTL_MESSAGE_FALLBACK'
)
||
define
(
'YII_INTL_MESSAGE_FALLBACK'
,
false
);
use
yii\base\Component
;
use
yii\base\NotSupportedException
;
/**
* MessageFormatter enhances the message formatter class provided by PHP intl extension.
* MessageFormatter allows formatting messages via [ICU message format](http://userguide.icu-project.org/formatparse/messages)
*
* This class enhances the message formatter class provided by the PHP intl extension.
*
* The following enhancements are provided:
*
* -
A
ccepts named arguments and mixed numeric and named arguments.
* -
It a
ccepts named arguments and mixed numeric and named arguments.
* - Issues no error when an insufficient number of arguments have been provided. Instead, the placeholders will not be
* substituted.
* - Fixes PHP 5.5 weird placeholder replacement in case no arguments are provided at all (https://bugs.php.net/bug.php?id=65920).
...
...
@@ -25,53 +25,151 @@ defined('YII_INTL_MESSAGE_FALLBACK') || define('YII_INTL_MESSAGE_FALLBACK', fals
* However it is highly recommended that you install [PHP intl extension](http://php.net/manual/en/book.intl.php) if you want
* to use MessageFormatter features.
*
* The fallback implementation only supports the following message formats:
* - plural formatting for english
* - select format
* - simple parameters
* - integer number parameters
*
* The fallback implementation does NOT support the ['apostrophe-friendly' syntax](http://www.php.net/manual/en/messageformatter.formatmessage.php).
* Also messages that are working with the fallback implementation are not necessarily compatible with the
* PHP intl MessageFormatter so do not rely on the fallback if you are able to install intl extension somehow.
*
* @property string $errorCode Code of the last error. This property is read-only.
* @property string $errorMessage Description of the last error. This property is read-only.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class
MessageFormatter
extends
\MessageFormatter
class
MessageFormatter
extends
Component
{
private
$_errorCode
=
0
;
private
$_errorMessage
=
''
;
/**
* Format the message.
* Get the error code from the last operation
* @link http://php.net/manual/en/messageformatter.geterrorcode.php
* @return string Code of the last error.
*/
public
function
getErrorCode
()
{
return
$this
->
_errorCode
;
}
/**
* Get the error text from the last operation
* @link http://php.net/manual/en/messageformatter.geterrormessage.php
* @return string Description of the last error.
*/
public
function
getErrorMessage
()
{
return
$this
->
_errorMessage
;
}
/**
* Formats a message via [ICU message format](http://userguide.icu-project.org/formatparse/messages)
*
* It uses the PHP intl extension's [MessageFormatter](http://www.php.net/manual/en/class.messageformatter.php)
* and works around some issues.
* If PHP intl is not installed a fallback will be used that supports a subset of the ICU message format.
*
* @link http://php.net/manual/en/messageformatter.format.php
* @param array $args Arguments to insert into the format string.
* @return string|boolean The formatted string, or false if an error occurred.
* @param string $pattern The pattern string to insert parameters into.
* @param array $params The array of name value pairs to insert into the format string.
* @param string $language The locale to use for formatting locale-dependent parts
* @return string|boolean The formatted pattern string or `FALSE` if an error occurred
*/
public
function
format
(
$
args
)
public
function
format
(
$
pattern
,
$params
,
$language
)
{
if
(
$args
===
[])
{
return
$this
->
getPattern
();
$this
->
_errorCode
=
0
;
$this
->
_errorMessage
=
''
;
if
(
$params
===
[])
{
return
$pattern
;
}
if
(
version_compare
(
PHP_VERSION
,
'5.5.0'
,
'<'
)
&&
!
YII_INTL_MESSAGE_FALLBACK
)
{
$pattern
=
self
::
replaceNamedArguments
(
$this
->
getPattern
(),
$args
);
$this
->
setPattern
(
$pattern
);
$args
=
array_values
(
$args
);
if
(
!
class_exists
(
'MessageFormatter'
,
false
))
{
return
$this
->
fallbackFormat
(
$pattern
,
$params
,
$language
);
}
if
(
version_compare
(
PHP_VERSION
,
'5.5.0'
,
'<'
))
{
$pattern
=
$this
->
replaceNamedArguments
(
$pattern
,
$params
);
$params
=
array_values
(
$params
);
}
$formatter
=
new
\MessageFormatter
(
$language
,
$pattern
);
if
(
$formatter
===
null
)
{
$this
->
_errorCode
=
-
1
;
$this
->
_errorMessage
=
"Message pattern is invalid."
;
return
false
;
}
$result
=
$formatter
->
format
(
$params
);
if
(
$result
===
false
)
{
$this
->
_errorCode
=
$formatter
->
getErrorCode
();
$this
->
_errorMessage
=
$formatter
->
getErrorMessage
();
return
false
;
}
else
{
return
$result
;
}
return
parent
::
format
(
$args
);
}
/**
*
Quick format message
.
*
Parses an input string according to an [ICU message format](http://userguide.icu-project.org/formatparse/messages) pattern
.
*
* @link http://php.net/manual/en/messageformatter.formatmessage.php
* @param string $locale The locale to use for formatting locale-dependent parts.
* @param string $pattern The pattern string to insert things into.
* @param array $args The array of values to insert into the format string.
* @return string|boolean The formatted pattern string or false if an error occurred.
* It uses the PHP intl extension's [MessageFormatter::parse()](http://www.php.net/manual/en/messageformatter.parsemessage.php)
* and adds support for named arguments.
* Usage of this method requires PHP intl extension to be installed.
*
* @param string $pattern The pattern to use for parsing the message.
* @param string $message The message to parse, conforming to the pattern.
* @param string $language The locale to use for formatting locale-dependent parts
* @return array|boolean An array containing items extracted, or `FALSE` on error.
* @throws \yii\base\NotSupportedException when PHP intl extension is not installed.
*/
public
static
function
formatMessage
(
$locale
,
$pattern
,
$args
)
public
function
parse
(
$pattern
,
$message
,
$language
)
{
if
(
$args
===
[])
{
return
$pattern
;
$this
->
_errorCode
=
0
;
$this
->
_errorMessage
=
''
;
if
(
!
class_exists
(
'MessageFormatter'
,
false
))
{
throw
new
NotSupportedException
(
'You have to install PHP intl extension to use this feature.'
);
}
if
(
version_compare
(
PHP_VERSION
,
'5.5.0'
,
'<'
)
&&
!
YII_INTL_MESSAGE_FALLBACK
)
{
$pattern
=
self
::
replaceNamedArguments
(
$pattern
,
$args
);
$args
=
array_values
(
$args
);
// replace named arguments
if
((
$tokens
=
$this
->
tokenizePattern
(
$pattern
))
===
false
)
{
return
false
;
}
$map
=
[];
foreach
(
$tokens
as
$i
=>
$token
)
{
if
(
is_array
(
$token
))
{
$param
=
trim
(
$token
[
0
]);
if
(
!
isset
(
$map
[
$param
]))
{
$map
[
$param
]
=
count
(
$map
);
}
$token
[
0
]
=
$map
[
$param
];
$tokens
[
$i
]
=
'{'
.
implode
(
','
,
$token
)
.
'}'
;
}
}
$pattern
=
implode
(
''
,
$tokens
);
$map
=
array_flip
(
$map
);
$formatter
=
new
\MessageFormatter
(
$language
,
$pattern
);
if
(
$formatter
===
null
)
{
$this
->
_errorCode
=
-
1
;
$this
->
_errorMessage
=
"Message pattern is invalid."
;
return
false
;
}
$result
=
$formatter
->
parse
(
$message
);
if
(
$result
===
false
)
{
$this
->
_errorCode
=
$formatter
->
getErrorCode
();
$this
->
_errorMessage
=
$formatter
->
getErrorMessage
();
return
false
;
}
else
{
$values
=
[];
foreach
(
$result
as
$key
=>
$value
)
{
$values
[
$map
[
$key
]]
=
$value
;
}
return
$values
;
}
return
parent
::
formatMessage
(
$locale
,
$pattern
,
$args
);
}
/**
...
...
@@ -92,7 +190,7 @@ class MessageFormatter extends \MessageFormatter
$pattern
=
$parts
[
0
];
$d
=
0
;
$stack
=
[];
for
(
$i
=
1
;
$i
<
$c
;
$i
++
)
{
for
(
$i
=
1
;
$i
<
$c
;
$i
++
)
{
if
(
preg_match
(
'~^(\s*)([\d\w]+)(\s*)([},])(\s*)(.*)$~us'
,
$parts
[
$i
],
$matches
))
{
// if we are not inside a plural or select this is a message
if
(
!
isset
(
$stack
[
$d
])
||
$stack
[
$d
]
!=
'plural'
&&
$stack
[
$d
]
!=
'select'
)
{
...
...
@@ -124,4 +222,159 @@ class MessageFormatter extends \MessageFormatter
}
return
$pattern
;
}
/**
* Fallback implementation for MessageFormatter::formatMessage
* @param string $pattern The pattern string to insert things into.
* @param array $args The array of values to insert into the format string
* @param string $locale The locale to use for formatting locale-dependent parts
* @return string|boolean The formatted pattern string or `FALSE` if an error occurred
*/
protected
function
fallbackFormat
(
$pattern
,
$args
,
$locale
)
{
if
((
$tokens
=
$this
->
tokenizePattern
(
$pattern
))
===
false
)
{
return
false
;
}
foreach
(
$tokens
as
$i
=>
$token
)
{
if
(
is_array
(
$token
))
{
if
((
$tokens
[
$i
]
=
$this
->
parseToken
(
$token
,
$args
,
$locale
))
===
false
)
{
return
false
;
}
}
}
return
implode
(
''
,
$tokens
);
}
/**
* Tokenizes a pattern by separating normal text from replaceable patterns
* @param string $pattern patter to tokenize
* @return array|bool array of tokens or false on failure
*/
private
function
tokenizePattern
(
$pattern
)
{
$depth
=
1
;
if
((
$start
=
$pos
=
mb_strpos
(
$pattern
,
'{'
))
===
false
)
{
return
[
$pattern
];
}
$tokens
=
[
mb_substr
(
$pattern
,
0
,
$pos
)];
while
(
true
)
{
$open
=
mb_strpos
(
$pattern
,
'{'
,
$pos
+
1
);
$close
=
mb_strpos
(
$pattern
,
'}'
,
$pos
+
1
);
if
(
$open
===
false
&&
$close
===
false
)
{
break
;
}
if
(
$open
===
false
)
{
$open
=
mb_strlen
(
$pattern
);
}
if
(
$close
>
$open
)
{
$depth
++
;
$pos
=
$open
;
}
else
{
$depth
--
;
$pos
=
$close
;
}
if
(
$depth
==
0
)
{
$tokens
[]
=
explode
(
','
,
mb_substr
(
$pattern
,
$start
+
1
,
$pos
-
$start
-
1
),
3
);
$start
=
$pos
+
1
;
$tokens
[]
=
mb_substr
(
$pattern
,
$start
,
$open
-
$start
);
$start
=
$open
;
}
}
if
(
$depth
!=
0
)
{
return
false
;
}
return
$tokens
;
}
/**
* Parses a token
* @param array $token the token to parse
* @param array $args arguments to replace
* @param string $locale the locale
* @return bool|string parsed token or false on failure
* @throws \yii\base\NotSupportedException when unsupported formatting is used.
*/
private
function
parseToken
(
$token
,
$args
,
$locale
)
{
$param
=
trim
(
$token
[
0
]);
if
(
isset
(
$args
[
$param
]))
{
$arg
=
$args
[
$param
];
}
else
{
return
'{'
.
implode
(
','
,
$token
)
.
'}'
;
}
$type
=
isset
(
$token
[
1
])
?
trim
(
$token
[
1
])
:
'none'
;
switch
(
$type
)
{
case
'date'
:
case
'time'
:
case
'spellout'
:
case
'ordinal'
:
case
'duration'
:
case
'choice'
:
case
'selectordinal'
:
throw
new
NotSupportedException
(
"Message format '
$type
' is not supported. You have to install PHP intl extension to use this feature."
);
case
'number'
:
if
(
is_int
(
$arg
)
&&
(
!
isset
(
$token
[
2
])
||
trim
(
$token
[
2
])
==
'integer'
))
{
return
$arg
;
}
throw
new
NotSupportedException
(
"Message format 'number' is only supported for integer values. You have to install PHP intl extension to use this feature."
);
case
'none'
:
return
$arg
;
case
'select'
:
/* http://icu-project.org/apiref/icu4c/classicu_1_1SelectFormat.html
selectStyle = (selector '{' message '}')+
*/
$select
=
static
::
tokenizePattern
(
$token
[
2
]);
$c
=
count
(
$select
);
$message
=
false
;
for
(
$i
=
0
;
$i
+
1
<
$c
;
$i
++
)
{
if
(
is_array
(
$select
[
$i
])
||
!
is_array
(
$select
[
$i
+
1
]))
{
return
false
;
}
$selector
=
trim
(
$select
[
$i
++
]);
if
(
$message
===
false
&&
$selector
==
'other'
||
$selector
==
$arg
)
{
$message
=
implode
(
','
,
$select
[
$i
]);
}
}
if
(
$message
!==
false
)
{
return
$this
->
fallbackFormat
(
$message
,
$args
,
$locale
);
}
break
;
case
'plural'
:
/* http://icu-project.org/apiref/icu4c/classicu_1_1PluralFormat.html
pluralStyle = [offsetValue] (selector '{' message '}')+
offsetValue = "offset:" number
selector = explicitValue | keyword
explicitValue = '=' number // adjacent, no white space in between
keyword = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
message: see MessageFormat
*/
$plural
=
static
::
tokenizePattern
(
$token
[
2
]);
$c
=
count
(
$plural
);
$message
=
false
;
$offset
=
0
;
for
(
$i
=
0
;
$i
+
1
<
$c
;
$i
++
)
{
if
(
is_array
(
$plural
[
$i
])
||
!
is_array
(
$plural
[
$i
+
1
]))
{
return
false
;
}
$selector
=
trim
(
$plural
[
$i
++
]);
if
(
$i
==
1
&&
substr
(
$selector
,
0
,
7
)
==
'offset:'
)
{
$offset
=
(
int
)
trim
(
mb_substr
(
$selector
,
7
,
(
$pos
=
mb_strpos
(
str_replace
([
"
\n
"
,
"
\r
"
,
"
\t
"
],
' '
,
$selector
),
' '
,
7
))
-
7
));
$selector
=
trim
(
mb_substr
(
$selector
,
$pos
+
1
));
}
if
(
$message
===
false
&&
$selector
==
'other'
||
$selector
[
0
]
==
'='
&&
(
int
)
mb_substr
(
$selector
,
1
)
==
$arg
||
$selector
==
'zero'
&&
$arg
-
$offset
==
0
||
$selector
==
'one'
&&
$arg
-
$offset
==
1
||
$selector
==
'two'
&&
$arg
-
$offset
==
2
)
{
$message
=
implode
(
','
,
str_replace
(
'#'
,
$arg
-
$offset
,
$plural
[
$i
]));
}
}
if
(
$message
!==
false
)
{
return
$this
->
fallbackFormat
(
$message
,
$args
,
$locale
);
}
break
;
}
return
false
;
}
}
framework/yii/log/Logger.php
View file @
31ea3f89
...
...
@@ -65,8 +65,8 @@ use yii\base\InvalidConfigException;
* second element the total time spent in SQL execution. This property is read-only.
* @property float $elapsedTime The total elapsed time in seconds for current request. This property is
* read-only.
* @property array $profiling The profiling results. Each array element has the following structure:
*
`[$token,
$category, $time]`. This property is read-only.
* @property array $profiling The profiling results. Each array element has the following structure:
`[$token,
* $category, $time]`. This property is read-only.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
...
...
framework/yii/redis/Connection.php
View file @
31ea3f89
...
...
@@ -384,7 +384,7 @@ class Connection extends Component
private
function
parseResponse
(
$command
)
{
if
((
$line
=
fgets
(
$this
->
_socket
))
===
false
)
{
if
((
$line
=
fgets
(
$this
->
_socket
))
===
false
)
{
throw
new
Exception
(
"Failed to read from socket.
\n
Redis command was: "
.
$command
);
}
$type
=
$line
[
0
];
...
...
@@ -405,7 +405,7 @@ class Connection extends Component
$length
=
$line
+
2
;
$data
=
''
;
while
(
$length
>
0
)
{
if
((
$block
=
fread
(
$this
->
_socket
,
$line
+
2
))
===
false
)
{
if
((
$block
=
fread
(
$this
->
_socket
,
$line
+
2
))
===
false
)
{
throw
new
Exception
(
"Failed to read from socket.
\n
Redis command was: "
.
$command
);
}
$data
.=
$block
;
...
...
@@ -415,7 +415,7 @@ class Connection extends Component
case
'*'
:
// Multi-bulk replies
$count
=
(
int
)
$line
;
$data
=
[];
for
(
$i
=
0
;
$i
<
$count
;
$i
++
)
{
for
(
$i
=
0
;
$i
<
$count
;
$i
++
)
{
$data
[]
=
$this
->
parseResponse
(
$command
);
}
return
$data
;
...
...
framework/yii/views/errorHandler/exception.php
View file @
31ea3f89
...
...
@@ -367,8 +367,8 @@ pre .diff .change{
<ul>
<?=
$handler
->
renderCallStackItem
(
$exception
->
getFile
(),
$exception
->
getLine
(),
null
,
null
,
1
)
?>
<?php
for
(
$i
=
0
,
$trace
=
$exception
->
getTrace
(),
$length
=
count
(
$trace
);
$i
<
$length
;
++
$i
)
:
?>
<?=
$handler
->
renderCallStackItem
(
@
$trace
[
$i
][
'file'
]
?:
null
,
@
$trace
[
$i
][
'line'
]
?:
null
,
@
$trace
[
$i
][
'class'
]
?:
null
,
@
$trace
[
$i
][
'function'
]
?:
null
,
$i
+
2
)
;
?>
<?=
$handler
->
renderCallStackItem
(
@
$trace
[
$i
][
'file'
]
?:
null
,
@
$trace
[
$i
][
'line'
]
?:
null
,
@
$trace
[
$i
][
'class'
]
?:
null
,
@
$trace
[
$i
][
'function'
]
?:
null
,
$i
+
2
)
?>
<?php
endfor
;
?>
</ul>
</div>
...
...
tests/README.md
0 → 100644
View file @
31ea3f89
Yii 2.0 Unit tests
==================
DIRECTORY STRUCTURE
-------------------
unit/ Unit tests to run with PHPUnit
data/ models, config and other test data
config.php this file contains configuration for database and caching backends
framework/ the framework unit tests
runtime/ the application runtime dir for the yii test app
web/ webapp for functional testing
HOW TO RUN THE TESTS
--------------------
Make sure you have PHPUnit installed.
Run PHPUnit in the yii repo base directory.
```
php
phpunit
```
You can run tests for specific groups only:
```
php
phpunit
--
group
=
mysql
,
base
,
i18n
```
You can get a list of available groups via
`phpunit --list-groups`
.
TEST CONFIGURATION
------------------
PHPUnit configuration is in
`phpunit.xml.dist`
in repository root folder.
You can create your own phpunit.xml to override dist config.
Database and other backend system configuration can be found in
`unit/data/config.php`
adjust them to your needs to allow testing databases and caching in your environment.
\ No newline at end of file
tests/unit/framework/caching/RedisCacheTest.php
View file @
31ea3f89
...
...
@@ -24,11 +24,11 @@ class RedisCacheTest extends CacheTestCase
'dataTimeout'
=>
0.1
,
];
$dsn
=
$config
[
'hostname'
]
.
':'
.
$config
[
'port'
];
if
(
!@
stream_socket_client
(
$dsn
,
$errorNumber
,
$errorDescription
,
0.5
))
{
if
(
!@
stream_socket_client
(
$dsn
,
$errorNumber
,
$errorDescription
,
0.5
))
{
$this
->
markTestSkipped
(
'No redis server running at '
.
$dsn
.
' : '
.
$errorNumber
.
' - '
.
$errorDescription
);
}
if
(
$this
->
_cacheInstance
===
null
)
{
if
(
$this
->
_cacheInstance
===
null
)
{
$this
->
_cacheInstance
=
new
RedisCache
(
$config
);
}
return
$this
->
_cacheInstance
;
...
...
tests/unit/framework/helpers/ConsoleTest.php
View file @
31ea3f89
...
...
@@ -73,7 +73,7 @@ class ConsoleTest extends TestCase
/* public function testScreenSize()
{
for($i = 1; $i < 20; $i++) {
for
($i = 1; $i < 20; $i++) {
echo implode(', ', Console::getScreenSize(true)) . "\n";
ob_flush();
sleep(1);
...
...
tests/unit/framework/i18n/FallbackMessageFormatterTest.php
View file @
31ea3f89
...
...
@@ -7,7 +7,7 @@
namespace
yiiunit\framework\i18n
;
use
yii\i18n\
Fallback
MessageFormatter
;
use
yii\i18n\MessageFormatter
;
use
yiiunit\TestCase
;
/**
...
...
@@ -34,6 +34,24 @@ class FallbackMessageFormatterTest extends TestCase
]
],
[
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
', number}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
self
::
N
=>
self
::
N_VALUE
,
self
::
SUBJECT
=>
self
::
SUBJECT_VALUE
,
]
],
[
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
', number, integer}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
self
::
N
=>
self
::
N_VALUE
,
self
::
SUBJECT
=>
self
::
SUBJECT_VALUE
,
]
],
// This one was provided by Aura.Intl. Thanks!
[
<<<_MSG_
{gender_of_host, select,
...
...
@@ -115,19 +133,10 @@ _MSG_
/**
* @dataProvider patterns
*/
public
function
testNamedArguments
Static
(
$pattern
,
$expected
,
$args
)
public
function
testNamedArguments
(
$pattern
,
$expected
,
$args
)
{
$result
=
FallbackMessageFormatter
::
formatMessage
(
'en_US'
,
$pattern
,
$args
);
$this
->
assertEquals
(
$expected
,
$result
);
}
/**
* @dataProvider patterns
*/
public
function
testNamedArgumentsObject
(
$pattern
,
$expected
,
$args
)
{
$formatter
=
new
FallbackMessageFormatter
(
'en_US'
,
$pattern
);
$result
=
$formatter
->
format
(
$args
);
$formatter
=
new
FallbackMessageFormatter
();
$result
=
$formatter
->
fallbackFormat
(
$pattern
,
$args
,
'en_US'
);
$this
->
assertEquals
(
$expected
,
$result
,
$formatter
->
getErrorMessage
());
}
...
...
@@ -135,9 +144,10 @@ _MSG_
{
$expected
=
'{'
.
self
::
SUBJECT
.
'} is '
.
self
::
N_VALUE
;
$result
=
FallbackMessageFormatter
::
formatMessage
(
'en_US'
,
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
'}'
,
[
$formatter
=
new
FallbackMessageFormatter
();
$result
=
$formatter
->
fallbackFormat
(
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
'}'
,
[
self
::
N
=>
self
::
N_VALUE
,
]);
]
,
'en_US'
);
$this
->
assertEquals
(
$expected
,
$result
);
}
...
...
@@ -145,11 +155,17 @@ _MSG_
public
function
testNoParams
()
{
$pattern
=
'{'
.
self
::
SUBJECT
.
'} is '
.
self
::
N
;
$result
=
FallbackMessageFormatter
::
formatMessage
(
'en_US'
,
$pattern
,
[]);
$this
->
assertEquals
(
$pattern
,
$result
);
$formatter
=
new
FallbackMessageFormatter
(
'en_US'
,
$pattern
);
$result
=
$formatter
->
f
ormat
([]
);
$formatter
=
new
FallbackMessageFormatter
();
$result
=
$formatter
->
f
allbackFormat
(
$pattern
,
[],
'en_US'
);
$this
->
assertEquals
(
$pattern
,
$result
,
$formatter
->
getErrorMessage
());
}
}
class
FallbackMessageFormatter
extends
MessageFormatter
{
public
function
fallbackFormat
(
$pattern
,
$args
,
$locale
)
{
return
parent
::
fallbackFormat
(
$pattern
,
$args
,
$locale
);
}
}
\ No newline at end of file
tests/unit/framework/i18n/MessageFormatterTest.php
View file @
31ea3f89
...
...
@@ -41,6 +41,15 @@ class MessageFormatterTest extends TestCase
]
],
[
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
', number, integer}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
self
::
N
=>
self
::
N_VALUE
,
self
::
SUBJECT
=>
self
::
SUBJECT_VALUE
,
]
],
// This one was provided by Aura.Intl. Thanks!
[
<<<_MSG_
{gender_of_host, select,
...
...
@@ -119,59 +128,116 @@ _MSG_
];
}
public
function
parsePatterns
()
{
return
[
[
self
::
SUBJECT_VALUE
.
' is {0, number}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
0
=>
self
::
N_VALUE
,
]
],
[
self
::
SUBJECT_VALUE
.
' is {'
.
self
::
N
.
', number}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
self
::
N
=>
self
::
N_VALUE
,
]
],
[
self
::
SUBJECT_VALUE
.
' is {'
.
self
::
N
.
', number, integer}'
,
// pattern
self
::
SUBJECT_VALUE
.
' is '
.
self
::
N_VALUE
,
// expected
[
// params
self
::
N
=>
self
::
N_VALUE
,
]
],
[
"
{
0,number,integer
}
monkeys on
{
1,number,integer
}
trees make
{
2,number
}
monkeys per tree"
,
"4,560 monkeys on 123 trees make 37.073 monkeys per tree"
,
[
0
=>
4560
,
1
=>
123
,
2
=>
37.073
],
'en_US'
],
[
"
{
0,number,integer
}
Affen auf
{
1,number,integer
}
Bäumen sind
{
2,number
}
Affen pro Baum"
,
"4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum"
,
[
0
=>
4560
,
1
=>
123
,
2
=>
37.073
],
'de'
,
],
[
"
{
monkeyCount,number,integer
}
monkeys on
{
trees,number,integer
}
trees make
{
monkeysPerTree,number
}
monkeys per tree"
,
"4,560 monkeys on 123 trees make 37.073 monkeys per tree"
,
[
'monkeyCount'
=>
4560
,
'trees'
=>
123
,
'monkeysPerTree'
=>
37.073
],
'en_US'
],
[
"
{
monkeyCount,number,integer
}
Affen auf
{
trees,number,integer
}
Bäumen sind
{
monkeysPerTree,number
}
Affen pro Baum"
,
"4.560 Affen auf 123 Bäumen sind 37,073 Affen pro Baum"
,
[
'monkeyCount'
=>
4560
,
'trees'
=>
123
,
'monkeysPerTree'
=>
37.073
],
'de'
,
],
];
}
/**
* @dataProvider patterns
*/
public
function
testNamedArguments
Static
(
$pattern
,
$expected
,
$args
)
public
function
testNamedArguments
(
$pattern
,
$expected
,
$args
)
{
$result
=
MessageFormatter
::
formatMessage
(
'en_US'
,
$pattern
,
$args
);
$this
->
assertEquals
(
$expected
,
$result
,
intl_get_error_message
());
$formatter
=
new
MessageFormatter
();
$result
=
$formatter
->
format
(
$pattern
,
$args
,
'en_US'
);
$this
->
assertEquals
(
$expected
,
$result
,
$formatter
->
getErrorMessage
());
}
/**
* @dataProvider patterns
* @dataProvider pa
rsePa
tterns
*/
public
function
test
NamedArgumentsObject
(
$pattern
,
$expected
,
$args
)
public
function
test
ParseNamedArguments
(
$pattern
,
$expected
,
$args
,
$locale
=
'en_US'
)
{
$formatter
=
new
MessageFormatter
(
'en_US'
,
$pattern
);
$result
=
$formatter
->
format
(
$args
);
$this
->
assertEquals
(
$
expected
,
$result
,
$formatter
->
getErrorMessage
()
);
$formatter
=
new
MessageFormatter
();
$result
=
$formatter
->
parse
(
$pattern
,
$expected
,
$locale
);
$this
->
assertEquals
(
$
args
,
$result
,
$formatter
->
getErrorMessage
()
.
' Pattern: '
.
$pattern
);
}
public
function
testInsufficientArguments
()
{
$expected
=
'{'
.
self
::
SUBJECT
.
'} is '
.
self
::
N_VALUE
;
$result
=
MessageFormatter
::
formatMessage
(
'en_US'
,
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
', number}'
,
[
$formatter
=
new
MessageFormatter
();
$result
=
$formatter
->
format
(
'{'
.
self
::
SUBJECT
.
'} is {'
.
self
::
N
.
', number}'
,
[
self
::
N
=>
self
::
N_VALUE
,
]);
$this
->
assertEquals
(
$expected
,
$result
,
intl_get_error_message
());
}
],
'en_US'
);
/**
* When instantiating a MessageFormatter with invalid pattern it should be null with default settings.
* It will be IntlException if intl.use_exceptions=1 and PHP 5.5 or newer or an error if intl.error_level is not 0.
*/
public
function
testNullConstructor
()
{
if
(
ini_get
(
'intl.use_exceptions'
))
{
$this
->
setExpectedException
(
'IntlException'
);
}
if
(
!
ini_get
(
'intl.error_level'
)
||
ini_get
(
'intl.use_exceptions'
))
{
$this
->
assertNull
(
new
MessageFormatter
(
'en_US'
,
''
));
}
$this
->
assertEquals
(
$expected
,
$result
,
$formatter
->
getErrorMessage
());
}
public
function
testNoParams
()
{
$pattern
=
'{'
.
self
::
SUBJECT
.
'} is '
.
self
::
N
;
$result
=
MessageFormatter
::
formatMessage
(
'en_US'
,
$pattern
,
[]);
$this
->
assertEquals
(
$pattern
,
$result
,
intl_get_error_message
());
$formatter
=
new
MessageFormatter
(
'en_US'
,
$pattern
);
$result
=
$formatter
->
format
([]);
$formatter
=
new
MessageFormatter
();
$result
=
$formatter
->
format
(
$pattern
,
[],
'en_US'
);
$this
->
assertEquals
(
$pattern
,
$result
,
$formatter
->
getErrorMessage
());
}
}
\ No newline at end of file
tests/unit/framework/validators/UrlValidatorTest.php
View file @
31ea3f89
...
...
@@ -59,7 +59,7 @@ class UrlValidatorTest extends TestCase
public
function
testValidateWithIdn
()
{
if
(
!
function_exists
(
'idn_to_ascii'
))
{
if
(
!
function_exists
(
'idn_to_ascii'
))
{
$this
->
markTestSkipped
(
'intl package required'
);
return
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment