CorpusController.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. <?php
  2. namespace Drupal\edlp_corpus\Controller;
  3. use Drupal\Core\Controller\ControllerBase;
  4. use Drupal\Core\Language\LanguageInterface;
  5. use Drupal\workflow\Entity\WorkflowManager;
  6. use Drupal\Core\Url;
  7. use Drupal\File\Entity\File;
  8. use Drupal\taxonomy\Entity\Term;
  9. // use Symfony\Component\HttpFoundation\JsonResponse;
  10. use Drupal\Core\Cache\CacheableJsonResponse;
  11. use Drupal\Core\Cache\CacheableMetadata;
  12. use Drupal\core\render\RenderContext;
  13. use Drupal\Core\Ajax\AjaxResponse;
  14. class CorpusController extends ControllerBase {
  15. /**
  16. * Display the markup.
  17. *
  18. * @return array
  19. */
  20. public function contentjson() {
  21. // @see https://www.droptica.com/blog/drupal-8-restjson-integration-simple-javascript-application/
  22. // @see https://www.sitepoint.com/drupal-8-version-entityfieldquery/
  23. // @see https://www.frobiovox.com/posts/2016/03/28/simplify-drupal-8-field-value-calls.html
  24. // @see https://chromatichq.com/blog/dependency-injection-drupal-8-plugins
  25. // Get a node storage object.
  26. // $file_storage = \Drupal::entityManager()->getStorage('node');
  27. $current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
  28. $config = \Drupal::config('system.site');
  29. $query = \Drupal::entityQuery('node')
  30. ->condition('status', 1)
  31. ->condition('type', 'enregistrement');
  32. $nids = $query->execute();
  33. $nodes = entity_load_multiple('node', $nids);
  34. $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node');
  35. $nodes_data = [];
  36. foreach ($nodes as $node) {
  37. // this would be ideal but it's too heavy to load : the whole ajax json goes from 138kb to 1.23Md (even optimized)...
  38. // $node_builder = $view_builder->view($node, 'popup');
  39. // $node = $n->getTranslation($current_langcode);
  40. // remove masqué
  41. $sid = WorkflowManager::getCurrentStateId($node, 'field_workflow');
  42. if($sid != 'corpus_documents_publie') continue;
  43. $entrees = [];
  44. foreach ($node->get('field_entrees')->getValue() as $key => $term) {
  45. $entrees[] = $term['target_id'];
  46. }
  47. // remove if no entries
  48. if(!count($entrees)) continue;
  49. if ($node->hasTranslation($current_langcode)
  50. && !$node->getTranslation($current_langcode)->field_description->isEmpty()) {
  51. $description_values = $node->getTranslation($current_langcode)->get('field_description')->getValue();
  52. }else{
  53. $description_values = $node->get('field_description')->getValue();
  54. }
  55. $description = count($description_values) ? $description_values[0]['value'] : "";
  56. // dpm($description);
  57. $field_son_values = $node->get('field_son')->getValue();
  58. $audio_fid = count($field_son_values) ? $field_son_values[0]['target_id'] : "";
  59. $audio_file = \Drupal\file\Entity\File::load($audio_fid);
  60. $audio_url = null;
  61. // if node don't have a sound file atteched, skip it
  62. if(!$audio_file) continue;
  63. $son_uri = $audio_file->getFileUri();
  64. $audio_url = file_create_url($son_uri);
  65. // has article ?
  66. $article_value = $node->body->getValue();
  67. $has_article = count($article_value);
  68. // if($has_article && $article_value[0]['value'] == "")
  69. // dpm($article_value);
  70. $document_url = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($node, $current_langcode) {
  71. if ($node->hasTranslation($current_langcode)){
  72. return $node->getTranslation($current_langcode)->toUrl()->toString();
  73. }else{
  74. return $node->toUrl()->toString();
  75. }
  76. });
  77. // favoris marker
  78. $nodes_data[] = array(
  79. "nid" => $node->get('nid')->getString(),
  80. "title" => $node->get('title')->getString(),
  81. "description" => $description,
  82. "entrees" => $entrees,
  83. // "son_fid" => $audio_fid,
  84. "audio_url" => $audio_url,
  85. "has_article" => $has_article,
  86. "chutier_action" => 'add',
  87. "document_url" => $document_url,
  88. );
  89. }
  90. $query = \Drupal::entityQuery('taxonomy_term')
  91. ->condition('vid', 'entrees');
  92. $tids = $query->execute();
  93. // $nodes = entity_load_multiple('node', $nids);
  94. foreach ($tids as $tid) {
  95. $entrees[] = $tid;
  96. }
  97. $data = array(
  98. 'date' => time(),
  99. 'site_name' => $config->get('name'),
  100. 'count' => count($nodes),
  101. 'nodes' => $nodes_data,
  102. 'entrees' => $entrees,
  103. 'language' => $current_langcode,
  104. );
  105. // https://spinningcode.org/2017/05/cached-json-responses-in-drupal-8/
  106. // cache is invalidated in edlp_corpus.module by tags
  107. $data['#cache'] = [
  108. 'max-age' => \Drupal\Core\Cache\Cache::PERMANENT,
  109. 'tags' => ['rebuild-corpus-cache'],
  110. 'contexts' => ['languages:language_content'],
  111. ];
  112. // $response = new JsonResponse();
  113. // $response->setData($data);
  114. $response = new CacheableJsonResponse($data);
  115. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));
  116. return $response;
  117. return array(
  118. '#markup'=>'Hello Corpus'
  119. );
  120. }
  121. // ___ ___ _
  122. // | \ ___ __ __|_ _|_ _ __| |_____ __
  123. // | |) / _ \/ _(_-<| || ' \/ _` / -_) \ /
  124. // |___/\___/\__/__/___|_||_\__,_\___/_\_\
  125. private function docsindexQuery() {
  126. // $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  127. $query = \Drupal::entityQuery('node')
  128. ->condition('status', 1)
  129. ->condition('type', 'enregistrement')
  130. ->sort('title', 'ASC');
  131. // ->range(0,50);
  132. $nids = $query->execute();
  133. $nodes = entity_load_multiple('node', $nids);
  134. // $current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
  135. $this->docsindex_nodes = [];
  136. $this->docsindex_nids = [];
  137. foreach ($nodes as $node) {
  138. // remove masqué
  139. $sid = WorkflowManager::getCurrentStateId($node, 'field_workflow');
  140. if($sid != 'corpus_documents_publie') continue;
  141. $this->docsindex_nodes[] = $node;
  142. // record an array of nids for corpus map filtering
  143. $this->docsindex_nids[] = $node->get('nid')->getString();
  144. // // translate the node
  145. // $node = \Drupal::service('entity.repository')->getTranslationFromContext($node, $language);
  146. // $title = $this->stripAccent($node->getTitle());
  147. // $ordered_trans_nodes[$title] = $node;
  148. }
  149. // // TODO: sort by title
  150. // ksort($ordered_trans_nodes);
  151. //
  152. // foreach ($ordered_trans_nodes as $title => $node) {
  153. // $this->docsindex_nodes[] = $node;
  154. // // record an array of nids for corpus map filtering
  155. // $this->docsindex_nids[] = $node->get('nid')->getString();
  156. // }
  157. }
  158. // private function stripAccent($str){
  159. // return strtr(
  160. // utf8_decode($str),
  161. // utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'),
  162. // 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
  163. // }
  164. private function docsindexToRenderable(){
  165. $this->docsindexQuery();
  166. return array(
  167. "#theme"=>'edlp_corpus_docsindex',
  168. '#docsindex_nodes' => $this->docsindex_nodes
  169. );
  170. }
  171. /**
  172. * Display lastdocs as a page.
  173. *
  174. * @return renderable array
  175. */
  176. public function docsindex() {
  177. return $this->docsindexToRenderable();
  178. }
  179. /**
  180. * Get lastdocs data as json through ajax.
  181. *
  182. * @return json
  183. */
  184. public function docsindexjson() {
  185. $renderable = $this->docsindexToRenderable();
  186. // $rendered = render($renderable);
  187. // We can't render directly the entity as it throw an exception with cachable data
  188. //http://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/#the-dreaded-leaked-metadata-error
  189. $rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($renderable) {
  190. return render($renderable);
  191. });
  192. $data = [
  193. 'rendered'=> $rendered,
  194. 'title'=>t('Documents Index'),
  195. 'documents_lies' => $this->docsindex_nids,
  196. ];
  197. // translations links
  198. $route_name = 'edlp_corpus.docsindex';
  199. $links = \Drupal::languageManager()->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, Url::fromRoute($route_name));
  200. if (isset($links->links)) {
  201. $translations_build = [
  202. '#theme' => 'links__language_block',
  203. '#links' => $links->links,
  204. '#attributes' => ['class' => ["language-switcher-{$links->method_id}",],],
  205. '#set_active_class' => TRUE,
  206. ];
  207. $translations_rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($translations_build) {return render($translations_build);});
  208. $data['translations_links'] = $translations_rendered;
  209. }
  210. $data['#cache'] = [
  211. 'max-age' => \Drupal\Core\Cache\Cache::PERMANENT,
  212. 'tags' => ['edlp-docsindex-cache'],
  213. 'contexts' => [
  214. 'languages:language_content',
  215. 'user'
  216. ]
  217. ];
  218. // $response = new JsonResponse();
  219. // $response->setData($data);
  220. $response = new CacheableJsonResponse($data);
  221. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));
  222. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($renderable));
  223. return $response;
  224. }
  225. // _ _ _
  226. // | | __ _ __| |_ __| |___ __ ___
  227. // | |__/ _` (_-< _/ _` / _ \/ _(_-<
  228. // |____\__,_/__/\__\__,_\___/\__/__/
  229. private function query() {
  230. $query = \Drupal::entityQuery('node')
  231. ->condition('status', 1)
  232. ->condition('type', 'enregistrement')
  233. ->sort('created', 'DESC')
  234. ->range(0,50);
  235. $nids = $query->execute();
  236. $nodes = entity_load_multiple('node', $nids);
  237. // $current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
  238. $this->lastdocs_nodes = [];
  239. $this->lastdocs_nids = [];
  240. foreach ($nodes as $node) {
  241. // remove masqué
  242. $sid = WorkflowManager::getCurrentStateId($node, 'field_workflow');
  243. if($sid != 'corpus_documents_publie') continue;
  244. $this->lastdocs_nodes[] = $node;
  245. // record an array of nids for corpus map filtering
  246. $this->lastdocs_nids[] = $node->get('nid')->getString();
  247. }
  248. // // record an array of nids for corpus map filtering
  249. // $this->lastdocs_nids = [];
  250. // foreach($nids as $key => $nid){
  251. // $this->lastdocs_nids[] = $nid;
  252. // }
  253. }
  254. private function toRenderable(){
  255. $this->query();
  256. // dpm($this->next_event_node);
  257. return array(
  258. "#theme"=>'edlp_corpus_lastdocs',
  259. '#lastdocs_nodes' => $this->lastdocs_nodes
  260. );
  261. }
  262. /**
  263. * Display lastdocs as a page.
  264. *
  265. * @return renderable array
  266. */
  267. public function lastdocs() {
  268. return $this->toRenderable();
  269. }
  270. /**
  271. * Get lastdocs data as json through ajax.
  272. *
  273. * @return json
  274. */
  275. public function lastdocsjson() {
  276. $renderable = $this->toRenderable();
  277. // $rendered = render($renderable);
  278. // We can't render directly the entity as it throw an exception with cachable data
  279. //http://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/#the-dreaded-leaked-metadata-error
  280. $rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($renderable) {
  281. return render($renderable);
  282. });
  283. $data = [
  284. 'rendered'=> $rendered,
  285. 'title'=>t('Recently uploaded'),
  286. 'documents_lies' => $this->lastdocs_nids,
  287. ];
  288. // translations links
  289. // use Drupal\Core\Url;
  290. // use Drupal\Core\Language\LanguageInterface;
  291. $route_name = 'edlp_corpus.lastdocs';
  292. $links = \Drupal::languageManager()->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, Url::fromRoute($route_name));
  293. if (isset($links->links)) {
  294. $translations_build = [
  295. '#theme' => 'links__language_block',
  296. '#links' => $links->links,
  297. '#attributes' => ['class' => ["language-switcher-{$links->method_id}",],],
  298. '#set_active_class' => TRUE,
  299. ];
  300. $translations_rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($translations_build) {return render($translations_build);});
  301. $data['translations_links'] = $translations_rendered;
  302. }
  303. $data['#cache'] = [
  304. 'max-age' => \Drupal\Core\Cache\Cache::PERMANENT,
  305. 'tags' => ['edlp-lastdocs-cache'],
  306. 'contexts' => [
  307. 'languages:language_content'
  308. ]
  309. ];
  310. // $response = new JsonResponse();
  311. // $response->setData($data);
  312. $response = new CacheableJsonResponse($data);
  313. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));
  314. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($renderable));
  315. return $response;
  316. }
  317. // _ _ _ _ ___ _
  318. // /_\ _ _| |_(_)__| |___ ___ |_ _|_ _ __| |_____ __
  319. // / _ \| '_| _| / _| / -_|_-< | || ' \/ _` / -_) \ /
  320. // /_/ \_\_| \__|_\__|_\___/__/ |___|_||_\__,_\___/_\_\
  321. private function articlesQuery() {
  322. $query = \Drupal::entityQuery('node')
  323. ->condition('status', 1)
  324. ->condition('type', 'enregistrement')
  325. ->condition('body', '', "<>")
  326. ->sort('created', 'DESC');
  327. // ->range(0,20);
  328. $nids = $query->execute();
  329. $nodes = entity_load_multiple('node', $nids);
  330. $current_langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
  331. $this->articles_nodes = [];
  332. $this->articles_nids = [];
  333. foreach ($nodes as $node) {
  334. // remove masqué
  335. $sid = WorkflowManager::getCurrentStateId($node, 'field_workflow');
  336. if($sid != 'corpus_documents_publie') continue;
  337. // TODO: check if article is translated
  338. if ($node->getTranslation($current_langcode)->body->isEmpty()) continue;
  339. $this->articles_nodes[] = $node;
  340. // record an array of nids for corpus map filtering
  341. $this->articles_nids[] = $node->get('nid')->getString();
  342. }
  343. }
  344. private function articlesToRenderable(){
  345. $this->articlesQuery();
  346. // dpm($this->next_event_node);
  347. return array(
  348. "#theme"=>'edlp_corpus_articlesindex',
  349. '#articles_nodes' => $this->articles_nodes
  350. );
  351. }
  352. /**
  353. * Display lastdocs as a page.
  354. *
  355. * @return renderable array
  356. */
  357. public function articlesindex() {
  358. return $this->articlesToRenderable();
  359. }
  360. /**
  361. * Get lastdocs data as json through ajax.
  362. *
  363. * @return json
  364. */
  365. public function articlesindexjson() {
  366. $renderable = $this->articlesToRenderable();
  367. // $rendered = render($renderable);
  368. // We can't render directly the entity as it throw an exception with cachable data
  369. //http://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/#the-dreaded-leaked-metadata-error
  370. $rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($renderable) {
  371. return render($renderable);
  372. });
  373. $data = [
  374. 'rendered'=> $rendered,
  375. 'title'=>'Articles',
  376. 'articles' => $this->articles_nids,
  377. 'documents_lies' => $this->articles_nids,
  378. ];
  379. // translations links
  380. // use Drupal\Core\Url;
  381. // use Drupal\Core\Language\LanguageInterface;
  382. $route_name = 'edlp_corpus.articlesindex';
  383. $links = \Drupal::languageManager()->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, Url::fromRoute($route_name));
  384. if (isset($links->links)) {
  385. $translations_build = [
  386. '#theme' => 'links__language_block',
  387. '#links' => $links->links,
  388. '#attributes' => ['class' => ["language-switcher-{$links->method_id}",],],
  389. '#set_active_class' => TRUE,
  390. ];
  391. $translations_rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($translations_build) {return render($translations_build);});
  392. $data['translations_links'] = $translations_rendered;
  393. }
  394. $data['#cache'] = [
  395. 'max-age' => \Drupal\Core\Cache\Cache::PERMANENT,
  396. 'tags' => ['edlp-articlesindex-cache'],
  397. 'contexts' => [
  398. 'languages:language_content'
  399. ]
  400. ];
  401. // $response = new JsonResponse();
  402. // $response->setData($data);
  403. $response = new CacheableJsonResponse($data);
  404. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));
  405. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($renderable));
  406. return $response;
  407. }
  408. // ___ _ _ _ _
  409. // / __|___| | |___ __| |_(_)___ _ _
  410. // | (__/ _ \ | / -_) _| _| / _ \ ' \
  411. // \___\___/_|_\___\__|\__|_\___/_||_|
  412. private function collectionQuery(){
  413. $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
  414. $query = \Drupal::entityQuery('taxonomy_term')
  415. // ->sort('weight', 'DESC')
  416. // ->sort('name', 'DESC')
  417. ->condition('vid', 'entrees');
  418. $tids = $query->execute();
  419. // $terms = entity_load_multiple('taxonomy_term', $tids);
  420. // $terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadMultiple($t‌​erms);
  421. $terms = Term::loadMultiple($tids);
  422. $ordered_terms = [];
  423. foreach ($terms as $term) {
  424. // remove masqué
  425. $sid = WorkflowManager::getCurrentStateId($term, 'field_workflow');
  426. if($sid == 'generique_masque') continue;
  427. // translate the term
  428. $term = \Drupal::service('entity.repository')->getTranslationFromContext($term, $language);
  429. $name = $term->getName();
  430. $ordered_trans_terms[$name] = $term;
  431. }
  432. ksort($ordered_trans_terms);
  433. $this->entrees_terms = $ordered_trans_terms;
  434. }
  435. private function collectionToRenderable(){
  436. $this->collectionQuery();
  437. return array(
  438. "#theme"=>'edlp_corpus_collection',
  439. '#entrees_terms' => $this->entrees_terms
  440. );
  441. }
  442. public function collection(){
  443. return $this->collectionToRenderable();
  444. }
  445. public function collectionjson(){
  446. $renderable = $this->collectionToRenderable();
  447. // $rendered = render($renderable);
  448. // We can't render directly the entity as it throw an exception with cachable data
  449. //http://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/#the-dreaded-leaked-metadata-error
  450. $rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($renderable) {
  451. return render($renderable);
  452. });
  453. $data = [
  454. 'rendered'=> $rendered,
  455. 'title'=>'Collection'
  456. ];
  457. // translations links
  458. // use Drupal\Core\Url;
  459. // use Drupal\Core\Language\LanguageInterface;
  460. $route_name = 'edlp_corpus.collection';
  461. $links = \Drupal::languageManager()->getLanguageSwitchLinks(LanguageInterface::TYPE_URL, Url::fromRoute($route_name));
  462. if (isset($links->links)) {
  463. $translations_build = [
  464. '#theme' => 'links__language_block',
  465. '#links' => $links->links,
  466. '#attributes' => ['class' => ["language-switcher-{$links->method_id}",],],
  467. '#set_active_class' => TRUE,
  468. ];
  469. $translations_rendered = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($translations_build) {return render($translations_build);});
  470. $data['translations_links'] = $translations_rendered;
  471. }
  472. $data['#cache'] = [
  473. 'max-age' => \Drupal\Core\Cache\Cache::PERMANENT,
  474. 'tags' => ['edlp-articlesindex-cache'],
  475. 'contexts' => [
  476. 'languages:language_content'
  477. ]
  478. ];
  479. // $response = new JsonResponse();
  480. // $response->setData($data);
  481. $response = new CacheableJsonResponse($data);
  482. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));
  483. $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($renderable));
  484. return $response;
  485. }
  486. }