44
55class EntityModel extends ModelAbstract
66{
7+ const STATE_NEW = 1 ;
8+
9+ const STATE_MANAGED = 2 ;
10+
711 protected $ entityClass ;
812
13+ private $ entityStates = [];
14+
915 public function entityClass ()
1016 {
1117 if (!$ this ->entityClass ) {
@@ -31,6 +37,62 @@ public function create(array $record = [])
3137
3238 public function save ($ entity )
3339 {
40+ $ entityClass = $ this ->entityClass ();
41+
42+ if (!$ entity instanceof $ entityClass ) {
43+ throw new \Exception ('Entity should be an instance of ` ' . $ entityClass . '`. ' );
44+ }
45+
46+ $ record = [];
47+
48+ (function () use (&$ record ) {
49+ $ record = get_object_vars ($ this );
50+ })->call ($ entity );
51+
52+ switch ($ this ->getEntityState ($ entity )) {
53+ case self ::STATE_NEW :
54+ $ this ->insert ($ record );
55+
56+ if ($ autoIncrement = $ this ->autoIncrement ()) {
57+ $ id = (int ) $ this ->connection ()->lastInsertId ();
58+
59+ (function () use ($ autoIncrement , $ id ) {
60+ $ this ->{$ autoIncrement } = $ id ;
61+ })->call ($ entity );
62+ }
63+
64+ $ this ->setEntityState ($ entity , self ::STATE_MANAGED );
65+
66+ break ;
67+ case self ::STATE_MANAGED :
68+ $ keys = [];
69+
70+ foreach ($ this ->firstUniqueKey () as $ key ) {
71+ $ keys [$ key ] = $ record [$ key ];
72+ }
73+
74+ $ query = $ this ->newUpdateQuery ()
75+ ->setMultiple (array_diff_key ($ record , $ keys ))
76+ ->whereMultiple ($ keys );
77+
78+ $ this ->connection ()->sqlExecute (...$ query ->toSql ());
79+
80+ break ;
81+ }
82+
83+ return $ this ;
84+ }
85+
86+ private function setEntityState ($ entity , $ state )
87+ {
88+ $ this ->entityStates [spl_object_hash ($ entity )] = $ state ;
89+
90+ return $ this ;
91+ }
92+
93+ private function getEntityState ($ entity )
94+ {
95+ return $ this ->entityStates [spl_object_hash ($ entity )] ?? self ::STATE_NEW ;
3496 }
3597
3698 protected function prepareRowInstance (array $ record )
0 commit comments