Skip to content
This repository
Browse code

Fix saving translate records with saveAll()

Also fixes issues saving translated data with validation
disabled.  By enabling data backup in beforeSave() and beforeValidate()
the existing behavior is preserved, and the current issue is fixed.

Fixes #2857
  • Loading branch information...
commit 6c5255ac73df0043262782d28ef1409c0aed67cc 1 parent 17a00eb
Mark Story authored
30  lib/Cake/Model/Behavior/TranslateBehavior.php
@@ -310,8 +310,35 @@ public function afterFind(Model $model, $results, $primary) {
310 310
  * @return boolean
311 311
  */
312 312
 	public function beforeValidate(Model $model) {
  313
+		unset($this->runtime[$model->alias]['beforeSave']);
  314
+		$this->_setRuntimeData($model);
  315
+		return true;
  316
+	}
  317
+
  318
+/**
  319
+ * beforeSave callback.
  320
+ *
  321
+ * @param Model $model Model save was called on.
  322
+ * @return boolean true.
  323
+ */
  324
+	public function beforeSave(Model $model) {
  325
+		$this->_setRuntimeData($model);
  326
+		return true;
  327
+	}
  328
+
  329
+/**
  330
+ * Sets the runtime data.
  331
+ *
  332
+ * Used from beforeValidate() and beforeSave() for compatibility issues,
  333
+ * and to allow translations to be persisted even when validation
  334
+ * is disabled.
  335
+ *
  336
+ * @param Model $model
  337
+ * @return void
  338
+ */
  339
+	protected function _setRuntimeData(Model $model) {
313 340
 		$locale = $this->_getLocale($model);
314  
-		if (empty($locale)) {
  341
+		if (empty($locale) || isset($this->runtime[$model->alias]['beforeSave'])) {
315 342
 			return true;
316 343
 		}
317 344
 		$fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
@@ -333,7 +360,6 @@ public function beforeValidate(Model $model) {
333 360
 			}
334 361
 		}
335 362
 		$this->runtime[$model->alias]['beforeSave'] = $tempData;
336  
-		return true;
337 363
 	}
338 364
 
339 365
 /**
179  lib/Cake/Test/Case/Model/Behavior/TranslateBehaviorTest.php
@@ -16,9 +16,6 @@
16 16
  * @since         CakePHP(tm) v 1.2.0.5669
17 17
  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
18 18
  */
19  
-if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
20  
-	define('CAKEPHP_UNIT_TEST_EXECUTION', 1);
21  
-}
22 19
 
23 20
 App::uses('Model', 'Model');
24 21
 App::uses('AppModel', 'Model');
@@ -119,7 +116,11 @@ public function testLocaleFalsePlain() {
119 116
 		$TestModel->locale = false;
120 117
 
121 118
 		$result = $TestModel->read(null, 1);
122  
-		$expected = array('TranslatedItem' => array('id' => 1, 'slug' => 'first_translated'));
  119
+		$expected = array('TranslatedItem' => array(
  120
+			'id' => 1,
  121
+			'slug' => 'first_translated',
  122
+			'translated_article_id' => 1,
  123
+		));
123 124
 		$this->assertEquals($expected, $result);
124 125
 
125 126
 		$result = $TestModel->find('all', array('fields' => array('slug')));
@@ -147,7 +148,7 @@ public function testLocaleFalseAssociations() {
147 148
 
148 149
 		$result = $TestModel->read(null, 1);
149 150
 		$expected = array(
150  
-			'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated'),
  151
+			'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated', 'translated_article_id' => 1),
151 152
 			'Title' => array(
152 153
 				array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
153 154
 				array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
@@ -203,7 +204,8 @@ public function testLocaleSingle() {
203 204
 				'slug' => 'first_translated',
204 205
 				'locale' => 'eng',
205 206
 				'title' => 'Title #1',
206  
-				'content' => 'Content #1'
  207
+				'content' => 'Content #1',
  208
+				'translated_article_id' => 1,
207 209
 			)
208 210
 		);
209 211
 		$this->assertEquals($expected, $result);
@@ -216,7 +218,8 @@ public function testLocaleSingle() {
216 218
 					'slug' => 'first_translated',
217 219
 					'locale' => 'eng',
218 220
 					'title' => 'Title #1',
219  
-					'content' => 'Content #1'
  221
+					'content' => 'Content #1',
  222
+					'translated_article_id' => 1,
220 223
 				)
221 224
 			),
