Project

General

Profile

Download (20.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * functions for annotation and sources handling which are to be rendered as
5
 * footnotes.
6
 *
7
 * @copyright
8
 *   (C) 2007-2020 EDIT
9
 *   European Distributed Institute of Taxonomy
10
 *   http://www.e-taxonomy.eu
11
 *
12
 *   The contents of this module are subject to the Mozilla
13
 *   Public License Version 1.1.
14
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
15
 *
16
 * @author
17
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
18
 */
19
const MEMBER_OF_FOOTNOTES = ' member-of-footnotes-';
20

    
21
/**
22
 * Creates the footnotes for the given CDM instance.
23
 *
24
 * Footnotes are created for annotations and original sources whereas the resulting footnote keys depend on the
25
 * parameters $footnote_list_key and $is_bibliography_aware, see parameter $footnote_list_key
26
 * for more details.
27
 *
28
 * possible keys for annotation and source footnotes:
29
 *       - $footnote_list_key
30
 *       - RenderHints::getFootnoteListKey()
31
 *     - original source footnotes
32
 *       - "BIBLIOGRAPHY" (when !$is_bibliography_aware && bibliography_settings['enabled'] == 1 )
33
 *       - "BIBLIOGRAPHY-$footnote_list_key" (when !$is_bibliography_aware && bibliography_settings['enabled'] == 0 )
34
 *       - $footnote_list_key (when $is_bibliography_aware)
35
 *
36
 * @param $cdm_entity
37
 *   A CDM entity
38
 * @param $footnote_list_key string
39
 *    Optional parameter. If this parameter is left empty (null, 0, "") the footnote key will be determined by the nested
40
 *    method calls by calling RenderHints::getFootnoteListKey().
41
 *    For original sources the $footnote_list_key will be overwritten by bibliography_footnote_list_key() when
42
 *    $is_bibliography_aware is set TRUE.
43
 * @param bool $do_link_to_reference
44
 *    Create a link to the reference pages for sources when TRUE.
45
 * @param bool $do_link_to_name_used_in_source
46
 *    Create a link to the name pages for name in source when TRUE.
47
 * @param bool $is_bibliography_aware
48
 *    Put source references into the bibliography when this param is TRUE.
49
 *    For original sources the $footnote_list_key will be overwritten
50
 *    by bibliography_footnote_list_key() when
51
 *    $is_bibliography_aware is set TRUE.
52
 * @param bool $add_annotations
53
 *    Footnotes for annotations will not be created if this is FALSE
54
 *
55
 * @return array
56
 *   An array of the footnote keys for the supplied cdm entity
57
 *
58
 * NOTE: Only used in @see handle_annotations_and_sources()
59
 */
60
function cdm_entity_footnotes(
61
  $cdm_entity,
62
  $footnote_list_key = NULL,
63
  $do_link_to_reference = FALSE,
64
  $do_link_to_name_used_in_source = FALSE,
65
  $is_bibliography_aware = FALSE,
66
  $add_annotations = TRUE
67
){
68

    
69
  $sources = cdm_entity_sources_sorted($cdm_entity);
70

    
71
  if (!isset($footnote_list_key) || !$footnote_list_key) {
72
    $footnote_list_key = RenderHints::getFootnoteListKey();
73
  }
74

    
75
  // Annotations as footnotes.
76
  if($add_annotations){
77
    $footnote_keys = cdm_entity_annotations_as_footnote_keys($cdm_entity, $footnote_list_key);
78
  }
79

    
80
  // Source references as footnotes.
81
  if($is_bibliography_aware){
82
    $bibliography_settings = get_bibliography_settings();
83
    $sources_footnote_list_key = bibliography_footnote_list_key($footnote_list_key);
84
    $original_source_footnote_tag = $bibliography_settings['enabled'] == 1 ? 'div' : null; // null will cause bibliography_footnote_list_key to use the default
85
  } else {
86
    $sources_footnote_list_key = $footnote_list_key;
87
    $original_source_footnote_tag = NULL;
88
  }
89

    
90
  foreach ($sources as $source) {
91
    if (_is_original_source_type($source)) {
92
      $fn_key = FootnoteManager::addNewFootnote(
93
        $sources_footnote_list_key,
94
        render_original_source(
95
          $source,
96
          $do_link_to_reference,
97
          $do_link_to_name_used_in_source
98
        ),
99
        $original_source_footnote_tag
100
      );
101
      // Ensure uniqueness of the footnote keys.
102
      if(array_search($fn_key, $footnote_keys)=== false) {
103
        $footnote_keys[] = $fn_key;
104
      }
105
    }
106
  }
107
  // Sort and render footnote keys.
108
  asort($footnote_keys);
109
  return $footnote_keys;
110
}
111

    
112
/**
113
 * Fetches the list of visible annotations for the cdm entity or for the comparable
114
 * object and returns the footnote keys.
115
 *
116
 * The footnotes are passed to the FootnoteManager in order to store the
117
 * annotations and to create the footnote keys.
118

    
119
 * @param stdClass $cdm_entity
120
 *   A single CdmBase instance ore comparable object.
121
 * @param $footnote_list_key string
122
 *    optional parameter. If this parameter is left empty (null, 0, "") the
123
 *    footnote key will be set to RenderHints::getFootnoteListKey()
124
 *    otherwise the supplied $footnote_list_key will be used.
125
 * @return array of footnote keys
126
 *
127
 * @see cdm_fetch_visible_annotations()
128
 */
129
function cdm_entity_annotations_as_footnote_keys(stdClass $cdm_entity, $footnote_list_key = NULL) {
130

    
131
  $foot_note_keys = [];
132

    
133
  if (!isset($footnote_list_key) || !$footnote_list_key) {
134
    $footnote_list_key = RenderHints::getFootnoteListKey();
135
  }
136

    
137
  // Adding the footnotes keys.
138
  $annotations = cdm_fetch_visible_annotations($cdm_entity);
139
  if (is_array($annotations)) {
140
    foreach ($annotations as $annotation) {
141
      $foot_note_keys[] = FootnoteManager::addNewFootnote($footnote_list_key, $annotation->text);
142
    }
143
  }
144

    
145
  return $foot_note_keys;
146
}
147

    
148
/**
149
 * Fetches the list of visible annotations for the cdm entity or for the comparable
150
 * object and returns a list of the annotation texts
151
 *
152
 * @param stdClass $cdm_entity
153
 *   A single CdmBase instance ore comparable object.
154
 *
155
 * @see cdm_fetch_visible_annotations()
156
 */
157
function cdm_entity_annotations_as_content(stdClass $cdm_entity) {
158

    
159
  $annotation_texts = [];
160
  $annotations = cdm_fetch_visible_annotations($cdm_entity);
161
  if (is_array($annotations)) {
162
    foreach ($annotations as $annotation) {
163
      if($annotation->text){
164
        $annotation_texts[] = $annotation->text;
165
      }
166
    }
167
  }
168
  return $annotation_texts;
169
}
170

    
171
/**
172
 * Creates markup for an array of foot note keys
173
 *
174
 * @param array $footnote_keys
175
 * @param string $separator
176
 *
177
 * @return string
178
 */
179
function render_footnote_keys(array $footnote_keys, $separator) {
180

    
181
  $footnotes_markup = '';
182
  foreach ($footnote_keys as $foot_note_key) {
183
    try {
184
      $footnotes_markup .= render_footnote_key($foot_note_key, ($footnotes_markup ? $separator : ''));
185
    } catch (Exception $e) {
186
      drupal_set_message("Exception: " . $e->getMessage(), 'error');
187
    }
188
  }
189
  return $footnotes_markup;
190
}
191

    
192
/**
193
 * Creates markup for a foot note key
194
 *
195
 * @param null $footnoteKey
196
 * @param string $separator
197
 * @param bool $separator_off
198
 *
199
 * @return string
200
 *   The footnote key markup
201
 */
202
function render_footnote_key($footnoteKey = null, $separator = '', $separator_off = false) {
203

    
204
  if (!is_object($footnoteKey) or !isset($footnoteKey->footnoteListKey)) {
205
    return '';
206
  }
207
  if (variable_get('cdm_dataportal_all_footnotes', CDM_DATAPORTAL_ALL_FOOTNOTES)) {
208
    return '';
209
  }
210

    
211
  if ($separator_off) {
212
    $separator = '';
213
  }
214
  $out = '<span class="footnote-key footnote-key-' . $footnoteKey->keyStr . MEMBER_OF_FOOTNOTES . $footnoteKey->footnoteListKey . '">'
215
    . $separator . '<a href="#footnote-' . $footnoteKey->keyStr . '">' . $footnoteKey->keyStr . '</a>' . '</span>';
216
  return $out;
217
}
218

    
219
/**
220
 * Create the markup for a footnote. This method is used in {@link Footnote::doRender()}
221
 * @param null $footnoteKey
222
 * @param null $footnoteText
223
 * @param string $enclosing_tag
224
 *   default is 'span'
225
 *
226
 * @return string
227
 *
228
 */
229
function render_footnote($footnoteKey = null, $footnoteText = null, $enclosing_tag = 'span', $footnote_list_key = null) {
230
  _add_js_footnotes();
231
  if($enclosing_tag == null){
232
    $enclosing_tag = 'span';
233
  }
234
  $class_attribute_member_of = '';
235
  if($footnote_list_key){
236
    $class_attribute_member_of = MEMBER_OF_FOOTNOTES . $footnote_list_key;
237
  }
238
  return '<' . $enclosing_tag . ' class="footnote footnote-' . $footnoteKey . $class_attribute_member_of . '">'
239
    . '<a name="footnote-' . $footnoteKey . '"></a>'
240
    . '<span class="footnote-anchor">' . $footnoteKey . '.</span>&nbsp;' . $footnoteText
241
    . '</' . $enclosing_tag . '>';
242
}
243

    
244

    
245

    
246
/**
247
 * Create markup for the footnotes mapped to the $footnoteListKey.
248
 *
249
 * @param null $footnote_list_key
250
 *  The footnote list key, see RenderHints::getFootnoteListKey()
251
 * @param $element_tag
252
 *  The tag for the footnote element
253
 *
254
 * @return string
255
 *   The markup
256
 */
257
function render_footnotes($footnote_list_key = null, $element_tag = 'span') {
258

    
259
  if (variable_get('cdm_dataportal_all_footnotes', CDM_DATAPORTAL_ALL_FOOTNOTES)) {
260
    return '';
261
  }
262

    
263
  if (!isset($footnote_list_key) || !$footnote_list_key) {
264
    $footnote_list_key = RenderHints::getFootnoteListKey();
265
  }
266

    
267
  $out = '<' . $element_tag . ' class="footnotes footnotes-' . $footnote_list_key . ' ">'
268
    . FootnoteManager::renderFootnoteList($footnote_list_key)
269
    . '</' . $element_tag . '>';
270

    
271
  FootnoteManager::removeFootnoteList($footnote_list_key);
272
  return $out;
273
}
274

    
275
/**
276
 * This method determines the footnote key for original sources to be shown in the bibliography block
277
 *
278
 * The footnote key depends on the value of the 'enabled' value of the bibliography_settings
279
 *    - enabled == 1 -> "BIBLIOGRAPHY"
280
 *    - enabled == 0 -> "BIBLIOGRAPHY-$key_suggestion"
281
 *
282
 * @see get_bibliography_settings() and @see constant BIBLIOGRAPHY_FOOTNOTE_KEY
283
 *
284
 * @param $key_suggestion string
285
 *    optional parameter. If this parameter is left empty (null, 0, "") the footnote key will be retrieved by
286
 *    calling RenderHints::getFootnoteListKey().
287

    
288
 *
289
 * @return string
290
 *  the footnote_list_key
291
 */
292
function bibliography_footnote_list_key($key_suggestion = null) {
293
  if(!$key_suggestion){
294
    $key_suggestion = RenderHints::getFootnoteListKey();
295
  }
296
  $bibliography_settings = get_bibliography_settings();
297
  $footnote_list_key = $bibliography_settings['enabled'] == 1 ? BIBLIOGRAPHY_FOOTNOTE_KEY : BIBLIOGRAPHY_FOOTNOTE_KEY . '-' . $key_suggestion;
298
  return $footnote_list_key;
299
}
300

    
301

    
302
/**
303
 * Creates footnote markup for the name relationship and
304
 * registers it in the {@link \FootnoteManager}. The resulting foonote
305
 * key is returned as markup.
306
 *
307
 * @param $name_rel
308
 *   The cdm name relationship
309
 * @return \FootnoteKey
310
 *  The FootnoteKey
311
 */
312
function handle_name_relationship_as_footnote($name_rel)
313
{
314
  $footnote_markup = '';
315
  $fnkey = null;
316
  if (isset($name_rel->ruleConsidered) && $name_rel->ruleConsidered) {
317
    $footnote_markup = '<span class="rule_considered">' . $name_rel->ruleConsidered . '</span>; ';
318
  }
319
  if (isset($name_rel->source->citation)) {
320
    $footnote_markup .= '<span class="reference">' . $name_rel->source->citation->titleCache . '</span>';
321
  }
322
  if (isset($name_rel->source->citationMicroReference) && $name_rel->source->citationMicroReference) {
323
    $footnote_markup .= (isset($name_rel->source->citation) ? ':' : '') . ' <span class="reference_detail">' . $name_rel->source->citationMicroReference . '</span>';
324
  }
325
  if ($footnote_markup) {
326
    $fnkey = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), $footnote_markup);
327
  }
