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
9d8a4012
Commit
9d8a4012
authored
Feb 10, 2012
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
6d6d8d95
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
358 additions
and
517 deletions
+358
-517
YiiBase.php
framework/YiiBase.php
+5
-6
Model.php
framework/base/Model.php
+4
-4
ModelBehavior.php
framework/base/ModelBehavior.php
+2
-2
ModelEvent.php
framework/base/ModelEvent.php
+6
-7
Object.php
framework/base/Object.php
+1
-1
ActiveFinder.php
framework/db/ar/ActiveFinder.php
+28
-28
ActiveMetaData.php
framework/db/ar/ActiveMetaData.php
+24
-2
ActiveRecord.php
framework/db/ar/ActiveRecord.php
+273
-458
JoinElement.php
framework/db/ar/JoinElement.php
+2
-2
Text.php
framework/util/Text.php
+13
-7
No files found.
framework/YiiBase.php
View file @
9d8a4012
...
@@ -75,17 +75,16 @@ class YiiBase
...
@@ -75,17 +75,16 @@ class YiiBase
);
);
/**
/**
* @var array initial property values that will be applied to objects newly created via [[createObject]].
* @var array initial property values that will be applied to objects newly created via [[createObject]].
* The array keys are fully qualified namespaced class names, and the array values are the corresponding
* The array keys are class names without leading backslashes "\", and the array values are the corresponding
* name-value pairs for initializing the created class instances. Please make sure class names are starting
* name-value pairs for initializing the created class instances. For example,
* with a backslash. For example,
*
*
* ~~~
* ~~~
* array(
* array(
* '
\
Bar' => array(
* 'Bar' => array(
* 'prop1' => 'value1',
* 'prop1' => 'value1',
* 'prop2' => 'value2',
* 'prop2' => 'value2',
* ),
* ),
* '
\
mycompany\foo\Car' => array(
* 'mycompany\foo\Car' => array(
* 'prop1' => 'value1',
* 'prop1' => 'value1',
* 'prop2' => 'value2',
* 'prop2' => 'value2',
* ),
* ),
...
@@ -375,7 +374,7 @@ class YiiBase
...
@@ -375,7 +374,7 @@ class YiiBase
$object
=
new
$class
;
$object
=
new
$class
;
}
}
$class
=
'\\'
.
get_class
(
$object
);
$class
=
get_class
(
$object
);
if
(
isset
(
\Yii
::
$objectConfig
[
$class
]))
{
if
(
isset
(
\Yii
::
$objectConfig
[
$class
]))
{
$config
=
array_merge
(
\Yii
::
$objectConfig
[
$class
],
$config
);
$config
=
array_merge
(
\Yii
::
$objectConfig
[
$class
],
$config
);
...
...
framework/base/Model.php
View file @
9d8a4012
...
@@ -207,7 +207,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
...
@@ -207,7 +207,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
public
function
beforeValidate
()
public
function
beforeValidate
()
{
{
if
(
$this
->
hasEventHandlers
(
'onBeforeValidate'
))
{
if
(
$this
->
hasEventHandlers
(
'onBeforeValidate'
))
{
$event
=
new
Validation
Event
(
$this
);
$event
=
new
Model
Event
(
$this
);
$this
->
onBeforeValidate
(
$event
);
$this
->
onBeforeValidate
(
$event
);
return
$event
->
isValid
;
return
$event
->
isValid
;
}
}
...
@@ -229,7 +229,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
...
@@ -229,7 +229,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
/**
/**
* This event is raised before the validation is performed.
* This event is raised before the validation is performed.
* @param
Validation
Event $event the event parameter
* @param
Model
Event $event the event parameter
*/
*/
public
function
onBeforeValidate
(
$event
)
public
function
onBeforeValidate
(
$event
)
{
{
...
@@ -457,7 +457,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
...
@@ -457,7 +457,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
*/
*/
public
function
generateAttributeLabel
(
$name
)
public
function
generateAttributeLabel
(
$name
)
{
{
return
Text
::
name
2words
(
$name
,
true
);
return
Text
::
camel
2words
(
$name
,
true
);
}
}
/**
/**
...
@@ -583,7 +583,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
...
@@ -583,7 +583,7 @@ class Model extends Component implements \IteratorAggregate, \ArrayAccess
/**
/**
* Returns an iterator for traversing the attributes in the model.
* Returns an iterator for traversing the attributes in the model.
* This method is required by the interface IteratorAggregate.
* This method is required by the interface IteratorAggregate.
* @return
CMap
Iterator an iterator for traversing the items in the list.
* @return
Dictionary
Iterator an iterator for traversing the items in the list.
*/
*/
public
function
getIterator
()
public
function
getIterator
()
{
{
...
...
framework/base/ModelBehavior.php
View file @
9d8a4012
...
@@ -52,9 +52,9 @@ class ModelBehavior extends Behavior
...
@@ -52,9 +52,9 @@ class ModelBehavior extends Behavior
/**
/**
* Responds to [[Model::onBeforeValidate]] event.
* Responds to [[Model::onBeforeValidate]] event.
* Override this method if you want to handle the corresponding event of the [[owner]].
* Override this method if you want to handle the corresponding event of the [[owner]].
* You may set the [[
Validation
Event::isValid|isValid]] property of the event parameter
* You may set the [[
Model
Event::isValid|isValid]] property of the event parameter
* to be false to cancel the validation process.
* to be false to cancel the validation process.
* @param
Validation
Event $event event parameter
* @param
Model
Event $event event parameter
*/
*/
public
function
beforeValidate
(
$event
)
public
function
beforeValidate
(
$event
)
{
{
...
...
framework/base/
Validation
Event.php
→
framework/base/
Model
Event.php
View file @
9d8a4012
<?php
<?php
/**
/**
*
Validation
Event class file.
*
Model
Event class file.
*
*
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
* @copyright Copyright © 2008-2012 Yii Software LLC
...
@@ -10,19 +10,18 @@
...
@@ -10,19 +10,18 @@
namespace
yii\base
;
namespace
yii\base
;
/**
/**
*
Validation
Event class.
*
Model
Event class.
*
*
*
ValidationEvent represents the parameter needed by model validation
events.
*
ModelEvent represents the parameter needed by model
events.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
* @since 2.0
*/
*/
class
Validation
Event
extends
Event
class
Model
Event
extends
Event
{
{
/**
/**
* @var boolean whether the model passes the validation by the event handler.
* @var boolean whether the model is in valid status. Defaults to true.
* Defaults to true. If it is set false, the [[Model::validate|model validation]] will be cancelled.
* A model is in valid status if it passes validation, or other checks.
* @see Model::onBeforeValidate
*/
*/
public
$isValid
=
true
;
public
$isValid
=
true
;
}
}
framework/base/Object.php
View file @
9d8a4012
...
@@ -299,7 +299,7 @@ class Object
...
@@ -299,7 +299,7 @@ class Object
*/
*/
public
static
function
newInstance
(
$config
=
array
())
public
static
function
newInstance
(
$config
=
array
())
{
{
$class
=
'\\'
.
get_called_class
();
$class
=
get_called_class
();
if
((
$n
=
func_num_args
())
>
1
)
{
if
((
$n
=
func_num_args
())
>
1
)
{
$args
=
func_get_args
();
$args
=
func_get_args
();
...
...
framework/db/ar/Active
Query
.php
→
framework/db/ar/Active
Finder
.php
View file @
9d8a4012
<?php
<?php
/**
/**
* Active
Query
class file.
* Active
Finder
class file.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
...
@@ -18,10 +18,10 @@ use yii\db\Exception;
...
@@ -18,10 +18,10 @@ use yii\db\Exception;
* ActiveFinder.php is ...
* ActiveFinder.php is ...
* todo: add SQL monitor
* todo: add SQL monitor
*
*
* todo: add Active
Query
Builder
* todo: add Active
Finder
Builder
* todo: quote join/on part of the relational query
* todo: quote join/on part of the relational query
* todo: modify QueryBuilder about join() methods
* todo: modify QueryBuilder about join() methods
* todo: unify Active
Query
and ActiveRelation in query building process
* todo: unify Active
Finder
and ActiveRelation in query building process
* todo: intelligent table aliasing (first table name, then relation name, finally t?)
* todo: intelligent table aliasing (first table name, then relation name, finally t?)
* todo: allow using tokens in primary query fragments
* todo: allow using tokens in primary query fragments
* todo: findBySql
* todo: findBySql
...
@@ -33,14 +33,14 @@ use yii\db\Exception;
...
@@ -33,14 +33,14 @@ use yii\db\Exception;
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
* @since 2.0
*/
*/
class
Active
Query
extends
\yii\base\Object
implements
\IteratorAggregate
,
\ArrayAccess
,
\Countable
class
Active
Finder
extends
\yii\base\Object
implements
\IteratorAggregate
,
\ArrayAccess
,
\Countable
{
{
/**
/**
* @var string the name of the ActiveRecord class.
* @var string the name of the ActiveRecord class.
*/
*/
public
$modelClass
;
public
$modelClass
;
/**
/**
* @var
\yii\db\dao\
Query the Query object
* @var Query the Query object
*/
*/
public
$query
;
public
$query
;
/**
/**
...
@@ -278,7 +278,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -278,7 +278,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* (which means the column contains a DB expression).
* (which means the column contains a DB expression).
* @param string $option additional option that should be appended to the 'SELECT' keyword. For example,
* @param string $option additional option that should be appended to the 'SELECT' keyword. For example,
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
* in MySQL, the option 'SQL_CALC_FOUND_ROWS' can be used.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
select
(
$columns
,
$option
=
''
)
public
function
select
(
$columns
,
$option
=
''
)
{
{
...
@@ -289,7 +289,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -289,7 +289,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
/**
/**
* Sets the value indicating whether to SELECT DISTINCT or not.
* Sets the value indicating whether to SELECT DISTINCT or not.
* @param bool $value whether to SELECT DISTINCT or not.
* @param bool $value whether to SELECT DISTINCT or not.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
distinct
(
$value
=
true
)
public
function
distinct
(
$value
=
true
)
{
{
...
@@ -304,7 +304,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -304,7 +304,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Table names can contain schema prefixes (e.g. 'public.tbl_user') and/or table aliases (e.g. 'tbl_user u').
* Table names can contain schema prefixes (e.g. 'public.tbl_user') and/or table aliases (e.g. 'tbl_user u').
* The method will automatically quote the table names unless it contains some parenthesis
* The method will automatically quote the table names unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* (which means the table is given as a sub-query or DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
from
(
$tables
)
public
function
from
(
$tables
)
{
{
...
@@ -379,7 +379,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -379,7 +379,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For example, `where('type=? AND status=?', 100, 1)`.
* For example, `where('type=? AND status=?', 100, 1)`.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see andWhere()
* @see andWhere()
* @see orWhere()
* @see orWhere()
*/
*/
...
@@ -400,7 +400,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -400,7 +400,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* on how to specify this parameter.
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see where()
* @see where()
* @see orWhere()
* @see orWhere()
*/
*/
...
@@ -421,7 +421,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -421,7 +421,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* on how to specify this parameter.
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see where()
* @see where()
* @see andWhere()
* @see andWhere()
*/
*/
...
@@ -445,7 +445,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -445,7 +445,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Please refer to [[where()]] on how to specify this parameter.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
join
(
$table
,
$condition
,
$params
=
array
())
public
function
join
(
$table
,
$condition
,
$params
=
array
())
{
{
...
@@ -466,7 +466,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -466,7 +466,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* @param string|array $condition the join condition that should appear in the ON part.
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @param array $params the parameters (name=>value) to be bound to the query
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
leftJoin
(
$table
,
$condition
,
$params
=
array
())
public
function
leftJoin
(
$table
,
$condition
,
$params
=
array
())
{
{
...
@@ -487,7 +487,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -487,7 +487,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* @param string|array $condition the join condition that should appear in the ON part.
* @param string|array $condition the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @param array $params the parameters (name=>value) to be bound to the query
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
rightJoin
(
$table
,
$condition
,
$params
=
array
())
public
function
rightJoin
(
$table
,
$condition
,
$params
=
array
())
{
{
...
@@ -506,7 +506,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -506,7 +506,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* (which means the table is given as a sub-query or DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
crossJoin
(
$table
)
public
function
crossJoin
(
$table
)
{
{
...
@@ -521,7 +521,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -521,7 +521,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* (which means the table is given as a sub-query or DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
naturalJoin
(
$table
)
public
function
naturalJoin
(
$table
)
{
{
...
@@ -535,7 +535,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -535,7 +535,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* (which means the column contains a DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see addGroupBy()
* @see addGroupBy()
*/
*/
public
function
groupBy
(
$columns
)
public
function
groupBy
(
$columns
)
...
@@ -550,7 +550,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -550,7 +550,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* Columns can be specified in either a string (e.g. "id, name") or an array (e.g. array('id', 'name')).
* The method will automatically quote the column names unless a column contains some parenthesis
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* (which means the column contains a DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see groupBy()
* @see groupBy()
*/
*/
public
function
addGroupBy
(
$columns
)
public
function
addGroupBy
(
$columns
)
...
@@ -565,7 +565,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -565,7 +565,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Please refer to [[where()]] on how to specify this parameter.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see andHaving()
* @see andHaving()
* @see orHaving()
* @see orHaving()
*/
*/
...
@@ -586,7 +586,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -586,7 +586,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* on how to specify this parameter.
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see having()
* @see having()
* @see orHaving()
* @see orHaving()
*/
*/
...
@@ -607,7 +607,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -607,7 +607,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* on how to specify this parameter.
* on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query.
* @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see having()
* @see having()
* @see andHaving()
* @see andHaving()
*/
*/
...
@@ -627,7 +627,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -627,7 +627,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* (which means the column contains a DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see addOrderBy()
* @see addOrderBy()
*/
*/
public
function
orderBy
(
$columns
)
public
function
orderBy
(
$columns
)
...
@@ -642,7 +642,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -642,7 +642,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* Columns can be specified in either a string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
* The method will automatically quote the column names unless a column contains some parenthesis
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* (which means the column contains a DB expression).
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see orderBy()
* @see orderBy()
*/
*/
public
function
addOrderBy
(
$columns
)
public
function
addOrderBy
(
$columns
)
...
@@ -654,7 +654,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -654,7 +654,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
/**
/**
* Sets the LIMIT part of the query.
* Sets the LIMIT part of the query.
* @param integer $limit the limit
* @param integer $limit the limit
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
limit
(
$limit
)
public
function
limit
(
$limit
)
{
{
...
@@ -665,7 +665,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -665,7 +665,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
/**
/**
* Sets the OFFSET part of the query.
* Sets the OFFSET part of the query.
* @param integer $offset the offset
* @param integer $offset the offset
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
offset
(
$offset
)
public
function
offset
(
$offset
)
{
{
...
@@ -676,7 +676,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -676,7 +676,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
/**
/**
* Appends a SQL statement using UNION operator.
* Appends a SQL statement using UNION operator.
* @param string|Query $sql the SQL statement to be appended using UNION
* @param string|Query $sql the SQL statement to be appended using UNION
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
*/
*/
public
function
union
(
$sql
)
public
function
union
(
$sql
)
{
{
...
@@ -694,7 +694,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -694,7 +694,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* @param array list of query parameter values indexed by parameter placeholders.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see addParams()
* @see addParams()
*/
*/
public
function
params
(
$params
)
public
function
params
(
$params
)
...
@@ -708,7 +708,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
...
@@ -708,7 +708,7 @@ class ActiveQuery extends \yii\base\Object implements \IteratorAggregate, \Array
* @param array list of query parameter values indexed by parameter placeholders.
* @param array list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Active
Query
the query object itself
* @return Active
Finder
the query object itself
* @see params()
* @see params()
*/
*/
public
function
addParams
(
$params
)
public
function
addParams
(
$params
)
...
...
framework/db/ar/ActiveMetaData.php
View file @
9d8a4012
...
@@ -14,6 +14,10 @@ use yii\db\dao\TableSchema;
...
@@ -14,6 +14,10 @@ use yii\db\dao\TableSchema;
class
ActiveMetaData
class
ActiveMetaData
{
{
/**
/**
* @var ActiveMetaData[] list of ActiveMetaData instances indexed by the model class names
*/
public
static
$instances
;
/**
* @var TableSchema the table schema information
* @var TableSchema the table schema information
*/
*/
public
$table
;
public
$table
;
...
@@ -27,14 +31,32 @@ class ActiveMetaData
...
@@ -27,14 +31,32 @@ class ActiveMetaData
public
$relations
=
array
();
public
$relations
=
array
();
/**
/**
* Returns an instance of ActiveMetaData for the specified model class.
* Note that each model class only has a single ActiveMetaData instance.
* This method will only create the ActiveMetaData instance if it is not previously
* done so for the specified model class.
* @param string $modelClass the model class name. Make sure the class name do NOT have a leading backslash "\".
* @param boolean $refresh whether to recreate the ActiveMetaData instance. Defaults to false.
* @return ActiveMetaData the ActiveMetaData instance for the specified model class.
*/
public
static
function
getInstance
(
$modelClass
,
$refresh
=
false
)
{
if
(
isset
(
self
::
$instances
[
$modelClass
])
&&
!
$refresh
)
{
return
self
::
$instances
[
$modelClass
];
}
else
{
return
self
::
$instances
[
$modelClass
]
=
new
self
(
$modelClass
);
}
}
/**
* Constructor.
* Constructor.
* @param string $modelClass the model class name
* @param string $modelClass the model class name
*/
*/
public
function
__construct
(
$modelClass
)
public
function
__construct
(
$modelClass
)
{
{
$this
->
modelClass
=
$modelClass
;
$tableName
=
$modelClass
::
tableName
();
$tableName
=
$modelClass
::
tableName
();
$this
->
table
=
$modelClass
::
getDbConnection
()
->
getDriver
()
->
getTableSchema
(
$tableName
);
$this
->
table
=
$modelClass
::
getDbConnection
()
->
getDriver
()
->
getTableSchema
(
$tableName
);
$this
->
modelClass
=
$modelClass
;
if
(
$this
->
table
===
null
)
{
if
(
$this
->
table
===
null
)
{
throw
new
Exception
(
"Unable to find table '
$tableName
' for ActiveRecord class '
$modelClass
'."
);
throw
new
Exception
(
"Unable to find table '
$tableName
' for ActiveRecord class '
$modelClass
'."
);
}
}
...
@@ -71,7 +93,7 @@ class ActiveMetaData
...
@@ -71,7 +93,7 @@ class ActiveMetaData
$relation
->
name
=
$matches
[
1
];
$relation
->
name
=
$matches
[
1
];
$modelClass
=
$matches
[
2
];
$modelClass
=
$matches
[
2
];
if
(
strpos
(
$modelClass
,
'\\'
)
!==
false
)
{
if
(
strpos
(
$modelClass
,
'\\'
)
!==
false
)
{
$relation
->
modelClass
=
'\\'
.
ltrim
(
$modelClass
,
'\\'
);
$relation
->
modelClass
=
ltrim
(
$modelClass
,
'\\'
);
}
else
{
}
else
{
$relation
->
modelClass
=
dirname
(
$this
->
modelClass
)
.
'\\'
.
$modelClass
;
$relation
->
modelClass
=
dirname
(
$this
->
modelClass
)
.
'\\'
.
$modelClass
;
}
}
...
...
framework/db/ar/ActiveRecord.php
View file @
9d8a4012
...
@@ -10,10 +10,15 @@
...
@@ -10,10 +10,15 @@
namespace
yii\db\ar
;
namespace
yii\db\ar
;
use
yii\base\Model
;
use
yii\base\Event
;
use
yii\base\ModelEvent
;
use
yii\db\Exception
;
use
yii\db\Exception
;
use
yii\db\dao\Connection
;
use
yii\db\dao\Connection
;
use
yii\db\dao\TableSchema
;
use
yii\db\dao\TableSchema
;
use
yii\db\dao\Query
;
use
yii\db\dao\Query
;
use
yii\db\dao\Expression
;
use
yii\util\Text
;
/**
/**
* ActiveRecord is the base class for classes representing relational data.
* ActiveRecord is the base class for classes representing relational data.
...
@@ -23,18 +28,16 @@ use yii\db\dao\Query;
...
@@ -23,18 +28,16 @@ use yii\db\dao\Query;
*
*
* @property array $attributes
* @property array $attributes
*/
*/
abstract
class
ActiveRecord
extends
\yii\base\
Model
abstract
class
ActiveRecord
extends
Model
{
{
/**
/**
* @var ActiveMetaData[] list of AR metadata indexed by AR class names
* @var array attribute values indexed by attribute names
*/
private
$_attributes
=
array
();
/**
* @var array old attribute values indexed by attribute names.
*/
*/
private
static
$_md
;
private
$_new
=
false
;
// whether this instance is new or not
private
$_attributes
=
array
();
// attribute name => attribute value
private
$_oldAttributes
;
private
$_oldAttributes
;
private
$_related
=
array
();
// attribute name => related objects
private
$_pk
;
// old primary key value
/**
/**
* Returns the metadata for this AR class.
* Returns the metadata for this AR class.
...
@@ -43,78 +46,119 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -43,78 +46,119 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
static
function
getMetaData
(
$refresh
=
false
)
public
static
function
getMetaData
(
$refresh
=
false
)
{
{
$class
=
get_called_class
();
return
ActiveMetaData
::
getInstance
(
get_called_class
(),
$refresh
);
if
(
!
$refresh
&&
isset
(
self
::
$_md
[
$class
]))
{
return
self
::
$_md
[
$class
];
}
else
{
return
self
::
$_md
[
$class
]
=
new
ActiveMetaData
(
'\\'
.
$class
);
}
}
}
/**
/**
* @param string|array|Query $q
* Creates an [[ActiveFinder]] instance for query purpose.
* @return ActiveQuery
*
* @throws Exception
* Because [[ActiveFinder]] implements a set of query building methods,
* additional query conditions can be specified by calling these methods.
*
* Below are some usage examples:
*
* ~~~
* // find all customers
* $customers = Customer::find()->all();
* // find a single customer whose ID is 10
* $customer = Customer::find(10)->one();
* // find all active customers and order them by their age:
* $customers = Customer::find(array('status' => 1))->orderBy('age')->all();
* ~~~
*
* @param mixed $q the query parameter. This can be one of the followings:
*
* - a scalar value (integer, string): query by a single primary key value.
* - an array of name-value pairs: query by a set of column values.
* - a [[Query]] object: query by a full query object.
*
* @return ActiveFinder the [[ActiveFinder]] instance for query purpose.
* @throws Exception if the query parameter is invalid.
*/
*/
public
static
function
find
(
$q
=
null
)
public
static
function
find
(
$q
=
null
)
{
{
$
query
=
static
::
createActiveQuery
();
$
finder
=
static
::
createActiveFinder
();
if
(
$q
instanceof
Query
)
{
if
(
$q
instanceof
Query
)
{
$
query
->
query
=
$q
;
$
finder
->
query
=
$q
;
}
elseif
(
is_array
(
$q
))
{
}
elseif
(
is_array
(
$q
))
{
// query by a
ttribut
es
// query by a
set of column valu
es
$
query
->
where
(
$q
);
$
finder
->
where
(
$q
);
}
elseif
(
$q
!==
null
)
{
}
elseif
(
$q
!==
null
)
{
// query by primary key
// query by primary key
$primaryKey
=
static
::
getMetaData
()
->
table
->
primaryKey
;
$primaryKey
=
static
::
getMetaData
()
->
table
->
primaryKey
;
if
(
count
(
$primaryKey
)
===
1
)
{
if
(
count
(
$primaryKey
)
===
1
)
{
$
query
->
where
(
array
(
$primaryKey
[
0
]
=>
$q
));
$
finder
->
where
(
array
(
$primaryKey
[
0
]
=>
$q
));
}
else
{
}
else
{
throw
new
Exception
(
'Multiple values are required to query by composite keys.'
);
throw
new
Exception
(
'Multiple values are required to query by composite
primary
keys.'
);
}
}
}
}
return
$
query
;
return
$
finder
;
}
}
/**
* Creates an [[ActiveFinder]] instance and query by a given SQL statement.
* Note that because the SQL statement is already specified, calling further
* query methods (such as `where()`, `orderBy()`) on [[ActiveFinder]] will have no effect.
* @param string $sql the SQL statement to be executed
* @param array $params parameters to be bound to the SQL statement during execution.
* @return ActiveFinder the [[ActiveFinder]] instance
*/
public
static
function
findBySql
(
$sql
,
$params
=
array
())
public
static
function
findBySql
(
$sql
,
$params
=
array
())
{
{
if
(
!
is_array
(
$params
))
{
if
(
!
is_array
(
$params
))
{
$params
=
func_get_args
();
$params
=
func_get_args
();
array_shift
(
$params
);
unset
(
$params
[
0
]
);
}
}
$
query
=
static
::
createActiveQuery
();
$
finder
=
static
::
createActiveFinder
();
$
query
->
sql
=
$sql
;
$
finder
->
sql
=
$sql
;
return
$
query
->
params
(
$params
);
return
$
finder
->
params
(
$params
);
}
}
public
static
function
updateAll
()
public
static
function
updateAll
(
$attributes
,
$condition
=
''
,
$params
=
array
()
)
{
{
$class
=
get_called_class
();
$query
=
new
Query
;
$query
->
update
(
$class
::
tableName
(),
$attributes
,
$condition
,
$params
);
return
$query
->
createCommand
(
$class
::
getDbConnection
())
->
execute
();
}
}
public
static
function
updateCounters
()
public
static
function
updateCounters
(
$counters
,
$condition
=
''
,
$params
=
array
()
)
{
{
$class
=
get_called_class
();
$db
=
$class
::
getDbConnection
();
foreach
(
$counters
as
$name
=>
$value
)
{
$value
=
(
int
)
$value
;
$quotedName
=
$db
->
quoteColumnName
(
$name
,
true
);
$counters
[
$name
]
=
new
Expression
(
$value
>=
0
?
"
$quotedName
+
$value
"
:
"
$quotedName$value
"
);
}
$query
=
new
Query
;
$query
->
update
(
$class
::
tableName
(),
$counters
,
$condition
,
$params
);
return
$query
->
createCommand
(
$class
::
getDbConnection
())
->
execute
();
}
}
public
static
function
deleteAll
()
public
static
function
deleteAll
(
$condition
=
''
,
$params
=
array
()
)
{
{
$class
=
get_called_class
();
$query
=
new
Query
;
$query
->
delete
(
$class
::
tableName
(),
$condition
,
$params
);
return
$query
->
createCommand
(
$class
::
getDbConnection
())
->
execute
();
}
}
/**
/**
* @return ActiveFinder
* Creates a [[ActiveFinder]] instance.
* This method is mainly called by [[find()]] and [[findBySql()]].
* @return ActiveFinder the newly created [[ActiveFinder]] instance.
*/
*/
public
static
function
createActiveFinder
()
public
static
function
createActiveFinder
()
{
{
return
new
ActiveFinder
(
'\\'
.
get_called_class
());
return
new
ActiveFinder
(
get_called_class
());
}
}
/**
/**
* Returns the database connection used by
active record
.
* Returns the database connection used by
this AR class
.
* By default, the "db" application component is used as the database connection.
* By default, the "db" application component is used as the database connection.
* You may override this method if you want to use a different database connection.
* You may override this method if you want to use a different database connection.
* @return Connection the database connection used by
active record
.
* @return Connection the database connection used by
this AR class
.
*/
*/
public
static
function
getDbConnection
()
public
static
function
getDbConnection
()
{
{
...
@@ -122,36 +166,24 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -122,36 +166,24 @@ abstract class ActiveRecord extends \yii\base\Model
}
}
/**
/**
* Returns the default named scope that should be implicitly applied to all queries for this model.
* Declares the name of the database table associated with this AR class.
* Note, default scope only applies to SELECT queries. It is ignored for INSERT, UPDATE and DELETE queries.
* By default this method returns the class name as the table name by calling [[Text::camel2id()]].
* The default implementation simply returns an empty array. You may override this method
* For example, 'Customer' becomes 'customer', and 'OrderDetail' becomes 'order_detail'.
* if the model needs to be queried with some default criteria (e.g. only active records should be returned).
* @return array the query criteria. This will be used as the parameter to the constructor
* of {@link CDbCriteria}.
*/
public
static
function
defaultScope
()
{
return
array
();
}
/**
* Returns the name of the associated database table.
* By default this method returns the class name as the table name.
* You may override this method if the table is not named after this convention.
* You may override this method if the table is not named after this convention.
* @return string the table name
* @return string the table name
*/
*/
public
static
function
tableName
()
public
static
function
tableName
()
{
{
return
basename
(
get_called_class
()
);
return
Text
::
camel2id
(
basename
(
get_called_class
()),
'_'
);
}
}
/**
/**
*
Returns the primary key of the associated database table
.
*
Declares the primary key name for this AR class
.
* This method is meant to be overridden in case when the table is not defined with a primary key
* This method is meant to be overridden in case when the table is not defined with a primary key
* (for some legacy database). If the table is already defined with a primary key,
* (for some legacy database). If the table is already defined with a primary key,
* you do not need to override this method. The default implementation simply returns null,
* you do not need to override this method. The default implementation simply returns null,
* meaning using the primary key defined in the database.
* meaning using the primary key defined in the database
table
.
* @return
mixed
the primary key of the associated database table.
* @return
string|array
the primary key of the associated database table.
* If the key is a single column, it should return the column name;
* If the key is a single column, it should return the column name;
* If the key is a composite one consisting of several columns, it should
* If the key is a composite one consisting of several columns, it should
* return the array of the key column names.
* return the array of the key column names.
...
@@ -161,22 +193,22 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -161,22 +193,22 @@ abstract class ActiveRecord extends \yii\base\Model
}
}
/**
/**
* Declares the relations for this A
ctiveRecord
class.
* Declares the relations for this A
R
class.
*
*
* Child classes may
want to
override this method to specify their relations.
* Child classes may override this method to specify their relations.
*
*
* The following shows how to declare relations for a
Programmer
AR class:
* The following shows how to declare relations for a
`Programmer`
AR class:
*
*
* ~~~
* ~~~
* return array(
* return array(
* 'manager:Manager' => '
?.manager_id = manager.
id',
* 'manager:Manager' => '
@.id = ?.manager_
id',
* 'assignments:Assignment[]' => array(
* 'assignments:Assignment[]' => array(
* 'on' => '
?.id = assignments.owner_id AND assignments.status=
1',
* 'on' => '
@.owner_id = ?.id AND @.status =
1',
* 'orderBy' => '
assignments
.create_time DESC',
* 'orderBy' => '
@
.create_time DESC',
* ),
* ),
* 'projects:Project[]' => array(
* 'projects:Project[]' => array(
* 'via' => 'assignments',
* 'via' => 'assignments',
* 'on' => '
projects.id = assignments
.project_id',
* 'on' => '
@.id = ?
.project_id',
* ),
* ),
* );
* );
* ~~~
* ~~~
...
@@ -265,6 +297,19 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -265,6 +297,19 @@ abstract class ActiveRecord extends \yii\base\Model
}
}
/**
/**
* Returns the default named scope that should be implicitly applied to all queries for this model.
* Note, default scope only applies to SELECT queries. It is ignored for INSERT, UPDATE and DELETE queries.
* The default implementation simply returns an empty array. You may override this method
* if the model needs to be queried with some default criteria (e.g. only active records should be returned).
* @return array the query criteria. This will be used as the parameter to the constructor
* of {@link CDbCriteria}.
*/
public
static
function
defaultScope
()
{
return
array
();
}
/**
* Returns the declaration of named scopes.
* Returns the declaration of named scopes.
* A named scope represents a query criteria that can be chained together with
* A named scope represents a query criteria that can be chained together with
* other named scopes and applied to a query. This method should be overridden
* other named scopes and applied to a query. This method should be overridden
...
@@ -301,50 +346,25 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -301,50 +346,25 @@ abstract class ActiveRecord extends \yii\base\Model
}
}
/**
/**
* Constructor.
* @param string $scenario scenario name. See {@link CModel::scenario} for more details about this parameter.
*/
public
function
__construct
(
$scenario
=
'insert'
)
{
if
(
$scenario
===
null
)
// internally used by populateData() and model()
{
return
;
}
$this
->
setScenario
(
$scenario
);
$this
->
setIsNewRecord
(
true
);
}
/**
* PHP sleep magic method.
* This method ensures that the model meta data reference is set to null.
* @return array
*/
public
function
__sleep
()
{
return
array_keys
((
array
)
$this
);
}
/**
* PHP getter magic method.
* PHP getter magic method.
* This method is overridden so that
AR attribute
s can be accessed like properties.
* This method is overridden so that
attributes and related object
s can be accessed like properties.
* @param string $name property name
* @param string $name property name
* @return mixed property value
* @return mixed property value
* @see getAttribute
* @see getAttribute
*/
*/
public
function
__get
(
$name
)
public
function
__get
(
$name
)
{
{
if
(
isset
(
$this
->
_attributes
[
$name
]))
{
if
(
isset
(
$this
->
_attributes
[
$name
])
||
array_key_exists
(
$name
,
$this
->
_attributes
)
)
{
return
$this
->
_attributes
[
$name
];
return
$this
->
_attributes
[
$name
];
}
elseif
(
isset
(
$this
->
getMetaData
()
->
table
->
columns
[
$name
]))
{
return
null
;
}
elseif
(
isset
(
$this
->
_related
[
$name
]))
{
return
$this
->
_related
[
$name
];
}
elseif
(
isset
(
$this
->
getMetaData
()
->
relations
[
$name
]))
{
return
$this
->
getRelatedRecord
(
$name
);
}
else
{
}
else
{
return
parent
::
__get
(
$name
);
$md
=
$this
->
getMetaData
();
if
(
isset
(
$md
->
table
->
columns
[
$name
]))
{
return
null
;
}
elseif
(
isset
(
$md
->
relations
[
$name
]))
{
return
$this
->
_attributes
[
$name
]
=
$this
->
loadRelatedRecord
(
$md
->
relations
[
$name
]);
}
}
}
return
parent
::
__get
(
$name
);
}
}
/**
/**
...
@@ -355,10 +375,9 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -355,10 +375,9 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
__set
(
$name
,
$value
)
public
function
__set
(
$name
,
$value
)
{
{
if
(
isset
(
$this
->
getMetaData
()
->
table
->
columns
[
$name
]))
{
$md
=
$this
->
getMetaData
();
if
(
isset
(
$md
->
table
->
columns
[
$name
])
||
isset
(
$md
->
relations
[
$name
]))
{
$this
->
_attributes
[
$name
]
=
$value
;
$this
->
_attributes
[
$name
]
=
$value
;
}
elseif
(
isset
(
$this
->
getMetaData
()
->
relations
[
$name
]))
{
$this
->
_related
[
$name
]
=
$value
;
}
else
{
}
else
{
parent
::
__set
(
$name
,
$value
);
parent
::
__set
(
$name
,
$value
);
}
}
...
@@ -375,12 +394,8 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -375,12 +394,8 @@ abstract class ActiveRecord extends \yii\base\Model
{
{
if
(
isset
(
$this
->
_attributes
[
$name
]))
{
if
(
isset
(
$this
->
_attributes
[
$name
]))
{
return
true
;
return
true
;
}
elseif
(
isset
(
$this
->
getMetaData
()
->
colum
ns
[
$name
]))
{
}
elseif
(
isset
(
$this
->
getMetaData
()
->
table
->
columns
[
$name
])
||
isset
(
$this
->
getMetaData
()
->
relatio
ns
[
$name
]))
{
return
false
;
return
false
;
}
elseif
(
isset
(
$this
->
_related
[
$name
]))
{
return
true
;
}
elseif
(
isset
(
$this
->
getMetaData
()
->
relations
[
$name
]))
{
return
$this
->
getRelatedRecord
(
$name
)
!==
null
;
}
else
{
}
else
{
return
parent
::
__isset
(
$name
);
return
parent
::
__isset
(
$name
);
}
}
...
@@ -394,10 +409,9 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -394,10 +409,9 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
__unset
(
$name
)
public
function
__unset
(
$name
)
{
{
if
(
isset
(
$this
->
getMetaData
()
->
columns
[
$name
]))
{
$md
=
$this
->
getMetaData
();
if
(
isset
(
$md
->
table
->
columns
[
$name
])
||
isset
(
$md
->
relations
[
$name
]))
{
unset
(
$this
->
_attributes
[
$name
]);
unset
(
$this
->
_attributes
[
$name
]);
}
elseif
(
isset
(
$this
->
getMetaData
()
->
relations
[
$name
]))
{
unset
(
$this
->
_related
[
$name
]);
}
else
{
}
else
{
parent
::
__unset
(
$name
);
parent
::
__unset
(
$name
);
}
}
...
@@ -408,39 +422,34 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -408,39 +422,34 @@ abstract class ActiveRecord extends \yii\base\Model
* Do not call this method. This is a PHP magic method that we override
* Do not call this method. This is a PHP magic method that we override
* to implement the named scope feature.
* to implement the named scope feature.
* @param string $name the method name
* @param string $name the method name
* @param array $param
eter
s method parameters
* @param array $params method parameters
* @return mixed the method return value
* @return mixed the method return value
*/
*/
public
function
__call
(
$name
,
$param
eter
s
)
public
function
__call
(
$name
,
$params
)
{
{
if
(
isset
(
$this
->
getMetaData
()
->
relations
[
$name
]))
{
$md
=
$this
->
getMetaData
();
if
(
empty
(
$parameters
))
{
if
(
isset
(
$md
->
relations
[
$name
]))
{
return
$this
->
getRelatedRecord
(
$name
,
false
);
return
$this
->
loadRelatedRecord
(
$md
->
relations
[
$name
],
isset
(
$params
[
0
])
?
$params
[
0
]
:
array
());
}
else
{
return
$this
->
getRelatedRecord
(
$name
,
false
,
$parameters
[
0
]);
}
}
$scopes
=
$this
->
scopes
();
if
(
isset
(
$scopes
[
$name
]))
{
$this
->
getDbCriteria
()
->
mergeWith
(
$scopes
[
$name
]);
return
$this
;
}
}
return
parent
::
__call
(
$name
,
$params
);
return
parent
::
__call
(
$name
,
$parameters
);
}
}
public
function
initRelatedRecord
(
$relation
)
/**
* Initializes the internal storage for the relation.
* This method is internally used by [[ActiveFinder]] when populating relation data.
* @param ActiveRelation $relation the relation object
*/
public
function
initRelation
(
$relation
)
{
{
$this
->
_
related
[
$relation
->
name
]
=
$relation
->
hasMany
?
array
()
:
null
;
$this
->
_
attributes
[
$relation
->
name
]
=
$relation
->
hasMany
?
array
()
:
null
;
}
}
public
function
addRelatedRecord
(
$relation
,
$record
)
public
function
addRelatedRecord
(
$relation
,
$record
)
{
{
if
(
$relation
->
hasMany
)
{
if
(
$relation
->
hasMany
)
{
$this
->
_
related
[
$relation
->
name
][]
=
$record
;
$this
->
_
attributes
[
$relation
->
name
][]
=
$record
;
}
else
{
}
else
{
$this
->
_
related
[
$relation
->
name
]
=
$record
;
$this
->
_
attributes
[
$relation
->
name
]
=
$record
;
}
}
}
}
...
@@ -458,69 +467,16 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -458,69 +467,16 @@ abstract class ActiveRecord extends \yii\base\Model
* @return mixed the related object(s).
* @return mixed the related object(s).
* @throws Exception if the relation is not specified in {@link relations}.
* @throws Exception if the relation is not specified in {@link relations}.
*/
*/
public
function
getRelatedRecord
(
$name
,
$refresh
=
false
,
$params
=
array
())
public
function
loadRelatedRecord
(
$relation
,
$params
=
array
())
{
{
if
(
!
$refresh
&&
$params
===
array
()
&&
(
isset
(
$this
->
_related
[
$name
])
||
array_key_exists
(
$name
,
$this
->
_related
)))
{
if
(
is_string
(
$relation
))
{
return
$this
->
_related
[
$name
];
$md
=
$this
->
getMetaData
();
}
if
(
!
isset
(
$md
->
relations
[
$relation
]))
{
throw
new
Exception
(
get_class
(
$this
)
.
' has no relation named "'
.
$relation
.
'".'
);
$md
=
$this
->
getMetaData
();
if
(
!
isset
(
$md
->
relations
[
$name
]))
{
throw
new
Exception
(
Yii
::
t
(
'yii'
,
'{class} does not have relation "{name}".'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{name}'
=>
$name
)));
}
Yii
::
trace
(
'lazy loading '
.
get_class
(
$this
)
.
'.'
.
$name
,
'system.db.ar.ActiveRecord'
);
$relation
=
$md
->
relations
[
$name
];
if
(
$this
->
getIsNewRecord
()
&&
!
$refresh
&&
(
$relation
instanceof
CHasOneRelation
||
$relation
instanceof
CHasManyRelation
))
{
return
$relation
instanceof
CHasOneRelation
?
null
:
array
();
}
if
(
$params
!==
array
())
// dynamic query
{
$exists
=
isset
(
$this
->
_related
[
$name
])
||
array_key_exists
(
$name
,
$this
->
_related
);
if
(
$exists
)
{
$save
=
$this
->
_related
[
$name
];
}
$r
=
array
(
$name
=>
$params
);
}
else
{
$r
=
$name
;
}
unset
(
$this
->
_related
[
$name
]);
$finder
=
new
CActiveFinder
(
$this
,
$r
);
$finder
->
lazyFind
(
$this
);
if
(
!
isset
(
$this
->
_related
[
$name
]))
{
if
(
$relation
instanceof
CHasManyRelation
)
{
$this
->
_related
[
$name
]
=
array
();
}
elseif
(
$relation
instanceof
CStatRelation
)
{
$this
->
_related
[
$name
]
=
$relation
->
defaultValue
;
}
else
{
$this
->
_related
[
$name
]
=
null
;
}
}
if
(
$params
!==
array
())
{
$results
=
$this
->
_related
[
$name
];
if
(
$exists
)
{
$this
->
_related
[
$name
]
=
$save
;
}
else
{
unset
(
$this
->
_related
[
$name
]);
}
}
return
$results
;
$relation
=
$md
->
relations
[
$relation
];
}
else
{
return
$this
->
_related
[
$name
];
}
}
}
$finder
=
$this
->
createActiveFinder
();
/**
* Returns a value indicating whether the named related object(s) has been loaded.
* @param string $name the relation name
* @return boolean a value indicating whether the named related object(s) has been loaded.
*/
public
function
hasRelated
(
$name
)
{
return
isset
(
$this
->
_related
[
$name
])
||
array_key_exists
(
$name
,
$this
->
_related
);
}
}
/**
/**
...
@@ -530,69 +486,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -530,69 +486,7 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
attributeNames
()
public
function
attributeNames
()
{
{
return
array_keys
(
$this
->
getMetaData
()
->
columns
);
return
array_keys
(
$this
->
getMetaData
()
->
table
->
columns
);
}
/**
* Returns the text label for the specified attribute.
* This method overrides the parent implementation by supporting
* returning the label defined in relational object.
* In particular, if the attribute name is in the form of "post.author.name",
* then this method will derive the label from the "author" relation's "name" attribute.
* @param string $attribute the attribute name
* @return string the attribute label
* @see generateAttributeLabel
*/
public
function
getAttributeLabel
(
$attribute
)
{
$labels
=
$this
->
attributeLabels
();
if
(
isset
(
$labels
[
$attribute
]))
{
return
$labels
[
$attribute
];
}
elseif
(
strpos
(
$attribute
,
'.'
)
!==
false
)
{
$segs
=
explode
(
'.'
,
$attribute
);
$name
=
array_pop
(
$segs
);
$model
=
$this
;
foreach
(
$segs
as
$seg
)
{
$relations
=
$model
->
getMetaData
()
->
relations
;
if
(
isset
(
$relations
[
$seg
]))
{
$model
=
ActiveRecord
::
model
(
$relations
[
$seg
]
->
className
);
}
else
{
break
;
}
}
return
$model
->
getAttributeLabel
(
$name
);
}
else
{
return
$this
->
generateAttributeLabel
(
$attribute
);
}
}
/**
* Returns the named relation declared for this AR class.
* @param string $name the relation name
* @return CActiveRelation the named relation declared for this AR class. Null if the relation does not exist.
*/
public
function
getActiveRelation
(
$name
)
{
return
isset
(
$this
->
getMetaData
()
->
relations
[
$name
])
?
$this
->
getMetaData
()
->
relations
[
$name
]
:
null
;
}
/**
* Returns the metadata of the table that this AR belongs to
* @return CDbTableSchema the metadata of the table that this AR belongs to
*/
public
function
getTableSchema
()
{
return
$this
->
getMetaData
()
->
tableSchema
;
}
/**
* Checks whether this AR has the named attribute
* @param string $name attribute name
* @return boolean whether this AR has the named attribute (table column).
*/
public
function
hasAttribute
(
$name
)
{
return
isset
(
$this
->
getMetaData
()
->
columns
[
$name
]);
}
}
/**
/**
...
@@ -608,11 +502,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -608,11 +502,7 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
getAttribute
(
$name
)
public
function
getAttribute
(
$name
)
{
{
if
(
property_exists
(
$this
,
$name
))
{
return
isset
(
$this
->
_attributes
[
$name
])
?
$this
->
_attributes
[
$name
]
:
null
;
return
$this
->
$name
;
}
elseif
(
isset
(
$this
->
_attributes
[
$name
]))
{
return
$this
->
_attributes
[
$name
];
}
}
}
/**
/**
...
@@ -620,53 +510,47 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -620,53 +510,47 @@ abstract class ActiveRecord extends \yii\base\Model
* You may also use $this->AttributeName to set the attribute value.
* You may also use $this->AttributeName to set the attribute value.
* @param string $name the attribute name
* @param string $name the attribute name
* @param mixed $value the attribute value.
* @param mixed $value the attribute value.
* @return boolean whether the attribute exists and the assignment is conducted successfully
* @see hasAttribute
* @see hasAttribute
*/
*/
public
function
setAttribute
(
$name
,
$value
)
public
function
setAttribute
(
$name
,
$value
)
{
{
if
(
property_exists
(
$this
,
$name
))
{
$this
->
_attributes
[
$name
]
=
$value
;
$this
->
$name
=
$value
;
}
elseif
(
isset
(
$this
->
getMetaData
()
->
table
->
columns
[
$name
]))
{
$this
->
_attributes
[
$name
]
=
$value
;
}
else
{
return
false
;
}
return
true
;
}
}
/**
/**
* Returns all column attribute values.
* Returns all column attribute values.
* Note, related objects are not returned.
* Note, related objects are not returned.
* @param
mixed
$names names of attributes whose value needs to be returned.
* @param
null|array
$names names of attributes whose value needs to be returned.
* If this is true (default), then all attribute values will be returned, including
* If this is true (default), then all attribute values will be returned, including
* those that are not loaded from DB (null will be returned for those attributes).
* those that are not loaded from DB (null will be returned for those attributes).
* If this is null, all attributes except those that are not loaded from DB will be returned.
* If this is null, all attributes except those that are not loaded from DB will be returned.
* @return array attribute values indexed by attribute names.
* @return array attribute values indexed by attribute names.
*/
*/
public
function
getAttributes
(
$names
=
true
)
public
function
getAttributes
(
$names
=
null
)
{
{
$attributes
=
$this
->
_attributes
;
if
(
$names
===
null
)
{
foreach
(
$this
->
getMetaData
()
->
columns
as
$name
=>
$column
)
{
$names
=
$this
->
attributeNames
();
if
(
property_exists
(
$this
,
$name
))
{
$attributes
[
$name
]
=
$this
->
$name
;
}
elseif
(
$names
===
true
&&
!
isset
(
$attributes
[
$name
]))
{
$attributes
[
$name
]
=
null
;
}
}
}
if
(
is_array
(
$names
))
{
$values
=
array
();
$attrs
=
array
();
foreach
(
$names
as
$name
)
{
foreach
(
$names
as
$name
)
{
$values
[
$name
]
=
isset
(
$this
->
_attributes
[
$name
])
?
$this
->
_attributes
[
$name
]
:
null
;
if
(
property_exists
(
$this
,
$name
))
{
}
$attrs
[
$name
]
=
$this
->
$name
;
return
$values
;
}
else
{
}
$attrs
[
$name
]
=
isset
(
$attributes
[
$name
])
?
$attributes
[
$name
]
:
null
;
}
public
function
getChangedAttributes
(
$names
=
null
)
{
if
(
$names
===
null
)
{
$names
=
$this
->
attributeNames
();
}
$names
=
array_flip
(
$names
);
$attributes
=
array
();
foreach
(
$this
->
_attributes
as
$name
=>
$value
)
{
if
(
isset
(
$names
[
$name
])
&&
(
!
array_key_exists
(
$name
,
$this
->
_oldAttributes
)
||
$value
!==
$this
->
_oldAttributes
[
$name
]))
{
$attributes
[
$name
]
=
$value
;
}
}
return
$attrs
;
}
else
{
return
$attributes
;
}
}
return
$attributes
;
}
}
/**
/**
...
@@ -710,7 +594,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -710,7 +594,7 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
getIsNewRecord
()
public
function
getIsNewRecord
()
{
{
return
$this
->
_new
;
return
empty
(
$this
->
_oldAttributes
)
;
}
}
/**
/**
...
@@ -720,13 +604,22 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -720,13 +604,22 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
setIsNewRecord
(
$value
)
public
function
setIsNewRecord
(
$value
)
{
{
$this
->
_new
=
$value
;
if
(
$value
)
{
$this
->
_oldAttributes
=
null
;
}
else
{
$this
->
_oldAttributes
=
array
();
foreach
(
$this
->
attributeNames
()
as
$name
)
{
if
(
isset
(
$this
->
_attributes
[
$name
]))
{
$this
->
_oldAttributes
[
$name
]
=
$this
->
_attributes
[
$name
];
}
}
}
}
}
/**
/**
* This event is raised before the record is saved.
* This event is raised before the record is saved.
* By setting {@link
C
ModelEvent::isValid} to be false, the normal {@link save()} process will be stopped.
* By setting {@link ModelEvent::isValid} to be false, the normal {@link save()} process will be stopped.
* @param
C
ModelEvent $event the event parameter
* @param ModelEvent $event the event parameter
*/
*/
public
function
onBeforeSave
(
$event
)
public
function
onBeforeSave
(
$event
)
{
{
...
@@ -735,7 +628,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -735,7 +628,7 @@ abstract class ActiveRecord extends \yii\base\Model
/**
/**
* This event is raised after the record is saved.
* This event is raised after the record is saved.
* @param
C
Event $event the event parameter
* @param Event $event the event parameter
*/
*/
public
function
onAfterSave
(
$event
)
public
function
onAfterSave
(
$event
)
{
{
...
@@ -744,8 +637,8 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -744,8 +637,8 @@ abstract class ActiveRecord extends \yii\base\Model
/**
/**
* This event is raised before the record is deleted.
* This event is raised before the record is deleted.
* By setting {@link
C
ModelEvent::isValid} to be false, the normal {@link delete()} process will be stopped.
* By setting {@link ModelEvent::isValid} to be false, the normal {@link delete()} process will be stopped.
* @param
C
ModelEvent $event the event parameter
* @param ModelEvent $event the event parameter
*/
*/
public
function
onBeforeDelete
(
$event
)
public
function
onBeforeDelete
(
$event
)
{
{
...
@@ -754,7 +647,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -754,7 +647,7 @@ abstract class ActiveRecord extends \yii\base\Model
/**
/**
* This event is raised after the record is deleted.
* This event is raised after the record is deleted.
* @param
C
Event $event the event parameter
* @param Event $event the event parameter
*/
*/
public
function
onAfterDelete
(
$event
)
public
function
onAfterDelete
(
$event
)
{
{
...
@@ -770,15 +663,11 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -770,15 +663,11 @@ abstract class ActiveRecord extends \yii\base\Model
* Make sure you call the parent implementation so that the event is raised properly.
* Make sure you call the parent implementation so that the event is raised properly.
* @return boolean whether the saving should be executed. Defaults to true.
* @return boolean whether the saving should be executed. Defaults to true.
*/
*/
p
rotected
function
beforeSave
()
p
ublic
function
beforeSave
()
{
{
if
(
$this
->
hasEventHandler
(
'onBeforeSave'
))
{
$event
=
new
ModelEvent
(
$this
);
$event
=
new
CModelEvent
(
$this
);
$this
->
onBeforeSave
(
$event
);
$this
->
onBeforeSave
(
$event
);
return
$event
->
isValid
;
return
$event
->
isValid
;
}
else
{
return
true
;
}
}
}
/**
/**
...
@@ -787,11 +676,9 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -787,11 +676,9 @@ abstract class ActiveRecord extends \yii\base\Model
* You may override this method to do postprocessing after record saving.
* You may override this method to do postprocessing after record saving.
* Make sure you call the parent implementation so that the event is raised properly.
* Make sure you call the parent implementation so that the event is raised properly.
*/
*/
p
rotected
function
afterSave
()
p
ublic
function
afterSave
()
{
{
if
(
$this
->
hasEventHandler
(
'onAfterSave'
))
{
$this
->
onAfterSave
(
new
Event
(
$this
));
$this
->
onAfterSave
(
new
CEvent
(
$this
));
}
}
}
/**
/**
...
@@ -801,15 +688,11 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -801,15 +688,11 @@ abstract class ActiveRecord extends \yii\base\Model
* Make sure you call the parent implementation so that the event is raised properly.
* Make sure you call the parent implementation so that the event is raised properly.
* @return boolean whether the record should be deleted. Defaults to true.
* @return boolean whether the record should be deleted. Defaults to true.
*/
*/
p
rotected
function
beforeDelete
()
p
ublic
function
beforeDelete
()
{
{
if
(
$this
->
hasEventHandler
(
'onBeforeDelete'
))
{
$event
=
new
ModelEvent
(
$this
);
$event
=
new
CModelEvent
(
$this
);
$this
->
onBeforeDelete
(
$event
);
$this
->
onBeforeDelete
(
$event
);
return
$event
->
isValid
;
return
$event
->
isValid
;
}
else
{
return
true
;
}
}
}
/**
/**
...
@@ -818,45 +701,9 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -818,45 +701,9 @@ abstract class ActiveRecord extends \yii\base\Model
* You may override this method to do postprocessing after the record is deleted.
* You may override this method to do postprocessing after the record is deleted.
* Make sure you call the parent implementation so that the event is raised properly.
* Make sure you call the parent implementation so that the event is raised properly.
*/
*/
p
rotected
function
afterDelete
()
p
ublic
function
afterDelete
()
{
{
if
(
$this
->
hasEventHandler
(
'onAfterDelete'
))
{
$this
->
onAfterDelete
(
new
Event
(
$this
));
$this
->
onAfterDelete
(
new
CEvent
(
$this
));
}
}
/**
* This method is invoked before an AR finder executes a find call.
* The find calls include {@link find}, {@link findAll}, {@link findByPk},
* {@link findAllByPk}, {@link findByAttributes} and {@link findAllByAttributes}.
* The default implementation raises the {@link onBeforeFind} event.
* If you override this method, make sure you call the parent implementation
* so that the event is raised properly.
*
* Starting from version 1.1.5, this method may be called with a hidden {@link CDbCriteria}
* parameter which represents the current query criteria as passed to a find method of AR.
*/
protected
function
beforeFind
()
{
if
(
$this
->
hasEventHandler
(
'onBeforeFind'
))
{
$event
=
new
CModelEvent
(
$this
);
// for backward compatibility
$event
->
criteria
=
func_num_args
()
>
0
?
func_get_arg
(
0
)
:
null
;
$this
->
onBeforeFind
(
$event
);
}
}
/**
* This method is invoked after each record is instantiated by a find method.
* The default implementation raises the {@link onAfterFind} event.
* You may override this method to do postprocessing after each newly found record is instantiated.
* Make sure you call the parent implementation so that the event is raised properly.
*/
protected
function
afterFind
()
{
if
(
$this
->
hasEventHandler
(
'onAfterFind'
))
{
$this
->
onAfterFind
(
new
CEvent
(
$this
));
}
}
}
/**
/**
...
@@ -869,36 +716,30 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -869,36 +716,30 @@ abstract class ActiveRecord extends \yii\base\Model
* @param array $attributes list of attributes that need to be saved. Defaults to null,
* @param array $attributes list of attributes that need to be saved. Defaults to null,
* meaning all attributes that are loaded from DB will be saved.
* meaning all attributes that are loaded from DB will be saved.
* @return boolean whether the attributes are valid and the record is inserted successfully.
* @return boolean whether the attributes are valid and the record is inserted successfully.
* @throws
C
Exception if the record is not new
* @throws Exception if the record is not new
*/
*/
public
function
insert
(
$attributes
=
null
)
public
function
insert
(
$attributes
=
null
)
{
{
if
(
!
$this
->
getIsNewRecord
())
{
throw
new
Exception
(
Yii
::
t
(
'yii'
,
'The active record cannot be inserted to database because it is not new.'
));
}
if
(
$this
->
beforeSave
())
{
if
(
$this
->
beforeSave
())
{
Yii
::
trace
(
get_class
(
$this
)
.
'.insert()'
,
'system.db.ar.ActiveRecord'
);
$db
=
$this
->
getDbConnection
(
);
$
builder
=
$this
->
getCommandBuilder
()
;
$
query
=
new
Query
;
$
table
=
$this
->
getMetaData
()
->
tableSchema
;
$
values
=
$this
->
getChangedAttributes
(
$attributes
)
;
$command
=
$
builder
->
createInsertCommand
(
$table
,
$this
->
getAttributes
(
$attributes
)
);
$command
=
$
query
->
insert
(
$this
->
tableName
(),
$values
)
->
createCommand
(
$db
);
if
(
$command
->
execute
())
{
if
(
$command
->
execute
())
{
$
primaryKey
=
$table
->
primaryKey
;
$
table
=
$this
->
getMetaData
()
->
table
;
if
(
$table
->
sequenceName
!==
null
)
{
if
(
$table
->
sequenceName
!==
null
)
{
if
(
is_string
(
$primaryKey
)
&&
$this
->
$primaryKey
===
null
)
{
foreach
(
$table
->
primaryKey
as
$name
)
{
$this
->
$primaryKey
=
$builder
->
getLastInsertID
(
$table
);
if
(
$this
->
$name
===
null
)
{
}
elseif
(
is_array
(
$primaryKey
))
{
$this
->
_attributes
[
$name
]
=
$db
->
getLastInsertID
(
$table
->
sequenceName
);
foreach
(
$primaryKey
as
$pk
)
{
break
;
if
(
$this
->
$pk
===
null
)
{
$this
->
$pk
=
$builder
->
getLastInsertID
(
$table
);
break
;
}
}
}
}
}
}
}
$this
->
_pk
=
$this
->
getPrimaryKey
();
foreach
(
$values
as
$name
=>
$value
)
{
$this
->
_oldAttributes
[
$name
]
=
$this
->
_attributes
[
$name
];
}
$this
->
afterSave
();
$this
->
afterSave
();
$this
->
setIsNewRecord
(
false
);
$this
->
setIsNewRecord
(
false
);
$this
->
setScenario
(
'update'
);
return
true
;
return
true
;
}
}
}
}
...
@@ -912,21 +753,20 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -912,21 +753,20 @@ abstract class ActiveRecord extends \yii\base\Model
* @param array $attributes list of attributes that need to be saved. Defaults to null,
* @param array $attributes list of attributes that need to be saved. Defaults to null,
* meaning all attributes that are loaded from DB will be saved.
* meaning all attributes that are loaded from DB will be saved.
* @return boolean whether the update is successful
* @return boolean whether the update is successful
* @throws
C
Exception if the record is new
* @throws Exception if the record is new
*/
*/
public
function
update
(
$attributes
=
null
)
public
function
update
(
$attributes
=
null
)
{
{
if
(
$this
->
getIsNewRecord
())
{
throw
new
Exception
(
Yii
::
t
(
'yii'
,
'The active record cannot be updated because it is new.'
));
}
if
(
$this
->
beforeSave
())
{
if
(
$this
->
beforeSave
())
{
Yii
::
trace
(
get_class
(
$this
)
.
'.update()'
,
'system.db.ar.ActiveRecord'
);
$values
=
$this
->
getChangedAttributes
(
$attributes
);
if
(
$this
->
_pk
===
null
)
{
if
(
$values
!==
array
())
{
$this
->
_pk
=
$this
->
getPrimaryKey
();
$this
->
updateAll
(
$values
,
$this
->
getOldPrimaryKey
(
true
));
foreach
(
$values
as
$name
=>
$value
)
{
$this
->
_oldAttributes
[
$name
]
=
$this
->
_attributes
[
$name
];
}
}
}
$this
->
updateByPk
(
$this
->
getOldPrimaryKey
(),
$this
->
getAttributes
(
$attributes
));
$this
->
_pk
=
$this
->
getPrimaryKey
();
$this
->
afterSave
();
$this
->
afterSave
();
$this
->
setIsNewRecord
(
false
);
return
true
;
return
true
;
}
else
{
}
else
{
return
false
;
return
false
;
...
@@ -936,25 +776,26 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -936,25 +776,26 @@ abstract class ActiveRecord extends \yii\base\Model
/**
/**
* Saves a selected list of attributes.
* Saves a selected list of attributes.
* Unlike {@link save}, this method only saves the specified attributes
* Unlike {@link save}, this method only saves the specified attributes
* of an existing row
dataset
and does NOT call either {@link beforeSave} or {@link afterSave}.
* of an existing row and does NOT call either {@link beforeSave} or {@link afterSave}.
* Also note that this method does n
either attribute filtering nor validation
.
* Also note that this method does n
ot validate attributes
.
* So do not use this method with untrusted data (such as user posted data).
* So do not use this method with untrusted data (such as user posted data).
* You may consider the following alternative if you want to do so:
* You may consider the following alternative if you want to do so:
* <pre>
*
* $postRecord=Post::model()->findByPk($postID);
* ~~~
* $postRecord->attributes=$_POST['post'];
* $user = User::find($id)->one;
* $postRecord->save();
* $user->attributes = $_POST['User'];
* </pre>
* $user->save();
* ~~~
*
* @param array $attributes attributes to be updated. Each element represents an attribute name
* @param array $attributes attributes to be updated. Each element represents an attribute name
* or an attribute value indexed by its name. If the latter, the record's
* or an attribute value indexed by its name. If the latter, the record's
* attribute will be changed accordingly before saving.
* attribute will be changed accordingly before saving.
* @return boolean whether the update is successful
* @return boolean whether the update is successful
* @throws
C
Exception if the record is new or any database error
* @throws Exception if the record is new or any database error
*/
*/
public
function
saveAttributes
(
$attributes
)
public
function
saveAttributes
(
$attributes
)
{
{
if
(
!
$this
->
getIsNewRecord
())
{
if
(
!
$this
->
getIsNewRecord
())
{
Yii
::
trace
(
get_class
(
$this
)
.
'.saveAttributes()'
,
'system.db.ar.ActiveRecord'
);
$values
=
array
();
$values
=
array
();
foreach
(
$attributes
as
$name
=>
$value
)
{
foreach
(
$attributes
as
$name
=>
$value
)
{
if
(
is_integer
(
$name
))
{
if
(
is_integer
(
$name
))
{
...
@@ -963,17 +804,13 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -963,17 +804,13 @@ abstract class ActiveRecord extends \yii\base\Model
$values
[
$name
]
=
$this
->
$name
=
$value
;
$values
[
$name
]
=
$this
->
$name
=
$value
;
}
}
}
}
if
(
$this
->
_pk
===
null
)
{
$this
->
updateAll
(
$values
,
$this
->
getOldPrimaryKey
(
true
));
$this
->
_pk
=
$this
->
getPrimaryKey
();
foreach
(
$values
as
$name
=>
$value
)
{
}
$this
->
_oldAttributes
[
$name
]
=
$value
;
if
(
$this
->
updateByPk
(
$this
->
getOldPrimaryKey
(),
$values
)
>
0
)
{
$this
->
_pk
=
$this
->
getPrimaryKey
();
return
true
;
}
else
{
return
false
;
}
}
return
true
;
}
else
{
}
else
{
throw
new
Exception
(
Yii
::
t
(
'yii'
,
'The active record cannot be updated because it is new.'
)
);
throw
new
Exception
(
'The active record cannot be updated because it is new.'
);
}
}
}
}
...
@@ -993,59 +830,55 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -993,59 +830,55 @@ abstract class ActiveRecord extends \yii\base\Model
*/
*/
public
function
saveCounters
(
$counters
)
public
function
saveCounters
(
$counters
)
{
{
Yii
::
trace
(
get_class
(
$this
)
.
'.saveCounters()'
,
'system.db.ar.ActiveRecord'
);
if
(
!
$this
->
getIsNewRecord
())
{
$builder
=
$this
->
getCommandBuilder
();
$this
->
updateCounters
(
$counters
,
$this
->
getOldPrimaryKey
(
true
));
$table
=
$this
->
getTableSchema
();
$criteria
=
$builder
->
createPkCriteria
(
$table
,
$this
->
getOldPrimaryKey
());
$command
=
$builder
->
createUpdateCounterCommand
(
$this
->
getTableSchema
(),
$counters
,
$criteria
);
if
(
$command
->
execute
())
{
foreach
(
$counters
as
$name
=>
$value
)
{
foreach
(
$counters
as
$name
=>
$value
)
{
$this
->
$name
=
$this
->
$name
+
$value
;
$this
->
$name
+=
$value
;
$this
->
_oldAttributes
[
$name
]
=
$this
->
$name
;
}
}
return
true
;
return
true
;
}
else
{
}
else
{
return
false
;
throw
new
Exception
(
'The active record cannot be updated because it is new.'
)
;
}
}
}
}
/**
/**
* Deletes the row corresponding to this active record.
* Deletes the row corresponding to this active record.
* @return boolean whether the deletion is successful.
* @return boolean whether the deletion is successful.
* @throws
C
Exception if the record is new
* @throws Exception if the record is new
*/
*/
public
function
delete
()
public
function
delete
()
{
{
if
(
!
$this
->
getIsNewRecord
())
{
if
(
!
$this
->
getIsNewRecord
())
{
Yii
::
trace
(
get_class
(
$this
)
.
'.delete()'
,
'system.db.ar.ActiveRecord'
);
if
(
$this
->
beforeDelete
())
{
if
(
$this
->
beforeDelete
())
{
$result
=
$this
->
deleteByPk
(
$this
->
getPrimaryKey
())
>
0
;
$result
=
$this
->
deleteAll
(
$this
->
getPrimaryKey
(
true
))
>
0
;
$this
->
_oldAttributes
=
null
;
$this
->
afterDelete
();
$this
->
afterDelete
();
return
$result
;
return
$result
;
}
else
{
}
else
{
return
false
;
return
false
;
}
}
}
else
{
}
else
{
throw
new
Exception
(
Yii
::
t
(
'yii'
,
'The active record cannot be deleted because it is new.'
)
);
throw
new
Exception
(
'The active record cannot be deleted because it is new.'
);
}
}
}
}
/**
/**
* Repopulates this active record with the latest data.
* Repopulates this active record with the latest data.
* @param array $attributes
* @return boolean whether the row still exists in the database. If true, the latest data will be populated to this active record.
* @return boolean whether the row still exists in the database. If true, the latest data will be populated to this active record.
*/
*/
public
function
refresh
()
public
function
refresh
(
$attributes
=
null
)
{
{
Yii
::
trace
(
get_class
(
$this
)
.
'.refresh()'
,
'system.db.ar.ActiveRecord'
);
if
(
!
$this
->
getIsNewRecord
()
&&
(
$record
=
$this
->
find
(
$this
->
getPrimaryKey
(
true
)))
!==
null
)
{
if
(
!
$this
->
getIsNewRecord
()
&&
(
$record
=
$this
->
findByPk
(
$this
->
getPrimaryKey
()))
!==
null
)
{
if
(
$attributes
===
null
)
{
$attributes
=
$this
->
attributeNames
();
}
$this
->
_attributes
=
array
();
$this
->
_attributes
=
array
();
$this
->
_related
=
array
();
foreach
(
$attributes
as
$name
)
{
foreach
(
$this
->
getMetaData
()
->
columns
as
$name
=>
$column
)
{
$this
->
_attributes
[
$name
]
=
$record
->
_attributes
[
$name
];
if
(
property_exists
(
$this
,
$name
))
{
$this
->
$name
=
$record
->
$name
;
}
else
{
$this
->
_attributes
[
$name
]
=
$record
->
$name
;
}
}
}
$this
->
_oldAttributes
=
$this
->
_attributes
;
return
true
;
return
true
;
}
else
{
}
else
{
return
false
;
return
false
;
...
@@ -1065,13 +898,15 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -1065,13 +898,15 @@ abstract class ActiveRecord extends \yii\base\Model
/**
/**
* Returns the primary key value.
* Returns the primary key value.
* @param boolean $asArray whether to return the primary key value as an array. If true,
* the return value will be an array with column name as key and column value as value.
* @return mixed the primary key value. An array (column name=>column value) is returned if the primary key is composite.
* @return mixed the primary key value. An array (column name=>column value) is returned if the primary key is composite.
* If primary key is not defined, null will be returned.
* If primary key is not defined, null will be returned.
*/
*/
public
function
getPrimaryKey
()
public
function
getPrimaryKey
(
$asArray
=
false
)
{
{
$table
=
static
::
getMetaData
()
->
table
;
$table
=
static
::
getMetaData
()
->
table
;
if
(
count
(
$table
->
primaryKey
)
===
1
)
{
if
(
count
(
$table
->
primaryKey
)
===
1
&&
!
$asArray
)
{
return
$this
->
{
$table
->
primaryKey
[
0
]};
return
$this
->
{
$table
->
primaryKey
[
0
]};
}
else
{
}
else
{
$values
=
array
();
$values
=
array
();
...
@@ -1083,44 +918,27 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -1083,44 +918,27 @@ abstract class ActiveRecord extends \yii\base\Model
}
}
/**
/**
* Sets the primary key value.
* After calling this method, the old primary key value can be obtained from {@link oldPrimaryKey}.
* @param mixed $value the new primary key value. If the primary key is composite, the new value
* should be provided as an array (column name=>column value).
*/
public
function
setPrimaryKey
(
$value
)
{
$this
->
_pk
=
$this
->
getPrimaryKey
();
$table
=
$this
->
getMetaData
()
->
table
;
if
(
count
(
$table
->
primaryKey
)
===
1
)
{
$this
->
{
$table
->
primaryKey
[
0
]}
=
$value
;
}
else
{
foreach
(
$table
->
primaryKey
as
$name
)
{
$this
->
$name
=
$value
[
$name
];
}
}
}
/**
* Returns the old primary key value.
* Returns the old primary key value.
* This refers to the primary key value that is populated into the record
* This refers to the primary key value that is populated into the record
* after executing a find method (e.g. find(), findAll()).
* after executing a find method (e.g. find(), findAll()).
* The value remains unchanged even if the primary key attribute is manually assigned with a different value.
* The value remains unchanged even if the primary key attribute is manually assigned with a different value.
* @param boolean $asArray whether to return the primary key value as an array. If true,
* the return value will be an array with column name as key and column value as value.
* @return mixed the old primary key value. An array (column name=>column value) is returned if the primary key is composite.
* @return mixed the old primary key value. An array (column name=>column value) is returned if the primary key is composite.
* If primary key is not defined, null will be returned.
* If primary key is not defined, null will be returned.
*/
*/
public
function
getOldPrimaryKey
()
public
function
getOldPrimaryKey
(
$asArray
=
false
)
{
{
return
$this
->
_pk
;
$table
=
static
::
getMetaData
()
->
table
;
}
if
(
count
(
$table
->
primaryKey
)
===
1
&&
!
$asArray
)
{
return
isset
(
$this
->
_oldAttributes
[
$table
->
primaryKey
[
0
]])
?
$this
->
_oldAttributes
[
$table
->
primaryKey
[
0
]]
:
null
;
/**
}
else
{
* Sets the old primary key value.
$values
=
array
();
* @param mixed $value the old primary key value.
foreach
(
$table
->
primaryKey
as
$name
)
{
*/
$values
[
$name
]
=
isset
(
$this
->
_oldAttributes
[
$name
])
?
$this
->
_oldAttributes
[
$name
]
:
null
;
public
function
setOldPrimaryKey
(
$value
)
}
{
return
$values
;
$this
->
_pk
=
$value
;
}
}
}
/**
/**
...
@@ -1135,16 +953,13 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -1135,16 +953,13 @@ abstract class ActiveRecord extends \yii\base\Model
public
static
function
populateData
(
$row
)
public
static
function
populateData
(
$row
)
{
{
$record
=
static
::
instantiate
(
$row
);
$record
=
static
::
instantiate
(
$row
);
$record
->
setScenario
(
'update'
);
$columns
=
static
::
getMetaData
()
->
table
->
columns
;
$columns
=
static
::
getMetaData
()
->
table
->
columns
;
foreach
(
$row
as
$name
=>
$value
)
{
foreach
(
$row
as
$name
=>
$value
)
{
if
(
property_exists
(
$record
,
$name
))
{
if
(
isset
(
$columns
[
$name
]))
{
$record
->
$name
=
$value
;
}
elseif
(
isset
(
$columns
[
$name
]))
{
$record
->
_attributes
[
$name
]
=
$value
;
$record
->
_attributes
[
$name
]
=
$value
;
}
}
}
}
$record
->
_
pk
=
$record
->
getPrimaryKey
()
;
$record
->
_
oldAttributes
=
$record
->
_attributes
;
return
$record
;
return
$record
;
}
}
...
@@ -1158,7 +973,7 @@ abstract class ActiveRecord extends \yii\base\Model
...
@@ -1158,7 +973,7 @@ abstract class ActiveRecord extends \yii\base\Model
* @param array $row list of attribute values for the active records.
* @param array $row list of attribute values for the active records.
* @return ActiveRecord the active record
* @return ActiveRecord the active record
*/
*/
p
rotected
static
function
instantiate
(
$row
)
p
ublic
static
function
instantiate
(
$row
)
{
{
return
static
::
newInstance
();
return
static
::
newInstance
();
}
}
...
...
framework/db/ar/JoinElement.php
View file @
9d8a4012
<?php
<?php
/**
/**
*
ActiveQuery
class file.
*
JoinElement
class file.
*
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @link http://www.yiiframework.com/
...
@@ -80,7 +80,7 @@ class JoinElement extends \yii\base\Object
...
@@ -80,7 +80,7 @@ class JoinElement extends \yii\base\Object
$record
=
$modelClass
::
populateData
(
$attributes
);
$record
=
$modelClass
::
populateData
(
$attributes
);
foreach
(
$this
->
children
as
$child
)
{
foreach
(
$this
->
children
as
$child
)
{
if
(
$child
->
relation
->
select
!==
false
)
{
if
(
$child
->
relation
->
select
!==
false
)
{
$record
->
initRelat
edRecord
(
$child
->
relation
);
$record
->
initRelat
ion
(
$child
->
relation
);
}
}
}
}
$this
->
records
[
$pk
]
=
$record
;
$this
->
records
[
$pk
]
=
$record
;
...
...
framework/util/Text.php
View file @
9d8a4012
...
@@ -57,26 +57,32 @@ class Text
...
@@ -57,26 +57,32 @@ class Text
}
}
/**
/**
* Converts a
class
name into space-separated words.
* Converts a
CamelCase
name into space-separated words.
* For example, 'PostTag' will be converted
as
'Post Tag'.
* For example, 'PostTag' will be converted
to
'Post Tag'.
* @param string $name the string to be converted
* @param string $name the string to be converted
* @param boolean $ucwords whether to capitalize the first letter in each word
* @param boolean $ucwords whether to capitalize the first letter in each word
* @return string the resulting words
* @return string the resulting words
*/
*/
public
static
function
name
2words
(
$name
,
$ucwords
=
true
)
public
static
function
camel
2words
(
$name
,
$ucwords
=
true
)
{
{
$label
=
trim
(
strtolower
(
str_replace
(
array
(
'-'
,
'_'
,
'.'
),
' '
,
preg_replace
(
'/(?<![A-Z])[A-Z]/'
,
' \0'
,
$name
))));
$label
=
trim
(
strtolower
(
str_replace
(
array
(
'-'
,
'_'
,
'.'
),
' '
,
preg_replace
(
'/(?<![A-Z])[A-Z]/'
,
' \0'
,
$name
))));
return
$ucwords
?
ucwords
(
$label
)
:
$label
;
return
$ucwords
?
ucwords
(
$label
)
:
$label
;
}
}
/**
/**
* Converts a class name into a HTML ID.
* Converts a CamelCase name into an ID in lowercase.
* For example, 'PostTag' will be converted as 'post-tag'.
* Words in the ID may be concatenated using the specified character (defaults to '-').
* For example, 'PostTag' will be converted to 'post-tag'.
* @param string $name the string to be converted
* @param string $name the string to be converted
* @param string $separator the character used to concatenate the words in the ID
* @return string the resulting ID
* @return string the resulting ID
*/
*/
public
static
function
name2id
(
$name
)
public
static
function
camel2id
(
$name
,
$separator
=
'-'
)
{
{
return
trim
(
strtolower
(
str_replace
(
'_'
,
'-'
,
preg_replace
(
'/(?<![A-Z])[A-Z]/'
,
'-\0'
,
$name
))),
'-'
);
if
(
$separator
===
'_'
)
{
return
trim
(
strtolower
(
preg_replace
(
'/(?<![A-Z])[A-Z]/'
,
'_\0'
,
$name
)),
'_'
);
}
else
{
return
trim
(
strtolower
(
str_replace
(
'_'
,
$separator
,
preg_replace
(
'/(?<![A-Z])[A-Z]/'
,
$separator
.
'\0'
,
$name
))),
$separator
);
}
}
}
}
}
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