222 225
 			array(
@@ -225,7 +228,8 @@ public function testLocaleSingle() {
225 228
 					'slug' => 'second_translated',
226 229
 					'locale' => 'eng',
227 230
 					'title' => 'Title #2',
228  
-					'content' => 'Content #2'
  231
+					'content' => 'Content #2',
  232
+					'translated_article_id' => 1,
229 233
 				)
230 234
 			),
231 235
 			array(
@@ -234,7 +238,8 @@ public function testLocaleSingle() {
234 238
 					'slug' => 'third_translated',
235 239
 					'locale' => 'eng',
236 240
 					'title' => 'Title #3',
237  
-					'content' => 'Content #3'
  241
+					'content' => 'Content #3',
  242
+					'translated_article_id' => 1,
238 243
 				)
239 244
 			)
240 245
 		);
@@ -259,7 +264,8 @@ public function testLocaleSingleWithConditions() {
259 264
 					'slug' => 'first_translated',
260 265
 					'locale' => 'eng',
261 266
 					'title' => 'Title #1',
262  
-					'content' => 'Content #1'
  267
+					'content' => 'Content #1',
  268
+					'translated_article_id' => 1,
263 269
 				)
264 270
 			)
265 271
 		);
@@ -273,7 +279,8 @@ public function testLocaleSingleWithConditions() {
273 279
 					'slug' => 'first_translated',
274 280
 					'locale' => 'eng',
275 281
 					'title' => 'Title #1',
276  
-					'content' => 'Content #1'
  282
+					'content' => 'Content #1',
  283
+					'translated_article_id' => 1,
277 284
 				)
278 285
 			)
279 286
 		);
@@ -301,7 +308,8 @@ public function testLocaleSingleAssociations() {
301 308
 				'slug' => 'first_translated',
302 309
 				'locale' => 'eng',
303 310
 				'title' => 'Title #1',
304  
-				'content' => 'Content #1'
  311
+				'content' => 'Content #1',
  312
+				'translated_article_id' => 1,
305 313
 			),
306 314
 			'Title' => array(
307 315
 				array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
@@ -322,17 +330,35 @@ public function testLocaleSingleAssociations() {
322 330
 		$result = $TestModel->find('all', array('fields' => array('TranslatedItem.title')));
323 331
 		$expected = array(
324 332
 			array(
325  
-				'TranslatedItem' => array('id' => 1, 'locale' => 'eng', 'title' => 'Title #1', 'slug' => 'first_translated'),
  333
+				'TranslatedItem' => array(
  334
+					'id' => 1,
  335
+					'locale' => 'eng',
  336
+					'title' => 'Title #1',
  337
+					'slug' => 'first_translated',
  338
+					'translated_article_id' => 1,
  339
+				),
326 340
 				'Title' => array(array('foreign_key' => 1, 'content' => 'Title #1')),
327 341
 				'Content' => array(array('foreign_key' => 1, 'content' => 'Content #1'))
328 342
 			),
329 343
 			array(
330  
-				'TranslatedItem' => array('id' => 2, 'locale' => 'eng', 'title' => 'Title #2', 'slug' => 'second_translated'),
  344
+				'TranslatedItem' => array(
  345
+					'id' => 2,
  346
+					'locale' => 'eng',
  347
+					'title' => 'Title #2',
  348
+					'slug' => 'second_translated',
  349
+					'translated_article_id' => 1,
  350
+				),
331 351
 				'Title' => array(array('foreign_key' => 2, 'content' => 'Title #2')),
332 352
 				'Content' => array(array('foreign_key' => 2, 'content' => 'Content #2'))
333 353
 			),
334 354
 			array(
335  
-				'TranslatedItem' => array('id' => 3, 'locale' => 'eng', 'title' => 'Title #3','slug' => 'third_translated'),
  355
+				'TranslatedItem' => array(
  356
+					'id' => 3,
  357
+					'locale' => 'eng',
  358
+					'title' => 'Title #3',
  359
+					'slug' => 'third_translated',
  360
+					'translated_article_id' => 1,
  361
+				),
336 362
 				'Title' => array(array('foreign_key' => 3, 'content' => 'Title #3')),
337 363
 				'Content' => array(array('foreign_key' => 3, 'content' => 'Content #3'))
338 364
 			)
@@ -358,7 +384,8 @@ public function testLocaleMultiple() {
358 384
 				'slug' => 'first_translated',
359 385
 				'locale' => 'deu',
360 386
 				'title' => 'Titel #1',
361  
-				'content' => 'Inhalt #1'
  387
+				'content' => 'Inhalt #1',
  388
+				'translated_article_id' => 1,
362 389
 			)
363 390
 		);
364 391
 		$this->assertEquals($expected, $result);
@@ -370,7 +397,7 @@ public function testLocaleMultiple() {
370 397
 					'slug' => 'first_translated',
371 398
 					'locale' => 'deu',
372 399
 					'content' => 'Inhalt #1',
373  
-					'title' => 'Titel #1'
  400
+					'title' => 'Titel #1',
374 401
 				)
375 402
 			),
376 403
 			array(
@@ -378,7 +405,7 @@ public function testLocaleMultiple() {
378 405
 					'slug' => 'second_translated',
379 406
 					'locale' => 'deu',
380 407
 					'title' => 'Titel #2',
381  
-					'content' => 'Inhalt #2'
  408
+					'content' => 'Inhalt #2',
382 409
 				)
383 410
 			),
384 411
 			array(
@@ -386,7 +413,7 @@ public function testLocaleMultiple() {
386 413
 					'slug' => 'third_translated',
387 414
 					'locale' => 'deu',
388 415
 					'title' => 'Titel #3',
389  
-					'content' => 'Inhalt #3'
  416
+					'content' => 'Inhalt #3',
390 417
 				)
391 418
 			)
392 419
 		);