328
  return $fnkey;
329
}
330

    
331
/**
332
 * Creates footnote markup for nomenclatural status and
333
 * registers it in the {@link \FootnoteManager}. The resulting foonote
334
 * key is returned as markup.
335
 *
336
 * @param $nom_status
337
 * @return \FootnoteKey
338
 *  The FootnoteKey
339
 */
340
function handle_nomenclatural_status_as_footnote($nom_status)
341
{
342
  // NomenclaturalStatus is a subclass of ReferencedEntityBase
343
  // and has the same structure as TaxonNameRelationship
344
  return handle_name_relationship_as_footnote($nom_status);
345
}
346

    
347
/**
348
 * Creates footnote markup for nomenclatural reference of the name and
349
 * registers it in the {@link \FootnoteManager}. The resulting foonote
350
 * key is returned as markup.
351
 *
352
 * @param $name
353
 * The name whose nomenclatural reference is to be shown as footnote
354
 * @return \FootnoteKey
355
 *  The FootnoteKey
356
 */
357
function handle_nomenclatural_reference_as_footnote($name)
358
{
359
  $footnote_markup = '';
360
  $footnote_key_markup = '';
361
  if (isset($name->nomenclaturalSource->citation) && $name->nomenclaturalSource->citation) {
362
    $footnote_markup .= '<span class="reference">' . $name->nomenclaturalSource->citation->titleCache . '</span>';
363
  }
364
  if (isset($name->nomenclaturalSource->citationMicroReference)) {
365
    $footnote_markup .= ($footnote_key_markup ? ':' : '') . '<span class="reference_detail">' . $name->nomenclaturalSource->citationMicroReference . '</span>';
366
  }
367
  $fnkey = null;
368
  if ($footnote_markup) {
369
    $fnkey = FootnoteManager::addNewFootnote(RenderHints::getFootnoteListKey(), $footnote_markup);
370
  }
371
  return $fnkey;
372
}
373

    
374
/* ============ annotations_and_sources handling =================== */
375
const ANNOTATIONS_AND_SOURCE_CONFIG_DEFAULT = [
376
  'sources_as_content' => FALSE,
377
  'annotations_as_content' => FALSE,
378
  'link_to_name_used_in_source' => TRUE,
379
  'link_to_reference' => TRUE,
380
  'add_footnote_keys' => TRUE,
381
  'bibliography_aware' => FALSE
382
];
383

    
384
/**
385
 * Provides the default configuration for handle_annotations_and_sources() in the
386
 * synonymy.
387
 *
388
 * @return bool[]
389
 */
