Project

General

Profile

Download (84.2 KB) Statistics
| Branch: | Tag: | Revision:
1 2fd6da0b Andreas Kohlbecker
<?php
2
/**
3
 * @file
4
 * Functions for dealing with CDM entities from the package model.name
5
 *
6
 * @copyright
7
 *   (C) 2007-2015 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 *
15
 * @author
16
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
17
 */
18
19
/**
20
 * @defgroup compose Compose functions
21
 * @{
22
 * Functions which are composing Drupal render arays
23
 *
24
 * The cdm_dataportal module needs to compose rather complex render arrays from
25
 * the data returned by the CDM REST service. The compose functions are
26
 * responsible for creating the render arrays.
27
 *
28
 * All these functions are also implementations of the compose_hook()
29
 * which is used in the proxy_content() function.
30
 * @}
31
 */
32
33
34
/**
35
 * Provides the name render template to be used within the page elements identified the the $renderPath.
36
 *
37 a565e612 Andreas Kohlbecker
 * The render templates arrays contains one or more name render templates to be used within the page elements identified the the
38 2fd6da0b Andreas Kohlbecker
 * renderPath. The renderPath is the key of the subelements whereas the value is the name render template.
39
 *
40 a565e612 Andreas Kohlbecker
 * The render paths used for a cdm_dataportal page can be visualized by supplying the HTTP query parameter RENDER_PATH=1.
41
 *
42
 * It will be tried to find  the best matching default RenderTemplate by stripping the dot separated render path
43
 * element by element. If no matching template is found the DEFAULT will be used:
44
 *
45
 * - related_taxon.heterotypicSynonymyGroup.taxon_page_synonymy
46
 * - related_taxon.heterotypicSynonymyGroup.taxon_page_synonymy
47
 * - related_taxon.heterotypicSynonymyGroup.taxon_page_synonymy
48 2fd6da0b Andreas Kohlbecker
 *
49
 * A single render template can be used for multiple render paths. In this case the according key of the render templates
50
 * array element should be the list of these render paths concatenated by ONLY a comma character without any whitespace.
51
 *
52
 * A render template is an associative array. The keys of this array are referring to the keys as defined in the part
53
 * definitions array.
54
 * @see get_partDefinition($taxonNameType) for more information
55
 *
56
 * The value of the render template element must be set to TRUE in order to let this part being rendered.
57
 * The namePart, nameAuthorPart and referencePart can also hold an associative array with a single
58
 * element: array('#uri' => TRUE). The value of the #uri element will be replaced by the according
59
 * links if the parameters $nameLink or $refenceLink are set.
60
 *
61 a565e612 Andreas Kohlbecker
 * @param string $render_path
62 2fd6da0b Andreas Kohlbecker
 *   The render path can consist of multiple dot separated elements
63
 *   @see RenderHints::getRenderPath()
64
 * @param string $nameLink
65 87aa88d6 Andreas Kohlbecker
 *   The link path or URL to be used for name parts if a link is forseen in the template
66 2fd6da0b Andreas Kohlbecker
 *   matching the given $renderPath.
67
 * @param string $referenceLink
68
 *   The link path ot URL to be used for nomenclatural reference parts if a link is forseen
69
 *   in the template matching the given $renderPath.
70
 * @return array
71
 *   An associative array, the render template
72
 */
73 a565e612 Andreas Kohlbecker
function get_nameRenderTemplate($render_path, $nameLink = NULL, $referenceLink = NULL) {
74 2fd6da0b Andreas Kohlbecker
75 03f4f6f7 Andreas Kohlbecker
  static $split_render_templates = NULL;
76
77
  if($split_render_templates == NULL) {
78 35abbad4 Andreas Kohlbecker
    $render_templates = variable_get(NameRenderConfiguration::CDM_NAME_RENDER_TEMPLATES, NameRenderConfiguration::CDM_NAME_RENDER_TEMPLATES_DEFAULT);
79 2fd6da0b Andreas Kohlbecker
    // needs to be converted to an array
80 db725031 Andreas Kohlbecker
    $render_templates = (object_to_array($render_templates));
81 03f4f6f7 Andreas Kohlbecker
82
    // separate render templates which are combined with a comma
83
    $split_render_templates = array();
84
    foreach($render_templates as $key => $template){
85
      if(strpos($key, ',')){
86
        foreach(explode(',', $key) as $path){
87
          $split_render_templates[$path] = $template;
88
        }
89
      } else {
90
        $split_render_templates[$key] = $template;
91
      }
92
    }
93 2fd6da0b Andreas Kohlbecker
  }
94
95
  // get the base element of the renderPath
96 a565e612 Andreas Kohlbecker
  if (($separatorPos = strpos($render_path, '.')) > 0) {
97
    $renderPath_base = substr($render_path, 0, $separatorPos);
98 2fd6da0b Andreas Kohlbecker
  } else {
99 a565e612 Andreas Kohlbecker
    $renderPath_base = $render_path;
100 2fd6da0b Andreas Kohlbecker
  }
101
102 03f4f6f7 Andreas Kohlbecker
  $template = NULL;
103 2fd6da0b Andreas Kohlbecker
  // 1. try to find a template using the render path base element
104 03f4f6f7 Andreas Kohlbecker
  if(array_key_exists($renderPath_base, $split_render_templates)){
105
    $template = (array)$split_render_templates[$renderPath_base];
106 2fd6da0b Andreas Kohlbecker
  }
107
108 a565e612 Andreas Kohlbecker
  // 2. Find best matching default RenderTemplate
109 2fd6da0b Andreas Kohlbecker
  // by stripping the dot separated render path element by element
110 a565e612 Andreas Kohlbecker
  // if no matching template is found the DEFAULT will be used.
111
  while (!is_array($template) && strlen($render_path) > 0) {
112 03f4f6f7 Andreas Kohlbecker
    foreach ($split_render_templates as $path => $t) {
113 a565e612 Andreas Kohlbecker
      if ($path == $render_path) {
114 2fd6da0b Andreas Kohlbecker
        $template = $t;
115
        break;
116
      }
117
    }
118
    // shorten by one element
119 a565e612 Andreas Kohlbecker
    $render_path = substr($render_path, strrpos($render_path, '.') + 1, strlen($render_path));
120 2fd6da0b Andreas Kohlbecker
  }
121
122 03f4f6f7 Andreas Kohlbecker
123 2fd6da0b Andreas Kohlbecker
  // 3. Otherwise get default RenderTemplate from theme.
124
  if (!is_array($template)) {
125 03f4f6f7 Andreas Kohlbecker
    $template = $split_render_templates['#DEFAULT'];
126 2fd6da0b Andreas Kohlbecker
  }
127
128
  // --- set the link uris to the according template fields if they exist
129
  if(isset($template['nameAuthorPart']) && isset($template['nameAuthorPart']['#uri'])) {
130
    if ($nameLink) {
131
      $template['nameAuthorPart']['#uri'] = $nameLink;
132
    }
133
    else {
134
      unset($template['nameAuthorPart']['#uri']);
135
    }
136
  }
137
138
  if ($nameLink && isset($template['namePart']['#uri'])) {
139
    $template['namePart']['#uri'] = $nameLink;
140
  }
141
  else {
142
    unset($template['namePart']['#uri']);
143
  }
144
145
  if ($referenceLink && isset($template['referencePart']['#uri'])) {
146
    $template['referencePart']['#uri'] = $referenceLink;
147
  }
148
  else {
149
    unset($template['referencePart']['#uri']);
150
  }
151
152
  return $template;
153
}
154
155
/**
156
 * The part definitions define the specific parts of which a rendered taxon name plus additional information will consist.
157
 *
158
 * A full taxon name plus additional information can consist of the following elements:
159
 *
160
 *   - name: the taxon name inclugin rank nbut without author
161
 *   - authorTeam:  The authors of a reference, also used in taxon names
162
 *   - authors:  The authors of a reference, also used in taxon names
163
 *   - reference: the nomenclatural reference,
164
 *   - microreference:  Volume, page number etc.
165
 *   - status:  The nomenclatural status of a name
166
 *   - description: name descriptions like protologues etc ...
167
 *
168
 * These elements are combined in the part definitions array to from the specific parts to be rendered.
169
 * Usually the following parts are formed:
170
 *
171
 * The name "Lapsana communis L., Sp. Pl.: 811. 1753" shall be an example here:
172
 *  - namePart: the name and rank (in example: "Lapsana communis")
173
 *  - authorshipPart: the author (in example: "L.")
174
 *  - nameAuthorPart: the combination of name and author part (in example: "Lapsana communis L.").
175
 *     This is useful for zoological names where the authorshipPart belongs to the name and both should
176
 *     be combined when a link to the taxon is rendered.
177
 *  - referencePart: the nomencaltural reference (in example: "Sp. Pl. 1753")
178
 *  - microreferencePart: usually the page number (in example ": 811.")
179
 *  - statusPart: the nomenclatorical status
180
 *  - descriptionPart:
181
 *
182
 * Each set of parts is dedicated to render a specific TaxonName type, the type names are used as keys for the
183
 * specific parts part definitions:
184
 *
185
 *  - BotanicalName
186
 *  - ZoologicalName
187
 *  - #DEFAULT:  covers ViralNames and general NonViralNames
188
 *
189
 * An example:
190
 * @code
191
 * array(
192
 *    'ZoologicalName' => array(
193
 *        'namePart' => array('name' => TRUE),
194
 *        'referencePart' => array('authorTeam' => TRUE),
195
 *        'microreferencePart' => array('microreference' => TRUE),
196
 *        'statusPart' => array('status' => TRUE),
197
 *        'descriptionPart' => array('description' => TRUE),
198
 *    ),
199
 *    'BotanicalName' => array(
200
 *        'namePart' => array(
201
 *            'name' => TRUE,
202
 *            'authors' => TRUE,
203
 *        ),
204
 *        'referencePart' => array(
205
 *            'reference' => TRUE,
206
 *            'microreference' => TRUE,
207
 *        ),
208
 *        'statusPart' => array('status' => TRUE),
209
 *        'descriptionPart' => array('description' => TRUE),
210
 *    ),
211
 *  );
212
 * @endcode
213
 *
214 828a0c8c Andreas Kohlbecker
 * @param object $taxonNameType
215
 *    A cdm TaxonNameType entity
216
 *
217 2fd6da0b Andreas Kohlbecker
 */
218
function get_partDefinition($taxonNameType) {
219
220
  static $part_definitions = null;
221
  if (!isset($part_definitions)) {
222 35abbad4 Andreas Kohlbecker
    $part_definitions = object_to_array(variable_get(NameRenderConfiguration::CDM_PART_DEFINITIONS, NameRenderConfiguration::CDM_PART_DEFINITIONS_DEFAULT));
223 2fd6da0b Andreas Kohlbecker
  }
224
225 c2545e1c Andreas Kohlbecker
  $dtype = nameTypeToDTYPE($taxonNameType);
226 2fd6da0b Andreas Kohlbecker
  if (array_key_exists($taxonNameType, $part_definitions)) {
227
    return $part_definitions[$taxonNameType];
228 c2545e1c Andreas Kohlbecker
  } else if (array_key_exists($dtype, $part_definitions)) {
229
    return $part_definitions[$dtype];
230 2fd6da0b Andreas Kohlbecker
  } else {
231
    return $part_definitions['#DEFAULT']; // covers ViralNames and general NonViralNames
232
  }
233
234
}
235
236
237
/**
238
 * Renders the markup for a CDM TaxonName instance.
239
 *
240
 * The layout of the name representation is configured by the
241
 * part_definitions and render_templates (see get_partDefinition() and
242
 * get_nameRenderTemplate())
243
 *
244 6679207a Andreas Kohlbecker
 * @param $taxon_name_or_taxon_base
245
 *    A cdm TaxonBase or TaxonName entity
246 20bfe15b Andreas Kohlbecker
 * @param $name_link
247 b9d4068f Andreas Kohlbecker
 *    URI to the taxon, the path provided by path_to_taxon() must be processed
248
 *    by url() before passing to this method
249
 * @param $reference_link
250
 *    URI to the reference, the path provided by path_to_reference() must be
251
 *    processed by url() before passing to this method
252 95ef7468 Andreas Kohlbecker
 * @param bool $show_taxon_name_annotations
253
 *    Enable the display of footnotes for annotations on the taxon and name
254
 *    (default: true)
255 6679207a Andreas Kohlbecker
 * @param bool $is_type_designation
256 2fd6da0b Andreas Kohlbecker
 *    To indicate that the supplied taxon name is a name type designation.
257 cd09cee6 Andreas Kohlbecker
 *    (default: false)
258
 * @param array $skip_render_template_parts
259
 *    The render template elements matching these part names will bes skipped.
260
 *    This parameter should only be used in rare cases like for suppressing
261
 *    the sec reference of synonyms. Normally the configuration of the
262
 *    name appearance should only be done via the render templates themselves. (default: [])
263 6679207a Andreas Kohlbecker
 * @param bool $is_invalid
264 c35bab7f Andreas Kohlbecker
 *   Indicates that this taxon is invalid. In this case the name part will be shown in double quotes.
265 cd09cee6 Andreas Kohlbecker
 *   This is useful when rendering taxon relation ships. (default: false)
266 2fd6da0b Andreas Kohlbecker
 *
267
 * @return string
268
 *  The markup for a taxon name.
269
 */
