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
3ba68632
Commit
3ba68632
authored
Jul 15, 2011
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finished Vector.
parent
0918f32e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
609 additions
and
132 deletions
+609
-132
Component.php
framework/base/Component.php
+142
-130
Event.php
framework/base/Event.php
+2
-2
Exception.php
framework/base/Exception.php
+25
-0
Vector.php
framework/base/Vector.php
+345
-0
VectorIterator.php
framework/base/VectorIterator.php
+95
-0
No files found.
framework/base/Component.php
View file @
3ba68632
...
...
@@ -5,7 +5,7 @@ namespace yii\base;
class
Component
{
private
$_e
;
private
$_
m
;
private
$_
b
;
/**
* Returns a property value, an event handler list or a behavior based on its name.
...
...
@@ -23,26 +23,27 @@ class Component
public
function
__get
(
$name
)
{
$getter
=
'get'
.
$name
;
if
(
method_exists
(
$this
,
$getter
)
)
if
(
method_exists
(
$this
,
$getter
))
{
// read property, e.g. getName(
)
return
$this
->
$getter
();
else
if
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
$this
->
_e
[
$name
]
=
new
yii\collections\Vector
;
}
elseif
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
// event, e.g. onClick()
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
{
$this
->
_e
[
$name
]
=
new
\yii\collections\Vector
;
}
return
$this
->
_e
[
$name
];
}
else
if
(
isset
(
$this
->
_m
[
$name
]))
return
$this
->
_m
[
$name
];
else
if
(
is_array
(
$this
->
_m
))
// has attached behaviors
{
foreach
(
$this
->
_m
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canGetProperty
(
$name
))
elseif
(
isset
(
$this
->
_b
[
$name
]))
{
// behavior
return
$this
->
_b
[
$name
];
}
elseif
(
is_array
(
$this
->
_b
))
{
// a behavior property
foreach
(
$this
->
_b
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canGetProperty
(
$name
))
{
return
$object
->
$name
;
}
}
throw
new
Exception
(
'Undefined property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
throw
new
Exception
(
'Getting unknown property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
/**
...
...
@@ -58,30 +59,32 @@ class Component
* @throws CException if the property/event is not defined or the property is read only.
* @see __get
*/
public
function
__set
(
$name
,
$value
)
public
function
__set
(
$name
,
$value
)
{
$setter
=
'set'
.
$name
;
if
(
method_exists
(
$this
,
$setter
))
$setter
=
'set'
.
$name
;
if
(
method_exists
(
$this
,
$setter
))
{
return
$this
->
$setter
(
$value
);
else
if
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
$this
->
_e
[
$name
]
=
new
yii\collections\Vector
;
}
elseif
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
{
$this
->
_e
[
$name
]
=
new
\yii\collections\Vector
;
}
return
$this
->
_e
[
$name
]
->
add
(
$value
);
}
else
if
(
is_array
(
$this
->
_m
))
{
foreach
(
$this
->
_m
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canSetProperty
(
$name
))
return
$object
->
$name
=
$value
;
elseif
(
is_array
(
$this
->
_b
))
{
foreach
(
$this
->
_b
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canSetProperty
(
$name
))
{
return
$object
->
$name
=
$value
;
}
}
if
(
method_exists
(
$this
,
'get'
.
$name
))
throw
new
Exception
(
'Unable to set read-only property: '
.
get_class
(
$this
)
.
'.'
$name
);
else
throw
new
Exception
(
'Undefined property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
if
(
method_exists
(
$this
,
'get'
.
$name
))
{
throw
new
Exception
(
'Setting read-only property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
else
{
throw
new
Exception
(
'Setting unknown property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
}
/**
...
...
@@ -93,23 +96,23 @@ class Component
*/
public
function
__isset
(
$name
)
{
$getter
=
'get'
.
$name
;
if
(
method_exists
(
$this
,
$getter
))
return
$this
->
$getter
()
!==
null
;
else
if
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
$name
=
strtolower
(
$name
);
$getter
=
'get'
.
$name
;
if
(
method_exists
(
$this
,
$getter
))
{
// property is not null
return
$this
->
$getter
()
!==
null
;
}
elseif
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
// has event handler
$name
=
strtolower
(
$name
);
return
isset
(
$this
->
_e
[
$name
])
&&
$this
->
_e
[
$name
]
->
getCount
();
}
else
if
(
isset
(
$this
->
_m
[
$name
]))
return
true
;
else
if
(
is_array
(
$this
->
_m
))
{
foreach
(
$this
->
_m
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canGetProperty
(
$name
))
elseif
(
isset
(
$this
->
_b
[
$name
]))
{
// has behavior
return
true
;
}
elseif
(
is_array
(
$this
->
_b
))
{
foreach
(
$this
->
_b
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canGetProperty
(
$name
))
{
return
$object
->
$name
!==
null
;
}
}
}
return
false
;
}
...
...
@@ -124,23 +127,26 @@ class Component
*/
public
function
__unset
(
$name
)
{
$setter
=
'set'
.
$name
;
if
(
method_exists
(
$this
,
$setter
))
$setter
=
'set'
.
$name
;
if
(
method_exists
(
$this
,
$setter
))
{
$this
->
$setter
(
null
);
else
if
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
}
elseif
(
method_exists
(
$this
,
$name
)
&&
strncasecmp
(
$name
,
'on'
,
2
)
===
0
)
{
unset
(
$this
->
_e
[
strtolower
(
$name
)]);
else
if
(
isset
(
$this
->
_m
[
$name
]))
}
elseif
(
isset
(
$this
->
_b
[
$name
]))
{
$this
->
detachBehavior
(
$name
);
else
if
(
is_array
(
$this
->
_m
))
{
foreach
(
$this
->
_m
as
$object
)
}
elseif
(
is_array
(
$this
->
_b
))
{
foreach
(
$this
->
_b
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
$object
->
canSetProperty
(
$name
))
return
$object
->
$name
=
null
;
if
(
$object
->
getEnabled
()
&&
$object
->
canSetProperty
(
$name
))
{
return
$object
->
$name
=
null
;
}
}
}
else
if
(
method_exists
(
$this
,
'get'
.
$name
))
throw
new
Exception
(
'Un
able to unset
read-only property: '
.
get_class
(
$this
)
.
'.'
$name
);
else
if
(
method_exists
(
$this
,
'get'
.
$name
))
throw
new
Exception
(
'Un
setting
read-only property: '
.
get_class
(
$this
)
.
'.'
$name
);
}
/**
...
...
@@ -152,18 +158,23 @@ class Component
* @return mixed the method return value
* @since 1.0.2
*/
public
function
__call
(
$name
,
$parameters
)
public
function
__call
(
$name
,
$parameters
)
{
if
(
$this
->
_m
!==
null
)
if
(
$this
->
_b
!==
null
)
{
foreach
(
$this
->
_m
as
$object
)
foreach
(
$this
->
_b
as
$object
)
{
if
(
$object
->
getEnabled
()
&&
method_exists
(
$object
,
$name
))
return
call_user_func_array
(
array
(
$object
,
$name
),
$parameters
);
if
(
$object
->
getEnabled
()
&&
method_exists
(
$object
,
$name
))
{
return
call_user_func_array
(
array
(
$object
,
$name
),
$parameters
);
}
}
}
if
(
$this
->
canGetProperty
(
$name
))
{
$func
=
$this
->
$name
;
if
(
$func
instanceof
\Closure
)
{
return
call_user_func_array
(
$func
,
$parameters
);
}
}
if
(
$this
->
canGetProperty
(
$name
)
&&
$this
->
$name
instanceof
\Closure
)
return
call_user_func_array
(
$this
->
$name
,
$parameters
);
throw
new
Exception
(
'Unknown method: '
.
get_class
(
$this
)
.
'::'
$name
.
'()'
);
}
...
...
@@ -176,7 +187,7 @@ class Component
*/
public
function
asa
(
$behavior
)
{
return
isset
(
$this
->
_
m
[
$behavior
])
?
$this
->
_m
[
$behavior
]
:
null
;
return
isset
(
$this
->
_
b
[
$behavior
])
?
$this
->
_b
[
$behavior
]
:
null
;
}
/**
...
...
@@ -196,8 +207,8 @@ class Component
*/
public
function
attachBehaviors
(
$behaviors
)
{
foreach
(
$behaviors
as
$name
=>
$behavior
)
$this
->
attachBehavior
(
$name
,
$behavior
);
foreach
(
$behaviors
as
$name
=>
$behavior
)
$this
->
attachBehavior
(
$name
,
$behavior
);
}
/**
...
...
@@ -206,11 +217,11 @@ class Component
*/
public
function
detachBehaviors
()
{
if
(
$this
->
_m
!==
null
)
if
(
$this
->
_b
!==
null
)
{
foreach
(
$this
->
_m
as
$name
=>
$behavior
)
foreach
(
$this
->
_b
as
$name
=>
$behavior
)
$this
->
detachBehavior
(
$name
);
$this
->
_
m
=
null
;
$this
->
_
b
=
null
;
}
}
...
...
@@ -225,13 +236,13 @@ class Component
* @return IBehavior the behavior object
* @since 1.0.2
*/
public
function
attachBehavior
(
$name
,
$behavior
)
public
function
attachBehavior
(
$name
,
$behavior
)
{
if
(
!
(
$behavior
instanceof
IBehavior
))
$behavior
=
Yii
::
createComponent
(
$behavior
);
if
(
!
(
$behavior
instanceof
IBehavior
))
$behavior
=
Yii
::
createComponent
(
$behavior
);
$behavior
->
setEnabled
(
true
);
$behavior
->
attach
(
$this
);
return
$this
->
_
m
[
$name
]
=
$behavior
;
return
$this
->
_
b
[
$name
]
=
$behavior
;
}
/**
...
...
@@ -243,11 +254,11 @@ class Component
*/
public
function
detachBehavior
(
$name
)
{
if
(
isset
(
$this
->
_m
[
$name
]))
if
(
isset
(
$this
->
_b
[
$name
]))
{
$this
->
_
m
[
$name
]
->
detach
(
$this
);
$behavior
=
$this
->
_m
[
$name
];
unset
(
$this
->
_
m
[
$name
]);
$this
->
_
b
[
$name
]
->
detach
(
$this
);
$behavior
=
$this
->
_b
[
$name
];
unset
(
$this
->
_
b
[
$name
]);
return
$behavior
;
}
}
...
...
@@ -258,9 +269,9 @@ class Component
*/
public
function
enableBehaviors
()
{
if
(
$this
->
_m
!==
null
)
if
(
$this
->
_b
!==
null
)
{
foreach
(
$this
->
_m
as
$behavior
)
foreach
(
$this
->
_b
as
$behavior
)
$behavior
->
setEnabled
(
true
);
}
}
...
...
@@ -271,9 +282,9 @@ class Component
*/
public
function
disableBehaviors
()
{
if
(
$this
->
_m
!==
null
)
if
(
$this
->
_b
!==
null
)
{
foreach
(
$this
->
_m
as
$behavior
)
foreach
(
$this
->
_b
as
$behavior
)
$behavior
->
setEnabled
(
false
);
}
}
...
...
@@ -287,8 +298,8 @@ class Component
*/
public
function
enableBehavior
(
$name
)
{
if
(
isset
(
$this
->
_m
[
$name
]))
$this
->
_
m
[
$name
]
->
setEnabled
(
true
);
if
(
isset
(
$this
->
_b
[
$name
]))
$this
->
_
b
[
$name
]
->
setEnabled
(
true
);
}
/**
...
...
@@ -299,8 +310,8 @@ class Component
*/
public
function
disableBehavior
(
$name
)
{
if
(
isset
(
$this
->
_m
[
$name
]))
$this
->
_
m
[
$name
]
->
setEnabled
(
false
);
if
(
isset
(
$this
->
_b
[
$name
]))
$this
->
_
b
[
$name
]
->
setEnabled
(
false
);
}
/**
...
...
@@ -308,13 +319,14 @@ class Component
* A property is defined if there is a getter or setter method
* defined in the class. Note, property names are case-insensitive.
* @param string $name the property name
* @param boolean $checkVar whether to check class properties. If false, only properties declared by getters will be checked.
* @return boolean whether the property is defined
* @see canGetProperty
* @see canSetProperty
*/
public
function
hasProperty
(
$name
)
public
function
hasProperty
(
$name
,
$checkVar
=
true
)
{
return
method_exists
(
$this
,
'get'
.
$name
)
||
method_exists
(
$this
,
'set'
.
$name
);
return
method_exists
(
$this
,
'get'
.
$name
)
||
method_exists
(
$this
,
'set'
.
$name
)
||
property_exists
(
$this
,
$name
);
}
/**
...
...
@@ -326,9 +338,9 @@ class Component
* @return boolean whether the property can be read
* @see canSetProperty
*/
public
function
canGetProperty
(
$name
,
$checkVar
=
true
)
public
function
canGetProperty
(
$name
,
$checkVar
=
true
)
{
return
method_exists
(
$this
,
'get'
.
$name
)
||
$checkVar
&&
property_exists
(
$this
,
$name
);
return
method_exists
(
$this
,
'get'
.
$name
)
||
$checkVar
&&
property_exists
(
$this
,
$name
);
}
/**
...
...
@@ -340,9 +352,9 @@ class Component
* @return boolean whether the property can be written
* @see canGetProperty
*/
public
function
canSetProperty
(
$name
,
$checkVar
=
true
)
public
function
canSetProperty
(
$name
,
$checkVar
=
true
)
{
return
method_exists
(
$this
,
'set'
.
$name
)
||
$checkVar
&&
property_exists
(
$this
,
$name
);
return
method_exists
(
$this
,
'set'
.
$name
)
||
$checkVar
&&
property_exists
(
$this
,
$name
);
}
/**
...
...
@@ -354,7 +366,7 @@ class Component
*/
public
function
hasEvent
(
$name
)
{
return
!
strncasecmp
(
$name
,
'on'
,
2
)
&&
method_exists
(
$this
,
$name
);
return
!
strncasecmp
(
$name
,
'on'
,
2
)
&&
method_exists
(
$this
,
$name
);
}
/**
...
...
@@ -364,8 +376,8 @@ class Component
*/
public
function
hasEventHandler
(
$name
)
{
$name
=
strtolower
(
$name
);
return
isset
(
$this
->
_e
[
$name
])
&&
$this
->
_e
[
$name
]
->
getCount
()
>
0
;
$name
=
strtolower
(
$name
);
return
isset
(
$this
->
_e
[
$name
])
&&
$this
->
_e
[
$name
]
->
getCount
()
>
0
;
}
/**
...
...
@@ -376,16 +388,16 @@ class Component
*/
public
function
getEventHandlers
(
$name
)
{
if
(
$this
->
hasEvent
(
$name
))
if
(
$this
->
hasEvent
(
$name
))
{
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
$this
->
_e
[
$name
]
=
new
CList
;
$name
=
strtolower
(
$name
);
if
(
!
isset
(
$this
->
_e
[
$name
]))
$this
->
_e
[
$name
]
=
new
CList
;
return
$this
->
_e
[
$name
];
}
else
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is not defined.'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
)));
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is not defined.'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
)));
}
/**
...
...
@@ -420,7 +432,7 @@ class Component
* @throws CException if the event is not defined
* @see detachEventHandler
*/
public
function
attachEventHandler
(
$name
,
$handler
)
public
function
attachEventHandler
(
$name
,
$handler
)
{
$this
->
getEventHandlers
(
$name
)
->
add
(
$handler
);
}
...
...
@@ -433,10 +445,10 @@ class Component
* @return boolean if the detachment process is successful
* @see attachEventHandler
*/
public
function
detachEventHandler
(
$name
,
$handler
)
public
function
detachEventHandler
(
$name
,
$handler
)
{
if
(
$this
->
hasEventHandler
(
$name
))
return
$this
->
getEventHandlers
(
$name
)
->
remove
(
$handler
)
!==
false
;
if
(
$this
->
hasEventHandler
(
$name
))
return
$this
->
getEventHandlers
(
$name
)
->
remove
(
$handler
)
!==
false
;
else
return
false
;
}
...
...
@@ -449,43 +461,43 @@ class Component
* @param CEvent $event the event parameter
* @throws CException if the event is undefined or an event handler is invalid.
*/
public
function
raiseEvent
(
$name
,
$event
)
public
function
raiseEvent
(
$name
,
$event
)
{
$name
=
strtolower
(
$name
);
if
(
isset
(
$this
->
_e
[
$name
]))
$name
=
strtolower
(
$name
);
if
(
isset
(
$this
->
_e
[
$name
]))
{
foreach
(
$this
->
_e
[
$name
]
as
$handler
)
foreach
(
$this
->
_e
[
$name
]
as
$handler
)
{
if
(
is_string
(
$handler
))
call_user_func
(
$handler
,
$event
);
else
if
(
is_callable
(
$handler
,
true
))
if
(
is_string
(
$handler
))
call_user_func
(
$handler
,
$event
);
else
if
(
is_callable
(
$handler
,
true
))
{
if
(
is_array
(
$handler
))
if
(
is_array
(
$handler
))
{
// an array: 0 - object, 1 - method name
list
(
$object
,
$method
)
=
$handler
;
if
(
is_string
(
$object
))
// static method call
call_user_func
(
$handler
,
$event
);
else
if
(
method_exists
(
$object
,
$method
))
list
(
$object
,
$method
)
=
$handler
;
if
(
is_string
(
$object
))
// static method call
call_user_func
(
$handler
,
$event
);
else
if
(
method_exists
(
$object
,
$method
))
$object
->
$method
(
$event
);
else
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is attached with an invalid handler "{handler}".'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
,
'{handler}'
=>
$handler
[
1
])));
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is attached with an invalid handler "{handler}".'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
,
'{handler}'
=>
$handler
[
1
])));
}
else
// PHP 5.3: anonymous function
call_user_func
(
$handler
,
$event
);
call_user_func
(
$handler
,
$event
);
}
else
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is attached with an invalid handler "{handler}".'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
,
'{handler}'
=>
gettype
(
$handler
))));
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is attached with an invalid handler "{handler}".'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
,
'{handler}'
=>
gettype
(
$handler
))));
// stop further handling if param.handled is set true
if
((
$event
instanceof
CEvent
)
&&
$event
->
handled
)
if
((
$event
instanceof
CEvent
)
&&
$event
->
handled
)
return
;
}
}
else
if
(
YII_DEBUG
&&
!
$this
->
hasEvent
(
$name
))
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is not defined.'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
)));
else
if
(
YII_DEBUG
&&
!
$this
->
hasEvent
(
$name
))
throw
new
CException
(
Yii
::
t
(
'yii'
,
'Event "{class}.{event}" is not defined.'
,
array
(
'{class}'
=>
get_class
(
$this
),
'{event}'
=>
$name
)));
}
/**
...
...
@@ -510,16 +522,16 @@ class Component
* @return mixed the expression result
* @since 1.1.0
*/
public
function
evaluateExpression
(
$_expression_
,
$_data_
=
array
())
public
function
evaluateExpression
(
$_expression_
,
$_data_
=
array
())
{
if
(
is_string
(
$_expression_
))
if
(
is_string
(
$_expression_
))
{
extract
(
$_data_
);
return
eval
(
'return '
.
$_expression_
.
';'
);
return
eval
(
'return '
.
$_expression_
.
';'
);
}
else
{
$_data_
[]
=
$this
;
$_data_
[]
=
$this
;
return
call_user_func_array
(
$_expression_
,
$_data_
);
}
}
...
...
framework/base/Event.php
View file @
3ba68632
...
...
@@ -3,7 +3,7 @@
namespace
yii\base
;
/**
*
C
Event is the base class for all event classes.
* Event is the base class for all event classes.
*
* It encapsulates the parameters associated with an event.
* The {@link sender} property describes who raises the event.
...
...
@@ -16,7 +16,7 @@ namespace yii\base;
* @package system.base
* @since 1.0
*/
class
CEvent
extends
C
Component
class
Event
extends
Component
{
/**
* @var object the sender of this event
...
...
framework/base/Exception.php
0 → 100644
View file @
3ba68632
<?php
namespace
yii\base
;
/**
* Exception class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2011 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
/**
* Exception represents a generic exception for all purposes.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Id: CException.php 2799 2011-01-01 19:31:13Z qiang.xue $
* @package system.base
* @since 1.0
*/
class
Exception
extends
\Exception
{
}
framework/base/Vector.php
0 → 100644
View file @
3ba68632
<?php
/**
* Vector class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\base
;
/**
* Vector implements an integer-indexed collection class.
*
* You can access, append, insert, remove an item from the vector
* by calling methods such as [[itemAt]], [[add]], [[insertAt]],
* [[remove]] and [[removeAt]].
*
* To get the number of the items in the vector, use [[getCount]].
*
* Because Vector implements a set of SPL interfaces, it can be used
* like a regular PHP array as follows,
*
* ~~~php
* $vector[] = $item; // append new item at the end
* $vector[$index] = $item; // set new item at $index
* unset($vector[$index]); // remove the item at $index
* if (isset($vector[$index])) // if the vector has an item at $index
* foreach ($vector as $index=>$item) // traverse each item in the vector
* $n = count($vector); // count the number of items
* ~~~
*
* Note that if you plan to extend Vector by performing additional operations
* with each addition or removal of an item (e.g. performing type check),
* please make sure you override [[insertAt]] and [[removeAt]].
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
Vector
extends
Component
implements
\IteratorAggregate
,
\ArrayAccess
,
\Countable
{
/**
* @var boolean whether this vector is read-only or not.
* If the vector is read-only, adding or moving items will throw an exception.
*/
public
$readOnly
;
/**
* @var array internal data storage
*/
private
$_d
=
array
();
/**
* @var integer number of items
*/
private
$_c
=
0
;
/**
* Constructor.
* Initializes the vector with an array or an iterable object.
* @param mixed $data the initial data to be populated into the vector.
* This can be an array or an iterable object. If null, the vector will be set as empty.
* @param boolean $readOnly whether the vector should be marked as read-only.
* @throws Exception if data is not well formed (neither an array nor an iterable object)
*/
public
function
__construct
(
$data
=
array
(),
$readOnly
=
false
)
{
if
(
$data
!==
array
())
{
$this
->
copyFrom
(
$data
);
}
$this
->
readOnly
=
$readOnly
;
}
/**
* Returns an iterator for traversing the items in the vector.
* This method is required by the SPL interface `IteratorAggregate`.
* It will be implicitly called when you use `foreach` to traverse the vector.
* @return Iterator an iterator for traversing the items in the vector.
*/
public
function
getIterator
()
{
return
new
VectorIterator
(
$this
->
_d
);
}
/**
* Returns the number of items in the vector.
* This method is required by the SPL `Countable` interface.
* It will be implicitly called when you use `count($vector)`.
* @return integer number of items in the vector.
*/
public
function
count
()
{
return
$this
->
getCount
();
}
/**
* Returns the number of items in the vector.
* @return integer the number of items in the vector
*/
public
function
getCount
()
{
return
$this
->
_c
;
}
/**
* Returns the item at the specified index.
* @param integer $index the index of the item
* @return mixed the item at the index
* @throws Exception if the index is out of range
*/
public
function
itemAt
(
$index
)
{
if
(
isset
(
$this
->
_d
[
$index
]))
{
return
$this
->
_d
[
$index
];
}
elseif
(
$index
>=
0
&&
$index
<
$this
->
_c
)
{
// in case the value is null
return
$this
->
_d
[
$index
];
}
throw
new
Exception
(
'Index out of range: '
.
$index
);
}
/**
* Appends an item at the end of the vector.
* @param mixed $item new item
* @return integer the zero-based index at which the item is added
* @throws Exception if the vector is read-only.
*/
public
function
add
(
$item
)
{
$this
->
insertAt
(
$this
->
_c
,
$item
);
return
$this
->
_c
-
1
;
}
/**
* Inserts an item at the specified position.
* Original item at the position and the following items will be moved
* one step towards the end.
* @param integer $index the specified position.
* @param mixed $item new item to be inserted into the vector
* @throws Exception if the index specified is out of range, or the vector is read-only.
*/
public
function
insertAt
(
$index
,
$item
)
{
if
(
!
$this
->
readOnly
)
{
if
(
$index
===
$this
->
_c
)
{
$this
->
_d
[
$this
->
_c
++
]
=
$item
;
}
elseif
(
$index
>=
0
&&
$index
<
$this
->
_c
)
{
array_splice
(
$this
->
_d
,
$index
,
0
,
array
(
$item
));
$this
->
_c
++
;
}
throw
new
Exception
(
'Index out of range: '
.
$index
);
}
throw
new
Exception
(
'Vector is read only.'
);
}
/**
* Removes an item from the vector.
* The vector will search for the item, and the first item found
* will be removed from the vector.
* @param mixed $item the item to be removed.
* @return mixed the index at which the item is being removed, or false
* if the item cannot be found in the vector.
* @throws Exception if the vector is read only.
*/
public
function
remove
(
$item
)
{
if
((
$index
=
$this
->
indexOf
(
$item
))
>=
0
)
{
$this
->
removeAt
(
$index
);
return
$index
;
}
else
return
false
;
}
/**
* Removes an item at the specified position.
* @param integer $index the index of the item to be removed.
* @return mixed the removed item.
* @throws Exception if the index is out of range, or the vector is read only.
*/
public
function
removeAt
(
$index
)
{
if
(
!
$this
->
readOnly
)
{
if
(
$index
>=
0
&&
$index
<
$this
->
_c
)
{
$this
->
_c
--
;
if
(
$index
===
$this
->
_c
)
{
return
array_pop
(
$this
->
_d
);
}
else
{
$item
=
$this
->
_d
[
$index
];
array_splice
(
$this
->
_d
,
$index
,
1
);
return
$item
;
}
}
throw
new
Exception
(
'Index out of range: '
.
$index
);
}
throw
new
Exception
(
'Vector is read only.'
);
}
/**
* Removes all items from the vector.
*/
public
function
clear
()
{
for
(
$i
=
$this
->
_c
-
1
;
$i
>=
0
;
--
$i
)
{
$this
->
removeAt
(
$i
);
}
}
/**
* Returns a value indicating whether the vector contains the specified item.
* Note that the search is based on strict PHP comparison.
* @param mixed $item the item
* @return boolean whether the vector contains the item
*/
public
function
contains
(
$item
)
{
return
$this
->
indexOf
(
$item
)
>=
0
;
}
/**
* Returns the index of the specified item in the vector.
* The index is zero-based. If the item is not found in the vector, -1 will be returned.
* Note that the search is based on strict PHP comparison.
* @param mixed $item the item
* @return integer the index of the item in the vector (0 based), -1 if not found.
*/
public
function
indexOf
(
$item
)
{
$index
=
array_search
(
$item
,
$this
->
_d
,
true
);
return
$index
===
false
?
-
1
:
$index
;
}
/**
* Returns the vector as a PHP array.
* @return array the items in the vector.
*/
public
function
toArray
()
{
return
$this
->
_d
;
}
/**
* Copies iterable data into the vector.
* Note, existing data in the vector will be cleared first.
* @param mixed $data the data to be copied from, must be an array or an object implementing `Traversable`
* @throws Exception if data is neither an array nor an object implementing `Traversable`.
*/
public
function
copyFrom
(
$data
)
{
if
(
is_array
(
$data
)
||
(
$data
instanceof
Traversable
))
{
if
(
$this
->
_c
>
0
)
{
$this
->
clear
();
}
if
(
$data
instanceof
self
)
{
$data
=
$data
->
_d
;
}
foreach
(
$data
as
$item
)
{
$this
->
add
(
$item
);
}
}
throw
new
Exception
(
'Data must be either an array or an object implementing Traversable.'
);
}
/**
* Merges iterable data into the vector.
* New items will be appended to the end of the existing items.
* @param mixed $data the data to be merged with, must be an array or an object implementing `Traversable`
* @throws Exception if data is neither an array nor an object implementing `Traversable`.
*/
public
function
mergeWith
(
$data
)
{
if
(
is_array
(
$data
)
||
(
$data
instanceof
Traversable
))
{
if
(
$data
instanceof
Vector
)
{
$data
=
$data
->
_d
;
}
foreach
(
$data
as
$item
)
{
$this
->
add
(
$item
);
}
}
throw
new
Exception
(
'Data must be either an array or an object implementing Traversable.'
);
}
/**
* Returns a value indicating whether there is an item at the specified offset.
* This method is required by the SPL interface `ArrayAccess`.
* It is implicitly called when you use something like `isset($vector[$index])`.
* @param integer $offset the offset to be checked
* @return boolean whether there is an item at the specified offset.
*/
public
function
offsetExists
(
$offset
)
{
return
$offset
>=
0
&&
$offset
<
$this
->
_c
;
}
/**
* Returns the item at the specified offset.
* This method is required by the SPL interface `ArrayAccess`.
* It is implicitly called when you use something like `$value = $vector[$index];`.
* @param integer $offset the offset to retrieve item.
* @return mixed the item at the offset
* @throws Exception if the offset is out of range
*/
public
function
offsetGet
(
$offset
)
{
return
$this
->
itemAt
(
$offset
);
}
/**
* Sets the item at the specified offset.
* This method is required by the SPL interface `ArrayAccess`.
* It is implicitly called when you use something like `$vector[$index] = $value;`.
* If the offset is null or equal to the number of the existing items,
* the new item will be appended to the vector.
* Otherwise, the existing item at the offset will be replaced with the new item.
* @param integer $offset the offset to set item
* @param mixed $item the item value
* @throws Exception if the offset is out of range, or the vector is read only.
*/
public
function
offsetSet
(
$offset
,
$item
)
{
if
(
$offset
===
null
||
$offset
===
$this
->
_c
)
{
$this
->
insertAt
(
$this
->
_c
,
$item
);
}
else
{
$this
->
removeAt
(
$offset
);
$this
->
insertAt
(
$offset
,
$item
);
}
}
/**
* Unsets the item at the specified offset.
* This method is required by the SPL interface `ArrayAccess`.
* It is implicitly called when you use something like `unset($vector[$index])`.
* This is equivalent to [[removeAt]].
* @param integer $offset the offset to unset item
* @throws Exception if the offset is out of range, or the vector is read only.
*/
public
function
offsetUnset
(
$offset
)
{
$this
->
removeAt
(
$offset
);
}
}
framework/base/VectorIterator.php
0 → 100644
View file @
3ba68632
<?php
/**
* VectorIterator class file.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.yiiframework.com/
* @copyright Copyright © 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace
yii\base
;
/**
* VectorIterator implements the SPL `Iterator` interface for [[Vector]].
*
* It allows [[Vector]] to return a new iterator for data traversing purpose.
* You normally do not use this class directly.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class
VectorIterator
implements
\Iterator
{
/**
* @var array the data to be iterated through
*/
private
$_d
;
/**
* @var integer index of the current item
*/
private
$_i
;
/**
* @var integer count of the data items
*/
private
$_c
;
/**
* Constructor.
* @param array $data the data to be iterated through
*/
public
function
__construct
(
&
$data
)
{
$this
->
_d
=
&
$data
;
$this
->
_i
=
0
;
$this
->
_c
=
count
(
$this
->
_d
);
}
/**
* Rewinds the index of the current item.
* This method is required by the SPL interface `Iterator`.
*/
public
function
rewind
()
{
$this
->
_i
=
0
;
}
/**
* Returns the key of the current item.
* This method is required by the SPL interface `Iterator`.
* @return integer the key of the current item
*/
public
function
key
()
{
return
$this
->
_i
;
}
/**
* Returns the current item.
* This method is required by the SPL interface `Iterator`.
* @return mixed the current item
*/
public
function
current
()
{
return
$this
->
_d
[
$this
->
_i
];
}
/**
* Moves the internal pointer to the next item.
* This method is required by the SPL interface `Iterator`.
*/
public
function
next
()
{
$this
->
_i
++
;
}
/**
* Returns a value indicating whether there is an item at current position.
* This method is required by the SPL interface `Iterator`.
* @return boolean whether there is an item at current position.
*/
public
function
valid
()
{
return
$this
->
_i
<
$this
->
_c
;
}
}
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