390
function synonymy_annotations_and_source_config() {
391
  static $annotations_and_sources_config = null;
392
  if(!$annotations_and_sources_config){
393
    $bibliography_settings = get_bibliography_settings();
394
    $annotations_and_sources_config = [
395
      'sources_as_content' => FALSE,
396
      'link_to_name_used_in_source' => TRUE,
397
      'link_to_reference' => TRUE,
398
      'add_footnote_keys' => TRUE,
399
      'bibliography_aware' => $bibliography_settings['enabled'] == 1
400
    ];
401
  }
402
  return $annotations_and_sources_config;
403
}
404

    
405
/**
406
 * Provides the default configuration for typedesignations which
407
 * are passed to the handle_annotations_and_sources()
408
 * function:
409
 * - 'sources_as_content' => TRUE,
410
 * - 'link_to_name_used_in_source' => FALSE,
411
 * - 'link_to_reference' => TRUE,
412
 * - 'add_footnote_keys' => FALSE,
413
 * - 'bibliography_aware' => FALSE
414
 *
415
 * @return array
416
 */
417
function annotations_and_sources_config_typedesignations() {
418
  static $annotations_and_sources_config = [
419
    'sources_as_content' => TRUE,
420
    'link_to_name_used_in_source' => FALSE,
421
    'link_to_reference' => TRUE,
422
    'add_footnote_keys' => FALSE,
423
    'bibliography_aware' => FALSE
424
  ];
425
  return $annotations_and_sources_config;
426
}
427

    
428
/**
429
 * Provides the default configuration for occurrences which
430
 * are passed to the handle_annotations_and_sources()
431
 * function:
432
 * - 'sources_as_content' => TRUE,
433
 * - 'link_to_name_used_in_source' => TRUE,
434
 * - 'link_to_reference' => FALSE,
435
 * - 'add_footnote_keys' => FALSE,
436
 * - 'bibliography_aware' => FALSE
437
 *
438
 * @return array
439
 */