270 20bfe15b Andreas Kohlbecker
function render_taxon_or_name($taxon_name_or_taxon_base, $name_link = NULL, $reference_link = NULL,
271 95ef7468 Andreas Kohlbecker
  $show_taxon_name_annotations = true, $is_type_designation = false, $skip_render_template_parts = [], $is_invalid = false) {
272 2fd6da0b Andreas Kohlbecker
273 ea3933d7 Andreas Kohlbecker
  $is_doubtful = false;
274 a764d3d1 Andreas Kohlbecker
  $taxon_base = null;
275 95ef7468 Andreas Kohlbecker
  $nom_status_fkey = null; // FootNoteKey
276 2fd6da0b Andreas Kohlbecker
  if($taxon_name_or_taxon_base->class == 'Taxon' || $taxon_name_or_taxon_base->class == 'Synonym'){
277 a764d3d1 Andreas Kohlbecker
    $taxon_base = $taxon_name_or_taxon_base;
278 e95b14dd Andreas Kohlbecker
    if(isset($taxon_name_or_taxon_base->name)){
279 a764d3d1 Andreas Kohlbecker
      $taxon_name = $taxon_name_or_taxon_base->name;
280 e95b14dd Andreas Kohlbecker
    } else {
281 a764d3d1 Andreas Kohlbecker
      $taxon_name = cdm_ws_get(CDM_WS_TAXON . '/$0/name', array($taxon_name_or_taxon_base->uuid));
282 e95b14dd Andreas Kohlbecker
    }
283 ea3933d7 Andreas Kohlbecker
    $is_doubtful = $taxon_name_or_taxon_base->doubtful;
284 de7bcbcc Andreas Kohlbecker
    // use the TaxonBase.tagged_title so we have the secRef
285
    $tagged_title = $taxon_name_or_taxon_base->taggedTitle;
286 2fd6da0b Andreas Kohlbecker
  } else {
287 102f8c26 Andreas Kohlbecker
    // assuming this is a TaxonName
288 a764d3d1 Andreas Kohlbecker
    $taxon_name = $taxon_name_or_taxon_base;
289
    if(isset($taxon_name->taggedFullTitle)){
290 de7bcbcc Andreas Kohlbecker
      $tagged_title = $taxon_name_or_taxon_base->taggedFullTitle;
291
    } else {
292
      $tagged_title = $taxon_name_or_taxon_base->taggedName;
293
    }
294 2fd6da0b Andreas Kohlbecker
  }
295
296
297 20bfe15b Andreas Kohlbecker
  $renderTemplate = get_nameRenderTemplate(RenderHints::getRenderPath(), $name_link, $reference_link);
298 a764d3d1 Andreas Kohlbecker
  $partDefinition = get_partDefinition($taxon_name->nameType);
299 2fd6da0b Andreas Kohlbecker
300
  // Apply definitions to template.
301
  foreach ($renderTemplate as $part => $uri) {
302
303
    if (isset($partDefinition[$part])) {
304
      $renderTemplate[$part] = $partDefinition[$part];
305
    }
306
    if (is_array($uri) && isset($uri['#uri'])) {
307
      $renderTemplate[$part]['#uri'] = $uri['#uri'];
308
    }
309
  }
310
311 cd09cee6 Andreas Kohlbecker
  foreach($skip_render_template_parts as $part){
312
    unset($renderTemplate[$part]);
313
  }
314
315 de7bcbcc Andreas Kohlbecker
  $secref_tagged_text = tagged_text_extract_reference_and_detail($tagged_title);
316
  // taxon names will have the nomenclatural reference in the tagged full title:
317
  $nomref_tagged_text = tagged_text_extract_reference($tagged_title);
318
  $nom_status_tagged_text = tagged_text_extract_nomstatus($tagged_title);
319 c35bab7f Andreas Kohlbecker
  $appended_phrase_tagged_text = array(); // this is filled later
320
321 de7bcbcc Andreas Kohlbecker
  normalize_tagged_text($tagged_title);
322 2fd6da0b Andreas Kohlbecker
323 61fc6c93 Andreas Kohlbecker
  $is_valid_tagged_title =
324 de7bcbcc Andreas Kohlbecker
    isset($tagged_title)
325
    && is_array($tagged_title)
326
    && isset($tagged_title[0]->text)
327
    && is_string($tagged_title[0]->text)
328
    && $tagged_title[0]->text != ''
329 61fc6c93 Andreas Kohlbecker
    && isset($tagged_title[0]->type);
330 2fd6da0b Andreas Kohlbecker
  $lastAuthorElementString = FALSE;
331
332 c35bab7f Andreas Kohlbecker
  $name_encasement = $is_invalid ? '"' : '';
333 54a3c136 Andreas Kohlbecker
  $doubtful_marker = $is_doubtful ? '?&#8239;' : ''; // 	&#8239; =  NARROW NO-BREAK SPACE
334 2330b553 Andreas Kohlbecker
  $doubtful_marker_markup = '';
335
336
  if($doubtful_marker){
337
    $doubtful_marker_markup = '<span class="doubtful">' . $doubtful_marker . '</span>';
338 61fc6c93 Andreas Kohlbecker
    if($tagged_title[0]->text == '?' ){
339
      // remove the first tagged text element
340
      unset($tagged_title[0]);
341
    }
342 2330b553 Andreas Kohlbecker
  }
343 c35bab7f Andreas Kohlbecker
344
  // split off all appendedPhrase item  from the end of the array (usually there only should  be one)
345 de7bcbcc Andreas Kohlbecker
  while($tagged_title[count($tagged_title)-1]->type == "appendedPhrase"){
346
    $appended_phrase_tagged_text[] = array_pop($tagged_title);
347 c35bab7f Andreas Kohlbecker
  }
348
349 2fd6da0b Andreas Kohlbecker
  // Got to use second entry as first one, see ToDo comment below ...
350 61fc6c93 Andreas Kohlbecker
  if ($is_valid_tagged_title) {
351 2fd6da0b Andreas Kohlbecker
352 de7bcbcc Andreas Kohlbecker
    $taggedName = $tagged_title;
353 2fd6da0b Andreas Kohlbecker
    $hasNamePart_with_Authors = isset($renderTemplate['namePart']) && isset($renderTemplate['namePart']['authors']);
354
    $hasNameAuthorPart_with_Authors = isset($renderTemplate['nameAuthorPart']) && isset($renderTemplate['nameAuthorPart']['authors']);
355
356 c35bab7f Andreas Kohlbecker
357 2fd6da0b Andreas Kohlbecker
    if (!(($hasNamePart_with_Authors) || ($hasNameAuthorPart_with_Authors))) {
358
      // Find author and split off from name.
359
      // TODO expecting to find the author as the last element.
360
      /*
361
      if($taggedName[count($taggedName)- 1]->type == 'authors'){
362
        $authorTeam = $taggedName[count($taggedName)- 1]->text;
363
        unset($taggedName[count($taggedName)- 1]);
364
      }
365
      */
366
367
      // Remove all authors.
368
      $taggedNameNew = array();
369
      foreach ($taggedName as $element) {
370
        if ($element->type != 'authors') {
371
          $taggedNameNew[] = $element;
372
        }
373
        else {
374
          $lastAuthorElementString = $element->text;
375
        }
376
      }
377
      $taggedName = $taggedNameNew;
378 e90899ac Andreas Kohlbecker
      unset($taggedNameNew);
379 2fd6da0b Andreas Kohlbecker
    }
380 cd09cee6 Andreas Kohlbecker
    $name = '<span class="' . $taxon_name->class . '">' . $doubtful_marker_markup . $name_encasement . cdm_tagged_text_to_markup($taggedName) . $name_encasement . '</span>';
381 2fd6da0b Andreas Kohlbecker
  }
382
  else {
383 61fc6c93 Andreas Kohlbecker
    // use titleCache instead
384 a764d3d1 Andreas Kohlbecker
    $name = '<span class="' . $taxon_name->class . '_titleCache">' . $doubtful_marker_markup . $name_encasement . $taxon_name->titleCache . $name_encasement . '</span>';
385 c35bab7f Andreas Kohlbecker
  }
386
387
388
  if(isset($appended_phrase_tagged_text[0])){
389 54a3c136 Andreas Kohlbecker
    $name .= ' <span class="appended-phrase">'. cdm_tagged_text_to_markup($appended_phrase_tagged_text) . '</span>';
390 2fd6da0b Andreas Kohlbecker
  }
391
392
  // Fill name into $renderTemplate.
393 c35bab7f Andreas Kohlbecker
  array_setr('name', $name , $renderTemplate);
394 2fd6da0b Andreas Kohlbecker
395
  // Fill with authorTeam.
396
  /*
397
  if($authorTeam){
398
    $authorTeamHtml = ' <span class="authorTeam">'.$authorTeam.'</span>';
399
    array_setr('authorTeam', $authorTeamHtml, $renderTemplate);
400
  }
401
  */
402
403
  // Fill with reference.
404
  if (isset($renderTemplate['referencePart']) && !$is_type_designation) {
405
406 a764d3d1 Andreas Kohlbecker
    $registrations = cdm_ws_get(CDM_WS_NAME, array($taxon_name->uuid, "registrations"));
407 eaff53f7 Andreas Kohlbecker
    $registration_markup = render_registrations($registrations);
408
409 2fd6da0b Andreas Kohlbecker
    // default separator
410
    $separator = '';
411
412 95ef7468 Andreas Kohlbecker
    // [Eckhard]:"Komma nach dem Taxonnamen ist grundsätzlich falsch,
413 2fd6da0b Andreas Kohlbecker
    // Komma nach dem Autornamen ist überall dort falsch, wo ein "in" folgt."
414 9c96ba36 Andreas Kohlbecker
    if (isset($renderTemplate['referencePart']['reference']) && isset($taxon_name->nomenclaturalSource)) {
415
      $microreference = $taxon_name->nomenclaturalSource->citationMicroReference;
416 8bc96896 Andreas Kohlbecker
      if(count($nomref_tagged_text) == 0 && isset($taxon_name->nomenclaturalSource->citation)){
417 5939425d Andreas Kohlbecker
        // drupal message for debugging of #9599
418
        // drupal_set_message("reference/$0/nomenclaturalCitation' must no longer be used (type: "
419
        //  . $taxon_name_or_taxon_base->class . (isset($taxon_name_or_taxon_base->type) ? " - " +$taxon_name_or_taxon_base->type : ""  . ")"), "error");
420 8bc96896 Andreas Kohlbecker
        $citation = cdm_ws_getNomenclaturalReference($taxon_name->nomenclaturalSource->citation->uuid, $microreference);
421 de7bcbcc Andreas Kohlbecker
        // Find preceding element of the reference.
422
        $precedingKey = get_preceding_contentElementKey('reference', $renderTemplate);
423
        if (str_beginsWith($citation, ", in")) {
424
          $citation = substr($citation, 2);
425
          $separator = ' ';
426
        }
427
        elseif (!str_beginsWith($citation, "in") && $precedingKey == 'authors') {
428
          $separator = ', ';
429
        } else {
430
          $separator = ' ';
431
        }
432
        $referenceArray['#separator'] = $separator;
433
        $referenceArray['#html'] = '<span class="reference">' . $citation . '</span>' . $registration_markup;
434 2fd6da0b Andreas Kohlbecker
      } else {
435 4fa58f06 Andreas Kohlbecker
        // this is the case for taxon names
436 de7bcbcc Andreas Kohlbecker
        $referenceArray['#html'] = cdm_tagged_text_to_markup($nomref_tagged_text);
437 2fd6da0b Andreas Kohlbecker
      }
438
439
      array_setr('reference', $referenceArray, $renderTemplate);
440
    }
441
442
    // If authors have been removed from the name part the last named authorteam
443
    // should be added to the reference citation, otherwise, keep the separator
444
    // out of the reference.
445
    if (isset($renderTemplate['referencePart']['authors']) && $lastAuthorElementString) {
446
      // If the nomenclaturalReference citation is not included in the
447 eaff53f7 Andreas Kohlbecker
      // reference part but display of the microreference
448 2fd6da0b Andreas Kohlbecker
      // is wanted, append the microreference to the authorTeam.
449
      $citation = '';
450
      if (!isset($renderTemplate['referencePart']['reference']) && isset($renderTemplate['referencePart']['microreference'])) {
451
        $separator = ": ";
452 a764d3d1 Andreas Kohlbecker
        $citation = $taxon_name->nomenclaturalMicroReference;
453 2fd6da0b Andreas Kohlbecker
      }
454
      $referenceArray['#html'] = ' <span class="reference">' . $lastAuthorElementString . $separator . $citation . '</span>';
455
      array_setr('authors', $referenceArray, $renderTemplate);
456
    }
457
  }
458
459
  $is_reference_year = false;
460
  if (isset($renderTemplate['referenceYearPart']['reference.year'])) {
461 a764d3d1 Andreas Kohlbecker
    if(isset($taxon_name->nomenclaturalSource->citation->datePublished)){
462
      $referenceArray['#html'] = ' <span class="reference">' . timePeriodToString($taxon_name->nomenclaturalSource->citation->datePublished) . '</span>';
463 2fd6da0b Andreas Kohlbecker
      array_setr('reference.year', $referenceArray, $renderTemplate);
464
      $is_reference_year = true;
465
    }
466
  }
467
468 e90899ac Andreas Kohlbecker
  // Fill with status.
469 dce1dacc Andreas Kohlbecker
  if(isset($renderTemplate['statusPart']['status'])){
470 1d0407b7 Andreas Kohlbecker
    if (isset($nom_status_tagged_text[0])) {
471 222784c5 Andreas Kohlbecker
        $tt_to_markup_options = array('html' => false);
472
        foreach ($nom_status_tagged_text as &$tt){
473
         if($tt->type == 'nomStatus'&& isset($tt->entityReference)) {
474
           $nom_status = cdm_ws_get(CDM_WS_NOMENCLATURALSTATUS, array($tt->entityReference->uuid));
475 8202a2c0 Andreas Kohlbecker
           $nom_status_fkey = handle_nomenclatural_status_as_footnote($nom_status);
476 222784c5 Andreas Kohlbecker
           $tt_to_markup_options['html'] = true;
477
         }
478
        }
479
        array_setr(
480
          'status',
481 e9ac7c6f Andreas Kohlbecker
          '<span class="nomenclatural_status">' . cdm_tagged_text_to_markup($nom_status_tagged_text, array('postSeparator'), 'span', $tt_to_markup_options) . '</span>',
482
          $renderTemplate);
483 e90899ac Andreas Kohlbecker
    }
484
  }
485
486 2fd6da0b Andreas Kohlbecker
  if (isset($renderTemplate['secReferencePart'])){
487
    if(isset($secref_tagged_text[1])){
488 e90899ac Andreas Kohlbecker
      $post_separator_markup = $is_reference_year ? '.': '';
489 6aad9da8 Andreas Kohlbecker
      if(isset($nom_status_tagged_text[count($nom_status_tagged_text) - 1]) && ($nom_status_tagged_text[count($nom_status_tagged_text) - 1]->type ==  'postSeparator')){
490 4a1ab871 Andreas Kohlbecker
        $post_separator_markup = cdm_tagged_text_to_markup(array($nom_status_tagged_text[count($nom_status_tagged_text) - 1 ]));
491 e90899ac Andreas Kohlbecker
      };
492 2fd6da0b Andreas Kohlbecker
      array_setr('secReference',
493 e90899ac Andreas Kohlbecker
        $post_separator_markup
494 2fd6da0b Andreas Kohlbecker
          . ' <span class="sec_reference">'
495 4bfe18f9 Andreas Kohlbecker
          . join('', cdm_tagged_text_values($secref_tagged_text))
496 2fd6da0b Andreas Kohlbecker
          . '</span>', $renderTemplate);
497
    }
498
  }
499
500
  // Fill with protologues etc...
501 f9b5740e Andreas Kohlbecker
  $protologue_links = [];
502 2fd6da0b Andreas Kohlbecker
  if (array_setr('description', TRUE, $renderTemplate)) {
503 f9b5740e Andreas Kohlbecker
    $external_links = cdm_ws_get(CDM_WS_NAME_PROTOLOGUE_LINKS, $taxon_name->uuid);
504
    if($external_links){
505
      foreach ($external_links as $link) {
506
        if (!empty($link->uri)) {
507 df2b235a Andreas Kohlbecker
          // for the link see also cdm_external_uri()
508 f86bb6df Andreas Kohlbecker
          $protologue_links[] = l(font_awesome_icon_markup('fa-book'), $link->uri, ['html' => true]);
509 20bfe15b Andreas Kohlbecker
          }
510 2fd6da0b Andreas Kohlbecker
        }
511
      }
512 e024a603 Andreas Kohlbecker
513
    // ---------------
514
515
    $additional_pub_markup = '';
516
      $descriptions = cdm_ws_get(CDM_WS_PORTAL_NAME_DESCRIPTIONS, $taxon_name->uuid);
517
      if($descriptions) {
518
        foreach ($descriptions as $description) {
519
          if (!empty($description)) {
520
            $additional_citations = [];
521
            $additional_data = [];
522
            foreach ($description->elements as $description_element) {
523
              if (isset($description_element->multilanguageText_L10n) && $description_element->multilanguageText_L10n->text) {
524 c11fa375 Andreas Kohlbecker
                RenderHints::setAnnotationsAndSourceConfig(synonymy_annotations_and_source_config());
525
                $annotations_and_sources = handle_annotations_and_sources($description_element);
526
                // synonymy_annotations_and_source_config() has 'sources_as_content' => FALSE, so no need to handle inline sources here
527 e024a603 Andreas Kohlbecker
                $element_media = cdm_description_element_media(
528
                  $description_element,
529
                  [
530
                    'application/pdf',
531
                    'image/png',
532
                    'image/jpeg',
533
                    'image/gif',
534
                    'text/html',
535
                  ]
536
                );
537
                if (isset($description_element->feature) && $description_element->feature->uuid == UUID_ADDITIONAL_PUBLICATION) {
538 54127ad4 Andreas Kohlbecker
                   $additional_citations[] = ' [& ' . trim($description_element->multilanguageText_L10n->text) . $element_media . $annotations_and_sources->footNoteKeysMarkup() .']';
539 e024a603 Andreas Kohlbecker
                } else {
540 54127ad4 Andreas Kohlbecker
                  $additional_data[] = ' [' . trim($description_element->multilanguageText_L10n->text) . $element_media . $annotations_and_sources->footNoteKeysMarkup(). ']';
541 e024a603 Andreas Kohlbecker
                }
542
              }
543
            }
544
            // merge
545
            $additional_citations = array_merge($additional_citations, $additional_data);
546
            $additional_pub_markup .= join(',', $additional_citations);
547
          }
548
        }
549
      }
550
      if($additional_pub_markup){
551 b15c610a Andreas Kohlbecker
        $additional_pub_markup = ' ' . $additional_pub_markup . '. '; // surround with space etc.
552 e024a603 Andreas Kohlbecker
      }
553 b15c610a Andreas Kohlbecker
      array_setr('description', $additional_pub_markup . join(', ', $protologue_links), $renderTemplate);
554 e024a603 Andreas Kohlbecker
      array_replace_keyr('description', 'protologue', $renderTemplate); // in preparation for #9319
555 2fd6da0b Andreas Kohlbecker
  }
556
557
  // Render.
558 f695daf4 Andreas Kohlbecker
  $out = '';
559
  if(isset($_REQUEST['RENDER_PATH'])){
560
    // developer option to show the render path with each taxon name
561
    $out .= '<span class="render-path">' . RenderHints::getRenderPath() . '</span>';
562
  }
563
  $out .= '<span class="' . html_class_attribute_ref($taxon_name_or_taxon_base)
564 a764d3d1 Andreas Kohlbecker
    . '" data-cdm-ref="/name/' . $taxon_name->uuid . '" data-cdm-render-path="' . RenderHints::getRenderPath() .'">';
565 2fd6da0b Andreas Kohlbecker
566
  foreach ($renderTemplate as $partName => $part) {
567
    $separator = '';
568
    $partHtml = '';
569
    $uri = FALSE;
570
    if (!is_array($part)) {
571
      continue;
572
    }
573
    if (isset($part['#uri']) && is_string($part['#uri'])) {
574
      $uri = $part['#uri'];
575
      unset($part['#uri']);
576
    }
577 cd09cee6 Andreas Kohlbecker
    foreach ($part as $part => $content) {
578 2fd6da0b Andreas Kohlbecker
      $html = '';
579
      if (is_array($content)) {
580
        $html = $content['#html'];
581
        if(isset($content['#separator'])) {
582
          $separator = $content['#separator'];
583
        }
584
      }
585
      elseif (is_string($content)) {
586
        $html = $content;
587
      }
588 a8393f17 Andreas Kohlbecker
      if($html){ // skip empty elements
589
        $partHtml .= '<span class="' . $part . '">' . $html . '</span>';
590
      }
591 2fd6da0b Andreas Kohlbecker
    }
592
    if ($uri) {
593 95ef7468 Andreas Kohlbecker
      // cannot use l() here since the #uri already should have been processed through uri() at this point
594 2fd6da0b Andreas Kohlbecker
      $out .= $separator . '<a href="' . $uri . '" class="' . $partName . '">' . $partHtml . '</a>';
595
596
    }
597
    else {
598
      $out .= $separator . $partHtml;
599
    }
600
  }
601
  $out .= '</span>';
602 95ef7468 Andreas Kohlbecker
603
  $annotations_and_sources = new AnnotationsAndSources();
604
  if($nom_status_fkey){
605
    // the nomenclatural status footnote key refers to the source citation
606
    $annotations_and_sources->addFootNoteKey($nom_status_fkey);
607
  }
608
  if ($show_taxon_name_annotations) {
609 a764d3d1 Andreas Kohlbecker
    if($taxon_base){
610 95ef7468 Andreas Kohlbecker
      $annotations_and_sources = handle_annotations_and_sources($taxon_base,
611
        null, null, $annotations_and_sources);
612 a764d3d1 Andreas Kohlbecker
    }
613 95ef7468 Andreas Kohlbecker
    $annotations_and_sources = handle_annotations_and_sources($taxon_name,
614
      null, null, $annotations_and_sources);
615 2fd6da0b Andreas Kohlbecker
  }
616 95ef7468 Andreas Kohlbecker
  $out .= $annotations_and_sources->footNoteKeysMarkup();
617 2fd6da0b Andreas Kohlbecker
  return $out;
618
}
619
620 7212f0bc Andreas Kohlbecker
621
622
/**
623 26b8a1bc Andreas Kohlbecker
 * Composes information for a registration from a dto object.
624
 *
625
 * Registrations which are not yet published are suppressed.
626 7212f0bc Andreas Kohlbecker
 *
627
 * @param $registration_dto
628
 * @param $with_citation
629
 *   Whether to show the citation.
630
 *
631
 * @return array
632
 *    A drupal render array with the elements:
633 26b8a1bc Andreas Kohlbecker
 *    - 'name'
634
 *    - 'name-relations'
635
 *    - 'specimen_type_designations'
636
 *    - 'name_type_designations'
637 7212f0bc Andreas Kohlbecker
 *    - 'citation'
638 26b8a1bc Andreas Kohlbecker
 *    - 'registration_date_and_institute'
639 7212f0bc Andreas Kohlbecker
 * @ingroup compose
640
 */
