TranslateBehaviorTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Model\Behavior;
  16. use Cake\Collection\Collection;
  17. use Cake\Event\Event;
  18. use Cake\I18n\I18n;
  19. use Cake\Model\Behavior\TranslateBehavior;
  20. use Cake\ORM\Entity;
  21. use Cake\ORM\TableRegistry;
  22. use Cake\TestSuite\TestCase;
  23. /**
  24. * Translate behavior test case
  25. */
  26. class TranslateBehaviorTest extends TestCase {
  27. /**
  28. * fixtures
  29. *
  30. * @var array
  31. */
  32. public $fixtures = [
  33. 'core.translates',
  34. 'core.articles',
  35. 'core.comments',
  36. 'core.authors'
  37. ];
  38. public function tearDown() {
  39. parent::tearDown();
  40. I18n::locale(I18n::defaultLocale());
  41. TableRegistry::clear();
  42. }
  43. /**
  44. * Returns an array with all the translations found for a set of records
  45. *
  46. * @param array|\Traversable $data
  47. * @return Collection
  48. */
  49. protected function _extractTranslations($data) {
  50. return (new Collection($data))->map(function ($row) {
  51. $translations = $row->get('_translations');
  52. if (!$translations) {
  53. return [];
  54. }
  55. return array_map(function ($t) {
  56. return $t->toArray();
  57. }, $translations);
  58. });
  59. }
  60. /**
  61. * Tests that fields from a translated model are overriden
  62. *
  63. * @return void
  64. */
  65. public function testFindSingleLocale() {
  66. $table = TableRegistry::get('Articles');
  67. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  68. $table->locale('eng');
  69. $results = $table->find()->combine('title', 'body', 'id')->toArray();
  70. $expected = [
  71. 1 => ['Title #1' => 'Content #1'],
  72. 2 => ['Title #2' => 'Content #2'],
  73. 3 => ['Title #3' => 'Content #3'],
  74. ];
  75. $this->assertSame($expected, $results);
  76. }
  77. /**
  78. * Tests that fields from a translated model use the I18n class locale
  79. * and that it propogates to associated models
  80. *
  81. * @return void
  82. */
  83. public function testFindSingleLocaleAssociatedEnv() {
  84. I18n::locale('eng');
  85. $table = TableRegistry::get('Articles');
  86. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  87. $table->hasMany('Comments');
  88. $table->Comments->addBehavior('Translate', ['fields' => ['comment']]);
  89. $results = $table->find()
  90. ->select(['id', 'title', 'body'])
  91. ->contain(['Comments' => ['fields' => ['article_id', 'comment']]])
  92. ->hydrate(false)
  93. ->toArray();
  94. $expected = [
  95. [
  96. 'id' => 1,
  97. 'title' => 'Title #1',
  98. 'body' => 'Content #1',
  99. 'comments' => [
  100. ['article_id' => 1, 'comment' => 'Comment #1', '_locale' => 'eng'],
  101. ['article_id' => 1, 'comment' => 'Comment #2', '_locale' => 'eng'],
  102. ['article_id' => 1, 'comment' => 'Comment #3', '_locale' => 'eng'],
  103. ['article_id' => 1, 'comment' => 'Comment #4', '_locale' => 'eng']
  104. ],
  105. '_locale' => 'eng'
  106. ],
  107. [
  108. 'id' => 2,
  109. 'title' => 'Title #2',
  110. 'body' => 'Content #2',
  111. 'comments' => [
  112. ['article_id' => 2, 'comment' => 'First Comment for Second Article', '_locale' => 'eng'],
  113. ['article_id' => 2, 'comment' => 'Second Comment for Second Article', '_locale' => 'eng']
  114. ],
  115. '_locale' => 'eng'
  116. ],
  117. [
  118. 'id' => 3,
  119. 'title' => 'Title #3',
  120. 'body' => 'Content #3',
  121. 'comments' => [],
  122. '_locale' => 'eng'
  123. ]
  124. ];
  125. $this->assertSame($expected, $results);
  126. I18n::locale('spa');
  127. $results = $table->find()
  128. ->select(['id', 'title', 'body'])
  129. ->contain(['Comments' => ['fields' => ['article_id', 'comment']]])
  130. ->hydrate(false)
  131. ->toArray();
  132. $expected = [
  133. [
  134. 'id' => 1,
  135. 'title' => 'First Article',
  136. 'body' => 'First Article Body',
  137. 'comments' => [
  138. ['article_id' => 1, 'comment' => 'First Comment for First Article', '_locale' => 'spa'],
  139. ['article_id' => 1, 'comment' => 'Second Comment for First Article', '_locale' => 'spa'],
  140. ['article_id' => 1, 'comment' => 'Third Comment for First Article', '_locale' => 'spa'],
  141. ['article_id' => 1, 'comment' => 'Comentario #4', '_locale' => 'spa']
  142. ],
  143. '_locale' => 'spa'
  144. ],
  145. [
  146. 'id' => 2,
  147. 'title' => 'Second Article',
  148. 'body' => 'Second Article Body',
  149. 'comments' => [
  150. ['article_id' => 2, 'comment' => 'First Comment for Second Article', '_locale' => 'spa'],
  151. ['article_id' => 2, 'comment' => 'Second Comment for Second Article', '_locale' => 'spa']
  152. ],
  153. '_locale' => 'spa'
  154. ],
  155. [
  156. 'id' => 3,
  157. 'title' => 'Third Article',
  158. 'body' => 'Third Article Body',
  159. 'comments' => [],
  160. '_locale' => 'spa'
  161. ]
  162. ];
  163. $this->assertSame($expected, $results);
  164. }
  165. /**
  166. * Tests that fields from a translated model are not overriden if translation
  167. * is null
  168. *
  169. * @return void
  170. */
  171. public function testFindSingleLocaleWithNullTranslation() {
  172. $table = TableRegistry::get('Comments');
  173. $table->addBehavior('Translate', ['fields' => ['comment']]);
  174. $table->locale('spa');
  175. $results = $table->find()
  176. ->where(['Comments.id' => 6])
  177. ->combine('id', 'comment')->toArray();
  178. $expected = [6 => 'Second Comment for Second Article'];
  179. $this->assertSame($expected, $results);
  180. }
  181. /**
  182. * Tests that overriding fields with the translate behavior works when
  183. * using conditions and that all other columns are preserved
  184. *
  185. * @return void
  186. */
  187. public function testFindSingleLocaleWithConditions() {
  188. $table = TableRegistry::get('Articles');
  189. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  190. $table->locale('eng');
  191. $results = $table->find()
  192. ->where(['Articles.id' => 2])
  193. ->all();
  194. $this->assertCount(1, $results);
  195. $row = $results->first();
  196. $expected = [
  197. 'id' => 2,
  198. 'title' => 'Title #2',
  199. 'body' => 'Content #2',
  200. 'author_id' => 3,
  201. 'published' => 'Y',
  202. '_locale' => 'eng'
  203. ];
  204. $this->assertEquals($expected, $row->toArray());
  205. }
  206. /**
  207. * Tests that translating fields work when other formatters are used
  208. *
  209. * @return void
  210. */
  211. public function testFindList() {
  212. $table = TableRegistry::get('Articles');
  213. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  214. $table->locale('eng');
  215. $results = $table->find('list')->toArray();
  216. $expected = [1 => 'Title #1', 2 => 'Title #2', 3 => 'Title #3'];
  217. $this->assertSame($expected, $results);
  218. }
  219. /**
  220. * Tests that the query count return the correct results
  221. *
  222. * @return void
  223. */
  224. public function testFindCount() {
  225. $table = TableRegistry::get('Articles');
  226. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  227. $table->locale('eng');
  228. $this->assertEquals(3, $table->find()->count());
  229. }
  230. /**
  231. * Tests that it is possible to get all translated fields at once
  232. *
  233. * @return void
  234. */
  235. public function testFindTranslations() {
  236. $table = TableRegistry::get('Articles');
  237. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  238. $results = $table->find('translations');
  239. $expected = [
  240. [
  241. 'eng' => ['title' => 'Title #1', 'body' => 'Content #1', 'locale' => 'eng'],
  242. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  243. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  244. ],
  245. [
  246. 'eng' => ['title' => 'Title #2', 'body' => 'Content #2', 'locale' => 'eng'],
  247. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  248. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  249. ],
  250. [
  251. 'eng' => ['title' => 'Title #3', 'body' => 'Content #3', 'locale' => 'eng'],
  252. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  253. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  254. ]
  255. ];
  256. $translations = $this->_extractTranslations($results);
  257. $this->assertEquals($expected, $translations->toArray());
  258. $expected = [
  259. 1 => ['First Article' => 'First Article Body'],
  260. 2 => ['Second Article' => 'Second Article Body'],
  261. 3 => ['Third Article' => 'Third Article Body']
  262. ];
  263. $grouped = $results->combine('title', 'body', 'id');
  264. $this->assertEquals($expected, $grouped->toArray());
  265. }
  266. /**
  267. * Tests that it is possible to request just a few translations
  268. *
  269. * @return void
  270. */
  271. public function testFindFilteredTranslations() {
  272. $table = TableRegistry::get('Articles');
  273. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  274. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  275. $expected = [
  276. [
  277. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  278. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  279. ],
  280. [
  281. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  282. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  283. ],
  284. [
  285. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  286. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  287. ]
  288. ];
  289. $translations = $this->_extractTranslations($results);
  290. $this->assertEquals($expected, $translations->toArray());
  291. $expected = [
  292. 1 => ['First Article' => 'First Article Body'],
  293. 2 => ['Second Article' => 'Second Article Body'],
  294. 3 => ['Third Article' => 'Third Article Body']
  295. ];
  296. $grouped = $results->combine('title', 'body', 'id');
  297. $this->assertEquals($expected, $grouped->toArray());
  298. }
  299. /**
  300. * Tests that it is possible to combine find('list') and find('translations')
  301. *
  302. * @return void
  303. */
  304. public function testFindTranslationsList() {
  305. $table = TableRegistry::get('Articles');
  306. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  307. $results = $table
  308. ->find('list', [
  309. 'idField' => 'title',
  310. 'valueField' => '_translations.deu.title',
  311. 'groupField' => 'id'
  312. ])
  313. ->find('translations', ['locales' => ['deu']]);
  314. $expected = [
  315. 1 => ['First Article' => 'Titel #1'],
  316. 2 => ['Second Article' => 'Titel #2'],
  317. 3 => ['Third Article' => 'Titel #3']
  318. ];
  319. $this->assertEquals($expected, $results->toArray());
  320. }
  321. /**
  322. * Tests that you can both override fields and find all translations
  323. *
  324. * @return void
  325. */
  326. public function testFindTranslationsWithFieldOverriding() {
  327. $table = TableRegistry::get('Articles');
  328. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  329. $table->locale('cze');
  330. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  331. $expected = [
  332. [
  333. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  334. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  335. ],
  336. [
  337. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  338. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  339. ],
  340. [
  341. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  342. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  343. ]
  344. ];
  345. $translations = $this->_extractTranslations($results);
  346. $this->assertEquals($expected, $translations->toArray());
  347. $expected = [
  348. 1 => ['Titulek #1' => 'Obsah #1'],
  349. 2 => ['Titulek #2' => 'Obsah #2'],
  350. 3 => ['Titulek #3' => 'Obsah #3']
  351. ];
  352. $grouped = $results->combine('title', 'body', 'id');
  353. $this->assertEquals($expected, $grouped->toArray());
  354. }
  355. /**
  356. * Tests that fields can be overriden in a hasMany association
  357. *
  358. * @return void
  359. */
  360. public function testFindSingleLocaleHasMany() {
  361. $table = TableRegistry::get('Articles');
  362. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  363. $table->hasMany('Comments');
  364. $comments = $table->hasMany('Comments')->target();
  365. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  366. $table->locale('eng');
  367. $comments->locale('eng');
  368. $results = $table->find()->contain(['Comments' => function ($q) {
  369. return $q->select(['id', 'comment', 'article_id']);
  370. }]);
  371. $list = new Collection($results->first()->comments);
  372. $expected = [
  373. 1 => 'Comment #1',
  374. 2 => 'Comment #2',
  375. 3 => 'Comment #3',
  376. 4 => 'Comment #4'
  377. ];
  378. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  379. }
  380. /**
  381. * Test that it is possible to bring translations from hasMany relations
  382. *
  383. * @return void
  384. */
  385. public function testTranslationsHasMany() {
  386. $table = TableRegistry::get('Articles');
  387. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  388. $table->hasMany('Comments');
  389. $comments = $table->hasMany('Comments')->target();
  390. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  391. $results = $table->find('translations')->contain([
  392. 'Comments' => function ($q) {
  393. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  394. }
  395. ]);
  396. $comments = $results->first()->comments;
  397. $expected = [
  398. [
  399. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  400. ],
  401. [
  402. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  403. ],
  404. [
  405. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  406. ],
  407. [
  408. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  409. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  410. ]
  411. ];
  412. $translations = $this->_extractTranslations($comments);
  413. $this->assertEquals($expected, $translations->toArray());
  414. }
  415. /**
  416. * Tests that it is possible to both override fields with a translation and
  417. * also find separately other translations
  418. *
  419. * @return void
  420. */
  421. public function testTranslationsHasManyWithOverride() {
  422. $table = TableRegistry::get('Articles');
  423. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  424. $table->hasMany('Comments');
  425. $comments = $table->hasMany('Comments')->target();
  426. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  427. $table->locale('cze');
  428. $comments->locale('eng');
  429. $results = $table->find('translations')->contain([
  430. 'Comments' => function ($q) {
  431. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  432. }
  433. ]);
  434. $comments = $results->first()->comments;
  435. $expected = [
  436. 1 => 'Comment #1',
  437. 2 => 'Comment #2',
  438. 3 => 'Comment #3',
  439. 4 => 'Comment #4'
  440. ];
  441. $list = new Collection($comments);
  442. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  443. $expected = [
  444. [
  445. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  446. ],
  447. [
  448. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  449. ],
  450. [
  451. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  452. ],
  453. [
  454. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  455. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  456. ]
  457. ];
  458. $translations = $this->_extractTranslations($comments);
  459. $this->assertEquals($expected, $translations->toArray());
  460. $this->assertEquals('Titulek #1', $results->first()->title);
  461. $this->assertEquals('Obsah #1', $results->first()->body);
  462. }
  463. /**
  464. * Tests that it is possible to translate belongsTo associations
  465. *
  466. * @return void
  467. */
  468. public function testFindSingleLocaleBelongsto() {
  469. $table = TableRegistry::get('Articles');
  470. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  471. $authors = $table->belongsTo('Authors')->target();
  472. $authors->addBehavior('Translate', ['fields' => ['name']]);
  473. $table->locale('eng');
  474. $authors->locale('eng');
  475. $results = $table->find()
  476. ->select(['title', 'body'])
  477. ->order(['title' => 'asc'])
  478. ->contain(['Authors' => function ($q) {
  479. return $q->select(['id', 'name']);
  480. }]);
  481. $expected = [
  482. [
  483. 'title' => 'Title #1',
  484. 'body' => 'Content #1',
  485. 'author' => ['id' => 1, 'name' => 'May-rianoh', '_locale' => 'eng'],
  486. '_locale' => 'eng'
  487. ],
  488. [
  489. 'title' => 'Title #2',
  490. 'body' => 'Content #2',
  491. 'author' => ['id' => 3, 'name' => 'larry', '_locale' => 'eng'],
  492. '_locale' => 'eng'
  493. ],
  494. [
  495. 'title' => 'Title #3',
  496. 'body' => 'Content #3',
  497. 'author' => ['id' => 1, 'name' => 'May-rianoh', '_locale' => 'eng'],
  498. '_locale' => 'eng'
  499. ]
  500. ];
  501. $results = array_map(function ($r) {
  502. return $r->toArray();
  503. }, $results->toArray());
  504. $this->assertEquals($expected, $results);
  505. }
  506. /**
  507. * Tests that updating an existing record translations work
  508. *
  509. * @return void
  510. */
  511. public function testUpdateSingleLocale() {
  512. $table = TableRegistry::get('Articles');
  513. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  514. $table->locale('eng');
  515. $article = $table->find()->first();
  516. $this->assertEquals(1, $article->get('id'));
  517. $article->set('title', 'New translated article');
  518. $table->save($article);
  519. $this->assertNull($article->get('_i18n'));
  520. $article = $table->find()->first();
  521. $this->assertEquals(1, $article->get('id'));
  522. $this->assertEquals('New translated article', $article->get('title'));
  523. $this->assertEquals('Content #1', $article->get('body'));
  524. $table->locale(false);
  525. $article = $table->find()->first();
  526. $this->assertEquals(1, $article->get('id'));
  527. $this->assertEquals('First Article', $article->get('title'));
  528. $table->locale('eng');
  529. $article->set('title', 'Wow, such translated article');
  530. $article->set('body', 'A translated body');
  531. $table->save($article);
  532. $this->assertNull($article->get('_i18n'));
  533. $article = $table->find()->first();
  534. $this->assertEquals(1, $article->get('id'));
  535. $this->assertEquals('Wow, such translated article', $article->get('title'));
  536. $this->assertEquals('A translated body', $article->get('body'));
  537. }
  538. /**
  539. * Tests adding new translation to a record
  540. *
  541. * @return void
  542. */
  543. public function testInsertNewTranslations() {
  544. $table = TableRegistry::get('Articles');
  545. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  546. $table->locale('fra');
  547. $article = $table->find()->first();
  548. $this->assertEquals(1, $article->get('id'));
  549. $article->set('title', 'Le titre');
  550. $table->save($article);
  551. $this->assertEquals('fra', $article->get('_locale'));
  552. $article = $table->find()->first();
  553. $this->assertEquals(1, $article->get('id'));
  554. $this->assertEquals('Le titre', $article->get('title'));
  555. $this->assertEquals('First Article Body', $article->get('body'));
  556. $article->set('title', 'Un autre titre');
  557. $article->set('body', 'Le contenu');
  558. $table->save($article);
  559. $this->assertNull($article->get('_i18n'));
  560. $article = $table->find()->first();
  561. $this->assertEquals('Un autre titre', $article->get('title'));
  562. $this->assertEquals('Le contenu', $article->get('body'));
  563. }
  564. /**
  565. * Tests that it is possible to use the _locale property to specify the language
  566. * to use for saving an entity
  567. *
  568. * @return void
  569. */
  570. public function testUpdateTranslationWithLocaleInEntity() {
  571. $table = TableRegistry::get('Articles');
  572. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  573. $article = $table->find()->first();
  574. $this->assertEquals(1, $article->get('id'));
  575. $article->set('_locale', 'fra');
  576. $article->set('title', 'Le titre');
  577. $table->save($article);
  578. $this->assertNull($article->get('_i18n'));
  579. $article = $table->find()->first();
  580. $this->assertEquals(1, $article->get('id'));
  581. $this->assertEquals('First Article', $article->get('title'));
  582. $this->assertEquals('First Article Body', $article->get('body'));
  583. $table->locale('fra');
  584. $article = $table->find()->first();
  585. $this->assertEquals(1, $article->get('id'));
  586. $this->assertEquals('Le titre', $article->get('title'));
  587. $this->assertEquals('First Article Body', $article->get('body'));
  588. }
  589. /**
  590. * Tests that translations are added to the whitelist of associations to be
  591. * saved
  592. *
  593. * @return void
  594. */
  595. public function testSaveTranslationWithAssociationWhitelist() {
  596. $table = TableRegistry::get('Articles');
  597. $table->hasMany('Comments');
  598. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  599. $table->locale('fra');
  600. $article = $table->find()->first();
  601. $this->assertEquals(1, $article->get('id'));
  602. $article->set('title', 'Le titre');
  603. $table->save($article, ['associated' => ['Comments']]);
  604. $this->assertNull($article->get('_i18n'));
  605. $article = $table->find()->first();
  606. $this->assertEquals('Le titre', $article->get('title'));
  607. }
  608. /**
  609. * Tests that after deleting a translated entity, all translations are also removed
  610. *
  611. * @return void
  612. */
  613. public function testDelete() {
  614. $table = TableRegistry::get('Articles');
  615. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  616. $article = $table->find()->first();
  617. $this->assertTrue($table->delete($article));
  618. $translations = TableRegistry::get('I18n')->find()
  619. ->where(['model' => 'Articles', 'foreign_key' => $article->id])
  620. ->count();
  621. $this->assertEquals(0, $translations);
  622. }
  623. /**
  624. * Tests saving multiple translations at once when the translations already
  625. * exist in the database
  626. *
  627. * @return void
  628. */
  629. public function testSaveMultipleTranslations() {
  630. $table = TableRegistry::get('Articles');
  631. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  632. $article = $results = $table->find('translations')->first();
  633. $translations = $article->get('_translations');
  634. $translations['deu']->set('title', 'Another title');
  635. $translations['eng']->set('body', 'Another body');
  636. $article->set('_translations', $translations);
  637. $table->save($article);
  638. $this->assertNull($article->get('_i18n'));
  639. $article = $results = $table->find('translations')->first();
  640. $translations = $article->get('_translations');
  641. $this->assertEquals('Another title', $translations['deu']->get('title'));
  642. $this->assertEquals('Another body', $translations['eng']->get('body'));
  643. }
  644. /**
  645. * Tests saving multiple existing translations and adding new ones
  646. *
  647. * @return void
  648. */
  649. public function testSaveMultipleNewTranslations() {
  650. $table = TableRegistry::get('Articles');
  651. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  652. $article = $results = $table->find('translations')->first();
  653. $translations = $article->get('_translations');
  654. $translations['deu']->set('title', 'Another title');
  655. $translations['eng']->set('body', 'Another body');
  656. $translations['spa'] = new Entity(['title' => 'Titulo']);
  657. $translations['fre'] = new Entity(['title' => 'Titre']);
  658. $article->set('_translations', $translations);
  659. $table->save($article);
  660. $this->assertNull($article->get('_i18n'));
  661. $article = $results = $table->find('translations')->first();
  662. $translations = $article->get('_translations');
  663. $this->assertEquals('Another title', $translations['deu']->get('title'));
  664. $this->assertEquals('Another body', $translations['eng']->get('body'));
  665. $this->assertEquals('Titulo', $translations['spa']->get('title'));
  666. $this->assertEquals('Titre', $translations['fre']->get('title'));
  667. }
  668. /**
  669. * Tests that iterating a resultset twice when using the translations finder
  670. * will not cause any errors nor information loss
  671. *
  672. * @return void
  673. */
  674. public function testUseCountInFindTranslations() {
  675. $table = TableRegistry::get('Articles');
  676. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  677. $articles = $results = $table->find('translations');
  678. $all = $articles->all();
  679. $this->assertCount(3, $all);
  680. $article = $all->first();
  681. $this->assertNotEmpty($article->get('_translations'));
  682. }
  683. }