Project

General

Profile

Download (23.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?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
 * The render templates arrays contains one or more name render template to be used within the page elements identified the the
38
 * renderPath. The renderPath is the key of the subelements whereas the value is the name render template.
39
 * The following keys are curretly recogized:
40
 *
41
 *   - list_of_taxa:
42
 *   - acceptedFor:
43
 *   - taxon_page_synonymy
44
 *   - typedesignations
45
 *   - taxon_page_title
46
 *   - polytomousKey
47
 *   - na: name + authorship
48
 *   - nar:name + authorship + reference
49
 *   - #DEFAULT
50
 *
51
 * A single render template can be used for multiple render paths. In this case the according key of the render templates
52
 * array element should be the list of these render paths concatenated by ONLY a comma character without any whitespace.
53
 *
54
 * A render template is an associative array. The keys of this array are referring to the keys as defined in the part
55
 * definitions array.
56
 * @see get_partDefinition($taxonNameType) for more information
57
 *
58
 * The value of the render template element must be set to TRUE in order to let this part being rendered.
59
 * The namePart, nameAuthorPart and referencePart can also hold an associative array with a single
60
 * element: array('#uri' => TRUE). The value of the #uri element will be replaced by the according
61
 * links if the parameters $nameLink or $refenceLink are set.
62
 *
63
 * @param string $renderPath
64
 *   The render path can consist of multiple dot separated elements
65
 *   @see RenderHints::getRenderPath()
66
 * @param string $nameLink
67
 *   The link path ot URL to be used for name parts if a link is forseen in the template
68
 *   matching the given $renderPath.
69
 * @param string $referenceLink
70
 *   The link path ot URL to be used for nomenclatural reference parts if a link is forseen
71
 *   in the template matching the given $renderPath.
72
 * @return array
73
 *   An associative array, the render template
74
 */
75
function get_nameRenderTemplate($renderPath, $nameLink = NULL, $referenceLink = NULL) {
76

    
77
  static $default_render_templates = NULL;
78
  static $split_render_templates = NULL;
79

    
80

    
81
  if (!isset($default_render_templates)) {
82
    $default_render_templates = unserialize(CDM_NAME_RENDER_TEMPLATES_DEFAULT);
83
  }
84
  if($split_render_templates == NULL) {
85
    $render_templates = variable_get(CDM_NAME_RENDER_TEMPLATES, $default_render_templates);
86
    // needs to be converted to an array
87
    $render_templates = (convert_to_array($render_templates));
88

    
89
    // separate render templates which are combined with a comma
90
    $split_render_templates = array();
91
    foreach($render_templates as $key => $template){
92
      if(strpos($key, ',')){
93
        foreach(explode(',', $key) as $path){
94
          $split_render_templates[$path] = $template;
95
        }
96
      } else {
97
        $split_render_templates[$key] = $template;
98
      }
99
    }
100
  }
101

    
102
  // get the base element of the renderPath
103
  if (($separatorPos = strpos($renderPath, '.')) > 0) {
104
    $renderPath_base = substr($renderPath, 0, $separatorPos);
105
  } else {
106
    $renderPath_base = $renderPath;
107
  }
108

    
109
  $template = NULL;
110
  // 1. try to find a template using the render path base element
111
  if(array_key_exists($renderPath_base, $split_render_templates)){
112
    $template = (array)$split_render_templates[$renderPath_base];
113
  }
114

    
115
  // 2. Find best matching default RenderTemplate in theme
116
  // by stripping the dot separated render path element by element
117
  // is no matching template is found the DEFAULT will be used.
118
  while (!is_array($template) && strlen($renderPath) > 0) {
119
    foreach ($split_render_templates as $path => $t) {
120
      if ($path == $renderPath) {
121
        $template = $t;
122
        break;
123
      }
124
    }
125
    // shorten by one element
126
    $renderPath = substr($renderPath, strrpos($renderPath, '.') + 1, strlen($renderPath));
127
  }
128

    
129

    
130
  // 3. Otherwise get default RenderTemplate from theme.
131
  if (!is_array($template)) {
132
    $template = $split_render_templates['#DEFAULT'];
133
  }
134

    
135
  // --- set the link uris to the according template fields if they exist
136
  if(isset($template['nameAuthorPart']) && isset($template['nameAuthorPart']['#uri'])) {
137
    if ($nameLink) {
138
      $template['nameAuthorPart']['#uri'] = $nameLink;
139
    }
140
    else {
141
      unset($template['nameAuthorPart']['#uri']);
142
    }
143
  }
144

    
145
  if ($nameLink && isset($template['namePart']['#uri'])) {
146
    $template['namePart']['#uri'] = $nameLink;
147
  }
148
  else {
149
    unset($template['namePart']['#uri']);
150
  }
151

    
152
  if ($referenceLink && isset($template['referencePart']['#uri'])) {
153
    $template['referencePart']['#uri'] = $referenceLink;
154
  }
155
  else {
156
    unset($template['referencePart']['#uri']);
157
  }
158

    
159
  return $template;
160
}
161

    
162
/**
163
 * The part definitions define the specific parts of which a rendered taxon name plus additional information will consist.
164
 *
165
 * A full taxon name plus additional information can consist of the following elements:
166
 *
167
 *   - name: the taxon name inclugin rank nbut without author
168
 *   - authorTeam:  The authors of a reference, also used in taxon names
169
 *   - authors:  The authors of a reference, also used in taxon names
170
 *   - reference: the nomenclatural reference,
171
 *   - microreference:  Volume, page number etc.
172
 *   - status:  The nomenclatural status of a name
173
 *   - description: name descriptions like protologues etc ...
174
 *
175
 * These elements are combined in the part definitions array to from the specific parts to be rendered.
176
 * Usually the following parts are formed:
177
 *
178
 * The name "Lapsana communis L., Sp. Pl.: 811. 1753" shall be an example here:
179
 *  - namePart: the name and rank (in example: "Lapsana communis")
180
 *  - authorshipPart: the author (in example: "L.")
181
 *  - nameAuthorPart: the combination of name and author part (in example: "Lapsana communis L.").
182
 *     This is useful for zoological names where the authorshipPart belongs to the name and both should
183
 *     be combined when a link to the taxon is rendered.
184
 *  - referencePart: the nomencaltural reference (in example: "Sp. Pl. 1753")
185
 *  - microreferencePart: usually the page number (in example ": 811.")
186
 *  - statusPart: the nomenclatorical status
187
 *  - descriptionPart:
188
 *
189
 * Each set of parts is dedicated to render a specific TaxonName type, the type names are used as keys for the
190
 * specific parts part definitions:
191
 *
192
 *  - BotanicalName
193
 *  - ZoologicalName
194
 *  - #DEFAULT:  covers ViralNames and general NonViralNames
195
 *
196
 * An example:
197
 * @code
198
 * array(
199
 *    'ZoologicalName' => array(
200
 *        'namePart' => array('name' => TRUE),
201
 *        'referencePart' => array('authorTeam' => TRUE),
202
 *        'microreferencePart' => array('microreference' => TRUE),
203
 *        'statusPart' => array('status' => TRUE),
204
 *        'descriptionPart' => array('description' => TRUE),
205
 *    ),
206
 *    'BotanicalName' => array(
207
 *        'namePart' => array(
208
 *            'name' => TRUE,
209
 *            'authors' => TRUE,
210
 *        ),
211
 *        'referencePart' => array(
212
 *            'reference' => TRUE,
213
 *            'microreference' => TRUE,
214
 *        ),
215
 *        'statusPart' => array('status' => TRUE),
216
 *        'descriptionPart' => array('description' => TRUE),
217
 *    ),
218
 *  );
219
 * @endcode
220
 *
221
 */
222
function get_partDefinition($taxonNameType) {
223

    
224
  static $default_part_definitions = null;
225
  if (!isset($default_part_definitions)) {
226
    $default_part_definitions= unserialize(CDM_PART_DEFINITIONS_DEFAULT);
227
  }
228

    
229
  static $part_definitions = null;
230
  if (!isset($part_definitions)) {
231
    $part_definitions = convert_to_array(variable_get(CDM_PART_DEFINITIONS, $default_part_definitions));
232
  }
233

    
234
  if (array_key_exists($taxonNameType, $part_definitions)) {
235
    return $part_definitions[$taxonNameType];
236
  } else {
237
    return $part_definitions['#DEFAULT']; // covers ViralNames and general NonViralNames
238
  }
239

    
240
}
241

    
242

    
243
/**
244
 * Renders the markup for a CDM TaxonName instance.
245
 *
246
 * The layout of the name representation is configured by the
247
 * part_definitions and render_templates (see get_partDefinition() and
248
 * get_nameRenderTemplate())
249
 *
250
 * @param $taxonName
251
 *    cdm TaxonNameBase instance
252
 * @param $sec
253
 *    the sec reference of a taxon having this name (optional)
254
 * @param $nameLink
255
 *    URI to the taxon, @see path_to_taxon(), must be processed by url() before passing to this method
256
 * @param $refenceLink
257
 *    URI to the reference, @see path_to_reference(), must be processed by url() before passing to this method
258
 * @param $show_annotations
259
 *    turns the display of annotations on
260
 * @param $is_type_designation
261
 *    To indicate that the supplied taxon name is a name type designation.
262
 * @param $skiptags
263
 *    an array of name elements tags like 'name', 'rank' to skip. The name part
264
 *          'authors' will not ber affected by this filter. This part is managed though the render template
265
 *          mechanism.
266
 * @param $is_invalid
267
 *   Indicates that this taxon is invalid. In this case the name part will be shown in double quotes.
268
 *   This is useful when rendering taxon relation ships.
269
 *
270
 * @return string
271
 *  The markup for a taxon name.
272
 *
273
 */
274
function render_taxon_or_name($taxon_name_or_taxon_base, $nameLink = NULL, $refenceLink = NULL,
275
  $show_annotations = true, $is_type_designation = false, $skiptags = array(), $is_invalid = false) {
276

    
277
  if($taxon_name_or_taxon_base->class == 'Taxon' || $taxon_name_or_taxon_base->class == 'Synonym'){
278
    $taxonName = $taxon_name_or_taxon_base->name;
279
    // use the TaxonBase.taggedTitle so we have the secRef
280
    $taggedTitle = $taxon_name_or_taxon_base->taggedTitle;
281
  } else {
282
    // assuming this is a TaxonNameBase
283
    $taxonName = $taxon_name_or_taxon_base;
284
    $taggedTitle = $taxon_name_or_taxon_base->taggedName;
285
  }
286

    
287

    
288
  $renderTemplate = get_nameRenderTemplate(RenderHints::getRenderPath(), $nameLink, $refenceLink);
289
  $partDefinition = get_partDefinition($taxonName->class);
290

    
291
  // Apply definitions to template.
292
  foreach ($renderTemplate as $part => $uri) {
293

    
294
    if (isset($partDefinition[$part])) {
295
      $renderTemplate[$part] = $partDefinition[$part];
296
    }
297
    if (is_array($uri) && isset($uri['#uri'])) {
298
      $renderTemplate[$part]['#uri'] = $uri['#uri'];
299
    }
300
  }
301

    
302
  $secref_tagged_text = split_secref_from_tagged_text($taggedTitle);
303
  $nom_status_tagged_text = split_nomstatus_from_tagged_text($taggedTitle);
304
  $appended_phrase_tagged_text = array(); // this is filled later
305

    
306
  normalize_tagged_text($taggedTitle);
307

    
308
  $firstEntryIsValidNamePart =
309
    isset($taggedTitle)
310
    && is_array($taggedTitle)
311
    && isset($taggedTitle[0]->text)
312
    && is_string($taggedTitle[0]->text)
313
    && $taggedTitle[0]->text != ''
314
    && isset($taggedTitle[0]->type)
315
    && $taggedTitle[0]->type == 'name';
316
  $lastAuthorElementString = FALSE;
317

    
318
  $name_encasement = $is_invalid ? '"' : '';
319

    
320
  // split off all appendedPhrase item  from the end of the array (usually there only should  be one)
321
  while($taggedTitle[count($taggedTitle)-1]->type == "appendedPhrase"){
322
    $appended_phrase_tagged_text[] = array_pop($taggedTitle);
323
  }
324

    
325
  // Got to use second entry as first one, see ToDo comment below ...
326
  if ($firstEntryIsValidNamePart) {
327

    
328
    $taggedName = $taggedTitle;
329
    $hasNamePart_with_Authors = isset($renderTemplate['namePart']) && isset($renderTemplate['namePart']['authors']);
330
    $hasNameAuthorPart_with_Authors = isset($renderTemplate['nameAuthorPart']) && isset($renderTemplate['nameAuthorPart']['authors']);
331

    
332

    
333
    if (!(($hasNamePart_with_Authors) || ($hasNameAuthorPart_with_Authors))) {
334
      // Find author and split off from name.
335
      // TODO expecting to find the author as the last element.
336
      /*
337
      if($taggedName[count($taggedName)- 1]->type == 'authors'){
338
        $authorTeam = $taggedName[count($taggedName)- 1]->text;
339
        unset($taggedName[count($taggedName)- 1]);
340
      }
341
      */
342

    
343
      // Remove all authors.
344
      $taggedNameNew = array();
345
      foreach ($taggedName as $element) {
346
        if ($element->type != 'authors') {
347
          $taggedNameNew[] = $element;
348
        }
349
        else {
350
          $lastAuthorElementString = $element->text;
351
        }
352
      }
353
      $taggedName = $taggedNameNew;
354
      unset($taggedNameNew);
355
    }
356
    $name = '<span class="' . $taxonName->class . '">' . $name_encasement . cdm_tagged_text_to_markup($taggedName, 'span', ' ', $skiptags) . $name_encasement . '</span>';
357
  }
358
  else {
359
    $name = '<span class="' . $taxonName->class . '_titleCache">' . $name_encasement . $taxonName->titleCache . $name_encasement . '</span>';
360
  }
361

    
362

    
363
  if(isset($appended_phrase_tagged_text[0])){
364
    $name .= ' '. cdm_tagged_text_to_markup($appended_phrase_tagged_text);
365
  }
366

    
367
  // Fill name into $renderTemplate.
368
  array_setr('name', $name , $renderTemplate);
369

    
370
  // Fill with authorTeam.
371
  /*
372
  if($authorTeam){
373
    $authorTeamHtml = ' <span class="authorTeam">'.$authorTeam.'</span>';
374
    array_setr('authorTeam', $authorTeamHtml, $renderTemplate);
375
  }
376
  */
377

    
378
  // Fill with reference.
379
  if (isset($renderTemplate['referencePart']) && !$is_type_designation) {
380

    
381
    // default separator
382
    $separator = '';
383

    
384
    // [Eckhard]:"Komma nach dem Taxonnamen ist grunsätzlich falsch,
385
    // Komma nach dem Autornamen ist überall dort falsch, wo ein "in" folgt."
386
    if (isset($renderTemplate['referencePart']['reference']) && isset($taxonName->nomenclaturalReference)) {
387
      $microreference = NULL;
388
      if (isset($renderTemplate['referencePart']['microreference'])&& isset($taxonName->nomenclaturalMicroReference)) {
389
        $microreference = $taxonName->nomenclaturalMicroReference;
390
      }
391
      $citation = cdm_ws_getNomenclaturalReference($taxonName->nomenclaturalReference->uuid, $microreference);
392

    
393
      // Find preceding element of the reference.
394
      $precedingKey = get_preceding_contentElementKey('reference', $renderTemplate);
395
      if (str_beginsWith($citation, ", in")) {
396
        $citation = substr($citation, 2);
397
        $separator = ' ';
398
      }
399
      elseif (!str_beginsWith($citation, "in") && $precedingKey == 'authors') {
400
        $separator = ', ';
401
      } else {
402
        $separator = ' ';
403
      }
404

    
405

    
406
      $referenceArray['#separator'] = $separator;
407
      $referenceArray['#html'] = '<span class="reference">' . $citation . '</span>';
408
      array_setr('reference', $referenceArray, $renderTemplate);
409
    }
410

    
411
    // If authors have been removed from the name part the last named authorteam
412
    // should be added to the reference citation, otherwise, keep the separator
413
    // out of the reference.
414
    if (isset($renderTemplate['referencePart']['authors']) && $lastAuthorElementString) {
415
      // If the nomenclaturalReference citation is not included in the
416
      // reference part but diplay of the microreference
417
      // is wanted, append the microreference to the authorTeam.
418
      $citation = '';
419
      if (!isset($renderTemplate['referencePart']['reference']) && isset($renderTemplate['referencePart']['microreference'])) {
420
        $separator = ": ";
421
        $citation = $taxonName->nomenclaturalMicroReference;
422
      }
423
      $referenceArray['#html'] = ' <span class="reference">' . $lastAuthorElementString . $separator . $citation . '</span>';
424
      array_setr('authors', $referenceArray, $renderTemplate);
425
    }
426
  }
427

    
428
  $is_reference_year = false;
429
  if (isset($renderTemplate['referenceYearPart']['reference.year'])) {
430
    if(isset($taxonName->nomenclaturalReference->datePublished)){
431
      $referenceArray['#html'] = ' <span class="reference">' . timePeriodToString($taxonName->nomenclaturalReference->datePublished) . '</span>';
432
      array_setr('reference.year', $referenceArray, $renderTemplate);
433
      $is_reference_year = true;
434
    }
435
  }
436

    
437
  // Fill with status.
438
  if(isset($renderTemplate['statusPart'])){
439
    if (isset($nom_status_tagged_text[0])) {
440
      if (array_setr('status', TRUE, $renderTemplate)) {
441
        array_setr('status', '<span class="nomenclatural_status">' . cdm_tagged_text_to_markup($nom_status_tagged_text, 'span', '', array('postSeparator')) . '</span>', $renderTemplate);
442
      }
443
    }
444
  }
445

    
446
  if (isset($renderTemplate['secReferencePart'])){
447
    if(isset($secref_tagged_text[1])){
448
      $post_separator_markup = $is_reference_year ? '.': '';
449
      if(isset($nom_status_tagged_text[count($nom_status_tagged_text) - 1]) && ($nom_status_tagged_text[count($nom_status_tagged_text) - 1]->type ==  'postSeparator')){
450
        $post_separator_markup = cdm_tagged_text_to_markup(array($nom_status_tagged_text[count($nom_status_tagged_text) - 1 ]));
451
      };
452
      array_setr('secReference',
453
        $post_separator_markup
454
          . ' <span class="sec_reference">'
455
          . join(' ', cdm_tagged_text_values($secref_tagged_text))
456
          . '</span>', $renderTemplate);
457
    }
458
  }
459

    
460

    
461
  // Fill with protologues etc...
462
  $descriptionHtml = '';
463
  if (array_setr('description', TRUE, $renderTemplate)) {
464
    $descriptions = cdm_ws_get(CDM_WS_PORTAL_NAME_DESCRIPTIONS, $taxonName->uuid);
465
    foreach ($descriptions as $description) {
466
      if (!empty($description)) {
467
        foreach ($description->elements as $description_element) {
468
          $second_citation = '';
469
          if (isset($description_element->multilanguageText_L10n) && $description_element->multilanguageText_L10n->text) {
470
            $second_citation = '[& ' . $description_element->multilanguageText_L10n->text . '].';
471
          }
472
          $descriptionHtml .= $second_citation;
473
          $descriptionHtml .= theme("cdm_media", array(
474
              'descriptionElement' => $description_element,
475
              'mimeTypePreference' => array(
476
                'application/pdf',
477
                'image/png',
478
                'image/jpeg',
479
                'image/gif',
480
                'text/html',
481
              )
482
            )
483
          );
484

    
485
        }
486
      }
487
    }
488
    array_setr('description', $descriptionHtml, $renderTemplate);
489
  }
490

    
491
  // Render.
492
  $out = '<span class="' . html_class_attribute_ref($taxon_name_or_taxon_base). '" data-cdm-ref="/name/' . $taxonName->uuid . '">';
493

    
494
  foreach ($renderTemplate as $partName => $part) {
495
    $separator = '';
496
    $partHtml = '';
497
    $uri = FALSE;
498
    if (!is_array($part)) {
499
      continue;
500
    }
501
    if (isset($part['#uri']) && is_string($part['#uri'])) {
502
      $uri = $part['#uri'];
503
      unset($part['#uri']);
504
    }
505
    foreach ($part as $key => $content) {
506
      $html = '';
507
      if (is_array($content)) {
508
        $html = $content['#html'];
509
        if(isset($content['#separator'])) {
510
          $separator = $content['#separator'];
511
        }
512
      }
513
      elseif (is_string($content)) {
514
        $html = $content;
515
      }
516
      $partHtml .= '<span class="' . $key . '">' . $html . '</span>';
517
    }
518
    if ($uri) {
519
      // cannot use l() here since the #uri aleady should have been processed through uri() at this point
520
      $out .= $separator . '<a href="' . $uri . '" class="' . $partName . '">' . $partHtml . '</a>';
521

    
522
    }
523
    else {
524
      $out .= $separator . $partHtml;
525
    }
526
  }
527
  $out .= '</span>';
528
  if ($show_annotations) {
529
    // $out .= theme('cdm_annotations_as_footnotekeys', $taxonName);
530
  }
531
  return $out;
532
}
533

    
534
/**
535
 * Renders the string of Homonyms for a given taxon.
536
 *
537
 * @param $taxon
538
 *    A CDM Taxon instance
539
 * @return String
540
 *    The string of homomyns
541
 *
542
 * @throws \Exception
543
 */
544
function cdm_name_relationships_of($taxon) {
545
// =========== START OF HOMONYMS ========== //
546
  RenderHints::pushToRenderStack('homonym');
547
  // the render stack element homonyms is being used in the default render templates !!!, see CDM_NAME_RENDER_TEMPLATES_DEFAULT
548

    
549
  // Later homonym or treated as later homonym AND bloking names.
550
  // TODO apply filter ? $name_rels_to_show = variable_get('name_relationships_to_show', NULL);
551
  $from_name_relations = cdm_ws_get(CDM_WS_PORTAL_TAXON_FROM_NAMERELATIONS,
552
    $taxon->uuid);
553
  $to_name_relations = cdm_ws_get(CDM_WS_PORTAL_TAXON_TO_NAMERELATIONS,
554
    $taxon->uuid);
555
  $name_relations = array_merge($from_name_relations, $to_name_relations);
556

    
557
  $homonyms_array = array();
558

    
559
  if ($name_relations) {
560
    foreach ($name_relations as $element) {
561
      $taxon_html = NULL;
562
      switch ($element->type->uuid) {
563
        case UUID_LATER_HOMONYM :
564
          $elementTaxonBasesUuid = isset ($element->toName->taxonBases [0]->uuid) ? $element->toName->taxonBases [0]->uuid : '';
565

    
566
          //from relation ships -> only shown at fromName-synonym
567
          if ($taxon->name->uuid == $element->fromName->uuid) {
568
            $taxon_html =render_taxon_or_name($element->toName,
569
              url(path_to_name($element->toName->uuid, $taxon->uuid, $elementTaxonBasesUuid))
570
            );
571
          }
572
          break;
573
        case UUID_TREATED_AS_LATER_HOMONYM :
574
          $elementTaxonBasesUuid = isset ($element->toName->taxonBases [0]->uuid) ? $element->toName->taxonBases [0]->uuid : '';
575

    
576
          //from relation ships -> only shown at fromName-synonym
577
          if ($taxon->name->uuid == $element->fromName->uuid) {
578
            $taxon_html = render_taxon_or_name($element->toName, url(path_to_name($element->toName->uuid)));
579
          }
580
          break;
581
        case UUID_BLOCKING_NAME_FOR :
582
          $elementTaxonBasesUuid = isset ($element->fromName->taxonBases [0]->uuid) ? $element->fromName->taxonBases [0]->uuid : '';
583

    
584
          //to relation ships -> only shown at toName-synonym
585
          if ($taxon->name->uuid == $element->toName->uuid) {
586
            $taxon_html = render_taxon_or_name($element->fromName,
587
              url(path_to_name($element->fromName->uuid, $taxon->uuid, $elementTaxonBasesUuid))
588
            );
589
          }
590
          break;
591
        default:
592
          $taxon_html = NULL;
593
      }
594
      if (isset($taxon_html) && $taxon_html) {
595
        if (count($homonyms_array)) {
596
          $homonyms_array [] = 'nec ' . $taxon_html;
597
        }
598
        else {
599
          $homonyms_array [] = 'non ' . $taxon_html;
600
        }
601
      }
602
    }
603
  }
604

    
605
  RenderHints::popFromRenderStack();
606
  return (count($homonyms_array) ?'[' . trim(join(" ", $homonyms_array)) . ']' : '');
607
}
608

    
609

    
610
  /**
611
 * Recursively searches the array for the $key and sets the given value.
612
 *
613
 * @param mixed $key
614
 *   Key to search for.
615
 * @param mixed $value
616
 *   Value to set.'
617
 * @param array $array
618
 *   Array to search in.
619
 *
620
 * @return bool
621
 *   True if the key has been found.
622
 */
623
function &array_setr($key, $value, array &$array) {
624
  $res = NULL;
625
  foreach ($array as $k => &$v) {
626
    if ($key == $k) {
627
      $v = $value;
628
      return $array;
629
    }
630
    elseif (is_array($v)) {
631
      $innerArray = array_setr($key, $value, $v);
632
      if ($innerArray) {
633
        return $array;
634
      }
635
    }
636
  }
637
  return $res;
638
}
639

    
640
/**
641
 * @todo Please document this function.
642
 * @see http://drupal.org/node/1354
643
 */
644
function &get_preceding_contentElement($contentElementKey, array &$renderTemplate) {
645
  $res = NULL;
646
  $precedingElement = NULL;
647
  foreach ($renderTemplate as &$part) {
648
    foreach ($part as $key => &$element) {
649
      if ($key == $contentElementKey) {
650
        return $precedingElement;
651
      }
652
      $precedingElement = $element;
653
    }
654
  }
655
  return $res;
656
}
657

    
658
/**
659
 * @todo Please document this function.
660
 * @see http://drupal.org/node/1354
661
 */
662
function &get_preceding_contentElementKey($contentElementKey, array &$renderTemplate) {
663
  $res = NULL;
664
  $precedingKey = NULL;
665
  foreach ($renderTemplate as &$part) {
666
    if (is_array($part)) {
667
      foreach ($part as $key => &$element) {
668
        if ($key == $contentElementKey) {
669
          return $precedingKey;
670
        }
671
        if (!str_beginsWith($key, '#')) {
672
          $precedingKey = $key;
673
        }
674
      }
675
    }
676
  }
677
  return $res;
678
}
(5-5/8)