641 26b8a1bc Andreas Kohlbecker
function compose_registration_dto_full($registration_dto, $with_citation = true)
642 7212f0bc Andreas Kohlbecker
{
643 54c10803 Andreas Kohlbecker
  $render_array = array(
644
    '#prefix' => '<div class="registration">',
645
    '#suffix' => '</div>'
646
  );
647 7212f0bc Andreas Kohlbecker
648 26b8a1bc Andreas Kohlbecker
  if(!(isset($registration_dto->identifier) && $registration_dto->status == 'PUBLISHED')){
649
    return $render_array;
650
  }
651
652 b7e96f18 Andreas Kohlbecker
  $render_array['sub_headline'] = markup_to_render_array(join(", ", registration_types($registration_dto)),-10, '<h3 class="registration_type">' . t('Event: '), '</h3>' );
653 c5abae79 Andreas Kohlbecker
  $render_array['nomenclatural_act'] = array(
654
    '#weight' => 0,
655
    '#prefix' => '<div class="nomenclatural_act">',
656 b7e96f18 Andreas Kohlbecker
657 c5abae79 Andreas Kohlbecker
    '#suffix' => '</div>'
658
  );
659 b90ef618 Andreas Kohlbecker
660 dc342fe0 Andreas Kohlbecker
  $typified_name = null;
661
662
  // Nomenclatural act block element
663
  $last_footnote_listkey = RenderHints::setFootnoteListKey("nomenclatural_act");
664 e69c4103 Andreas Kohlbecker
  // name
665 991ae630 Andreas Kohlbecker
  $name_relations = null;
666 a584de6a Andreas Kohlbecker
  if(isset($registration_dto->nameRef) && $registration_dto->nameRef){
667 26b8a1bc Andreas Kohlbecker
    $name = cdm_ws_get(CDM_WS_PORTAL_NAME, $registration_dto->nameRef->uuid);
668 a7560a18 Andreas Kohlbecker
    cdm_load_tagged_full_title($name);
669 c5abae79 Andreas Kohlbecker
    $render_array['nomenclatural_act']['published_name'] = markup_to_render_array('<div class="published-name">' . render_taxon_or_name($name, url(path_to_name($name->uuid))) . '</div>', 0);
670 26b8a1bc Andreas Kohlbecker
    $name_relations = cdm_ws_fetch_all(str_replace("$0", $registration_dto->nameRef->uuid, CDM_WS_PORTAL_NAME_NAME_RELATIONS));
671 991ae630 Andreas Kohlbecker
    // need to create the name relationships later, so that the foot notes are in correct order, see section // name relations
672 2dce3b2a Andreas Kohlbecker
  } else {
673
    // in this case the registration must have a
674 dc342fe0 Andreas Kohlbecker
    // typified name will be rendered later
675
    $typified_name = cdm_ws_get(CDM_WS_PORTAL_NAME, $registration_dto->typifiedNameRef->uuid);
676
677 26b8a1bc Andreas Kohlbecker
  }
678 991ae630 Andreas Kohlbecker
679 e69c4103 Andreas Kohlbecker
  // typedesignation in detail
680 a0ab64df Andreas Müller
  if(is_object($registration_dto->orderedTypeDesignationWorkingSets)) {
681 26b8a1bc Andreas Kohlbecker
    $field_unit_uuids = array();
682
    $specimen_type_designation_refs = array();
683
    $name_type_designation_refs = array();
684 a0ab64df Andreas Müller
    foreach ((array)$registration_dto->orderedTypeDesignationWorkingSets as $workingset_ref => $obj) {
685 67f5eac2 Andreas Kohlbecker
      $tokens = explode("#", $workingset_ref);
686
      $types_in_fieldunit = get_object_vars($obj); // convert into associative array
687
688 26b8a1bc Andreas Kohlbecker
      if ($tokens[0] == 'NameTypeDesignation') {
689 67f5eac2 Andreas Kohlbecker
        foreach ($types_in_fieldunit as $type_status => $entity_reference_list) {
690
          if(!isset($name_type_designation_refs[$type_status])){
691
            $name_type_designation_refs[$type_status]  = $entity_reference_list;
692
          } else {
693 90e36873 Andreas Kohlbecker
            $specimen_type_designation_refs[$type_status] = array_merge($specimen_type_designation_refs[$type_status], $entity_reference_list);
694 67f5eac2 Andreas Kohlbecker
          }
695 7212f0bc Andreas Kohlbecker
        }
696 26b8a1bc Andreas Kohlbecker
      } else if ($tokens[0] == 'FieldUnit'){
697
        $field_unit_uuids[] = $tokens[1];
698 67f5eac2 Andreas Kohlbecker
        foreach ($types_in_fieldunit as $type_status => $entity_reference_list) {
699
          if(!isset($specimen_type_designation_refs[$type_status])){
700
            $specimen_type_designation_refs[$type_status] =  $entity_reference_list;
701
          } else {
702
            array_push($specimen_type_designation_refs[$type_status], $entity_reference_list);
703
          }
704
        }
705 26b8a1bc Andreas Kohlbecker
      } else {
706
        drupal_set_message("Unimplemented type: " . $tokens[0], 'error');
707 7212f0bc Andreas Kohlbecker
      }
708
    }
709 991ae630 Andreas Kohlbecker
    // type designations which are in this nomenclatural act.
710 26b8a1bc Andreas Kohlbecker
    if (count($name_type_designation_refs) > 0) {
711 c5abae79 Andreas Kohlbecker
      $render_array['nomenclatural_act']['name_type_designations'] = compose_name_type_designations($name_type_designation_refs);
712
      $render_array['nomenclatural_act']['name_type_designations']['#prefix'] = '<p class="name_type_designations">';
713
      $render_array['nomenclatural_act']['name_type_designations']['#suffix'] = '</p>';
714
      $render_array['nomenclatural_act']['name_type_designations']['#weight'] = 20;
715 26b8a1bc Andreas Kohlbecker
    }
716
    if (count($field_unit_uuids) > 0) {
717 e69c4103 Andreas Kohlbecker
      $specimen_type_designations_array = compose_specimen_type_designations($specimen_type_designation_refs, true);
718 c5abae79 Andreas Kohlbecker
      $render_array['nomenclatural_act']['specimen_type_designations'] = $specimen_type_designations_array['type_designations'];
719 41a348be Andreas Kohlbecker
      $render_array['map'] = $specimen_type_designations_array['map'];
720 c5abae79 Andreas Kohlbecker
      $render_array['map']['#weight'] = $render_array['nomenclatural_act']['#weight'] + 20;
721 26b8a1bc Andreas Kohlbecker
    }
722 7212f0bc Andreas Kohlbecker
  }
723
724 991ae630 Andreas Kohlbecker
  // name relations
725
  if($name_relations){
726
    $render_array['nomenclatural_act']['name_relations'] = compose_name_relationships_list($name_relations, $registration_dto->nameRef->uuid, null);
727
    $render_array['nomenclatural_act']['name_relations']['#weight'] = 10;
728
  }
729
730 7212f0bc Andreas Kohlbecker
  // citation
731
  if ($with_citation) {
732
    $render_array['citation'] = markup_to_render_array(
733 c5abae79 Andreas Kohlbecker
      "<div class=\"citation nomenclatural_act_citation" . html_class_attribute_ref(new TypedEntityReference("Reference", $registration_dto->citationUuid)) . "\">"
734
      . "<span class=\"label\">published in: </span>"
735 2ffe4d59 Andreas Kohlbecker
      . $registration_dto->bibliographicInRefCitationString
736
      . l(custom_icon_font_markup('icon-interal-link-alt-solid', array('class' => array('superscript'))), path_to_reference($registration_dto->citationUuid), array('html' => true))
737 c5abae79 Andreas Kohlbecker
      . "</div>",
738
      $render_array['nomenclatural_act']['#weight'] + 10 );
739 7212f0bc Andreas Kohlbecker
  }
740
741 1c30a02b Andreas Kohlbecker
  $render_array['nomenclatural_act']['footnotes'] = markup_to_render_array(render_footnotes(),100);
742 0e617798 Andreas Kohlbecker
743 dc342fe0 Andreas Kohlbecker
  // END of nomenclatural act block
744
  RenderHints::setFootnoteListKey($last_footnote_listkey );
745
746
  if($typified_name){
747
    $render_array['typified_name'] = markup_to_render_array('<p class="typified-name">for ' . render_taxon_or_name($typified_name, url(path_to_name($typified_name->uuid))) . '</p>', 40);
748
  }
749
750 7212f0bc Andreas Kohlbecker
  // registration date and office
751 12466422 Andreas Kohlbecker
  $registration_date_insitute_markup = render_registration_date_and_institute($registration_dto);
752 26b8a1bc Andreas Kohlbecker
  if($registration_date_insitute_markup){
753
    $render_array['registration_date_and_institute'] = markup_to_render_array(
754
      $registration_date_insitute_markup . '</p>',
755
      100);
756
  }
757
758 dc342fe0 Andreas Kohlbecker
  $render_array['page_footnotes'] = markup_to_render_array(render_footnotes(), 110);
759 0e617798 Andreas Kohlbecker
760 26b8a1bc Andreas Kohlbecker
  return $render_array;
761
}
762
763
764
/**
765
 * Composes a compact representation for a registrationDTO object
766
 *
767
 * Registrations which are not yet published are suppressed.
768
 *
769
 * @param $registration_dto
770
 * @param $style string
771
 *   The style of how to compose the 'identifier' and 'registration_date_and_institute' part with the summary
772 06fba5d3 Andreas Kohlbecker
 *   - 'citation': Similar to the appearance of nomenclatural acts in print media
773 26b8a1bc Andreas Kohlbecker
 *   - 'list-item' : style suitable for result lists etc
774
 *
775
 * @return array
776
 *    A drupal render array with the elements:
777
 *    - 'registration-metadata' when $style == 'list-item'
778
 *    - 'summary'
779
 * @ingroup compose
780
 */
