namespace
woo\domain;
class
ObjectWatcher{
private
$all
=
array
();
private
$dirty
=
array
();
private
$new
=
array
();
private
$delete
=
array
();
private
static
$instance
;
private
function
__construct (){}
static
function
instance(){
if
(!self::
$instance
){
self::
$instance
=
new
ObjectWatcher();
}
return
self::
$instance
;
}
function
globalKey(DomainObject
$obj
){
$key
= get_class(
$obj
) .
"."
.
$obj
->getId();
return
$key
;
}
static
function
add(DomainObject
$obj
){
$inst
= self::instance();
$inst
->all[
$inst
->globalKey(
$obj
)] =
$obj
;
}
static
function
exists(
$classname
,
$id
){
$inst
= self::instance();
$key
=
"$classname.$id"
;
if
(isset(
$inst
->all[
$key
]){
return
$inst
->all[
$key
];
}
return
null;
}
static
function
addDelete(DomainObject
$obj
){
$self
= self::instance();
$self
->
delete
[
$self
->globalKey(
$obj
)] =
$obj
;
}
static
function
addDirty(DomainObject
$obj
){
$inst
= self::instance();
if
(!in_array(
$obj
,
$inst
->
new
,true)){
$inst
->dirty[
$inst
->globalKey(
$obj
)] =
$obj
;
}
}
static
function
addNew(DomainObject
$obj
){
$inst
= self::instance();
$inst
->
new
[] =
$obj
;
}
static
function
addClean(DomainObject
$obj
){
$self
= self::instance();
unset(
$self
->
delete
[
$self
->globalKey(
$obj
)]);
unset(
$self
->dirty[
$self
->globalKey(
$obj
)]);
$self
->
new
=
array_filter
(
$self
->
new
,
function
(
$a
)
use
(
$obj
) {
return
!(
$a
===
$obj
);});
}
function
performOperations(){
foreach
(
$this
->dirty
as
$key
=>
$obj
){
$obj
->finder()->update(
$obj
);
}
foreach
(
$this
->
new
as
$key
=>
$obj
){
$obj
->finder()->insert(
$obj
);
}
$this
->dirty =
array
();
$this
->
new
=
array
();
}
}
abstract
class
DomainObject{
private
$id
= -1;
function
__construct (
$id
=null){
if
(
is_null
(
$id
)){
$this
->markNew();
}
else
{
$this
->id =
$id
;
}
}
function
markNew(){
ObjectWatcher::addNew(
$this
);
}
function
markDeleted(){
ObjectWatcher::addDelete(
$this
);
}
function
markDirty(){
ObjectWatcher::addDirty(
$this
);
}
function
markClean(){
ObjectWatcher::addClean(
$this
);
}
function
setId(
$id
){
$this
->id =
$id
;
}
function
getId(){
return
$this
->id;
}
function
finder(){
return
self::getFinder(get_class(
$this
));
}
static
function
getFinder(
$type
){
return
HelperFactory::getFinder(
$type
);
}
}
class
Venue
extends
DomainObject {
private
$name
;
private
$spaces
;
function
__construct (
$id
= null,
$name
=null){
$this
->name=
$name
;
$this
->spaces = self::getCollection(
'\\woo\\domain\\space'
);
parent::__construct(
$id
);
}
function
setSpaces(SpaceCollection
$spaces
){
$this
->spaces =
$spaces
;
$this
->markDirty();
}
function
addSpace(Space
$space
){
$this
->spaces->add(
$space
);
$space
->setVenue(
$this
);
$this
->markDirty();
}
function
setName(
$name_s
){
$this
->name =
$name_s
;
$this
->markDirty();
}
function
getName(){
return
$this
->name;
}
}
class
Space
extends
DomainObject{
function
setName(
$name_s
){
$this
->name =
$name_s
;
$this
->markDirty();
}
function
setVenue(Venue
$venue
){
$this
->venue =
$venue
;
$this
->markDirty();
}
}
abstract
class
Mapper{
abstract
static
$PDO
;
function
__construct (){
if
(!isset(self::
$PDO
){
$dsn
= \woo\base\ApplicationRegistry::getDSN();
if
(
is_null
(
$dsn
)){
throw
new
\woo\base\AppException(
"no dns"
);
}
self::
$PDO
=
new
\PDO(
$dsn
);
self::
$PDO
->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
}
}
private
function
getFroMap(
$id
){
return
\woo\domain\ObjectWatcher::exists(
$this
->targetClass(),
$id
);
}
private
function
addToMap(\woo\domain\DomainObject
$obj
){
return
\woo\domain\ObjectWatcher::add(
$obj
);
}
function
createObject(
$array
){
$old
=
$this
->getFromMap(
$array
[
'id'
]);
if
(
$old
){
return
$old
;}
$obj
=
$this
->doCreateObject(
$array
);
$this
->addToMap(
$obj
);
$obj
->markClean();
return
$obj
;
}
function
find(
$id
){
$old
=
$this
->getFromMap(
$id
);
if
(
$old
){
return
$old
}
$this
->selectStmt()->execute(
array
(
$id
));
$array
=
$this
->selectStmt()->fetch();
$this
->selectStmt()->closeCursor();
if
(!
is_array
(
$array
)){
return
null;
}
if
(!isset(
$array
[
'id'
])){
return
null;
}
$object
=
$this
->createObject(
$array
);
$this
->addToMap(
$object
);
return
$object
;
}
function
insert(\woo\domain\DomainObject
$obj
){
$this
->doInsert(
$obj
);
$this
->addToMap(
$obj
);
}
abstract
function
targetClass();
abstract
function
update(\woo\domain\DomainObject
$objet
);
protected
abstract
function
doCreateObject(
array
$array
);
protected
abstract
function
selectStmt();
protected
abstract
function
doInsert(\woo\domain\DomainObject
$object
);
}
class
VenueMapper
extends
Mapper {
function
__construct (){
parent::__construct();
$this
->selectStmt = self::
$PDO
->prepare(
"select * from venue where id=?"
);
$this
->updateStmt = self::
$PDO
->prepare(
"update venue set name=?,id=? where id=?"
);
$this
->insertStmt = self::
$PDO
->prepare(
"insert into venue (name) values(?)"
);
}
protected
function
getCollection(
array
$raw
){
return
new
SpaceCollection(
$raw
,
$this
);
}
protected
function
doCreateObject (
array
$array
){
$obj
=
new
\woo\domain\Venue(
$array
[
'id'
]);
$obj
->setname(
$array
[
'name'
]);
return
$obj
;
}
protected
function
doInsert(\woo\domain\DomainObject
$object
){
print
'inserting'
;
debug_print_backtrace();
$values
=
array
(
$object
->getName());
$this
->insertStmt->execute(
$values
);
$id
= self::
$PDO
->lastInsertId();
$object
->setId(
$id
);
}
function
update(\woo\domain\DomainObject
$object
){
print
"updation\n"
;
$values
=
array
(
$object
->getName(),
$object
->getId(),
$object
->getId());
$this
->updateStmt->execute(
$values
);
}
function
selectStmt(){
return
$this
->selectStmt;
}
}
$venue
=
new
\woo\domain\Venue(null,
"The Green Tree"
);
$venue
->addSpace(
new
\woo\domain\Space(null,
"The Space Upstairs"
));
$venue
->addSpace(
new
\woo\domain\Space(null,
"The Bar Stage"
));
\woo\domain\ObjectWatcher::instance()->performOperations();