440
function annotations_and_sources_config_occurrences() {
441
  static $annotations_and_sources_config = [
442
    'sources_as_content' => TRUE,
443
    'link_to_name_used_in_source' => TRUE,
444
    'link_to_reference' => FALSE,
445
    'add_footnote_keys' => FALSE,
446
    'bibliography_aware' => FALSE
447
  ];
448
  return $annotations_and_sources_config;
449
}
450

    
451
function annotation_and_source_config_taxon_node() {
452
  static $conf = null;
453
  if(!$conf){
454
    $bibliography_settings = get_bibliography_settings();
455
    $conf = [
456
      'sources_as_content' => false,
457
      'link_to_name_used_in_source' => false,
458
      'link_to_reference' => true,
459
      'add_footnote_keys' => true,
460
      'bibliography_aware' => $bibliography_settings['enabled'] == 1
461
    ];
462
  }
463
  return $conf;
464
}
465

    
466
/**
467
 * Creates a handle_annotations_and_sources configuration array from feature_block_settings.
468
 *
469
 * The handle_annotations_and_sources configuration array is meant to be used for the
470
 * method handle_annotations_and_sources().
471
 *
472
 * @param $feature_block_settings array
473
 *
474
 * @return array
475
 *   The configuration array for handle_annotations_and_sources()
476
 */
