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
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Rotua Panjaitan
yii2
Commits
6dd495b6
Commit
6dd495b6
authored
Jan 17, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added init and afterFind events to AR.
Implemented scope support.
parent
ed8b7952
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
122 additions
and
14 deletions
+122
-14
ActiveRecord.md
docs/api/db/ActiveRecord.md
+83
-2
Object.php
framework/base/Object.php
+3
-2
ActiveQuery.php
framework/db/ActiveQuery.php
+0
-1
ActiveRecord.php
framework/db/ActiveRecord.php
+27
-0
Schema.php
framework/db/Schema.php
+8
-8
Schema.php
framework/db/mysql/Schema.php
+1
-1
No files found.
docs/api/db/ActiveRecord.md
View file @
6dd495b6
...
...
@@ -363,4 +363,86 @@ value of `$customer` and then call [[save()]] to save the order into database.
### Data Input and Validation
// todo
\ No newline at end of file
TBD
### Life Cycles of an ActiveRecord Object
An ActiveRecord object undergoes different life cycles when it is used in different cases.
Subclasses or ActiveRecord behaviors may "inject" custom code in these life cycles through
method overriding and event handling mechanisms.
When instantiating a new ActiveRecord instance, we will have the following life cycles:
1.
constructor
2.
[
[init()
]
]: will trigger an
[
[init
]
] event
When getting an ActiveRecord instance through the
[
[find()
]
] method, we will have the following life cycles:
1.
constructor
2.
[
[init()
]
]: will trigger an
[
[init
]
] event
3.
[
[afterFind()
]
]: will trigger an
[
[afterFind
]
] event
When calling
[
[save()
]
] to insert or update an ActiveRecord, we will have the following life cycles:
1.
[
[beforeValidate()
]
]: will trigger an
[
[beforeValidate
]
] event
2.
[
[beforeSave()
]
]: will trigger an
[
[beforeSave
]
] event
3.
perform the actual data insertion or updating
4.
[
[afterSave()
]
]: will trigger an
[
[afterSave
]
] event
5.
[
[afterValidate()
]
]: will trigger an
[
[afterValidate
]
] event
Finally when calling
[
[delete()
]
] to delete an ActiveRecord, we will have the following life cycles:
1.
[
[beforeDelete()
]
]: will trigger an
[
[beforeDelete
]
] event
2.
perform the actual data deletion
3.
[
[afterDelete()
]
]: will trigger an
[
[afterDelete
]
] event
### Scopes
A scope is a method that customizes a given
[
[ActiveQuery
]
] object. Scope methods are defined
in the ActiveRecord classes. They can be invoked through the
[
[ActiveQuery
]
] object that is created
via
[
[find()
]
] or
[
[findBySql()
]
]. The following is an example:
~~~
class Customer extends \yii\db\ActiveRecord
{
// ...
/**
* @param ActiveQuery $query
*/
public function active($query)
{
$query->andWhere('status = 1');
}
}
$customers = Customer::find()->active()->all();
~~~
In the above, the
`active()`
method is defined in
`Customer`
while we are calling it
through
`ActiveQuery`
returned by
`Customer::find()`
.
Scopes can be parameterized. For example, we can define and use the following
`olderThan`
scope:
~~~
class Customer extends \yii\db\ActiveRecord
{
// ...
/**
* @param ActiveQuery $query
* @param integer $age
*/
public function olderThan($query, $age = 30)
{
$query->andWhere('age > :age', array(':age' => $age));
}
}
$customers = Customer::find()->olderThan(50)->all();
~~~
The parameters should follow after the
`$query`
parameter when defining the scope method, and they
can take default values like shown above.
framework/base/Object.php
View file @
6dd495b6
...
...
@@ -78,7 +78,8 @@ class Object
* will be implicitly called when executing `$object->property = $value;`.
* @param string $name the property name or the event name
* @param mixed $value the property value
* @throws UnknownPropertyException if the property is not defined or read-only.
* @throws UnknownPropertyException if the property is not defined
* @throws InvalidCallException if the property is read-only.
* @see __get
*/
public
function
__set
(
$name
,
$value
)
...
...
@@ -122,7 +123,7 @@ class Object
* Note that if the property is not defined, this method will do nothing.
* If the property is read-only, it will throw an exception.
* @param string $name the property name
* @throws
UnknownProperty
Exception if the property is read only.
* @throws
InvalidCall
Exception if the property is read only.
*/
public
function
__unset
(
$name
)
{
...
...
framework/db/ActiveQuery.php
View file @
6dd495b6
...
...
@@ -14,7 +14,6 @@ use yii\db\Connection;
use
yii\db\Command
;
use
yii\db\QueryBuilder
;
use
yii\db\Expression
;
use
yii\db\Exception
;
/**
* ActiveQuery represents a DB query associated with an Active Record class.
...
...
framework/db/ActiveRecord.php
View file @
6dd495b6
...
...
@@ -32,6 +32,8 @@ use yii\util\StringHelper;
* @property mixed $primaryKey the primary key value.
* @property mixed $oldPrimaryKey the old primary key value.
*
* @event ModelEvent init an event that is triggered when the record is initialized (in [[init()]]).
* @event ModelEvent afterFind an event that is triggered after the record is created and populated with query result.
* @event ModelEvent beforeInsert an event that is triggered before inserting a record.
* You may set [[ModelEvent::isValid]] to be false to stop the insertion.
* @event Event afterInsert an event that is triggered before inserting a record.
...
...
@@ -762,6 +764,30 @@ class ActiveRecord extends Model
}
/**
* Initializes the object.
* This method is called at the end of the constructor.
* The default implementation will trigger an [[afterInsert]] event.
* If you override this method, make sure you call the parent implementation at the end
* to ensure triggering of the event.
*/
public
function
init
()
{
parent
::
init
();
$this
->
trigger
(
'init'
);
}
/**
* This method is called when the AR object is created and populated with the query result.
* The default implementation will trigger an [[afterFind]] event.
* When overriding this method, make sure you call the parent implementation to ensure the
* event is triggered.
*/
public
function
afterFind
()
{
$this
->
trigger
(
'afterFind'
);
}
/**
* Sets the value indicating whether the record is new.
* @param boolean $value whether the record is new and should be inserted when calling [[save()]].
* @see getIsNewRecord
...
...
@@ -956,6 +982,7 @@ class ActiveRecord extends Model
}
}
$record
->
_oldAttributes
=
$record
->
_attributes
;
$record
->
afterFind
();
return
$record
;
}
...
...
framework/db/Schema.php
View file @
6dd495b6
...
...
@@ -329,10 +329,10 @@ abstract class Schema extends \yii\base\Object
/**
* Extracts the PHP type from abstract DB type.
* @param
string $type abstract DB type
* @param
ColumnSchema $column the column schema information
* @return string PHP type name
*/
protected
function
getColumnPhpType
(
$
type
)
protected
function
getColumnPhpType
(
$
column
)
{
static
$typeMap
=
array
(
// abstract type => php type
'smallint'
=>
'integer'
,
...
...
@@ -341,13 +341,13 @@ abstract class Schema extends \yii\base\Object
'boolean'
=>
'boolean'
,
'float'
=>
'double'
,
);
if
(
isset
(
$typeMap
[
$type
]))
{
if
(
$type
===
'bigint'
)
{
return
PHP_INT_SIZE
==
8
&&
!
$
this
->
unsigned
?
'integer'
:
'string'
;
}
elseif
(
$type
===
'integer'
)
{
return
PHP_INT_SIZE
==
4
&&
$
this
->
unsigned
?
'string'
:
'integer'
;
if
(
isset
(
$typeMap
[
$
column
->
type
]))
{
if
(
$
column
->
type
===
'bigint'
)
{
return
PHP_INT_SIZE
==
8
&&
!
$
column
->
unsigned
?
'integer'
:
'string'
;
}
elseif
(
$
column
->
type
===
'integer'
)
{
return
PHP_INT_SIZE
==
4
&&
$
column
->
unsigned
?
'string'
:
'integer'
;
}
else
{
return
$typeMap
[
$
this
->
type
];
return
$typeMap
[
$
column
->
type
];
}
}
else
{
return
'string'
;
...
...
framework/db/mysql/Schema.php
View file @
6dd495b6
...
...
@@ -165,7 +165,7 @@ class Schema extends \yii\db\Schema
}
}
$column
->
phpType
=
$this
->
getColumnPhpType
(
$column
->
type
);
$column
->
phpType
=
$this
->
getColumnPhpType
(
$column
);
if
(
$column
->
type
!==
'timestamp'
||
$info
[
'Default'
]
!==
'CURRENT_TIMESTAMP'
)
{
$column
->
defaultValue
=
$column
->
typecast
(
$info
[
'Default'
]);
...
...
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