@@ -4996,8 +4996,8 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
49964996
49974997 protected function preSaveRelatedRecords (<AdapterInterface> connection, related, <CollectionInterface> visited ) -> bool
49984998 {
4999- var className, manager, type, relation, columns, referencedFields, nesting, name, record;
5000-
4999+ var className, manager, type, relation, columns, referencedFields, nesting, name, record, columnA, columnB ;
5000+ int columnCount, i;
50015001 let nesting = false ;
50025002
50035003 /**
@@ -5034,17 +5034,6 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
50345034 " Only objects can be stored as part of belongs-to relations in '" . get_class(this ) . " ' Relation " . name
50355035 );
50365036 }
5037- let columns = relation-> getFields(),
5038- referencedFields = relation-> getReferencedFields();
5039- // let columns = relation->getFields(),
5040- // referencedModel = relation->getReferencedModel(),
5041- // referencedFields = relation->getReferencedFields();
5042-
5043- if unlikely typeof columns === " array" {
5044- connection-> rollback(nesting);
5045-
5046- throw new Exception (" Not implemented in '" . get_class(this ) . " ' Relation " . name);
5047- }
50485037
50495038 /**
50505039 * If dynamic update is enabled, saving the record must not take any action
@@ -5069,7 +5058,18 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
50695058 * Read the attribute from the referenced model and assign
50705059 * it to the current model
50715060 */
5072- let this -> {columns} = record-> readAttribute(referencedFields);
5061+ let columns = relation-> getFields(),
5062+ referencedFields = relation-> getReferencedFields();
5063+ if unlikely typeof columns === " array" {
5064+ let columnCount = count(columns) - 1 ;
5065+ for i in range(0 , columnCount) {
5066+ let columnA = columns[i];
5067+ let columnB = referencedFields[i];
5068+ let this -> {columnA} = record-> {columnB};
5069+ }
5070+ } else {
5071+ let this -> {columns} = record-> {referencedFields};
5072+ }
50735073 }
50745074 }
50755075 }
@@ -5105,11 +5105,14 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
51055105 protected function postSaveRelatedRecords (<AdapterInterface> connection, related, <CollectionInterface> visited ) -> bool
51065106 {
51075107 var nesting, className, manager, relation, name, record,
5108- columns, referencedModel, referencedFields, relatedRecords, value,
5108+ columns, referencedModel, referencedFields, relatedRecords,
51095109 recordAfter, intermediateModel, intermediateFields,
5110- intermediateValue, intermediateModelName,
5111- intermediateReferencedFields, existingIntermediateModel;
5110+ intermediateModelName,
5111+ intermediateReferencedFields, existingIntermediateModel, columnA, columnB ;
51125112 bool isThrough;
5113+ int columnCount, referencedFieldsCount, i;
5114+ string intermediateConditions;
5115+ array conditions, placeholders;
51135116
51145117 let nesting = false ,
51155118 className = get_class(this ),
@@ -5144,12 +5147,6 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
51445147 referencedModel = relation-> getReferencedModel(),
51455148 referencedFields = relation-> getReferencedFields();
51465149
5147- if unlikely typeof columns === " array" {
5148- connection-> rollback(nesting);
5149-
5150- throw new Exception (" Not implemented in '" . className . " ' on Relation " . name);
5151- }
5152-
51535150 /**
51545151 * Create an implicit array for has-many/has-one records
51555152 */
@@ -5159,18 +5156,6 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
51595156 let relatedRecords = record;
51605157 }
51615158
5162- if unlikely ! fetch value, this -> {columns} {
5163- connection-> rollback(nesting);
5164-
5165- throw new Exception (
5166- " The column '" . columns . " ' needs to be present in the model '" . className . " '"
5167- );
5168- }
5169-
5170- /**
5171- * Get the value of the field from the current model
5172- * Check if the relation is a has-many-to-many
5173- */
51745159 let isThrough = (bool) relation-> isThrough();
51755160
51765161 /**
@@ -5180,7 +5165,30 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
51805165 let intermediateModelName = relation-> getIntermediateModel(),
51815166 intermediateFields = relation-> getIntermediateFields(),
51825167 intermediateReferencedFields = relation-> getIntermediateReferencedFields();
5183-
5168+ if unlikely typeof columns === " array" {
5169+ let columnCount = count(columns) - 1 ;
5170+ if relation-> getType() == Relation:: HAS_ONE_THROUGH {
5171+ let placeholders = [];
5172+ let conditions = [];
5173+ for i in range(0 , columnCount) {
5174+ let columnA = columns[i];
5175+ let conditions[] = " [" . intermediateFields[i] . " ] = :APR" . i . " :" ,
5176+ placeholders[" APR" . i] = this -> {columnA};
5177+ }
5178+ let intermediateConditions = join(" AND " , conditions);
5179+ }
5180+ } else {
5181+ if relation-> getType() == Relation:: HAS_ONE_THROUGH {
5182+ let placeholders = [];
5183+ let intermediateConditions = " [" . intermediateFields . " ] = ?0" ;
5184+ let placeholders[] = this -> {columns};
5185+ }
5186+ }
5187+ if unlikely typeof referencedFields === " array" {
5188+ let referencedFieldsCount = count(referencedFields) - 1 ;
5189+ } else {
5190+ let referencedFieldsCount = null ;
5191+ }
51845192 for recordAfter in relatedRecords {
51855193 /**
51865194 * Save the record and get messages
@@ -5213,38 +5221,39 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
52135221 if relation-> getType() == Relation:: HAS_ONE_THROUGH {
52145222 let existingIntermediateModel = intermediateModel-> findFirst(
52155223 [
5216- " [ " . intermediateFields . " ] = ?0 " ,
5217- " bind" : [value]
5224+ intermediateConditions ,
5225+ " bind" : placeholders
52185226 ]
52195227 );
52205228
52215229 if existingIntermediateModel {
52225230 let intermediateModel = existingIntermediateModel;
52235231 }
52245232 }
5225-
5226- /**
5227- * Write value in the intermediate model
5228- */
5229- intermediateModel-> writeAttribute(
5230- intermediateFields,
5231- value
5232- );
5233-
5234- /**
5235- * Get the value from the referenced model
5236- */
5237- let intermediateValue = recordAfter-> readAttribute(
5238- referencedFields
5239- );
5240-
5241- /**
5242- * Write the intermediate value in the intermediate model
5243- */
5244- intermediateModel-> writeAttribute(
5245- intermediateReferencedFields,
5246- intermediateValue
5247- );
5233+ if unlikely typeof columns === " array" {
5234+ for i in range(0 , columnCount) {
5235+ let columnA = columns[i];
5236+ let columnB = intermediateFields[i];
5237+ let intermediateModel-> {columnB} = this -> {columnA};
5238+ }
5239+ } else {
5240+ /**
5241+ * Write value in the intermediate model
5242+ */
5243+ let intermediateModel-> {intermediateFields} = this -> {columns};
5244+ }
5245+ if unlikely typeof referencedFields === " array" {
5246+ for i in range(0 , referencedFieldsCount) {
5247+ let columnA = referencedFields[i];
5248+ let columnB = intermediateReferencedFields[i];
5249+ let intermediateModel-> {columnB} = recordAfter-> {columnA};
5250+ }
5251+ } else {
5252+ /**
5253+ * Write the intermediate value in the intermediate model
5254+ */
5255+ let intermediateModel-> {intermediateReferencedFields} = recordAfter-> {referencedFields};
5256+ }
52485257
52495258 /**
52505259 * Save the record and get messages
@@ -5264,27 +5273,56 @@ abstract class Model extends AbstractInjectionAware implements EntityInterface,
52645273 }
52655274 }
52665275 } else {
5267- for recordAfter in relatedRecords {
5268- /**
5269- * Assign the value to the
5270- */
5271- recordAfter-> writeAttribute(referencedFields, value);
5272- /**
5273- * Save the record and get messages
5274- */
5275- if ! recordAfter-> doSave(visited) {
5276+ if unlikely typeof columns === " array" {
5277+ let columnCount = count(columns) - 1 ;
5278+ for recordAfter in relatedRecords {
5279+ for i in range(0 , columnCount) {
5280+ let columnA = columns[i];
5281+ let columnB = referencedFields[i];
5282+ let recordAfter-> {columnB} = this -> {columnA};
5283+ }
52765284 /**
5277- * Get the validation messages generated by the
5278- * referenced model
5285+ * Save the record and get messages
52795286 */
5280- this -> appendMessagesFrom(recordAfter);
5281-
5287+ if ! recordAfter-> doSave(visited) {
5288+ /**
5289+ * Get the validation messages generated by the
5290+ * referenced model
5291+ */
5292+ this -> appendMessagesFrom(recordAfter);
5293+
5294+ /**
5295+ * Rollback the implicit transaction
5296+ */
5297+ connection-> rollback(nesting);
5298+
5299+ return false ;
5300+ }
5301+ }
5302+ } else {
5303+ for recordAfter in relatedRecords {
52825304 /**
5283- * Rollback the implicit transaction
5305+ * Assign the value to the
52845306 */
5285- connection-> rollback(nesting);
5307+ let recordAfter-> {referencedFields} = this -> {columns};
5308+ /**
5309+ * Save the record and get messages
5310+ */
5311+ if ! recordAfter-> doSave(visited) {
52865312
5287- return false ;
5313+ /**
5314+ * Get the validation messages generated by the
5315+ * referenced model
5316+ */
5317+ this -> appendMessagesFrom(recordAfter);
5318+
5319+ /**
5320+ * Rollback the implicit transaction
5321+ */
5322+ connection-> rollback(nesting);
5323+
5324+ return false ;
5325+ }
52885326 }
52895327 }
52905328 }
0 commit comments