@@ -415,7 +442,8 @@ public function testMissingTranslation() {
415 442
 				'slug' => 'first_translated',
416 443
 				'locale' => 'rus',
417 444
 				'title' => '',
418  
-				'content' => ''
  445
+				'content' => '',
  446
+				'translated_article_id' => 1,
419 447
 			)
420 448
 		);
421 449
 		$this->assertEquals($expected, $result);
@@ -499,7 +527,12 @@ public function testSaveCreate() {
499 527
 
500 528
 		$TestModel = new TranslatedItem();
501 529
 		$TestModel->locale = 'spa';
502  
-		$data = array('slug' => 'fourth_translated', 'title' => 'Leyenda #4', 'content' => 'Contenido #4');
  530
+		$data = array(
  531
+			'slug' => 'fourth_translated',
  532
+			'title' => 'Leyenda #4',
  533
+			'content' => 'Contenido #4',
  534
+			'translated_article_id' => null
  535
+		);
503 536
 		$TestModel->create($data);
504 537
 		$TestModel->save();
505 538
 		$result = $TestModel->read();
@@ -517,7 +550,7 @@ public function testSaveUpdate() {
517 550
 
518 551
 		$TestModel = new TranslatedItem();
519 552
 		$TestModel->locale = 'spa';
520  
-		$oldData = array('slug' => 'fourth_translated', 'title' => 'Leyenda #4');
  553
+		$oldData = array('slug' => 'fourth_translated', 'title' => 'Leyenda #4', 'translated_article_id' => 1);
521 554
 		$TestModel->create($oldData);
522 555
 		$TestModel->save();
523 556
 		$id = $TestModel->id;
@@ -554,7 +587,14 @@ public function testMultipleCreate() {
554 587
 
555 588
 		$result = $TestModel->read();
556 589
 		$expected = array(
557  
-			'TranslatedItem' => array('id' => 4, 'slug' => 'new_translated', 'locale' => 'eng', 'title' => 'New title', 'content' => 'New content'),
  590
+			'TranslatedItem' => array(
  591
+				'id' => 4,
  592
+				'slug' => 'new_translated',
  593
+				'locale' => 'eng',
  594
+				'title' => 'New title',
  595
+				'content' => 'New content',
  596
+				'translated_article_id' => null,
  597
+			),
558 598
 			'Title' => array(
559 599
 				array('id' => 21, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'New title'),
560 600
 				array('id' => 22, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'Nuevo leyenda')
@@ -591,7 +631,14 @@ public function testMultipleUpdate() {
591 631
 		$TestModel->bindTranslation($translations, false);
592 632
 		$result = $TestModel->read(null, 1);
593 633
 		$expected = array(
594  
-			'TranslatedItem' => array('id' => '1', 'slug' => 'first_translated', 'locale' => 'eng', 'title' => 'New Title #1', 'content' => 'New Content #1'),
  634
+			'TranslatedItem' => array(
  635
+				'id' => '1',
  636
+				'slug' => 'first_translated',
  637
+				'locale' => 'eng',
  638
+				'title' => 'New Title #1',
  639
+				'content' => 'New Content #1',
  640
+				'translated_article_id' => 1,
  641
+			),
595 642
 			'Title' => array(
596 643
 				array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'New Title #1'),
597 644
 				array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Neue Titel #1'),
@@ -634,7 +681,14 @@ public function testMixedCreateUpdateWithArrayLocale() {
634 681
 		$result['Title'] = Set::sort($result['Title'], '{n}.id', 'asc');
635 682
 		$result['Content'] = Set::sort($result['Content'], '{n}.id', 'asc');
636 683
 		$expected = array(
637  
-			'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated', 'locale' => 'cze', 'title' => 'Titulek #1', 'content' => 'Upraveny obsah #1'),
  684
+			'TranslatedItem' => array(
  685
+				'id' => 1,
  686
+				'slug' => 'first_translated',
  687
+				'locale' => 'cze',
  688
+				'title' => 'Titulek #1',
  689
+				'content' => 'Upraveny obsah #1',
  690
+				'translated_article_id' => 1,
  691
+			),
638 692
 			'Title' => array(
639 693
 				array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Updated Title #1'),
640 694
 				array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
@@ -651,6 +705,44 @@ public function testMixedCreateUpdateWithArrayLocale() {
651 705
 	}
652 706
 
653 707
 /**
  708
+ * Test that saveAll() works with hasMany associations that contain
  709
+ * translations.
  710
+ *
  711
+ * @return void
  712
+ */
  713
+	public function testSaveAllTranslatedAssociations() {
  714
+		$this->loadFixtures('Translate', 'TranslateArticle', 'TranslatedItem', 'TranslatedArticle', 'User');
  715
+		$Model = new TranslatedArticle();
  716
+		$Model->locale = 'eng';
  717
+
  718
+		$data = array(
  719
+			'TranslatedArticle' => array(
  720
+				'user_id' => 1,
  721
+				'published' => 'Y',
  722
+				'title' => 'Title (eng) #1',
  723
+				'body' => 'Body (eng) #1'
  724
+			),
  725
+			'TranslatedItem' => array(
  726
+				array(
  727
+					'title' => 'Nuevo leyenda #1',
  728
+					'content' => 'Upraveny obsah #1'
  729
+				),
  730
+				array(
  731
+					'title' => 'New Title #2',
  732
+					'content' => 'New Content #2'
  733
+				),
  734
+			)
  735
+		);
  736
+		$result = $Model->saveAll($data);
  737
+		$this->assertTrue($result);
  738
+
  739
+		$result = $Model->TranslatedItem->find('all', array(
  740
+			'conditions' => array('translated_article_id' => $Model->id)
  741
+		));
  742
+		$this->assertCount(2, $result);
  743
+	}
  744
+
  745
+/**
654 746
  * testValidation method
655 747
  *
656 748
  * @return void
@@ -661,11 +753,13 @@ public function testValidation() {
661 753
 		$TestModel = new TranslatedItem();
662 754
 		$TestModel->locale = 'eng';
663 755
 		$TestModel->validate['title'] = '/Only this title/';
664  
-		$data = array('TranslatedItem' => array(
665  
-			'id' => 1,
666  
-			'title' => array('eng' => 'New Title #1', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
667  
-			'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
668  
-		));
  756
+		$data = array(
  757
+			'TranslatedItem' => array(
  758
+				'id' => 1,
  759
+				'title' => array('eng' => 'New Title #1', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
  760
+				'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
  761
+			)
  762
+		);
669 763
 		$TestModel->create();
670 764
 		$this->assertFalse($TestModel->save($data));
671 765
 		$this->assertEquals(array('This field cannot be left blank'), $TestModel->validationErrors['title']);
@@ -748,7 +842,8 @@ public function testAnotherTranslateTable() {
748 842
 				'slug' => 'first_translated',
749 843
 				'locale' => 'eng',
750 844
 				'title' => 'Another Title #1',
751  
-				'content' => 'Another Content #1'
  845
+				'content' => 'Another Content #1',
  846
+				'translated_article_id' => 1,
752 847
 			)
753 848
 		);
754 849
 		$this->assertEquals($expected, $result);
@@ -760,7 +855,7 @@ public function testAnotherTranslateTable() {
760 855
  * @return void
761 856
  */
762 857
 	public function testTranslateWithAssociations() {
763  
-		$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User', 'Comment', 'ArticlesTag', 'Tag');
  858
+		$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'TranslatedItem', 'User', 'Comment', 'ArticlesTag', 'Tag');
764 859
 
765 860
 		$TestModel = new TranslatedArticle();
766 861
 		$TestModel->locale = 'eng';
@@ -784,6 +879,23 @@ public function testTranslateWithAssociations() {
784 879
 				'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
785 880
 				'created' => '2007-03-17 01:16:23',
786 881
 				'updated' => '2007-03-17 01:18:31'
  882
+			),
  883
+			'TranslatedItem' => array(
  884
+				array(
  885
+					'id' => 1,
  886
+					'translated_article_id' => 1,
  887
+					'slug' => 'first_translated'
  888
+				),
  889
+				array(
  890
+					'id' => 2,
  891
+					'translated_article_id' => 1,
  892
+					'slug' => 'second_translated'
  893
+				),
  894
+				array(
  895
+					'id' => 3,
  896
+					'translated_article_id' => 1,
  897
+					'slug' => 'third_translated'
  898
+				),
787 899
 			)
788 900
 		);
789 901
 		$this->assertEquals($expected, $result);
@@ -863,7 +975,8 @@ public function testTranslateTableWithPrefix() {
863 975
 			'slug' => 'first_translated',
864 976
 			'locale' => 'eng',
865 977
 			'content' => 'Content #1',
866  
-			'title' => 'Title #1'
  978
+			'title' => 'Title #1',
  979
+			'translated_article_id' => 1,
867 980
 		));
868 981
 		$this->assertEquals($expected, $result);
869 982
 	}
11  lib/Cake/Test/Case/Model/models.php
@@ -3119,7 +3119,7 @@ class TranslatedItem2 extends CakeTestModel {
3119 3119
 /**
3120 3120
  * translateModel property
3121 3121
  *
3122  
- * @var string 'TranslateTestModel'
  3122
+ * @var string 
3123 3123
  */
3124 3124
 	public $translateModel = 'TranslateWithPrefix';
3125 3125
 
@@ -3163,7 +3163,7 @@ class TranslatedItemWithTable extends CakeTestModel {
3163 3163
 /**
3164 3164
  * translateModel property
3165 3165
  *
3166  
- * @var string 'TranslateTestModel'
  3166
+ * @var string
3167 3167
  */
3168 3168
 	public $translateModel = 'TranslateTestModel';
3169 3169
 
@@ -3248,6 +3248,13 @@ class TranslatedArticle extends CakeTestModel {
3248 3248
  */
3249 3249
 	public $belongsTo = array('User');
3250 3250
 
  3251
+/**
  3252
+ * belongsTo property
  3253
+ *
  3254
+ * @var array
  3255
+ */
  3256
+	public $hasMany = array('TranslatedItem');
  3257
+
3251 3258
 }
3252 3259
 
3253 3260
 class CounterCacheUser extends CakeTestModel {
7  lib/Cake/Test/Fixture/TranslatedItemFixture.php
@@ -38,6 +38,7 @@ class TranslatedItemFixture extends CakeTestFixture {
38 38
  */
39 39
 	public $fields = array(
40 40
 		'id' => array('type' => 'integer', 'key' => 'primary'),
  41
+		'translated_article_id' => array('type' => 'integer'),
41 42
 		'slug' => array('type' => 'string', 'null' => false)
42 43
 	);
43 44
 
@@ -47,8 +48,8 @@ class TranslatedItemFixture extends CakeTestFixture {
47 48
  * @var array
48 49
  */
49 50
 	public $records = array(
50  
-		array('slug' => 'first_translated'),
51  
-		array('slug' => 'second_translated'),
52  
-		array('slug' => 'third_translated')
  51
+		array('translated_article_id' => 1, 'slug' => 'first_translated'),
  52
+		array('translated_article_id' => 1, 'slug' => 'second_translated'),
  53
+		array('translated_article_id' => 1, 'slug' => 'third_translated')
53 54
 	);
54 55
 }

0 notes on commit 6c5255a

Please sign in to comment.
Something went wrong with that request. Please try again.