781
function compose_registration_dto_compact($registration_dto, $style = 'citation', $tag_enclosing_summary = 'p')
782
{
783
  $render_array = array();
784
  $media_link_map = array();
785
786
  if(!(isset($registration_dto->identifier) && $registration_dto->status == 'PUBLISHED')){
787
    return $render_array;
788
  }
789
790 b6e9b53a Andreas Kohlbecker
  $registration_date_institute_markup = render_registration_date_and_institute($registration_dto, 'span');
791
  $identifier_markup = render_link_to_registration($registration_dto->identifier);
792 26b8a1bc Andreas Kohlbecker
793 f461a488 Andreas Kohlbecker
  $tagged_text_options = array();
794
  if(isset($registration_dto->nameRef)){
795
    $tagged_text_options[] = array(
796
      'filter-type' => 'name',
797
      'prefix' => '<span class="registered_name">',
798
      'suffix' => '</span>',
799
    );
800
  } else {
801
    $tagged_text_options[] = array(
802
      'filter-type' => 'name',
803
      'prefix' => '<span class="referenced_typified_name">',
804
      'suffix' => '</span>',
805
    );
806
  }
807
  cdm_tagged_text_add_options($registration_dto->summaryTaggedText, $tagged_text_options);
808 0991781d Andreas Kohlbecker
  $tagged_text_cropped = tagged_text_crop_at($registration_dto->summaryTaggedText, 'reference', '/[dD]esignated\s+[bB]y/');
809 50f675e7 Andreas Kohlbecker
  $tagged_text_expanded = cdm_tagged_text_expand_entity_references($tagged_text_cropped);
810 947ee97b Andreas Kohlbecker
  foreach ($tagged_text_expanded  as $tagged_text){
811 26b8a1bc Andreas Kohlbecker
    if(isset($tagged_text->entityReference->type) && $tagged_text->entityReference->type == 'SpecimenTypeDesignation') {
812
      $mediaDTOs = cdm_ws_get('typedesignation/$0/media', array($tagged_text->entityReference->uuid));
813
      if(isset($mediaDTOs[0]->uri)){
814
        $media_url_key = '{link-' . $mediaDTOs[0]->uuid . '}';
815
        $tagged_text->text = str_replace('[icon]', '[icon]' . $media_url_key, $tagged_text->text);
816
        $media_link_map[$media_url_key] =  cdm_external_uri($mediaDTOs[0]->uri, true);
817
      }
818
    }
819
  }
820 947ee97b Andreas Kohlbecker
  $registation_markup = cdm_tagged_text_to_markup($tagged_text_expanded);
821 26b8a1bc Andreas Kohlbecker
  foreach($media_link_map as $media_url_key => $link){
822
    $registation_markup = str_replace($media_url_key, $link, $registation_markup);
823
  }
824
  if($style == 'citation') {
825 b6e9b53a Andreas Kohlbecker
    $registation_markup = $registation_markup . ' ' . $identifier_markup . ' ' . $registration_date_institute_markup;
826 26b8a1bc Andreas Kohlbecker
  } else {
827 b6e9b53a Andreas Kohlbecker
    $render_array['registration-metadata'] = markup_to_render_array('<div class="registration-metadata">' . $identifier_markup . ' ' . $registration_date_institute_markup. "</div>", -10);
828 26b8a1bc Andreas Kohlbecker
  }
829 f461a488 Andreas Kohlbecker
  $render_array['summary'] = markup_to_render_array('<' . $tag_enclosing_summary . ' class="registration-summary">' . $registation_markup . '</' . $tag_enclosing_summary . '>', 0);
830 26b8a1bc Andreas Kohlbecker
831
  return $render_array;
832
}
833
834
/**
835
 * Renders the registrationDate and institutionTitleCache of the $registration_dto as markup.
836
 *
837
 * @param $registration_dto
838
 * @return string
839
 *    The markup or an empty string
840
 */
841 12466422 Andreas Kohlbecker
function render_registration_date_and_institute($registration_dto, $enclosing_tag = 'p') {
842
  $registration_date_institute_markup = '';
843 26b8a1bc Andreas Kohlbecker
  if ($registration_dto->registrationDate) {
844 7212f0bc Andreas Kohlbecker
    $date_string = format_datetime($registration_dto->registrationDate);
845 26b8a1bc Andreas Kohlbecker
    if (isset($registration_dto->institutionTitleCache) && $registration_dto->institutionTitleCache) {
846 12466422 Andreas Kohlbecker
      $registration_date_institute_markup =
847 7212f0bc Andreas Kohlbecker
        t("Registration on @date in @institution", array(
848
          '@date' => $date_string,
849
          '@institution' => $registration_dto->institutionTitleCache,
850
        ));
851
    } else {
852 12466422 Andreas Kohlbecker
      $registration_date_institute_markup =
853 7212f0bc Andreas Kohlbecker
        t("Registration on @date", array(
854
          '@date' => $date_string
855
        ));
856
    }
857 12466422 Andreas Kohlbecker
    $registration_date_institute_markup = '<' .$enclosing_tag . ' class="registration-date-and-institute">'. $registration_date_institute_markup . '</' .$enclosing_tag . '>';
858 7212f0bc Andreas Kohlbecker
  }
859 12466422 Andreas Kohlbecker
  return $registration_date_institute_markup;
860 7212f0bc Andreas Kohlbecker
}
861
862
863 eaff53f7 Andreas Kohlbecker
/**
864
 * @param $registrations
865
 * @return string
866
 */
867
function render_registrations($registrations)
868
{
869
  $registration_markup = '';
870
  $registration_markup_array = array();
871
  if ($registrations) {
872
    foreach ($registrations as $reg) {
873
      $registration_markup_array[] = render_registration($reg);
874
    }
875
    $registration_markup = " Registration" . (count($registration_markup_array) > 1 ? 's: ' : ': ')
876
      . join(', ', $registration_markup_array);
877
  }
878
  return $registration_markup;
879
}
880
881 471192e3 Andreas Kohlbecker
882 7212f0bc Andreas Kohlbecker
/**
883
 * Renders a registration
884
 *
885 26b8a1bc Andreas Kohlbecker
 * TODO replace by compose_registration_dto_compact
886 7212f0bc Andreas Kohlbecker
 * @param $registration
887
 */
888
function render_registration($registration){
889
  $markup = '';
890
891
  if(isset($registration->identifier) && $registration->status == 'PUBLISHED'){
892
    $office_class_attribute = '';
893
    if(isset($registration->institution->titleCache)){
894 a584de6a Andreas Kohlbecker
      $office_class_attribute = registration_institution_class_attribute($registration);
895 7212f0bc Andreas Kohlbecker
    }
896 b6e9b53a Andreas Kohlbecker
    $markup = "<span class=\"registration $office_class_attribute\">" . render_link_to_registration($registration->identifier) . ', '
897 7212f0bc Andreas Kohlbecker
      .  preg_replace('/^([^T]*)(.*)$/', '${1}', $registration->registrationDate)
898
      . '</span>';
899
  }
900
  return $markup;
901
}
902
903 26b8a1bc Andreas Kohlbecker
/**
904
 * @param $registration
905
 * @return string
906
 */
907 a584de6a Andreas Kohlbecker
function registration_institution_class_attribute($registration_dto)
908 26b8a1bc Andreas Kohlbecker
{
909
  if(isset($registration_dto->institutionTitleCache)){
910
    $institutionTitleCache = $registration_dto->institutionTitleCache;
911
  } else {
912
    // fall back option to also support cdm entities
913
    $institutionTitleCache = @$registration_dto->institution->titleCache;
914
  }
915
  return $institutionTitleCache ? 'registration-' . strtolower(preg_replace('/[^a-zA-Z0-9]/', '-', $institutionTitleCache)) : '';
916
}
917
918 7212f0bc Andreas Kohlbecker
919 79904336 Andreas Kohlbecker
/**
920
 * Renders and array of CDM TypeDesignations
921
 *
922 0e617798 Andreas Kohlbecker
 *  - NameTypeDesignation
923
 *  - SpecimenTypeDesignation
924
 *  - TextualTypeDesignation
925
 *
926 846f21e1 Andreas Kohlbecker
 * @param array $type_designations an array of cdm TypeDesignation entities
927 79904336 Andreas Kohlbecker
 *  to render
928
 * @param string $enclosing_tag the tag element type to enclose the whole list
929
 *  of type designation with. By default this DOM element is <ul>
930
 * @param string $element_tag the tag element type to be used for each
931
 *  type designation item.
932
 * @param bool $link_to_specimen_page whether a specimen in type designation element
933
 *  should be a link or not.
934
 *
935
 * @return string The markup.
936
 *
937
 * @InGroup Render
938
 */
939
function render_type_designations($type_designations, $enclosing_tag = 'ul', $element_tag =  'li', $link_to_specimen_page = true) {
940
941
  // need to add element to render path since type designations
942
  // need other name render template
943
  RenderHints::pushToRenderStack('typedesignations');
944
945
  $out = '<' . $enclosing_tag .' class="typeDesignations">';
946
  $specimen_type_designations = array();
947
  $name_type_designations = array();
948
  $textual_type_designations = array();
949
  $separator = ',';
950
951
  foreach ($type_designations as $type_designation) {
952
    switch ($type_designation->class) {
953
      case 'SpecimenTypeDesignation':
954
        $specimen_type_designations[] = $type_designation;
955
        break;
956
      case 'NameTypeDesignation':
957
        $name_type_designations[] = $type_designation;
958
        break;
959
      case 'TextualTypeDesignation':
960
        $textual_type_designations[] = $type_designation;
961
        break;
962
      default:  throw new Exception('Unknown type designation class: ' . $type_designation->class);
963
    }
964
  }
965
966
  // NameTypeDesignation ..................................
967
  if(!empty($name_type_designations)){
968 04d5812b Andreas Kohlbecker
    usort($name_type_designations, "compare_type_designations_by_status");
969 79904336 Andreas Kohlbecker
    foreach($name_type_designations as $name_type_designation){
970
      if ($name_type_designation->notDesignated) {
971
        $out .= '<'. $element_tag .' class="' . html_class_attribute_ref($name_type_designation) . '">' .  type_designation_status_label_markup($name_type_designation)  . ': '
972
          . t('not designated') . '</'. $element_tag .'>';
973
      }
974
      elseif (isset($name_type_designation->typeName)) {
975
        $link_to_name_page = url(path_to_name($name_type_designation->typeName->uuid));
976
        $out .= '<'. $element_tag .' class="' . html_class_attribute_ref($name_type_designation) . '">' .  type_designation_status_label_markup($name_type_designation) ;
977
978 2f5cf318 Andreas Kohlbecker
        if (!empty($name_type_designation->designationSource->citation)) {
979 79904336 Andreas Kohlbecker
          $out .= type_designation_citation_layout($name_type_designation, $separator); // TODO type_designation_citation_layout() needs most probably to be replaced
980
981
        }
982
        $referenceUri = '';
983 6679207a Andreas Kohlbecker
        if (isset($name_type_designation->typeName->nomenclaturalSource->citation)) {
984
          $referenceUri = url(path_to_reference($name_type_designation->typeName->nomenclaturalSource->citation->uuid));
985 79904336 Andreas Kohlbecker
        }
986
        $out .= ': ' . render_taxon_or_name($name_type_designation->typeName, $link_to_name_page, $referenceUri, TRUE, TRUE);
987
      }
988 69303661 Andreas Kohlbecker
      RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
989
      $annotations_and_sources = handle_annotations_and_sources($name_type_designation);
990 95ef7468 Andreas Kohlbecker
      $out .= $annotations_and_sources->footNoteKeysMarkup();
991 79904336 Andreas Kohlbecker
    }
992
  } // END NameTypeDesignation
993
994
  // SpecimenTypeDesignation ...................................
995
  if (!empty($specimen_type_designations)) {
996
    usort($specimen_type_designations, "compare_specimen_type_designation");
997
    foreach ($specimen_type_designations as $specimen_type_designation) {
998
      $type_citation_markup = '';
999
1000 2f5cf318 Andreas Kohlbecker
      if (!empty($specimen_type_designation->designationSource->citation)) {
1001 79904336 Andreas Kohlbecker
1002 2f5cf318 Andreas Kohlbecker
        $citation_footnote_str = cdm_reference_markup($specimen_type_designation->designationSource->citation, null, false, true);
1003
        $author_team = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $specimen_type_designation->designationSource->citation->uuid);
1004 79904336 Andreas Kohlbecker
1005
        if (!empty($author_team->titleCache)) {
1006 2f5cf318 Andreas Kohlbecker
          $year = @timePeriodToString($specimen_type_designation->designationSource->citation->datePublished, true, 'YYYY');
1007 79904336 Andreas Kohlbecker
          $authorteam_str = $author_team->titleCache . ($year ? ' ' : '') . $year;
1008 2f5cf318 Andreas Kohlbecker
          if ($authorteam_str == $specimen_type_designation->designationSource->citation->titleCache) {
1009 79904336 Andreas Kohlbecker
            $citation_footnote_str = '';
1010
          }
1011
        } else {
1012
          $authorteam_str = $citation_footnote_str;
1013
          // no need for a footnote in case in case it is used as replacement for missing author teams
1014
          $citation_footnote_str = '';
1015
        }
1016
1017
        // for being registered a typedesignation MUST HAVE a citation, so it is save to handle the
1018
        // Registration output in if condition checking if the citation is present
1019
        $registration_markup = render_registrations($specimen_type_designation->registrations);
1020
        $citation_footnote_str .= ($citation_footnote_str ? ' ' : '') . $registration_markup;
1021
1022
        $footnote_key_markup = '';
1023
        if ($citation_footnote_str) {
1024
          // footnotes should be rendered in the parent element so we
1025
          // are relying on the FootnoteListKey set there
1026
          $_fkey2 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), $citation_footnote_str);
1027 d8069342 Andreas Kohlbecker
          $footnote_key_markup = render_footnote_key($_fkey2, $separator, TRUE);
1028 79904336 Andreas Kohlbecker
        }
1029
1030
        $type_citation_markup .= '&nbsp;(' . t('designated by') . '&nbsp;<span class="typeReference">' . $authorteam_str . '</span>';
1031 2f5cf318 Andreas Kohlbecker
        if (!empty($specimen_type_designation->designationSource->citationMicroReference)) {
1032
          $type_citation_markup .= ': ' . trim($specimen_type_designation->designationSource->citationMicroReference);
1033 79904336 Andreas Kohlbecker
        }
1034
        $type_citation_markup .= $footnote_key_markup . ')';
1035
      }
1036
1037
      $out .= '<'. $element_tag .' class="' . html_class_attribute_ref($specimen_type_designation) . '">';
1038
      $out .= type_designation_status_label_markup($specimen_type_designation) . $type_citation_markup;
1039
1040
1041
      $derivedUnitFacadeInstance = null;
1042
      if (isset($specimen_type_designation->typeSpecimen)) {
1043
        $derivedUnitFacadeInstance = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, $specimen_type_designation->typeSpecimen->uuid);
1044
      }
1045
1046
      if (!empty($derivedUnitFacadeInstance->titleCache)) {
1047
        $specimen_markup = $derivedUnitFacadeInstance->titleCache;
1048
        if($link_to_specimen_page && isset($derivedUnitFacadeInstance->specimenLabel) && $derivedUnitFacadeInstance->specimenLabel){
1049
          $specimen_markup = str_replace($derivedUnitFacadeInstance->specimenLabel, l($derivedUnitFacadeInstance->specimenLabel, path_to_specimen($specimen_type_designation->typeSpecimen->uuid)), $specimen_markup);
1050
        }
1051 69303661 Andreas Kohlbecker
        RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
1052
        $annotations_and_sources = handle_annotations_and_sources($derivedUnitFacadeInstance);
1053 79904336 Andreas Kohlbecker
        $out .= ': <span class="' . html_class_attribute_ref($specimen_type_designation->typeSpecimen) . '">'
1054
          . $specimen_markup
1055
          . '</span>'; // . ': ' . theme('cdm_specimen', array('specimenTypeDesignation' => $derivedUnitFacadeInstance));
1056
        if(!empty($derivedUnitFacadeInstance->preferredStableUri)){
1057
          $out .= ' ' . l($derivedUnitFacadeInstance->preferredStableUri, $derivedUnitFacadeInstance->preferredStableUri, array('absolute' => true));
1058
        }
1059 95ef7468 Andreas Kohlbecker
        $out .= $annotations_and_sources->footNoteKeysMarkup();
1060 79904336 Andreas Kohlbecker
      }
1061
      $out .= '</'. $element_tag .'>';
1062
    }
1063
  } // END Specimen type designations
1064
1065
  // TextualTypeDesignation .........................
1066 04d5812b Andreas Kohlbecker
  usort($textual_type_designations, 'compare_textual_type_designation');
