kloonbron-drupal-patch.inc.txt 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. Taak 127-A — Drupal-patch voor de kloonbron
  2. ===========================================
  3. Bestand op de server:
  4. sites/all/modules/custom/custom.mijn_aanmeldingen.inc
  5. (volledig pad productie: /data/disk/o1/static/uitgaanskrant/sites/all/
  6. modules/custom/custom.mijn_aanmeldingen.inc)
  7. TWEE INGREPEN, daarna `drush @uitgaanskrant.com cc all`:
  8. 1) REGEL 125 in _custom_aanm_veldkaart(), blok 'activity':
  9. 'entree' => NULL,
  10. wordt
  11. 'entree' => 'field_act_entree',
  12. Waarom: _custom_stadsactiviteit_create() schrijft wel degelijk naar
  13. field_act_entree (door Bob toegevoegd 2026-08-26, zelfde vocabulary als
  14. field_goo_entree). Zonder deze regel gaat het entree-type verloren bij
  15. het klonen van een activiteit. Bewijs: node 222818 heeft
  16. field_act_entree = 36197 en dat kwam niet mee in de respons.
  17. 2) REGELS 240 t/m 313 (de regel `/**` van het A2-docblock t/m de laatste `}`
  18. van het bestand) vervangen door ALLES hieronder, vanaf de markering.
  19. Getest op productie 2026-09-20 (read-only, via drush php-script; het bestand
  20. zelf is niet gewijzigd). Uitkomsten staan in TASKS.md taak 127-A.
  21. Let op: `file_create_url()` geeft onder drush `http://` omdat er geen
  22. request-context is. Via een echte HTTP-request levert Drupal `https://` --
  23. niet "repareren", wel bij de eerste test vanuit de app controleren.
  24. ⬇ PLAK VANAF HIER ⬇
  25. /**
  26. * Alle bestands-URL's van een (multi-value) bestandsveld.
  27. *
  28. * Tegenhanger van _custom_aanm_bestand_url() voor meerdere waarden.
  29. */
  30. function _custom_aanm_bestand_urls($node, $veld) {
  31. $uit = array();
  32. if (empty($veld)) {
  33. return $uit;
  34. }
  35. $items = field_get_items('node', $node, $veld);
  36. if (empty($items) || !is_array($items)) {
  37. return $uit;
  38. }
  39. foreach ($items as $item) {
  40. if (is_array($item) && !empty($item['uri'])) {
  41. $uit[] = file_create_url($item['uri']);
  42. }
  43. }
  44. return $uit;
  45. }
  46. /**
  47. * Uitgeklapte keten provincie|gemeente|plaats voor een town-tid.
  48. *
  49. * Zelfde niveaubepaling als _custom_mijn_stadsrechten_service():
  50. * count(taxonomy_get_parents_all()) geeft 1 = provincie, 2 = gemeente,
  51. * 3 = plaats. De app splitst 'keten' met dezelfde custom functions als
  52. * bij de stadsrechten-cascade, dus het scheidingsteken moet '|' blijven.
  53. */
  54. function _custom_aanm_keten($tid) {
  55. $leeg = array(
  56. 'provincie_tid' => NULL,
  57. 'gemeente_tid' => NULL,
  58. 'plaats_tid' => NULL,
  59. 'keten' => '||',
  60. );
  61. if (empty($tid)) {
  62. return $leeg;
  63. }
  64. $ouders = taxonomy_get_parents_all((int) $tid);
  65. if (empty($ouders)) {
  66. return $leeg;
  67. }
  68. // taxonomy_get_parents_all levert kind -> ... -> wortel; omdraaien.
  69. $pad = array_reverse($ouders);
  70. $uit = $leeg;
  71. if (isset($pad[0])) {
  72. $uit['provincie_tid'] = (string) $pad[0]->tid;
  73. }
  74. if (isset($pad[1])) {
  75. $uit['gemeente_tid'] = (string) $pad[1]->tid;
  76. }
  77. if (isset($pad[2])) {
  78. $uit['plaats_tid'] = (string) $pad[2]->tid;
  79. }
  80. $uit['keten'] = implode('|', array(
  81. $uit['provincie_tid'] !== NULL ? $uit['provincie_tid'] : '',
  82. $uit['gemeente_tid'] !== NULL ? $uit['gemeente_tid'] : '',
  83. $uit['plaats_tid'] !== NULL ? $uit['plaats_tid'] : '',
  84. ));
  85. return $uit;
  86. }
  87. /**
  88. * A2 — kloonbron: de RAUWE waarden van één eigen aanmelding.
  89. *
  90. * GET /nl/flutterdrup/aanmelding_kloonbron.json?nid=X
  91. *
  92. * Geeft tids en fids terug, niet de weergavewaarden — precies de sleutels
  93. * die evenementen/create en stadsactiviteiten/create verwachten. Daarnaast
  94. * logo_url/fotos_urls voor de preview op de aanmaakpagina, en bij een
  95. * activiteit de uitgeklapte plaatsketen voor de cascade-dropdowns.
  96. */
  97. function _custom_aanmelding_kloonbron() {
  98. global $user;
  99. if (empty($user->uid)) {
  100. return services_error('Niet ingelogd.', 401);
  101. }
  102. $nid = isset($_GET['nid']) ? (int) $_GET['nid'] : 0;
  103. if ($nid < 1) {
  104. return services_error('Parameter nid ontbreekt.', 400);
  105. }
  106. $node = node_load($nid);
  107. if (!$node) {
  108. return services_error('Aanmelding niet gevonden.', 404);
  109. }
  110. if (!in_array($node->type, array('go_out_event', 'activity'), TRUE)) {
  111. return services_error('Dit is geen aanmelding.', 400);
  112. }
  113. // Eigenaarscheck: zonder dit leest iemand andermans gegevens uit.
  114. if ((int) $node->uid !== (int) $user->uid) {
  115. return services_error('Geen toegang tot deze aanmelding.', 403);
  116. }
  117. $v = _custom_aanm_veldkaart($node->type);
  118. $titel = !empty($v['titel']) ? _custom_aanm_item($node, $v['titel']) : NULL;
  119. if (empty($titel)) {
  120. $titel = $node->title;
  121. }
  122. // Gedeelde velden. De datumvelden komen bewust NIET mee: je kloont juist
  123. // om hetzelfde op een nieuwe datum te zetten.
  124. $uit = array(
  125. 'nid' => (int) $node->nid,
  126. 'type' => $node->type,
  127. 'titel' => $titel,
  128. 'omschrijving' => _custom_aanm_item($node, 'body', 'value'),
  129. 'entree_prijs' => _custom_aanm_item($node, $v['prijs'], 'value'),
  130. 'toelichting_entree' => _custom_aanm_item($node, $v['toelichting'], 'value'),
  131. 'website_url' => _custom_aanm_item($node, $v['website'], 'url'),
  132. 'categorie_tids' => _custom_aanm_lijst($node, $v['categorie'], 'tid'),
  133. 'logo_fid' => _custom_aanm_item($node, $v['logo'], 'fid'),
  134. 'fotos_fids' => _custom_aanm_lijst($node, $v['fotos'], 'fid'),
  135. // Voor de preview op de aanmaakpagina; de create-actie gebruikt de fids.
  136. 'logo_url' => _custom_aanm_bestand_url($node, $v['logo']),
  137. 'fotos_urls' => _custom_aanm_bestand_urls($node, $v['fotos']),
  138. // Beide types hebben een entree-veld (field_goo_entree resp.
  139. // field_act_entree, zelfde vocabulary) — zie _custom_aanm_veldkaart().
  140. 'entree_tid' => !empty($v['entree'])
  141. ? _custom_aanm_item($node, $v['entree'], 'tid')
  142. : NULL,
  143. );
  144. if ($node->type === 'go_out_event') {
  145. $uit['horecagelegenheid_nid'] = _custom_aanm_item($node, $v['horeca'], 'target_id');
  146. $uit['tickets_url'] = _custom_aanm_item($node, $v['tickets'], 'url');
  147. }
  148. else {
  149. $plaats_tid = _custom_aanm_item($node, $v['plaats'], 'tid');
  150. $uit['plaats_tid'] = $plaats_tid;
  151. // Uitgeklapt, zodat de app de drie cascade-dropdowns kan voorvullen.
  152. $uit += _custom_aanm_keten($plaats_tid);
  153. $uit['organisator'] = _custom_aanm_item($node, $v['organisator'], 'value');
  154. $uit['contact'] = _custom_aanm_item($node, $v['contact'], 'value');
  155. $adres = field_get_items('node', $node, $v['adres']);
  156. if (!empty($adres[0]) && is_array($adres[0])) {
  157. $uit['adres_straat'] = isset($adres[0]['thoroughfare']) ? $adres[0]['thoroughfare'] : NULL;
  158. $uit['adres_postcode'] = isset($adres[0]['postal_code']) ? $adres[0]['postal_code'] : NULL;
  159. $uit['adres_plaats'] = isset($adres[0]['locality']) ? $adres[0]['locality'] : NULL;
  160. }
  161. }
  162. return $uit;
  163. }