477
function handle_annotations_and_sources_config($feature_block_settings){
478

    
479
  $config = [
480
    'sources_as_content' => $feature_block_settings['sources_as_content'] == 1,
481
    'link_to_name_used_in_source' => $feature_block_settings['link_to_name_used_in_source'] == 1,
482
    'link_to_reference' => $feature_block_settings['link_to_reference'] == 1,
483
    'add_footnote_keys' => (
484
      $feature_block_settings['sources_as_content'] !== 1 ||
485
      $feature_block_settings['sources_as_content_to_bibliography'] == 1
486
    ),
487
    'bibliography_aware' => TRUE // FIXME shouldn't this be retrieved from the settings?
488
  ];
489
  return $config;
490
}
491

    
492
/**
493
 * @param $entity
494
 *    The cdm entity for which the annotations and sources are to be handled.
495
 * @param $inline_text_prefix
496
 *   Only used to decide if the source references should be enclosed in
497
 *   brackets or not when displayed inline. This text will not be included into
498
 *   the response.
499
 * @param $footnote_list_key_suggestion string
500
 *   Optional parameter. If this parameter is left empty (null, 0, "") the
501
 *   footnote key will be determined by the nested method calls by calling
502
 *   RenderHints::getFootnoteListKey().
503
 *
504
 * @return AnnotationsAndSources
505
 *  an object with the following elements:
506
 *   - foot_note_keys: all footnote keys as markup
507
 *   - source_references: an array of the source references citations
508
 *   - names used in source: an associative array of the names in source,
509
 *        the name in source strings are de-duplicated
510
 *        !!!NOTE!!!!: this field will most probably be removed soon (TODO)
511
 */