1067 79904336 Andreas Kohlbecker
  if(!empty($textual_type_designations)) {
1068 69303661 Andreas Kohlbecker
      RenderHints::setAnnotationsAndSourceConfig([
1069 f34df40f Andreas Kohlbecker
          // these settings differ from those provided by annotations_and_sources_config_typedesignations()
1070 3c4a5472 Andreas Kohlbecker
          // TODO is this by purpose? please document the reason for the difference
1071 79904336 Andreas Kohlbecker
          'sources_as_content' => false, // as footnotes
1072
          'link_to_name_used_in_source' => false,
1073
          'link_to_reference' => true,
1074 a6c4c53c Andreas Kohlbecker
          'add_footnote_keys' => true,
1075
          'bibliography_aware' => false
1076 69303661 Andreas Kohlbecker
        ]
1077 79904336 Andreas Kohlbecker
      );
1078 69303661 Andreas Kohlbecker
    foreach ($textual_type_designations as $textual_type_designation) {
1079
      $annotations_and_sources = handle_annotations_and_sources($textual_type_designation);
1080 a6c4c53c Andreas Kohlbecker
      $encasement =  $textual_type_designation->verbatim ? '"' : '';
1081
      $out .= '<' . $element_tag . ' class="' . html_class_attribute_ref($textual_type_designation) . '">' . type_designation_status_label_markup(null)
1082 95ef7468 Andreas Kohlbecker
        . ': ' .  $encasement . trim($textual_type_designation->text_L10n->text) . $encasement .  $annotations_and_sources->footNoteKeysMarkup() .'</' . $element_tag . '>';
1083
//      if($annotations_and_sources->hasSourceReferences())){
1084
//        $citation_markup = join(', ', getSourceReferences());
1085 a6c4c53c Andreas Kohlbecker
//      }
1086
//      $out .= $citation_markup;
1087 79904336 Andreas Kohlbecker
    }
1088
  }
1089
1090 991ae630 Andreas Kohlbecker
  // Footnotes for citations, collection acronyms.
1091 79904336 Andreas Kohlbecker
  // footnotes should be rendered in the parent element so we
1092
  // are relying on the FootnoteListKey set there
1093
  $_fkey = FootnoteManager::addNewFootnote(
1094
    RenderHints::getFootnoteListKey(),
1095
    (isset($derivedUnitFacadeInstance->collection->titleCache) ? $derivedUnitFacadeInstance->collection->titleCache : FALSE)
1096
  );
1097 d8069342 Andreas Kohlbecker
  $out .= render_footnote_key($_fkey, $separator);
1098 79904336 Andreas Kohlbecker
  $out .= '</' . $enclosing_tag .'>';
1099
1100
  RenderHints::popFromRenderStack();
1101
1102
  return $out;
1103
}
1104
1105 a584de6a Andreas Kohlbecker
/**
1106
 * Creates markup for a list of SpecimenTypedesignationDTO
1107
 *
1108
 * @param array $specimen_typedesignation_dtos
1109
 *  The SpecimenTypedesignationDTOs to be rendered
1110
 *
1111 56a041f8 Andreas Kohlbecker
 * @param bool $show_type_specimen
1112
 *
1113
 * @param string $enclosing_tag
1114
 * @param string $element_tag
1115
 *
1116 a584de6a Andreas Kohlbecker
 * @return string
1117
 *   The markup.
1118
 */
1119 56a041f8 Andreas Kohlbecker
function render_specimen_typedesignation_dto($specimen_typedesignation_dtos, $show_type_specimen = FALSE, $enclosing_tag = 'ul', $element_tag = 'li'){
1120 a584de6a Andreas Kohlbecker
1121
  // need to add element to render path since type designations
1122
  // need other name render template
1123
  RenderHints::pushToRenderStack('typedesignations');
1124
1125
  $out = '<' . $enclosing_tag .' class="typeDesignations">';
1126
  $separator = ',';
1127
1128
  if (!empty($specimen_typedesignation_dtos)) {
1129
    // usort($specimen_type_designations, "compare_specimen_type_designation"); // FIXME create compare function for SpecimenTypedesignationDTO
1130
    foreach ($specimen_typedesignation_dtos as $std_dto) {
1131
      $type_citation_markup = '';
1132
1133 2f5cf318 Andreas Kohlbecker
      if (!empty($std_dto->designationSource->citation)) {
1134 a584de6a Andreas Kohlbecker
1135 2f5cf318 Andreas Kohlbecker
        $citation_footnote_str = cdm_reference_markup($std_dto->designationSource->citation, null, false, true);
1136
        $author_team = cdm_ws_get(CDM_WS_REFERENCE_AUTHORTEAM, $std_dto->designationSource->citation->uuid);
1137 a584de6a Andreas Kohlbecker
1138
        if (!empty($author_team->titleCache)) {
1139 2f5cf318 Andreas Kohlbecker
          $year = @timePeriodToString($std_dto->designationSource->citation->datePublished, true, 'YYYY');
1140 a584de6a Andreas Kohlbecker
          $authorteam_str = $author_team->titleCache . ($year ? ' ' : '') . $year;
1141 2f5cf318 Andreas Kohlbecker
          if ($authorteam_str == $std_dto->designationSource->citation->titleCache) {
1142 a584de6a Andreas Kohlbecker
            $citation_footnote_str = '';
1143
          }
1144
        } else {
1145
          $authorteam_str = $citation_footnote_str;
1146
          // no need for a footnote in case in case it is used as replacement for missing author teams
1147
          $citation_footnote_str = '';
1148
        }
1149
1150
        // for being registered a typedesignation MUST HAVE a citation, so it is save to handle the
1151
        // Registration output in the conditional block which has been checked that the citation is present
1152
        $registration_markup = render_registrations($std_dto->registrations);
1153
        $citation_footnote_str .= ($citation_footnote_str ? ' ' : '') . $registration_markup;
1154
1155
        $footnote_key_markup = '';
1156
        if ($citation_footnote_str) {
1157
          // footnotes should be rendered in the parent element so we
1158
          // are relying on the FootnoteListKey set there
1159
          $_fkey2 = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), $citation_footnote_str);
1160
          $footnote_key_markup = render_footnote_key($_fkey2, $separator, TRUE);
1161
        }
1162
1163
        $type_citation_markup .= '&nbsp;(' . t('designated by') . '&nbsp;<span class="typeReference">' . $authorteam_str . '</span>';
1164 2f5cf318 Andreas Kohlbecker
        if (!empty($std_dto->designationSource->citationMicroReference)) {
1165
          $type_citation_markup .= ': ' . trim($std_dto->designationSource->citationMicroReference);
1166 a584de6a Andreas Kohlbecker
        }
1167
        $type_citation_markup .= $footnote_key_markup . ')';
1168
      }
1169
1170
      $out .= '<'. $element_tag .' class="' . html_class_attribute_ref($std_dto) . '">';
1171
      $out .= type_designation_dto_status_label_markup($std_dto) . $type_citation_markup;
1172
1173 56a041f8 Andreas Kohlbecker
      if($show_type_specimen){
1174
        $derivedUnitFacadeInstance = null;
1175
        if (isset($std_dto->typeSpecimen)) {
1176
          $derivedUnitFacadeInstance = cdm_ws_get(CDM_WS_DERIVEDUNIT_FACADE, $std_dto->typeSpecimen->uuid);
1177 a584de6a Andreas Kohlbecker
        }
1178 56a041f8 Andreas Kohlbecker
1179
        if (!empty($derivedUnitFacadeInstance->titleCache)) {
1180
          $specimen_markup = $derivedUnitFacadeInstance->titleCache;
1181
          if(isset($derivedUnitFacadeInstance->specimenLabel) && $derivedUnitFacadeInstance->specimenLabel){
1182
            $specimen_markup = str_replace($derivedUnitFacadeInstance->specimenLabel, l($derivedUnitFacadeInstance->specimenLabel, path_to_specimen($std_dto->typeSpecimen->uuid)), $specimen_markup);
1183
          }
1184
          RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
1185
          $annotations_and_sources = handle_annotations_and_sources($derivedUnitFacadeInstance);
1186
          $out .= ': <span class="' . html_class_attribute_ref($std_dto->typeSpecimen) . '">'
1187
            . $specimen_markup
1188
            . '</span>'; // . ': ' . theme('cdm_specimen', array('specimenTypeDesignation' => $derivedUnitFacadeInstance));
1189
          if(!empty($derivedUnitFacadeInstance->preferredStableUri)){
1190
            $out .= ' ' . l($derivedUnitFacadeInstance->preferredStableUri, $derivedUnitFacadeInstance->preferredStableUri, array('absolute' => true));
1191
          }
1192
          $out .= $annotations_and_sources->footNoteKeysMarkup();
1193 a584de6a Andreas Kohlbecker
        }
1194
      }
1195 56a041f8 Andreas Kohlbecker
1196 a584de6a Andreas Kohlbecker
      $out .= '</'. $element_tag .'>';
1197
    }
1198 d5b2e2e8 Andreas Kohlbecker
    RenderHints::popFromRenderStack();
1199 a584de6a Andreas Kohlbecker
  }
1200
  return $out;
1201
}
1202
1203 79904336 Andreas Kohlbecker
1204 a9a04561 Andreas Kohlbecker
/**
1205
 * Composes the textual representation for the type designation of taxon name identified by the uuid in with a map for the location data.
1206 41a348be Andreas Kohlbecker
 *
1207 a9a04561 Andreas Kohlbecker
 * @param $taxon_name_uuid
1208 10858926 Andreas Kohlbecker
 * @param $show_specimen_details
1209 a9a04561 Andreas Kohlbecker
 * @return array
1210 ae177dac Andreas Kohlbecker
 *    A drupal render array with the following elements:
1211 a9a04561 Andreas Kohlbecker
 *    - 'type_designations'
1212
 *    - 'map'
1213 ae177dac Andreas Kohlbecker
 *    - 'specimens'
1214 a9a04561 Andreas Kohlbecker
 *
1215
 * @ingroup compose
1216
 */
1217 10858926 Andreas Kohlbecker
function compose_type_designations($taxon_name_uuid, $show_specimen_details = false)
1218 a9a04561 Andreas Kohlbecker
{
1219 41a348be Andreas Kohlbecker
  $render_array = array(
1220
    'type_designations' => array(),
1221
    'map' => array(),
1222
    );
1223 a9a04561 Andreas Kohlbecker
  $type_designations = cdm_ws_get(CDM_WS_PORTAL_NAME_TYPEDESIGNATIONS, $taxon_name_uuid);
1224
  if ($type_designations) {
1225 fb939fdc Andreas Kohlbecker
    usort($type_designations, 'compare_specimen_type_designation');
1226 a9a04561 Andreas Kohlbecker
    $render_array['type_designations'] = markup_to_render_array(
1227 0c720425 Andreas Kohlbecker
      render_type_designations($type_designations, 'div', 'div')
1228 a9a04561 Andreas Kohlbecker
    );
1229
1230
    $render_array['map'] = compose_type_designations_map($type_designations);
1231
  }
1232
  return $render_array;
1233
}
1234
1235
1236 471192e3 Andreas Kohlbecker
/**
1237
 * Composes the TypedEntityReference to name type designations passed as associatve array.
1238
 *
1239 991ae630 Andreas Kohlbecker
 * @param $type_entity_refs_by_status array
1240 471192e3 Andreas Kohlbecker
 *   an associative array of name type type => TypedEntityReference for name type designations as
1241
 *   produced by the eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager
1242
 *
1243
 * @ingroup compose
1244
 */
1245 991ae630 Andreas Kohlbecker
function compose_name_type_designations($type_entity_refs_by_status){
1246 471192e3 Andreas Kohlbecker
  $render_array = array();
1247 e1e2d593 Andreas Kohlbecker
  $preferredStableUri = '';
1248 991ae630 Andreas Kohlbecker
  foreach($type_entity_refs_by_status as $type_status => $name_type_entityRefs){
1249
    foreach ($name_type_entityRefs as $name_type_entity_ref){
1250
      $type_designation = cdm_ws_get(CDM_WS_TYPEDESIGNATION, array($name_type_entity_ref->uuid, 'preferredUri'));
1251
      $footnote_keys = '';
1252
1253 f5396e17 Andreas Kohlbecker
      if(isset($type_designation->typeSpecimen->preferredStableUri) && $type_designation->typeSpecimen->preferredStableUri){
1254
        $preferredStableUri = $type_designation->typeSpecimen->preferredStableUri;
1255
      }
1256 991ae630 Andreas Kohlbecker
      // annotations and sources for the $derived_unit_facade_dto
1257 69303661 Andreas Kohlbecker
      RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
1258
      $annotations_and_sources = handle_annotations_and_sources($name_type_entity_ref);
1259 991ae630 Andreas Kohlbecker
1260 95ef7468 Andreas Kohlbecker
      $render_array[] = markup_to_render_array('<div class="name_type_designation ' . html_class_attribute_ref($name_type_entity_ref)  .
1261
        '"><span class="type-status">'. ucfirst($type_status) . "</span>: "
1262 86b95854 Andreas Kohlbecker
        . cdm_tagged_text_to_markup($name_type_entity_ref->taggedText)
1263 f5396e17 Andreas Kohlbecker
        . ($preferredStableUri ? " ". l($preferredStableUri,  $preferredStableUri) : '')
1264 95ef7468 Andreas Kohlbecker
        . $annotations_and_sources->footNoteKeysMarkup()
1265 f5396e17 Andreas Kohlbecker
        . '</div>');
1266
      }
1267 f5e7f68e Andreas Kohlbecker
  }
1268
  return $render_array;
1269
}
1270
1271
/**
1272 41a348be Andreas Kohlbecker
 * Composes the specimen type designations with map from the the $type_entity_refs
1273 f5e7f68e Andreas Kohlbecker
 *
1274
 * @param $type_entity_refs array
1275
 *   an associative array of specimen type type => TypedEntityReference for specimen type designations as
1276
 *   produced by the eu.etaxonomy.cdm.api.service.name.TypeDesignationSetManager
1277
 *
1278 e69c4103 Andreas Kohlbecker
 * @param $show_media_specimen
1279 41a348be Andreas Kohlbecker
 * @return array
1280 6abd581c Andreas Kohlbecker
 *    A drupal render array with the following elements:
1281 41a348be Andreas Kohlbecker
 *    - 'type_designations'
1282
 *    - 'map'
1283
 *
1284
 * @ingroup compose
1285
 *
1286 f5e7f68e Andreas Kohlbecker
 */
