66 * @author Yohanes Candrajaya <[email protected] > 77 * @since 1.0
88 */
9+
910namespace mootensai \relation ;
1011
1112use \yii \db \ActiveRecord ;
1213use \yii \db \Exception ;
1314use \yii \helpers \Inflector ;
1415use \yii \helpers \StringHelper ;
1516
16- trait RelationTrait{
17-
17+ trait RelationTrait {
18+
1819 public function loadAll ($ POST ) {
1920 if ($ this ->load ($ POST )) {
2021 $ shortName = StringHelper::basename (get_class ($ this ));
@@ -46,7 +47,7 @@ public function loadAll($POST) {
4647 return false ;
4748 }
4849 }
49-
50+
5051 public function saveAll () {
5152 /* @var $this ActiveRecord */
5253 $ db = $ this ->getDb ();
@@ -61,47 +62,47 @@ public function saveAll() {
6162 $ relPKAttr = $ records [0 ]->primaryKey ();
6263 $ isCompositePK = (count ($ relPKAttr ) > 1 );
6364 /* @var $relModel ActiveRecord */
64- foreach ($ records as $ index => $ relModel ){
65- foreach ($ link as $ key => $ value ){
65+ foreach ($ records as $ index => $ relModel ) {
66+ foreach ($ link as $ key => $ value ) {
6667 $ relModel ->$ key = $ this ->$ value ;
6768 $ notDeletedFK [$ key ] = "$ key = ' {$ this ->$ value }' " ;
6869 }
6970 $ relSave = $ relModel ->save ();
70- if (!$ relSave) {
71+ if (!$ relSave || ! empty ( $ relModel -> errors )) {
7172 $ relModelWords = Inflector::camel2words (StringHelper::basename ($ AQ ->modelClass ));
7273 $ index ++;
73- foreach ($ relModel ->errors as $ validation ){
74- foreach ($ validation as $ errorMsg ){
75- $ this ->addError ($ name ,"$ relModelWords # $ index : $ errorMsg " );
74+ foreach ($ relModel ->errors as $ validation ) {
75+ foreach ($ validation as $ errorMsg ) {
76+ $ this ->addError ($ name , "$ relModelWords # $ index : $ errorMsg " );
7677 }
7778 }
7879 $ error = 1 ;
79- }else {
80+ } else {
8081 //GET PK OF REL MODEL
81- if ($ isCompositePK ){
82- foreach ($ relModel ->primaryKey as $ attr => $ value ){
82+ if ($ isCompositePK ) {
83+ foreach ($ relModel ->primaryKey as $ attr => $ value ) {
8384 $ notDeletedPK [$ attr ][] = "' $ value' " ;
8485 }
85- } else {
86+ } else {
8687 $ notDeletedPK [] = "' $ relModel ->primaryKey ' " ;
8788 }
8889 }
8990 }
90- if (!$ this ->isNewRecord ){
91+ if (!$ this ->isNewRecord ) {
9192 //DELETE WITH 'NOT IN' PK MODEL & REL MODEL
9293 $ notDeletedFK = implode (' AND ' , $ notDeletedFK );
93- if ($ isCompositePK ){
94+ if ($ isCompositePK ) {
9495 $ compiledNotDeletedPK = [];
95- foreach ($ notDeletedPK as $ attr => $ pks ){
96- $ compiledNotDeletedPK [$ attr ] = "$ attr NOT IN( " . implode (', ' , $ pks ). ") " ;
97- if (!empty ($ compiledNotDeletedPK [$ attr ])){
98- $ relModel ->deleteAll ("$ notDeletedFK AND " . implode (' AND ' , $ compiledNotDeletedPK ));
96+ foreach ($ notDeletedPK as $ attr => $ pks ) {
97+ $ compiledNotDeletedPK [$ attr ] = "$ attr NOT IN( " . implode (', ' , $ pks ) . ") " ;
98+ if (!empty ($ compiledNotDeletedPK [$ attr ])) {
99+ $ relModel ->deleteAll ("$ notDeletedFK AND " . implode (' AND ' , $ compiledNotDeletedPK ));
99100 }
100101 }
101- }else {
102+ } else {
102103 $ compiledNotDeletedPK = implode (', ' , $ notDeletedPK );
103- if (!empty ($ compiledNotDeletedPK )){
104- $ relModel ->deleteAll ($ notDeletedFK. ' AND ' . $ relPKAttr [0 ]. " NOT IN ( $ compiledNotDeletedPK) " );
104+ if (!empty ($ compiledNotDeletedPK )) {
105+ $ relModel ->deleteAll ($ notDeletedFK . ' AND ' . $ relPKAttr [0 ] . " NOT IN ( $ compiledNotDeletedPK) " );
105106 }
106107 }
107108 }
@@ -120,28 +121,102 @@ public function saveAll() {
120121 throw $ exc ;
121122 }
122123 }
123-
124- /* this function is deprecated*/
125- public function getAttributesWithRelatedAsPost (){
124+
125+ public function deleteWithRelated () {
126+ /* @var $this ActiveRecord */
127+ $ db = $ this ->getDb ();
128+ $ trans = $ db ->beginTransaction ();
129+ try {
130+ $ error = 0 ;
131+ $ relData = $ this ->getRelationData ();
132+ foreach ($ relData as $ data ) {
133+ if ($ data ['ismultiple ' ]){
134+ $ AQ = $ this ->getRelation ($ data ['name ' ]);
135+ $ link = $ AQ ->link ;
136+ if (count ($ this ->{$ data ['name ' ]})){
137+ $ relPKAttr = $ this ->{$ data ['name ' ]}[0 ]->primaryKey ();
138+ $ isCompositePK = (count ($ relPKAttr ) > 1 );
139+ foreach ($ link as $ key => $ value ) {
140+ if (isset ($ this ->$ value )){
141+ $ array [$ key ] = $ key . ' = ' . $ this ->$ value ;
142+ }
143+ }
144+ $ error = !$ this ->{$ data ['name ' ]}[0 ]->deleteAll (implode (' AND ' , $ array ));
145+ }
146+ }
147+ }
148+ if ($ error ) {
149+ $ trans ->rollback ();
150+ return false ;
151+ }
152+ if ($ this ->delete ()){
153+ $ trans ->commit ();
154+ return true ;
155+ }
156+ $ trans ->rollBack ();
157+ } catch (Exception $ exc ) {
158+ $ trans ->rollBack ();
159+ throw $ exc ;
160+ }
161+ }
162+
163+ public function getRelationData () {
164+ $ ARMethods = get_class_methods ('\yii\db\ActiveRecord ' );
165+ $ modelMethods = get_class_methods ('\yii\base\Model ' );
166+ $ reflection = new \ReflectionClass ($ this );
167+ $ i = 0 ;
168+ $ stack = [];
169+ /* @var $method \ReflectionMethod */
170+ foreach ($ reflection ->getMethods () as $ method ) {
171+ if (in_array ($ method ->name , $ ARMethods ) || in_array ($ method ->name , $ modelMethods )) {
172+ continue ;
173+ }
174+ if ($ method ->name === 'bindModels ' ) {continue ;}
175+ if ($ method ->name === 'attachBehaviorInternal ' ) {continue ;}
176+ if ($ method ->name === 'loadAll ' ) {continue ;}
177+ if ($ method ->name === 'saveAll ' ) {continue ;}
178+ if ($ method ->name === 'getRelationData ' ) {continue ;}
179+ if ($ method ->name === 'getAttributesWithRelatedAsPost ' ) {continue ;}
180+ if ($ method ->name === 'getAttributesWithRelated ' ) {continue ;}
181+ if ($ method ->name === 'deleteWithRelated ' ) {continue ;}
182+ try {
183+ $ rel = $ this ->{$ method ->name }();
184+ if ($ rel instanceof \yii \db \ActiveQuery){
185+ $ stack [$ i ]['name ' ] = lcfirst (str_replace ('get ' , '' , $ method ->name ));
186+ $ stack [$ i ]['method ' ] = $ method ->name ;
187+ $ stack [$ i ]['ismultiple ' ] = $ rel ->multiple ;
188+ $ i ++;
189+ }
190+ } catch (\yii \base \ErrorException $ exc ) {
191+ //
192+ }
193+ }
194+ return $ stack ;
195+ }
196+
197+ /* this function is deprecated */
198+
199+ public function getAttributesWithRelatedAsPost () {
126200 $ return = [];
127201 $ shortName = StringHelper::basename (get_class ($ this ));
128202 $ return [$ shortName ] = $ this ->attributes ;
129- foreach ($ this ->relatedRecords as $ records ){
130- foreach ($ records as $ index => $ record ){
203+ foreach ($ this ->relatedRecords as $ records ) {
204+ foreach ($ records as $ index => $ record ) {
131205 $ shortNameRel = StringHelper::basename (get_class ($ record ));
132206 $ return [$ shortNameRel ][$ index ] = $ record ->attributes ;
133207 }
134208 }
135209 return $ return ;
136210 }
137-
138- public function getAttributesWithRelated (){
211+
212+ public function getAttributesWithRelated () {
139213 $ return = $ this ->attributes ;
140- foreach ($ this ->relatedRecords as $ name => $ records ){
141- foreach ($ records as $ index => $ record ){
214+ foreach ($ this ->relatedRecords as $ name => $ records ) {
215+ foreach ($ records as $ index => $ record ) {
142216 $ return [$ name ][$ index ] = $ record ->attributes ;
143217 }
144218 }
145219 return $ return ;
146220 }
221+
147222}
0 commit comments