512
function handle_annotations_and_sources($entity, $inline_text_prefix = null, $footnote_list_key_suggestion = null, AnnotationsAndSources $annotationsAndSources = null) {
513

    
514
  if($annotationsAndSources == null){
515
    $annotationsAndSources = new AnnotationsAndSources();
516
  }
517

    
518
  // some entity types only have single sources:
519
  $sources = cdm_entity_sources_sorted($entity);
520

    
521
  $config = RenderHints::getAnnotationsAndSourceConfig();
522

    
523
  if ($config['sources_as_content']) {
524
    foreach ($sources as $source) {
525
      if (_is_original_source_type($source)) {
526
        $reference_citation = render_original_source(
527
          $source,
528
          $config['link_to_reference'],
529
          $config['link_to_name_used_in_source']
530
        );
531

    
532
        if ($reference_citation) {
533
          if (empty($inline_text_prefix)) {
534
            $annotationsAndSources->addSourceReferencesCitation($reference_citation);
535
          } else {
536
            $annotationsAndSources->addSourceReferencesCitation(' (' . $reference_citation . ')');
537
          }
538
        }
539

    
540
        // also put the name in source into the array, these are already included in the $reference_citation but are
541
        // still required to be available separately in some contexts.
542
        $name_in_source_render_array = compose_name_in_source(
543
          $source,
544
          $config['link_to_name_used_in_source']
545
        );
546

    
547
        if (!empty($name_in_source_render_array)) {
548
          $annotationsAndSources->putNamesUsedInSource($name_in_source_render_array['#_plaintext'], drupal_render($name_in_source_render_array));
549
        }
550
      }
551
    } // END of loop over sources
552

    
553
    // annotations footnotes separate from sources
554
    $footnote_keys = cdm_entity_annotations_as_footnote_keys($entity, $footnote_list_key_suggestion);
555
    $annotationsAndSources->addAllFootNoteKeys($footnote_keys);
556

    
557
  } // END of references inline
558

    
559
  // footnotes for sources and annotations or put into into bibliography if requested ...
560
  $do_foonotes_as_content = isset($config['annotations_as_content']) && $config['annotations_as_content'];
561
  if($do_foonotes_as_content){
562
    $annotationsAndSources->setAnnotations(cdm_entity_annotations_as_content($entity));
563
  }
564
  if ($config['add_footnote_keys']) {
565
    $annotationsAndSources->addAllFootNoteKeys(cdm_entity_footnotes(
566
      $entity,
567
      $footnote_list_key_suggestion,
568
      $config['link_to_reference'],
569
      $config['link_to_name_used_in_source'],
570
      (!empty($config['bibliography_aware']) ? $config['bibliography_aware'] : FALSE),
571
      !$do_foonotes_as_content
572
    ));
573
  }
574
  return $annotationsAndSources;
575
}
576

    
577
/**
578
 * Get the source or the sources from a cdm entity and return them ordered by see compare_original_sources()
579
 * (Some entity types only have single sources)
580
 * @param $entity
581
 *
582
 * @return array
583
 */
584
function cdm_entity_sources_sorted($entity) {
585
  if (isset($entity->source) && is_object($entity->source)) {
586
    $sources = [$entity->source];
587
  }
588
  else if (isset($entity->sources)) {
589
    $sources = $entity->sources;
590
  }
591
  else {
592
    // try to load the sources
593
    if(isset_not_empty($entity->uuid)){
594
      $sources = cdm_ws_fetch_all(cdm_compose_url('portal/' . cdm_ws_base_uri($entity->class), [ $entity->uuid, 'sources']));
595
    } else {
596
      // this may happen with DerivedUnitFaced, also with others?
597
      $sources = [];
598
    }
599
  }
600
  usort($sources, 'compare_original_sources');
601
  return $sources;
602
}
603

    
604
/**
605
 * Compare two different footnotes objects.
606
 *
607
 * The comparison is based on the footnote key. The one which is
608
 * displayed as footnote number.
609
 *
610
 * @param mixed $a
611
 *   Footnote object $a.
612
 * @param mixed $b
613
 *   Footnote object $b.
614
 *
615
 * @return int
616
 *
617
 * @deprecated seems to be unused: TODO remove!
618
 */
619
function footnotes_key_compare($a, $b) {
620
  $res = 0;
621
  if (empty($a) || empty($b)) {
622
    return $res;
623
  }
624
  if ($a->keyStr < $b->keyStr) {
625
    $res = -1;
626
  }
627
  elseif ($a->keyStr > $b->keyStr) {
628
    $res = 1;
629
  }
630
  return $res;
631
}
632

    
633

    
(4-4/16)