1287 e69c4103 Andreas Kohlbecker
function compose_specimen_type_designations($type_entity_refs, $show_media_specimen){
1288 204e8173 Andreas Kohlbecker
1289 f5e7f68e Andreas Kohlbecker
  $render_array = array();
1290 204e8173 Andreas Kohlbecker
1291 41a348be Andreas Kohlbecker
  $type_designation_list = array();
1292 d8de8d4d Andreas Kohlbecker
  uksort($type_entity_refs, "compare_type_designation_status_labels");
1293 0e617798 Andreas Kohlbecker
  foreach($type_entity_refs as $type_status => $type_designation_entity_refs){
1294
    foreach($type_designation_entity_refs as $type_designation_entity_ref){
1295 204e8173 Andreas Kohlbecker
1296 0e617798 Andreas Kohlbecker
      $type_designation = cdm_ws_get(CDM_WS_PORTAL_TYPEDESIGNATION, array($type_designation_entity_ref->uuid));
1297 e69c4103 Andreas Kohlbecker
      $type_designation_list[] = $type_designation; // collect for the map
1298
1299 0e617798 Andreas Kohlbecker
      $derived_unit_facade_dto = cdm_ws_get(CDM_WS_PORTAL_DERIVEDUNIT_FACADE, $type_designation->typeSpecimen->uuid);
1300 b8a0efb3 Andreas Kohlbecker
      // the media specimen is not contained in the $type_designation returned by CDM_PORTAL_TYPEDESIGNATION, so we need to fetch it separately
1301
      $mediaSpecimen = cdm_ws_get(CDM_WS_PORTAL_OCCURRENCE, array($type_designation->typeSpecimen->uuid, 'mediaSpecimen'));
1302
1303 204e8173 Andreas Kohlbecker
1304 67f5eac2 Andreas Kohlbecker
      $preferredStableUri = '';
1305
      $citation_markup = '';
1306
      $media = '';
1307 204e8173 Andreas Kohlbecker
1308 0e617798 Andreas Kohlbecker
      // annotations and sources for the $derived_unit_facade_dto
1309 69303661 Andreas Kohlbecker
      RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
1310
      $annotations_and_sources = handle_annotations_and_sources($derived_unit_facade_dto);
1311 95ef7468 Andreas Kohlbecker
      $source_citations = $annotations_and_sources->getSourceReferences();
1312
      $foot_note_keys = $annotations_and_sources->footNoteKeysMarkup();
1313 0e617798 Andreas Kohlbecker
1314 67f5eac2 Andreas Kohlbecker
      // preferredStableUri
1315
      if(isset($type_designation->typeSpecimen->preferredStableUri) && $type_designation->typeSpecimen->preferredStableUri){
1316
        $preferredStableUri = $type_designation->typeSpecimen->preferredStableUri;
1317 204e8173 Andreas Kohlbecker
      }
1318 67f5eac2 Andreas Kohlbecker
1319 e69c4103 Andreas Kohlbecker
      if($show_media_specimen && $mediaSpecimen){
1320 67f5eac2 Andreas Kohlbecker
        // compose output
1321
        // mediaURI
1322
        if(isset($mediaSpecimen->representations[0])) {
1323
          $gallery_settings = getGallerySettings(CDM_DATAPORTAL_SPECIMEN_GALLERY_NAME);
1324
          $captionElements = array(
1325
            '#uri' => t('open media'),
1326
            'elements' => array('-none-'),
1327
            'sources_as_content' => true
1328
          );
1329 9f07f8ae Andreas Kohlbecker
          $media = compose_cdm_media_gallery(array(
1330 67f5eac2 Andreas Kohlbecker
            'mediaList' => array($mediaSpecimen),
1331 0e617798 Andreas Kohlbecker
            'galleryName' => CDM_DATAPORTAL_TYPE_SPECIMEN_GALLERY_NAME . '_' . $type_designation_entity_ref->uuid,
1332 67f5eac2 Andreas Kohlbecker
            'maxExtend' => $gallery_settings['cdm_dataportal_media_maxextend'],
1333
            'cols' => $gallery_settings['cdm_dataportal_media_cols'],
1334
            'captionElements' => $captionElements,
1335
          ));
1336
        }
1337 0e617798 Andreas Kohlbecker
        // citation and detail for the media specimen
1338 69303661 Andreas Kohlbecker
        RenderHints::setAnnotationsAndSourceConfig(annotations_and_sources_config_typedesignations());
1339
        $annotations_and_sources = handle_annotations_and_sources($mediaSpecimen);
1340 95ef7468 Andreas Kohlbecker
        if($annotations_and_sources->hasSourceReferences()){
1341
          $source_citations = array_merge($source_citations, $annotations_and_sources->getSourceReferences());
1342 0e617798 Andreas Kohlbecker
        }
1343 95ef7468 Andreas Kohlbecker
        if($annotations_and_sources->hasFootnoteKeys()){
1344
          $foot_note_keys .= ', ' . $annotations_and_sources->footNoteKeysMarkup();
1345 67f5eac2 Andreas Kohlbecker
        }
1346 204e8173 Andreas Kohlbecker
      }
1347
1348 0e617798 Andreas Kohlbecker
      $citation_markup = join(', ', $source_citations);
1349
1350
      $specimen_markup = $derived_unit_facade_dto->titleCache;
1351
      if(isset($derived_unit_facade_dto->specimenLabel) && $derived_unit_facade_dto->specimenLabel){
1352
        $specimen_markup = str_replace(
1353
          $derived_unit_facade_dto->specimenLabel,
1354
          l($derived_unit_facade_dto->specimenLabel, path_to_specimen($type_designation->typeSpecimen->uuid)), $specimen_markup);
1355 e69c4103 Andreas Kohlbecker
      }
1356
1357 0e617798 Andreas Kohlbecker
      $type_designation_render_array = markup_to_render_array(
1358
        '<div class="type_designation_entity_ref ' . html_class_attribute_ref($type_designation_entity_ref)  . '">
1359 2154d631 Andreas Kohlbecker
          <span class="type-status">' . ucfirst($type_status) . "</span>: "
1360 0e617798 Andreas Kohlbecker
        . $specimen_markup . $foot_note_keys
1361 67f5eac2 Andreas Kohlbecker
        . ($citation_markup ? ' '. $citation_markup : '')
1362
        . ($preferredStableUri ? " ". l($preferredStableUri,  $preferredStableUri) : '')
1363
        . $media
1364
        . '</div>');
1365 e69c4103 Andreas Kohlbecker
1366
      $render_array['type_designations'][] = $type_designation_render_array;
1367 67f5eac2 Andreas Kohlbecker
    }
1368 471192e3 Andreas Kohlbecker
  }
1369 41a348be Andreas Kohlbecker
  if(count($type_designation_list) > 0 ){
1370
    $render_array['map'] = compose_type_designations_map($type_designation_list);
1371
  } else {
1372
    $render_array['map'] = array();
1373
  }
1374 471192e3 Andreas Kohlbecker
  return $render_array;
1375
}
1376
1377 d86468e9 Andreas Kohlbecker
/**
1378 95ef7468 Andreas Kohlbecker
 * Creates the markup for the given name relationship.
1379 d86468e9 Andreas Kohlbecker
 *
1380 95ef7468 Andreas Kohlbecker
 * For the footnotes see handle_annotations_and_sources().
1381
 *
1382
 * @param $other_name
1383
 *      The other name from the NameRelationship see get_other_name()
1384 ef686dd8 Andreas Kohlbecker
 * @param $current_taxon_uuid
1385
 * @param $show_name_cache_only
1386
 *    The nameCache will be shown instead of the titleCache if this parameter is true.
1387
 * @return null|string
1388 26f042e4 Andreas Kohlbecker
 *    The markup or null
1389 95ef7468 Andreas Kohlbecker
 *
1390
 * @see \get_other_name
1391 ef686dd8 Andreas Kohlbecker
 */
1392 95ef7468 Andreas Kohlbecker
function name_relationship_markup($current_name_uuid, $name_rel, $current_taxon_uuid, $show_name_cache_only = false){
1393 ef686dd8 Andreas Kohlbecker
1394
  $relationship_markup = null;
1395
1396 95ef7468 Andreas Kohlbecker
  $other_name = get_other_name($current_name_uuid, $name_rel);
1397 ef686dd8 Andreas Kohlbecker
1398 95ef7468 Andreas Kohlbecker
  cdm_load_tagged_full_title($other_name);
1399 a7560a18 Andreas Kohlbecker
1400 95ef7468 Andreas Kohlbecker
  $highlited_synonym_uuid = isset ($other_name->taxonBases[0]->uuid) ? $other_name->taxonBases[0]->uuid : '';
1401
  if($show_name_cache_only){
1402 ef686dd8 Andreas Kohlbecker
    $relationship_markup = l(
1403 95ef7468 Andreas Kohlbecker
      '<span class="' . html_class_attribute_ref($other_name) . '"">' . $other_name->nameCache . '</span>',
1404
      path_to_name($other_name->uuid, $current_taxon_uuid, $highlited_synonym_uuid, false),
1405 ef686dd8 Andreas Kohlbecker
      array('html' => true)
1406
    );
1407 95ef7468 Andreas Kohlbecker
    $annotations_and_sources = handle_annotations_and_sources($other_name);
1408
    $relationship_markup .= $annotations_and_sources->footNoteKeysMarkup();
1409
  } else {
1410
    $relationship_markup = render_taxon_or_name($other_name,
1411
      url(path_to_name($other_name->uuid, $current_taxon_uuid, $highlited_synonym_uuid, false))
1412
    );
1413 ef686dd8 Andreas Kohlbecker
  }
1414
1415
  return $relationship_markup;
1416
}
1417
1418 95ef7468 Andreas Kohlbecker
/**
1419
 * Determined the other name which is contained in the NameRelationship entity.
1420
 *
1421
 * @param $current_name_uuid
1422
 *   The uuid of this name.
1423
 * @param $name_rel
1424
 *   The cdm NameRelationship entity
1425
 *
1426
 * @return object
1427
 *   The other cdm Name entity.
1428
 */
1429
function get_other_name($current_name_uuid, $name_rel) {
1430
  $current_name_is_toName = $current_name_uuid == $name_rel->toName->uuid;
1431
1432
  if ($current_name_is_toName) {
1433
    $name = $name_rel->fromName;
1434
  }
1435
  else {
1436
    $name = $name_rel->toName;
1437
  }
1438
  return $name;
1439
}
1440
1441 ef686dd8 Andreas Kohlbecker
1442
/**
1443 96614dfe Andreas Kohlbecker
 * Composes an inline representation of selected name relationships
1444 16592d77 Andreas Kohlbecker
 *
1445 23a017dd Andreas Kohlbecker
 * The output of this function will be usually appended to taxon name representations.
1446 ef686dd8 Andreas Kohlbecker
 * Only the following types are displayed: LATER_HOMONYM, TREATED_AS_LATER_HOMONYM, BLOCKING_NAME_FOR, ORTHOGRAPHIC_VARIANT
1447
 *
1448
 * LATER_HOMONYM, TREATED_AS_LATER_HOMONYM, BLOCKING_NAME_FOR are displayed as
1449
 * non {titleCache} nec {titleCache} nec {titleCache} whereas the related names
1450
 * are ordered alphabetically.
1451
 *
1452
 * ORTHOGRAPHIC_VARIANT is displayed as 'ort. var. {nameCache}'
1453 23a017dd Andreas Kohlbecker
 *
1454
 * Related issues:
1455
 *   - https://dev.e-taxonomy.eu/redmine/issues/5697 "Show name conserved against as [non xxx]"
1456
 *   - https://dev.e-taxonomy.eu/redmine/issues/6678 "How to correctly show name relationship "orth. var." in dataportal"
1457
 *   - https://dev.e-taxonomy.eu/redmine/issues/5857
1458 ef686dd8 Andreas Kohlbecker
 *   - https://dev.e-taxonomy.eu/redmine/issues/2001 "[Cichorieae Portal] Name Relationship -> blocking name are not shown"
1459 0b7bbf68 Andreas Kohlbecker
 *
1460 d4ea0dd9 Andreas Kohlbecker
 * @param $name_relations
1461
 *    The list of CDM NameRelationsips
1462
 * @param $current_name_uuid
1463 3c088da3 Andreas Kohlbecker
 *    The Uuid of the name for which the relations are to be rendered, the current name will be hidden when
1464
 *    rendering the relation an only the other name is shown. Parameter is REQUIRED.
1465
 * @param $suppress_if_current_name_is_source
1466
 *    The display of the relation will be
1467
 *    suppressed is the current name is on the source of the relation edge.
1468
 *    That is if it is on the from side of the relation. Except for 'blocking name for' which is
1469
 *    an inverse relation. For this relation type the toName is taken in to account.
1470 d4ea0dd9 Andreas Kohlbecker
 * @param $current_taxon_uuid
1471
 *    The taxon to be omitted from related taxa. This is only used to create links, see path_to_name()
1472 96614dfe Andreas Kohlbecker
 * @return array
1473
 *    A drupal render array
1474
 *
1475
 * @ingroup Compose
1476 0b7bbf68 Andreas Kohlbecker
 */
1477 96614dfe Andreas Kohlbecker
function compose_name_relationships_inline($name_relations, $current_name_uuid, $current_taxon_uuid, $suppress_if_current_name_is_source = true) {
1478 f695daf4 Andreas Kohlbecker
1479 0b7bbf68 Andreas Kohlbecker
  RenderHints::pushToRenderStack('homonym');
1480 35abbad4 Andreas Kohlbecker
  // the render stack element homonyms is being used in the default render templates !!!, see NameRenderConfiguration::CDM_NAME_RENDER_TEMPLATES_DEFAULT
1481 0b7bbf68 Andreas Kohlbecker
1482 ef686dd8 Andreas Kohlbecker
  $selected_name_rel_uuids = variable_get(CDM_NAME_RELATIONSHIP_INLINE_TYPES, unserialize(CDM_NAME_RELATIONSHIP_INLINE_TYPES_DEFAULT));
1483 7efd13a9 Andreas Kohlbecker
  $name_rel_type_filter = array('direct' => array(), 'inverse' => array());
1484
  foreach ($selected_name_rel_uuids as $uuid){
1485
    $name_rel_type_filter['direct'][$uuid] = $uuid;
1486
    if($uuid != UUID_NAMERELATIONSHIPTYPE_MISSPELLING){
1487
      $name_rel_type_filter['inverse'][$uuid] = $uuid;
1488
    }
1489
  }
1490 6421984d Andreas Kohlbecker
1491 1636cc86 Andreas Kohlbecker
  $list_prefix = '<span class="name_relationships">[';
1492
  $list_suffix = ']</span>';
1493 96614dfe Andreas Kohlbecker
  $item_prefix = '<span class="item">';
1494
  $item_suffix = '</span> ';
1495 f8d5d6d9 Andreas Kohlbecker
  $render_array = compose_name_relationships($name_relations, $name_rel_type_filter, $current_name_uuid, $current_taxon_uuid, $list_prefix, $list_suffix, $item_prefix, $item_suffix);
1496 7efd13a9 Andreas Kohlbecker
1497
  // remove the glue space from the last item element which has been added by the $item_suffix = '</span> '
1498
  $items_ctn = count($render_array['list']['items']);
1499
  if($items_ctn){
1500
    $render_array['list']['items'][$items_ctn - 1]['#suffix'] = '</span>';
1501
  }
1502 0b7bbf68 Andreas Kohlbecker
1503
  RenderHints::popFromRenderStack();
1504 96614dfe Andreas Kohlbecker
  return $render_array;
1505 d4ea0dd9 Andreas Kohlbecker
}
1506
1507 ef686dd8 Andreas Kohlbecker
/**
1508
 * Composes an list representation of the name relationships.
1509
 *
1510
 * The output of this function will be usually appended to taxon name representations.
1511
 *
1512
 * Related issues:
1513
 *   - https://dev.e-taxonomy.eu/redmine/issues/5697 "Show name conserved against as [non xxx]"
1514
 *   - https://dev.e-taxonomy.eu/redmine/issues/6678 "How to correctly show name relationship "orth. var." in dataportal"
1515
 *   - https://dev.e-taxonomy.eu/redmine/issues/5857
1516
 *
1517
 * @param $name_relations
1518
 *    The list of CDM NameRelationsips
1519
 * @param $current_name_uuid
1520
 *    The Uuid of the name for which the relations are to be rendered, the current name will be hidden when
1521
 *    rendering the relation an only the other name is shown. Parameter is REQUIRED.
1522
 * @param $current_taxon_uuid
1523
 *    The taxon to be omitted from related taxa. This is only used to create links, see path_to_name()
1524
 * @return array
1525
 *    A drupal render array
1526
 *
1527
 * @ingroup Compose
1528
 */
