TranslateBehaviorTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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 CakePHP(tm) v 3.0.0
  13. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  14. */
  15. namespace Cake\Test\TestCase\Model\Behavior;
  16. use Cake\Collection\Collection;
  17. use Cake\Event\Event;
  18. use Cake\Model\Behavior\TranslateBehavior;
  19. use Cake\ORM\Entity;
  20. use Cake\ORM\TableRegistry;
  21. use Cake\TestSuite\TestCase;
  22. /**
  23. * Translate behavior test case
  24. */
  25. class TranslateBehaviorTest extends TestCase {
  26. /**
  27. * fixtures
  28. *
  29. * @var array
  30. */
  31. public $fixtures = [
  32. 'core.translate',
  33. 'core.article',
  34. 'core.comment',
  35. 'core.author'
  36. ];
  37. public function tearDown() {
  38. parent::tearDown();
  39. TableRegistry::clear();
  40. }
  41. /**
  42. * Returns an array with all the translations found for a set of records
  43. *
  44. * @return Collection
  45. */
  46. protected function _extractTranslations($data) {
  47. return (new Collection($data))->map(function($row) {
  48. $translations = $row->get('_translations');
  49. if (!$translations) {
  50. return [];
  51. }
  52. return array_map(function($t) {
  53. return $t->toArray();
  54. }, $translations);
  55. });
  56. }
  57. /**
  58. * Tests that fields from a translated model are overriden
  59. *
  60. * @return void
  61. */
  62. public function testFindSingleLocale() {
  63. $table = TableRegistry::get('Articles');
  64. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  65. $table->locale('eng');
  66. $results = $table->find()->combine('title', 'body', 'id')->toArray();
  67. $expected = [
  68. 1 => ['Title #1' => 'Content #1'],
  69. 2 => ['Title #2' => 'Content #2'],
  70. 3 => ['Title #3' => 'Content #3'],
  71. ];
  72. $this->assertSame($expected, $results);
  73. }
  74. /**
  75. * Tests that overriding fields with the translate behavior works when
  76. * using conditions and that all other columns are preserved
  77. *
  78. * @return void
  79. */
  80. public function testFindSingleLocaleWithConditions() {
  81. $table = TableRegistry::get('Articles');
  82. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  83. $table->locale('eng');
  84. $results = $table->find()
  85. ->where(['Articles.id' => 2])
  86. ->all();
  87. $this->assertCount(1, $results);
  88. $row = $results->first();
  89. $expected = [
  90. 'id' => 2,
  91. 'title' => 'Title #2',
  92. 'body' => 'Content #2',
  93. 'author_id' => 3,
  94. 'published' => 'Y',
  95. '_locale' => 'eng'
  96. ];
  97. $this->assertEquals($expected, $row->toArray());
  98. }
  99. /**
  100. * Tests that translating fields work when other formatters are used
  101. *
  102. * @return void
  103. */
  104. public function testFindList() {
  105. $table = TableRegistry::get('Articles');
  106. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  107. $table->locale('eng');
  108. $results = $table->find('list')->toArray();
  109. $expected = [1 => 'Title #1', 2 => 'Title #2', 3 => 'Title #3'];
  110. $this->assertSame($expected, $results);
  111. }
  112. /**
  113. * Tests that the query count return the correct results
  114. *
  115. * @return void
  116. */
  117. public function testFindCount() {
  118. $table = TableRegistry::get('Articles');
  119. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  120. $table->locale('eng');
  121. $this->assertEquals(3, $table->find()->count());
  122. }
  123. /**
  124. * Tests that it is possible to get all translated fields at once
  125. *
  126. * @return void
  127. */
  128. public function testFindTranslations() {
  129. $table = TableRegistry::get('Articles');
  130. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  131. $results = $table->find('translations');
  132. $expected = [
  133. [
  134. 'eng' => ['title' => 'Title #1', 'body' => 'Content #1', 'locale' => 'eng'],
  135. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  136. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  137. ],
  138. [
  139. 'eng' => ['title' => 'Title #2', 'body' => 'Content #2', 'locale' => 'eng'],
  140. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  141. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  142. ],
  143. [
  144. 'eng' => ['title' => 'Title #3', 'body' => 'Content #3', 'locale' => 'eng'],
  145. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  146. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  147. ]
  148. ];
  149. $translations = $this->_extractTranslations($results);
  150. $this->assertEquals($expected, $translations->toArray());
  151. $expected = [
  152. 1 => ['First Article' => 'First Article Body'],
  153. 2 => ['Second Article' => 'Second Article Body'],
  154. 3 => ['Third Article' => 'Third Article Body']
  155. ];
  156. $grouped = $results->combine('title', 'body', 'id');
  157. $this->assertEquals($expected, $grouped->toArray());
  158. }
  159. /**
  160. * Tests that it is possible to request just a few translations
  161. *
  162. * @return void
  163. */
  164. public function testFindFilteredTranslations() {
  165. $table = TableRegistry::get('Articles');
  166. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  167. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  168. $expected = [
  169. [
  170. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  171. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  172. ],
  173. [
  174. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  175. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  176. ],
  177. [
  178. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  179. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  180. ]
  181. ];
  182. $translations = $this->_extractTranslations($results);
  183. $this->assertEquals($expected, $translations->toArray());
  184. $expected = [
  185. 1 => ['First Article' => 'First Article Body'],
  186. 2 => ['Second Article' => 'Second Article Body'],
  187. 3 => ['Third Article' => 'Third Article Body']
  188. ];
  189. $grouped = $results->combine('title', 'body', 'id');
  190. $this->assertEquals($expected, $grouped->toArray());
  191. }
  192. /**
  193. * Tests that it is possible to combine find('list') and find('translations')
  194. *
  195. * @return void
  196. */
  197. public function testFindTranslationsList() {
  198. $table = TableRegistry::get('Articles');
  199. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  200. $results = $table
  201. ->find('list', [
  202. 'idField' => 'title',
  203. 'valueField' => '_translations.deu.title',
  204. 'groupField' => 'id'
  205. ])
  206. ->find('translations', ['locales' => ['deu']]);
  207. $expected = [
  208. 1 => ['First Article' => 'Titel #1'],
  209. 2 => ['Second Article' => 'Titel #2'],
  210. 3 => ['Third Article' => 'Titel #3']
  211. ];
  212. $this->assertEquals($expected, $results->toArray());
  213. }
  214. /**
  215. * Tests that you can both override fields and find all translations
  216. *
  217. * @return void
  218. */
  219. public function testFindTranslationsWithFieldOverriding() {
  220. $table = TableRegistry::get('Articles');
  221. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  222. $table->locale('cze');
  223. $results = $table->find('translations', ['locales' => ['deu', 'cze']]);
  224. $expected = [
  225. [
  226. 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
  227. 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
  228. ],
  229. [
  230. 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
  231. 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
  232. ],
  233. [
  234. 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
  235. 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
  236. ]
  237. ];
  238. $translations = $this->_extractTranslations($results);
  239. $this->assertEquals($expected, $translations->toArray());
  240. $expected = [
  241. 1 => ['Titulek #1' => 'Obsah #1'],
  242. 2 => ['Titulek #2' => 'Obsah #2'],
  243. 3 => ['Titulek #3' => 'Obsah #3']
  244. ];
  245. $grouped = $results->combine('title', 'body', 'id');
  246. $this->assertEquals($expected, $grouped->toArray());
  247. }
  248. /**
  249. * Tests that fields can be overriden in a hasMany association
  250. *
  251. * @return void
  252. */
  253. public function testFindSingleLocaleHasMany() {
  254. $table = TableRegistry::get('Articles');
  255. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  256. $table->hasMany('Comments');
  257. $comments = $table->hasMany('Comments')->target();
  258. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  259. $table->locale('eng');
  260. $comments->locale('eng');
  261. $results = $table->find()->contain(['Comments' => function($q) {
  262. return $q->select(['id', 'comment', 'article_id']);
  263. }]);
  264. $list = new Collection($results->first()->comments);
  265. $expected = [
  266. 1 => 'Comment #1',
  267. 2 => 'Comment #2',
  268. 3 => 'Comment #3',
  269. 4 => 'Comment #4'
  270. ];
  271. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  272. }
  273. /**
  274. * Test that it is possible to bring translations from hasMany relations
  275. *
  276. * @return void
  277. */
  278. public function testTranslationsHasMany() {
  279. $table = TableRegistry::get('Articles');
  280. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  281. $table->hasMany('Comments');
  282. $comments = $table->hasMany('Comments')->target();
  283. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  284. $results = $table->find('translations')->contain([
  285. 'Comments' => function($q) {
  286. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  287. }
  288. ]);
  289. $comments = $results->first()->comments;
  290. $expected = [
  291. [
  292. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  293. ],
  294. [
  295. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  296. ],
  297. [
  298. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  299. ],
  300. [
  301. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  302. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  303. ]
  304. ];
  305. $translations = $this->_extractTranslations($comments);
  306. $this->assertEquals($expected, $translations->toArray());
  307. }
  308. /**
  309. * Tests that it is possible to both override fields with a translation and
  310. * also find separately other translations
  311. *
  312. * @return void
  313. */
  314. public function testTranslationsHasManyWithOverride() {
  315. $table = TableRegistry::get('Articles');
  316. $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
  317. $table->hasMany('Comments');
  318. $comments = $table->hasMany('Comments')->target();
  319. $comments->addBehavior('Translate', ['fields' => ['comment']]);
  320. $table->locale('cze');
  321. $comments->locale('eng');
  322. $results = $table->find('translations')->contain([
  323. 'Comments' => function($q) {
  324. return $q->find('translations')->select(['id', 'comment', 'article_id']);
  325. }
  326. ]);
  327. $comments = $results->first()->comments;
  328. $expected = [
  329. 1 => 'Comment #1',
  330. 2 => 'Comment #2',
  331. 3 => 'Comment #3',
  332. 4 => 'Comment #4'
  333. ];
  334. $list = new Collection($comments);
  335. $this->assertEquals($expected, $list->combine('id', 'comment')->toArray());
  336. $expected = [
  337. [
  338. 'eng' => ['comment' => 'Comment #1', 'locale' => 'eng']
  339. ],
  340. [
  341. 'eng' => ['comment' => 'Comment #2', 'locale' => 'eng']
  342. ],
  343. [
  344. 'eng' => ['comment' => 'Comment #3', 'locale' => 'eng']
  345. ],
  346. [
  347. 'eng' => ['comment' => 'Comment #4', 'locale' => 'eng'],
  348. 'spa' => ['comment' => 'Comentario #4', 'locale' => 'spa']
  349. ]
  350. ];
  351. $translations = $this->_extractTranslations($comments);
  352. $this->assertEquals($expected, $translations->toArray());
  353. $this->assertEquals('Titulek #1', $results->first()->title);
  354. $this->assertEquals('Obsah #1', $results->first()->body);
  355. }
  356. }