Project

General

Profile

Download (7.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Class to manage footnotes.
5
 *
6
 * @copyright
7
 *   (C) 2007-2012 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

    
16
/**
17
 * Manages footnotes in multiple list. Each of these footnote lists is
18
 * identified by a footnoteListKey.
19
 *
20
 * The $footnoteListKey for the current page part that should be stored in the
21
 * the RenderHints class by calling @see RenderHints::setFootnoteListKey($footnoteListKey)
22
 */
23
class FootnoteManager {
24
  private static $fnstore = [];
25
  private static $blockedFootnoteLitsKeys = [];
26
  /*
27
   * An associative array holding information on
28
   * special footnote sets which are to be handle separately
29
   *
30
   * The key of the map is the $footnoteListKey which is also the
31
   * key of the  $fnstore map
32
   *
33
   * The values are associative arrays with the following optional elements:
34
   *  - enclosing_tag: the enclosing tag to be used for rendering of the footnote,
35
   *    @see theme_cdm_footnote()
36
   *  - key_format: 'latin', 'ROMAN', 'roman', 'ALPHA', 'alpha'
37
   * and one required element:
38
   *  - key_index: the set specific counter, to replace the
39
   *    default $footnote_key_index
40
   */
41
  private static $fn_sets = array();
42
  private static $default_set_definition = array(
43
    'key_index' => 1,
44
    'enclosing_tag' => null,
45
    'key_format' => 'numeric'
46
  );
47

    
48
  /**
49
   * Private constructor.
50
   */
51
  private function __construct() {}
52

    
53
  /**
54
   * Get a list of footnotes.
55
   *
56
   * @param string $footnoteListKey
57
   *   A string as key to the list of footnotes.
58
   *
59
   * @return array
60
   *   An array of footnotes objects.
61
   */
62
  public static function getFootnoteList($footnoteListKey) {
63
    return array_key_exists($footnoteListKey, self::$fnstore) ? self::$fnstore[$footnoteListKey] : NULL;
64
  }
65

    
66
  /**
67
   * Remove a list of footnotes.
68
   *
69
   * @param string $footnoteListKey
70
   *   A string as key to the list of footnotes.
71
   *
72
   * @return void
73
   */
74
  public static function removeFootnoteList($footnoteListKey) {
75
    if (array_key_exists($footnoteListKey, self::$fnstore)) {
76
      unset(self::$fnstore[$footnoteListKey]);
77
    }
78
  }
79

    
80
  /**
81
   * Render a footnote list
82
   *
83
   * @param string $footnoteListKey
84
   * @param string $separator
85
   *
86
   * @return string
87
   *   The rendered footnotelist or an empty string if the $footnoteListKey is
88
   *   blocked
89
   */
90
  public static function renderFootnoteList($footnoteListKey, $separator = ', ') {
91

    
92
    if(self::isBlockedFootnoteListKey($footnoteListKey)){
93
      // the footnote key is blocked, don't render it!
94
      return '';
95
    }
96
    $out = '';
97
    if (array_key_exists($footnoteListKey, self::$fnstore)) {
98
      foreach (self::$fnstore[$footnoteListKey] as $fn) {
99
        $out .= $fn->doRender($footnoteListKey) . $separator;
100
      }
101
      $out = substr($out, 0, strlen($out) - strlen($separator));
102
    }
103
    return $out;
104
  }
105

    
106
  /**
107
   * Provides the content of foot notes
108
   *
109
   * @param string $footnoteListKey
110
   *
111
   * @return array
112
   *   The content of foot notes or an empty array if the $footnoteListKey is
113
   *   blocked
114
   */
115
  public static function footnoteListContents($footnoteListKey) {
116

    
117
    if(self::isBlockedFootnoteListKey($footnoteListKey)){
118
      // the footnote key is blocked, don't render it!
119
      return [];
120
    }
121
    $content_list = [];
122
    if (array_key_exists($footnoteListKey, self::$fnstore)) {
123
      foreach (self::$fnstore[$footnoteListKey] as $fn) {
124
        $content_list[] = $fn->getContent();
125
      }
126
    }
127
    return $content_list;
128
  }
129

    
130
  /**
131
   * Add a new footnote.
132
   *
133
   * @param $footnoteListKey
134
   * @param $object
135
   *
136
   * @return FootnoteKey
137
   */
138
  public static function addNewFootnote($footnoteListKey, $object = NULL) {
139
    if (!$object || !$footnoteListKey || self::isBlockedFootnoteListKey($footnoteListKey)) {
140
      return null;
141
    }
142
    if (!array_key_exists($footnoteListKey, self::$fnstore)) {
143
      self::$fnstore[$footnoteListKey] = array();
144
    }
145

    
146
    $key_label = NULL;
147
    if (!($key_label = self::footnoteExists($footnoteListKey, $object))) {
148

    
149
      $set_def = &self::matchFootnoteSetDefinition($footnoteListKey);
150

    
151
      $fn_index = $set_def['key_index']++;
152

    
153
      // see http://php.net/manual/de/function.base-convert.php
154
      switch($set_def['key_format']) {
155
        case 'ROMAN':
156
          $key_label = roman_numerals($fn_index);
157
          break;
158
        case 'roman':
159
          $key_label = strtolower(roman_numerals($fn_index));
160
          break;
161
        case 'ALPHA':
162
          $key_label = num2alpha($fn_index - 1);
163
          break;
164
        case 'alpha':
165
          $key_label = strtolower(num2alpha($fn_index - 1));
166
          break;
167
        case 'latin':
168
        default:
169
          $key_label = $fn_index;
170
      }
171

    
172
      $fn = new Footnote($key_label, $object, $set_def['enclosing_tag']);
173
      self::$fnstore[$footnoteListKey][$key_label] = $fn;
174
    }
175

    
176
    return new FootnoteKey($key_label, $footnoteListKey);
177
  }
178

    
179
  /**
180
   * Check if a footnote exists.
181
   *
182
   * @param $footnoteListKey
183
   * @param $object
184
   *
185
   * @return bool|int|string
186
   */
187
  private static function footnoteExists($footnoteListKey, $object) {
188
    foreach (self::$fnstore[$footnoteListKey] as $key => $fn) {
189
      /*
190
      When using the comparison operator (==), object variables are compared
191
      in a simple manner, namely:
192
      Two object instances are equal if they have the same attributes and
193
      values, and are instances of the same class.
194
      */
195
      if ($object == $fn->object) {
196
        return $key;
197
      }
198
    }
199
    return FALSE;
200
  }
201

    
202
  /**
203
   * Register special footnote set for the given $footnoteListKey which is to be handle separately
204
   * @param $footnoteListKey
205
   * @param $enclosing_tag: the enclosing tag to be used for rendering of the footnote, @see theme_cdm_footnote()
206
   * @param $key_format: 'latin', 'ROMAN', 'roman', 'ALPHA', 'alpha'
207
   */
208
  public static function registerFootnoteSet($footnoteListKey, $enclosing_tag = null, $key_format = null){
209

    
210
    $set_def = array('key_index' => 1);
211
    if($enclosing_tag){
212
      $set_def['enclosing_tag'] = $enclosing_tag;
213
    } else {
214
      $set_def['enclosing_tag'] = self::$default_set_definition['enclosing_tag'];
215
    }
216
    if($key_format){
217
      $set_def['key_format'] = $key_format;
218
    } else {
219
      $set_def['key_format'] = self::$default_set_definition['key_format'];
220
    }
221
    self::$fn_sets[$footnoteListKey] = $set_def;
222
  }
223

    
224
  /**
225
   * Returns the footnote set definition which has been
226
   * registered with a key which matches the given $footnoteListKey.
227
   * A match is the first key which is equal to or which starts with $footnoteListKey
228
   * If no match is found the default is returned.
229
   *
230
   * @see registerFootnoteSet()
231
   *
232
   * @param $footnoteListKey
233
   * @return array
234
   */
235
  public static function &matchFootnoteSetDefinition($footnoteListKey){
236

    
237
    foreach(self::$fn_sets as $fn_set_key => &$fn_set_def){
238
      if($footnoteListKey == $fn_set_key || str_beginsWith($footnoteListKey, $fn_set_key)){
239
        return $fn_set_def;
240
      }
241
    }
242
    return self::$default_set_definition;
243
  }
244

    
245
  public static function blockFootnotesFor($footnoteListKey) {
246
    if(array_search($footnoteListKey, self::$blockedFootnoteLitsKeys) === false){
247
      self::$blockedFootnoteLitsKeys[] = $footnoteListKey;
248
    }
249
  }
250
  public static function unblockFootnotesFor($footnoteListKey) {
251
    $index = array_search($footnoteListKey, self::$blockedFootnoteLitsKeys);
252
    if($index !== false){
253
      unset(self::$blockedFootnoteLitsKeys[$index]);
254
    }
255
  }
256

    
257
  /**
258
   * @param $footnoteListKey
259
   *
260
   * @return bool
261
   */
262
  public static function isBlockedFootnoteListKey($footnoteListKey) {
263
    return array_search($footnoteListKey, self::$blockedFootnoteLitsKeys) !== false;
264
  }
265

    
266
  /**
267
   * Stop users from cloning.
268
   */
269
  public function __clone() {
270
    trigger_error('Cloning instances of the singleton class FootNoteManager is prohibited', E_USER_ERROR);
271
  }
272
}
(13-13/14)