1529 96614dfe Andreas Kohlbecker
function compose_name_relationships_list($name_relations, $current_name_uuid, $current_taxon_uuid) {
1530 ef686dd8 Andreas Kohlbecker
1531
  // $ordered_name_relation_type_uuids = array_keys(cdm_terms_by_type_as_option('NameRelationshipType', CDM_ORDER_BY_ORDER_INDEX_ASC));
1532
1533 222784c5 Andreas Kohlbecker
  $key = 'name_relationships';
1534
  RenderHints::pushToRenderStack($key);
1535 b59fbdfa Andreas Kohlbecker
  if(RenderHints::isUnsetFootnoteListKey()){
1536 222784c5 Andreas Kohlbecker
    RenderHints::setFootnoteListKey($key);
1537
  }
1538 ef686dd8 Andreas Kohlbecker
  // the render stack element homonyms is being used in the default render templates !!!, see CDM_NAME_RENDER_TEMPLATES_DEFAULT
1539
1540 85669a85 Andreas Kohlbecker
  $selected_name_rel_uuids = variable_get(CDM_NAME_RELATIONSHIP_LIST_TYPES, cdm_vocabulary_as_defaults(UUID_NAME_RELATIONSHIP_TYPE));
1541 7efd13a9 Andreas Kohlbecker
  $name_rel_type_filter = array('direct' => array(), 'inverse' => array());
1542
  foreach ($selected_name_rel_uuids as $uuid){
1543
    $name_rel_type_filter['direct'][$uuid] = $uuid;
1544
    $name_rel_type_filter['inverse'][$uuid] = $uuid;
1545
  }
1546 ef686dd8 Andreas Kohlbecker
1547 96614dfe Andreas Kohlbecker
  $list_prefix = '<div class="relationships_list name_relationships">';
1548
  $list_suffix = '</div>';
1549
  $item_prefix = '<div class="item">';
1550
  $item_suffix = '</div>';
1551
1552 f8d5d6d9 Andreas Kohlbecker
  $render_array = compose_name_relationships($name_relations, $name_rel_type_filter, $current_name_uuid, $current_taxon_uuid, $list_prefix, $list_suffix, $item_prefix, $item_suffix);
1553 96614dfe Andreas Kohlbecker
1554
  RenderHints::popFromRenderStack();
1555 222784c5 Andreas Kohlbecker
  if(RenderHints::getFootnoteListKey() == $key) {
1556 d8069342 Andreas Kohlbecker
    $render_array['footnotes'] = markup_to_render_array(render_footnotes(RenderHints::getFootnoteListKey()));
1557 222784c5 Andreas Kohlbecker
    RenderHints::clearFootnoteListKey();
1558
  }
1559 96614dfe Andreas Kohlbecker
  return $render_array;
1560
}
1561
1562
/**
1563
 * @param $name_relations
1564 7efd13a9 Andreas Kohlbecker
 * @param $name_rel_type_filter
1565
 *   Associative array with two keys:
1566
 *   - 'direct': the relationship type uuids for the direct direction of the relation edge to be included
1567
 *   - 'inverse': the relationship type uuids for the direct direction of the relation edge to be included
1568 96614dfe Andreas Kohlbecker
 * @param $current_name_uuid
1569
 * @param $current_taxon_uuid
1570
 * @param $list_prefix
1571
 * @param $list_suffix
1572
 * @param $item_prefix
1573
 * @param $item_suffix
1574
 * @return array
1575
 *
1576
 * @ingroup Compose
1577
 */
1578 7efd13a9 Andreas Kohlbecker
function compose_name_relationships($name_relations, $name_rel_type_filter, $current_name_uuid, $current_taxon_uuid,
1579 f8d5d6d9 Andreas Kohlbecker
                                    $list_prefix, $list_suffix, $item_prefix, $item_suffix)
1580 96614dfe Andreas Kohlbecker
{
1581
  $non_nec_name_reltype_uuids = array(UUID_NAMERELATIONSHIPTYPE_LATER_HOMONYM,
1582
    UUID_NAMERELATIONSHIPTYPE_TREATED_AS_LATER_HOMONYM,
1583 1636cc86 Andreas Kohlbecker
    UUID_NAMERELATIONSHIPTYPE_CONSERVED_AGAINST,
1584 7efd13a9 Andreas Kohlbecker
    UUID_NAMERELATIONSHIPTYPE_MISSPELLING,
1585 96614dfe Andreas Kohlbecker
    UUID_NAMERELATIONSHIPTYPE_BLOCKING_NAME_FOR);
1586
1587 ef686dd8 Andreas Kohlbecker
  $render_array = array(
1588
    'list' => array(
1589 96614dfe Andreas Kohlbecker
      '#prefix' => $list_prefix,
1590
      '#suffix' => $list_suffix,
1591 ef686dd8 Andreas Kohlbecker
      'items' => array()
1592
    ),
1593
    'footnotes' => array()
1594
  );
1595
1596 96614dfe Andreas Kohlbecker
  if ($name_relations) {
1597 ef686dd8 Andreas Kohlbecker
1598
    // remove all relations which are not selected in the settings and
1599 96614dfe Andreas Kohlbecker
    // separate all LATER_HOMONYM, TREATED_AS_LATER_HOMONYM, BLOCKING_NAME_FOR relations and ORTHOGRAPHIC_VARIANTs
1600 ef686dd8 Andreas Kohlbecker
    // for special handling
1601
    $filtered_name_rels = array();
1602
    $non_nec_name_rels = array();
1603
    $orthographic_variants = array();
1604 96614dfe Andreas Kohlbecker
    foreach ($name_relations as $name_rel) {
1605
      $rel_type_uuid = $name_rel->type->uuid;
1606 7efd13a9 Andreas Kohlbecker
      $is_inverse_relation = $current_name_uuid == $name_rel->toName->uuid;
1607
      if ((!$is_inverse_relation && isset($name_rel_type_filter['direct'][$rel_type_uuid]) && $name_rel_type_filter['direct'][$rel_type_uuid])
1608
        ||($is_inverse_relation && isset($name_rel_type_filter['inverse'][$rel_type_uuid]) && $name_rel_type_filter['inverse'][$rel_type_uuid])) {
1609
1610 96614dfe Andreas Kohlbecker
        if (array_search($rel_type_uuid, $non_nec_name_reltype_uuids) !== false && (
1611
            $current_name_uuid == $name_rel->fromName->uuid && $rel_type_uuid != UUID_NAMERELATIONSHIPTYPE_BLOCKING_NAME_FOR
1612
            || $current_name_uuid == $name_rel->toName->uuid && $rel_type_uuid == UUID_NAMERELATIONSHIPTYPE_BLOCKING_NAME_FOR
1613
          )
1614
        ){
1615 ef686dd8 Andreas Kohlbecker
          $non_nec_name_rels[] = $name_rel;
1616 96614dfe Andreas Kohlbecker
        } else if (UUID_NAMERELATIONSHIPTYPE_ORTHOGRAPHIC_VARIANT == $rel_type_uuid) {
1617 ef686dd8 Andreas Kohlbecker
          $orthographic_variants[] = $name_rel;
1618
        } else {
1619 96614dfe Andreas Kohlbecker
1620 ef686dd8 Andreas Kohlbecker
          $filtered_name_rels[] = $name_rel;
1621
        }
1622
      }
1623
    }
1624
    $name_relations = $filtered_name_rels;
1625
1626
    usort($name_relations, 'compare_name_relations_by_term_order_index');
1627
1628 7efd13a9 Andreas Kohlbecker
    // compose
1629 95ef7468 Andreas Kohlbecker
    $show_name_cache_only = FALSE;
1630 96614dfe Andreas Kohlbecker
    foreach ($name_relations as $name_rel) {
1631 ef686dd8 Andreas Kohlbecker
1632 96614dfe Andreas Kohlbecker
      $is_inverse_relation = $current_name_uuid == $name_rel->toName->uuid;
1633 95ef7468 Andreas Kohlbecker
      $rel_footnote_key_markup = render_footnote_key(handle_name_relationship_as_footnote($name_rel),'');
1634
      $relationship_markup = name_relationship_markup($current_name_uuid, $name_rel, $current_taxon_uuid, $show_name_cache_only);
1635 ef686dd8 Andreas Kohlbecker
      $label = cdm_relationship_type_term_abbreviated_label($name_rel->type, $is_inverse_relation);
1636 95ef7468 Andreas Kohlbecker
1637 ef686dd8 Andreas Kohlbecker
      $symbol = cdm_relationship_type_term_symbol($name_rel->type, $is_inverse_relation);
1638 f8d5d6d9 Andreas Kohlbecker
      $symbol_markup = '<span class="symbol" title="' . $label . '">' . $symbol . '</span>' . $rel_footnote_key_markup . ' ';
1639
      $relationship_markup = $symbol_markup . $relationship_markup;
1640 96614dfe Andreas Kohlbecker
      if ($relationship_markup) {
1641 ef686dd8 Andreas Kohlbecker
        $render_array['list']['items'][] = markup_to_render_array($relationship_markup,
1642
          null,
1643 96614dfe Andreas Kohlbecker
          $item_prefix,
1644
          $item_suffix);
1645 ef686dd8 Andreas Kohlbecker
      }
1646
    }
1647
1648
    // name relationships to be displayed as non nec
1649 96614dfe Andreas Kohlbecker
    if (count($non_nec_name_rels) > 0) {
1650 ef686dd8 Andreas Kohlbecker
      $non_nec_markup = '';
1651 95ef7468 Andreas Kohlbecker
      $show_name_cache_only = FALSE;
1652 96614dfe Andreas Kohlbecker
      foreach ($non_nec_name_rels as $name_rel) {
1653 95ef7468 Andreas Kohlbecker
1654 96614dfe Andreas Kohlbecker
        $is_inverse_relation = $current_name_uuid == $name_rel->toName->uuid;
1655 95ef7468 Andreas Kohlbecker
        $rel_footnote_key_markup = render_footnote_key(handle_name_relationship_as_footnote($name_rel),'');
1656
        $relationship_markup = name_relationship_markup($current_name_uuid, $name_rel, $current_taxon_uuid, $show_name_cache_only);
1657 96614dfe Andreas Kohlbecker
        $label = cdm_relationship_type_term_abbreviated_label($name_rel->type, $is_inverse_relation);
1658 95ef7468 Andreas Kohlbecker
1659 ef686dd8 Andreas Kohlbecker
        $symbol = $non_nec_markup ? ' nec ' : 'non';
1660 f8d5d6d9 Andreas Kohlbecker
        $symbol_markup = '<span class="symbol" title="' . $label . '">' . $symbol . '</span>' . $rel_footnote_key_markup .  ' ';
1661
        $non_nec_markup .= $symbol_markup . $relationship_markup;
1662 96614dfe Andreas Kohlbecker
      }
1663
      if ($non_nec_markup) {
1664
        $render_array['list']['items'][] = markup_to_render_array($non_nec_markup,
1665
          null,
1666
          $item_prefix,
1667
          $item_suffix);
1668 ef686dd8 Andreas Kohlbecker
      }
1669
    }
1670
1671
    // orthographic variants
1672 96614dfe Andreas Kohlbecker
    if (count($orthographic_variants) > 0) {
1673 95ef7468 Andreas Kohlbecker
      $show_name_cache_only = TRUE;
1674 96614dfe Andreas Kohlbecker
      foreach ($orthographic_variants as $name_rel) {
1675
1676
        $is_inverse_relation = $current_name_uuid == $name_rel->toName->uuid;
1677 95ef7468 Andreas Kohlbecker
        $rel_footnote_key_markup = render_footnote_key(handle_name_relationship_as_footnote($name_rel),'');
1678
        $relationship_markup = name_relationship_markup($current_name_uuid, $name_rel, $current_taxon_uuid, $show_name_cache_only);
1679 96614dfe Andreas Kohlbecker
        $label = cdm_relationship_type_term_abbreviated_label($name_rel->type, $is_inverse_relation);
1680 ef686dd8 Andreas Kohlbecker
        $symbol = cdm_relationship_type_term_symbol($name_rel->type, $is_inverse_relation);
1681 f8d5d6d9 Andreas Kohlbecker
        $symbol_markup = '<span class="symbol" title="' . $label . '">' . $symbol . '</span>' . $rel_footnote_key_markup .  ' ';
1682 95ef7468 Andreas Kohlbecker
        $relationship_markup = $symbol_markup . $relationship_markup;
1683 ef686dd8 Andreas Kohlbecker
      }
1684 26f042e4 Andreas Kohlbecker
      if (isset($relationship_markup) && $relationship_markup) {
1685 ef686dd8 Andreas Kohlbecker
        $render_array['list']['items'][] = markup_to_render_array($relationship_markup,
1686
          null,
1687 96614dfe Andreas Kohlbecker
          $item_prefix,
1688
          $item_suffix);
1689 ef686dd8 Andreas Kohlbecker
      }
1690
    }
1691
  }
1692
  return $render_array;
1693
}
1694
1695
1696 222784c5 Andreas Kohlbecker
1697 d4ea0dd9 Andreas Kohlbecker
/**
1698
 * @param $taxon
1699
 * @return array
1700
 */
1701
function cdm_name_relationships_for_taxon($taxon)
1702
{
1703
  $from_name_relations = cdm_ws_get(CDM_WS_PORTAL_TAXON_FROM_NAMERELATIONS, $taxon->uuid);
1704
  $to_name_relations = cdm_ws_get(CDM_WS_PORTAL_TAXON_TO_NAMERELATIONS, $taxon->uuid);
1705
  $name_relations = array_merge($from_name_relations, $to_name_relations);
1706
  return $name_relations;
1707 0b7bbf68 Andreas Kohlbecker
}
1708
1709
1710 d4ea0dd9 Andreas Kohlbecker
/**
1711 2fd6da0b Andreas Kohlbecker
 * Recursively searches the array for the $key and sets the given value.
1712
 *
1713 c11d7e10 Andreas Kohlbecker
 * Expects the key to be used only once in nested array structures.
1714
 *
1715 2fd6da0b Andreas Kohlbecker
 * @param mixed $key
1716
 *   Key to search for.
1717
 * @param mixed $value
1718
 *   Value to set.'
1719
 * @param array $array
1720
 *   Array to search in.
1721
 *
1722 c11d7e10 Andreas Kohlbecker
 * @return array
1723
 *   The array the key has been found.
1724 2fd6da0b Andreas Kohlbecker
 */
1725
function &array_setr($key, $value, array &$array) {
1726
  $res = NULL;
1727
  foreach ($array as $k => &$v) {
1728
    if ($key == $k) {
1729
      $v = $value;
1730
      return $array;
1731
    }
1732
    elseif (is_array($v)) {
1733
      $innerArray = array_setr($key, $value, $v);
1734
      if ($innerArray) {
1735
        return $array;
1736
      }
1737
    }
1738
  }
1739
  return $res;
1740
}
1741
1742 c11d7e10 Andreas Kohlbecker
/**
1743
 * Recursively searches the array for the $key and sets is to $new_key
1744
 *
1745
 * Expects the key to be used only once in nested array structures.
1746
 *
1747
 * @param mixed $key
1748
 *   Key to search for.
1749
 * @param mixed $new_key
1750
 *   The new key to use
1751
 * @param array $array
1752
 *   Array to search in.
1753
 *
1754
 * @return bool
1755
 *   True if the key has been found.
1756
 */
1757
function array_replace_keyr($key, $new_key, array &$array) {
1758
  $res = NULL;
1759
  if(array_key_exists($key, $array)){
1760
    $value = $array[$key];
1761
    unset($array[$key]);
1762
    $array[$new_key] = $value;
1763
    return true;
1764
  } else {
1765
    // search in next level
1766
    foreach ($array as &$v) {
1767
        if (is_array($v)) {
1768
          array_replace_keyr($key, $new_key, $v);
1769
        }
1770
      }
1771
  }
1772
1773
  return false;
1774
}
1775
1776 2fd6da0b Andreas Kohlbecker
/**
1777
 * @todo Please document this function.
1778
 * @see http://drupal.org/node/1354
1779
 */
1780
function &get_preceding_contentElement($contentElementKey, array &$renderTemplate) {
1781
  $res = NULL;
1782
  $precedingElement = NULL;
1783
  foreach ($renderTemplate as &$part) {
1784
    foreach ($part as $key => &$element) {
1785
      if ($key == $contentElementKey) {
1786
        return $precedingElement;
1787
      }
1788
      $precedingElement = $element;
1789
    }
1790
  }
1791
  return $res;
1792
}
1793
1794
/**
1795
 * @todo Please document this function.
1796
 * @see http://drupal.org/node/1354
1797
 */
1798
function &get_preceding_contentElementKey($contentElementKey, array &$renderTemplate) {
1799
  $res = NULL;
1800
  $precedingKey = NULL;
1801
  foreach ($renderTemplate as &$part) {
1802
    if (is_array($part)) {
1803
      foreach ($part as $key => &$element) {
1804
        if ($key == $contentElementKey) {
1805
          return $precedingKey;
1806
        }
1807
        if (!str_beginsWith($key, '#')) {
1808
          $precedingKey = $key;
1809
        }
1810
      }
1811
    }
1812
  }
1813
  return $res;
1814
}
1815 c2545e1c Andreas Kohlbecker
1816
function nameTypeToDTYPE($dtype){
1817
  static $nameTypeLabelMap = array(
1818
    "ICNB" => "BacterialName",
1819
    "ICNAFP" => "BotanicalName",
1820
    "ICNCP" => "CultivarPlantName",
1821
    "ICZN" => "ZoologicalName",
1822
    "ICVCN" => "ViralName",
1823
    "Any taxon name" => "TaxonName",
1824
    "NonViral" => "TaxonName",
1825
    "Fungus" => "BotanicalName",
1826
    "Plant" => "BotanicalName",
1827
    "Algae" => "BotanicalName",
1828
  );
1829
  return $nameTypeLabelMap[$dtype];
1830
1831
}
1832 ef686dd8 Andreas Kohlbecker
1833
1834
function compare_name_relations_by_term_order_index($name_rel1, $name_rel2){
1835
  return compare_terms_by_order_index($name_rel1->type, $name_rel2->type);
1836
}
1837 b90ef618 Andreas Kohlbecker
1838
/**
1839
 * Provides an array with the different registration types covered by the passed registration.
1840
 *
1841
 * The labels in the returned array are translatable.
1842
 *
1843
 * See also https://dev.e-taxonomy.eu/redmine/issues/8016
1844
 *
1845
 * @param $registration_dto
1846
 * @return array
1847
 *    An array of the labels describing the different registration types covered by the passed registration.
1848
 */
1849
function registration_types($registration_dto){
1850
  $reg_type_labels = array();
1851
  if(isset($registration_dto->nameRef)){
1852 0a02c62f Andreas Kohlbecker
    $reg_type_labels["name"] = t("new name");
1853
    $reg_type_labels["taxon"] = t("new taxon");
1854 b90ef618 Andreas Kohlbecker
    $name_relations = cdm_ws_fetch_all(str_replace("$0", $registration_dto->nameRef->uuid, CDM_WS_PORTAL_NAME_NAME_RELATIONS));
1855 0a02c62f Andreas Kohlbecker
    $is_new_combination = true;
1856 b90ef618 Andreas Kohlbecker
    foreach($name_relations as $name_rel){
1857
      if(isset($name_rel->type->uuid)){
1858
        $name_is_from_name = $registration_dto->nameRef->uuid == $name_rel->fromName->uuid;
1859
        switch($name_rel->type->uuid) {
1860
          case UUID_NAMERELATIONSHIPTYPE_BASIONYM:
1861
            if(!$name_is_from_name){
1862 0a02c62f Andreas Kohlbecker
              $reg_type_labels["basionym"] = t("new combination");
1863
              $is_new_combination = true;
1864 b90ef618 Andreas Kohlbecker
            }
1865
            break;
1866
          case UUID_NAMERELATIONSHIPTYPE_REPLACED_SYNONYM:
1867
            if(!$name_is_from_name) {
1868 0a02c62f Andreas Kohlbecker
              $is_new_combination = true;
1869 b90ef618 Andreas Kohlbecker
            }
1870
            break;
1871
          case UUID_NAMERELATIONSHIPTYPE_VALIDATED_BY_NAME:
1872
            if(!$name_is_from_name) {
1873 0a02c62f Andreas Kohlbecker
              $reg_type_labels["validation"] = t("validation");
1874 b90ef618 Andreas Kohlbecker
            }
1875
            break;
1876
          case UUID_NAMERELATIONSHIPTYPE_ORTHOGRAPHIC_VARIANT:
1877
            if(!$name_is_from_name) {
1878 0a02c62f Andreas Kohlbecker
              $reg_type_labels["orth_var"] = t("orthographical correction");
1879 b90ef618 Andreas Kohlbecker
            }break;
1880
          default:
1881
            // NOTHING
1882
        }
1883
      }
1884
    }
1885 0a02c62f Andreas Kohlbecker
    if($is_new_combination){
1886
      unset($reg_type_labels["taxon"]);
1887
    }
1888 b90ef618 Andreas Kohlbecker
  }
1889 a0ab64df Andreas Müller
  if(isset($registration_dto->orderedTypeDesignationWorkingSets)){
1890 0a02c62f Andreas Kohlbecker
    $reg_type_labels[] = t("new nomenclatural type");
1891 b90ef618 Andreas Kohlbecker
  }
1892
  return $reg_type_labels;
1893 b059b449 Andreas Kohlbecker
}
1894
1895
/**
1896
 * Collects and deduplicates the type designations associated with the passes synonyms.
1897
 *
1898
 * @param $synonymy_group
1899
 *    An array containing a homotypic or heterotypic group of names.
1900 5f188298 Andreas Kohlbecker
 * @param $accepted_taxon_name_uuid
1901 34852f2d Andreas Kohlbecker
 *    The uuid of the accepted taxon name. Optional parameter which is required when composing
1902
 *    the information for the homotypic group. In this case the accepted taxon is not included
1903
 *    in the $synonymy_group and must therefor passed in this second parameter.
1904
 *
1905 b059b449 Andreas Kohlbecker
 * @return array
1906 a584de6a Andreas Kohlbecker
 *    The CDM TypeDesignation entities
1907 b059b449 Andreas Kohlbecker
 */
1908 dfbc27b0 Andreas Kohlbecker
function type_designations_for_synonymy_group($synonymy_group, $accepted_taxon_name_uuid = null)
1909
{
1910
  if (count($synonymy_group) > 0) {
1911 34852f2d Andreas Kohlbecker
    $name_uuid = array_pop($synonymy_group)->name->uuid;
1912
  } else {
1913
    $name_uuid = $accepted_taxon_name_uuid;
1914
  }
1915
  if ($name_uuid) {
1916
   $type_designations = cdm_ws_get(CDM_WS_PORTAL_NAME_TYPEDESIGNATIONS_IN_HOMOTYPICAL_GROUP, $name_uuid);
1917
    if ($type_designations) {
1918 3d14fdcf Andreas Kohlbecker
      return $type_designations;
1919
    }
1920 b059b449 Andreas Kohlbecker
  }
1921 34852f2d Andreas Kohlbecker
1922 dfbc27b0 Andreas Kohlbecker
  return array();
1923 fb939fdc Andreas Kohlbecker
}
1924
1925
1926
/**
1927 04d5812b Andreas Kohlbecker
 * Compares two SpecimenTypeDesignations
1928 fb939fdc Andreas Kohlbecker
 *
1929
 * @param object $a
1930
 *   A SpecimenTypeDesignation.
1931
 * @param object $b
1932
 *   SpecimenTypeDesignation.
1933
 */
1934
function compare_specimen_type_designation($a, $b) {
1935
1936 04d5812b Andreas Kohlbecker
  $cmp_by_status = compare_type_designations_by_status($a,$b);
1937
  if($cmp_by_status !== 0){
1938
    return $cmp_by_status;
1939
  }
1940 fb939fdc Andreas Kohlbecker
1941
  $aQuantifier = FALSE;
1942
  $bQuantifier = FALSE;
1943
  if ($aQuantifier == $bQuantifier) {
1944
    // Sort alphabetically.
1945
    $a_text =  isset($a->typeSpecimen->titleCache) ? preg_replace('/[\[\]\"]/', '', $a->typeSpecimen->titleCache) : '';
1946
    $b_text =  isset($b->typeSpecimen->titleCache) ? preg_replace('/[\[\]\"]/', '', $b->typeSpecimen->titleCache) : '';
1947
    return strcasecmp($a_text, $b_text);
1948
  }
1949 04d5812b Andreas Kohlbecker
  return ($aQuantifier < $bQuantifier) ? -1 : (($aQuantifier > $bQuantifier) ? 1 : 0);
1950
}
1951
1952
/**
1953
 * Compares the status of two TypeDesignations
1954
 *
1955
 * @param object $a
1956
 *   A TypeDesignation
1957
 * @param object $b
1958
 *   TypeDesignation
1959
 */
1960
function compare_type_designations_by_status($a, $b) {
1961 e5a89a58 Andreas Kohlbecker
  $status_a = isset($a->typeStatus) ? $a->typeStatus : null;
1962
  $status_b = isset($b->typeStatus) ? $b->typeStatus : null;
1963
  return compare_type_designation_status($status_a, $status_b);
1964 fb939fdc Andreas Kohlbecker
}
1965
1966
/**
1967 04d5812b Andreas Kohlbecker
 * Compares two TypeDesignationStatusBase
1968 fb939fdc Andreas Kohlbecker
 *
1969
 * @param object $a
1970
 *   A TypeDesignationStatusBase.
1971
 * @param object $b
1972
 *   TypeDesignationStatusBase.
1973
 */
1974
function compare_type_designation_status($a, $b) {
1975
  $type_status_order = type_status_order();
1976
  $aQuantifier = FALSE;
1977
  $bQuantifier = FALSE;
1978
  if (isset($a->label) && isset($b->label)) {
1979
    $aQuantifier = array_search($a->label, $type_status_order);
1980
    $bQuantifier = array_search($b->label, $type_status_order);
1981
  }
1982 04d5812b Andreas Kohlbecker
  return ($aQuantifier < $bQuantifier) ? -1 : (($aQuantifier > $bQuantifier) ? 1 : 0);
1983
}
1984
1985
/**
1986
 * Compares the two TextualTypeDesignations
1987
 *
1988
 * @param object $a
1989
 *   A TextualTypeDesignations.
1990
 * @param object $b
1991
 *   TextualTypeDesignations.
1992
 */
1993
function compare_textual_type_designation($a, $b) {
1994
1995
  $cmp_by_status = compare_type_designations_by_status($a,$b);
1996
  if($cmp_by_status !== 0){
1997
    return $cmp_by_status;
1998
  }
1999
2000
  $aQuantifier = FALSE;
2001
  $bQuantifier = FALSE;
2002
  if ($aQuantifier == $bQuantifier) {
2003
    // Sort alphabetically.
2004
    $a_text =  isset($a->text_L10n->text) ? $a->text_L10n->text : '';
2005
    $b_text =  isset($b->text_L10n->text) ? $b->text_L10n->text : '';
2006
    return strcasecmp($a_text, $b_text);
2007
  }
2008
  return ($aQuantifier < $bQuantifier) ? -1 : (($aQuantifier > $bQuantifier) ? 1 : 0);
2009 fb939fdc Andreas Kohlbecker
}
2010
2011 d8de8d4d Andreas Kohlbecker
2012
/**
2013
 * Compares two SpecimenTypeDesignation status labels
2014
 *
2015
 * @param string $a
2016
 *   A TypeDesignationStatus label.
2017
 * @param string $b
2018
 *   A TypeDesignationStatus label.
2019
 */
2020
function compare_type_designation_status_labels($a, $b) {
2021
2022
  $type_status_order = type_status_order();
2023
2024
  $aQuantifier = FALSE;
2025
  $bQuantifier = FALSE;
2026
  if (isset($a) && isset($b)) {
2027 22354fa0 Andreas Kohlbecker
    $aQuantifier = array_search(ucfirst($a), $type_status_order);
2028
    $bQuantifier = array_search(ucfirst($b), $type_status_order);
2029 d8de8d4d Andreas Kohlbecker
  }
2030
  return ($aQuantifier < $bQuantifier) ? -1 : 1;
2031
}
2032
2033 fb939fdc Andreas Kohlbecker
/**
2034 071a56e6 Andreas Kohlbecker
 * Preliminary implementation of a preset to define a sort order for
2035
 * type designation status.
2036
 *
2037
 * TODO this is only preliminary and may break in future,
2038
 *      see https://dev.e-taxonomy.eu/redmine/issues/8402?issue_count=96&issue_position=4&next_issue_id=8351&prev_issue_id=7966#note-4
2039 fb939fdc Andreas Kohlbecker
 * @return array
2040 071a56e6 Andreas Kohlbecker
 *   The array of orderd type labels
2041 fb939fdc Andreas Kohlbecker
 */
2042
function type_status_order()
2043
{
2044
  /*
2045
    This is the desired sort order as of now: Holotype Isotype Lectotype
2046
    Isolectotype Syntype.
2047
    TODO Basically, what we are trying to do is, we define
2048
    an ordered array of TypeDesignation-states and use the index of this array
2049
    for comparison. This array has to be filled with the cdm- TypeDesignation
2050
    states and the order should be parameterisable inside the dataportal.
2051
    */
2052 071a56e6 Andreas Kohlbecker
  static $type_status_order = array(
2053 fb939fdc Andreas Kohlbecker
    'Epitype',
2054
    'Holotype',
2055
    'Isotype',
2056
    'Lectotype',
2057
    'Isolectotype',
2058
    'Syntype',
2059
    'Paratype'
2060
  );
2061
  return $type_status_order;
2062 4eab6eeb Andreas Kohlbecker
}
2063
2064
/**
2065
 * Return HTML for the lectotype citation with the correct layout.
2066
 *
2067
 * This function prints the lectotype citation with the correct layout.
2068
 * Lectotypes are renderized in the synonymy tab of a taxon if they exist.
2069
 *
2070
 * @param mixed $typeDesignation
2071
 *   Object containing the lectotype citation to print.
2072
 *
2073
 * @return string
2074
 *   Valid html string.
2075
 */
2076
function type_designation_citation_layout($typeDesignation, $footnote_separator = ',') {
2077
  $res = '';
2078 2f5cf318 Andreas Kohlbecker
  $citation = $typeDesignation->designationSource->citation;
2079
  $pages = $typeDesignation->designationSource->citationMicroReference;
2080 4eab6eeb Andreas Kohlbecker
  if(isset($typeDesignation->typeStatus->uuid) && isset($typeDesignation->typeStatus->representation_L10n)) {
2081
    if ( $typeDesignation->typeStatus->uuid == UUID_NTD_ORIGINAL_DESIGNATION || $typeDesignation->typeStatus->uuid == UUID_NTD_MONOTYPY) {
2082
      $res = ' (' . $typeDesignation->typeStatus->representation_L10n . ')';
2083
      return $res;
2084
    }
2085
  }
2086
2087
  if ($citation) {
2088
    // $type = $typeDesignation_citation->type;
2089
    $year = isset($citation->datePublished->start) ? substr($citation->datePublished->start, 0, 4) : '';
2090
    $author = isset($citation->authorship->titleCache) ? $citation->authorship->titleCache : '';
2091
    $res .= ' (designated by ';
2092
    $res .= $author;
2093
    $res .= ($year ? ' ' . $year : '');
2094
    $res .= ($pages ? ': ' . $pages : '');
2095
    // $res .= ')';
2096
2097
    // footnotes should be rendered in the parent element so we
2098
    // are relying on the FootnoteListKey set there
2099 46a93d1e Andreas Kohlbecker
    $fkey_typeDesignation = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), $citation->titleCache);
2100 d8069342 Andreas Kohlbecker
    $res .= render_footnote_key($fkey_typeDesignation, $footnote_separator,TRUE) . ')';
2101 4eab6eeb Andreas Kohlbecker
  }
2102
  return $res;
2103
}
2104
2105
/**
2106
 * Creates markup for the status of a type designation. In case the status or its representation is missing the label will be set to "Type"
2107
 *
2108
 * @param $type_designation
2109
 * @return string
2110
 */
2111
function type_designation_status_label_markup($type_designation)
2112
{
2113
  return '<span class="type-status">'
2114
    . ((isset($type_designation->typeStatus->representation_L10n)) ? ucfirst($type_designation->typeStatus->representation_L10n) : t('Type')) . '</span>'
2115
    ;
2116
}
2117 a584de6a Andreas Kohlbecker
2118
/**
2119
 * Creates markup for the status of a type designation DTO.
2120
 * In case the status or its representation is missing the label will be set to "Type"
2121
 *
2122
 * @param $type_designation
2123
 * @return string
2124
 */
2125
function type_designation_dto_status_label_markup($type_designation)
2126
{
2127
  return '<span class="type-status">'
2128
    . ((isset($type_designation->typeStatus_L10n)) ? ucfirst($type_designation->typeStatus_L10n) : t('Type')) . '</span>'
2129
    ;
2130
}